diff --git a/erpnext/accounts/Print Format/POS Invoice/POS Invoice.txt b/erpnext/accounts/Print Format/POS Invoice/POS Invoice.txt
index aab8e18491..980195642f 100644
--- a/erpnext/accounts/Print Format/POS Invoice/POS Invoice.txt
+++ b/erpnext/accounts/Print Format/POS Invoice/POS Invoice.txt
@@ -2,14 +2,14 @@
{
"creation": "2011-12-21 11:08:55",
"docstatus": 0,
- "modified": "2013-09-13 17:17:47",
+ "modified": "2013-12-26 18:13:48",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"doc_type": "Sales Invoice",
"doctype": "Print Format",
- "html": "\n
\n\n\n\n\n\n\n\
-
\
- \
- Net Total | \
- | \
-
\
-
\
+
\
+
\
+ \
+ Net Total | \
+ | \
+
\
+
\
+
\
\
\
\
@@ -48,6 +50,18 @@ erpnext.POS = Class.extend({
\
\
\
+
\
\
\
\
@@ -82,6 +96,10 @@ erpnext.POS = Class.extend({
me.refresh();
});
+ this.wrapper.find('input.discount-amount').on("change", function() {
+ wn.model.set_value(me.frm.doctype, me.frm.docname, "discount_amount", this.value);
+ });
+
this.call_function("delete-items", function() {me.remove_selected_item();});
this.call_function("make-payment", function() {me.make_payment();});
},
@@ -112,9 +130,9 @@ erpnext.POS = Class.extend({
},
make: function() {
this.make_party();
- this.make_item_group();
- this.make_search();
this.make_barcode();
+ this.make_search();
+ this.make_item_group();
this.make_item_list();
},
make_party: function() {
@@ -137,23 +155,23 @@ erpnext.POS = Class.extend({
me.party.toLowerCase(), this.value);
});
},
- make_item_group: function() {
+ make_barcode: function() {
var me = this;
- this.item_group = wn.ui.form.make_control({
+ this.barcode = wn.ui.form.make_control({
df: {
- "fieldtype": "Link",
- "options": "Item Group",
- "label": "Item Group",
- "fieldname": "pos_item_group",
- "placeholder": "Item Group"
+ "fieldtype": "Data",
+ "label": "Barcode",
+ "fieldname": "pos_barcode",
+ "placeholder": "Barcode / Serial No"
},
- parent: this.wrapper.find(".item-group-area"),
+ parent: this.wrapper.find(".barcode-area"),
only_input: true,
});
- this.item_group.make_input();
- this.item_group.$input.on("change", function() {
- if(!me.item_group.autocomplete_open)
- me.make_item_list();
+ this.barcode.make_input();
+ this.barcode.$input.on("keypress", function() {
+ if(me.barcode_timeout)
+ clearTimeout(me.barcode_timeout);
+ me.barcode_timeout = setTimeout(function() { me.add_item_thru_barcode(); }, 1000);
});
},
make_search: function() {
@@ -176,23 +194,23 @@ erpnext.POS = Class.extend({
me.item_timeout = setTimeout(function() { me.make_item_list(); }, 1000);
});
},
- make_barcode: function() {
+ make_item_group: function() {
var me = this;
- this.barcode = wn.ui.form.make_control({
+ this.item_group = wn.ui.form.make_control({
df: {
- "fieldtype": "Data",
- "label": "Barcode",
- "fieldname": "pos_barcode",
- "placeholder": "Barcode / Serial No"
+ "fieldtype": "Link",
+ "options": "Item Group",
+ "label": "Item Group",
+ "fieldname": "pos_item_group",
+ "placeholder": "Item Group"
},
- parent: this.wrapper.find(".barcode-area"),
+ parent: this.wrapper.find(".item-group-area"),
only_input: true,
});
- this.barcode.make_input();
- this.barcode.$input.on("keypress", function() {
- if(me.barcode_timeout)
- clearTimeout(me.barcode_timeout);
- me.barcode_timeout = setTimeout(function() { me.add_item_thru_barcode(); }, 1000);
+ this.item_group.make_input();
+ this.item_group.$input.on("change", function() {
+ if(!me.item_group.autocomplete_open)
+ me.make_item_list();
});
},
make_item_list: function() {
@@ -321,6 +339,7 @@ erpnext.POS = Class.extend({
refresh: function() {
var me = this;
this.party_field.set_input(this.frm.doc[this.party.toLowerCase()]);
+ this.wrapper.find('input.discount-amount').val(this.frm.doc.discount_amount);
this.barcode.set_input("");
this.show_items_in_item_cart();
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index 9c6a9b223d..136519e42b 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -25,7 +25,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
}
// toggle to pos view if is_pos is 1 in user_defaults
- if ((cint(wn.defaults.get_user_defaults("is_pos"))===1 || cur_frm.doc.is_pos)) {
+ if ((cint(wn.defaults.get_user_defaults("is_pos"))===1 || this.frm.doc.is_pos)) {
if(this.frm.doc.__islocal && !this.frm.doc.amended_from && !this.frm.doc.customer) {
this.frm.set_value("is_pos", 1);
this.is_pos(function() {
@@ -145,8 +145,8 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
me.set_default_values();
me.set_dynamic_labels();
me.calculate_taxes_and_totals();
-
- if(callback_fn) callback_fn()
+
+ if(callback_fn) callback_fn();
}
}
});
@@ -334,7 +334,7 @@ cur_frm.fields_dict['project_name'].get_query = function(doc, cdt, cdn) {
// --------------------------------
cur_frm.set_query("income_account", "entries", function(doc) {
return{
- query: "accounts.doctype.sales_invoice.sales_invoice.get_income_account",
+ query: "erpnext.accounts.doctype.sales_invoice.sales_invoice.get_income_account",
filters: {'company': doc.company}
}
});
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index f77abfe72a..4a059441fe 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -556,12 +556,12 @@ class DocType(SellingController):
def make_tax_gl_entries(self, gl_entries):
for tax in self.doclist.get({"parentfield": "other_charges"}):
- if flt(tax.tax_amount):
+ if flt(tax.tax_amount_after_discount_amount):
gl_entries.append(
self.get_gl_dict({
"account": tax.account_head,
"against": self.doc.debit_to,
- "credit": flt(tax.tax_amount),
+ "credit": flt(tax.tax_amount_after_discount_amount),
"remarks": self.doc.remarks,
"cost_center": tax.cost_center
})
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.txt b/erpnext/accounts/doctype/sales_invoice/sales_invoice.txt
index 7de68a06ed..66f7d32c3d 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.txt
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.txt
@@ -2,7 +2,7 @@
{
"creation": "2013-05-24 19:29:05",
"docstatus": 0,
- "modified": "2013-12-20 19:24:29",
+ "modified": "2014-01-03 14:52:16",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -455,6 +455,14 @@
"print_hide": 1,
"read_only": 1
},
+ {
+ "doctype": "DocField",
+ "fieldname": "discount_amount",
+ "fieldtype": "Currency",
+ "label": "Discount Amount",
+ "options": "Company:company:default_currency",
+ "print_hide": 0
+ },
{
"doctype": "DocField",
"fieldname": "totals",
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index c68b97a3b2..709507abc1 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -44,7 +44,6 @@ class TestSalesInvoice(unittest.TestCase):
def test_sales_invoice_calculation_base_currency(self):
si = webnotes.bean(copy=test_records[2])
- si.run_method("calculate_taxes_and_totals")
si.insert()
expected_values = {
@@ -136,7 +135,114 @@ class TestSalesInvoice(unittest.TestCase):
self.assertEquals(si.doc.grand_total, 1627.05)
self.assertEquals(si.doc.grand_total_export, 32.54)
+
+ def test_sales_invoice_discount_amount(self):
+ si = webnotes.bean(copy=test_records[3])
+ si.doc.discount_amount = 104.95
+ si.doclist.append({
+ "doctype": "Sales Taxes and Charges",
+ "parentfield": "other_charges",
+ "charge_type": "On Previous Row Amount",
+ "account_head": "_Test Account Service Tax - _TC",
+ "cost_center": "_Test Cost Center - _TC",
+ "description": "Service Tax",
+ "rate": 10,
+ "row_id": 8,
+ "idx": 9
+ })
+ si.insert()
+
+ expected_values = {
+ "keys": ["ref_rate", "adj_rate", "export_rate", "export_amount",
+ "base_ref_rate", "basic_rate", "amount"],
+ "_Test Item Home Desktop 100": [62.5, 0, 62.5, 625.0, 50, 50, 465.37],
+ "_Test Item Home Desktop 200": [190.66, 0, 190.66, 953.3, 150, 150, 698.08],
+ }
+
+ # check if children are saved
+ self.assertEquals(len(si.doclist.get({"parentfield": "entries"})),
+ len(expected_values)-1)
+
+ # check if item values are calculated
+ for d in si.doclist.get({"parentfield": "entries"}):
+ for i, k in enumerate(expected_values["keys"]):
+ self.assertEquals(d.fields.get(k), expected_values[d.item_code][i])
+
+ # check net total
+ self.assertEquals(si.doc.net_total, 1163.45)
+ self.assertEquals(si.doc.net_total_export, 1578.3)
+
+ # check tax calculation
+ expected_values = {
+ "keys": ["tax_amount", "tax_amount_after_discount_amount", "total"],
+ "_Test Account Excise Duty - _TC": [140, 130.31, 1293.76],
+ "_Test Account Education Cess - _TC": [2.8, 2.61, 1296.37],
+ "_Test Account S&H Education Cess - _TC": [1.4, 1.31, 1297.68],
+ "_Test Account CST - _TC": [27.88, 25.96, 1323.64],
+ "_Test Account VAT - _TC": [156.25, 145.43, 1469.07],
+ "_Test Account Customs Duty - _TC": [125, 116.35, 1585.42],
+ "_Test Account Shipping Charges - _TC": [100, 100, 1685.42],
+ "_Test Account Discount - _TC": [-180.33, -168.54, 1516.88],
+ "_Test Account Service Tax - _TC": [-18.03, -16.88, 1500]
+ }
+
+ for d in si.doclist.get({"parentfield": "other_charges"}):
+ for i, k in enumerate(expected_values["keys"]):
+ self.assertEquals(d.fields.get(k), expected_values[d.account_head][i])
+ self.assertEquals(si.doc.grand_total, 1500)
+ self.assertEquals(si.doc.grand_total_export, 1500)
+
+ def test_discount_amount_gl_entry(self):
+ si = webnotes.bean(copy=test_records[3])
+ si.doc.discount_amount = 104.95
+ si.doclist.append({
+ "doctype": "Sales Taxes and Charges",
+ "parentfield": "other_charges",
+ "charge_type": "On Previous Row Amount",
+ "account_head": "_Test Account Service Tax - _TC",
+ "cost_center": "_Test Cost Center - _TC",
+ "description": "Service Tax",
+ "rate": 10,
+ "row_id": 8,
+ "idx": 9
+ })
+ si.insert()
+ si.submit()
+
+ gl_entries = webnotes.conn.sql("""select account, debit, credit
+ from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
+ order by account asc""", si.doc.name, as_dict=1)
+
+ self.assertTrue(gl_entries)
+
+ expected_values = sorted([
+ [si.doc.debit_to, 1500, 0.0],
+ [test_records[3][1]["income_account"], 0.0, 1163.45],
+ [test_records[3][3]["account_head"], 0.0, 130.31],
+ [test_records[3][4]["account_head"], 0.0, 2.61],
+ [test_records[3][5]["account_head"], 0.0, 1.31],
+ [test_records[3][6]["account_head"], 0.0, 25.96],
+ [test_records[3][7]["account_head"], 0.0, 145.43],
+ [test_records[3][8]["account_head"], 0.0, 116.35],
+ [test_records[3][9]["account_head"], 0.0, 100],
+ [test_records[3][10]["account_head"], 168.54, 0.0],
+ ["_Test Account Service Tax - _TC", 16.88, 0.0],
+ ])
+
+ for i, gle in enumerate(gl_entries):
+ self.assertEquals(expected_values[i][0], gle.account)
+ self.assertEquals(expected_values[i][1], gle.debit)
+ self.assertEquals(expected_values[i][2], gle.credit)
+
+ # cancel
+ si.cancel()
+
+ gle = webnotes.conn.sql("""select * from `tabGL Entry`
+ where voucher_type='Sales Invoice' and voucher_no=%s""", si.doc.name)
+
+ self.assertFalse(gle)
+
def test_inclusive_rate_validations(self):
si = webnotes.bean(copy=test_records[2])
for i, tax in enumerate(si.doclist.get({"parentfield": "other_charges"})):
@@ -148,16 +254,15 @@ class TestSalesInvoice(unittest.TestCase):
si.doclist[i].included_in_print_rate = 1
# tax type "Actual" cannot be inclusive
- self.assertRaises(webnotes.ValidationError, si.run_method, "calculate_taxes_and_totals")
+ self.assertRaises(webnotes.ValidationError, si.insert)
# taxes above included type 'On Previous Row Total' should also be included
si.doclist[3].included_in_print_rate = 0
- self.assertRaises(webnotes.ValidationError, si.run_method, "calculate_taxes_and_totals")
+ self.assertRaises(webnotes.ValidationError, si.insert)
def test_sales_invoice_calculation_base_currency_with_tax_inclusive_price(self):
# prepare
si = webnotes.bean(copy=test_records[3])
- si.run_method("calculate_taxes_and_totals")
si.insert()
expected_values = {
@@ -195,7 +300,7 @@ class TestSalesInvoice(unittest.TestCase):
for d in si.doclist.get({"parentfield": "other_charges"}):
for i, k in enumerate(expected_values["keys"]):
- self.assertEquals(flt(d.fields.get(k), 6), expected_values[d.account_head][i])
+ self.assertEquals(d.fields.get(k), expected_values[d.account_head][i])
self.assertEquals(si.doc.grand_total, 1622.98)
self.assertEquals(si.doc.grand_total_export, 1622.98)
@@ -211,7 +316,6 @@ class TestSalesInvoice(unittest.TestCase):
si.doclist[2].adj_rate = 20
si.doclist[9].rate = 5000
- si.run_method("calculate_taxes_and_totals")
si.insert()
expected_values = {
@@ -249,7 +353,7 @@ class TestSalesInvoice(unittest.TestCase):
for d in si.doclist.get({"parentfield": "other_charges"}):
for i, k in enumerate(expected_values["keys"]):
- self.assertEquals(flt(d.fields.get(k), 6), expected_values[d.account_head][i])
+ self.assertEquals(d.fields.get(k), expected_values[d.account_head][i])
self.assertEquals(si.doc.grand_total, 65205.16)
self.assertEquals(si.doc.grand_total_export, 1304.1)
@@ -403,7 +507,6 @@ class TestSalesInvoice(unittest.TestCase):
pr = webnotes.bean(copy=pr_test_records[0])
pr.doc.naming_series = "_T-Purchase Receipt-"
pr.doclist[1].warehouse = "_Test Warehouse No Account - _TC"
- pr.run_method("calculate_taxes_and_totals")
pr.insert()
pr.submit()
@@ -448,7 +551,7 @@ class TestSalesInvoice(unittest.TestCase):
self.assertFalse(gle)
set_perpetual_inventory(0)
- def test_sales_invoice_gl_entry_with_aii_no_item_code(self):
+ def test_sales_invoice_gl_entry_with_aii_no_item_code(self):
self.clear_stock_account_balance()
set_perpetual_inventory()
@@ -508,7 +611,6 @@ class TestSalesInvoice(unittest.TestCase):
as pr_test_records
pr = webnotes.bean(copy=pr_test_records[0])
pr.doc.naming_series = "_T-Purchase Receipt-"
- pr.run_method("calculate_taxes_and_totals")
pr.insert()
pr.submit()
diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.txt b/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.txt
index 49df5f7291..8bb154cb7f 100644
--- a/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.txt
+++ b/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.txt
@@ -2,7 +2,7 @@
{
"creation": "2013-04-24 11:39:32",
"docstatus": 0,
- "modified": "2013-12-31 17:51:47",
+ "modified": "2014-01-03 15:04:25",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -132,12 +132,21 @@
"report_hide": 1,
"width": "150px"
},
+ {
+ "doctype": "DocField",
+ "fieldname": "tax_amount_after_discount_amount",
+ "fieldtype": "Currency",
+ "hidden": 1,
+ "label": "Tax Amount After Discount Amount",
+ "options": "Company:company:default_currency",
+ "read_only": 1
+ },
{
"doctype": "DocField",
"fieldname": "item_wise_tax_detail",
"fieldtype": "Small Text",
"hidden": 1,
- "label": "Item Wise Tax Detail ",
+ "label": "Item Wise Tax Detail",
"oldfieldname": "item_wise_tax_detail",
"oldfieldtype": "Small Text",
"read_only": 1
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 0cdead9030..0e9b3db6c0 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
@@ -19,6 +19,10 @@ cur_frm.pformat.net_total_export = function(doc) {
return '';
}
+cur_frm.pformat.discount_amount = function(doc) {
+ return '';
+}
+
cur_frm.pformat.grand_total_export = function(doc) {
return '';
}
@@ -33,10 +37,10 @@ cur_frm.pformat.in_words_export = function(doc) {
cur_frm.pformat.other_charges= function(doc){
//function to make row of table
- var make_row = function(title,val,bold){
+ var make_row = function(title, val, bold){
var bstart = ''; var bend = '';
- return '
'+(bold?bstart:'')+title+(bold?bend:'')+' | '
- +''+format_currency(val, doc.currency)+' | '
+ return '
' + (bold?bstart:'') + title + (bold?bend:'') + ' | '
+ +'' + format_currency(val, doc.currency) + ' | '
+'
'
}
@@ -52,7 +56,7 @@ cur_frm.pformat.other_charges= function(doc){
out ='';
if (!doc.print_without_amount) {
- var cl = getchildren('Sales Taxes and Charges',doc.name,'other_charges');
+ var cl = getchildren('Sales Taxes and Charges', doc.name, 'other_charges');
// outer table
var out=' | ';
@@ -60,6 +64,7 @@ cur_frm.pformat.other_charges= function(doc){
// main table
out +='';
+
if(!print_hide('net_total_export')) {
out += make_row('Net Total', doc.net_total_export, 1);
}
@@ -68,26 +73,31 @@ cur_frm.pformat.other_charges= function(doc){
if(cl.length){
for(var i=0;i';
out += '';
out += 'In Words | '
- out+= ''+doc.in_words_export+' | '
+ out += '' + doc.in_words_export + ' | '
}
- out +='
| ';
+ out += ' |
';
}
return out;
}
@@ -99,7 +109,7 @@ cur_frm.cscript.charge_type = function(doc, cdt, cdn) {
d.charge_type = '';
}
validated = false;
- refresh_field('charge_type',d.name,'other_charges');
+ refresh_field('charge_type', d.name, 'other_charges');
cur_frm.cscript.row_id(doc, cdt, cdn);
cur_frm.cscript.rate(doc, cdt, cdn);
cur_frm.cscript.tax_amount(doc, cdt, cdn);
@@ -122,7 +132,7 @@ cur_frm.cscript.row_id = function(doc, cdt, cdn) {
}
}
validated = false;
- refresh_field('row_id',d.name,'other_charges');
+ refresh_field('row_id', d.name, 'other_charges');
}
/*---------------------- Get rate if account_head has account_type as TAX or CHARGEABLE-------------------------------------*/
@@ -152,7 +162,7 @@ cur_frm.cscript.rate = function(doc, cdt, cdn) {
d.rate = '';
}
validated = false;
- refresh_field('rate',d.name,'other_charges');
+ refresh_field('rate', d.name, 'other_charges');
}
cur_frm.cscript.tax_amount = function(doc, cdt, cdn) {
@@ -166,5 +176,5 @@ cur_frm.cscript.tax_amount = function(doc, cdt, cdn) {
d.tax_amount = '';
}
validated = false;
- refresh_field('tax_amount',d.name,'other_charges');
+ refresh_field('tax_amount', d.name, 'other_charges');
};
\ No newline at end of file
diff --git a/erpnext/accounts/report/sales_register/sales_register.py b/erpnext/accounts/report/sales_register/sales_register.py
index 49b914e4a3..8fab6a9d97 100644
--- a/erpnext/accounts/report/sales_register/sales_register.py
+++ b/erpnext/accounts/report/sales_register/sales_register.py
@@ -79,7 +79,7 @@ def get_columns(invoice_list):
tax_accounts = webnotes.conn.sql_list("""select distinct account_head
from `tabSales Taxes and Charges` where parenttype = 'Sales Invoice'
- and docstatus = 1 and ifnull(tax_amount, 0) != 0
+ and docstatus = 1 and ifnull(tax_amount_after_discount_amount, 0) != 0
and parent in (%s) order by account_head""" %
', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]))
@@ -126,7 +126,8 @@ def get_invoice_income_map(invoice_list):
return invoice_income_map
def get_invoice_tax_map(invoice_list, invoice_income_map, income_accounts):
- tax_details = webnotes.conn.sql("""select parent, account_head, sum(tax_amount) as tax_amount
+ tax_details = webnotes.conn.sql("""select parent, account_head,
+ sum(tax_amount_after_discount_amount) as tax_amount
from `tabSales Taxes and Charges` where parent in (%s) group by parent, account_head""" %
', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)
diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.js b/erpnext/buying/doctype/purchase_common/purchase_common.js
index cc24925905..f528f6cf1b 100644
--- a/erpnext/buying/doctype/purchase_common/purchase_common.js
+++ b/erpnext/buying/doctype/purchase_common/purchase_common.js
@@ -360,6 +360,14 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({
});
}
}
+
+ if(this.frm.tax_doclist.length) {
+ if(!wn.meta.get_docfield(this.frm.tax_doclist[0].doctype, "tax_amount_after_discount_amount", this.frm.doctype)) {
+ $.each(this.frm.tax_doclist, function(i, tax) {
+ delete tax["tax_amount_after_discount_amount"];
+ });
+ }
+ }
},
calculate_outstanding_amount: function() {
diff --git a/erpnext/buying/doctype/purchase_order/test_purchase_order.py b/erpnext/buying/doctype/purchase_order/test_purchase_order.py
index 3659f6ddee..eafb3f34f0 100644
--- a/erpnext/buying/doctype/purchase_order/test_purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/test_purchase_order.py
@@ -1,7 +1,6 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
-
from __future__ import unicode_literals
import unittest
import webnotes
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index d48a7a6d17..e7393eb735 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -133,6 +133,12 @@ class AccountsController(TransactionBase):
self.doclist.append(tax)
def calculate_taxes_and_totals(self):
+ self.discount_amount_applied = False
+ self._calculate_taxes_and_totals()
+ if self.meta.get_field(self.doc.doctype, "discount_amount"):
+ self.apply_discount_amount()
+
+ def _calculate_taxes_and_totals(self):
# validate conversion rate
company_currency = get_company_currency(self.doc.company)
if not self.doc.currency or self.doc.currency == company_currency:
@@ -141,7 +147,7 @@ class AccountsController(TransactionBase):
else:
validate_conversion_rate(self.doc.currency, self.doc.conversion_rate,
self.meta.get_label("conversion_rate"), self.doc.company)
-
+
self.doc.conversion_rate = flt(self.doc.conversion_rate)
self.item_doclist = self.doclist.get({"parentfield": self.fname})
self.tax_doclist = self.doclist.get({"parentfield": self.other_fname})
@@ -157,17 +163,19 @@ class AccountsController(TransactionBase):
self.calculate_totals()
self._cleanup()
- # TODO
- # print format: show net_total_export instead of net_total
-
def initialize_taxes(self):
for tax in self.tax_doclist:
tax.item_wise_tax_detail = {}
- for fieldname in ["tax_amount", "total",
- "tax_amount_for_current_item", "grand_total_for_current_item",
- "tax_fraction_for_current_item", "grand_total_fraction_for_current_item"]:
- tax.fields[fieldname] = 0.0
-
+ tax_fields = ["total", "tax_amount_after_discount_amount",
+ "tax_amount_for_current_item", "grand_total_for_current_item",
+ "tax_fraction_for_current_item", "grand_total_fraction_for_current_item"]
+
+ if not self.discount_amount_applied:
+ tax_fields.append("tax_amount")
+
+ for fieldname in tax_fields:
+ tax.fields[fieldname] = 0.0
+
self.validate_on_previous_row(tax)
self.validate_inclusive_tax(tax)
self.round_floats_in(tax)
@@ -215,39 +223,44 @@ class AccountsController(TransactionBase):
"charge_type": tax.charge_type,
}, raise_exception=True)
elif tax.charge_type == "On Previous Row Amount" and \
- not cint(self.tax_doclist[tax.row_id - 1].included_in_print_rate):
+ not cint(self.tax_doclist[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.tax_doclist[:tax.row_id - 1]]):
+ not all([cint(t.included_in_print_rate) for t in self.tax_doclist[:cint(tax.row_id) - 1]]):
# all rows about the reffered tax should be inclusive
_on_previous_row_error("1 - %d" % (tax.row_id,))
def calculate_taxes(self):
- for item in self.item_doclist:
+ # maintain actual tax rate based on idx
+ actual_tax_dict = dict([[tax.idx, tax.rate] for tax in self.tax_doclist
+ if tax.charge_type == "Actual"])
+
+ for n, item in enumerate(self.item_doclist):
item_tax_map = self._load_item_tax_rate(item.item_tax_rate)
for i, tax in enumerate(self.tax_doclist):
# tax_amount represents the amount of tax for the current step
current_tax_amount = self.get_current_tax_amount(item, tax, item_tax_map)
+
+ # Adjust divisional loss to the last item
+ if tax.charge_type == "Actual":
+ actual_tax_dict[tax.idx] -= current_tax_amount
+ if n == len(self.item_doclist) - 1:
+ current_tax_amount += actual_tax_dict[tax.idx]
if hasattr(self, "set_item_tax_amount"):
self.set_item_tax_amount(item, tax, current_tax_amount)
- # case when net total is 0 but there is an actual type charge
- # in this case add the actual amount to tax.tax_amount
- # and tax.grand_total_for_current_item for the first such iteration
- if tax.charge_type=="Actual" and \
- not (current_tax_amount or self.doc.net_total or tax.tax_amount):
- zero_net_total_adjustment = flt(tax.rate, self.precision("tax_amount", tax))
- current_tax_amount += zero_net_total_adjustment
-
# store tax_amount for current item as it will be used for
# charge type = 'On Previous Row Amount'
tax.tax_amount_for_current_item = current_tax_amount
# accumulate tax amount into tax.tax_amount
- tax.tax_amount += current_tax_amount
+ if not self.discount_amount_applied:
+ tax.tax_amount += current_tax_amount
+
+ tax.tax_amount_after_discount_amount += current_tax_amount
if tax.category:
# if just for valuation, do not add the tax amount in total
@@ -260,17 +273,36 @@ class AccountsController(TransactionBase):
# note: grand_total_for_current_item contains the contribution of
# item's amount, previously applied tax and the current tax on that item
if i==0:
- tax.grand_total_for_current_item = flt(item.amount +
- current_tax_amount, self.precision("total", tax))
-
+ tax.grand_total_for_current_item = flt(item.amount + current_tax_amount,
+ self.precision("total", tax))
else:
tax.grand_total_for_current_item = \
- flt(self.tax_doclist[i-1].grand_total_for_current_item +
+ flt(self.tax_doclist[i-1].grand_total_for_current_item +
current_tax_amount, self.precision("total", tax))
# in tax.total, accumulate grand total of each item
tax.total += tax.grand_total_for_current_item
-
+
+ # set precision in the last item iteration
+ if n == len(self.item_doclist) - 1:
+ self.round_off_totals(tax)
+
+ # adjust Discount Amount loss in last tax iteration
+ if i == (len(self.tax_doclist) - 1) and self.discount_amount_applied:
+ self.adjust_discount_amount_loss(tax)
+
+ def round_off_totals(self, tax):
+ tax.total = flt(tax.total, self.precision("total", tax))
+ tax.tax_amount = flt(tax.tax_amount, self.precision("tax_amount", tax))
+ tax.tax_amount_after_discount_amount = flt(tax.tax_amount_after_discount_amount,
+ self.precision("tax_amount", tax))
+
+ def adjust_discount_amount_loss(self, tax):
+ discount_amount_loss = self.doc.grand_total - flt(self.doc.discount_amount) - tax.total
+ tax.tax_amount_after_discount_amount = flt(tax.tax_amount_after_discount_amount +
+ discount_amount_loss, self.precision("tax_amount", tax))
+ tax.total = flt(tax.total + discount_amount_loss, self.precision("total", tax))
+
def get_current_tax_amount(self, item, tax, item_tax_map):
tax_rate = self._get_tax_rate(tax, item_tax_map)
current_tax_amount = 0.0
@@ -289,9 +321,9 @@ class AccountsController(TransactionBase):
elif tax.charge_type == "On Previous Row Total":
current_tax_amount = (tax_rate / 100.0) * \
self.tax_doclist[cint(tax.row_id) - 1].grand_total_for_current_item
-
+
current_tax_amount = flt(current_tax_amount, self.precision("tax_amount", tax))
-
+
# store tax breakup for each item
key = item.item_code or item.item_name
if tax.item_wise_tax_detail.get(key):
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 40de926ea0..f630f5ae83 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -5,7 +5,6 @@ from __future__ import unicode_literals
import webnotes
from webnotes import _, msgprint
from webnotes.utils import flt, _round
-
from erpnext.buying.utils import get_item_details
from erpnext.setup.utils import get_company_currency
@@ -148,7 +147,7 @@ class BuyingController(StockController):
def _cleanup(self):
super(BuyingController, self)._cleanup()
- # except in purchase invoice, rate field is purchase_rate
+ # except in purchase invoice, rate field is purchase_rate
# reset fieldname of rate
if self.doc.doctype != "Purchase Invoice":
df = self.meta.get_field("rate", parentfield=self.fname)
@@ -161,6 +160,10 @@ class BuyingController(StockController):
if not self.meta.get_field("item_tax_amount", parentfield=self.fname):
for item in self.item_doclist:
del item.fields["item_tax_amount"]
+
+ if not self.meta.get_field("tax_amount_after_discount_amount", parentfield=self.other_fname):
+ for tax in self.tax_doclist:
+ del tax.fields["tax_amount_after_discount_amount"]
def set_item_tax_amount(self, item, tax, current_tax_amount):
"""
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index f950f28181..04bcfaeb04 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -121,7 +121,7 @@ class SellingController(StockController):
cumulated_tax_fraction += tax.tax_fraction_for_current_item
- if cumulated_tax_fraction:
+ if cumulated_tax_fraction and not self.discount_amount_applied:
item.amount = flt((item.export_amount * self.doc.conversion_rate) /
(1 + cumulated_tax_fraction), self.precision("amount", item))
@@ -158,22 +158,23 @@ class SellingController(StockController):
return current_tax_fraction
def calculate_item_values(self):
- for item in self.item_doclist:
- self.round_floats_in(item)
-
- if item.adj_rate == 100:
- item.export_rate = 0
- elif not item.export_rate:
- item.export_rate = flt(item.ref_rate * (1.0 - (item.adj_rate / 100.0)),
- self.precision("export_rate", item))
-
- item.export_amount = flt(item.export_rate * item.qty,
- self.precision("export_amount", item))
+ if not self.discount_amount_applied:
+ for item in self.item_doclist:
+ self.round_floats_in(item)
+
+ if item.adj_rate == 100:
+ item.export_rate = 0
+ elif not item.export_rate:
+ item.export_rate = flt(item.ref_rate * (1.0 - (item.adj_rate / 100.0)),
+ self.precision("export_rate", item))
+
+ item.export_amount = flt(item.export_rate * item.qty,
+ self.precision("export_amount", item))
+
+ self._set_in_company_currency(item, "ref_rate", "base_ref_rate")
+ self._set_in_company_currency(item, "export_rate", "basic_rate")
+ self._set_in_company_currency(item, "export_amount", "amount")
- self._set_in_company_currency(item, "ref_rate", "base_ref_rate")
- self._set_in_company_currency(item, "export_rate", "basic_rate")
- self._set_in_company_currency(item, "export_amount", "amount")
-
def calculate_net_total(self):
self.doc.net_total = self.doc.net_total_export = 0.0
@@ -191,12 +192,40 @@ class SellingController(StockController):
self.doc.other_charges_total = flt(self.doc.grand_total - self.doc.net_total,
self.precision("other_charges_total"))
- self.doc.other_charges_total_export = flt(self.doc.grand_total_export - self.doc.net_total_export,
- self.precision("other_charges_total_export"))
+ self.doc.other_charges_total_export = flt(self.doc.grand_total_export -
+ self.doc.net_total_export + flt(self.doc.discount_amount), self.precision("other_charges_total_export"))
self.doc.rounded_total = _round(self.doc.grand_total)
self.doc.rounded_total_export = _round(self.doc.grand_total_export)
-
+
+ def apply_discount_amount(self):
+ if self.doc.discount_amount:
+ grand_total_for_discount_amount = self.get_grand_total_for_discount_amount()
+
+ if grand_total_for_discount_amount:
+ # calculate item amount after Discount Amount
+ for item in self.item_doclist:
+ distributed_amount = flt(self.doc.discount_amount) * item.amount / grand_total_for_discount_amount
+ item.amount = flt(item.amount - distributed_amount, self.precision("amount", item))
+
+ self.discount_amount_applied = True
+ self._calculate_taxes_and_totals()
+
+ def get_grand_total_for_discount_amount(self):
+ actual_taxes_dict = {}
+
+ for tax in self.tax_doclist:
+ if tax.charge_type == "Actual":
+ actual_taxes_dict.setdefault(tax.idx, tax.tax_amount)
+ elif tax.row_id in actual_taxes_dict:
+ actual_tax_amount = flt(actual_taxes_dict.get(tax.row_id, 0)) * \
+ flt(tax.rate) / 100
+ actual_taxes_dict.setdefault(tax.idx, actual_tax_amount)
+
+ grand_total_for_discount_amount = flt(self.doc.grand_total - sum(actual_taxes_dict.values()),
+ self.precision("grand_total"))
+ return grand_total_for_discount_amount
+
def calculate_outstanding_amount(self):
# NOTE:
# write_off_amount is only for POS Invoice
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index c1ab098298..f39e214245 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -1,3 +1,21 @@
erpnext.patches.4_0.update_user_properties
erpnext.patches.4_0.move_warehouse_user_to_restrictions
-erpnext.patches.4_0.new_permissions
\ No newline at end of file
+erpnext.patches.4_0.new_permissions
+
+execute:webnotes.reload_doc('accounts', 'doctype', 'sales_invoice') # 2014-01-03
+execute:webnotes.reload_doc('selling', 'doctype', 'sales_order') # 2014-01-03
+execute:webnotes.reload_doc('selling', 'doctype', 'quotation') # 2014-01-03
+execute:webnotes.reload_doc('stock', 'doctype', 'delivery_note') # 2014-01-03
+execute:webnotes.reload_doc('accounts', 'Print Format', 'POS Invoice') # 2014-01-03
+execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Classic') # 2014-01-03
+execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Modern') # 2014-01-03
+execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Spartan') # 2014-01-03
+execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Classic') # 2014-01-03
+execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Modern') # 2014-01-03
+execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Spartan') # 2014-01-03
+execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Classic') # 2014-01-03
+execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Modern') # 2014-01-03
+execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Spartan') # 2014-01-03
+execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Classic') # 2014-01-03
+execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Modern') # 2014-01-03
+execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Spartan') # 2014-01-03
\ No newline at end of file
diff --git a/erpnext/patches/patch_list.py b/erpnext/patches/patch_list.py
index e455913f59..002e3c7084 100644
--- a/erpnext/patches/patch_list.py
+++ b/erpnext/patches/patch_list.py
@@ -172,18 +172,18 @@ patch_list = [
"patches.july_2013.p05_custom_doctypes_in_list_view",
"patches.july_2013.p06_same_sales_rate",
"patches.july_2013.p07_repost_billed_amt_in_sales_cycle",
- "execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Classic') # 2013-07-22",
- "execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Modern') # 2013-07-22",
- "execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Spartan') # 2013-07-22",
- "execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Classic') # 2013-07-22",
- "execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Modern') # 2013-07-22",
- "execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Spartan') # 2013-07-22",
- "execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Classic') # 2013-07-22",
- "execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Modern') # 2013-07-22",
- "execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Spartan') # 2013-07-22",
- "execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Classic') # 2013-07-22",
- "execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Modern') # 2013-07-22",
- "execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Spartan') # 2013-07-22",
+ "execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Classic') # 2013-12-26",
+ "execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Modern') # 2013-12-26",
+ "execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Spartan') # 2013-12-26",
+ "execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Classic') # 2013-12-26",
+ "execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Modern') # 2013-12-26",
+ "execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Spartan') # 2013-12-26",
+ "execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Classic') # 2013-12-26",
+ "execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Modern') # 2013-12-26",
+ "execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Spartan') # 2013-12-26",
+ "execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Classic') # 2013-12-26",
+ "execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Modern') # 2013-12-26",
+ "execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Spartan') # 2013-12-26",
"patches.july_2013.p08_custom_print_format_net_total_export",
"patches.july_2013.p09_remove_website_pyc",
"patches.july_2013.p10_change_partner_user_to_website_user",
@@ -262,4 +262,9 @@ patch_list = [
"execute:webnotes.delete_doc('DocType', 'Warehouse Type')",
"patches.1312.p01_delete_old_stock_reports",
"patches.1312.p02_update_item_details_in_item_price",
+ "execute:webnotes.reload_doc('accounts', 'Print Format', 'POS Invoice') # 2013-12-26",
+ "execute:webnotes.reload_doc('accounts', 'doctype', 'sales_invoice') # 2013-12-26",
+ "execute:webnotes.reload_doc('selling', 'doctype', 'sales_order') # 2013-12-26",
+ "execute:webnotes.reload_doc('selling', 'doctype', 'quotation') # 2013-12-26",
+ "execute:webnotes.reload_doc('stock', 'doctype', 'delivery_note') # 2013-12-26",
]
\ No newline at end of file
diff --git a/erpnext/public/js/transaction.js b/erpnext/public/js/transaction.js
index 5b48820c9c..7db7aef51d 100644
--- a/erpnext/public/js/transaction.js
+++ b/erpnext/public/js/transaction.js
@@ -511,10 +511,17 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
},
calculate_taxes_and_totals: function() {
+ this.discount_amount_applied = false;
+ this._calculate_taxes_and_totals();
+ if (wn.meta.get_docfield(this.frm.doc.doctype, "discount_amount"))
+ this.apply_discount_amount();
+ },
+
+ _calculate_taxes_and_totals: function() {
this.validate_conversion_rate();
this.frm.item_doclist = this.get_item_doclist();
this.frm.tax_doclist = this.get_tax_doclist();
-
+
this.calculate_item_values();
this.initialize_taxes();
this.determine_exclusive_rate && this.determine_exclusive_rate();
@@ -522,18 +529,23 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
this.calculate_taxes();
this.calculate_totals();
this._cleanup();
-
+
this.show_item_wise_taxes();
},
initialize_taxes: function() {
var me = this;
+
$.each(this.frm.tax_doclist, function(i, tax) {
tax.item_wise_tax_detail = {};
- $.each(["tax_amount", "total",
+ tax_fields = ["total", "tax_amount_after_discount_amount",
"tax_amount_for_current_item", "grand_total_for_current_item",
- "tax_fraction_for_current_item", "grand_total_fraction_for_current_item"],
- function(i, fieldname) { tax[fieldname] = 0.0 });
+ "tax_fraction_for_current_item", "grand_total_fraction_for_current_item"]
+
+ if (!me.discount_amount_applied)
+ tax_fields.push("tax_amount");
+
+ $.each(tax_fields, function(i, fieldname) { tax[fieldname] = 0.0 });
me.validate_on_previous_row(tax);
me.validate_inclusive_tax(tax);
@@ -543,31 +555,41 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
calculate_taxes: function() {
var me = this;
+ var actual_tax_dict = {};
+ // maintain actual tax rate based on idx
+ $.each(this.frm.tax_doclist, function(i, tax) {
+ if (tax.charge_type == "Actual") {
+ actual_tax_dict[tax.idx] = flt(tax.rate);
+ }
+ });
+
$.each(this.frm.item_doclist, function(n, item) {
var item_tax_map = me._load_item_tax_rate(item.item_tax_rate);
-
+
$.each(me.frm.tax_doclist, function(i, tax) {
// tax_amount represents the amount of tax for the current step
var current_tax_amount = me.get_current_tax_amount(item, tax, item_tax_map);
- me.set_item_tax_amount && me.set_item_tax_amount(item, tax, current_tax_amount);
-
- // case when net total is 0 but there is an actual type charge
- // in this case add the actual amount to tax.tax_amount
- // and tax.grand_total_for_current_item for the first such iteration
- if(tax.charge_type == "Actual" &&
- !(current_tax_amount || me.frm.doc.net_total || tax.tax_amount)) {
- var zero_net_total_adjustment = flt(tax.rate, precision("tax_amount", tax));
- current_tax_amount += zero_net_total_adjustment;
+ // Adjust divisional loss to the last item
+ if (tax.charge_type == "Actual") {
+ actual_tax_dict[tax.idx] -= current_tax_amount;
+ if (n == me.frm.item_doclist.length - 1) {
+ current_tax_amount += actual_tax_dict[tax.idx]
}
-
+ }
+
+ me.set_item_tax_amount && me.set_item_tax_amount(item, tax, current_tax_amount);
+
// store tax_amount for current item as it will be used for
// charge type = 'On Previous Row Amount'
tax.tax_amount_for_current_item = current_tax_amount;
// accumulate tax amount into tax.tax_amount
- tax.tax_amount += current_tax_amount;
+ if (!me.discount_amount_applied)
+ tax.tax_amount += current_tax_amount;
+
+ tax.tax_amount_after_discount_amount += current_tax_amount;
// for buying
if(tax.category) {
@@ -592,9 +614,32 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
// in tax.total, accumulate grand total for each item
tax.total += tax.grand_total_for_current_item;
+
+ // set precision in the last item iteration
+ if (n == me.frm.item_doclist.length - 1) {
+ me.round_off_totals(tax);
+
+ // adjust Discount Amount loss in last tax iteration
+ if ((i == me.frm.tax_doclist.length - 1) && me.discount_amount_applied)
+ me.adjust_discount_amount_loss(tax);
+ }
});
});
},
+
+ round_off_totals: function(tax) {
+ tax.total = flt(tax.total, precision("total", tax));
+ tax.tax_amount = flt(tax.tax_amount, precision("tax_amount", tax));
+ tax.tax_amount_after_discount_amount = flt(tax.tax_amount_after_discount_amount,
+ precision("tax_amount", tax));
+ },
+
+ adjust_discount_amount_loss: function(tax) {
+ var discount_amount_loss = this.frm.doc.grand_total - flt(this.frm.doc.discount_amount) - tax.total;
+ tax.tax_amount_after_discount_amount = flt(tax.tax_amount_after_discount_amount +
+ discount_amount_loss, precision("tax_amount", tax));
+ tax.total = flt(tax.total + discount_amount_loss, precision("total", tax));
+ },
get_current_tax_amount: function(item, tax, item_tax_map) {
var tax_rate = this._get_tax_rate(tax, item_tax_map);
@@ -617,9 +662,8 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
} else if(tax.charge_type == "On Previous Row Total") {
current_tax_amount = (tax_rate / 100.0) *
this.frm.tax_doclist[cint(tax.row_id) - 1].grand_total_for_current_item;
-
}
-
+
current_tax_amount = flt(current_tax_amount, precision("tax_amount", tax));
// store tax breakup for each item
diff --git a/erpnext/selling/Print Format/Quotation Classic/Quotation Classic.txt b/erpnext/selling/Print Format/Quotation Classic/Quotation Classic.txt
index e7588c4522..05c3c598ca 100644
--- a/erpnext/selling/Print Format/Quotation Classic/Quotation Classic.txt
+++ b/erpnext/selling/Print Format/Quotation Classic/Quotation Classic.txt
@@ -2,14 +2,14 @@
{
"creation": "2013-04-19 13:30:51",
"docstatus": 0,
- "modified": "2013-08-07 19:55:11",
+ "modified": "2013-12-26 17:45:37",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"doc_type": "Quotation",
"doctype": "Print Format",
- "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n\n",
+ "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n",
"module": "Selling",
"name": "__common__",
"print_format_type": "Client",
diff --git a/erpnext/selling/Print Format/Quotation Modern/Quotation Modern.txt b/erpnext/selling/Print Format/Quotation Modern/Quotation Modern.txt
index 20d380dcbf..35850e62eb 100644
--- a/erpnext/selling/Print Format/Quotation Modern/Quotation Modern.txt
+++ b/erpnext/selling/Print Format/Quotation Modern/Quotation Modern.txt
@@ -2,14 +2,14 @@
{
"creation": "2013-04-19 13:30:51",
"docstatus": 0,
- "modified": "2013-08-07 20:12:11",
+ "modified": "2013-12-26 17:45:15",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"doc_type": "Quotation",
"doctype": "Print Format",
- "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n\n",
+ "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n",
"module": "Selling",
"name": "__common__",
"print_format_type": "Client",
diff --git a/erpnext/selling/Print Format/Quotation Spartan/Quotation Spartan.txt b/erpnext/selling/Print Format/Quotation Spartan/Quotation Spartan.txt
index c5b4cb92b3..3b4452666b 100644
--- a/erpnext/selling/Print Format/Quotation Spartan/Quotation Spartan.txt
+++ b/erpnext/selling/Print Format/Quotation Spartan/Quotation Spartan.txt
@@ -2,14 +2,14 @@
{
"creation": "2013-04-19 13:30:51",
"docstatus": 0,
- "modified": "2013-08-07 19:53:01",
+ "modified": "2013-12-26 17:45:50",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"doc_type": "Quotation",
"doctype": "Print Format",
- "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n\n",
+ "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n",
"module": "Selling",
"name": "__common__",
"print_format_type": "Client",
diff --git a/erpnext/selling/Print Format/Sales Order Classic/Sales Order Classic.txt b/erpnext/selling/Print Format/Sales Order Classic/Sales Order Classic.txt
index 7f2748ac0c..7ee19c0f2d 100644
--- a/erpnext/selling/Print Format/Sales Order Classic/Sales Order Classic.txt
+++ b/erpnext/selling/Print Format/Sales Order Classic/Sales Order Classic.txt
@@ -2,14 +2,14 @@
{
"creation": "2013-04-19 13:30:51",
"docstatus": 0,
- "modified": "2013-08-07 19:45:49",
+ "modified": "2013-12-26 17:35:51",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"doc_type": "Sales Order",
"doctype": "Print Format",
- "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n\n",
+ "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n",
"module": "Selling",
"name": "__common__",
"print_format_type": "Client",
diff --git a/erpnext/selling/Print Format/Sales Order Modern/Sales Order Modern.txt b/erpnext/selling/Print Format/Sales Order Modern/Sales Order Modern.txt
index e4102b2359..7cf481d7b8 100644
--- a/erpnext/selling/Print Format/Sales Order Modern/Sales Order Modern.txt
+++ b/erpnext/selling/Print Format/Sales Order Modern/Sales Order Modern.txt
@@ -2,14 +2,14 @@
{
"creation": "2013-04-19 13:30:51",
"docstatus": 0,
- "modified": "2013-08-07 20:12:23",
+ "modified": "2013-12-26 17:34:24",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"doc_type": "Sales Order",
"doctype": "Print Format",
- "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n\n",
+ "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n",
"module": "Selling",
"name": "__common__",
"print_format_type": "Client",
diff --git a/erpnext/selling/Print Format/Sales Order Spartan/Sales Order Spartan.txt b/erpnext/selling/Print Format/Sales Order Spartan/Sales Order Spartan.txt
index 105b65b21b..8da27b7d70 100644
--- a/erpnext/selling/Print Format/Sales Order Spartan/Sales Order Spartan.txt
+++ b/erpnext/selling/Print Format/Sales Order Spartan/Sales Order Spartan.txt
@@ -2,14 +2,14 @@
{
"creation": "2013-04-19 13:30:51",
"docstatus": 0,
- "modified": "2013-08-07 19:45:59",
+ "modified": "2013-12-26 17:35:29",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"doc_type": "Sales Order",
"doctype": "Print Format",
- "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n\n",
+ "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n",
"module": "Selling",
"name": "__common__",
"print_format_type": "Client",
diff --git a/erpnext/selling/doctype/quotation/quotation.txt b/erpnext/selling/doctype/quotation/quotation.txt
index 3657e4acef..4795653262 100644
--- a/erpnext/selling/doctype/quotation/quotation.txt
+++ b/erpnext/selling/doctype/quotation/quotation.txt
@@ -2,7 +2,7 @@
{
"creation": "2013-05-24 19:29:08",
"docstatus": 0,
- "modified": "2013-12-20 19:24:25",
+ "modified": "2014-01-03 14:54:05",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -460,6 +460,13 @@
"print_hide": 1,
"read_only": 1
},
+ {
+ "doctype": "DocField",
+ "fieldname": "discount_amount",
+ "fieldtype": "Currency",
+ "label": "Discount Amount",
+ "options": "Company:company:default_currency"
+ },
{
"doctype": "DocField",
"fieldname": "totals",
diff --git a/erpnext/selling/doctype/sales_order/sales_order.txt b/erpnext/selling/doctype/sales_order/sales_order.txt
index f9582fb213..2dc62f334a 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.txt
+++ b/erpnext/selling/doctype/sales_order/sales_order.txt
@@ -2,7 +2,7 @@
{
"creation": "2013-06-18 12:39:59",
"docstatus": 0,
- "modified": "2013-12-20 19:24:32",
+ "modified": "2014-01-03 14:51:19",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -480,6 +480,13 @@
"read_only": 1,
"width": "150px"
},
+ {
+ "doctype": "DocField",
+ "fieldname": "discount_amount",
+ "fieldtype": "Currency",
+ "label": "Discount Amount",
+ "options": "Company:company:default_currency"
+ },
{
"doctype": "DocField",
"fieldname": "totals",
diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js
index 1c8aed3553..330e725ed8 100644
--- a/erpnext/selling/sales_common.js
+++ b/erpnext/selling/sales_common.js
@@ -225,6 +225,10 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
this.calculate_taxes_and_totals();
},
+
+ discount_amount: function() {
+ this.calculate_taxes_and_totals();
+ },
commission_rate: function() {
this.calculate_commission();
@@ -310,15 +314,17 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
calculate_item_values: function() {
var me = this;
- $.each(this.frm.item_doclist, function(i, item) {
- wn.model.round_floats_in(item);
- item.export_amount = flt(item.export_rate * item.qty, precision("export_amount", item));
-
- me._set_in_company_currency(item, "ref_rate", "base_ref_rate");
- me._set_in_company_currency(item, "export_rate", "basic_rate");
- me._set_in_company_currency(item, "export_amount", "amount");
- });
+ if (!this.discount_amount_applied) {
+ $.each(this.frm.item_doclist, function(i, item) {
+ wn.model.round_floats_in(item);
+ item.export_amount = flt(item.export_rate * item.qty, precision("export_amount", item));
+
+ me._set_in_company_currency(item, "ref_rate", "base_ref_rate");
+ me._set_in_company_currency(item, "export_rate", "basic_rate");
+ me._set_in_company_currency(item, "export_amount", "amount");
+ });
+ }
},
determine_exclusive_rate: function() {
@@ -341,11 +347,11 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
cumulated_tax_fraction += tax.tax_fraction_for_current_item;
});
- if(cumulated_tax_fraction) {
+ if(cumulated_tax_fraction && !me.discount_amount_applied) {
item.amount = flt(
(item.export_amount * me.frm.doc.conversion_rate) / (1 + cumulated_tax_fraction),
precision("amount", item));
-
+
item.basic_rate = flt(item.amount / item.qty, precision("basic_rate", item));
if(item.adj_rate == 100) {
@@ -385,18 +391,20 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
calculate_net_total: function() {
var me = this;
-
this.frm.doc.net_total = this.frm.doc.net_total_export = 0.0;
+
$.each(this.frm.item_doclist, function(i, item) {
me.frm.doc.net_total += item.amount;
me.frm.doc.net_total_export += item.export_amount;
});
-
+
wn.model.round_floats_in(this.frm.doc, ["net_total", "net_total_export"]);
},
calculate_totals: function() {
+ var me = this;
var tax_count = this.frm.tax_doclist.length;
+
this.frm.doc.grand_total = flt(
tax_count ? this.frm.tax_doclist[tax_count - 1].total : this.frm.doc.net_total,
precision("grand_total"));
@@ -405,13 +413,56 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
this.frm.doc.other_charges_total = flt(this.frm.doc.grand_total - this.frm.doc.net_total,
precision("other_charges_total"));
- this.frm.doc.other_charges_total_export = flt(
- this.frm.doc.grand_total_export - this.frm.doc.net_total_export,
+ this.frm.doc.other_charges_total_export = flt(this.frm.doc.grand_total_export -
+ this.frm.doc.net_total_export + flt(this.frm.doc.discount_amount),
precision("other_charges_total_export"));
this.frm.doc.rounded_total = Math.round(this.frm.doc.grand_total);
this.frm.doc.rounded_total_export = Math.round(this.frm.doc.grand_total_export);
},
+
+ apply_discount_amount: function() {
+ var me = this;
+ var distributed_amount = 0.0;
+
+ if (this.frm.doc.discount_amount) {
+ var grand_total_for_discount_amount = this.get_grand_total_for_discount_amount();
+ // calculate item amount after Discount Amount
+ if (grand_total_for_discount_amount) {
+ $.each(this.frm.item_doclist, function(i, item) {
+ distributed_amount = flt(me.frm.doc.discount_amount) * item.amount / grand_total_for_discount_amount;
+ item.amount = flt(item.amount - distributed_amount, precision("amount", item));
+ });
+
+ this.discount_amount_applied = true;
+ this._calculate_taxes_and_totals();
+ }
+ }
+ },
+
+ get_grand_total_for_discount_amount: function() {
+ var me = this;
+ var total_actual_tax = 0.0;
+ var actual_taxes_dict = {};
+
+ $.each(this.frm.tax_doclist, function(i, tax) {
+ if (tax.charge_type == "Actual")
+ actual_taxes_dict[tax.idx] = tax.tax_amount;
+ else if (actual_taxes_dict[tax.row_id] !== null) {
+ actual_tax_amount = flt(actual_taxes_dict[tax.row_id]) * flt(tax.rate) / 100;
+ actual_taxes_dict[tax.idx] = actual_tax_amount;
+ }
+ });
+
+ $.each(actual_taxes_dict, function(key, value) {
+ if (value)
+ total_actual_tax += value;
+ });
+
+ grand_total_for_discount_amount = flt(this.frm.doc.grand_total - total_actual_tax,
+ precision("grand_total"));
+ return grand_total_for_discount_amount;
+ },
calculate_outstanding_amount: function() {
// NOTE:
diff --git a/erpnext/stock/Print Format/Delivery Note Classic/Delivery Note Classic.txt b/erpnext/stock/Print Format/Delivery Note Classic/Delivery Note Classic.txt
index 163dffaa87..d4c0cc1983 100644
--- a/erpnext/stock/Print Format/Delivery Note Classic/Delivery Note Classic.txt
+++ b/erpnext/stock/Print Format/Delivery Note Classic/Delivery Note Classic.txt
@@ -2,14 +2,14 @@
{
"creation": "2013-04-19 13:31:11",
"docstatus": 0,
- "modified": "2013-08-07 19:44:55",
+ "modified": "2013-12-26 17:36:51",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"doc_type": "Delivery Note",
"doctype": "Print Format",
- "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n\n",
+ "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n",
"module": "Stock",
"name": "__common__",
"print_format_type": "Client",
diff --git a/erpnext/stock/Print Format/Delivery Note Modern/Delivery Note Modern.txt b/erpnext/stock/Print Format/Delivery Note Modern/Delivery Note Modern.txt
index f4323a9e1f..3b36f6f1c0 100644
--- a/erpnext/stock/Print Format/Delivery Note Modern/Delivery Note Modern.txt
+++ b/erpnext/stock/Print Format/Delivery Note Modern/Delivery Note Modern.txt
@@ -2,14 +2,14 @@
{
"creation": "2013-04-19 13:31:11",
"docstatus": 0,
- "modified": "2013-08-07 20:12:29",
+ "modified": "2013-12-26 17:36:26",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"doc_type": "Delivery Note",
"doctype": "Print Format",
- "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n\n",
+ "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n",
"module": "Stock",
"name": "__common__",
"print_format_type": "Client",
diff --git a/erpnext/stock/Print Format/Delivery Note Spartan/Delivery Note Spartan.txt b/erpnext/stock/Print Format/Delivery Note Spartan/Delivery Note Spartan.txt
index 03fbef521e..072d411004 100644
--- a/erpnext/stock/Print Format/Delivery Note Spartan/Delivery Note Spartan.txt
+++ b/erpnext/stock/Print Format/Delivery Note Spartan/Delivery Note Spartan.txt
@@ -2,14 +2,14 @@
{
"creation": "2013-04-19 13:31:11",
"docstatus": 0,
- "modified": "2013-08-07 19:44:37",
+ "modified": "2013-12-26 17:37:14",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"doc_type": "Delivery Note",
"doctype": "Print Format",
- "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n\n",
+ "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n",
"module": "Stock",
"name": "__common__",
"print_format_type": "Client",
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.txt b/erpnext/stock/doctype/delivery_note/delivery_note.txt
index 36615a28d0..b2677a39e5 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.txt
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.txt
@@ -2,7 +2,7 @@
{
"creation": "2013-05-24 19:29:09",
"docstatus": 0,
- "modified": "2013-12-20 19:24:02",
+ "modified": "2014-01-03 14:53:03",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -468,7 +468,7 @@
"fieldname": "other_charges_total_export",
"fieldtype": "Currency",
"label": "Taxes and Charges Total",
- "options": "company",
+ "options": "Company:company:default_currency",
"print_hide": 1,
"read_only": 1
},
@@ -490,6 +490,13 @@
"read_only": 1,
"width": "150px"
},
+ {
+ "doctype": "DocField",
+ "fieldname": "discount_amount",
+ "fieldtype": "Currency",
+ "label": "Discount Amount",
+ "options": "Company:company:default_currency"
+ },
{
"doctype": "DocField",
"fieldname": "totals",
diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js
index 1ee5e049e4..23845364da 100644
--- a/erpnext/stock/doctype/item/item.js
+++ b/erpnext/stock/doctype/item/item.js
@@ -97,7 +97,8 @@ cur_frm.fields_dict['default_sales_cost_center'].get_query = function(doc) {
cur_frm.fields_dict['item_tax'].grid.get_field("tax_type").get_query = function(doc, cdt, cdn) {
return{
filters:[
- ['Account', 'account_type', 'in', 'Tax, Chargeable'],
+ ['Account', 'account_type', 'in',
+ 'Tax, Chargeable, Income Account, Expense Account'],
['Account', 'docstatus', '!=', 2]
]
}
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 73e8dc2b09..fb6f73d335 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -151,8 +151,8 @@ class DocType(DocListController, WebsiteGenerator):
if d.tax_type:
account_type = webnotes.conn.get_value("Account", d.tax_type, "account_type")
- if account_type not in ['Tax', 'Chargeable']:
- msgprint("'%s' is not Tax / Chargeable Account" % d.tax_type, raise_exception=1)
+ if account_type not in ['Tax', 'Chargeable', 'Income Account', 'Expense Account']:
+ msgprint("'%s' is not Tax / Chargeable / Income / Expense Account" % d.tax_type, raise_exception=1)
else:
if d.tax_type in check_list:
msgprint("Rate is entered twice for: '%s'" % d.tax_type, raise_exception=1)