Compare commits

...

13 Commits

Author SHA1 Message Date
mergify[bot]
bd7e5b3e05 refactor: use consistent report column names (backport #54451) (backport #54478) (#54506)
* refactor: use consistent report column names

(cherry picked from commit 7630c01e40)

# Conflicts:
#	erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py
(cherry picked from commit ab188c4404)

* refactor: better label for entity type

(cherry picked from commit 8e12bda108)
(cherry picked from commit e1ff203f95)

* fix: add party_type for dynamic link and add it to grouping key

(cherry picked from commit a3ad1fb163)
(cherry picked from commit 6eb2868a15)

* fix: use key consistently

(cherry picked from commit 8f9a5e6c0c)
(cherry picked from commit 32d46b3e88)

* chore: resolve conflicts

(cherry picked from commit 34e94d6e7a)

* chore: translate values correctly

(cherry picked from commit 83fd655042)

---------

Co-authored-by: Smit Vora <smitvora203@gmail.com>
2026-04-24 20:01:36 +05:30
Frappe PR Bot
adf92a8292 chore(release): Bumped to Version 14.92.14
## [14.92.14](https://github.com/frappe/erpnext/compare/v14.92.13...v14.92.14) (2026-04-10)

### Bug Fixes

* added exception handling on service level agreement apply hook ([#50096](https://github.com/frappe/erpnext/issues/50096)) ([#54192](https://github.com/frappe/erpnext/issues/54192)) ([12b2788](12b27883f6))
2026-04-10 11:53:37 +00:00
diptanilsaha
df6dc540f8 Merge pull request #54202 from frappe/mergify/bp/version-14/pr-54192
fix: added exception handling on service level agreement apply hook (#50096) (backport #54192)
2026-04-10 17:22:07 +05:30
diptanilsaha
12b27883f6 fix: added exception handling on service level agreement apply hook (#50096) (#54192)
Co-authored-by: Ankush Menat <ankush@frappe.io>
(cherry picked from commit 21311dab86)
2026-04-10 11:33:06 +00:00
Frappe PR Bot
5bbfb79cdc chore(release): Bumped to Version 14.92.13
## [14.92.13](https://github.com/frappe/erpnext/compare/v14.92.12...v14.92.13) (2026-03-21)

### Bug Fixes

* allow zero valuation rate ([7a98e13](7a98e13d7d))
2026-03-21 08:34:35 +00:00
rohitwaghchaure
266ac2d5be Merge pull request #53637 from frappe/mergify/bp/version-14/pr-53635
fix: allow zero valuation rate (backport #53635)
2026-03-21 14:03:04 +05:30
Rohit Waghchaure
7a98e13d7d fix: allow zero valuation rate
(cherry picked from commit a6eadb18c9)
2026-03-19 08:32:50 +00:00
rohitwaghchaure
aeee42e857 Merge pull request #52349 from frappe/version-14-hotfix
chore: release v14
2026-02-03 22:48:16 +05:30
Mihir Kandoi
e1674d2017 Merge pull request #51658 from mihir-kandoi/eol-msg 2026-01-30 17:09:28 +05:30
Mihir Kandoi
65d7c6b882 chore: rename filename 2026-01-30 17:08:48 +05:30
Mihir Kandoi
90d88b1c26 chore: fix grammar 2026-01-13 11:00:42 +05:30
Mihir Kandoi
22eec09175 chore: update links 2026-01-13 10:52:51 +05:30
Mihir Kandoi
3f186b24f3 chore: EOL announcement for v14 2026-01-10 22:44:44 +05:30
7 changed files with 50 additions and 26 deletions

View File

@@ -3,7 +3,7 @@ import inspect
import frappe
__version__ = "14.92.12"
__version__ = "14.92.14"
def get_default_company(user=None):

View File

@@ -52,28 +52,25 @@ def group_by_party_and_category(data, filters):
party_category_wise_map = {}
for row in data:
key = (row.get("party_type"), row.get("party"), row.get("tax_withholding_category"))
party_category_wise_map.setdefault(
(row.get("party"), row.get("section_code")),
key,
{
"pan": row.get("pan"),
"tax_id": row.get("tax_id"),
"party": row.get("party"),
"party_type": row.get("party_type"),
"party_name": row.get("party_name"),
"section_code": row.get("section_code"),
"entity_type": row.get("entity_type"),
"tax_withholding_category": row.get("tax_withholding_category"),
"party_entity_type": row.get("party_entity_type"),
"rate": row.get("rate"),
"total_amount": 0.0,
"tax_amount": 0.0,
},
)
party_category_wise_map.get((row.get("party"), row.get("section_code")))["total_amount"] += row.get(
"total_amount", 0.0
)
party_category_wise_map.get((row.get("party"), row.get("section_code")))["tax_amount"] += row.get(
"tax_amount", 0.0
)
party_category_wise_map.get(key)["total_amount"] += row.get("total_amount", 0.0)
party_category_wise_map.get(key)["tax_amount"] += row.get("tax_amount", 0.0)
final_result = get_final_result(party_category_wise_map)
@@ -114,13 +111,18 @@ def get_columns(filters):
columns.extend(
[
{
"label": _("Section Code"),
"label": _("Tax Withholding Category"),
"options": "Tax Withholding Category",
"fieldname": "section_code",
"fieldname": "tax_withholding_category",
"fieldtype": "Link",
"width": 180,
},
{"label": _("Entity Type"), "fieldname": "entity_type", "fieldtype": "Data", "width": 180},
{
"label": _("{0} Type").format(_(filters.get("party_type", "Party"))),
"fieldname": "party_entity_type",
"fieldtype": "Data",
"width": 180,
},
{
"label": _("TDS Rate %") if filters.get("party_type") == "Supplier" else _("TCS Rate %"),
"fieldname": "rate",

View File

@@ -106,8 +106,8 @@ def get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_
row.update(
{
"section_code": tax_withholding_category or "",
"entity_type": party_map.get(party, {}).get(party_type),
"tax_withholding_category": tax_withholding_category or "",
"party_entity_type": party_map.get(party, {}).get(party_type),
"rate": rate,
"total_amount": total_amount,
"grand_total": grand_total,
@@ -127,7 +127,7 @@ def get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_
else:
entries[key] = row
out = list(entries.values())
out.sort(key=lambda x: (x["section_code"], x["transaction_date"]))
out.sort(key=lambda x: (x["tax_withholding_category"], x["transaction_date"], x["ref_no"]))
return out
@@ -177,9 +177,9 @@ def get_columns(filters):
pan = "pan" if frappe.db.has_column(filters.party_type, "pan") else "tax_id"
columns = [
{
"label": _("Section Code"),
"label": _("Tax Withholding Category"),
"options": "Tax Withholding Category",
"fieldname": "section_code",
"fieldname": "tax_withholding_category",
"fieldtype": "Link",
"width": 90,
},
@@ -208,7 +208,12 @@ def get_columns(filters):
columns.extend(
[
{"label": _("Entity Type"), "fieldname": "entity_type", "fieldtype": "Data", "width": 100},
{
"label": _("{0} Type").format(_(filters.get("party_type", "Party"))),
"fieldname": "party_entity_type",
"fieldtype": "Data",
"width": 100,
},
]
)
if filters.party_type == "Supplier":

View File

@@ -118,7 +118,7 @@ class TestTdsPayableMonthly(AccountsTestMixin, FrappeTestCase):
voucher_expected_values = expected_values[i]
voucher_actual_values = (
voucher.ref_no,
voucher.section_code,
voucher.tax_withholding_category,
voucher.rate,
voucher.base_total,
voucher.tax_amount,

View File

@@ -0,0 +1,11 @@
# End of Life reached
With the release of ERPNext version 16, version 14 has reached its end of life.
This means that version 14 of ERPNext (which is running on this site) will no longer receive critical bug fixes and is no longer covered under Frappe Support.
We highly recommend that you update to version 16 to get the latest bug fixes, features and other improvements.
[Click here to know more about version 16](https://frappe.io/erpnext/version-16)
If you're on [Frappe Cloud](https://frappe.io/cloud), [click here to learn how to update to v16](https://docs.frappe.io/cloud/sites/version-upgrade)

View File

@@ -991,7 +991,7 @@ class update_entries_after:
# else it remains the same as that of previous entry
self.wh_data.valuation_rate = new_stock_value / new_stock_qty
if not self.wh_data.valuation_rate and sle.voucher_detail_no:
if self.wh_data.valuation_rate is None and sle.voucher_detail_no:
allow_zero_rate = self.check_if_allow_zero_valuation_rate(sle.voucher_type, sle.voucher_detail_no)
if not allow_zero_rate:
self.wh_data.valuation_rate = self.get_fallback_rate(sle)

View File

@@ -449,10 +449,16 @@ def get_documents_with_active_service_level_agreement():
def set_documents_with_active_service_level_agreement():
active = [
sla.document_type for sla in frappe.get_all("Service Level Agreement", fields=["document_type"])
]
frappe.cache().hset("service_level_agreement", "active", active)
try:
active = frozenset(
sla.document_type for sla in frappe.get_all("Service Level Agreement", fields=["document_type"])
)
frappe.cache().hset("service_level_agreement", "active", active)
except (frappe.DoesNotExistError, frappe.db.TableMissingError):
# This happens during install / uninstall when wildcard hook for SLA intercepts some doc action.
# In both cases, the error can be safely ignored.
active = frozenset()
return active