Merge pull request #41354 from frappe/version-14-hotfix

chore: release v14
This commit is contained in:
ruthra kumar
2024-05-09 10:58:39 +05:30
committed by GitHub
9 changed files with 60 additions and 16 deletions

View File

@@ -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")

View File

@@ -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,

View File

@@ -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
}
}

View File

@@ -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

View File

@@ -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");
},

View File

@@ -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
}
}

View File

@@ -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"))

View File

@@ -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",
]

View File

@@ -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