From 165a832a10a378659585fc34ac246197ca95d425 Mon Sep 17 00:00:00 2001 From: Smit Vora Date: Thu, 16 Nov 2023 11:45:28 +0530 Subject: [PATCH 01/10] ci(Mergify): configuration update (cherry picked from commit e410092f6bd0fb8e2267400884f86949f9c8f317) # Conflicts: # .mergify.yml --- .mergify.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/.mergify.yml b/.mergify.yml index c549f5335..7c8c01471 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -53,3 +53,29 @@ pull_request_rules: - version-14-hotfix assignees: - "{{ author }}" +<<<<<<< HEAD +======= + + - name: backport to version-15-hotfix + conditions: + - label="backport version-15-hotfix" + actions: + backport: + branches: + - version-15-hotfix + assignees: + - "{{ author }}" + + - name: automatically merge backport if they pass tests + conditions: + - author=mergify[bot] + - base~=^mergify/bp/ + - head~=^version- + - label!=conflicts + - check-success="linters" + - check-success="Check Commit Titles" + - check-success="Python Unit Tests" + actions: + merge: + method: merge +>>>>>>> e410092f (ci(Mergify): configuration update) From 86932977acd0cfa03b5fd9252b4441896b7c3194 Mon Sep 17 00:00:00 2001 From: Smit Vora Date: Thu, 16 Nov 2023 11:59:33 +0530 Subject: [PATCH 02/10] chore: resolve conflicts --- .mergify.yml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/.mergify.yml b/.mergify.yml index 7c8c01471..c5fac9d98 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -53,18 +53,6 @@ pull_request_rules: - version-14-hotfix assignees: - "{{ author }}" -<<<<<<< HEAD -======= - - - name: backport to version-15-hotfix - conditions: - - label="backport version-15-hotfix" - actions: - backport: - branches: - - version-15-hotfix - assignees: - - "{{ author }}" - name: automatically merge backport if they pass tests conditions: @@ -78,4 +66,3 @@ pull_request_rules: actions: merge: method: merge ->>>>>>> e410092f (ci(Mergify): configuration update) From 78edd151b55817d4a5f8ff96ec5e8eb93c95eebb Mon Sep 17 00:00:00 2001 From: Smit Vora Date: Thu, 16 Nov 2023 12:16:09 +0530 Subject: [PATCH 03/10] ci(Mergify): configuration update Signed-off-by: Smit Vora (cherry picked from commit ad6258973b08caf52665c7931482c3f14a1b2064) --- .mergify.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.mergify.yml b/.mergify.yml index c5fac9d98..ddc42effd 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -57,12 +57,9 @@ pull_request_rules: - name: automatically merge backport if they pass tests conditions: - author=mergify[bot] - - base~=^mergify/bp/ - - head~=^version- + - base~=^version- + - head~=^mergify/bp/ - label!=conflicts - - check-success="linters" - - check-success="Check Commit Titles" - - check-success="Python Unit Tests" actions: merge: method: merge From 94b9d4ed4d23297d628cd455e8442dd59f99796e Mon Sep 17 00:00:00 2001 From: Smit Vora Date: Thu, 16 Nov 2023 10:23:54 +0530 Subject: [PATCH 04/10] test: test cases for advance gst entries (cherry picked from commit 34e132897367d481ccbe62ad684f9ece6efcb3db) --- .../overrides/test_advance_payment_entry.py | 157 ++++++++++++++++++ india_compliance/gst_india/utils/tests.py | 10 +- 2 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 india_compliance/gst_india/overrides/test_advance_payment_entry.py diff --git a/india_compliance/gst_india/overrides/test_advance_payment_entry.py b/india_compliance/gst_india/overrides/test_advance_payment_entry.py new file mode 100644 index 000000000..67f52229b --- /dev/null +++ b/india_compliance/gst_india/overrides/test_advance_payment_entry.py @@ -0,0 +1,157 @@ +import json +from contextlib import contextmanager + +import frappe +from frappe.tests.utils import FrappeTestCase + +from india_compliance.gst_india.utils.tests import create_transaction + + +@contextmanager +def toggle_seperate_advance_accounting(): + # Enable Provisional Expense + frappe.db.set_value( + "Company", + "_Test Indian Registered Company", + { + "book_advance_payments_in_separate_party_account": 1, + "default_advance_received_account": "Creditors - _TIRC", + }, + ) + + try: + yield + + finally: + frappe.db.set_value( + "Company", + "_Test Indian Registered Company", + { + "book_advance_payments_in_separate_party_account": 0, + "default_advance_received_account": None, + }, + ) + + +class TestAdvancePaymentEntry(FrappeTestCase): + EXPECTED_GL = [ + {"account": "Cash - _TIRC", "debit": 11800.0, "credit": 0.0}, + {"account": "Debtors - _TIRC", "debit": 0.0, "credit": 10000.0}, + {"account": "Output Tax SGST - _TIRC", "debit": 0.0, "credit": 900.0}, + {"account": "Output Tax CGST - _TIRC", "debit": 0.0, "credit": 900.0}, + {"account": "Debtors - _TIRC", "debit": 0.0, "credit": 18.0}, + {"account": "Output Tax SGST - _TIRC", "debit": 9.0, "credit": 0.0}, + {"account": "Output Tax CGST - _TIRC", "debit": 9.0, "credit": 0.0}, + ] + + def test_advance_payment_entry(self): + payment_doc = self._create_payment_entry() + self._create_sales_invoice(payment_doc) + + # Assert GL Entries for Payment Entry + self.assertGLEntries(payment_doc, self.EXPECTED_GL) + + @toggle_seperate_advance_accounting() + def test_advance_payment_entry_with_seperate_account(self): + payment_doc = self._create_payment_entry() + self._create_sales_invoice(payment_doc) + + # Assert GL Entries for Payment Entry + self.assertGLEntries( + payment_doc, + [ + {"account": "Cash - _TIRC", "debit": 11800.0, "credit": 0.0}, + {"account": "Creditors - _TIRC", "debit": 0.0, "credit": 10000.0}, + {"account": "Output Tax CGST - _TIRC", "debit": 0.0, "credit": 900.0}, + {"account": "Output Tax SGST - _TIRC", "debit": 0.0, "credit": 900.0}, + {"account": "Creditors - _TIRC", "debit": 100.0, "credit": 0.0}, + {"account": "Debtors - _TIRC", "debit": 0.0, "credit": 100.0}, + {"account": "Debtors - _TIRC", "debit": 0.0, "credit": 18.0}, + {"account": "Output Tax CGST - _TIRC", "debit": 9.0, "credit": 0.0}, + {"account": "Output Tax SGST - _TIRC", "debit": 9.0, "credit": 0.0}, + ], + ) + + def test_payment_entry_allocation(self): + payment_doc = self._create_payment_entry() + invoice_doc = self._create_sales_invoice() + + pr = frappe.get_doc("Payment Reconciliation") + pr.company = "_Test Indian Registered Company" + pr.party_type = "Customer" + pr.party = invoice_doc.customer + pr.receivable_payable_account = invoice_doc.debit_to + + pr.get_unreconciled_entries() + + invoices = [ + row.as_dict() + for row in pr.invoices + if row.invoice_number == invoice_doc.name + ] + payments = [ + row.as_dict() + for row in pr.payments + if row.reference_name == payment_doc.name + ] + + pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments})) + pr.reconcile() + + self.assertGLEntries(payment_doc, self.EXPECTED_GL) + + def _create_sales_invoice(self, payment_doc=None): + invoice_doc = create_transaction( + doctype="Sales Invoice", + is_in_state=1, + do_not_submit=True, + ) + + if payment_doc: + invoice_doc.set_advances() + for row in invoice_doc.advances: + if row.reference_name == payment_doc.name: + # Allocate Net of taxes + row.allocated_amount = invoice_doc.net_total # 100 + else: + row.allocated_amount = 0 + + invoice_doc.submit() + + return invoice_doc + + def _create_payment_entry(self): + payment_doc = create_transaction( + doctype="Payment Entry", + payment_type="Receive", + mode_of_payment="Cash", + company_address="_Test Indian Registered Company-Billing", + party_type="Customer", + party="_Test Registered Customer", + customer_address="_Test Registered Customer-Billing", + paid_to="Cash - _TIRC", + paid_amount=10000, + is_in_state=1, + do_not_save=True, + ) + + payment_doc.setup_party_account_field() + payment_doc.set_missing_values() + payment_doc.set_exchange_rate() + payment_doc.received_amount = ( + payment_doc.paid_amount / payment_doc.target_exchange_rate + ) + payment_doc.save() + payment_doc.submit() + + return payment_doc + + def assertGLEntries(self, payment_doc, expected_gl_entries): + gl_entries = frappe.get_all( + "GL Entry", + filters={"voucher_no": payment_doc.name}, + fields=["account", "debit", "credit"], + ) + out_str = json.dumps(sorted(gl_entries, key=json.dumps)) + expected_out_str = json.dumps(sorted(expected_gl_entries, key=json.dumps)) + self.assertEqual(out_str, expected_out_str) diff --git a/india_compliance/gst_india/utils/tests.py b/india_compliance/gst_india/utils/tests.py index 6558b6f55..6f68e05f9 100644 --- a/india_compliance/gst_india/utils/tests.py +++ b/india_compliance/gst_india/utils/tests.py @@ -43,7 +43,7 @@ def create_transaction(**data): if not transaction.get("customer") and transaction.doctype != "Quotation": transaction.customer = "_Test Registered Customer" - else: + elif transaction.doctype not in ["Payment Entry", "Journal Entry"]: if not transaction.supplier: transaction.supplier = "_Test Registered Supplier" @@ -90,6 +90,9 @@ def append_item(transaction, data=None, company_abbr="_TIRC"): if not data: data = frappe._dict() + if data.doctype in ["Payment Entry", "Journal Entry"]: + return + return transaction.append( "items", { @@ -119,11 +122,14 @@ def _append_taxes( if isinstance(accounts, str): accounts = [accounts] - if transaction.doctype in SALES_DOCTYPES: + if transaction.doctype in SALES_DOCTYPES or transaction.doctype == "Payment Entry": account_type = "Output Tax" else: account_type = "Input Tax" + if transaction.doctype == "Payment Entry" and charge_type == "On Net Total": + charge_type = "On Paid Amount" + for account in accounts: tax = { "charge_type": charge_type, From bbd1526cbde0023a90c80c170d2eeb4d03bad941 Mon Sep 17 00:00:00 2001 From: Smit Vora Date: Thu, 16 Nov 2023 19:36:38 +0530 Subject: [PATCH 05/10] fix: account field missing in v14, fallback to paid_from --- india_compliance/gst_india/overrides/payment_entry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/india_compliance/gst_india/overrides/payment_entry.py b/india_compliance/gst_india/overrides/payment_entry.py index b0556f199..e82ebd16e 100644 --- a/india_compliance/gst_india/overrides/payment_entry.py +++ b/india_compliance/gst_india/overrides/payment_entry.py @@ -127,7 +127,7 @@ def get_gl_for_advance_gst_reversal(payment_entry, reference_row): # Reduce receivables gl_entry = payment_entry.get_gl_dict( { - "account": reference_row.account, + "account": reference_row.get("account") or payment_entry.paid_from, "credit": total_amount, "credit_in_account_currency": total_amount, "party_type": payment_entry.party_type, From 10fd474a1ed2e8daae650f584d8594372b9977d8 Mon Sep 17 00:00:00 2001 From: Smit Vora Date: Thu, 16 Nov 2023 18:59:59 +0530 Subject: [PATCH 06/10] fix: don't process for fuzzy match if bill_no is missing (cherry picked from commit 7a88718d2ad184b566681594af553702f1979009) --- .../gst_india/doctype/purchase_reconciliation_tool/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/india_compliance/gst_india/doctype/purchase_reconciliation_tool/__init__.py b/india_compliance/gst_india/doctype/purchase_reconciliation_tool/__init__.py index f71d3ed2a..e60ae2d7a 100644 --- a/india_compliance/gst_india/doctype/purchase_reconciliation_tool/__init__.py +++ b/india_compliance/gst_india/doctype/purchase_reconciliation_tool/__init__.py @@ -882,6 +882,9 @@ def fuzzy_match(self, purchase, inward_supply): - First check for partial ratio, with 100% confidence - Next check for approximate match, with 90% confidence """ + if not purchase.bill_no or not inward_supply.bill_no: + return False + if abs((purchase.bill_date - inward_supply.bill_date).days) > 10: return False From 91166c5a33adf3a1cda2fb4f06802c658d22ad67 Mon Sep 17 00:00:00 2001 From: Smit Vora Date: Thu, 16 Nov 2023 20:01:02 +0530 Subject: [PATCH 07/10] test: remove unrelated tests from v14 --- .../overrides/test_advance_payment_entry.py | 48 ------------------- 1 file changed, 48 deletions(-) diff --git a/india_compliance/gst_india/overrides/test_advance_payment_entry.py b/india_compliance/gst_india/overrides/test_advance_payment_entry.py index 67f52229b..4946d2847 100644 --- a/india_compliance/gst_india/overrides/test_advance_payment_entry.py +++ b/india_compliance/gst_india/overrides/test_advance_payment_entry.py @@ -1,5 +1,4 @@ import json -from contextlib import contextmanager import frappe from frappe.tests.utils import FrappeTestCase @@ -7,32 +6,6 @@ from india_compliance.gst_india.utils.tests import create_transaction -@contextmanager -def toggle_seperate_advance_accounting(): - # Enable Provisional Expense - frappe.db.set_value( - "Company", - "_Test Indian Registered Company", - { - "book_advance_payments_in_separate_party_account": 1, - "default_advance_received_account": "Creditors - _TIRC", - }, - ) - - try: - yield - - finally: - frappe.db.set_value( - "Company", - "_Test Indian Registered Company", - { - "book_advance_payments_in_separate_party_account": 0, - "default_advance_received_account": None, - }, - ) - - class TestAdvancePaymentEntry(FrappeTestCase): EXPECTED_GL = [ {"account": "Cash - _TIRC", "debit": 11800.0, "credit": 0.0}, @@ -51,27 +24,6 @@ def test_advance_payment_entry(self): # Assert GL Entries for Payment Entry self.assertGLEntries(payment_doc, self.EXPECTED_GL) - @toggle_seperate_advance_accounting() - def test_advance_payment_entry_with_seperate_account(self): - payment_doc = self._create_payment_entry() - self._create_sales_invoice(payment_doc) - - # Assert GL Entries for Payment Entry - self.assertGLEntries( - payment_doc, - [ - {"account": "Cash - _TIRC", "debit": 11800.0, "credit": 0.0}, - {"account": "Creditors - _TIRC", "debit": 0.0, "credit": 10000.0}, - {"account": "Output Tax CGST - _TIRC", "debit": 0.0, "credit": 900.0}, - {"account": "Output Tax SGST - _TIRC", "debit": 0.0, "credit": 900.0}, - {"account": "Creditors - _TIRC", "debit": 100.0, "credit": 0.0}, - {"account": "Debtors - _TIRC", "debit": 0.0, "credit": 100.0}, - {"account": "Debtors - _TIRC", "debit": 0.0, "credit": 18.0}, - {"account": "Output Tax CGST - _TIRC", "debit": 9.0, "credit": 0.0}, - {"account": "Output Tax SGST - _TIRC", "debit": 9.0, "credit": 0.0}, - ], - ) - def test_payment_entry_allocation(self): payment_doc = self._create_payment_entry() invoice_doc = self._create_sales_invoice() From 8b0348b59a60c3ddf3c3c3268b1d20a01bc1c15f Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Fri, 17 Nov 2023 19:00:49 +0530 Subject: [PATCH 08/10] fix: update minimum versions (cherry picked from commit edc5abe0f21658ba02e8494fc00270b290785183) # Conflicts: # india_compliance/patches/check_version_compatibility.py --- india_compliance/patches/check_version_compatibility.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/india_compliance/patches/check_version_compatibility.py b/india_compliance/patches/check_version_compatibility.py index 1348b7ccd..a230fd082 100644 --- a/india_compliance/patches/check_version_compatibility.py +++ b/india_compliance/patches/check_version_compatibility.py @@ -13,12 +13,20 @@ { "app_name": "Frappe", "current_version": version.parse(frappe.__version__), +<<<<<<< HEAD "required_versions": {"version-14": "14.54.0"}, +======= + "required_versions": {"version-14": "14.54.0", "version-15": "15.1.0"}, +>>>>>>> edc5abe0 (fix: update minimum versions) }, { "app_name": "ERPNext", "current_version": version.parse(erpnext.__version__), +<<<<<<< HEAD "required_versions": {"version-14": "14.45.1"}, +======= + "required_versions": {"version-14": "14.45.1", "version-15": "15.2.0"}, +>>>>>>> edc5abe0 (fix: update minimum versions) }, ] From 99509fb7eb24f2ecc39f220f0353f055a57fec6d Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Fri, 17 Nov 2023 19:03:08 +0530 Subject: [PATCH 09/10] chore: fix conflicts --- india_compliance/patches/check_version_compatibility.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/india_compliance/patches/check_version_compatibility.py b/india_compliance/patches/check_version_compatibility.py index a230fd082..5bc0fbe6f 100644 --- a/india_compliance/patches/check_version_compatibility.py +++ b/india_compliance/patches/check_version_compatibility.py @@ -13,20 +13,12 @@ { "app_name": "Frappe", "current_version": version.parse(frappe.__version__), -<<<<<<< HEAD - "required_versions": {"version-14": "14.54.0"}, -======= "required_versions": {"version-14": "14.54.0", "version-15": "15.1.0"}, ->>>>>>> edc5abe0 (fix: update minimum versions) }, { "app_name": "ERPNext", "current_version": version.parse(erpnext.__version__), -<<<<<<< HEAD - "required_versions": {"version-14": "14.45.1"}, -======= "required_versions": {"version-14": "14.45.1", "version-15": "15.2.0"}, ->>>>>>> edc5abe0 (fix: update minimum versions) }, ] From 36c9fa0a95563baaa4c8911eda2802b64d41debe Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Sat, 18 Nov 2023 16:33:35 +0530 Subject: [PATCH 10/10] fix: revert perm check for GST account names (cherry picked from commit df509a5ae77f29c8c0f8b02e97f785f3c08de8d5) --- india_compliance/gst_india/utils/__init__.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/india_compliance/gst_india/utils/__init__.py b/india_compliance/gst_india/utils/__init__.py index f7ad90c91..8c279b7c2 100644 --- a/india_compliance/gst_india/utils/__init__.py +++ b/india_compliance/gst_india/utils/__init__.py @@ -90,7 +90,6 @@ def send_updated_doc(doc, set_docinfo=False): def get_gstin_list(party, party_type="Company"): """ Returns a list the party's GSTINs. - This function doesn't check for permissions since GSTINs are publicly available. """ frappe.has_permission(party_type, doc=party, throw=True) @@ -464,15 +463,13 @@ def get_gst_accounts_by_type(company, account_type, throw=True): @frappe.whitelist() def get_all_gst_accounts(company): + """ + Permission not checked here: + List of GST account names isn't considered sensitive data + """ if not company: frappe.throw(_("Please set Company first")) - if not ( - frappe.has_permission("Account", "read") - or frappe.has_permission("Account", "select") - ): - frappe.throw(_("Not Permitted to select/read Accounts"), frappe.PermissionError) - settings = frappe.get_cached_doc("GST Settings") accounts_list = []