-
Notifications
You must be signed in to change notification settings - Fork 12
fix: return current_net_amount on get_current_tax_amount ovveride function on rounding #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| __version__ = "0.1.4" | ||
| __version__ = "0.1.5" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,7 +5,7 @@ if (erpnext.taxes_and_totals) { | |
| erpnext.taxes_and_totals.prototype.get_current_tax_amount = function (item, tax, item_tax_map) { | ||
| var tax_rate = this._get_tax_rate(tax, item_tax_map); | ||
| var current_tax_amount = 0.0; | ||
|
|
||
| var current_net_amount = 0.0; | ||
| // To set row_id by default as previous row. | ||
| if(["On Previous Row Amount", "On Previous Row Total"].includes(tax.charge_type)) { | ||
| if (tax.idx === 1) { | ||
|
|
@@ -17,23 +17,29 @@ if (erpnext.taxes_and_totals) { | |
| } | ||
| } | ||
| if(tax.charge_type == "Actual") { | ||
| current_net_amount = item.net_amount | ||
| // distribute the tax amount proportionally to each item row | ||
| var actual = flt(tax.tax_amount, precision("tax_amount", tax)); | ||
| current_tax_amount = this.frm.doc.net_total ? | ||
| ((item.net_amount / this.frm.doc.net_total) * actual) : 0.0; | ||
|
|
||
| } else if(tax.charge_type == "On Net Total") { | ||
| if (tax.account_head in item_tax_map) { | ||
| current_net_amount = item.net_amount | ||
| }; | ||
| if (tax.included_in_print_rate){ | ||
| var net_amount = item.amount / (1 + tax_rate / 100.0) | ||
| current_tax_amount = item.amount - net_amount | ||
| }else { | ||
| current_tax_amount = (tax_rate / 100.0) * item.net_amount; | ||
|
Comment on lines
+27
to
34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: cat -n round_tax_amount_row_wise/public/js/taxes_and_totals_override.js | head -60Repository: ruknsoftware/Round-Tax-Amount-Row-wise Length of output: 3052 🏁 Script executed: fd -t f "taxes_and_totals_override.js" -x wc -l {}Repository: ruknsoftware/Round-Tax-Amount-Row-wise Length of output: 152 🏁 Script executed: curl -s "https://raw.githubusercontent.com/frappe/erpnext/v15.101.0/erpnext/public/js/controllers/taxes_and_totals.js" | head -200Repository: ruknsoftware/Round-Tax-Amount-Row-wise Length of output: 6771 🏁 Script executed: curl -s "https://raw.githubusercontent.com/frappe/erpnext/v15.101.0/erpnext/public/js/controllers/taxes_and_totals.js" | grep -A 50 "get_current_tax_amount"Repository: ruknsoftware/Round-Tax-Amount-Row-wise Length of output: 4066 Fix the net amount returned for inclusive taxes. When 🤖 Prompt for AI Agents |
||
| } | ||
| } else if(tax.charge_type == "On Previous Row Amount") { | ||
| current_net_amount = this.frm.doc["taxes"][cint(tax.row_id) - 1].tax_amount_for_current_item | ||
| current_tax_amount = (tax_rate / 100.0) * | ||
| this.frm.doc["taxes"][cint(tax.row_id) - 1].tax_amount_for_current_item; | ||
|
|
||
| } else if(tax.charge_type == "On Previous Row Total") { | ||
| current_net_amount = this.frm.doc["taxes"][cint(tax.row_id) - 1].grand_total_for_current_item | ||
| current_tax_amount = (tax_rate / 100.0) * | ||
| this.frm.doc["taxes"][cint(tax.row_id) - 1].grand_total_for_current_item; | ||
| } else if (tax.charge_type == "On Item Quantity") { | ||
|
|
@@ -43,7 +49,16 @@ if (erpnext.taxes_and_totals) { | |
| if (!tax.dont_recompute_tax) { | ||
| this.set_item_wise_tax(item, tax, tax_rate, current_tax_amount); | ||
| } | ||
| return flt(current_tax_amount, precision("tax_amount", tax)) | ||
| // return [current_net_amount, flt(current_tax_amount, precision("tax_amount", tax))]; | ||
| const erpnext_version = frappe.boot?.versions?.erpnext; | ||
| // Ensure that the version checked is formatted as semantic version strings | ||
| if (is_version_greater_or_equal(erpnext_version, "15.101")){ | ||
| return [current_net_amount, flt(current_tax_amount, precision("tax_amount", tax))]; | ||
|
|
||
| }else { | ||
| return flt(current_tax_amount, precision("tax_amount", tax)) | ||
| } | ||
|
Comment on lines
+53
to
+60
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❓ Verification inconclusiveScript executed: # First, let's examine the file in question
cat -n round_tax_amount_row_wise/public/js/taxes_and_totals_override.js | sed -n '50,65p'Repository: ruknsoftware/Round-Tax-Amount-Row-wise Repository: ruknsoftware/Round-Tax-Amount-Row-wise stdout: Script executed: # Also check the helper function at lines 86-110
cat -n round_tax_amount_row_wise/public/js/taxes_and_totals_override.js | sed -n '80,115p'Repository: ruknsoftware/Round-Tax-Amount-Row-wise Repository: ruknsoftware/Round-Tax-Amount-Row-wise stdout: ERPNext JavaScript API get_current_tax_amount tuple return version history There is no public ERPNext JavaScript API function named get_current_tax_amount that returns a tuple. The function get_current_tax_amount appears in Python server-side code in erpnext/controllers/taxes_and_totals.py within the calculate_taxes_and_totals class, used for tax calculations during document processing (e.g., Sales Invoice, Purchase Invoice). In recent versions (develop branch as of 2026), it has been renamed to get_current_tax_and_net_amount, which returns two values: current_net_amount, current_tax_amount. This change was part of PR Citations:
ERPNext v15.10.1 calculate_taxes get_current_tax_amount contract In ERPNext v15.10.1, the calculate_taxes method in the calculate_taxes_and_totals class (erpnext/controllers/taxes_and_totals.py) handles tax calculations for documents like Sales Invoices, Purchase Invoices, and those generated from Contracts (e.g., recurring invoices). The method iterates over items and taxes, calling self.get_current_tax_and_net_amount(item, tax, item_tax_map) to compute current_net_amount and current_tax_amount for each tax row and item combination. These represent the net amount base and tax amount for the current calculation step, depending on the tax charge_type (e.g., "On Net Total", "On Previous Row Amount", "Actual"). Previously, there was a get_current_tax_amount method, but it was updated to get_current_tax_and_net_amount to also return net amounts (as part of PR Citations:
ERPNext JavaScript calculate_taxes get_current_tax_amount return value version The get_current_tax_amount function is a JavaScript method in ERPNext's taxes_and_totals.js file (erpnext/public/js/controllers/taxes_and_totals.js), used within the calculate_taxes method of the erpnext.taxes_and_totals controller. It calculates the tax amount for a specific item and tax row during client-side tax computation in documents like Sales Invoice. It takes three parameters: - item: The current item row object - tax: The current tax row object - item_tax_map: Object mapping tax account heads to rates from the item's tax template The function returns a single float value: current_tax_amount, which is the computed tax amount for that item-tax combination, rounded to the tax's tax_amount precision using flt(current_tax_amount, precision("tax_amount", tax)). This value is used to: 1. Accumulate into tax.tax_amount across all items 2. Populate item-wise tax details via set_item_wise_tax(item, tax, tax_rate, current_tax_amount) The computation logic branches by tax.charge_type: - "Actual": Proportional distribution: (item.net_amount / doc.net_total) * tax.tax_amount - "On Net Total": (tax_rate / 100.0) * item.net_amount - "On Previous Row Amount": (tax_rate / 100.0) * doc.taxes[cint(tax.row_id) - 1].tax_amount - "On Previous Row Total": (tax_rate / 100.0) * doc.taxes[cint(tax.row_id) - 1].grand_total_for_current_item - "On Item Quantity": (tax_rate / 100.0) * item_amount / item.qty (truncated in source) Source code from ~v13-v15 (gist 2017, GitLab v15.10.0). In v16 (current as of 2026-04-05, releases up to v16.11.0), tax calculation moved primarily server-side to Python erpnext/controllers/taxes_and_totals.py with get_current_tax_and_net_amount returning tuple (current_net_amount, current_tax_amount). Client-side JS likely simplified or deprecated for real-time preview, but function name matches older authoritative client-side implementation. Citations:
ERPNext v15.10.0 v15.10.1 v15.11.0 taxes_and_totals.js calculate_taxes JavaScript The file taxes_and_totals.js in ERPNext v15 (including versions around v15.10.0, v15.10.1, v15.11.0) is located at erpnext/public/js/controllers/taxes_and_totals.js. It contains JavaScript methods for client-side tax and totals calculation in transaction forms like Sales Invoice, Purchase Invoice, etc. A mirror of v15.10.0 is available at https://gitlab.roduq.pl/roduq/erpnext/-/blob/v15.10.0/erpnext/public/js/controllers/taxes_and_totals.js, which includes functions like calculate_commission for sales documents. The primary function for taxes is likely calculate_taxes_and_totals, which can be overridden via monkey patching in custom apps, as discussed in Frappe forums for v15. This JS file works alongside the Python backend in erpnext/controllers/taxes_and_totals.py, which has a calculate_taxes method that processes tax rows based on charge_type (Actual, On Net Total, On Previous Row Amount, etc.), item tax maps, and inclusive taxes. No specific changes or diffs were found between v15.10.0, v15.10.1, and v15.11.0 regarding calculate_taxes in the JS file; ERPNext v15 uses continuous versioning (e.g., v15.10.x as minor updates within the v15 branch). The official GitHub repo uses 'version-15' branch for stable v15 code, with tags like v15.103.1 as of 2026. For overriding: Extend via custom JS file with frappe.ui.form.on('Sales Invoice', { taxes_and_totals_update: function(frm) { ... } }) or monkey patch the class. Citations:
ERPNext PR when did JavaScript calculate_taxes expect tuple array return from get_current_tax_amount The JavaScript function get_current_tax_amount in ERPNext's taxes_and_totals.js (used in calculate_taxes) originally returned a single value (current_tax_amount). This changed to return a tuple/array [current_net_amount, current_tax_amount] to match backend changes in PR Citations:
ERPNext v16.0.0 release JavaScript get_current_tax_amount tuple array PR 43372 ERPNext v16.0.0 was released on January 12, 2026. PR Citations:
ERPNext version-15 branch v15.12.0 v15.13.0 get_current_tax_amount scalar tuple In ERPNext version 15 branch, specifically around tags v15.12.0 and v15.13.0, the function related to "get_current_tax_amount" is get_current_tax_and_net_amount in erpnext/controllers/taxes_and_totals.py. This method returns a tuple containing the current net amount and tax amount (current_net_amount, current_tax_amount) for tax calculations in documents like Sales Invoice and Purchase Invoice. This function computes the tax amount for the current tax row based on the item's net amount, tax rate from item_tax_map, and tax charge type. It is called within the calculate_taxes method: current_net_amount, current_tax_amount = self.get_current_tax_and_net_amount(item, tax, item_tax_map) The return is a tuple (scalar values for net and tax amounts), not a single scalar. No direct "get_current_tax_amount" function exists; it was likely renamed or refactored in PR Citations:
The version cutoff ERPNext v15.10.1 still returns a scalar float from |
||
|
|
||
| }; | ||
|
|
||
|
|
||
|
|
@@ -67,3 +82,29 @@ if (erpnext.taxes_and_totals) { | |
| tax_detail[key] = [tax_rate, flt(item_wise_tax_amount, precision("base_tax_amount", tax))]; | ||
| }; | ||
| } | ||
|
|
||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| function is_version_greater_or_equal(current, target) { | ||
| if (!current) return false; | ||
|
|
||
| // If current is an object (some older Frappe configs stored it as object) | ||
| if (typeof current === "object" && current.version) { | ||
| current = current.version; | ||
| } | ||
|
|
||
| // Clean beta/alpha suffix e.g "15.10.1-beta" -> "15.10.1" | ||
| current = String(current).split("-")[0]; | ||
| target = String(target).split("-")[0]; | ||
|
|
||
| const c = current.split(".").map(Number); | ||
| const t = target.split(".").map(Number); | ||
|
|
||
| for (let i = 0; i < Math.max(c.length, t.length); i++) { | ||
| const cv = c[i] || 0; | ||
| const tv = t[i] || 0; | ||
|
|
||
| if (cv > tv) return true; | ||
| if (cv < tv) return false; | ||
| } | ||
|
|
||
| return true; // equal | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
current_net_amountnot set whentax.account_headis not initem_tax_map.Unlike the
"Actual"charge type (line 20) which unconditionally setscurrent_net_amount = item.net_amount, the"On Net Total"branch only sets it when the tax account head exists initem_tax_map. If the condition is false,current_net_amountremains0.0, which may produce incorrect results when returned.Is this intentional? If not, consider setting
current_net_amount = item.net_amountunconditionally for this charge type as well.🤖 Prompt for AI Agents