diff --git a/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py b/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py index 40c732bae5..23caac047a 100644 --- a/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py +++ b/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py @@ -226,6 +226,42 @@ class TestTaxWithholdingCategory(unittest.TestCase): for d in reversed(invoices): d.cancel() + orders = [] + + po = create_purchase_order(supplier="Test TDS Supplier4", rate=20000, do_not_save=True) + po.extend( + "items", + [ + { + "doctype": "Purchase Order Item", + "item_code": frappe.db.get_value("Item", {"item_name": "TDS Item"}, "name"), + "qty": 1, + "rate": 20000, + "cost_center": "Main - _TC", + "expense_account": "Stock Received But Not Billed - _TC", + "apply_tds": 0, + }, + { + "doctype": "Purchase Order Item", + "item_code": frappe.db.get_value("Item", {"item_name": "TDS Item"}, "name"), + "qty": 1, + "rate": 35000, + "cost_center": "Main - _TC", + "expense_account": "Stock Received But Not Billed - _TC", + "apply_tds": 1, + }, + ], + ) + po.save() + po.submit() + orders.append(po) + + self.assertEqual(po.taxes[0].tax_amount, 5500) + + # cancel orders to avoid clashing + for d in reversed(orders): + d.cancel() + def test_multi_category_single_supplier(self): frappe.db.set_value( "Supplier", "Test TDS Supplier5", "tax_withholding_category", "Test Service Category" @@ -348,6 +384,39 @@ def create_purchase_invoice(**args): return pi +def create_purchase_order(**args): + # return purchase order doc object + item = frappe.db.get_value("Item", {"item_name": "TDS Item"}, "name") + + args = frappe._dict(args) + po = frappe.get_doc( + { + "doctype": "Purchase Order", + "transaction_date": today(), + "schedule_date": today(), + "apply_tds": 0 if args.do_not_apply_tds else 1, + "supplier": args.supplier, + "company": "_Test Company", + "taxes_and_charges": "", + "currency": "INR", + "taxes": [], + "items": [ + { + "doctype": "Purchase Order Item", + "item_code": item, + "qty": args.qty or 1, + "rate": args.rate or 10000, + "cost_center": "Main - _TC", + "expense_account": "Stock Received But Not Billed - _TC", + } + ], + } + ) + + po.save() + return po + + def create_sales_invoice(**args): # return sales invoice doc object item = frappe.db.get_value("Item", {"item_name": "TCS Item"}, "name") diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json index ded45b866e..e2a70c21be 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.json +++ b/erpnext/buying/doctype/purchase_order/purchase_order.json @@ -54,6 +54,8 @@ "column_break_26", "total", "net_total", + "tax_withholding_net_total", + "base_tax_withholding_net_total", "section_break_48", "pricing_rules", "raw_material_details", @@ -1220,6 +1222,26 @@ "label": "Additional Info", "oldfieldtype": "Section Break" }, + { + "default": "0", + "fieldname": "tax_withholding_net_total", + "fieldtype": "Currency", + "hidden": 1, + "label": "Tax Withholding Net Total", + "no_copy": 1, + "options": "currency", + "read_only": 1 + }, + { + "fieldname": "base_tax_withholding_net_total", + "fieldtype": "Currency", + "hidden": 1, + "label": "Base Tax Withholding Net Total", + "no_copy": 1, + "options": "currency", + "print_hide": 1, + "read_only": 1 + }, { "fieldname": "column_break_99", "fieldtype": "Column Break" diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json index b8203bd128..d471783ab9 100644 --- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json +++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json @@ -44,6 +44,7 @@ "discount_amount", "base_rate_with_margin", "sec_break2", + "apply_tds", "rate", "amount", "item_tax_template", @@ -889,6 +890,12 @@ { "fieldname": "column_break_54", "fieldtype": "Column Break" + }, + { + "default": "1", + "fieldname": "apply_tds", + "fieldtype": "Check", + "label": "Apply TDS" } ], "idx": 1, diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 2624181c19..73d5d3e5f3 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -317,4 +317,4 @@ erpnext.patches.v14_0.fix_subcontracting_receipt_gl_entries erpnext.patches.v14_0.migrate_remarks_from_gl_to_payment_ledger erpnext.patches.v13_0.update_schedule_type_in_loans erpnext.patches.v14_0.create_accounting_dimensions_for_asset_capitalization -erpnext.patches.v14_0.update_tds_fields +erpnext.patches.v14_0.update_partial_tds_fields diff --git a/erpnext/patches/v14_0/update_tds_fields.py b/erpnext/patches/v14_0/update_partial_tds_fields.py similarity index 64% rename from erpnext/patches/v14_0/update_tds_fields.py rename to erpnext/patches/v14_0/update_partial_tds_fields.py index a333c5d7a5..5ccc2dc3aa 100644 --- a/erpnext/patches/v14_0/update_tds_fields.py +++ b/erpnext/patches/v14_0/update_partial_tds_fields.py @@ -25,5 +25,21 @@ def execute(): ).where( purchase_invoice.docstatus == 1 ).run() + + purchase_order = frappe.qb.DocType("Purchase Order") + + frappe.qb.update(purchase_order).set( + purchase_order.tax_withholding_net_total, purchase_order.net_total + ).set( + purchase_order.base_tax_withholding_net_total, purchase_order.base_net_total + ).where( + purchase_order.company == company.name + ).where( + purchase_order.apply_tds == 1 + ).where( + purchase_order.transaction_date >= fiscal_year_details.year_start_date + ).where( + purchase_order.docstatus == 1 + ).run() except FiscalYearError: pass