From f1a864349ebb3154b40bdde21ed881e4efb82a83 Mon Sep 17 00:00:00 2001 From: barredterra <14891507+barredterra@users.noreply.github.com> Date: Tue, 8 Apr 2025 02:28:46 +0200 Subject: [PATCH 01/13] fix: make report's "printed on" translatable (cherry picked from commit 18e9a9881ce963f3013767a238680ec3f5158297) --- .../report/accounts_receivable/accounts_receivable.html | 2 +- .../bank_reconciliation_statement.html | 2 +- erpnext/accounts/report/financial_statements.html | 2 +- erpnext/accounts/report/general_ledger/general_ledger.html | 2 +- .../supplier_quotation_comparison.html | 6 ++---- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html index 7d8d33c46b4..6ae42853ca3 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html @@ -282,4 +282,4 @@ {% } %} -

{{ __("Printed On ") }}{%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}

\ No newline at end of file +

{%= __("Printed On {0}", [frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string())]) %}

diff --git a/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.html b/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.html index eaabc90205f..fb809f2c456 100644 --- a/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.html +++ b/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.html @@ -46,4 +46,4 @@ {% } %} -

Printed On {%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}

+

{%= __("Printed On {0}", [frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string())]) %}

diff --git a/erpnext/accounts/report/financial_statements.html b/erpnext/accounts/report/financial_statements.html index 2bb09cf0dc5..3633b26c052 100644 --- a/erpnext/accounts/report/financial_statements.html +++ b/erpnext/accounts/report/financial_statements.html @@ -67,5 +67,5 @@

- Printed On {%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %} + {%= __("Printed On {0}", [frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string())]) %}

diff --git a/erpnext/accounts/report/general_ledger/general_ledger.html b/erpnext/accounts/report/general_ledger/general_ledger.html index 3c4e1a05c97..81b5c97937c 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.html +++ b/erpnext/accounts/report/general_ledger/general_ledger.html @@ -78,4 +78,4 @@ {% } %} -

Printed On {%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}

+

{%= __("Printed on {0}", [frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string())]) %}

diff --git a/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.html b/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.html index 015b31c2064..869dadb2fc1 100644 --- a/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.html +++ b/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.html @@ -124,9 +124,7 @@ -

Analysis Chart

+

{%= __("Analysis Chart") %}

- - -

Printed On {%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}

+

{%= __("Printed On {0}", [frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string())]) %}

From 056cc35379622b17e73619f2d4c40311ed805255 Mon Sep 17 00:00:00 2001 From: barredterra <14891507+barredterra@users.noreply.github.com> Date: Tue, 8 Apr 2025 15:01:21 +0200 Subject: [PATCH 02/13] fix: go for lower case "on" because we already have translations for that (cherry picked from commit 7cf83ffce72867fdf5a999c6e148516eed1db8ae) --- .../report/accounts_receivable/accounts_receivable.html | 2 +- .../bank_reconciliation_statement.html | 2 +- erpnext/accounts/report/financial_statements.html | 2 +- .../supplier_quotation_comparison.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html index 6ae42853ca3..9cae94ff8b4 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html @@ -282,4 +282,4 @@ {% } %} -

{%= __("Printed On {0}", [frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string())]) %}

+

{%= __("Printed on {0}", [frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string())]) %}

diff --git a/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.html b/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.html index fb809f2c456..422b25965f0 100644 --- a/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.html +++ b/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.html @@ -46,4 +46,4 @@ {% } %} -

{%= __("Printed On {0}", [frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string())]) %}

+

{%= __("Printed on {0}", [frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string())]) %}

diff --git a/erpnext/accounts/report/financial_statements.html b/erpnext/accounts/report/financial_statements.html index 3633b26c052..dc1d0093bce 100644 --- a/erpnext/accounts/report/financial_statements.html +++ b/erpnext/accounts/report/financial_statements.html @@ -67,5 +67,5 @@

- {%= __("Printed On {0}", [frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string())]) %} + {%= __("Printed on {0}", [frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string())]) %}

diff --git a/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.html b/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.html index 869dadb2fc1..f98dff66853 100644 --- a/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.html +++ b/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.html @@ -127,4 +127,4 @@

{%= __("Analysis Chart") %}

-

{%= __("Printed On {0}", [frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string())]) %}

+

{%= __("Printed on {0}", [frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string())]) %}

From 033fa09eb46f3bbfa8195d94b2b872cbae521723 Mon Sep 17 00:00:00 2001 From: barredterra <14891507+barredterra@users.noreply.github.com> Date: Tue, 8 Apr 2025 15:08:40 +0200 Subject: [PATCH 03/13] fix: remove redundant letter head (cherry picked from commit 7896f8a855a3cd6217e0b36a2517922c562c8080) --- .../bank_reconciliation_statement.html | 3 --- .../supplier_quotation_comparison.html | 3 --- 2 files changed, 6 deletions(-) diff --git a/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.html b/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.html index 422b25965f0..6957ab41681 100644 --- a/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.html +++ b/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.html @@ -1,6 +1,3 @@ -
- {%= frappe.boot.letter_heads[frappe.defaults.get_default("letter_head")] %} -

{%= __("Bank Reconciliation Statement") %}

{%= filters.account && (filters.account + ", "+filters.report_date) || "" %} {%= filters.company %}


diff --git a/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.html b/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.html index f98dff66853..2fb0986c7bb 100644 --- a/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.html +++ b/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.html @@ -94,9 +94,6 @@ -
- {%= frappe.boot.letter_heads[frappe.defaults.get_default("letter_head")] %} -

{%= __(report.report_name) %}

{%= filters.item %}

From 443ed5b2ce38fd301d97bb3a1c02f68d8493ba1c Mon Sep 17 00:00:00 2001 From: barredterra <14891507+barredterra@users.noreply.github.com> Date: Tue, 8 Apr 2025 15:56:48 +0200 Subject: [PATCH 04/13] chore: add missing german translation (cherry picked from commit d94ebd0c781d72c6c4e9f23499635fc0595b0c4f) --- erpnext/translations/de.csv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/translations/de.csv b/erpnext/translations/de.csv index 648fba49fe5..dc71198987d 100644 --- a/erpnext/translations/de.csv +++ b/erpnext/translations/de.csv @@ -316,7 +316,7 @@ BOM {0} does not belong to Item {1},Stückliste {0} gehört nicht zum Artikel {1 BOM {0} must be active,Stückliste {0} muss aktiv sein, BOM {0} must be submitted,Stückliste {0} muss übertragen werden, Balance,Saldo, -Balance (Dr - Cr),Balance (Dr - Cr), +Balance (Dr - Cr),Saldo (S - H), Balance ({0}),Saldo ({0}), Balance Qty,Bilanzmenge, Balance Sheet,Bilanz, @@ -4009,6 +4009,7 @@ Partially ordered,teilweise geordnete, Please select company first,Bitte wählen Sie zuerst die Firma aus, Please select patient,Bitte wählen Sie Patient, Printed On ,Gedruckt am, +Printed on {0},Gedruckt am {0}, Projected qty,Geplante Menge, Sales person,Vertriebsmitarbeiter, Serial No {0} Created,Seriennummer {0} Erstellt, From a3d4d344542c70ce62cffcee7dd0315d11d03bd2 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 9 Apr 2025 17:14:40 +0530 Subject: [PATCH 05/13] fix: serial no validation for stock reconciliation --- erpnext/stock/doctype/serial_no/serial_no.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py index 9dfd12acc2c..654f28e661c 100644 --- a/erpnext/stock/doctype/serial_no/serial_no.py +++ b/erpnext/stock/doctype/serial_no/serial_no.py @@ -279,7 +279,14 @@ def validate_serial_no(sle, item_det): _("Serial No {0} quantity {1} cannot be a fraction").format(sle.item_code, sle.actual_qty) ) - if len(serial_nos) and len(serial_nos) != abs(cint(sle.actual_qty)): + if ( + ( + (sle.voucher_type == "Stock Reconciliation" and sle.actual_qty > 0) + or sle.voucher_type != "Stock Reconciliation" + ) + and len(serial_nos) + and len(serial_nos) != abs(cint(sle.actual_qty)) + ): frappe.throw( _("{0} Serial Numbers required for Item {1}. You have provided {2}.").format( abs(sle.actual_qty), sle.item_code, len(serial_nos) From 7a74dac2c2370a22ed2cf6d31563bb407e657902 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 10 Apr 2025 09:56:08 +0530 Subject: [PATCH 06/13] perf: stock ageing report generation --- .../stock/report/stock_ageing/stock_ageing.js | 6 + .../stock/report/stock_ageing/stock_ageing.py | 110 ++++++++++++++++-- 2 files changed, 107 insertions(+), 9 deletions(-) diff --git a/erpnext/stock/report/stock_ageing/stock_ageing.js b/erpnext/stock/report/stock_ageing/stock_ageing.js index 726b507663d..f0cb1bbb372 100644 --- a/erpnext/stock/report/stock_ageing/stock_ageing.js +++ b/erpnext/stock/report/stock_ageing/stock_ageing.js @@ -81,5 +81,11 @@ frappe.query_reports["Stock Ageing"] = { fieldtype: "Check", default: 0, }, + { + fieldname: "ignore_closing_balance", + label: __("Ignore Closing Balance"), + fieldtype: "Check", + default: 0, + }, ], }; diff --git a/erpnext/stock/report/stock_ageing/stock_ageing.py b/erpnext/stock/report/stock_ageing/stock_ageing.py index ea94c15c0e8..7d63209f478 100644 --- a/erpnext/stock/report/stock_ageing/stock_ageing.py +++ b/erpnext/stock/report/stock_ageing/stock_ageing.py @@ -6,7 +6,8 @@ from operator import itemgetter import frappe from frappe import _ -from frappe.utils import cint, date_diff, flt, get_datetime +from frappe.query_builder import Order +from frappe.utils import add_days, cint, date_diff, flt, get_date_str, get_datetime, getdate from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos @@ -49,7 +50,13 @@ def format_report_data(filters: Filters, item_details: dict, to_date: str) -> li latest_age = date_diff(to_date, fifo_queue[-1][1]) range1, range2, range3, above_range3 = get_range_age(filters, fifo_queue, to_date, item_dict) - row = [details.name, details.item_name, details.description, details.item_group, details.brand] + row = [ + details.name or details.item_code, + details.item_name, + details.description, + details.item_group, + details.brand, + ] if filters.get("show_warehouse_wise_stock"): row.append(details.warehouse) @@ -217,6 +224,67 @@ class FIFOSlots: self.filters = filters self.sle = sle + def get_closing_balance(self): + if self.filters.get("ignore_closing_balance"): + return [] + + if ( + self.filters.get("item_code") + or self.filters.get("warehouse") + or self.filters.get("warehouse_type") + ): + return + + if self.sle: + return + + table = frappe.qb.DocType("Closing Stock Balance") + + query = ( + frappe.qb.from_(table) + .select(table.name, table.to_date) + .where( + (table.docstatus == 1) + & (table.company == self.filters.company) + & (table.to_date < self.filters.get("to_date")) + & (table.status == "Completed") + ) + .orderby(table.to_date, order=Order.desc) + .limit(1) + ) + + for fieldname in ["warehouse", "item_code", "item_group", "warehouse_type"]: + if self.filters.get(fieldname): + query = query.where(table[fieldname] == self.filters.get(fieldname)) + + return query.run(as_dict=True) + + def prepare_stock_ageing_from_stock_closing_balance(self): + closing_balance = self.get_closing_balance() + if not closing_balance: + return + + self.start_from = add_days(closing_balance[0].to_date, 1) + closing_data = frappe.get_doc("Closing Stock Balance", closing_balance[0].name).get_prepared_data() + stock_ledger_entries = closing_data.get("data") + + for d in stock_ledger_entries: + if isinstance(d, dict): + d = frappe._dict(d) + + d.actual_qty = d.bal_qty + key, fifo_queue, transferred_item_key = self.__init_key_stores(d) + serial_nos = d.serial_no if d.serial_no else [] + if fifo_queue and isinstance(fifo_queue[0][0], str): + d.has_serial_no = 1 + + if d.actual_qty > 0: + self.__compute_incoming_stock(d, fifo_queue, transferred_item_key, serial_nos) + else: + self.__compute_outgoing_stock(d, fifo_queue, transferred_item_key, serial_nos) + + self.__update_balances(d, key) + def generate(self) -> dict: """ Returns dict of the foll.g structure: @@ -227,6 +295,9 @@ class FIFOSlots: consumed/updated and maintained via FIFO. ** } """ + self.start_from = None + self.prepare_stock_ageing_from_stock_closing_balance() + stock_ledger_entries = self.sle _system_settings = frappe.get_cached_doc("System Settings") @@ -259,15 +330,32 @@ class FIFOSlots: return self.item_details + def format_fifo_queue(self, fifo_queue: list) -> list: + if not fifo_queue: + return [] + + fifo_queue = [[x[0], getdate(x[1])] for x in fifo_queue] + return fifo_queue + def __init_key_stores(self, row: dict) -> tuple: "Initialise keys and FIFO Queue." - key = (row.name, row.warehouse) - self.item_details.setdefault(key, {"details": row, "fifo_queue": []}) - fifo_queue = self.item_details[key]["fifo_queue"] + if not row.name: + key = (row.item_code, row.warehouse) + else: + key = (row.name, row.warehouse) - transferred_item_key = (row.voucher_no, row.name, row.warehouse) - self.transferred_item_details.setdefault(transferred_item_key, []) + if key not in self.item_details: + row.fifo_queue = self.format_fifo_queue(row.fifo_queue) + + self.item_details.setdefault(key, {"details": row, "fifo_queue": row.fifo_queue or []}) + + fifo_queue = self.item_details[key]["fifo_queue"] + transferred_item_key = None + + if row.voucher_no: + transferred_item_key = (row.voucher_no, row.name, row.warehouse) + self.transferred_item_details.setdefault(transferred_item_key, []) return key, fifo_queue, transferred_item_key @@ -351,10 +439,10 @@ class FIFOSlots: transfer_qty_to_pop = 0 def __update_balances(self, row: dict, key: tuple | str): - self.item_details[key]["qty_after_transaction"] = row.qty_after_transaction + self.item_details[key]["qty_after_transaction"] = row.qty_after_transaction or row.bal_qty if "total_qty" not in self.item_details[key]: - self.item_details[key]["total_qty"] = row.actual_qty + self.item_details[key]["total_qty"] = row.actual_qty or row.bal_qty else: self.item_details[key]["total_qty"] += row.actual_qty @@ -417,6 +505,10 @@ class FIFOSlots: ) ) + if self.start_from: + from_date = get_datetime(get_date_str(self.start_from) + " 00:00:00") + sle_query = sle_query.where(sle.posting_datetime >= from_date) + if self.filters.get("warehouse"): sle_query = self.__get_warehouse_conditions(sle, sle_query) elif self.filters.get("warehouse_type"): From 6ec33c0098ca819768925f342850e3c09a5f9699 Mon Sep 17 00:00:00 2001 From: ljain112 Date: Fri, 11 Apr 2025 15:06:03 +0530 Subject: [PATCH 07/13] fix: correct doctype in item_wise_purchase register (cherry picked from commit b8b8dce733f92acc5d77b005f3e85befe20de671) --- .../item_wise_purchase_register/item_wise_purchase_register.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py index b313ed8b173..ae822c5b413 100644 --- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py +++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py @@ -369,7 +369,7 @@ def get_items(filters, additional_table_columns): from frappe.desk.reportview import build_match_conditions query, params = query.walk() - match_conditions = build_match_conditions("Sales Invoice") + match_conditions = build_match_conditions(doctype) if match_conditions: query += " and " + match_conditions From 5844aafd1257e34a226f0c287c8868f6aeec9d69 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 14 Apr 2025 12:27:51 +0530 Subject: [PATCH 08/13] fix: revert #46900 - against_voucher filter in general ledger (cherry picked from commit adb331ef7132374ac1b00a3a39287184a435a31a) # Conflicts: # erpnext/accounts/report/general_ledger/general_ledger.py --- .../report/general_ledger/general_ledger.js | 5 +++++ .../report/general_ledger/general_ledger.py | 21 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/erpnext/accounts/report/general_ledger/general_ledger.js b/erpnext/accounts/report/general_ledger/general_ledger.js index e7d10501d87..a0160f33c92 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.js +++ b/erpnext/accounts/report/general_ledger/general_ledger.js @@ -52,6 +52,11 @@ frappe.query_reports["General Ledger"] = { frappe.query_report.set_filter_value("group_by", "Group by Voucher (Consolidated)"); }, }, + { + fieldname: "against_voucher_no", + label: __("Against Voucher No"), + fieldtype: "Data", + }, { fieldtype: "Break", }, diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py index 0a24e084942..5fbf4e0e4c5 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.py +++ b/erpnext/accounts/report/general_ledger/general_ledger.py @@ -225,6 +225,9 @@ def get_conditions(filters): if filters.get("voucher_no"): conditions.append("voucher_no=%(voucher_no)s") + if filters.get("against_voucher_no"): + conditions.append("against_voucher=%(against_voucher_no)s") + if filters.get("ignore_err"): err_journals = frappe.db.get_all( "Journal Entry", @@ -468,11 +471,21 @@ def get_accountwise_gle(filters, accounting_dimensions, gl_entries, gle_map): data[key][rev_dr_or_cr] = 0 data[key][rev_dr_or_cr + "_in_account_currency"] = 0 + if data[key].against_voucher and gle.against_voucher: + data[key].against_voucher += ", " + gle.against_voucher + from_date, to_date = getdate(filters.from_date), getdate(filters.to_date) show_opening_entries = filters.get("show_opening_entries") for gle in gl_entries: group_by_value = gle.get(group_by) +<<<<<<< HEAD +======= + gle.voucher_subtype = _(gle.voucher_subtype) + gle.against_voucher_type = _(gle.against_voucher_type) + gle.remarks = _(gle.remarks) + gle.party_type = _(gle.party_type) +>>>>>>> adb331ef71 (fix: revert #46900 - against_voucher filter in general ledger) if gle.posting_date < from_date or (cstr(gle.is_opening) == "Yes" and not show_opening_entries): if not group_by_voucher_consolidated: @@ -630,6 +643,14 @@ def get_columns(filters): columns.extend( [ + {"label": _("Against Voucher Type"), "fieldname": "against_voucher_type", "width": 100}, + { + "label": _("Against Voucher"), + "fieldname": "against_voucher", + "fieldtype": "Dynamic Link", + "options": "against_voucher_type", + "width": 100, + }, {"label": _("Supplier Invoice No"), "fieldname": "bill_no", "fieldtype": "Data", "width": 100}, ] ) From 694f158fc87895000bab3a43701138319ec1fb3d Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 14 Apr 2025 13:25:36 +0530 Subject: [PATCH 09/13] chore: resolve conflict --- erpnext/accounts/report/general_ledger/general_ledger.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py index 5fbf4e0e4c5..62806a957e3 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.py +++ b/erpnext/accounts/report/general_ledger/general_ledger.py @@ -479,13 +479,6 @@ def get_accountwise_gle(filters, accounting_dimensions, gl_entries, gle_map): for gle in gl_entries: group_by_value = gle.get(group_by) -<<<<<<< HEAD -======= - gle.voucher_subtype = _(gle.voucher_subtype) - gle.against_voucher_type = _(gle.against_voucher_type) - gle.remarks = _(gle.remarks) - gle.party_type = _(gle.party_type) ->>>>>>> adb331ef71 (fix: revert #46900 - against_voucher filter in general ledger) if gle.posting_date < from_date or (cstr(gle.is_opening) == "Yes" and not show_opening_entries): if not group_by_voucher_consolidated: From 253a0675924526811c990079eb845b7ea0fcd002 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Fri, 4 Apr 2025 13:38:45 +0530 Subject: [PATCH 10/13] fix: stock entry repack amount calculation (cherry picked from commit 544ceb93cd23045499246d2f21b1ab6419aeff44) # Conflicts: # erpnext/stock/stock_ledger.py --- .../doctype/stock_entry/test_stock_entry.py | 53 +++++++++++++++++++ erpnext/stock/stock_ledger.py | 9 ++++ 2 files changed, 62 insertions(+) diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py index bb7d944e639..53c739599ff 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -1835,6 +1835,59 @@ class TestStockEntry(FrappeTestCase): self.assertEqual(sle.stock_value_difference, 100) self.assertEqual(sle.stock_value, 100 * i) + def test_stock_entry_amount(self): + warehouse = "_Test Warehouse - _TC" + rm_item_code = "Test Stock Entry Amount 1" + make_item(rm_item_code, {"is_stock_item": 1}) + + fg_item_code = "Test Repack Stock Entry Amount 1" + make_item(fg_item_code, {"is_stock_item": 1}) + + make_stock_entry( + item_code=rm_item_code, + qty=1, + to_warehouse=warehouse, + basic_rate=200, + posting_date=nowdate(), + ) + + se = make_stock_entry( + item_code=rm_item_code, + qty=1, + purpose="Repack", + basic_rate=100, + do_not_save=True, + ) + + se.items[0].s_warehouse = warehouse + se.append( + "items", + { + "item_code": fg_item_code, + "qty": 1, + "t_warehouse": warehouse, + "uom": "Nos", + "conversion_factor": 1.0, + }, + ) + se.set_stock_entry_type() + se.submit() + + self.assertEqual(se.items[0].amount, 200) + self.assertEqual(se.items[0].basic_amount, 200) + + make_stock_entry( + item_code=rm_item_code, + qty=1, + to_warehouse=warehouse, + basic_rate=300, + posting_date=add_days(nowdate(), -1), + ) + + se.reload() + self.assertEqual(se.items[0].amount, 300) + self.assertEqual(se.items[0].basic_amount, 300) + def make_serialized_item(**args): args = frappe._dict(args) diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index 58c2fb51339..1fe77823aee 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -864,7 +864,16 @@ class update_entries_after: stock_entry.calculate_rate_and_amount(reset_outgoing_rate=False, raise_error_if_no_rate=False) stock_entry.db_update() for d in stock_entry.items: +<<<<<<< HEAD if d.name == voucher_detail_no or (not d.s_warehouse and d.t_warehouse): +======= + # Update only the row that matches the voucher_detail_no or the row containing the FG/Scrap Item. + if ( + d.name == voucher_detail_no + or (not d.s_warehouse and d.t_warehouse) + or stock_entry.purpose in ["Manufacture", "Repack"] + ): +>>>>>>> 544ceb93cd (fix: stock entry repack amount calculation) d.db_update() def update_rate_on_delivery_and_sales_return(self, sle, outgoing_rate): From 3f3fb323cfc99b616ec2ccb4292707ae9f606fed Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Mon, 14 Apr 2025 18:02:24 +0530 Subject: [PATCH 11/13] chore: fix conflicts --- erpnext/stock/stock_ledger.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index 1fe77823aee..08a8262b246 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -864,16 +864,12 @@ class update_entries_after: stock_entry.calculate_rate_and_amount(reset_outgoing_rate=False, raise_error_if_no_rate=False) stock_entry.db_update() for d in stock_entry.items: -<<<<<<< HEAD - if d.name == voucher_detail_no or (not d.s_warehouse and d.t_warehouse): -======= # Update only the row that matches the voucher_detail_no or the row containing the FG/Scrap Item. if ( d.name == voucher_detail_no or (not d.s_warehouse and d.t_warehouse) or stock_entry.purpose in ["Manufacture", "Repack"] ): ->>>>>>> 544ceb93cd (fix: stock entry repack amount calculation) d.db_update() def update_rate_on_delivery_and_sales_return(self, sle, outgoing_rate): From 8801584c8d7cca8d3ea78f5e26615db7060395f8 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 10 Apr 2025 13:43:42 +0530 Subject: [PATCH 12/13] fix: update the modified date in for SLEs and GLs after rename (cherry picked from commit dc5a5ef25887c3ce66be9f6c2d5653ce173289eb) --- erpnext/accounts/doctype/gl_entry/gl_entry.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py index b2797fc9db3..f57c070f80b 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.py +++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py @@ -7,7 +7,7 @@ from frappe import _ from frappe.model.document import Document from frappe.model.meta import get_field_precision from frappe.model.naming import set_name_from_naming_options -from frappe.utils import flt, fmt_money +from frappe.utils import flt, fmt_money, now import erpnext from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import ( @@ -405,7 +405,7 @@ def rename_temporarily_named_docs(doctype): set_name_from_naming_options(frappe.get_meta(doctype).autoname, doc) newname = doc.name frappe.db.sql( - f"UPDATE `tab{doctype}` SET name = %s, to_rename = 0 where name = %s", - (newname, oldname), + f"UPDATE `tab{doctype}` SET name = %s, to_rename = 0, modified = %s where name = %s", + (newname, now(), oldname), auto_commit=True, ) From b88f6c125239d404312db67d85db61901f93fe5f Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 14 Apr 2025 19:19:50 +0200 Subject: [PATCH 13/13] fix(Payment Entry): set account type if missing (backport #47069) (backport #47070) (#47072) Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> fix(Payment Entry): set account type if missing (backport #47069) (#47070) fix(Payment Entry): set account type if missing (#47069) --- .../doctype/payment_entry/payment_entry.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index d40efc52d84..5830246bca9 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -350,15 +350,25 @@ class PaymentEntry(AccountsController): self.set(self.party_account_field, party_account) self.party_account = party_account - if self.paid_from and not (self.paid_from_account_currency or self.paid_from_account_balance): + if self.paid_from and ( + not self.paid_from_account_currency + or not self.paid_from_account_balance + or not self.paid_from_account_type + ): acc = get_account_details(self.paid_from, self.posting_date, self.cost_center) self.paid_from_account_currency = acc.account_currency self.paid_from_account_balance = acc.account_balance + self.paid_from_account_type = acc.account_type - if self.paid_to and not (self.paid_to_account_currency or self.paid_to_account_balance): + if self.paid_to and ( + not self.paid_to_account_currency + or not self.paid_to_account_balance + or not self.paid_to_account_type + ): acc = get_account_details(self.paid_to, self.posting_date, self.cost_center) self.paid_to_account_currency = acc.account_currency self.paid_to_account_balance = acc.account_balance + self.paid_to_account_type = acc.account_type self.party_account_currency = ( self.paid_from_account_currency