feat: Run MRP at parent level in the production plan (#21545)
* enhance: provision to make material request from other location * fix: source warehouse for material transfer from production plan Co-authored-by: Rohit Waghchaure <rohitw1991@gmail.com>
This commit is contained in:
parent
39805918d4
commit
da17f9cb05
@ -1,4 +1,5 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2017-12-01 12:12:55.048691",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
@ -6,8 +7,9 @@
|
||||
"field_order": [
|
||||
"item_code",
|
||||
"item_name",
|
||||
"warehouse",
|
||||
"material_request_type",
|
||||
"from_warehouse",
|
||||
"warehouse",
|
||||
"column_break_4",
|
||||
"quantity",
|
||||
"uom",
|
||||
@ -46,6 +48,7 @@
|
||||
{
|
||||
"fieldname": "material_request_type",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Material Request Type",
|
||||
"options": "\nPurchase\nMaterial Transfer\nMaterial Issue\nManufacture\nCustomer Provided"
|
||||
},
|
||||
@ -64,11 +67,11 @@
|
||||
{
|
||||
"fieldname": "projected_qty",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 1,
|
||||
"label": "Projected Qty",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "actual_qty",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 1,
|
||||
@ -119,10 +122,18 @@
|
||||
"label": "UOM",
|
||||
"options": "UOM",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.material_request_type == 'Material Transfer'",
|
||||
"fieldname": "from_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"label": "From Warehouse",
|
||||
"options": "Warehouse"
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"modified": "2019-11-08 15:15:43.979360",
|
||||
"links": [],
|
||||
"modified": "2020-02-03 12:22:29.913302",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Material Request Plan Item",
|
||||
|
@ -19,7 +19,8 @@ frappe.ui.form.on('Production Plan', {
|
||||
frm.set_query('for_warehouse', function(doc) {
|
||||
return {
|
||||
filters: {
|
||||
company: doc.company
|
||||
company: doc.company,
|
||||
is_group: 0
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -188,12 +189,53 @@ frappe.ui.form.on('Production Plan', {
|
||||
},
|
||||
|
||||
get_items_for_mr: function(frm) {
|
||||
const set_fields = ['actual_qty', 'item_code','item_name', 'description', 'uom',
|
||||
if (!frm.doc.for_warehouse) {
|
||||
frappe.throw(__("Select warehouse for material requests"));
|
||||
}
|
||||
|
||||
if (frm.doc.ignore_existing_ordered_qty) {
|
||||
frm.events.get_items_for_material_requests(frm);
|
||||
} else {
|
||||
const title = __("Transfer Materials For Warehouse {0}", [frm.doc.for_warehouse]);
|
||||
var dialog = new frappe.ui.Dialog({
|
||||
title: title,
|
||||
fields: [
|
||||
{
|
||||
"fieldtype": "Table MultiSelect", "label": __("Source Warehouses"),
|
||||
"fieldname": "warehouses", "options": "Production Plan Material Request Warehouse",
|
||||
"description": "System will pickup the materials from the selected warehouses",
|
||||
get_query: function () {
|
||||
return {
|
||||
filters: {
|
||||
company: frm.doc.company
|
||||
}
|
||||
};
|
||||
},
|
||||
},
|
||||
]
|
||||
});
|
||||
|
||||
dialog.show();
|
||||
|
||||
dialog.set_primary_action(__("Get Items"), () => {
|
||||
let warehouses = dialog.get_values().warehouses;
|
||||
frm.events.get_items_for_material_requests(frm, warehouses);
|
||||
dialog.hide();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
get_items_for_material_requests: function(frm, warehouses) {
|
||||
const set_fields = ['actual_qty', 'item_code','item_name', 'description', 'uom', 'from_warehouse',
|
||||
'min_order_qty', 'quantity', 'sales_order', 'warehouse', 'projected_qty', 'material_request_type'];
|
||||
|
||||
frappe.call({
|
||||
method: "erpnext.manufacturing.doctype.production_plan.production_plan.get_items_for_material_requests",
|
||||
freeze: true,
|
||||
args: {doc: frm.doc},
|
||||
args: {
|
||||
doc: frm.doc,
|
||||
warehouses: warehouses || []
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
frm.set_value('mr_items', []);
|
||||
@ -212,14 +254,14 @@ frappe.ui.form.on('Production Plan', {
|
||||
},
|
||||
|
||||
for_warehouse: function(frm) {
|
||||
if (frm.doc.mr_items) {
|
||||
if (frm.doc.mr_items && frm.doc.for_warehouse) {
|
||||
frm.trigger("get_items_for_mr");
|
||||
}
|
||||
},
|
||||
|
||||
download_materials_required: function(frm) {
|
||||
let get_template_url = 'erpnext.manufacturing.doctype.production_plan.production_plan.download_raw_materials';
|
||||
open_url_post(frappe.request.url, { cmd: get_template_url, production_plan: frm.doc.name });
|
||||
open_url_post(frappe.request.url, { cmd: get_template_url, doc: frm.doc });
|
||||
},
|
||||
|
||||
show_progress: function(frm) {
|
||||
|
@ -43,6 +43,7 @@
|
||||
"total_produced_qty",
|
||||
"column_break_32",
|
||||
"status",
|
||||
"warehouses",
|
||||
"amended_from"
|
||||
],
|
||||
"fields": [
|
||||
@ -218,12 +219,6 @@
|
||||
"fieldname": "column_break_25",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "for_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"label": "For Warehouse",
|
||||
"options": "Warehouse"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:!doc.__islocal",
|
||||
"fieldname": "download_materials_required",
|
||||
@ -292,12 +287,26 @@
|
||||
"options": "Production Plan",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "for_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"label": "Material Request Warehouse",
|
||||
"options": "Warehouse"
|
||||
},
|
||||
{
|
||||
"fieldname": "warehouses",
|
||||
"fieldtype": "Table MultiSelect",
|
||||
"hidden": 1,
|
||||
"label": "Warehouses",
|
||||
"options": "Production Plan Material Request Warehouse",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-calendar",
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-01-21 19:13:10.113854",
|
||||
"modified": "2020-02-03 00:25:25.934202",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Production Plan",
|
||||
|
@ -3,7 +3,7 @@
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe, json
|
||||
import frappe, json, copy
|
||||
from frappe import msgprint, _
|
||||
from six import string_types, iteritems
|
||||
|
||||
@ -385,6 +385,7 @@ class ProductionPlan(Document):
|
||||
# add item
|
||||
material_request.append("items", {
|
||||
"item_code": item.item_code,
|
||||
"from_warehouse": item.from_warehouse,
|
||||
"qty": item.quantity,
|
||||
"schedule_date": schedule_date,
|
||||
"warehouse": item.warehouse,
|
||||
@ -415,19 +416,18 @@ class ProductionPlan(Document):
|
||||
msgprint(_("No material request created"))
|
||||
|
||||
@frappe.whitelist()
|
||||
def download_raw_materials(production_plan):
|
||||
doc = frappe.get_doc('Production Plan', production_plan)
|
||||
doc.check_permission()
|
||||
def download_raw_materials(doc):
|
||||
if isinstance(doc, string_types):
|
||||
doc = frappe._dict(json.loads(doc))
|
||||
|
||||
item_list = [['Item Code', 'Description', 'Stock UOM', 'Required Qty', 'Warehouse',
|
||||
'projected Qty', 'Actual Qty']]
|
||||
|
||||
doc = doc.as_dict()
|
||||
for d in get_items_for_material_requests(doc, ignore_existing_ordered_qty=True):
|
||||
for d in get_items_for_material_requests(doc):
|
||||
item_list.append([d.get('item_code'), d.get('description'), d.get('stock_uom'), d.get('quantity'),
|
||||
d.get('warehouse'), d.get('projected_qty'), d.get('actual_qty')])
|
||||
|
||||
if not doc.for_warehouse:
|
||||
if not doc.get('for_warehouse'):
|
||||
row = {'item_code': d.get('item_code')}
|
||||
for bin_dict in get_bin_details(row, doc.company, all_warehouse=True):
|
||||
if d.get("warehouse") == bin_dict.get('warehouse'):
|
||||
@ -610,26 +610,43 @@ def get_bin_details(row, company, for_warehouse=None, all_warehouse=False):
|
||||
""".format(conditions=conditions), { "item_code": row['item_code'] }, as_dict=1)
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_items_for_material_requests(doc, ignore_existing_ordered_qty=None):
|
||||
def get_items_for_material_requests(doc, warehouses=None):
|
||||
if isinstance(doc, string_types):
|
||||
doc = frappe._dict(json.loads(doc))
|
||||
|
||||
warehouse_list = []
|
||||
if warehouses:
|
||||
if isinstance(warehouses, string_types):
|
||||
warehouses = json.loads(warehouses)
|
||||
|
||||
for row in warehouses:
|
||||
child_warehouses = frappe.db.get_descendants('Warehouse', row.get("warehouse"))
|
||||
if child_warehouses:
|
||||
warehouse_list.extend(child_warehouses)
|
||||
else:
|
||||
warehouse_list.append(row.get("warehouse"))
|
||||
|
||||
if warehouse_list:
|
||||
warehouses = list(set(warehouse_list))
|
||||
|
||||
if doc.get("for_warehouse") and doc.get("for_warehouse") in warehouses:
|
||||
warehouses.remove(doc.get("for_warehouse"))
|
||||
|
||||
warehouse_list = None
|
||||
|
||||
doc['mr_items'] = []
|
||||
po_items = doc.get('po_items') if doc.get('po_items') else doc.get('items')
|
||||
if not po_items:
|
||||
frappe.throw(_("Items are required to pull the raw materials which is associated with it."))
|
||||
|
||||
company = doc.get('company')
|
||||
warehouse = doc.get('for_warehouse')
|
||||
|
||||
if not ignore_existing_ordered_qty:
|
||||
ignore_existing_ordered_qty = doc.get('ignore_existing_ordered_qty')
|
||||
ignore_existing_ordered_qty = doc.get('ignore_existing_ordered_qty')
|
||||
|
||||
so_item_details = frappe._dict()
|
||||
for data in po_items:
|
||||
planned_qty = data.get('required_qty') or data.get('planned_qty')
|
||||
ignore_existing_ordered_qty = data.get('ignore_existing_ordered_qty') or ignore_existing_ordered_qty
|
||||
warehouse = data.get("warehouse") or warehouse
|
||||
warehouse = doc.get('for_warehouse')
|
||||
|
||||
item_details = {}
|
||||
if data.get("bom") or data.get("bom_no"):
|
||||
@ -700,12 +717,51 @@ def get_items_for_material_requests(doc, ignore_existing_ordered_qty=None):
|
||||
if items:
|
||||
mr_items.append(items)
|
||||
|
||||
if not ignore_existing_ordered_qty and warehouses:
|
||||
new_mr_items = []
|
||||
for item in mr_items:
|
||||
get_materials_from_other_locations(item, warehouses, new_mr_items, company)
|
||||
|
||||
mr_items = new_mr_items
|
||||
|
||||
if not mr_items:
|
||||
frappe.msgprint(_("""As raw materials projected quantity is more than required quantity, there is no need to create material request.
|
||||
Still if you want to make material request, kindly enable <b>Ignore Existing Projected Quantity</b> checkbox"""))
|
||||
frappe.msgprint(_("""As raw materials projected quantity is more than required quantity,
|
||||
there is no need to create material request for the warehouse {0}.
|
||||
Still if you want to make material request,
|
||||
kindly enable <b>Ignore Existing Projected Quantity</b> checkbox""").format(doc.get('for_warehouse')))
|
||||
|
||||
return mr_items
|
||||
|
||||
def get_materials_from_other_locations(item, warehouses, new_mr_items, company):
|
||||
from erpnext.stock.doctype.pick_list.pick_list import get_available_item_locations
|
||||
locations = get_available_item_locations(item.get("item_code"),
|
||||
warehouses, item.get("quantity"), company, ignore_validation=True)
|
||||
|
||||
if not locations:
|
||||
new_mr_items.append(item)
|
||||
return
|
||||
|
||||
required_qty = item.get("quantity")
|
||||
for d in locations:
|
||||
if required_qty <=0: return
|
||||
|
||||
new_dict = copy.deepcopy(item)
|
||||
quantity = required_qty if d.get("qty") > required_qty else d.get("qty")
|
||||
|
||||
if required_qty > 0:
|
||||
new_dict.update({
|
||||
"quantity": quantity,
|
||||
"material_request_type": "Material Transfer",
|
||||
"from_warehouse": d.get("warehouse")
|
||||
})
|
||||
|
||||
required_qty -= quantity
|
||||
new_mr_items.append(new_dict)
|
||||
|
||||
if required_qty:
|
||||
item["quantity"] = required_qty
|
||||
new_mr_items.append(item)
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_item_data(item_code):
|
||||
item_details = get_item_details(item_code)
|
||||
|
@ -0,0 +1,8 @@
|
||||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Production Plan Material Request Warehouse', {
|
||||
// refresh: function(frm) {
|
||||
|
||||
// }
|
||||
});
|
@ -0,0 +1,42 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2020-02-02 10:37:16.650836",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"warehouse"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "warehouse",
|
||||
"fieldtype": "Link",
|
||||
"label": "Warehouse",
|
||||
"options": "Warehouse"
|
||||
}
|
||||
],
|
||||
"links": [],
|
||||
"modified": "2020-02-02 10:37:16.650836",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Production Plan Material Request Warehouse",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class ProductionPlanMaterialRequestWarehouse(Document):
|
||||
pass
|
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# import frappe
|
||||
import unittest
|
||||
|
||||
class TestProductionPlanMaterialRequestWarehouse(unittest.TestCase):
|
||||
pass
|
@ -20,6 +20,17 @@ frappe.ui.form.on('Material Request', {
|
||||
frm.set_indicator_formatter('item_code',
|
||||
function(doc) { return (doc.qty<=doc.ordered_qty) ? "green" : "orange"; });
|
||||
|
||||
frm.set_query("item_code", "items", function() {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.item_query"
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query("from_warehouse", "items", function(doc) {
|
||||
return {
|
||||
filters: {'company': doc.company}
|
||||
};
|
||||
})
|
||||
},
|
||||
|
||||
onload: function(frm) {
|
||||
@ -53,6 +64,16 @@ frappe.ui.form.on('Material Request', {
|
||||
frm.toggle_reqd('customer', frm.doc.material_request_type=="Customer Provided");
|
||||
},
|
||||
|
||||
set_from_warehouse: function(frm) {
|
||||
if (frm.doc.material_request_type == "Material Transfer"
|
||||
&& frm.doc.set_from_warehouse) {
|
||||
frm.doc.items.forEach(d => {
|
||||
frappe.model.set_value(d.doctype, d.name,
|
||||
"from_warehouse", frm.doc.set_from_warehouse);
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
make_custom_buttons: function(frm) {
|
||||
if (frm.doc.docstatus==0) {
|
||||
frm.add_custom_button(__("Bill of Materials"),
|
||||
@ -159,6 +180,7 @@ frappe.ui.form.on('Material Request', {
|
||||
args: {
|
||||
args: {
|
||||
item_code: item.item_code,
|
||||
from_warehouse: item.from_warehouse,
|
||||
warehouse: item.warehouse,
|
||||
doctype: frm.doc.doctype,
|
||||
buying_price_list: frappe.defaults.get_default('buying_price_list'),
|
||||
@ -176,9 +198,11 @@ frappe.ui.form.on('Material Request', {
|
||||
},
|
||||
callback: function(r) {
|
||||
const d = item;
|
||||
const qty_fields = ['actual_qty', 'projected_qty', 'min_order_qty'];
|
||||
|
||||
if(!r.exc) {
|
||||
$.each(r.message, function(k, v) {
|
||||
if(!d[k]) d[k] = v;
|
||||
if(!d[k] || in_list(qty_fields, k)) d[k] = v;
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -324,6 +348,16 @@ frappe.ui.form.on("Material Request Item", {
|
||||
frm.events.get_item_data(frm, item);
|
||||
},
|
||||
|
||||
from_warehouse: function(frm, doctype, name) {
|
||||
const item = locals[doctype][name];
|
||||
frm.events.get_item_data(frm, item);
|
||||
},
|
||||
|
||||
warehouse: function(frm, doctype, name) {
|
||||
const item = locals[doctype][name];
|
||||
frm.events.get_item_data(frm, item);
|
||||
},
|
||||
|
||||
rate: function(frm, doctype, name) {
|
||||
const item = locals[doctype][name];
|
||||
frm.events.get_item_data(frm, item);
|
||||
|
@ -18,6 +18,8 @@
|
||||
"amended_from",
|
||||
"warehouse_section",
|
||||
"set_warehouse",
|
||||
"column_break5",
|
||||
"set_from_warehouse",
|
||||
"items_section",
|
||||
"scan_barcode",
|
||||
"items",
|
||||
@ -287,13 +289,27 @@
|
||||
"fieldtype": "Link",
|
||||
"label": "Set Warehouse",
|
||||
"options": "Warehouse"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break5",
|
||||
"fieldtype": "Column Break",
|
||||
"oldfieldtype": "Column Break",
|
||||
"print_width": "50%",
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.material_request_type == 'Material Transfer'",
|
||||
"fieldname": "set_from_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"label": "Set From Warehouse",
|
||||
"options": "Warehouse"
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-ticket",
|
||||
"idx": 70,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-03-02 20:21:09.990867",
|
||||
"modified": "2020-05-01 20:21:09.990867",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Material Request",
|
||||
|
@ -456,6 +456,9 @@ def make_stock_entry(source_name, target_doc=None):
|
||||
if source_parent.material_request_type == "Customer Provided":
|
||||
target.allow_zero_valuation_rate = 1
|
||||
|
||||
if source_parent.material_request_type == "Material Transfer":
|
||||
target.s_warehouse = obj.from_warehouse
|
||||
|
||||
def set_missing_values(source, target):
|
||||
target.purpose = source.material_request_type
|
||||
if source.job_card:
|
||||
|
@ -1,4 +1,5 @@
|
||||
{
|
||||
"actions": [],
|
||||
"autoname": "hash",
|
||||
"creation": "2013-02-22 01:28:02",
|
||||
"doctype": "DocType",
|
||||
@ -21,6 +22,7 @@
|
||||
"quantity_and_warehouse",
|
||||
"qty",
|
||||
"stock_uom",
|
||||
"from_warehouse",
|
||||
"warehouse",
|
||||
"col_break2",
|
||||
"uom",
|
||||
@ -419,12 +421,19 @@
|
||||
{
|
||||
"fieldname": "col_break4",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:parent.material_request_type == \"Material Transfer\"",
|
||||
"fieldname": "from_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"label": "Source Warehouse (Material Transfer)",
|
||||
"options": "Warehouse"
|
||||
}
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-04-16 09:00:00.992835",
|
||||
"modified": "2020-05-01 09:00:00.992835",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Material Request Item",
|
||||
|
@ -139,7 +139,7 @@ def get_items_with_location_and_quantity(item_doc, item_location_map):
|
||||
item_location_map[item_doc.item_code] = available_locations
|
||||
return locations
|
||||
|
||||
def get_available_item_locations(item_code, from_warehouses, required_qty, company):
|
||||
def get_available_item_locations(item_code, from_warehouses, required_qty, company, ignore_validation=False):
|
||||
locations = []
|
||||
if frappe.get_cached_value('Item', item_code, 'has_serial_no'):
|
||||
locations = get_available_item_locations_for_serialized_item(item_code, from_warehouses, required_qty, company)
|
||||
@ -152,7 +152,7 @@ def get_available_item_locations(item_code, from_warehouses, required_qty, compa
|
||||
|
||||
remaining_qty = required_qty - total_qty_available
|
||||
|
||||
if remaining_qty > 0:
|
||||
if remaining_qty > 0 and not ignore_validation:
|
||||
frappe.msgprint(_('{0} units of {1} is not available.')
|
||||
.format(remaining_qty, frappe.get_desk_link('Item', item_code)))
|
||||
|
||||
|
@ -1053,9 +1053,9 @@ class StockEntry(StockController):
|
||||
fields=["required_qty", "consumed_qty"]
|
||||
)
|
||||
|
||||
req_qty = flt(req_items[0].required_qty)
|
||||
req_qty = flt(req_items[0].required_qty) if req_items else flt(4)
|
||||
req_qty_each = flt(req_qty / manufacturing_qty)
|
||||
consumed_qty = flt(req_items[0].consumed_qty)
|
||||
consumed_qty = flt(req_items[0].consumed_qty) if req_items else 0
|
||||
|
||||
if trans_qty and manufacturing_qty > (produced_qty + flt(self.fg_completed_qty)):
|
||||
if qty >= req_qty:
|
||||
|
@ -77,7 +77,11 @@ def get_item_details(args, doc=None, for_validate=False, overwrite_warehouse=Tru
|
||||
if args.customer and cint(args.is_pos):
|
||||
out.update(get_pos_profile_item_details(args.company, args))
|
||||
|
||||
if out.get("warehouse"):
|
||||
if (args.get("doctype") == "Material Request" and
|
||||
args.get("material_request_type") == "Material Transfer"):
|
||||
out.update(get_bin_details(args.item_code, args.get("from_warehouse")))
|
||||
|
||||
elif out.get("warehouse"):
|
||||
out.update(get_bin_details(args.item_code, out.warehouse))
|
||||
|
||||
# update args with out, if key or value not exists
|
||||
|
Loading…
x
Reference in New Issue
Block a user