From 9f988910b54a3ca0cf00d1706127f4ad5e349e1c Mon Sep 17 00:00:00 2001 From: Maharshi Patel Date: Sun, 25 Sep 2022 23:24:59 +0530 Subject: [PATCH 01/24] fix: payment reconciliation tool consider cost_center for JV We need to consider cost center in all four cases of get_conditions. I have removed check in if statement for get_invoices, get_payments, get_return_invoices as it is not required. --- .../doctype/payment_reconciliation/payment_reconciliation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py index e5b942fb6ef..9b81657af52 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py @@ -332,7 +332,7 @@ class PaymentReconciliation(Document): def get_conditions(self, get_invoices=False, get_payments=False, get_return_invoices=False): condition = " and company = '{0}' ".format(self.company) - if self.get("cost_center") and (get_invoices or get_payments or get_return_invoices): + if self.get("cost_center"): condition = " and cost_center = '{0}' ".format(self.cost_center) if get_invoices: From a13eecc961df0f73219b878181ff7126f7e555e7 Mon Sep 17 00:00:00 2001 From: Maharshi Patel Date: Tue, 27 Sep 2022 13:40:04 +0530 Subject: [PATCH 02/24] fix: SEZ Without Payment of Tax don't add tax rows taxes were added even when gst_category was SEZ and export_type was Without Payment of Tax --- erpnext/regional/india/utils.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py index 1f5212857aa..993680e528b 100644 --- a/erpnext/regional/india/utils.py +++ b/erpnext/regional/india/utils.py @@ -257,9 +257,16 @@ def get_regional_address_details(party_details, doctype, company): update_party_details(party_details, doctype) + customer_gst_category = frappe.get_value( + "Customer", party_details.customer, ["gst_category", "export_type"] + ) + party_details.place_of_supply = get_place_of_supply(party_details, doctype) - if is_internal_transfer(party_details, doctype): + if is_internal_transfer(party_details, doctype) or customer_gst_category == ( + "SEZ", + "Without Payment of Tax", + ): party_details.taxes_and_charges = "" party_details.taxes = [] return party_details From b4a511cbb4aa7f2f7f7d25b6d4d291a3b4075e26 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 28 Sep 2022 15:36:59 +0530 Subject: [PATCH 03/24] fix: Disbursement Account in patch to update old loans (cherry picked from commit be623ce8e8e9c25d2327383c057b5e810b28c4a7) --- erpnext/patches/v13_0/update_old_loans.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/erpnext/patches/v13_0/update_old_loans.py b/erpnext/patches/v13_0/update_old_loans.py index a1d40b739eb..0bd3fcdec4c 100644 --- a/erpnext/patches/v13_0/update_old_loans.py +++ b/erpnext/patches/v13_0/update_old_loans.py @@ -100,6 +100,7 @@ def execute(): "mode_of_payment": loan.mode_of_payment, "loan_account": loan.loan_account, "payment_account": loan.payment_account, + "disbursement_account": loan.payment_account, "interest_income_account": loan.interest_income_account, "penalty_income_account": loan.penalty_income_account, }, @@ -190,6 +191,7 @@ def create_loan_type(loan, loan_type_name, penalty_account): loan_type_doc.company = loan.company loan_type_doc.mode_of_payment = loan.mode_of_payment loan_type_doc.payment_account = loan.payment_account + loan_type_doc.disbursement_account = loan.payment_account loan_type_doc.loan_account = loan.loan_account loan_type_doc.interest_income_account = loan.interest_income_account loan_type_doc.penalty_income_account = penalty_account From 14ab9d91584c7bd90d545de7a93b68b354d06a7e Mon Sep 17 00:00:00 2001 From: anandbaburajan Date: Wed, 28 Sep 2022 21:25:42 +0530 Subject: [PATCH 04/24] fix: asset requiring maintenance sold status --- erpnext/assets/doctype/asset/asset.py | 18 +++++++++++-- erpnext/assets/doctype/asset/test_asset.py | 31 +++++++++++++++++++++- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 1ce815ae2bd..653eb745552 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -643,13 +643,27 @@ class Asset(AccountsController): self.db_set("status", status) def get_status(self): - """Returns status based on whether it is draft, submitted, scrapped or depreciated""" + """Returns status based on whether it is draft, submitted, sold, scrapped or depreciated""" if self.docstatus == 0: status = "Draft" elif self.docstatus == 1: status = "Submitted" - if self.journal_entry_for_scrap: + item = frappe.qb.DocType("Sales Invoice Item").as_("item") + si = frappe.qb.DocType("Sales Invoice").as_("si") + + is_asset_sold = ( + frappe.qb.from_(item) + .select(item.parent) + .inner_join(si) + .on(item.parent == si.name) + .where(item.asset == self.name) + .where(si.docstatus == 1) + ).run() + + if is_asset_sold: + status = "Sold" + elif self.journal_entry_for_scrap: status = "Scrapped" elif self.finance_books: idx = self.get_default_finance_book_idx() or 0 diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py index 13475f34c39..493bd40a5dd 100644 --- a/erpnext/assets/doctype/asset/test_asset.py +++ b/erpnext/assets/doctype/asset/test_asset.py @@ -7,7 +7,7 @@ import frappe from frappe.utils import add_days, add_months, cstr, flt, get_last_day, getdate, nowdate from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice -from erpnext.assets.doctype.asset.asset import make_sales_invoice +from erpnext.assets.doctype.asset.asset import make_sales_invoice, update_maintenance_status from erpnext.assets.doctype.asset.depreciation import ( post_depreciation_entries, restore_asset, @@ -238,6 +238,34 @@ class TestAsset(AssetSetup): self.assertEqual(frappe.db.get_value("Asset", asset.name, "status"), "Partially Depreciated") + def test_asset_with_maintenance_required_status_after_sale(self): + asset = create_asset( + calculate_depreciation=1, + available_for_use_date="2020-06-06", + purchase_date="2020-01-01", + expected_value_after_useful_life=10000, + total_number_of_depreciations=3, + frequency_of_depreciation=10, + maintenance_required=1, + depreciation_start_date="2020-12-31", + submit=1, + ) + + post_depreciation_entries(date="2021-01-01") + + si = make_sales_invoice(asset=asset.name, item_code="Macbook Pro", company="_Test Company") + si.customer = "_Test Customer" + si.due_date = nowdate() + si.get("items")[0].rate = 25000 + si.insert() + si.submit() + + self.assertEqual(frappe.db.get_value("Asset", asset.name, "status"), "Sold") + + update_maintenance_status() + + self.assertEqual(frappe.db.get_value("Asset", asset.name, "status"), "Sold") + def test_expense_head(self): pr = make_purchase_receipt( item_code="Macbook Pro", qty=2, rate=200000.0, location="Test Location" @@ -1353,6 +1381,7 @@ def create_asset(**args): "number_of_depreciations_booked": args.number_of_depreciations_booked or 0, "gross_purchase_amount": args.gross_purchase_amount or 100000, "purchase_receipt_amount": args.purchase_receipt_amount or 100000, + "maintenance_required": args.maintenance_required or 0, "warehouse": args.warehouse or "_Test Warehouse - _TC", "available_for_use_date": args.available_for_use_date or "2020-06-06", "location": args.location or "Test Location", From 430a4c98a0e90fc1b9fdec137ff86f4497de421d Mon Sep 17 00:00:00 2001 From: anandbaburajan Date: Thu, 29 Sep 2022 08:58:33 +0530 Subject: [PATCH 05/24] chore: refactor by creating is_sold --- erpnext/assets/doctype/asset/asset.py | 29 +++++++++++++++------------ 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 653eb745552..2b0602193d8 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -649,19 +649,7 @@ class Asset(AccountsController): elif self.docstatus == 1: status = "Submitted" - item = frappe.qb.DocType("Sales Invoice Item").as_("item") - si = frappe.qb.DocType("Sales Invoice").as_("si") - - is_asset_sold = ( - frappe.qb.from_(item) - .select(item.parent) - .inner_join(si) - .on(item.parent == si.name) - .where(item.asset == self.name) - .where(si.docstatus == 1) - ).run() - - if is_asset_sold: + if self.is_sold(): status = "Sold" elif self.journal_entry_for_scrap: status = "Scrapped" @@ -679,6 +667,21 @@ class Asset(AccountsController): status = "Cancelled" return status + def is_sold(self): + item = frappe.qb.DocType("Sales Invoice Item").as_("item") + si = frappe.qb.DocType("Sales Invoice").as_("si") + + asset_sales_invoice = ( + frappe.qb.from_(item) + .select(item.parent) + .inner_join(si) + .on(item.parent == si.name) + .where(item.asset == self.name) + .where(si.docstatus == 1) + ).run() + + return True if asset_sales_invoice else False + def get_default_finance_book_idx(self): if not self.get("default_finance_book") and self.company: self.default_finance_book = erpnext.get_default_finance_book(self.company) From 712432864095cb193a1e031bb2f3ab33d1619f01 Mon Sep 17 00:00:00 2001 From: Sagar Sharma Date: Wed, 28 Sep 2022 15:40:07 +0530 Subject: [PATCH 06/24] fix: show `Make Purchase Invoice` button based on permission (cherry picked from commit 80080a3d7bc2e4a69c7a18742ce89534920ab118) --- erpnext/templates/pages/order.html | 2 +- erpnext/templates/pages/order.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/templates/pages/order.html b/erpnext/templates/pages/order.html index a10870db278..ec1d49788bd 100644 --- a/erpnext/templates/pages/order.html +++ b/erpnext/templates/pages/order.html @@ -18,7 +18,7 @@