Validate taxes and charges input, commonified
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index 6f16dcd..8040c41 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -3,7 +3,6 @@
frappe.provide("erpnext.accounts");
{% include 'buying/doctype/purchase_common/purchase_common.js' %};
-{% include 'accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js' %}
erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
onload: function() {
diff --git a/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.py b/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.py
index e93c572..b004a2e 100644
--- a/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.py
+++ b/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.py
@@ -2,8 +2,11 @@
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
-import frappe
from frappe.model.document import Document
+from erpnext.controllers.accounts_controller import validate_taxes_and_charges, validate_inclusive_tax
class PurchaseTaxesandChargesMaster(Document):
- pass
+ def validate(self):
+ for tax in self.get("taxes"):
+ validate_taxes_and_charges(tax)
+ validate_inclusive_tax(tax, self)
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index bbc0dd2..4670303 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -5,7 +5,6 @@
cur_frm.pformat.print_heading = 'Invoice';
{% include 'selling/sales_common.js' %};
-{% include 'accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js' %}
frappe.provide("erpnext.accounts");
erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.extend({
diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js
index 58a80a8..b5dc38f 100644
--- a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js
+++ b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js
@@ -1,8 +1,6 @@
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
-cur_frm.cscript.tax_table = "Sales Taxes and Charges";
-
{% include "public/js/controllers/accounts.js" %}
cur_frm.cscript.onload = function(doc, cdt, cdn) {
diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.py b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.py
index 6ab5ab2..4317f2a 100644
--- a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.py
+++ b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.py
@@ -3,8 +3,8 @@
from __future__ import unicode_literals
import frappe
-from frappe.utils import cint
from frappe.model.document import Document
+from erpnext.controllers.accounts_controller import validate_taxes_and_charges, validate_inclusive_tax
class SalesTaxesandChargesMaster(Document):
def validate(self):
@@ -15,3 +15,8 @@
# at least one territory
self.validate_table_has_rows("territories")
+
+ for tax in self.get("taxes"):
+ validate_taxes_and_charges(tax)
+ validate_inclusive_tax(tax, self)
+
diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.js b/erpnext/buying/doctype/purchase_common/purchase_common.js
index f98dab7..dc3b3a3 100644
--- a/erpnext/buying/doctype/purchase_common/purchase_common.js
+++ b/erpnext/buying/doctype/purchase_common/purchase_common.js
@@ -1,11 +1,12 @@
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
+cur_frm.cscript.tax_table = "Purchase Taxes and Charges";
+{% include 'accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js' %}
+
frappe.provide("erpnext.buying");
frappe.require("assets/erpnext/js/controllers/transaction.js");
-{% include "public/js/controllers/accounts.js" %};
-
cur_frm.email_field = "contact_email";
erpnext.buying.BuyingController = erpnext.TransactionController.extend({
@@ -166,97 +167,6 @@
this.frm.doc.outstanding_amount = flt(this.frm.doc.total_amount_to_pay - this.frm.doc.total_advance,
precision("outstanding_amount"));
}
- },
-
- change_form_labels: function(company_currency) {
- var me = this;
- var field_label_map = {};
-
- var setup_field_label_map = function(fields_list, currency) {
- $.each(fields_list, function(i, fname) {
- var docfield = frappe.meta.docfield_map[me.frm.doc.doctype][fname];
- if(docfield) {
- var label = __(docfield.label || "").replace(/\([^\)]*\)/g, "");
- field_label_map[fname] = label.trim() + " (" + currency + ")";
- }
- });
- };
-
-
- setup_field_label_map(["base_net_total", "base_total_taxes_and_charges", "base_grand_total", "base_in_words",
- "base_taxes_and_charges_added", "base_taxes_and_charges_deducted",
- "outstanding_amount", "total_advance", "total_amount_to_pay", "base_rounded_total"],
- company_currency);
-
- setup_field_label_map(["net_total", "grand_total", "in_words",
- "taxes_and_charges_added", "taxes_and_charges_deducted"], this.frm.doc.currency);
-
- cur_frm.set_df_property("conversion_rate", "description", "1 " + this.frm.doc.currency
- + " = [?] " + company_currency);
-
- if(this.frm.doc.price_list_currency && this.frm.doc.price_list_currency!=company_currency) {
- cur_frm.set_df_property("plc_conversion_rate", "description", "1 " + this.frm.doc.price_list_currency
- + " = [?] " + company_currency);
- }
-
- // toggle fields
- this.frm.toggle_display(["conversion_rate", "base_net_total", "base_grand_total",
- "base_in_words", "base_taxes_and_charges_added", "base_taxes_and_charges_deducted"],
- this.frm.doc.currency !== company_currency);
-
- this.frm.toggle_display(["plc_conversion_rate", "price_list_currency"],
- this.frm.doc.price_list_currency !== company_currency);
-
- // set labels
- $.each(field_label_map, function(fname, label) {
- me.frm.fields_dict[fname].set_label(label);
- });
-
- },
-
- change_grid_labels: function(company_currency) {
- var me = this;
- var field_label_map = {};
-
- var setup_field_label_map = function(fields_list, currency, parentfield) {
- var grid_doctype = me.frm.fields_dict[parentfield].grid.doctype;
- $.each(fields_list, function(i, fname) {
- var docfield = frappe.meta.docfield_map[grid_doctype][fname];
- if(docfield) {
- var label = __(docfield.label || "").replace(/\([^\)]*\)/g, "");
- field_label_map[grid_doctype + "-" + fname] =
- label.trim() + " (" + currency + ")";
- }
- });
- };
-
- setup_field_label_map(["base_rate", "base_price_list_rate", "base_amount", "base_rate"],
- company_currency, "items");
-
- setup_field_label_map(["rate", "price_list_rate", "amount"], this.frm.doc.currency, "items");
-
- if(this.frm.fields_dict["taxes"]) {
- setup_field_label_map(["tax_amount", "total"], company_currency, "taxes");
- }
-
- if(this.frm.fields_dict["advances"]) {
- setup_field_label_map(["advance_amount", "allocated_amount"], company_currency,
- "advances");
- }
-
- // toggle columns
- var item_grid = this.frm.fields_dict["items"].grid;
- var fieldnames = $.map(["base_rate", "base_price_list_rate", "base_amount", "base_rate"], function(fname) {
- return frappe.meta.get_docfield(item_grid.doctype, fname, me.frm.docname) ? fname : null;
- });
-
- item_grid.set_column_disp(fieldnames, this.frm.doc.currency != company_currency);
-
- // set labels
- var $wrapper = $(this.frm.wrapper);
- $.each(field_label_map, function(fname, label) {
- $wrapper.find('[data-grid-fieldname="'+fname+'"]').text(label);
- });
}
});
cur_frm.add_fetch('project_name', 'cost_center', 'cost_center');
@@ -279,8 +189,3 @@
}
});
}
-
-
-frappe.ui.form.on("Purchase Taxes and Charges", "rate", function(frm, cdt, cdn) {
- cur_frm.cscript.calculate_taxes_and_totals();
-})
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index b1eee0e..27ea0d4 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -4,7 +4,6 @@
frappe.provide("erpnext.buying");
{% include 'buying/doctype/purchase_common/purchase_common.js' %};
-{% include 'accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js' %}
erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend({
refresh: function(doc, cdt, cdn) {
diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js
index 9c2bbed..ecd9185 100644
--- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js
+++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js
@@ -3,7 +3,6 @@
// attach required files
{% include 'buying/doctype/purchase_common/purchase_common.js' %};
-{% include 'accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js' %}
erpnext.buying.SupplierQuotationController = erpnext.buying.BuyingController.extend({
refresh: function() {
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index c0a63cd..1765fbf 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import frappe
from frappe import _, throw
-from frappe.utils import today, flt
+from frappe.utils import today, flt, cint
from erpnext.setup.utils import get_company_currency, get_exchange_rate
from erpnext.accounts.utils import get_fiscal_year, validate_fiscal_year
from erpnext.utilities.transaction_base import TransactionBase
@@ -357,3 +357,34 @@
if not conversion_rate:
throw(_("{0} is mandatory. Maybe Currency Exchange record is not created for {1} to {2}.").format(
conversion_rate_label, currency, company_currency))
+
+def validate_taxes_and_charges(tax):
+ if not tax.charge_type and (tax.row_id or tax.rate or tax.tax_amount):
+ frappe.throw(_("Please select Charge Type first"))
+ elif tax.charge_type in ['Actual', 'On Net Total'] and tax.row_id:
+ frappe.throw(_("Can refer row only if the charge type is 'On Previous Row Amount' or 'Previous Row Total'"))
+ elif tax.charge_type in ['On Previous Row Amount', 'On Previous Row Total'] and tax.row_id:
+ if cint(tax.idx) == 1:
+ frappe.throw(_("Cannot select charge type as 'On Previous Row Amount' or 'On Previous Row Total' for first row"))
+ elif not tax.row_id:
+ frappe.throw(_("Please specify a valid Row ID for row {0} in table {1}".format(tax.idx, _(tax.doctype))))
+ elif tax.row_id and cint(tax.row_id) >= cint(tax.idx):
+ frappe.throw(_("Cannot refer row number greater than or equal to current row number for this Charge type"))
+
+def validate_inclusive_tax(tax, doc):
+ def _on_previous_row_error(row_range):
+ throw(_("To include tax in row {0} in Item rate, taxes in rows {1} must also be included").format(tax.idx,
+ row_range))
+
+ if cint(getattr(tax, "included_in_print_rate", None)):
+ if tax.charge_type == "Actual":
+ # inclusive tax cannot be of type Actual
+ throw(_("Charge of type 'Actual' in row {0} cannot be included in Item Rate").format(tax.idx))
+ elif tax.charge_type == "On Previous Row Amount" and \
+ not cint(doc.get("taxes")[cint(tax.row_id) - 1].included_in_print_rate):
+ # referred row should also be inclusive
+ _on_previous_row_error(tax.row_id)
+ elif tax.charge_type == "On Previous Row Total" and \
+ not all([cint(t.included_in_print_rate) for t in doc.get("taxes")[:cint(tax.row_id) - 1]]):
+ # all rows about the reffered tax should be inclusive
+ _on_previous_row_error("1 - %d" % (tax.row_id,))
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index 0b32d47..eb397f8 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -3,10 +3,10 @@
from __future__ import unicode_literals
import json
-from frappe import _, throw
from frappe.utils import cint, flt, rounded
from erpnext.setup.utils import get_company_currency
-from erpnext.controllers.accounts_controller import validate_conversion_rate
+from erpnext.controllers.accounts_controller import validate_conversion_rate, \
+ validate_taxes_and_charges, validate_inclusive_tax
class calculate_taxes_and_totals(object):
def __init__(self, doc):
@@ -71,6 +71,9 @@
def initialize_taxes(self):
for tax in self.doc.get("taxes"):
+ validate_taxes_and_charges(tax)
+ validate_inclusive_tax(tax, self.doc)
+
tax.item_wise_tax_detail = {}
tax_fields = ["total", "tax_amount_after_discount_amount",
"tax_amount_for_current_item", "grand_total_for_current_item",
@@ -83,37 +86,8 @@
for fieldname in tax_fields:
tax.set(fieldname, 0.0)
- self.validate_on_previous_row(tax)
- self.validate_inclusive_tax(tax)
self.doc.round_floats_in(tax)
- def validate_on_previous_row(self, tax):
- """
- validate if a valid row id is mentioned in case of
- On Previous Row Amount and On Previous Row Total
- """
- if tax.charge_type in ["On Previous Row Amount", "On Previous Row Total"] and \
- (not tax.row_id or cint(tax.row_id) >= tax.idx):
- throw(_("Please specify a valid Row ID for {0} in row {1}").format(_(tax.doctype), tax.idx))
-
- def validate_inclusive_tax(self, tax):
- def _on_previous_row_error(row_range):
- throw(_("To include tax in row {0} in Item rate, taxes in rows {1} must also be included").format(tax.idx,
- row_range))
-
- if cint(getattr(tax, "included_in_print_rate", None)):
- if tax.charge_type == "Actual":
- # inclusive tax cannot be of type Actual
- throw(_("Charge of type 'Actual' in row {0} cannot be included in Item Rate").format(tax.idx))
- elif tax.charge_type == "On Previous Row Amount" and \
- not cint(self.doc.get("taxes")[cint(tax.row_id) - 1].included_in_print_rate):
- # referred row should also be inclusive
- _on_previous_row_error(tax.row_id)
- elif tax.charge_type == "On Previous Row Total" and \
- not all([cint(t.included_in_print_rate) for t in self.doc.get("taxes")[:cint(tax.row_id) - 1]]):
- # all rows about the reffered tax should be inclusive
- _on_previous_row_error("1 - %d" % (tax.row_id,))
-
def determine_exclusive_rate(self):
if not any((cint(tax.included_in_print_rate) for tax in self.doc.get("taxes"))) or \
self.doc.doctype not in ["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"]:
diff --git a/erpnext/public/js/controllers/accounts.js b/erpnext/public/js/controllers/accounts.js
index 8911832..d0f27bc 100644
--- a/erpnext/public/js/controllers/accounts.js
+++ b/erpnext/public/js/controllers/accounts.js
@@ -19,45 +19,94 @@
}
}
-
-var validate_taxes_and_charges = function(cdt, cdn) {
+cur_frm.cscript.validate_taxes_and_charges = function(cdt, cdn) {
var d = locals[cdt][cdn];
+ var msg = "";
if(!d.charge_type && (d.row_id || d.rate || d.tax_amount)) {
- msgprint(__("Please select Charge Type first"));
+ msg = __("Please select Charge Type first");
d.row_id = "";
d.rate = d.tax_amount = 0.0;
} else if((d.charge_type == 'Actual' || d.charge_type == 'On Net Total') && d.row_id) {
- msgprint(__("Can refer row only if the charge type is 'On Previous Row Amount' or 'Previous Row Total'"));
+ msg = __("Can refer row only if the charge type is 'On Previous Row Amount' or 'Previous Row Total'");
d.row_id = "";
} else if((d.charge_type == 'On Previous Row Amount' || d.charge_type == 'On Previous Row Total') && d.row_id) {
if (d.idx == 1) {
- msgprint(__("Cannot select charge type as 'On Previous Row Amount' or 'On Previous Row Total' for first row"));
+ msg = __("Cannot select charge type as 'On Previous Row Amount' or 'On Previous Row Total' for first row");
d.charge_type = '';
- } else if (d.row_i && d.row_id >= d.idx) {
- msgprint(__("Cannot refer row number greater than or equal to current row number for this Charge type"));
+ } else if (!d.row_id) {
+ msg = __("Please specify a valid Row ID for row {0} in table {1}", [d.idx, __(d.doctype)]);
+ d.row_id = "";
+ } else if(d.row_id && d.row_id >= d.idx) {
+ msg = __("Cannot refer row number greater than or equal to current row number for this Charge type");
d.row_id = "";
}
}
- validated = false;
- refresh_field('row_id', d.name, 'taxes');
+ if(msg) {
+ validated = false;
+ refresh_field("taxes");
+ frappe.throw(msg);
+ }
+
+}
+
+cur_frm.cscript.validate_inclusive_tax = function(tax) {
+ var actual_type_error = function() {
+ var msg = __("Actual type tax cannot be included in Item rate in row {0}", [tax.idx])
+ frappe.throw(msg);
+ };
+
+ var on_previous_row_error = function(row_range) {
+ var msg = __("For row {0} in {1}. To include {2} in Item rate, rows {3} must also be included",
+ [tax.idx, __(tax.doctype), tax.charge_type, row_range])
+ frappe.throw(msg);
+ };
+
+ if(cint(tax.included_in_print_rate)) {
+ if(tax.charge_type == "Actual") {
+ // inclusive tax cannot be of type Actual
+ actual_type_error();
+ } else if(tax.charge_type == "On Previous Row Amount" &&
+ !cint(this.frm.doc["taxes"][tax.row_id - 1].included_in_print_rate)) {
+ // referred row should also be an inclusive tax
+ on_previous_row_error(tax.row_id);
+ } else if(tax.charge_type == "On Previous Row Total") {
+ var taxes_not_included = $.map(this.frm.doc["taxes"].slice(0, tax.row_id),
+ function(t) { return cint(t.included_in_print_rate) ? null : t; });
+ if(taxes_not_included.length > 0) {
+ // all rows above this tax should be inclusive
+ on_previous_row_error(tax.row_id == 1 ? "1" : "1 - " + tax.row_id);
+ }
+ }
+ }
}
frappe.ui.form.on(cur_frm.cscript.tax_table, "row_id", function(frm, cdt, cdn) {
- validate_taxes_and_charges(cdt, cdn);
+ cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
});
frappe.ui.form.on(cur_frm.cscript.tax_table, "rate", function(frm, cdt, cdn) {
- validate_taxes_and_charges(cdt, cdn);
+ cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
});
frappe.ui.form.on(cur_frm.cscript.tax_table, "tax_amount", function(frm, cdt, cdn) {
- validate_taxes_and_charges(cdt, cdn);
+ cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
});
frappe.ui.form.on(cur_frm.cscript.tax_table, "charge_type", function(frm, cdt, cdn) {
- validate_taxes_and_charges(cdt, cdn);
+ cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
});
+frappe.ui.form.on(cur_frm.cscript.tax_table, "included_in_print_rate", function(frm, cdt, cdn) {
+ var tax = frappe.get_doc(cdt, cdn);
+ try {
+ cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
+ cur_frm.cscript.validate_inclusive_tax(tax);
+ } catch(e) {
+ tax.included_in_print_rate = 0;
+ refresh_field("included_in_print_rate", tax.name, tax.parentfield);
+ throw e;
+ }
+});
cur_frm.set_query("account_head", "taxes", function(doc) {
if(cur_frm.cscript.tax_table == "Sales Taxes and Charges") {
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index 4018742..4668398 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -94,7 +94,7 @@
$.each(tax_fields, function(i, fieldname) { tax[fieldname] = 0.0 });
- me.validate_on_previous_row(tax);
+ cur_frm.cscript.validate_taxes_and_charges(tax.doctype, tax.name);
me.validate_inclusive_tax(tax);
frappe.model.round_floats_in(tax);
});
@@ -129,10 +129,7 @@
});
if(cumulated_tax_fraction && !me.discount_amount_applied) {
- item.net_amount = flt(
- (item.amount * me.frm.doc.conversion_rate) / (1 + cumulated_tax_fraction),
- precision("net_amount", item));
-
+ item.net_amount = flt(item.amount / (1 + cumulated_tax_fraction), precision("net_amount", item));
item.net_rate = flt(item.net_amount / item.qty, precision("net_rate", item));
me.set_in_company_currency(item, ["net_rate", "net_amount"]);
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 519b04c..88b4ac4 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -274,22 +274,6 @@
this.apply_pricing_rule(frappe.get_doc(cdt, cdn), true);
},
- tax_amount: function(doc, cdt, cdn) {
- this.calculate_taxes_and_totals();
- },
-
- row_id: function(doc, cdt, cdn) {
- var tax = frappe.get_doc(cdt, cdn);
- try {
- this.validate_on_previous_row(tax);
- this.calculate_taxes_and_totals();
- } catch(e) {
- tax.row_id = null;
- refresh_field("row_id", tax.name, tax.parentfield);
- throw e;
- }
- },
-
set_dynamic_labels: function() {
// What TODO? should we make price list system non-mandatory?
this.frm.toggle_reqd("plc_conversion_rate",
@@ -301,6 +285,114 @@
this.frm.refresh_fields();
},
+
+ change_form_labels: function(company_currency) {
+ var me = this;
+ var field_label_map = {};
+
+ var setup_field_label_map = function(fields_list, currency) {
+ $.each(fields_list, function(i, fname) {
+ var docfield = frappe.meta.docfield_map[me.frm.doc.doctype][fname];
+ if(docfield) {
+ var label = __(docfield.label || "").replace(/\([^\)]*\)/g, "");
+ field_label_map[fname] = label.trim() + " (" + currency + ")";
+ }
+ });
+ };
+ setup_field_label_map(["base_total", "base_net_total", "base_total_taxes_and_charges",
+ "base_discount_amount", "base_grand_total", "base_rounded_total", "base_in_words",
+ "base_taxes_and_charges_added", "base_taxes_and_charges_deducted", "total_amount_to_pay",
+ "outstanding_amount", "total_advance", "paid_amount", "write_off_amount"],
+ company_currency);
+
+ setup_field_label_map(["total", "net_total", "total_taxes_and_charges", "discount_amount",
+ "grand_total", "taxes_and_charges_added", "taxes_and_charges_deducted",
+ "rounded_total", "in_words"], this.frm.doc.currency);
+
+ cur_frm.set_df_property("conversion_rate", "description", "1 " + this.frm.doc.currency
+ + " = [?] " + company_currency)
+
+ if(this.frm.doc.price_list_currency && this.frm.doc.price_list_currency!=company_currency) {
+ cur_frm.set_df_property("plc_conversion_rate", "description", "1 " + this.frm.doc.price_list_currency
+ + " = [?] " + company_currency)
+ }
+
+ // toggle fields
+ this.frm.toggle_display(["conversion_rate", "base_total", "base_net_total", "base_total_taxes_and_charges",
+ "base_taxes_and_charges_added", "base_taxes_and_charges_deducted",
+ "base_grand_total", "base_rounded_total", "base_in_words", "base_discount_amount"],
+ this.frm.doc.currency != company_currency);
+
+ this.frm.toggle_display(["plc_conversion_rate", "price_list_currency"],
+ this.frm.doc.price_list_currency != company_currency);
+
+ // set labels
+ $.each(field_label_map, function(fname, label) {
+ me.frm.fields_dict[fname].set_label(label);
+ });
+ },
+
+ change_grid_labels: function(company_currency) {
+ var me = this;
+ var field_label_map = {};
+
+ var setup_field_label_map = function(fields_list, currency, parentfield) {
+ var grid_doctype = me.frm.fields_dict[parentfield].grid.doctype;
+ $.each(fields_list, function(i, fname) {
+ var docfield = frappe.meta.docfield_map[grid_doctype][fname];
+ if(docfield) {
+ var label = __(docfield.label || "").replace(/\([^\)]*\)/g, "");
+ field_label_map[grid_doctype + "-" + fname] =
+ label.trim() + " (" + currency + ")";
+ }
+ });
+ }
+
+ setup_field_label_map(["base_rate", "base_net_rate", "base_price_list_rate", "base_amount", "base_net_amount"],
+ company_currency, "items");
+
+ setup_field_label_map(["rate", "net_rate", "price_list_rate", "amount", "net_amount"],
+ this.frm.doc.currency, "items");
+
+ if(this.frm.fields_dict["taxes"]) {
+ setup_field_label_map(["tax_amount", "total", "tax_amount_after_discount"], this.frm.doc.currency, "taxes");
+
+ setup_field_label_map(["base_tax_amount", "base_total", "base_tax_amount_after_discount"], company_currency, "taxes");
+ }
+
+ if(this.frm.fields_dict["advances"]) {
+ setup_field_label_map(["advance_amount", "allocated_amount"], company_currency, "advances");
+ }
+
+ // toggle columns
+ var item_grid = this.frm.fields_dict["items"].grid;
+ $.each(["base_rate", "base_price_list_rate", "base_amount"], function(i, fname) {
+ if(frappe.meta.get_docfield(item_grid.doctype, fname))
+ item_grid.set_column_disp(fname, me.frm.doc.currency != company_currency);
+ });
+
+ var show = (cint(cur_frm.doc.discount_amount)) ||
+ ((cur_frm.doc.taxes || []).filter(function(d) {return d.included_in_print_rate===1}).length);
+
+ $.each(["net_rate", "net_amount"], function(i, fname) {
+ if(frappe.meta.get_docfield(item_grid.doctype, fname))
+ item_grid.set_column_disp(fname, show);
+ });
+
+ $.each(["base_net_rate", "base_net_amount"], function(i, fname) {
+ if(frappe.meta.get_docfield(item_grid.doctype, fname))
+ item_grid.set_column_disp(fname, (show && (me.frm.doc.currency != company_currency)));
+ });
+
+ // set labels
+ var $wrapper = $(this.frm.wrapper);
+ $.each(field_label_map, function(fname, label) {
+ fname = fname.split("-");
+ var df = frappe.meta.get_docfield(fname[0], fname[1], me.frm.doc.name);
+ if(df) df.label = label;
+ });
+ },
+
recalculate: function() {
this.calculate_taxes_and_totals();
},
@@ -426,60 +518,6 @@
});
},
- included_in_print_rate: function(doc, cdt, cdn) {
- var tax = frappe.get_doc(cdt, cdn);
- try {
- this.validate_on_previous_row(tax);
- this.validate_inclusive_tax(tax);
- this.calculate_taxes_and_totals();
- } catch(e) {
- tax.included_in_print_rate = 0;
- refresh_field("included_in_print_rate", tax.name, tax.parentfield);
- throw e;
- }
- },
-
- validate_on_previous_row: function(tax) {
- // validate if a valid row id is mentioned in case of
- // On Previous Row Amount and On Previous Row Total
- if((["On Previous Row Amount", "On Previous Row Total"].indexOf(tax.charge_type) != -1) &&
- (!tax.row_id || cint(tax.row_id) >= tax.idx)) {
- var msg = __("Please specify a valid Row ID for row {0} in table {1}", [tax.idx, __(tax.doctype)])
- frappe.throw(msg);
- }
- },
-
- validate_inclusive_tax: function(tax) {
- var actual_type_error = function() {
- var msg = __("Actual type tax cannot be included in Item rate in row {0}", [tax.idx])
- frappe.throw(msg);
- };
-
- var on_previous_row_error = function(row_range) {
- var msg = __("For row {0} in {1}. To include {2} in Item rate, rows {3} must also be included",
- [tax.idx, __(tax.doctype), tax.charge_type, row_range])
- frappe.throw(msg);
- };
-
- if(cint(tax.included_in_print_rate)) {
- if(tax.charge_type == "Actual") {
- // inclusive tax cannot be of type Actual
- actual_type_error();
- } else if(tax.charge_type == "On Previous Row Amount" &&
- !cint(this.frm.doc["taxes"][tax.row_id - 1].included_in_print_rate)) {
- // referred row should also be an inclusive tax
- on_previous_row_error(tax.row_id);
- } else if(tax.charge_type == "On Previous Row Total") {
- var taxes_not_included = $.map(this.frm.doc["taxes"].slice(0, tax.row_id),
- function(t) { return cint(t.included_in_print_rate) ? null : t; });
- if(taxes_not_included.length > 0) {
- // all rows above this tax should be inclusive
- on_previous_row_error(tax.row_id == 1 ? "1" : "1 - " + tax.row_id);
- }
- }
- }
- },
-
get_item_wise_taxes_html: function() {
var item_tax = {};
var tax_accounts = [];
@@ -650,3 +688,19 @@
cur_frm.cscript.calculate_taxes_and_totals();
})
+
+frappe.ui.form.on(cur_frm.cscript.tax_table, "rate", function(frm, cdt, cdn) {
+ cur_frm.cscript.calculate_taxes_and_totals();
+})
+
+frappe.ui.form.on(cur_frm.cscript.tax_table, "tax_amount", function(frm, cdt, cdn) {
+ cur_frm.cscript.calculate_taxes_and_totals();
+})
+
+frappe.ui.form.on(cur_frm.cscript.tax_table, "row_id", function(frm, cdt, cdn) {
+ cur_frm.cscript.calculate_taxes_and_totals();
+})
+
+frappe.ui.form.on(cur_frm.cscript.tax_table, "included_in_print_rate", function(frm, cdt, cdn) {
+ cur_frm.cscript.calculate_taxes_and_totals();
+})
diff --git a/erpnext/selling/doctype/quotation/quotation.js b/erpnext/selling/doctype/quotation/quotation.js
index c63939d..4767f51 100644
--- a/erpnext/selling/doctype/quotation/quotation.js
+++ b/erpnext/selling/doctype/quotation/quotation.js
@@ -3,7 +3,6 @@
{% include 'selling/sales_common.js' %}
-{% include 'accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js' %}
erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({
onload: function(doc, dt, dn) {
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index 15b0e39..bc9d0d1 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -2,7 +2,6 @@
// License: GNU General Public License v3. See license.txt
{% include 'selling/sales_common.js' %}
-{% include 'accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js' %}
erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend({
refresh: function(doc, dt, dn) {
diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js
index c153f94..5d49e2f 100644
--- a/erpnext/selling/sales_common.js
+++ b/erpnext/selling/sales_common.js
@@ -2,11 +2,12 @@
// License: GNU General Public License v3. See license.txt
+cur_frm.cscript.tax_table = "Sales Taxes and Charges";
+{% include 'accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js' %}
+
frappe.provide("erpnext.selling");
frappe.require("assets/erpnext/js/controllers/transaction.js");
-{% include "public/js/controllers/accounts.js" %};
-
cur_frm.email_field = "contact_email";
erpnext.selling.SellingController = erpnext.TransactionController.extend({
@@ -311,109 +312,6 @@
}
}
refresh_field('sales_bom_help');
- },
-
- change_form_labels: function(company_currency) {
- var me = this;
- var field_label_map = {};
-
- var setup_field_label_map = function(fields_list, currency) {
- $.each(fields_list, function(i, fname) {
- var docfield = frappe.meta.docfield_map[me.frm.doc.doctype][fname];
- if(docfield) {
- var label = __(docfield.label || "").replace(/\([^\)]*\)/g, "");
- field_label_map[fname] = label.trim() + " (" + currency + ")";
- }
- });
- };
- setup_field_label_map(["base_total", "base_net_total", "base_total_taxes_and_charges",
- "base_discount_amount", "base_grand_total", "base_rounded_total", "base_in_words",
- "outstanding_amount", "total_advance", "paid_amount", "write_off_amount"],
- company_currency);
-
- setup_field_label_map(["total", "net_total", "total_taxes_and_charges", "discount_amount", "grand_total",
- "rounded_total", "in_words"], this.frm.doc.currency);
-
- cur_frm.set_df_property("conversion_rate", "description", "1 " + this.frm.doc.currency
- + " = [?] " + company_currency)
-
- if(this.frm.doc.price_list_currency && this.frm.doc.price_list_currency!=company_currency) {
- cur_frm.set_df_property("plc_conversion_rate", "description", "1 " + this.frm.doc.price_list_currency
- + " = [?] " + company_currency)
- }
-
- // toggle fields
- this.frm.toggle_display(["conversion_rate", "base_total", "base_net_total", "base_total_taxes_and_charges",
- "base_grand_total", "base_rounded_total", "base_in_words", "base_discount_amount"],
- this.frm.doc.currency != company_currency);
-
- this.frm.toggle_display(["plc_conversion_rate", "price_list_currency"],
- this.frm.doc.price_list_currency != company_currency);
-
- // set labels
- $.each(field_label_map, function(fname, label) {
- me.frm.fields_dict[fname].set_label(label);
- });
- },
-
- change_grid_labels: function(company_currency) {
- var me = this;
- var field_label_map = {};
-
- var setup_field_label_map = function(fields_list, currency, parentfield) {
- var grid_doctype = me.frm.fields_dict[parentfield].grid.doctype;
- $.each(fields_list, function(i, fname) {
- var docfield = frappe.meta.docfield_map[grid_doctype][fname];
- if(docfield) {
- var label = __(docfield.label || "").replace(/\([^\)]*\)/g, "");
- field_label_map[grid_doctype + "-" + fname] =
- label.trim() + " (" + currency + ")";
- }
- });
- }
-
- setup_field_label_map(["base_rate", "base_net_rate", "base_price_list_rate", "base_amount", "base_net_amount"],
- company_currency, "items");
-
- setup_field_label_map(["rate", "net_rate", "price_list_rate", "amount", "net_amount"],
- this.frm.doc.currency, "items");
-
- setup_field_label_map(["tax_amount", "total", "tax_amount_after_discount"], this.frm.doc.currency, "taxes");
-
- setup_field_label_map(["base_tax_amount", "base_total", "base_tax_amount_after_discount"], company_currency, "taxes");
-
- if(this.frm.fields_dict["advances"]) {
- setup_field_label_map(["advance_amount", "allocated_amount"], company_currency,
- "advances");
- }
-
- // toggle columns
- var item_grid = this.frm.fields_dict["items"].grid;
- $.each(["base_rate", "base_price_list_rate", "base_amount"], function(i, fname) {
- if(frappe.meta.get_docfield(item_grid.doctype, fname))
- item_grid.set_column_disp(fname, me.frm.doc.currency != company_currency);
- });
-
- var show = (cint(cur_frm.doc.discount_amount)) ||
- ((cur_frm.doc.taxes || []).filter(function(d) {return d.included_in_print_rate===1}).length);
-
- $.each(["net_rate", "net_amount"], function(i, fname) {
- if(frappe.meta.get_docfield(item_grid.doctype, fname))
- item_grid.set_column_disp(fname, show);
- });
-
- $.each(["base_net_rate", "base_net_amount"], function(i, fname) {
- if(frappe.meta.get_docfield(item_grid.doctype, fname))
- item_grid.set_column_disp(fname, (show && (me.frm.doc.currency != company_currency)));
- });
-
- // set labels
- var $wrapper = $(this.frm.wrapper);
- $.each(field_label_map, function(fname, label) {
- fname = fname.split("-");
- var df = frappe.meta.get_docfield(fname[0], fname[1], me.frm.doc.name);
- if(df) df.label = label;
- });
}
});
@@ -433,7 +331,3 @@
})
}
})
-
-frappe.ui.form.on("Sales Taxes and Charges", "rate", function(frm, cdt, cdn) {
- cur_frm.cscript.calculate_taxes_and_totals();
-})
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js
index 51afa2c..185c242 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.js
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.js
@@ -2,7 +2,6 @@
// License: GNU General Public License v3. See license.txt
{% include 'selling/sales_common.js' %};
-{% include 'accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js' %}
frappe.provide("erpnext.stock");
frappe.provide("erpnext.stock.delivery_note");
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
index 50a1073..a7e6620 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
@@ -2,7 +2,6 @@
// License: GNU General Public License v3. See license.txt
{% include 'buying/doctype/purchase_common/purchase_common.js' %};
-{% include 'accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js' %}
frappe.provide("erpnext.stock");
erpnext.stock.PurchaseReceiptController = erpnext.buying.BuyingController.extend({