From c9da1fc568db4d6a163b3ba755ec69e776bcea69 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 19 May 2021 18:38:35 +0530 Subject: [PATCH] chore: Test case for adance TDS allocation --- .../doctype/payment_entry/payment_entry.json | 333 +++++------------- .../doctype/payment_entry/payment_entry.py | 6 +- .../purchase_invoice/purchase_invoice.py | 41 --- .../purchase_invoice/test_purchase_invoice.py | 90 +++++ .../doctype/sales_invoice/sales_invoice.py | 41 --- erpnext/controllers/accounts_controller.py | 56 ++- 6 files changed, 233 insertions(+), 334 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.json b/erpnext/accounts/doctype/payment_entry/payment_entry.json index afc72045e6c..b4b92f926ea 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.json +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.json @@ -97,9 +97,7 @@ { "fieldname": "type_of_payment", "fieldtype": "Section Break", - "label": "Type of Payment", - "show_days": 1, - "show_seconds": 1 + "label": "Type of Payment" }, { "bold": 1, @@ -109,9 +107,7 @@ "options": "ACC-PAY-.YYYY.-", "print_hide": 1, "reqd": 1, - "set_only_once": 1, - "show_days": 1, - "show_seconds": 1 + "set_only_once": 1 }, { "bold": 1, @@ -122,15 +118,11 @@ "label": "Payment Type", "options": "Receive\nPay\nInternal Transfer", "print_hide": 1, - "reqd": 1, - "show_days": 1, - "show_seconds": 1 + "reqd": 1 }, { "fieldname": "column_break_5", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "bold": 1, @@ -139,9 +131,7 @@ "fieldtype": "Date", "in_list_view": 1, "label": "Posting Date", - "reqd": 1, - "show_days": 1, - "show_seconds": 1 + "reqd": 1 }, { "fieldname": "company", @@ -150,34 +140,26 @@ "options": "Company", "print_hide": 1, "remember_last_selected_value": 1, - "reqd": 1, - "show_days": 1, - "show_seconds": 1 + "reqd": 1 }, { "fieldname": "cost_center", "fieldtype": "Link", "label": "Cost Center", - "options": "Cost Center", - "show_days": 1, - "show_seconds": 1 + "options": "Cost Center" }, { "fieldname": "mode_of_payment", "fieldtype": "Link", "in_list_view": 1, "label": "Mode of Payment", - "options": "Mode of Payment", - "show_days": 1, - "show_seconds": 1 + "options": "Mode of Payment" }, { "depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type)", "fieldname": "party_section", "fieldtype": "Section Break", - "label": "Payment From / To", - "show_days": 1, - "show_seconds": 1 + "label": "Payment From / To" }, { "depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type) && doc.docstatus==0", @@ -187,9 +169,7 @@ "label": "Party Type", "options": "DocType", "print_hide": 1, - "search_index": 1, - "show_days": 1, - "show_seconds": 1 + "search_index": 1 }, { "bold": 1, @@ -198,9 +178,7 @@ "fieldtype": "Dynamic Link", "in_standard_filter": 1, "label": "Party", - "options": "party_type", - "show_days": 1, - "show_seconds": 1 + "options": "party_type" }, { "allow_on_submit": 1, @@ -208,24 +186,18 @@ "fieldname": "party_name", "fieldtype": "Data", "in_global_search": 1, - "label": "Party Name", - "show_days": 1, - "show_seconds": 1 + "label": "Party Name" }, { "fieldname": "column_break_11", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "depends_on": "party", "fieldname": "contact_person", "fieldtype": "Link", "label": "Contact", - "options": "Contact", - "show_days": 1, - "show_seconds": 1 + "options": "Contact" }, { "depends_on": "contact_person", @@ -233,17 +205,13 @@ "fieldtype": "Data", "label": "Email", "options": "Email", - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "collapsible": 1, "fieldname": "payment_accounts_section", "fieldtype": "Section Break", - "label": "Accounts", - "show_days": 1, - "show_seconds": 1 + "label": "Accounts" }, { "depends_on": "party", @@ -251,9 +219,7 @@ "fieldtype": "Currency", "label": "Party Balance", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "bold": 1, @@ -264,9 +230,7 @@ "label": "Account Paid From", "options": "Account", "print_hide": 1, - "reqd": 1, - "show_days": 1, - "show_seconds": 1 + "reqd": 1 }, { "depends_on": "paid_from", @@ -276,9 +240,7 @@ "options": "Currency", "print_hide": 1, "read_only": 1, - "reqd": 1, - "show_days": 1, - "show_seconds": 1 + "reqd": 1 }, { "depends_on": "paid_from", @@ -287,15 +249,11 @@ "label": "Account Balance", "options": "paid_from_account_currency", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "column_break_18", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "depends_on": "eval:(in_list([\"Internal Transfer\", \"Receive\"], doc.payment_type) || doc.party)", @@ -305,9 +263,7 @@ "label": "Account Paid To", "options": "Account", "print_hide": 1, - "reqd": 1, - "show_days": 1, - "show_seconds": 1 + "reqd": 1 }, { "depends_on": "paid_to", @@ -317,9 +273,7 @@ "options": "Currency", "print_hide": 1, "read_only": 1, - "reqd": 1, - "show_days": 1, - "show_seconds": 1 + "reqd": 1 }, { "depends_on": "paid_to", @@ -328,17 +282,13 @@ "label": "Account Balance", "options": "paid_to_account_currency", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "depends_on": "eval:(doc.paid_to && doc.paid_from)", "fieldname": "payment_amounts_section", "fieldtype": "Section Break", - "label": "Amount", - "show_days": 1, - "show_seconds": 1 + "label": "Amount" }, { "bold": 1, @@ -346,18 +296,14 @@ "fieldtype": "Currency", "label": "Paid Amount", "options": "paid_from_account_currency", - "reqd": 1, - "show_days": 1, - "show_seconds": 1 + "reqd": 1 }, { "fieldname": "source_exchange_rate", "fieldtype": "Float", "label": "Exchange Rate", "print_hide": 1, - "reqd": 1, - "show_days": 1, - "show_seconds": 1 + "reqd": 1 }, { "fieldname": "base_paid_amount", @@ -366,15 +312,11 @@ "options": "Company:company:default_currency", "print_hide": 1, "read_only": 1, - "reqd": 1, - "show_days": 1, - "show_seconds": 1 + "reqd": 1 }, { "fieldname": "column_break_21", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "bold": 1, @@ -383,18 +325,14 @@ "label": "Received Amount", "options": "paid_to_account_currency", "print_hide": 1, - "reqd": 1, - "show_days": 1, - "show_seconds": 1 + "reqd": 1 }, { "fieldname": "target_exchange_rate", "fieldtype": "Float", "label": "Exchange Rate", "print_hide": 1, - "reqd": 1, - "show_days": 1, - "show_seconds": 1 + "reqd": 1 }, { "fieldname": "base_received_amount", @@ -403,40 +341,30 @@ "options": "Company:company:default_currency", "print_hide": 1, "read_only": 1, - "reqd": 1, - "show_days": 1, - "show_seconds": 1 + "reqd": 1 }, { "depends_on": "eval:(doc.party && doc.paid_from && doc.paid_to && doc.paid_amount && doc.received_amount)", "fieldname": "section_break_14", "fieldtype": "Section Break", - "label": "Reference", - "show_days": 1, - "show_seconds": 1 + "label": "Reference" }, { "depends_on": "eval:doc.docstatus==0", "fieldname": "get_outstanding_invoice", "fieldtype": "Button", - "label": "Get Outstanding Invoice", - "show_days": 1, - "show_seconds": 1 + "label": "Get Outstanding Invoice" }, { "fieldname": "references", "fieldtype": "Table", "label": "Payment References", - "options": "Payment Entry Reference", - "show_days": 1, - "show_seconds": 1 + "options": "Payment Entry Reference" }, { "fieldname": "section_break_34", "fieldtype": "Section Break", - "label": "Writeoff", - "show_days": 1, - "show_seconds": 1 + "label": "Writeoff" }, { "bold": 1, @@ -445,9 +373,7 @@ "fieldtype": "Currency", "label": "Total Allocated Amount", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "base_total_allocated_amount", @@ -455,31 +381,23 @@ "label": "Total Allocated Amount (Company Currency)", "options": "Company:company:default_currency", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "set_exchange_gain_loss", "fieldtype": "Button", - "label": "Set Exchange Gain / Loss", - "show_days": 1, - "show_seconds": 1 + "label": "Set Exchange Gain / Loss" }, { "fieldname": "column_break_36", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "depends_on": "eval:(doc.paid_amount && doc.received_amount && doc.references)", "fieldname": "unallocated_amount", "fieldtype": "Currency", "label": "Unallocated Amount", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "bold": 1, @@ -489,17 +407,13 @@ "label": "Difference Amount (Company Currency)", "options": "Company:company:default_currency", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "depends_on": "difference_amount", "fieldname": "write_off_difference_amount", "fieldtype": "Button", - "label": "Write Off Difference Amount", - "show_days": 1, - "show_seconds": 1 + "label": "Write Off Difference Amount" }, { "collapsible": 1, @@ -507,39 +421,29 @@ "depends_on": "eval:(doc.paid_amount && doc.received_amount)", "fieldname": "deductions_or_loss_section", "fieldtype": "Section Break", - "label": "Deductions or Loss", - "show_days": 1, - "show_seconds": 1 + "label": "Deductions or Loss" }, { "fieldname": "deductions", "fieldtype": "Table", "label": "Payment Deductions or Loss", - "options": "Payment Entry Deduction", - "show_days": 1, - "show_seconds": 1 + "options": "Payment Entry Deduction" }, { "fieldname": "transaction_references", "fieldtype": "Section Break", - "label": "Transaction ID", - "show_days": 1, - "show_seconds": 1 + "label": "Transaction ID" }, { "bold": 1, "depends_on": "eval:(doc.paid_from && doc.paid_to)", "fieldname": "reference_no", "fieldtype": "Data", - "label": "Cheque/Reference No", - "show_days": 1, - "show_seconds": 1 + "label": "Cheque/Reference No" }, { "fieldname": "column_break_23", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "bold": 1, @@ -547,9 +451,7 @@ "fieldname": "reference_date", "fieldtype": "Date", "label": "Cheque/Reference Date", - "search_index": 1, - "show_days": 1, - "show_seconds": 1 + "search_index": 1 }, { "depends_on": "eval:doc.docstatus==1", @@ -558,76 +460,58 @@ "label": "Clearance Date", "no_copy": 1, "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "collapsible": 1, "depends_on": "eval:(doc.paid_from && doc.paid_to && doc.paid_amount && doc.received_amount)", "fieldname": "section_break_12", "fieldtype": "Section Break", - "label": "More Information", - "show_days": 1, - "show_seconds": 1 + "label": "More Information" }, { "fieldname": "project", "fieldtype": "Link", "label": "Project", "options": "Project", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "fieldname": "remarks", "fieldtype": "Small Text", "label": "Remarks", "no_copy": 1, - "read_only_depends_on": "eval:doc.custom_remarks == 0", - "show_days": 1, - "show_seconds": 1 + "read_only_depends_on": "eval:doc.custom_remarks == 0" }, { "fieldname": "column_break_16", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "fieldname": "letter_head", "fieldtype": "Link", "label": "Letter Head", "options": "Letter Head", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "fieldname": "print_heading", "fieldtype": "Link", "label": "Print Heading", "options": "Print Heading", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "fetch_from": "bank_account.bank", "fieldname": "bank", "fieldtype": "Read Only", - "label": "Bank", - "show_days": 1, - "show_seconds": 1 + "label": "Bank" }, { "fetch_from": "bank_account.bank_account_no", "fieldname": "bank_account_no", "fieldtype": "Read Only", - "label": "Bank Account No", - "show_days": 1, - "show_seconds": 1 + "label": "Bank Account No" }, { "fieldname": "payment_order", @@ -636,16 +520,12 @@ "no_copy": 1, "options": "Payment Order", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "subscription_section", "fieldtype": "Section Break", - "label": "Subscription Section", - "show_days": 1, - "show_seconds": 1 + "label": "Subscription Section" }, { "allow_on_submit": 1, @@ -655,9 +535,7 @@ "no_copy": 1, "options": "Auto Repeat", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "amended_from", @@ -666,9 +544,7 @@ "no_copy": 1, "options": "Payment Entry", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "title", @@ -683,18 +559,14 @@ "fieldname": "bank_account", "fieldtype": "Link", "label": "Company Bank Account", - "options": "Bank Account", - "show_days": 1, - "show_seconds": 1 + "options": "Bank Account" }, { "depends_on": "party", "fieldname": "party_bank_account", "fieldtype": "Link", "label": "Party Bank Account", - "options": "Bank Account", - "show_days": 1, - "show_seconds": 1 + "options": "Bank Account" }, { "fieldname": "payment_order_status", @@ -702,23 +574,17 @@ "hidden": 1, "label": "Payment Order Status", "options": "Initiated\nPayment Ordered", - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "collapsible": 1, "fieldname": "accounting_dimensions_section", "fieldtype": "Section Break", - "label": "Accounting Dimensions", - "show_days": 1, - "show_seconds": 1 + "label": "Accounting Dimensions" }, { "fieldname": "dimension_col_break", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "default": "Draft", @@ -739,70 +605,55 @@ "fieldname": "tax_withholding_category", "fieldtype": "Link", "label": "Tax Withholding Category", - "options": "Tax Withholding Category", - "show_days": 1, - "show_seconds": 1 + "mandatory_depends_on": "eval:doc.apply_tax_withholding_amount", + "options": "Tax Withholding Category" }, { "default": "0", "depends_on": "eval:doc.party_type == 'Supplier'", "fieldname": "apply_tax_withholding_amount", "fieldtype": "Check", - "label": "Apply Tax Withholding Amount", - "show_days": 1, - "show_seconds": 1 + "label": "Apply Tax Withholding Amount" }, { "collapsible": 1, "fieldname": "taxes_and_charges_section", "fieldtype": "Section Break", - "label": "Taxes and Charges", - "show_days": 1, - "show_seconds": 1 + "label": "Taxes and Charges" }, { "depends_on": "eval:doc.party_type == 'Supplier'", "fieldname": "purchase_taxes_and_charges_template", "fieldtype": "Link", "label": "Taxes and Charges Template", - "options": "Purchase Taxes and Charges Template", - "show_days": 1, - "show_seconds": 1 + "options": "Purchase Taxes and Charges Template" }, { "depends_on": "eval: doc.party_type == 'Customer'", "fieldname": "sales_taxes_and_charges_template", "fieldtype": "Link", "label": "Taxes and Charges Template", - "options": "Sales Taxes and Charges Template", - "show_days": 1, - "show_seconds": 1 + "options": "Sales Taxes and Charges Template" }, { "depends_on": "eval: doc.party_type == 'Supplier' || doc.party_type == 'Customer'", "fieldname": "taxes", "fieldtype": "Table", "label": "Advance Taxes and Charges", - "options": "Advance Taxes and Charges", - "show_days": 1, - "show_seconds": 1 + "options": "Advance Taxes and Charges" }, { "fieldname": "base_total_taxes_and_charges", "fieldtype": "Currency", "label": "Total Taxes and Charges (Company Currency)", "options": "Company:company:default_currency", - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "total_taxes_and_charges", "fieldtype": "Currency", "label": "Total Taxes and Charges", - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "paid_amount_after_tax", @@ -810,61 +661,47 @@ "hidden": 1, "label": "Paid Amount After Tax", "options": "paid_from_account_currency", - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "base_paid_amount_after_tax", "fieldtype": "Currency", "label": "Paid Amount After Tax (Company Currency)", "options": "Company:company:default_currency", - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "column_break_55", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "fieldname": "section_break_56", "fieldtype": "Section Break", - "hide_border": 1, - "show_days": 1, - "show_seconds": 1 + "hide_border": 1 }, { "fieldname": "advance_tax_account", "fieldtype": "Link", "label": "Advance Tax Account", - "options": "Account", - "show_days": 1, - "show_seconds": 1 + "options": "Account" }, { "fieldname": "received_amount_after_tax", "fieldtype": "Currency", "label": "Received Amount After Tax", - "options": "paid_to_account_currency", - "show_days": 1, - "show_seconds": 1 + "options": "paid_to_account_currency" }, { "fieldname": "base_received_amount_after_tax", "fieldtype": "Currency", "label": "Received Amount After Tax (Company Currency)", - "options": "Company:company:default_currency", - "show_days": 1, - "show_seconds": 1 + "options": "Company:company:default_currency" } ], "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2021-05-15 13:05:16.958866", + "modified": "2021-05-19 02:33:08.192932", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Entry", @@ -908,4 +745,4 @@ "sort_order": "DESC", "title_field": "title", "track_changes": 1 -} +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index ac8e7070f53..cbe8045fd1e 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -436,7 +436,10 @@ class PaymentEntry(AccountsController): if not tax_withholding_details: return - tax_withholding_details.update({'included_in_paid_amount': included_in_paid_amount}) + tax_withholding_details.update({ + 'included_in_paid_amount': included_in_paid_amount, + 'cost_center': self.cost_center or erpnext.get_default_cost_center(self.company) + }) accounts = [] for d in self.taxes: @@ -1412,6 +1415,7 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount= if doc.doctype == 'Purchase Order' and doc.apply_tds: pe.apply_tax_withholding_amount = 1 + pe.tax_withholding_category = doc.tax_withholding_category return pe diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index f925bcf5baa..934c731cf13 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -900,47 +900,6 @@ class PurchaseInvoice(BuyingController): "cost_center": self.cost_center }, account_currency, item=self)) - def allocate_advance_taxes(self, gl_entries): - tax_map = self.get_tax_map() - for pe in self.get('advances'): - if pe.reference_type == 'Payment Entry': - pe = frappe.get_doc('Payment Entry', pe.reference_name) - for tax in pe.get('taxes'): - account_currency = get_account_currency(tax.account_head) - dr_or_cr = "credit" if tax.add_deduct_tax == "Add" else "debit" - rev_dr_cr = "debit" if tax.add_deduct_tax == "Add" else "credit" - - unallocated_amount = tax.tax_amount - tax.allocated_amount - if tax_map.get(tax.account_head): - amount = tax_map.get(tax.account_head) - if amount < unallocated_amount: - unallocated_amount = amount - - gl_entries.append( - self.get_gl_dict({ - "account": tax.account_head, - "against": self.supplier, - dr_or_cr: unallocated_amount, - dr_or_cr + "_in_account_currency": unallocated_amount - if account_currency==self.company_currency - else unallocated_amount, - 'cost_center': tax.cost_center - }, account_currency, item=tax)) - - gl_entries.append( - self.get_gl_dict({ - "account": pe.advance_tax_account, - "against": self.supplier, - rev_dr_cr: unallocated_amount, - rev_dr_cr + "_in_account_currency": unallocated_amount - if account_currency==self.company_currency - else unallocated_amount, - 'cost_center': tax.cost_center or self.cost_center - }, account_currency, item=tax)) - - frappe.db.set_value('Advance Taxes and Charges', tax.name, 'allocated_amount', tax.allocated_amount + unallocated_amount) - tax_map[tax.account_head] -= unallocated_amount - def make_payment_gl_entries(self, gl_entries): # Make Cash GL Entries if cint(self.is_paid) and self.cash_bank_account and self.paid_amount: diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index 66be11ff231..0da46e98866 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -950,6 +950,96 @@ class TestPurchaseInvoice(unittest.TestCase): acc_settings.submit_journal_entriessubmit_journal_entries = 0 acc_settings.save() + def test_purchase_invoice_advance_taxes(self): + from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order + from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry + from erpnext.buying.doctype.purchase_order.purchase_order import get_mapped_purchase_invoice + + # Update tax withholding category with current fiscal year and rate details + update_tax_witholding_category('_Test Company', 'TDS Payable - _TC', nowdate()) + + # Create Purchase Order with TDS applied + po = create_purchase_order(do_not_save=1, rate=3000) + po.apply_tds = 1 + po.tax_withholding_category = 'TDS - 194 - Dividends - Individual' + po.save() + po.submit() + + # Update Unrealized Profit / Loss Account which is used as default advance tax account + frappe.db.set_value('Company', '_Test Company', 'unrealized_profit_loss_account', '_Test Account Excise Duty - _TC') + + # Create Payment Entry Against the order + payment_entry = get_payment_entry(dt='Purchase Order', dn=po.name) + payment_entry.save() + payment_entry.submit() + + # Check GLE for Payment Entry + expected_gle = [ + ['_Test Account Excise Duty - _TC', 6000, 0], + ['Cash - _TC', 0, 24000], + ['Creditors - _TC', 24000, 0], + ['TDS Payable - _TC', 0, 6000], + ] + + gl_entries = frappe.db.sql("""select account, debit, credit + from `tabGL Entry` + where voucher_type='Payment Entry' and voucher_no=%s + order by account asc""", (payment_entry.name), as_dict=1) + + for i, gle in enumerate(gl_entries): + self.assertEqual(expected_gle[i][0], gle.account) + self.assertEqual(expected_gle[i][1], gle.debit) + self.assertEqual(expected_gle[i][2], gle.credit) + + # Create Purchase Invoice against Purchase Order + purchase_invoice = get_mapped_purchase_invoice(po.name) + purchase_invoice.allocate_advances_automatically = 1 + purchase_invoice.save() + purchase_invoice.submit() + + # Check GLE for Purchase Invoice + # Zero net effect on final TDS Payable on invoice + expected_gle = [ + ['_Test Account Excise Duty - _TC', 0, 6000], + ['Cost of Goods Sold - _TC', 30000, 0], + ['Creditors - _TC', 0, 24000], + ['TDS Payable - _TC', 6000, 6000], + ] + + gl_entries = frappe.db.sql("""select account, debit, credit + from `tabGL Entry` + where voucher_type='Purchase Invoice' and voucher_no=%s + order by account asc""", (purchase_invoice.name), as_dict=1) + + for i, gle in enumerate(gl_entries): + self.assertEqual(expected_gle[i][0], gle.account) + self.assertEqual(expected_gle[i][1], gle.debit) + self.assertEqual(expected_gle[i][2], gle.credit) + +def update_tax_witholding_category(company, account, date): + from erpnext.accounts.utils import get_fiscal_year + + fiscal_year = get_fiscal_year(date=date, company=company) + + if not frappe.db.get_value('Tax Withholding Rate', + {'parent': 'TDS - 194 - Dividends - Individual', 'fiscal_year': fiscal_year[0]}): + tds_category = frappe.get_doc('Tax Withholding Category', 'TDS - 194 - Dividends - Individual') + tds_category.append('rates', { + 'fiscal_year': fiscal_year[0], + 'tax_withholding_rate': 20, + 'single_threshold': 2500, + 'cumulative_threshold': 0 + }) + tds_category.save() + + if not frappe.db.get_value('Tax Withholding Account', + {'parent': 'TDS - 194 - Dividends - Individual', 'account': account}): + tds_category = frappe.get_doc('Tax Withholding Category', 'TDS - 194 - Dividends - Individual') + tds_category.append('accounts', { + 'company': company, + 'account': account + }) + tds_category.save() def unlink_payment_on_cancel_of_invoice(enable=1): accounts_settings = frappe.get_doc("Accounts Settings") diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 664b3ab0f2e..485ae18bf04 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -913,47 +913,6 @@ class SalesInvoice(SellingController): "cost_center": self.cost_center }, account_currency, item=self)) - def allocate_advance_taxes(self, gl_entries): - tax_map = self.get_tax_map() - for pe in self.get('advances'): - if pe.reference_type == 'Payment Entry': - pe = frappe.get_doc('Payment Entry', pe.reference_name) - for tax in pe.get('taxes'): - account_currency = get_account_currency(tax.account_head) - dr_or_cr = "debit" if tax.add_deduct_tax == "Add" else "credit" - rev_dr_cr = "credit" if tax.add_deduct_tax == "Add" else "debit" - - unallocated_amount = tax.tax_amount - tax.allocated_amount - if tax_map.get(tax.account_head): - amount = tax_map.get(tax.account_head) - if amount < unallocated_amount: - unallocated_amount = amount - - gl_entries.append( - self.get_gl_dict({ - "account": tax.account_head, - "against": self.customer, - dr_or_cr: unallocated_amount, - dr_or_cr + "_in_account_currency": unallocated_amount - if account_currency==self.company_currency - else unallocated_amount, - 'cost_center': tax.cost_center - }, account_currency, item=tax)) - - gl_entries.append( - self.get_gl_dict({ - "account": pe.advance_tax_account, - "against": self.customer, - rev_dr_cr: unallocated_amount, - rev_dr_cr + "_in_account_currency": unallocated_amount - if account_currency==self.company_currency - else unallocated_amount, - 'cost_center': tax.cost_center - }, account_currency, item=tax)) - - frappe.db.set_value('Advance Taxes and Charges', tax.name, 'allocated_amount', tax.allocated_amount + unallocated_amount) - tax_map[tax.account_head] -= unallocated_amount - def make_item_gl_entries(self, gl_entries): # income account gl entries for item in self.get("items"): diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 11a9d90a1f6..1e85433a604 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -700,7 +700,7 @@ class AccountsController(TransactionBase): from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries if self.doctype in ["Sales Invoice", "Purchase Invoice"]: - self.update_allocated_advance_taxes() + self.update_allocated_advance_taxes_on_cancel() if frappe.db.get_single_value('Accounts Settings', 'unlink_payment_on_cancellation_of_invoice'): unlink_ref_doc_from_payment_entries(self) @@ -716,7 +716,7 @@ class AccountsController(TransactionBase): return tax_map - def update_allocated_advance_taxes(self): + def update_allocated_advance_taxes_on_cancel(self): if self.get('advances'): tax_accounts = [d.account_head for d in self.get('taxes')] allocated_tax_map = frappe._dict(frappe.get_all('GL Entry', fields=['account', 'sum(credit - debit)'], @@ -734,10 +734,60 @@ class AccountsController(TransactionBase): allocated_amount = tax.tax_amount if allocated_amount: - frappe.db.set_value('Advance Taxes and Charges', tax.name, 'allocated_amount', tax.allocated_amount - allocated_amount) + frappe.db.set_value('Advance Taxes and Charges', tax.name, 'allocated_amount', + tax.allocated_amount - allocated_amount) tax_map[tax.account_head] -= allocated_amount allocated_tax_map[tax.account_head] -= allocated_amount + def allocate_advance_taxes(self, gl_entries): + tax_map = self.get_tax_map() + for pe in self.get("advances"): + if pe.reference_type == "Payment Entry": + pe = frappe.get_doc("Payment Entry", pe.reference_name) + for tax in pe.get("taxes"): + account_currency = get_account_currency(tax.account_head) + + if self.doctype == "Purchase Invoice": + dr_or_cr = "credit" if tax.add_deduct_tax == "Add" else "debit" + rev_dr_cr = "debit" if tax.add_deduct_tax == "Add" else "credit" + else: + dr_or_cr = "debit" if tax.add_deduct_tax == "Add" else "credit" + rev_dr_cr = "credit" if tax.add_deduct_tax == "Add" else "debit" + + party = self.supplier if self.doctype == "Purchase Invoice" else self.customer + unallocated_amount = tax.tax_amount - tax.allocated_amount + if tax_map.get(tax.account_head): + amount = tax_map.get(tax.account_head) + if amount < unallocated_amount: + unallocated_amount = amount + + gl_entries.append( + self.get_gl_dict({ + "account": tax.account_head, + "against": party, + dr_or_cr: unallocated_amount, + dr_or_cr + "_in_account_currency": unallocated_amount + if account_currency==self.company_currency + else unallocated_amount, + "cost_center": tax.cost_center + }, account_currency, item=tax)) + + gl_entries.append( + self.get_gl_dict({ + "account": pe.advance_tax_account, + "against": party, + rev_dr_cr: unallocated_amount, + rev_dr_cr + "_in_account_currency": unallocated_amount + if account_currency==self.company_currency + else unallocated_amount, + "cost_center": tax.cost_center + }, account_currency, item=tax)) + + frappe.db.set_value("Advance Taxes and Charges", tax.name, "allocated_amount", + tax.allocated_amount + unallocated_amount) + + tax_map[tax.account_head] -= unallocated_amount + def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on, parentfield): from erpnext.controllers.status_updater import get_allowance_for item_allowance = {}