diff --git a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py index cb0c223bffa..18658e6e4a6 100644 --- a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py +++ b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py @@ -976,7 +976,7 @@ class TestPricingRule(unittest.TestCase): so.load_from_db() self.assertEqual(so.items[1].is_free_item, 1) self.assertEqual(so.items[1].item_code, "_Test Item") - self.assertEqual(so.items[1].qty, 4) + self.assertEqual(so.items[1].qty, 3) def test_apply_multiple_pricing_rules_for_discount_percentage_and_amount(self): frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule 1") diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py index ce96a3d1240..2a78bebd103 100644 --- a/erpnext/accounts/doctype/pricing_rule/utils.py +++ b/erpnext/accounts/doctype/pricing_rule/utils.py @@ -6,6 +6,7 @@ import copy import json +import math import frappe from frappe import _, bold @@ -638,7 +639,7 @@ def get_product_discount_rule(pricing_rule, item_details, args=None, doc=None): if transaction_qty: qty = flt(transaction_qty) * qty / pricing_rule.recurse_for if pricing_rule.round_free_qty: - qty = round(qty) + qty = math.floor(qty) free_item_data_args = { "item_code": free_item, diff --git a/erpnext/accounts/doctype/psoa_cost_center/psoa_cost_center.json b/erpnext/accounts/doctype/psoa_cost_center/psoa_cost_center.json index e292b60d68d..ef4a55861fb 100644 --- a/erpnext/accounts/doctype/psoa_cost_center/psoa_cost_center.json +++ b/erpnext/accounts/doctype/psoa_cost_center/psoa_cost_center.json @@ -11,13 +11,15 @@ { "fieldname": "cost_center_name", "fieldtype": "Link", + "in_list_view": 1, "label": "Cost Center", - "options": "Cost Center" + "options": "Cost Center", + "reqd": 1 } ], "istable": 1, "links": [], - "modified": "2020-08-03 16:56:45.744905", + "modified": "2024-05-03 17:16:51.666461", "modified_by": "Administrator", "module": "Accounts", "name": "PSOA Cost Center", @@ -27,4 +29,4 @@ "sort_field": "modified", "sort_order": "DESC", "track_changes": 1 -} \ No newline at end of file +} diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index f4d4772901c..5d656bb0a79 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -717,20 +717,22 @@ class GrossProfitGenerator: frappe.qb.from_(purchase_invoice_item) .inner_join(purchase_invoice) .on(purchase_invoice.name == purchase_invoice_item.parent) - .select(purchase_invoice_item.base_rate / purchase_invoice_item.conversion_factor) + .select( + purchase_invoice.name, + purchase_invoice_item.base_rate / purchase_invoice_item.conversion_factor, + ) .where(purchase_invoice.docstatus == 1) .where(purchase_invoice.posting_date <= self.filters.to_date) .where(purchase_invoice_item.item_code == item_code) ) if row.project: - query.where(purchase_invoice_item.project == row.project) + query = query.where(purchase_invoice_item.project == row.project) if row.cost_center: - query.where(purchase_invoice_item.cost_center == row.cost_center) + query = query.where(purchase_invoice_item.cost_center == row.cost_center) - query.orderby(purchase_invoice.posting_date, order=frappe.qb.desc) - query.limit(1) + query = query.orderby(purchase_invoice.posting_date, order=frappe.qb.desc).limit(1) last_purchase_rate = query.run() return flt(last_purchase_rate[0][0]) if last_purchase_rate else 0 diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js index 29d41fe7625..a7972790b1a 100644 --- a/erpnext/stock/doctype/item/item.js +++ b/erpnext/stock/doctype/item/item.js @@ -15,6 +15,9 @@ frappe.ui.form.on("Item", { frm.add_fetch("tax_type", "tax_rate", "tax_rate"); frm.make_methods = { + Quotation: () => { + open_form(frm, "Quotation", "Quotation Item", "items"); + }, "Sales Order": () => { open_form(frm, "Sales Order", "Sales Order Item", "items"); }, diff --git a/erpnext/stock/doctype/pick_list_item/pick_list_item.json b/erpnext/stock/doctype/pick_list_item/pick_list_item.json index 883cdd19e7c..bad79a02907 100644 --- a/erpnext/stock/doctype/pick_list_item/pick_list_item.json +++ b/erpnext/stock/doctype/pick_list_item/pick_list_item.json @@ -126,7 +126,8 @@ "in_list_view": 1, "label": "Item", "options": "Item", - "reqd": 1 + "reqd": 1, + "search_index": 1 }, { "fieldname": "quantity_section", @@ -193,7 +194,7 @@ ], "istable": 1, "links": [], - "modified": "2023-07-25 11:56:23.361867", + "modified": "2024-05-07 15:32:42.905446", "modified_by": "Administrator", "module": "Stock", "name": "Pick List Item", @@ -204,4 +205,4 @@ "sort_order": "DESC", "states": [], "track_changes": 1 -} \ No newline at end of file +} diff --git a/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py b/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py index 8e27b8c4f69..7c23e4c8f1e 100644 --- a/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py +++ b/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py @@ -29,8 +29,15 @@ def execute(filters=None): sle_count = _estimate_table_row_count("Stock Ledger Entry") - if sle_count > SLE_COUNT_LIMIT and not filters.get("item_code") and not filters.get("warehouse"): - frappe.throw(_("Please select either the Item or Warehouse filter to generate the report.")) + if ( + sle_count > SLE_COUNT_LIMIT + and not filters.get("item_code") + and not filters.get("warehouse") + and not filters.get("warehouse_type") + ): + frappe.throw( + _("Please select either the Item or Warehouse or Warehouse Type filter to generate the report.") + ) if filters.from_date > filters.to_date: frappe.throw(_("From Date must be before To Date")) diff --git a/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py b/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py index e1cce31329e..f5a059a7f61 100644 --- a/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py +++ b/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py @@ -56,13 +56,14 @@ def execute(filters=None): item_value.setdefault((item, item_map[item]["item_group"]), []) item_value[(item, item_map[item]["item_group"])].append(total_stock_value) + itemwise_brand = frappe._dict(get_itemwise_brand(items)) # sum bal_qty by item for (item, item_group), wh_balance in item_balance.items(): if not item_ageing.get(item): continue total_stock_value = sum(item_value[(item, item_group)]) - row = [item, item_map[item]["item_name"], item_group, total_stock_value] + row = [item, item_map[item]["item_name"], item_group, itemwise_brand.get(item), total_stock_value] fifo_queue = item_ageing[item]["fifo_queue"] average_age = 0.00 @@ -85,6 +86,10 @@ def execute(filters=None): return columns, data +def get_itemwise_brand(items): + return frappe.get_all("Item", filters={"name": ("in", items)}, fields=["name", "brand"], as_list=1) + + def get_columns(filters): """return columns""" @@ -92,6 +97,7 @@ def get_columns(filters): _("Item") + ":Link/Item:150", _("Item Name") + ":Link/Item:150", _("Item Group") + "::120", + _("Brand") + ":Link/Brand:120", _("Value") + ":Currency:120", _("Age") + ":Float:120", ] diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py index c0235f9b85c..aeae7c84679 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py @@ -8,6 +8,7 @@ from frappe.utils import cint, flt, getdate, nowdate import erpnext from erpnext.accounts.utils import get_account_currency from erpnext.controllers.subcontracting_controller import SubcontractingController +from erpnext.stock.utils import get_incoming_rate class SubcontractingReceipt(SubcontractingController): @@ -67,6 +68,7 @@ class SubcontractingReceipt(SubcontractingController): self.set_items_bom() self.set_items_cost_center() self.set_items_expense_account() + self.reset_rate_for_serial_batch_supplied_items() def validate(self): if ( @@ -124,6 +126,26 @@ class SubcontractingReceipt(SubcontractingController): self.calculate_supplied_items_qty_and_amount() self.calculate_items_qty_and_amount() + def reset_rate_for_serial_batch_supplied_items(self): + for item in self.supplied_items: + if item.serial_no or item.batch_no: + args = frappe._dict( + { + "item_code": item.rm_item_code, + "warehouse": self.supplier_warehouse, + "posting_date": self.posting_date, + "posting_time": self.posting_time, + "qty": flt(item.consumed_qty), + "serial_no": item.serial_no, + "batch_no": item.batch_no, + "voucher_type": self.doctype, + "voucher_no": self.name, + "company": self.company, + "allow_zero_valuation": 1, + } + ) + item.rate = get_incoming_rate(args) + def has_serial_batch_items(self): if not self.get("supplied_items"): return False