Skip to content

Commit

Permalink
Merge pull request #44640 from frappe/version-15-hotfix
Browse files Browse the repository at this point in the history
chore: release v15
  • Loading branch information
ruthra-kumar authored Dec 12, 2024
2 parents 925eb44 + 33273fa commit 911ec37
Show file tree
Hide file tree
Showing 55 changed files with 574 additions and 166 deletions.
18 changes: 11 additions & 7 deletions erpnext/accounts/doctype/bank_transaction/bank_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,13 +208,17 @@ def auto_set_party(self):
if self.party_type and self.party:
return

result = AutoMatchParty(
bank_party_account_number=self.bank_party_account_number,
bank_party_iban=self.bank_party_iban,
bank_party_name=self.bank_party_name,
description=self.description,
deposit=self.deposit,
).match()
result = None
try:
result = AutoMatchParty(
bank_party_account_number=self.bank_party_account_number,
bank_party_iban=self.bank_party_iban,
bank_party_name=self.bank_party_name,
description=self.description,
deposit=self.deposit,
).match()
except Exception:
frappe.log_error(title=_("Error in party matching for Bank Transaction {0}").format(self.name))

if not result:
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,7 @@ def get_nonreconciled_payment_entries(self):
self.add_payment_entries(non_reconciled_payments)

def get_payment_entries(self):
if self.default_advance_account:
party_account = [self.receivable_payable_account, self.default_advance_account]
else:
party_account = [self.receivable_payable_account]
party_account = [self.receivable_payable_account]

order_doctype = "Sales Order" if self.party_type == "Customer" else "Purchase Order"
condition = frappe._dict(
Expand Down Expand Up @@ -187,6 +184,7 @@ def get_payment_entries(self):
self.party,
party_account,
order_doctype,
default_advance_account=self.default_advance_account,
against_all_orders=True,
limit=self.payment_limit,
condition=condition,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const INDICATORS = {
"Partially Paid": "orange",
Cancelled: "red",
Draft: "gray",
Draft: "red",
Failed: "red",
Initiated: "green",
Paid: "blue",
Expand Down
13 changes: 11 additions & 2 deletions erpnext/accounts/doctype/pricing_rule/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -651,8 +651,17 @@ def get_product_discount_rule(pricing_rule, item_details, args=None, doc=None):

qty = pricing_rule.free_qty or 1
if pricing_rule.is_recursive:
transaction_qty = (args.get("qty") if args else doc.total_qty) - pricing_rule.apply_recursion_over
if transaction_qty:
transaction_qty = sum(
[
row.qty
for row in doc.items
if not row.is_free_item
and row.item_code == args.item_code
and row.pricing_rules == args.pricing_rules
]
)
transaction_qty = transaction_qty - pricing_rule.apply_recursion_over
if transaction_qty and transaction_qty > 0:
qty = flt(transaction_qty) * qty / pricing_rule.recurse_for
if pricing_rule.round_free_qty:
qty = (flt(transaction_qty) // pricing_rule.recurse_for) * (pricing_rule.free_qty or 1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ frappe.listview_settings["Sales Invoice"] = {
],
get_indicator: function (doc) {
const status_colors = {
Draft: "grey",
Draft: "red",
Unpaid: "orange",
Paid: "green",
Return: "gray",
Expand Down
14 changes: 8 additions & 6 deletions erpnext/accounts/report/general_ledger/general_ledger.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@ def execute(filters=None):
if filters.get("party"):
filters.party = frappe.parse_json(filters.get("party"))

if filters.get("voucher_no") and not filters.get("group_by"):
filters.group_by = "Group by Voucher (Consolidated)"

validate_filters(filters, account_details)

validate_party(filters)
Expand Down Expand Up @@ -373,16 +370,21 @@ def get_data_with_opening_closing(filters, account_details, accounting_dimension
if acc_dict.entries:
# opening
data.append({"debit_in_transaction_currency": None, "credit_in_transaction_currency": None})
if filters.get("group_by") != "Group by Voucher":
if (not filters.get("group_by") and not filters.get("voucher_no")) or (
filters.get("group_by") and filters.get("group_by") != "Group by Voucher"
):
data.append(acc_dict.totals.opening)

data += acc_dict.entries

# totals
data.append(acc_dict.totals.total)
if filters.get("group_by") or not filters.voucher_no:
data.append(acc_dict.totals.total)

# closing
if filters.get("group_by") != "Group by Voucher":
if (not filters.get("group_by") and not filters.get("voucher_no")) or (
filters.get("group_by") and filters.get("group_by") != "Group by Voucher"
):
data.append(acc_dict.totals.closing)

data.append({"debit_in_transaction_currency": None, "credit_in_transaction_currency": None})
Expand Down
2 changes: 1 addition & 1 deletion erpnext/assets/doctype/asset/asset.js
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ frappe.ui.form.on("Asset", {
}

frm.dashboard.render_graph({
title: "Asset Value",
title: __("Asset Value"),
data: {
labels: x_intervals,
datasets: [
Expand Down
8 changes: 7 additions & 1 deletion erpnext/assets/doctype/asset/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,9 @@ def set_depreciation_rate(self):
)

def validate_asset_finance_books(self, row):
row.expected_value_after_useful_life = flt(
row.expected_value_after_useful_life, self.precision("gross_purchase_amount")
)
if flt(row.expected_value_after_useful_life) >= flt(self.gross_purchase_amount):
frappe.throw(
_("Row {0}: Expected Value After Useful Life must be less than Gross Purchase Amount").format(
Expand All @@ -430,7 +433,10 @@ def validate_asset_finance_books(self, row):
self.opening_accumulated_depreciation = 0
self.opening_number_of_booked_depreciations = 0
else:
depreciable_amount = flt(self.gross_purchase_amount) - flt(row.expected_value_after_useful_life)
depreciable_amount = flt(
flt(self.gross_purchase_amount) - flt(row.expected_value_after_useful_life),
self.precision("gross_purchase_amount"),
)
if flt(self.opening_accumulated_depreciation) > depreciable_amount:
frappe.throw(
_("Opening Accumulated Depreciation must be less than or equal to {0}").format(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ def prepare_data(data, filters):


def prepare_chart_data(pending, completed):
labels = ["Amount to Bill", "Billed Amount"]
labels = [_("Amount to Bill"), _("Billed Amount")]

return {
"data": {"labels": labels, "datasets": [{"values": [pending, completed]}]},
Expand Down
26 changes: 19 additions & 7 deletions erpnext/controllers/accounts_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -2916,6 +2916,7 @@ def get_advance_payment_entries(
party_account,
order_doctype,
order_list=None,
default_advance_account=None,
include_unallocated=True,
against_all_orders=False,
limit=None,
Expand All @@ -2929,6 +2930,7 @@ def get_advance_payment_entries(
party_type,
party,
party_account,
default_advance_account,
limit,
condition,
)
Expand All @@ -2952,6 +2954,7 @@ def get_advance_payment_entries(
party_type,
party,
party_account,
default_advance_account,
limit,
condition,
)
Expand All @@ -2967,6 +2970,7 @@ def get_common_query(
party_type,
party,
party_account,
default_advance_account,
limit,
condition,
):
Expand All @@ -2988,14 +2992,22 @@ def get_common_query(
.where(payment_entry.docstatus == 1)
)

if payment_type == "Receive":
q = q.select((payment_entry.paid_from_account_currency).as_("currency"))
q = q.select(payment_entry.paid_from)
q = q.where(payment_entry.paid_from.isin(party_account))
field = "paid_from" if payment_type == "Receive" else "paid_to"

q = q.select((payment_entry[f"{field}_account_currency"]).as_("currency"))
q = q.select(payment_entry[field])
account_condition = payment_entry[field].isin(party_account)
if default_advance_account:
q = q.where(
account_condition
| (
(payment_entry[field] == default_advance_account)
& (payment_entry.book_advance_payments_in_separate_party_account == 1)
)
)

else:
q = q.select((payment_entry.paid_to_account_currency).as_("currency"))
q = q.select(payment_entry.paid_to)
q = q.where(payment_entry.paid_to.isin(party_account))
q = q.where(account_condition)

if payment_type == "Receive":
q = q.select((payment_entry.source_exchange_rate).as_("exchange_rate"))
Expand Down
7 changes: 7 additions & 0 deletions erpnext/manufacturing/doctype/bom/bom.js
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,13 @@ frappe.ui.form.on("BOM", {
cur_dialog.refresh();
},
});

fields.push({
fieldtype: "Check",
label: __("Use Multi-Level BOM"),
fieldname: "use_multi_level_bom",
default: frm.doc?.__onload.use_multi_level_bom,
});
}

var has_template_rm = frm.doc.items.filter((d) => d.has_variants === 1) || [];
Expand Down
35 changes: 35 additions & 0 deletions erpnext/manufacturing/doctype/bom/bom.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,23 @@ def get_index_for_bom(self, existing_boms):

return index

def onload(self):
super().onload()

self.set_onload_for_muulti_level_bom()

def set_onload_for_muulti_level_bom(self):
use_multi_level_bom = frappe.db.get_value(
"Property Setter",
{"field_name": "use_multi_level_bom", "doc_type": "Work Order", "property": "default"},
"value",
)

if use_multi_level_bom is None:
use_multi_level_bom = 1

self.set_onload("use_multi_level_bom", cint(use_multi_level_bom))

@staticmethod
def get_next_version_index(existing_boms: list[str]) -> int:
# split by "/" and "-"
Expand Down Expand Up @@ -259,6 +276,24 @@ def validate(self):
self.update_cost(update_parent=False, from_child_bom=True, update_hour_rate=False, save=False)
self.set_process_loss_qty()
self.validate_scrap_items()
self.set_default_uom()

def set_default_uom(self):
if not self.get("items"):
return

item_wise_uom = frappe._dict(
frappe.get_all(
"Item",
filters={"name": ("in", [item.item_code for item in self.items])},
fields=["name", "stock_uom"],
as_list=1,
)
)

for row in self.get("items"):
if row.stock_uom != item_wise_uom.get(row.item_code):
row.stock_uom = item_wise_uom.get(row.item_code)

def get_context(self, context):
context.parents = [{"name": "boms", "title": _("All BOMs")}]
Expand Down
20 changes: 20 additions & 0 deletions erpnext/manufacturing/doctype/bom/test_bom.py
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,26 @@ def test_do_not_include_manufacturing_and_fixed_items(self):
self.assertTrue("_Test RM Item 2 Fixed Asset Item" not in items)
self.assertTrue("_Test RM Item 3 Manufacture Item" in items)

def test_bom_raw_materials_stock_uom(self):
rm_item = make_item(
properties={"is_stock_item": 1, "valuation_rate": 1000.0, "stock_uom": "Nos"}
).name
fg_item = make_item(properties={"is_stock_item": 1}).name

from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom

bom = make_bom(item=fg_item, raw_materials=[rm_item], do_not_submit=True)
for row in bom.items:
self.assertEqual(row.stock_uom, "Nos")

frappe.db.set_value("Item", rm_item, "stock_uom", "Kg")

bom.items[0].qty = 2
bom.save()

for row in bom.items:
self.assertEqual(row.stock_uom, "Kg")


def get_default_bom(item_code="_Test FG Item 2"):
return frappe.db.get_value("BOM", {"item": item_code, "is_active": 1, "is_default": 1})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@
"depends_on": "eval:!doc.__islocal",
"fieldname": "download_materials_required",
"fieldtype": "Button",
"label": "Download Materials Request Plan"
"label": "Download Required Materials"
},
{
"fieldname": "get_items_for_mr",
Expand Down Expand Up @@ -398,7 +398,7 @@
"collapsible": 1,
"fieldname": "download_materials_request_plan_section_section",
"fieldtype": "Section Break",
"label": "Download Materials Request Plan Section"
"label": "Preview Required Materials"
},
{
"default": "0",
Expand Down Expand Up @@ -439,7 +439,7 @@
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2024-02-27 13:34:20.692211",
"modified": "2024-12-04 11:55:03.108971",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Production Plan",
Expand All @@ -463,4 +463,4 @@
"sort_field": "modified",
"sort_order": "ASC",
"states": []
}
}
Loading

0 comments on commit 911ec37

Please sign in to comment.