diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py index 6f600cc08e3bbe20138e25d01c20a42217ab4d70..f375aebcde6d4235ff8ed2592264719e98b8c82c 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.py +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py @@ -550,6 +550,7 @@ class ProductionPlan(Document): self.db_set("status", self.status) def on_submit(self): + self.check_production_items() self.update_bin_qty() self.update_sales_order() @@ -734,6 +735,7 @@ class ProductionPlan(Document): if self.sub_assembly_items: item["use_multi_level_bom"] = 0 + self.check_production_items() set_default_warehouses(item, default_warehouses) work_order = self.create_work_order(item) if work_order: @@ -1099,6 +1101,13 @@ class ProductionPlan(Document): all_work_orders_completed = all(s == "Completed" for s in wo_status) return all_work_orders_completed + def check_production_items(self): + items_data = self.get_production_items() + row=0 + for key, item in items_data.items(): + row += 1 + if (item["material_request"] is None and self.get_items_from=="Material Request"): + frappe.throw(_("Row #{0} : This article is not related to a material request").format(row)) @frappe.whitelist() def download_raw_materials(doc, warehouses=None): diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py index cfe62b16b119414377b8da48076e6965238b0864..91a4cf1bd16f8f9512ba33214c7447b93b8366a8 100644 --- a/erpnext/setup/install.py +++ b/erpnext/setup/install.py @@ -97,7 +97,7 @@ def set_single_defaults(): pass setup_currency_exchange() - set_venue_settings_defaults() +# set_venue_settings_defaults() def setup_currency_exchange(): diff --git a/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.js b/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.js index 8d46b14a1774eb6a4fa0b97ea6fc7a29fc59eaab..ee9c819ebd01494a0e3d350cf7db881317093f9e 100644 --- a/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.js +++ b/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.js @@ -16,17 +16,53 @@ frappe.query_reports["Itemwise Recommended Reorder Level"] = { default: frappe.datetime.get_today(), }, { - fieldname: "item_group", - label: __("Item Group"), - fieldtype: "Link", - options: "Item Group", - reqd: 1, + "fieldname":"brand", + "label": __("Brand"), + "fieldtype": "Link", + "options": "Brand" }, { - fieldname: "brand", - label: __("Brand"), - fieldtype: "Link", - options: "Brand", + "fieldname":"item_group", + "label": __("Item Group"), + "fieldtype": "MultiSelectList", + "width": "100", + get_data: function(txt) { + return frappe.db.get_link_options('Item Group', txt); + }, + + on_change: function(report){ + let selectedGroups = frappe.query_report.get_filter_value("item_group"); + let selectedItems = frappe.query_report.get_filter_value("item_name"); + + frappe.db.get_list("Item", { + filters: { + item_group:["in", selectedGroups], + name:["in", selectedItems] + }, + fields:["name"] + }).then((items) => { + let itemNames = items.map(item=>item.name); + frappe.query_report.set_filter_value("item_name", itemNames); + }) + + report.refresh(); + } + }, + { + "fieldname":"item_name", + "label": __("Items"), + "fieldtype": "MultiSelectList", + "width": "100", + get_data: function(txt) { + let itGro = frappe.query_report.get_filter_value("item_group"); + if (itGro==""){ + return frappe.db.get_link_options('Item', txt) + } else { + return frappe.db.get_link_options('Item', txt, { + "item_group":["in", itGro] + }); + } + } }, - ], -}; + ] +} \ No newline at end of file diff --git a/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py b/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py index c4358b809fcce9a1c6609148d3384fe488436f77..cad2c089b4bd80a486b227b4516ae9a56ef37130 100644 --- a/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py +++ b/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py @@ -1,6 +1,7 @@ # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: GNU General Public License v3. See license.txt +from erpnext.stock.report.stock_ledger.stock_ledger import get_item_name_condition import frappe from frappe import _ from frappe.query_builder.functions import Abs, Sum @@ -69,10 +70,13 @@ def get_columns(): def get_item_info(filters): from erpnext.stock.report.stock_ledger.stock_ledger import get_item_group_condition + from pypika import Criterion item = frappe.qb.DocType("Item") +# ig = frappe.qb.DocType("Item Group") query = ( frappe.qb.from_(item) +# .from_(ig) .select( item.name, item.item_name, @@ -82,14 +86,29 @@ def get_item_info(filters): item.safety_stock, item.lead_time_days, ) - .where((item.is_stock_item == 1) & (item.disabled == 0)) + .where( + (item.is_stock_item == 1) + & (item.disabled == 0) +# & (item.item_group == ig.name) + ) ) if brand := filters.get("brand"): query = query.where(item.brand == brand) - - if conditions := get_item_group_condition(filters.get("item_group"), item): - query = query.where(conditions) + + groups = filters.get("item_group") + conditions = [] + for group in groups: + if condition := get_item_group_condition(group, item): + conditions.append(condition) + query = query.where(Criterion.any(conditions)) + + items = filters.get("item_name") + conditions=[] + for itm in items: + if condition := get_item_name_condition(itm, item): + conditions.append(condition) + query = query.where(Criterion.any(conditions)) return query.run(as_dict=True) diff --git a/erpnext/stock/report/stock_ledger/stock_ledger.py b/erpnext/stock/report/stock_ledger/stock_ledger.py index 391395503b09e4b983216fced94bb99a97e7c3e6..77d97ebe3ef39144910d927b5d47eded77f92618 100644 --- a/erpnext/stock/report/stock_ledger/stock_ledger.py +++ b/erpnext/stock/report/stock_ledger/stock_ledger.py @@ -657,3 +657,20 @@ def check_inventory_dimension_filters_applied(filters) -> bool: return True return False + +def get_item_name_condition(selectedItem, item_table=None): + item_name_details = frappe.db.get_value("Item", selectedItem, as_dict=1) + if item_name_details: + if item_table: + itm = frappe.qb.DocType("Item") + return item_table.name.isin( + ( + frappe.qb.from_(itm) + .select(itm.name) + .where( + (selectedItem == itm.item_code) + ) + ) + ) + else: + return diff --git a/test.txt b/test.txt new file mode 100644 index 0000000000000000000000000000000000000000..632e4fe73c3da8c9018008dbda117fc6b00e3e83 --- /dev/null +++ b/test.txt @@ -0,0 +1 @@ +Bonjour