diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py index 1a5ee36b95af..2c876e09725f 100644 --- a/erpnext/accounts/doctype/account/account.py +++ b/erpnext/accounts/doctype/account/account.py @@ -103,14 +103,12 @@ def autoname(self): self.name = get_autoname_with_number(self.account_number, self.account_name, self.company) def validate(self): - from erpnext.accounts.utils import validate_field_number - if frappe.local.flags.allow_unverified_charts: return self.validate_parent() self.validate_parent_child_account_type() self.validate_root_details() - validate_field_number("Account", self.name, self.account_number, self.company, "account_number") + self.validate_account_number() self.validate_group_or_ledger() self.set_root_and_report_type() self.validate_mandatory() @@ -311,6 +309,22 @@ def validate_account_currency(self): if frappe.db.get_value("GL Entry", {"account": self.name}): frappe.throw(_("Currency can not be changed after making entries using some other currency")) + def validate_account_number(self, account_number=None): + if not account_number: + account_number = self.account_number + + if account_number: + account_with_same_number = frappe.db.get_value( + "Account", + {"account_number": account_number, "company": self.company, "name": ["!=", self.name]}, + ) + if account_with_same_number: + frappe.throw( + _("Account Number {0} already used in account {1}").format( + account_number, account_with_same_number + ) + ) + def create_account_for_child_company(self, parent_acc_name_map, descendants, parent_acc_name): for company in descendants: company_bold = frappe.bold(company) @@ -464,19 +478,6 @@ def get_account_autoname(account_number, account_name, company): return " - ".join(parts) -def validate_account_number(name, account_number, company): - if account_number: - account_with_same_number = frappe.db.get_value( - "Account", {"account_number": account_number, "company": company, "name": ["!=", name]} - ) - if account_with_same_number: - frappe.throw( - _("Account Number {0} already used in account {1}").format( - account_number, account_with_same_number - ) - ) - - @frappe.whitelist() def update_account_number(name, account_name, account_number=None, from_descendant=False): account = frappe.get_cached_doc("Account", name) @@ -517,7 +518,7 @@ def update_account_number(name, account_name, account_number=None, from_descenda frappe.throw(message, title=_("Rename Not Allowed")) - validate_account_number(name, account_number, account.company) + account.validate_account_number(account_number) if account_number: frappe.db.set_value("Account", name, "account_number", account_number.strip()) else: diff --git a/erpnext/accounts/doctype/bank_account/bank_account.json b/erpnext/accounts/doctype/bank_account/bank_account.json index 32f1c675d3b1..a5a7691eb76e 100644 --- a/erpnext/accounts/doctype/bank_account/bank_account.json +++ b/erpnext/accounts/doctype/bank_account/bank_account.json @@ -208,8 +208,54 @@ "label": "Disabled" } ], - "links": [], - "modified": "2023-09-22 21:31:34.763977", + "links": [ + { + "group": "Transactions", + "link_doctype": "Payment Request", + "link_fieldname": "bank_account" + }, + { + "group": "Transactions", + "link_doctype": "Payment Order", + "link_fieldname": "bank_account" + }, + { + "group": "Transactions", + "link_doctype": "Bank Guarantee", + "link_fieldname": "bank_account" + }, + { + "group": "Transactions", + "link_doctype": "Payroll Entry", + "link_fieldname": "bank_account" + }, + { + "group": "Transactions", + "link_doctype": "Bank Transaction", + "link_fieldname": "bank_account" + }, + { + "group": "Accounting", + "link_doctype": "Payment Entry", + "link_fieldname": "bank_account" + }, + { + "group": "Accounting", + "link_doctype": "Journal Entry", + "link_fieldname": "bank_account" + }, + { + "group": "Party", + "link_doctype": "Customer", + "link_fieldname": "default_bank_account" + }, + { + "group": "Party", + "link_doctype": "Supplier", + "link_fieldname": "default_bank_account" + } + ], + "modified": "2024-09-24 06:57:41.292970", "modified_by": "Administrator", "module": "Accounts", "name": "Bank Account", @@ -246,4 +292,4 @@ "sort_order": "DESC", "states": [], "track_changes": 1 -} \ No newline at end of file +} diff --git a/erpnext/accounts/doctype/bank_account/bank_account_dashboard.py b/erpnext/accounts/doctype/bank_account/bank_account_dashboard.py deleted file mode 100644 index 8bf8d8a5cd01..000000000000 --- a/erpnext/accounts/doctype/bank_account/bank_account_dashboard.py +++ /dev/null @@ -1,20 +0,0 @@ -from frappe import _ - - -def get_data(): - return { - "fieldname": "bank_account", - "non_standard_fieldnames": { - "Customer": "default_bank_account", - "Supplier": "default_bank_account", - }, - "transactions": [ - { - "label": _("Payments"), - "items": ["Payment Entry", "Payment Request", "Payment Order", "Payroll Entry"], - }, - {"label": _("Party"), "items": ["Customer", "Supplier"]}, - {"items": ["Bank Guarantee"]}, - {"items": ["Journal Entry"]}, - ], - } diff --git a/erpnext/accounts/doctype/bank_clearance/bank_clearance.py b/erpnext/accounts/doctype/bank_clearance/bank_clearance.py index 85713c6c9a6a..92abb8cea89b 100644 --- a/erpnext/accounts/doctype/bank_clearance/bank_clearance.py +++ b/erpnext/accounts/doctype/bank_clearance/bank_clearance.py @@ -108,8 +108,18 @@ def update_clearance_date(self): if not d.clearance_date: d.clearance_date = None - payment_entry = frappe.get_doc(d.payment_document, d.payment_entry) - payment_entry.db_set("clearance_date", d.clearance_date) + if d.payment_document == "Sales Invoice": + frappe.db.set_value( + "Sales Invoice Payment", + {"parent": d.payment_entry, "account": self.get("account"), "amount": [">", 0]}, + "clearance_date", + d.clearance_date, + ) + + else: + frappe.db.set_value( + d.payment_document, d.payment_entry, "clearance_date", d.clearance_date + ) clearance_date_updated = True diff --git a/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py b/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py index d785bfbfef22..658a69a48037 100644 --- a/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py +++ b/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py @@ -6,16 +6,29 @@ import frappe from frappe.utils import add_months, getdate +from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice +from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice +from erpnext.stock.doctype.item.test_item import create_item +from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse from erpnext.tests.utils import if_lending_app_installed, if_lending_app_not_installed class TestBankClearance(unittest.TestCase): @classmethod def setUpClass(cls): + create_warehouse( + warehouse_name="_Test Warehouse", + properties={"parent_warehouse": "All Warehouses - _TC"}, + company="_Test Company", + ) + create_item("_Test Item") + create_cost_center(cost_center_name="_Test Cost Center", company="_Test Company") + clear_payment_entries() clear_loan_transactions() + clear_pos_sales_invoices() make_bank_account() add_transactions() @@ -83,11 +96,41 @@ def make_loan(): bank_clearance.get_payment_entries() self.assertEqual(len(bank_clearance.payment_entries), 3) + def test_update_clearance_date_on_si(self): + sales_invoice = make_pos_sales_invoice() + + date = getdate() + bank_clearance = frappe.get_doc("Bank Clearance") + bank_clearance.account = "_Test Bank Clearance - _TC" + bank_clearance.from_date = add_months(date, -1) + bank_clearance.to_date = date + bank_clearance.include_pos_transactions = 1 + bank_clearance.get_payment_entries() + + self.assertNotEqual(len(bank_clearance.payment_entries), 0) + for payment in bank_clearance.payment_entries: + if payment.payment_entry == sales_invoice.name: + payment.clearance_date = date + + bank_clearance.update_clearance_date() + + si_clearance_date = frappe.db.get_value( + "Sales Invoice Payment", + {"parent": sales_invoice.name, "account": bank_clearance.account}, + "clearance_date", + ) + + self.assertEqual(si_clearance_date, date) + def clear_payment_entries(): frappe.db.delete("Payment Entry") +def clear_pos_sales_invoices(): + frappe.db.delete("Sales Invoice", {"is_pos": 1}) + + @if_lending_app_installed def clear_loan_transactions(): for dt in [ @@ -115,9 +158,45 @@ def add_transactions(): def make_payment_entry(): - pi = make_purchase_invoice(supplier="_Test Supplier", qty=1, rate=690) + from erpnext.buying.doctype.supplier.test_supplier import create_supplier + + supplier = create_supplier(supplier_name="_Test Supplier") + pi = make_purchase_invoice( + supplier=supplier, + supplier_warehouse="_Test Warehouse - _TC", + expense_account="Cost of Goods Sold - _TC", + uom="Nos", + qty=1, + rate=690, + ) pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank Clearance - _TC") pe.reference_no = "Conrad Oct 18" pe.reference_date = "2018-10-24" pe.insert() pe.submit() + + +def make_pos_sales_invoice(): + from erpnext.accounts.doctype.opening_invoice_creation_tool.test_opening_invoice_creation_tool import ( + make_customer, + ) + + mode_of_payment = frappe.get_doc({"doctype": "Mode of Payment", "name": "Cash"}) + + if not frappe.db.get_value("Mode of Payment Account", {"company": "_Test Company", "parent": "Cash"}): + mode_of_payment.append( + "accounts", {"company": "_Test Company", "default_account": "_Test Bank Clearance - _TC"} + ) + mode_of_payment.save() + + customer = make_customer(customer="_Test Customer") + + si = create_sales_invoice(customer=customer, item="_Test Item", is_pos=1, qty=1, rate=1000, do_not_save=1) + si.set("payments", []) + si.append( + "payments", {"mode_of_payment": "Cash", "account": "_Test Bank Clearance - _TC", "amount": 1000} + ) + si.insert() + si.submit() + + return si diff --git a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py index c53faf9ff390..3d4b182d52dc 100644 --- a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py @@ -515,6 +515,23 @@ def test_negative_debit_and_credit_with_same_account_head(self): self.assertEqual(row.debit_in_account_currency, 100) self.assertEqual(row.credit_in_account_currency, 100) + def test_transaction_exchange_rate_on_journals(self): + jv = make_journal_entry("_Test Bank - _TC", "_Test Receivable USD - _TC", 100, save=False) + jv.accounts[0].update({"debit_in_account_currency": 8500, "exchange_rate": 1}) + jv.accounts[1].update({"party_type": "Customer", "party": "_Test Customer USD", "exchange_rate": 85}) + jv.submit() + actual = frappe.db.get_all( + "GL Entry", + filters={"voucher_no": jv.name, "is_cancelled": 0}, + fields=["account", "transaction_exchange_rate"], + order_by="account", + ) + expected = [ + {"account": "_Test Bank - _TC", "transaction_exchange_rate": 1.0}, + {"account": "_Test Receivable USD - _TC", "transaction_exchange_rate": 85.0}, + ] + self.assertEqual(expected, actual) + def make_journal_entry( account1, diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index 13baff9e7a82..625608b5374b 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -145,9 +145,21 @@ def set_liability_account(self): self.is_opening = "No" return - liability_account = get_party_account( - self.party_type, self.party, self.company, include_advance=True - )[1] + accounts = get_party_account(self.party_type, self.party, self.company, include_advance=True) + + liability_account = accounts[1] if len(accounts) > 1 else None + fieldname = ( + "default_advance_received_account" + if self.party_type == "Customer" + else "default_advance_paid_account" + ) + + if not liability_account: + throw( + _("Please set default {0} in Company {1}").format( + frappe.bold(frappe.get_meta("Company").get_label(fieldname)), frappe.bold(self.company) + ) + ) self.set(self.party_account_field, liability_account) diff --git a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.js b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.js index 68a85f7ee963..c171713dc611 100644 --- a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.js +++ b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.js @@ -194,7 +194,9 @@ function refresh_payments(d, frm) { } if (payment) { payment.expected_amount += flt(p.amount); - payment.closing_amount = payment.expected_amount; + if (payment.closing_amount === 0) { + payment.closing_amount = payment.expected_amount; + } payment.difference = payment.closing_amount - payment.expected_amount; } else { frm.add_child("payment_reconciliation", { diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.js b/erpnext/accounts/doctype/pos_invoice/pos_invoice.js index a6e8bfa62869..8707ee88860d 100644 --- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.js +++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.js @@ -40,6 +40,19 @@ erpnext.selling.POSInvoiceController = class POSInvoiceController extends erpnex }; }); + this.frm.set_query("item_code", "items", function (doc) { + return { + query: "erpnext.accounts.doctype.pos_invoice.pos_invoice.item_query", + filters: { + has_variants: ["=", 0], + is_sales_item: ["=", 1], + disabled: ["=", 0], + is_fixed_asset: ["=", 0], + pos_profile: ["=", doc.pos_profile], + }, + }; + }); + erpnext.accounts.dimensions.setup_dimension_filters(this.frm, this.frm.doctype); } diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py index d517c9d6da22..742af7dd0fe0 100644 --- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py +++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py @@ -6,6 +6,7 @@ from frappe import _, bold from frappe.query_builder.functions import IfNull, Sum from frappe.utils import cint, flt, get_link_to_form, getdate, nowdate +from frappe.utils.nestedset import get_descendants_of from erpnext.accounts.doctype.loyalty_program.loyalty_program import validate_loyalty_points from erpnext.accounts.doctype.payment_request.payment_request import make_payment_request @@ -15,6 +16,7 @@ update_multi_mode_option, ) from erpnext.accounts.party import get_due_date, get_party_account +from erpnext.controllers.queries import item_query as _item_query from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos @@ -449,7 +451,7 @@ def validate_payment_amount(self): if self.is_return and entry.amount > 0: frappe.throw(_("Row #{0} (Payment Table): Amount must be negative").format(entry.idx)) - if self.is_return: + if self.is_return and self.docstatus != 0: invoice_total = self.rounded_total or self.grand_total total_amount_in_payments = flt(total_amount_in_payments, self.precision("grand_total")) if total_amount_in_payments and total_amount_in_payments < invoice_total: @@ -837,3 +839,29 @@ def append_payment(payment_mode): ]: payment_mode = get_mode_of_payment_info(mode_of_payment, doc.company) append_payment(payment_mode[0]) + + +@frappe.whitelist() +@frappe.validate_and_sanitize_search_inputs +def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=False): + if pos_profile := filters.get("pos_profile")[1]: + pos_profile = frappe.get_cached_doc("POS Profile", pos_profile) + if item_groups := get_item_group(pos_profile): + filters["item_group"] = ["in", tuple(item_groups)] + + del filters["pos_profile"] + + else: + filters.pop("pos_profile", None) + + return _item_query(doctype, txt, searchfield, start, page_len, filters, as_dict) + + +def get_item_group(pos_profile): + item_groups = [] + if pos_profile.get("item_groups"): + # Get items based on the item groups defined in the POS profile + for row in pos_profile.get("item_groups"): + item_groups.extend(get_descendants_of("Item Group", row.item_group)) + + return list(set(item_groups)) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 1214ddee8cd2..010d3b8bcd5c 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -340,6 +340,7 @@ def validate(self): ): validate_loyalty_points(self, self.loyalty_points) + self.allow_write_off_only_on_pos() self.reset_default_field_value("set_warehouse", "items", "warehouse") def validate_accounts(self): @@ -1021,6 +1022,10 @@ def validate_delivery_note(self): raise_exception=1, ) + def allow_write_off_only_on_pos(self): + if not self.is_pos and self.write_off_account: + self.write_off_account = None + def validate_write_off_account(self): if flt(self.write_off_amount) and not self.write_off_account: self.write_off_account = frappe.get_cached_value("Company", self.company, "write_off_account") diff --git a/erpnext/accounts/doctype/tax_rule/tax_rule.py b/erpnext/accounts/doctype/tax_rule/tax_rule.py index ed623c6635e6..1c0c0a3c1d61 100644 --- a/erpnext/accounts/doctype/tax_rule/tax_rule.py +++ b/erpnext/accounts/doctype/tax_rule/tax_rule.py @@ -185,7 +185,7 @@ def get_tax_template(posting_date, args): conditions.append("(from_date is null) and (to_date is null)") conditions.append( - "ifnull(tax_category, '') = {}".format(frappe.db.escape(cstr(args.get("tax_category")))) + "ifnull(tax_category, '') = {}".format(frappe.db.escape(cstr(args.get("tax_category")), False)) ) if "tax_category" in args.keys(): del args["tax_category"] diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py index 1a7638aaae46..43100c812852 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py @@ -310,8 +310,8 @@ def build_data(self): must_consider = False if self.filters.get("for_revaluation_journals"): - if (abs(row.outstanding) >= 0.0 / 10**self.currency_precision) or ( - abs(row.outstanding_in_account_currency) >= 0.0 / 10**self.currency_precision + if (abs(row.outstanding) >= 1.0 / 10**self.currency_precision) or ( + abs(row.outstanding_in_account_currency) >= 1.0 / 10**self.currency_precision ): must_consider = True else: diff --git a/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py b/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py index b288e8e5ac73..64e6a3404646 100644 --- a/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py +++ b/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py @@ -37,7 +37,7 @@ def get_group_by_asset_category_data(filters): - flt(row.cost_of_sold_asset) - flt(row.cost_of_scrapped_asset) ) - + # Update row with corresponding asset data row.update( next( asset @@ -68,7 +68,7 @@ def get_group_by_asset_category_data(filters): def get_asset_categories_for_grouped_by_category(filters): condition = "" if filters.get("asset_category"): - condition += " and asset_category = %(asset_category)s" + condition += " and a.asset_category = %(asset_category)s" if filters.get("finance_book"): condition += " and exists (select 1 from `tabAsset Depreciation Schedule` ads where ads.asset = a.name and ads.finance_book = %(finance_book)s)" @@ -113,8 +113,13 @@ def get_asset_categories_for_grouped_by_category(filters): 0 end), 0) as cost_of_scrapped_asset from `tabAsset` a - where docstatus=1 and company=%(company)s and purchase_date <= %(to_date)s {condition} - and not exists(select name from `tabAsset Capitalization Asset Item` where asset = a.name) + where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s {condition} + and not exists( + select 1 from `tabAsset Capitalization Asset Item` acai join `tabAsset Capitalization` ac on acai.parent=ac.name + where acai.asset = a.name + and ac.posting_date <= %(to_date)s + and ac.docstatus=1 + ) group by a.asset_category """, { @@ -131,53 +136,59 @@ def get_asset_categories_for_grouped_by_category(filters): def get_asset_details_for_grouped_by_category(filters): condition = "" if filters.get("asset"): - condition += " and name = %(asset)s" + condition += " and a.name = %(asset)s" if filters.get("finance_book"): - condition += " and exists (select 1 from `tabAsset Depreciation Schedule` ads where ads.asset = `tabAsset`.name and ads.finance_book = %(finance_book)s)" + condition += " and exists (select 1 from `tabAsset Depreciation Schedule` ads where ads.asset = a.name and ads.finance_book = %(finance_book)s)" # nosemgrep return frappe.db.sql( f""" - SELECT name, - ifnull(sum(case when purchase_date < %(from_date)s then - case when ifnull(disposal_date, 0) = 0 or disposal_date >= %(from_date)s then - gross_purchase_amount + SELECT a.name, + ifnull(sum(case when a.purchase_date < %(from_date)s then + case when ifnull(a.disposal_date, 0) = 0 or a.disposal_date >= %(from_date)s then + a.gross_purchase_amount else 0 end else 0 end), 0) as cost_as_on_from_date, - ifnull(sum(case when purchase_date >= %(from_date)s then - gross_purchase_amount + ifnull(sum(case when a.purchase_date >= %(from_date)s then + a.gross_purchase_amount else 0 end), 0) as cost_of_new_purchase, - ifnull(sum(case when ifnull(disposal_date, 0) != 0 - and disposal_date >= %(from_date)s - and disposal_date <= %(to_date)s then - case when status = "Sold" then - gross_purchase_amount + ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 + and a.disposal_date >= %(from_date)s + and a.disposal_date <= %(to_date)s then + case when a.status = "Sold" then + a.gross_purchase_amount else 0 end else 0 end), 0) as cost_of_sold_asset, - ifnull(sum(case when ifnull(disposal_date, 0) != 0 - and disposal_date >= %(from_date)s - and disposal_date <= %(to_date)s then - case when status = "Scrapped" then - gross_purchase_amount + ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 + and a.disposal_date >= %(from_date)s + and a.disposal_date <= %(to_date)s then + case when a.status = "Scrapped" then + a.gross_purchase_amount else 0 end else 0 end), 0) as cost_of_scrapped_asset - from `tabAsset` - where docstatus=1 and company=%(company)s and purchase_date <= %(to_date)s {condition} - group by name + from `tabAsset` a + where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s {condition} + and not exists( + select 1 from `tabAsset Capitalization Asset Item` acai join `tabAsset Capitalization` ac on acai.parent=ac.name + where acai.asset = a.name + and ac.posting_date <= %(to_date)s + and ac.docstatus=1 + ) + group by a.name """, { "to_date": filters.to_date, diff --git a/erpnext/accounts/report/balance_sheet/balance_sheet.py b/erpnext/accounts/report/balance_sheet/balance_sheet.py index e89a177a8671..274c8a7a3714 100644 --- a/erpnext/accounts/report/balance_sheet/balance_sheet.py +++ b/erpnext/accounts/report/balance_sheet/balance_sheet.py @@ -95,7 +95,7 @@ def execute(filters=None): filters.periodicity, period_list, filters.accumulated_values, company=filters.company ) - chart = get_chart_data(filters, columns, asset, liability, equity) + chart = get_chart_data(filters, columns, asset, liability, equity, currency) report_summary, primitive_summary = get_report_summary( period_list, asset, liability, equity, provisional_profit_loss, currency, filters @@ -221,7 +221,7 @@ def get_report_summary( ], (net_asset - net_liability + net_equity) -def get_chart_data(filters, columns, asset, liability, equity): +def get_chart_data(filters, columns, asset, liability, equity, currency): labels = [d.get("label") for d in columns[2:]] asset_data, liability_data, equity_data = [], [], [] @@ -249,4 +249,8 @@ def get_chart_data(filters, columns, asset, liability, equity): else: chart["type"] = "line" + chart["fieldtype"] = "Currency" + chart["options"] = "currency" + chart["currency"] = currency + return chart diff --git a/erpnext/accounts/report/cash_flow/cash_flow.py b/erpnext/accounts/report/cash_flow/cash_flow.py index c034f95ec002..9b4416714158 100644 --- a/erpnext/accounts/report/cash_flow/cash_flow.py +++ b/erpnext/accounts/report/cash_flow/cash_flow.py @@ -111,7 +111,7 @@ def execute(filters=None): ) columns = get_columns(filters.periodicity, period_list, filters.accumulated_values, filters.company) - chart = get_chart_data(columns, data) + chart = get_chart_data(columns, data, company_currency) report_summary = get_report_summary(summary_data, company_currency) @@ -252,7 +252,7 @@ def get_report_summary(summary_data, currency): return report_summary -def get_chart_data(columns, data): +def get_chart_data(columns, data, currency): labels = [d.get("label") for d in columns[2:]] datasets = [ { @@ -267,5 +267,7 @@ def get_chart_data(columns, data): chart = {"data": {"labels": labels, "datasets": datasets}, "type": "bar"} chart["fieldtype"] = "Currency" + chart["options"] = "currency" + chart["currency"] = currency return chart diff --git a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py index 2931b728a424..e6aa215924d1 100644 --- a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py +++ b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py @@ -115,7 +115,7 @@ def get_balance_sheet_data(fiscal_year, companies, columns, filters): True, ) - chart = get_chart_data(filters, columns, asset, liability, equity) + chart = get_chart_data(filters, columns, asset, liability, equity, company_currency) return data, message, chart, report_summary @@ -173,7 +173,7 @@ def get_profit_loss_data(fiscal_year, companies, columns, filters): if net_profit_loss: data.append(net_profit_loss) - chart = get_pl_chart_data(filters, columns, income, expense, net_profit_loss) + chart = get_pl_chart_data(filters, columns, income, expense, net_profit_loss, company_currency) report_summary, primitive_summary = get_pl_summary( companies, "", income, expense, net_profit_loss, company_currency, filters, True diff --git a/erpnext/accounts/report/general_and_payment_ledger_comparison/general_and_payment_ledger_comparison.py b/erpnext/accounts/report/general_and_payment_ledger_comparison/general_and_payment_ledger_comparison.py index 89cf7e504f0c..9d079eb9ebd2 100644 --- a/erpnext/accounts/report/general_and_payment_ledger_comparison/general_and_payment_ledger_comparison.py +++ b/erpnext/accounts/report/general_and_payment_ledger_comparison/general_and_payment_ledger_comparison.py @@ -199,8 +199,7 @@ def get_columns(self): dict( label=_("Voucher Type"), fieldname="voucher_type", - fieldtype="Link", - options="DocType", + fieldtype="Data", width="100", ) ) @@ -219,8 +218,7 @@ def get_columns(self): dict( label=_("Party Type"), fieldname="party_type", - fieldtype="Link", - options="DocType", + fieldtype="Data", width="100", ) ) diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py index 2564eb0800f2..1c1d10c087b9 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.py +++ b/erpnext/accounts/report/general_ledger/general_ledger.py @@ -35,6 +35,9 @@ 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) diff --git a/erpnext/accounts/report/payment_ledger/payment_ledger.py b/erpnext/accounts/report/payment_ledger/payment_ledger.py index 9852c6e7ab99..d4f0f0a107d9 100644 --- a/erpnext/accounts/report/payment_ledger/payment_ledger.py +++ b/erpnext/accounts/report/payment_ledger/payment_ledger.py @@ -210,7 +210,7 @@ def get_columns(self): ) ) self.columns.append( - dict(label=_("Currency"), fieldname="currency", fieldtype="Currency", hidden=True) + dict(label=_("Currency"), fieldname="currency", fieldtype="Link", options="Currency", hidden=True) ) def run(self): diff --git a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py index 58610b22a93c..35453f2ec442 100644 --- a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py +++ b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py @@ -59,11 +59,11 @@ def execute(filters=None): columns = get_columns(filters.periodicity, period_list, filters.accumulated_values, filters.company) - chart = get_chart_data(filters, columns, income, expense, net_profit_loss) - currency = filters.presentation_currency or frappe.get_cached_value( "Company", filters.company, "default_currency" ) + chart = get_chart_data(filters, columns, income, expense, net_profit_loss, currency) + report_summary, primitive_summary = get_report_summary( period_list, filters.periodicity, income, expense, net_profit_loss, currency, filters ) @@ -152,7 +152,7 @@ def get_net_profit_loss(income, expense, period_list, company, currency=None, co return net_profit_loss -def get_chart_data(filters, columns, income, expense, net_profit_loss): +def get_chart_data(filters, columns, income, expense, net_profit_loss, currency): labels = [d.get("label") for d in columns[2:]] income_data, expense_data, net_profit = [], [], [] @@ -181,5 +181,7 @@ def get_chart_data(filters, columns, income, expense, net_profit_loss): chart["type"] = "line" chart["fieldtype"] = "Currency" + chart["options"] = "currency" + chart["currency"] = currency return chart diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js index 0a21516c1773..c6e76abb0b59 100644 --- a/erpnext/assets/doctype/asset/asset.js +++ b/erpnext/assets/doctype/asset/asset.js @@ -213,7 +213,7 @@ frappe.ui.form.on("Asset", {
{{row.status}}
-