Skip to content

Commit

Permalink
Merge pull request #36545 from frappe/version-13-hotfix
Browse files Browse the repository at this point in the history
chore: release v13
  • Loading branch information
deepeshgarg007 authored Aug 8, 2023
2 parents 0281afc + 5dbca09 commit 8c51f2e
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 11 deletions.
18 changes: 17 additions & 1 deletion erpnext/accounts/doctype/payment_entry/payment_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,9 @@ def set_tax_withholding(self):
if not self.apply_tax_withholding_amount:
return

net_total = self.paid_amount
order_amount = self.get_order_net_total()

net_total = flt(order_amount) + flt(self.unallocated_amount)

# Adding args as purchase invoice to get TDS amount
args = frappe._dict(
Expand Down Expand Up @@ -661,6 +663,20 @@ def set_tax_withholding(self):
for d in to_remove:
self.remove(d)

def get_order_net_total(self):
if self.party_type == "Supplier":
doctype = "Purchase Order"
else:
doctype = "Sales Order"

docnames = [d.reference_name for d in self.references if d.reference_doctype == doctype]

tax_withholding_net_total = frappe.db.get_value(
doctype, {"name": ["in", docnames]}, ["sum(base_net_total)"]
)

return tax_withholding_net_total

def apply_taxes(self):
self.initialize_taxes()
self.determine_exclusive_rate()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,42 @@ def test_tds_calculation_on_net_total(self):
for d in reversed(invoices):
d.cancel()

def test_tds_deduction_for_po_via_payment_entry(self):
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry

frappe.db.set_value(
"Supplier", "Test TDS Supplier8", "tax_withholding_category", "Cumulative Threshold TDS"
)
order = create_purchase_order(supplier="Test TDS Supplier8", rate=40000, do_not_save=True)

# Add some tax on the order
order.append(
"taxes",
{
"category": "Total",
"charge_type": "Actual",
"account_head": "_Test Account VAT - _TC",
"cost_center": "Main - _TC",
"tax_amount": 8000,
"description": "Test",
"add_deduct_tax": "Add",
},
)

order.save()

order.apply_tds = 1
order.tax_withholding_category = "Cumulative Threshold TDS"
order.submit()

self.assertEqual(order.taxes[0].tax_amount, 4000)

payment = get_payment_entry(order.doctype, order.name)
payment.apply_tax_withholding_amount = 1
payment.tax_withholding_category = "Cumulative Threshold TDS"
payment.submit()
self.assertEqual(payment.taxes[0].tax_amount, 4000)

def test_multi_category_single_supplier(self):
frappe.db.set_value(
"Supplier", "Test TDS Supplier5", "tax_withholding_category", "Test Service Category"
Expand Down Expand Up @@ -275,6 +311,37 @@ def cancel_invoices():
frappe.get_doc("Sales Invoice", d).cancel()


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_purchase_invoice(**args):
# return sales invoice doc object
item = frappe.db.get_value("Item", {"item_name": "TDS Item"}, "name")
Expand Down Expand Up @@ -351,6 +418,8 @@ def create_records():
"Test TDS Supplier4",
"Test TDS Supplier5",
"Test TDS Supplier6",
"Test TDS Supplier7",
"Test TDS Supplier8",
]:
if frappe.db.exists("Supplier", name):
continue
Expand Down
36 changes: 26 additions & 10 deletions erpnext/assets/doctype/asset/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,17 +148,33 @@ def validate_item(self):
frappe.throw(_("Item {0} must be a non-stock item").format(self.item_code))

def validate_cost_center(self):
if not self.cost_center:
return

cost_center_company = frappe.db.get_value("Cost Center", self.cost_center, "company")
if cost_center_company != self.company:
frappe.throw(
_("Selected Cost Center {} doesn't belongs to {}").format(
frappe.bold(self.cost_center), frappe.bold(self.company)
),
title=_("Invalid Cost Center"),
if self.cost_center:
cost_center_company, cost_center_is_group = frappe.db.get_value(
"Cost Center", self.cost_center, ["company", "is_group"]
)
if cost_center_company != self.company:
frappe.throw(
_("Cost Center {} doesn't belong to Company {}").format(
frappe.bold(self.cost_center), frappe.bold(self.company)
),
title=_("Invalid Cost Center"),
)
if cost_center_is_group:
frappe.throw(
_(
"Cost Center {} is a group cost center and group cost centers cannot be used in transactions"
).format(frappe.bold(self.cost_center)),
title=_("Invalid Cost Center"),
)

else:
if not frappe.get_cached_value("Company", self.company, "depreciation_cost_center"):
frappe.throw(
_(
"Please set a Cost Center for the Asset or set an Asset Depreciation Cost Center for the Company {}"
).format(frappe.bold(self.company)),
title=_("Missing Cost Center"),
)

def validate_in_use_date(self):
if not self.available_for_use_date:
Expand Down

0 comments on commit 8c51f2e

Please sign in to comment.