Merge pull request #38316 from frappe/mergify/bp/version-15-hotfix/pr-38269
fix: skip fixed assets in product bundle (backport #38269)
This commit is contained in:
commit
64d9c5d61c
@ -556,7 +556,7 @@ def get_stock_availability(item_code, warehouse):
|
|||||||
return bin_qty - pos_sales_qty, is_stock_item
|
return bin_qty - pos_sales_qty, is_stock_item
|
||||||
else:
|
else:
|
||||||
is_stock_item = True
|
is_stock_item = True
|
||||||
if frappe.db.exists("Product Bundle", item_code):
|
if frappe.db.exists("Product Bundle", {"name": item_code, "disabled": 0}):
|
||||||
return get_bundle_availability(item_code, warehouse), is_stock_item
|
return get_bundle_availability(item_code, warehouse), is_stock_item
|
||||||
else:
|
else:
|
||||||
is_stock_item = False
|
is_stock_item = False
|
||||||
|
@ -350,11 +350,12 @@ class SellingController(StockController):
|
|||||||
return il
|
return il
|
||||||
|
|
||||||
def has_product_bundle(self, item_code):
|
def has_product_bundle(self, item_code):
|
||||||
return frappe.db.sql(
|
product_bundle = frappe.qb.DocType("Product Bundle")
|
||||||
"""select name from `tabProduct Bundle`
|
return (
|
||||||
where new_item_code=%s and docstatus != 2""",
|
frappe.qb.from_(product_bundle)
|
||||||
item_code,
|
.select(product_bundle.name)
|
||||||
)
|
.where((product_bundle.new_item_code == item_code) & (product_bundle.disabled == 0))
|
||||||
|
).run()
|
||||||
|
|
||||||
def get_already_delivered_qty(self, current_docname, so, so_detail):
|
def get_already_delivered_qty(self, current_docname, so, so_detail):
|
||||||
delivered_via_dn = frappe.db.sql(
|
delivered_via_dn = frappe.db.sql(
|
||||||
|
@ -1,315 +1,119 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_guest_to_view": 0,
|
"allow_import": 1,
|
||||||
"allow_import": 1,
|
"creation": "2013-06-20 11:53:21",
|
||||||
"allow_rename": 0,
|
"description": "Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**. \n\nThe package **Item** will have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\".\n\nFor Example: If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Product Bundle Item.\n\nNote: BOM = Bill of Materials",
|
||||||
"beta": 0,
|
"doctype": "DocType",
|
||||||
"creation": "2013-06-20 11:53:21",
|
"engine": "InnoDB",
|
||||||
"custom": 0,
|
"field_order": [
|
||||||
"description": "Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**. \n\nThe package **Item** will have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\".\n\nFor Example: If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Product Bundle Item.\n\nNote: BOM = Bill of Materials",
|
"basic_section",
|
||||||
"docstatus": 0,
|
"new_item_code",
|
||||||
"doctype": "DocType",
|
"description",
|
||||||
"document_type": "",
|
"column_break_eonk",
|
||||||
"editable_grid": 0,
|
"disabled",
|
||||||
|
"item_section",
|
||||||
|
"items",
|
||||||
|
"section_break_4",
|
||||||
|
"about"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "basic_section",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Section Break"
|
||||||
"bold": 0,
|
},
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "basic_section",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "new_item_code",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Link",
|
||||||
"bold": 0,
|
"in_global_search": 1,
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"columns": 0,
|
"label": "Parent Item",
|
||||||
"description": "",
|
"no_copy": 1,
|
||||||
"fieldname": "new_item_code",
|
"oldfieldname": "new_item_code",
|
||||||
"fieldtype": "Link",
|
"oldfieldtype": "Data",
|
||||||
"hidden": 0,
|
"options": "Item",
|
||||||
"ignore_user_permissions": 0,
|
"reqd": 1
|
||||||
"ignore_xss_filter": 0,
|
},
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 1,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Parent Item",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"oldfieldname": "new_item_code",
|
|
||||||
"oldfieldtype": "Data",
|
|
||||||
"options": "Item",
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "description",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Data",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Description"
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "description",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Description",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"description": "List items that form the package.",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "item_section",
|
||||||
"bold": 0,
|
"fieldtype": "Section Break",
|
||||||
"collapsible": 0,
|
"label": "Items"
|
||||||
"columns": 0,
|
},
|
||||||
"description": "List items that form the package.",
|
|
||||||
"fieldname": "item_section",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Items",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "items",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Table",
|
||||||
"bold": 0,
|
"label": "Items",
|
||||||
"collapsible": 0,
|
"oldfieldname": "sales_bom_items",
|
||||||
"columns": 0,
|
"oldfieldtype": "Table",
|
||||||
"fieldname": "items",
|
"options": "Product Bundle Item",
|
||||||
"fieldtype": "Table",
|
"reqd": 1
|
||||||
"hidden": 0,
|
},
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Items",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"oldfieldname": "sales_bom_items",
|
|
||||||
"oldfieldtype": "Table",
|
|
||||||
"options": "Product Bundle Item",
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "section_break_4",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Section Break"
|
||||||
"bold": 0,
|
},
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_4",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "about",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "HTML",
|
||||||
"bold": 0,
|
"options": "<h3>About Product Bundle</h3>\n\n<p>Aggregate group of <b>Items</b> into another <b>Item</b>. This is useful if you are bundling a certain <b>Items</b> into a package and you maintain stock of the packed <b>Items</b> and not the aggregate <b>Item</b>.</p>\n<p>The package <b>Item</b> will have <code>Is Stock Item</code> as <b>No</b> and <code>Is Sales Item</code> as <b>Yes</b>.</p>\n<h4>Example:</h4>\n<p>If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Product Bundle Item.</p>"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
{
|
||||||
"fieldname": "about",
|
"default": "0",
|
||||||
"fieldtype": "HTML",
|
"fieldname": "disabled",
|
||||||
"hidden": 0,
|
"fieldtype": "Check",
|
||||||
"ignore_user_permissions": 0,
|
"label": "Disabled"
|
||||||
"ignore_xss_filter": 0,
|
},
|
||||||
"in_filter": 0,
|
{
|
||||||
"in_global_search": 0,
|
"fieldname": "column_break_eonk",
|
||||||
"in_list_view": 0,
|
"fieldtype": "Column Break"
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "<h3>About Product Bundle</h3>\n\n<p>Aggregate group of <b>Items</b> into another <b>Item</b>. This is useful if you are bundling a certain <b>Items</b> into a package and you maintain stock of the packed <b>Items</b> and not the aggregate <b>Item</b>.</p>\n<p>The package <b>Item</b> will have <code>Is Stock Item</code> as <b>No</b> and <code>Is Sales Item</code> as <b>Yes</b>.</p>\n<h4>Example:</h4>\n<p>If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Product Bundle Item.</p>",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"icon": "fa fa-sitemap",
|
||||||
"hide_heading": 0,
|
"idx": 1,
|
||||||
"hide_toolbar": 0,
|
"links": [],
|
||||||
"icon": "fa fa-sitemap",
|
"modified": "2023-11-22 15:20:46.805114",
|
||||||
"idx": 1,
|
"modified_by": "Administrator",
|
||||||
"image_view": 0,
|
"module": "Selling",
|
||||||
"in_create": 0,
|
"name": "Product Bundle",
|
||||||
"is_submittable": 0,
|
"owner": "Administrator",
|
||||||
"issingle": 0,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2020-09-18 17:26:09.703215",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Selling",
|
|
||||||
"name": "Product Bundle",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"create": 1,
|
||||||
"apply_user_permissions": 0,
|
"delete": 1,
|
||||||
"cancel": 0,
|
"email": 1,
|
||||||
"create": 1,
|
"print": 1,
|
||||||
"delete": 1,
|
"read": 1,
|
||||||
"email": 1,
|
"report": 1,
|
||||||
"export": 0,
|
"role": "Stock Manager",
|
||||||
"if_owner": 0,
|
"share": 1,
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Stock Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"email": 1,
|
||||||
"apply_user_permissions": 0,
|
"print": 1,
|
||||||
"cancel": 0,
|
"read": 1,
|
||||||
"create": 0,
|
"report": 1,
|
||||||
"delete": 0,
|
"role": "Stock User"
|
||||||
"email": 1,
|
},
|
||||||
"export": 0,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Stock User",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 0,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"create": 1,
|
||||||
"apply_user_permissions": 0,
|
"delete": 1,
|
||||||
"cancel": 0,
|
"email": 1,
|
||||||
"create": 1,
|
"print": 1,
|
||||||
"delete": 1,
|
"read": 1,
|
||||||
"email": 1,
|
"report": 1,
|
||||||
"export": 0,
|
"role": "Sales User",
|
||||||
"if_owner": 0,
|
"share": 1,
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Sales User",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 0,
|
"sort_field": "modified",
|
||||||
"read_only": 0,
|
"sort_order": "ASC",
|
||||||
"read_only_onload": 0,
|
"states": []
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_order": "ASC",
|
|
||||||
"track_changes": 0,
|
|
||||||
"track_seen": 0
|
|
||||||
}
|
}
|
@ -59,10 +59,12 @@ class ProductBundle(Document):
|
|||||||
"""Validates, main Item is not a stock item"""
|
"""Validates, main Item is not a stock item"""
|
||||||
if frappe.db.get_value("Item", self.new_item_code, "is_stock_item"):
|
if frappe.db.get_value("Item", self.new_item_code, "is_stock_item"):
|
||||||
frappe.throw(_("Parent Item {0} must not be a Stock Item").format(self.new_item_code))
|
frappe.throw(_("Parent Item {0} must not be a Stock Item").format(self.new_item_code))
|
||||||
|
if frappe.db.get_value("Item", self.new_item_code, "is_fixed_asset"):
|
||||||
|
frappe.throw(_("Parent Item {0} must not be a Fixed Asset").format(self.new_item_code))
|
||||||
|
|
||||||
def validate_child_items(self):
|
def validate_child_items(self):
|
||||||
for item in self.items:
|
for item in self.items:
|
||||||
if frappe.db.exists("Product Bundle", item.item_code):
|
if frappe.db.exists("Product Bundle", {"name": item.item_code, "disabled": 0}):
|
||||||
frappe.throw(
|
frappe.throw(
|
||||||
_(
|
_(
|
||||||
"Row #{0}: Child Item should not be a Product Bundle. Please remove Item {1} and Save"
|
"Row #{0}: Child Item should not be a Product Bundle. Please remove Item {1} and Save"
|
||||||
@ -73,12 +75,17 @@ class ProductBundle(Document):
|
|||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@frappe.validate_and_sanitize_search_inputs
|
@frappe.validate_and_sanitize_search_inputs
|
||||||
def get_new_item_code(doctype, txt, searchfield, start, page_len, filters):
|
def get_new_item_code(doctype, txt, searchfield, start, page_len, filters):
|
||||||
from erpnext.controllers.queries import get_match_cond
|
product_bundles = frappe.db.get_list("Product Bundle", {"disabled": 0}, pluck="name")
|
||||||
|
item = frappe.qb.DocType("Item")
|
||||||
return frappe.db.sql(
|
return (
|
||||||
"""select name, item_name, description from tabItem
|
frappe.qb.from_(item)
|
||||||
where is_stock_item=0 and name not in (select name from `tabProduct Bundle`)
|
.select("*")
|
||||||
and %s like %s %s limit %s offset %s"""
|
.where(
|
||||||
% (searchfield, "%s", get_match_cond(doctype), "%s", "%s"),
|
(item.is_stock_item == 0)
|
||||||
("%%%s%%" % txt, page_len, start),
|
& (item.is_fixed_asset == 0)
|
||||||
)
|
& (item.name.notin(product_bundles))
|
||||||
|
& (item[searchfield].like(f"%{txt}%"))
|
||||||
|
)
|
||||||
|
.limit(page_len)
|
||||||
|
.offset(start)
|
||||||
|
).run()
|
||||||
|
@ -688,7 +688,9 @@ def make_material_request(source_name, target_doc=None):
|
|||||||
"Sales Order Item": {
|
"Sales Order Item": {
|
||||||
"doctype": "Material Request Item",
|
"doctype": "Material Request Item",
|
||||||
"field_map": {"name": "sales_order_item", "parent": "sales_order"},
|
"field_map": {"name": "sales_order_item", "parent": "sales_order"},
|
||||||
"condition": lambda item: not frappe.db.exists("Product Bundle", item.item_code)
|
"condition": lambda item: not frappe.db.exists(
|
||||||
|
"Product Bundle", {"name": item.item_code, "disabled": 0}
|
||||||
|
)
|
||||||
and get_remaining_qty(item) > 0,
|
and get_remaining_qty(item) > 0,
|
||||||
"postprocess": update_item,
|
"postprocess": update_item,
|
||||||
},
|
},
|
||||||
@ -1309,7 +1311,7 @@ def set_delivery_date(items, sales_order):
|
|||||||
|
|
||||||
|
|
||||||
def is_product_bundle(item_code):
|
def is_product_bundle(item_code):
|
||||||
return frappe.db.exists("Product Bundle", item_code)
|
return frappe.db.exists("Product Bundle", {"name": item_code, "disabled": 0})
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@ -1521,7 +1523,7 @@ def get_work_order_items(sales_order, for_raw_material_request=0):
|
|||||||
product_bundle_parents = [
|
product_bundle_parents = [
|
||||||
pb.new_item_code
|
pb.new_item_code
|
||||||
for pb in frappe.get_all(
|
for pb in frappe.get_all(
|
||||||
"Product Bundle", {"new_item_code": ["in", item_codes]}, ["new_item_code"]
|
"Product Bundle", {"new_item_code": ["in", item_codes], "disabled": 0}, ["new_item_code"]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -615,7 +615,7 @@ class DeliveryNote(SellingController):
|
|||||||
items_list = [item.item_code for item in self.items]
|
items_list = [item.item_code for item in self.items]
|
||||||
return frappe.db.get_all(
|
return frappe.db.get_all(
|
||||||
"Product Bundle",
|
"Product Bundle",
|
||||||
filters={"new_item_code": ["in", items_list]},
|
filters={"new_item_code": ["in", items_list], "disabled": 0},
|
||||||
pluck="name",
|
pluck="name",
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -938,7 +938,7 @@ def make_packing_slip(source_name, target_doc=None):
|
|||||||
},
|
},
|
||||||
"postprocess": update_item,
|
"postprocess": update_item,
|
||||||
"condition": lambda item: (
|
"condition": lambda item: (
|
||||||
not frappe.db.exists("Product Bundle", {"new_item_code": item.item_code})
|
not frappe.db.exists("Product Bundle", {"new_item_code": item.item_code, "disabled": 0})
|
||||||
and flt(item.packed_qty) < flt(item.qty)
|
and flt(item.packed_qty) < flt(item.qty)
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -512,8 +512,12 @@ class Item(Document):
|
|||||||
|
|
||||||
def validate_duplicate_product_bundles_before_merge(self, old_name, new_name):
|
def validate_duplicate_product_bundles_before_merge(self, old_name, new_name):
|
||||||
"Block merge if both old and new items have product bundles."
|
"Block merge if both old and new items have product bundles."
|
||||||
old_bundle = frappe.get_value("Product Bundle", filters={"new_item_code": old_name})
|
old_bundle = frappe.get_value(
|
||||||
new_bundle = frappe.get_value("Product Bundle", filters={"new_item_code": new_name})
|
"Product Bundle", filters={"new_item_code": old_name, "disabled": 0}
|
||||||
|
)
|
||||||
|
new_bundle = frappe.get_value(
|
||||||
|
"Product Bundle", filters={"new_item_code": new_name, "disabled": 0}
|
||||||
|
)
|
||||||
|
|
||||||
if old_bundle and new_bundle:
|
if old_bundle and new_bundle:
|
||||||
bundle_link = get_link_to_form("Product Bundle", old_bundle)
|
bundle_link = get_link_to_form("Product Bundle", old_bundle)
|
||||||
|
@ -55,7 +55,7 @@ def make_packing_list(doc):
|
|||||||
|
|
||||||
|
|
||||||
def is_product_bundle(item_code: str) -> bool:
|
def is_product_bundle(item_code: str) -> bool:
|
||||||
return bool(frappe.db.exists("Product Bundle", {"new_item_code": item_code}))
|
return bool(frappe.db.exists("Product Bundle", {"new_item_code": item_code, "disabled": 0}))
|
||||||
|
|
||||||
|
|
||||||
def get_indexed_packed_items_table(doc):
|
def get_indexed_packed_items_table(doc):
|
||||||
@ -111,7 +111,7 @@ def get_product_bundle_items(item_code):
|
|||||||
product_bundle_item.uom,
|
product_bundle_item.uom,
|
||||||
product_bundle_item.description,
|
product_bundle_item.description,
|
||||||
)
|
)
|
||||||
.where(product_bundle.new_item_code == item_code)
|
.where((product_bundle.new_item_code == item_code) & (product_bundle.disabled == 0))
|
||||||
.orderby(product_bundle_item.idx)
|
.orderby(product_bundle_item.idx)
|
||||||
)
|
)
|
||||||
return query.run(as_dict=True)
|
return query.run(as_dict=True)
|
||||||
|
@ -368,7 +368,9 @@ class PickList(Document):
|
|||||||
frappe.throw("Row #{0}: Item Code is Mandatory".format(item.idx))
|
frappe.throw("Row #{0}: Item Code is Mandatory".format(item.idx))
|
||||||
if not cint(
|
if not cint(
|
||||||
frappe.get_cached_value("Item", item.item_code, "is_stock_item")
|
frappe.get_cached_value("Item", item.item_code, "is_stock_item")
|
||||||
) and not frappe.db.exists("Product Bundle", {"new_item_code": item.item_code}):
|
) and not frappe.db.exists(
|
||||||
|
"Product Bundle", {"new_item_code": item.item_code, "disabled": 0}
|
||||||
|
):
|
||||||
continue
|
continue
|
||||||
item_code = item.item_code
|
item_code = item.item_code
|
||||||
reference = item.sales_order_item or item.material_request_item
|
reference = item.sales_order_item or item.material_request_item
|
||||||
@ -507,7 +509,9 @@ class PickList(Document):
|
|||||||
# bundle_item_code: Dict[component, qty]
|
# bundle_item_code: Dict[component, qty]
|
||||||
product_bundle_qty_map = {}
|
product_bundle_qty_map = {}
|
||||||
for bundle_item_code in bundles:
|
for bundle_item_code in bundles:
|
||||||
bundle = frappe.get_last_doc("Product Bundle", {"new_item_code": bundle_item_code})
|
bundle = frappe.get_last_doc(
|
||||||
|
"Product Bundle", {"new_item_code": bundle_item_code, "disabled": 0}
|
||||||
|
)
|
||||||
product_bundle_qty_map[bundle_item_code] = {item.item_code: item.qty for item in bundle.items}
|
product_bundle_qty_map[bundle_item_code] = {item.item_code: item.qty for item in bundle.items}
|
||||||
return product_bundle_qty_map
|
return product_bundle_qty_map
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ def remove_standard_fields(details):
|
|||||||
|
|
||||||
|
|
||||||
def set_valuation_rate(out, args):
|
def set_valuation_rate(out, args):
|
||||||
if frappe.db.exists("Product Bundle", args.item_code, cache=True):
|
if frappe.db.exists("Product Bundle", {"name": args.item_code, "disabled": 0}, cache=True):
|
||||||
valuation_rate = 0.0
|
valuation_rate = 0.0
|
||||||
bundled_items = frappe.get_doc("Product Bundle", args.item_code)
|
bundled_items = frappe.get_doc("Product Bundle", args.item_code)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user