Validate taxes and charges input, commonified

This commit is contained in:
Nabin Hait 2015-02-23 11:58:15 +05:30
parent 34afcfb4a1
commit 613d081a60
18 changed files with 242 additions and 340 deletions

View File

@ -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() {

View File

@ -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)

View File

@ -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({

View File

@ -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) {

View File

@ -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 @@ class SalesTaxesandChargesMaster(Document):
# 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)

View File

@ -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 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({
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 @@ erpnext.buying.get_default_bom = function(frm) {
}
});
}
frappe.ui.form.on("Purchase Taxes and Charges", "rate", function(frm, cdt, cdn) {
cur_frm.cscript.calculate_taxes_and_totals();
})

View File

@ -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) {

View File

@ -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() {

View File

@ -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 @@ def validate_conversion_rate(currency, conversion_rate, conversion_rate_label, c
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,))

View File

@ -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 @@ class calculate_taxes_and_totals(object):
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 @@ class calculate_taxes_and_totals(object):
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"]:

View File

@ -19,45 +19,94 @@ cur_frm.cscript.account_head = function(doc, cdt, cdn) {
}
}
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") {

View File

@ -94,7 +94,7 @@ erpnext.taxes_and_totals = erpnext.stock.StockController.extend({
$.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 @@ erpnext.taxes_and_totals = erpnext.stock.StockController.extend({
});
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"]);

View File

@ -274,22 +274,6 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
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 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
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 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
});
},
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 @@ frappe.ui.form.on(cur_frm.doctype + "Item", "rate", function(frm, cdt, cdn) {
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();
})

View File

@ -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) {

View File

@ -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) {

View File

@ -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 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
}
}
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(cur_frm.doctype,"project_name", function(frm) {
})
}
})
frappe.ui.form.on("Sales Taxes and Charges", "rate", function(frm, cdt, cdn) {
cur_frm.cscript.calculate_taxes_and_totals();
})

View File

@ -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");

View File

@ -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({