Fixed conflict while merging with develop branch

This commit is contained in:
Nabin Hait 2014-01-20 17:18:16 +05:30
commit 5c6d13a0df
36 changed files with 529 additions and 193 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -32,12 +32,14 @@ erpnext.POS = Class.extend({
</div>\ </div>\
<br>\ <br>\
<div class="totals-area" style="margin-left: 40%;">\ <div class="totals-area" style="margin-left: 40%;">\
<div class="net-total-area">\
<table class="table table-condensed">\ <table class="table table-condensed">\
<tr>\ <tr>\
<td><b>Net Total</b></td>\ <td><b>Net Total</b></td>\
<td style="text-align: right;" class="net-total"></td>\ <td style="text-align: right;" class="net-total"></td>\
</tr>\ </tr>\
</table>\ </table>\
</div>\
<div class="tax-table" style="display: none;">\ <div class="tax-table" style="display: none;">\
<table class="table table-condensed">\ <table class="table table-condensed">\
<thead>\ <thead>\
@ -50,6 +52,18 @@ erpnext.POS = Class.extend({
</tbody>\ </tbody>\
</table>\ </table>\
</div>\ </div>\
<div class="discount-amount-area">\
<table class="table table-condensed">\
<tr>\
<td style="vertical-align: middle;" width="50%"><b>Discount Amount</b></td>\
<td width="20%"></td>\
<td style="text-align: right;">\
<input type="text" class="form-control discount-amount" \
style="text-align: right;">\
</td>\
</tr>\
</table>\
</div>\
<div class="grand-total-area">\ <div class="grand-total-area">\
<table class="table table-condensed">\ <table class="table table-condensed">\
<tr>\ <tr>\
@ -90,6 +104,10 @@ erpnext.POS = Class.extend({
me.refresh(); 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("remove-items", function() {me.remove_selected_items();}); this.call_function("remove-items", function() {me.remove_selected_items();});
this.call_function("make-payment", function() {me.make_payment();}); this.call_function("make-payment", function() {me.make_payment();});
}, },
@ -120,9 +138,9 @@ erpnext.POS = Class.extend({
}, },
make: function() { make: function() {
this.make_party(); this.make_party();
this.make_item_group();
this.make_search();
this.make_barcode(); this.make_barcode();
this.make_search();
this.make_item_group();
this.make_item_list(); this.make_item_list();
}, },
make_party: function() { make_party: function() {
@ -145,23 +163,23 @@ erpnext.POS = Class.extend({
me.party.toLowerCase(), this.value); me.party.toLowerCase(), this.value);
}); });
}, },
make_item_group: function() { make_barcode: function() {
var me = this; var me = this;
this.item_group = wn.ui.form.make_control({ this.barcode = wn.ui.form.make_control({
df: { df: {
"fieldtype": "Link", "fieldtype": "Data",
"options": "Item Group", "label": "Barcode",
"label": "Item Group", "fieldname": "pos_barcode",
"fieldname": "pos_item_group", "placeholder": "Barcode / Serial No"
"placeholder": "Item Group"
}, },
parent: this.wrapper.find(".item-group-area"), parent: this.wrapper.find(".barcode-area"),
only_input: true, only_input: true,
}); });
this.item_group.make_input(); this.barcode.make_input();
this.item_group.$input.on("change", function() { this.barcode.$input.on("keypress", function() {
if(!me.item_group.autocomplete_open) if(me.barcode_timeout)
me.make_item_list(); clearTimeout(me.barcode_timeout);
me.barcode_timeout = setTimeout(function() { me.add_item_thru_barcode(); }, 1000);
}); });
}, },
make_search: function() { make_search: function() {
@ -184,23 +202,23 @@ erpnext.POS = Class.extend({
me.item_timeout = setTimeout(function() { me.make_item_list(); }, 1000); me.item_timeout = setTimeout(function() { me.make_item_list(); }, 1000);
}); });
}, },
make_barcode: function() { make_item_group: function() {
var me = this; var me = this;
this.barcode = wn.ui.form.make_control({ this.item_group = wn.ui.form.make_control({
df: { df: {
"fieldtype": "Data", "fieldtype": "Link",
"label": "Barcode", "options": "Item Group",
"fieldname": "pos_barcode", "label": "Item Group",
"placeholder": "Barcode / Serial No" "fieldname": "pos_item_group",
"placeholder": "Item Group"
}, },
parent: this.wrapper.find(".barcode-area"), parent: this.wrapper.find(".item-group-area"),
only_input: true, only_input: true,
}); });
this.barcode.make_input(); this.item_group.make_input();
this.barcode.$input.on("keypress", function() { this.item_group.$input.on("change", function() {
if(me.barcode_timeout) if(!me.item_group.autocomplete_open)
clearTimeout(me.barcode_timeout); me.make_item_list();
me.barcode_timeout = setTimeout(function() { me.add_item_thru_barcode(); }, 1000);
}); });
}, },
make_item_list: function() { make_item_list: function() {
@ -329,6 +347,7 @@ erpnext.POS = Class.extend({
refresh: function() { refresh: function() {
var me = this; var me = this;
this.party_field.set_input(this.frm.doc[this.party.toLowerCase()]); 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.barcode.set_input("");
this.show_items_in_item_cart(); this.show_items_in_item_cart();

View File

@ -25,7 +25,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
} }
// toggle to pos view if is_pos is 1 in user_defaults // 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) { if(this.frm.doc.__islocal && !this.frm.doc.amended_from && !this.frm.doc.customer) {
this.frm.set_value("is_pos", 1); this.frm.set_value("is_pos", 1);
this.is_pos(function() { this.is_pos(function() {
@ -147,7 +147,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
me.set_dynamic_labels(); me.set_dynamic_labels();
me.calculate_taxes_and_totals(); me.calculate_taxes_and_totals();
if(callback_fn) callback_fn() if(callback_fn) callback_fn();
} }
} }
}); });
@ -335,7 +335,7 @@ cur_frm.fields_dict['project_name'].get_query = function(doc, cdt, cdn) {
// -------------------------------- // --------------------------------
cur_frm.set_query("income_account", "entries", function(doc) { cur_frm.set_query("income_account", "entries", function(doc) {
return{ 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} filters: {'company': doc.company}
} }
}); });

View File

@ -558,12 +558,12 @@ class DocType(SellingController):
def make_tax_gl_entries(self, gl_entries): def make_tax_gl_entries(self, gl_entries):
for tax in self.doclist.get({"parentfield": "other_charges"}): 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( gl_entries.append(
self.get_gl_dict({ self.get_gl_dict({
"account": tax.account_head, "account": tax.account_head,
"against": self.doc.debit_to, "against": self.doc.debit_to,
"credit": flt(tax.tax_amount), "credit": flt(tax.tax_amount_after_discount_amount),
"remarks": self.doc.remarks, "remarks": self.doc.remarks,
"cost_center": tax.cost_center "cost_center": tax.cost_center
}) })

View File

@ -455,6 +455,14 @@
"print_hide": 1, "print_hide": 1,
"read_only": 1 "read_only": 1
}, },
{
"doctype": "DocField",
"fieldname": "discount_amount",
"fieldtype": "Currency",
"label": "Discount Amount",
"options": "Company:company:default_currency",
"print_hide": 0
},
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "totals", "fieldname": "totals",

View File

@ -44,7 +44,6 @@ class TestSalesInvoice(unittest.TestCase):
def test_sales_invoice_calculation_base_currency(self): def test_sales_invoice_calculation_base_currency(self):
si = webnotes.bean(copy=test_records[2]) si = webnotes.bean(copy=test_records[2])
si.run_method("calculate_taxes_and_totals")
si.insert() si.insert()
expected_values = { expected_values = {
@ -137,6 +136,113 @@ class TestSalesInvoice(unittest.TestCase):
self.assertEquals(si.doc.grand_total, 1627.05) self.assertEquals(si.doc.grand_total, 1627.05)
self.assertEquals(si.doc.grand_total_export, 32.54) 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): def test_inclusive_rate_validations(self):
si = webnotes.bean(copy=test_records[2]) si = webnotes.bean(copy=test_records[2])
for i, tax in enumerate(si.doclist.get({"parentfield": "other_charges"})): 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 si.doclist[i].included_in_print_rate = 1
# tax type "Actual" cannot be inclusive # 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 # taxes above included type 'On Previous Row Total' should also be included
si.doclist[3].included_in_print_rate = 0 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): def test_sales_invoice_calculation_base_currency_with_tax_inclusive_price(self):
# prepare # prepare
si = webnotes.bean(copy=test_records[3]) si = webnotes.bean(copy=test_records[3])
si.run_method("calculate_taxes_and_totals")
si.insert() si.insert()
expected_values = { expected_values = {
@ -195,7 +300,7 @@ class TestSalesInvoice(unittest.TestCase):
for d in si.doclist.get({"parentfield": "other_charges"}): for d in si.doclist.get({"parentfield": "other_charges"}):
for i, k in enumerate(expected_values["keys"]): 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, 1622.98)
self.assertEquals(si.doc.grand_total_export, 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[2].adj_rate = 20
si.doclist[9].rate = 5000 si.doclist[9].rate = 5000
si.run_method("calculate_taxes_and_totals")
si.insert() si.insert()
expected_values = { expected_values = {
@ -249,7 +353,7 @@ class TestSalesInvoice(unittest.TestCase):
for d in si.doclist.get({"parentfield": "other_charges"}): for d in si.doclist.get({"parentfield": "other_charges"}):
for i, k in enumerate(expected_values["keys"]): 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, 65205.16)
self.assertEquals(si.doc.grand_total_export, 1304.1) 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 = webnotes.bean(copy=pr_test_records[0])
pr.doc.naming_series = "_T-Purchase Receipt-" pr.doc.naming_series = "_T-Purchase Receipt-"
pr.doclist[1].warehouse = "_Test Warehouse No Account - _TC" pr.doclist[1].warehouse = "_Test Warehouse No Account - _TC"
pr.run_method("calculate_taxes_and_totals")
pr.insert() pr.insert()
pr.submit() pr.submit()
@ -508,7 +611,6 @@ class TestSalesInvoice(unittest.TestCase):
as pr_test_records as pr_test_records
pr = webnotes.bean(copy=pr_test_records[0]) pr = webnotes.bean(copy=pr_test_records[0])
pr.doc.naming_series = "_T-Purchase Receipt-" pr.doc.naming_series = "_T-Purchase Receipt-"
pr.run_method("calculate_taxes_and_totals")
pr.insert() pr.insert()
pr.submit() pr.submit()

View File

@ -2,7 +2,7 @@
{ {
"creation": "2013-04-24 11:39:32", "creation": "2013-04-24 11:39:32",
"docstatus": 0, "docstatus": 0,
"modified": "2013-12-31 17:51:47", "modified": "2014-01-03 15:04:25",
"modified_by": "Administrator", "modified_by": "Administrator",
"owner": "Administrator" "owner": "Administrator"
}, },
@ -132,6 +132,15 @@
"report_hide": 1, "report_hide": 1,
"width": "150px" "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", "doctype": "DocField",
"fieldname": "item_wise_tax_detail", "fieldname": "item_wise_tax_detail",

View File

@ -19,6 +19,10 @@ cur_frm.pformat.net_total_export = function(doc) {
return ''; return '';
} }
cur_frm.pformat.discount_amount = function(doc) {
return '';
}
cur_frm.pformat.grand_total_export = function(doc) { cur_frm.pformat.grand_total_export = function(doc) {
return ''; return '';
} }
@ -60,6 +64,7 @@ cur_frm.pformat.other_charges= function(doc){
// main table // main table
out +='<table class="noborder" style="width:100%">'; out +='<table class="noborder" style="width:100%">';
if(!print_hide('net_total_export')) { if(!print_hide('net_total_export')) {
out += make_row('Net Total', doc.net_total_export, 1); out += make_row('Net Total', doc.net_total_export, 1);
} }
@ -72,6 +77,11 @@ cur_frm.pformat.other_charges= function(doc){
} }
} }
// Discount Amount
if(!print_hide('discount_amount') && doc.discount_amount) {
out += make_row('Discount Amount', convert_rate(doc.discount_amount), 0);
}
// grand total // grand total
if(!print_hide('grand_total_export')) { if(!print_hide('grand_total_export')) {
out += make_row('Grand Total', doc.grand_total_export, 1); out += make_row('Grand Total', doc.grand_total_export, 1);

View File

@ -79,7 +79,7 @@ def get_columns(invoice_list):
tax_accounts = webnotes.conn.sql_list("""select distinct account_head tax_accounts = webnotes.conn.sql_list("""select distinct account_head
from `tabSales Taxes and Charges` where parenttype = 'Sales Invoice' 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""" % and parent in (%s) order by account_head""" %
', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list])) ', '.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 return invoice_income_map
def get_invoice_tax_map(invoice_list, invoice_income_map, income_accounts): 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""" % 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) ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)

View File

@ -366,6 +366,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() { calculate_outstanding_amount: function() {

View File

@ -1,7 +1,6 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt # License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals from __future__ import unicode_literals
import unittest import unittest
import webnotes import webnotes

View File

@ -132,6 +132,12 @@ class AccountsController(TransactionBase):
self.doclist.append(tax) self.doclist.append(tax)
def calculate_taxes_and_totals(self): 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 # validate conversion rate
company_currency = get_company_currency(self.doc.company) company_currency = get_company_currency(self.doc.company)
if not self.doc.currency or self.doc.currency == company_currency: if not self.doc.currency or self.doc.currency == company_currency:
@ -156,15 +162,17 @@ class AccountsController(TransactionBase):
self.calculate_totals() self.calculate_totals()
self._cleanup() self._cleanup()
# TODO
# print format: show net_total_export instead of net_total
def initialize_taxes(self): def initialize_taxes(self):
for tax in self.tax_doclist: for tax in self.tax_doclist:
tax.item_wise_tax_detail = {} tax.item_wise_tax_detail = {}
for fieldname in ["tax_amount", "total", tax_fields = ["total", "tax_amount_after_discount_amount",
"tax_amount_for_current_item", "grand_total_for_current_item", "tax_amount_for_current_item", "grand_total_for_current_item",
"tax_fraction_for_current_item", "grand_total_fraction_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 tax.fields[fieldname] = 0.0
self.validate_on_previous_row(tax) self.validate_on_previous_row(tax)
@ -214,11 +222,11 @@ class AccountsController(TransactionBase):
"charge_type": tax.charge_type, "charge_type": tax.charge_type,
}) })
elif tax.charge_type == "On Previous Row Amount" and \ 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 # referred row should also be inclusive
_on_previous_row_error(tax.row_id) _on_previous_row_error(tax.row_id)
elif tax.charge_type == "On Previous Row Total" and \ 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 # all rows about the reffered tax should be inclusive
_on_previous_row_error("1 - %d" % (tax.row_id,)) _on_previous_row_error("1 - %d" % (tax.row_id,))
@ -245,8 +253,11 @@ class AccountsController(TransactionBase):
tax.tax_amount_for_current_item = current_tax_amount tax.tax_amount_for_current_item = current_tax_amount
# accumulate tax amount into tax.tax_amount # accumulate tax amount into tax.tax_amount
if not self.discount_amount_applied:
tax.tax_amount += current_tax_amount tax.tax_amount += current_tax_amount
tax.tax_amount_after_discount_amount += current_tax_amount
if tax.category: if tax.category:
# if just for valuation, do not add the tax amount in total # if just for valuation, do not add the tax amount in total
# hence, setting it as 0 for further steps # hence, setting it as 0 for further steps
@ -259,9 +270,8 @@ class AccountsController(TransactionBase):
# note: grand_total_for_current_item contains the contribution of # note: grand_total_for_current_item contains the contribution of
# item's amount, previously applied tax and the current tax on that item # item's amount, previously applied tax and the current tax on that item
if i==0: if i==0:
tax.grand_total_for_current_item = flt(item.amount + tax.grand_total_for_current_item = flt(item.amount + current_tax_amount,
current_tax_amount, self.precision("total", tax)) self.precision("total", tax))
else: else:
tax.grand_total_for_current_item = \ 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 +
@ -272,8 +282,23 @@ class AccountsController(TransactionBase):
# set precision in the last item iteration # set precision in the last item iteration
if n == len(self.item_doclist) - 1: 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.total = flt(tax.total, self.precision("total", tax))
tax.tax_amount = flt(tax.tax_amount, self.precision("tax_amount", 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): def get_current_tax_amount(self, item, tax, item_tax_map):
tax_rate = self._get_tax_rate(tax, item_tax_map) tax_rate = self._get_tax_rate(tax, item_tax_map)

View File

@ -5,7 +5,6 @@ from __future__ import unicode_literals
import webnotes import webnotes
from webnotes import _, msgprint from webnotes import _, msgprint
from webnotes.utils import flt, _round from webnotes.utils import flt, _round
from erpnext.buying.utils import get_item_details from erpnext.buying.utils import get_item_details
from erpnext.setup.utils import get_company_currency from erpnext.setup.utils import get_company_currency
@ -180,6 +179,11 @@ class BuyingController(StockController):
for item in self.item_doclist: for item in self.item_doclist:
del item.fields["item_tax_amount"] 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"]
# update valuation rate # update valuation rate
def update_valuation_rate(self, parentfield): def update_valuation_rate(self, parentfield):
""" """

View File

@ -121,7 +121,7 @@ class SellingController(StockController):
cumulated_tax_fraction += tax.tax_fraction_for_current_item 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) / item.amount = flt((item.export_amount * self.doc.conversion_rate) /
(1 + cumulated_tax_fraction), self.precision("amount", item)) (1 + cumulated_tax_fraction), self.precision("amount", item))
@ -158,6 +158,7 @@ class SellingController(StockController):
return current_tax_fraction return current_tax_fraction
def calculate_item_values(self): def calculate_item_values(self):
if not self.discount_amount_applied:
for item in self.item_doclist: for item in self.item_doclist:
self.round_floats_in(item) self.round_floats_in(item)
@ -191,13 +192,42 @@ class SellingController(StockController):
self.doc.other_charges_total = flt(self.doc.grand_total - self.doc.net_total, self.doc.other_charges_total = flt(self.doc.grand_total - self.doc.net_total,
self.precision("other_charges_total")) self.precision("other_charges_total"))
self.doc.other_charges_total_export = flt(
self.doc.grand_total_export - self.doc.net_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.precision("other_charges_total_export"))
self.doc.rounded_total = _round(self.doc.grand_total) self.doc.rounded_total = _round(self.doc.grand_total)
self.doc.rounded_total_export = _round(self.doc.grand_total_export) 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): def calculate_outstanding_amount(self):
# NOTE: # NOTE:
# write_off_amount is only for POS Invoice # write_off_amount is only for POS Invoice

View File

@ -46,13 +46,9 @@ standard_queries = Customer:erpnext.selling.utils.get_customer_list
scheduler_event = all:erpnext.support.doctype.support_ticket.get_support_mails.get_support_mails scheduler_event = all:erpnext.support.doctype.support_ticket.get_support_mails.get_support_mails
scheduler_event = all:erpnext.hr.doctype.job_applicant.get_job_applications.get_job_applications scheduler_event = all:erpnext.hr.doctype.job_applicant.get_job_applications.get_job_applications
scheduler_event = all:erpnext.selling.doctype.lead.get_leads.get_leads scheduler_event = all:erpnext.selling.doctype.lead.get_leads.get_leads
scheduler_event = all:webnotes.utils.email_lib.bulk.flush
#### Daily #### Daily
scheduler_event = daily:webnotes.core.doctype.event.event.send_event_digest
scheduler_event = daily:webnotes.core.doctype.notification_count.notification_count.delete_event_notification_count
scheduler_event = daily:webnotes.utils.email_lib.bulk.clear_outbox
scheduler_event = daily:erpnext.accounts.doctype.sales_invoice.sales_invoice.manage_recurring_invoices scheduler_event = daily:erpnext.accounts.doctype.sales_invoice.sales_invoice.manage_recurring_invoices
scheduler_event = daily:erpnext.setup.doctype.backup_manager.backup_manager.take_backups_daily scheduler_event = daily:erpnext.setup.doctype.backup_manager.backup_manager.take_backups_daily
scheduler_event = daily:erpnext.stock.utils.reorder_item scheduler_event = daily:erpnext.stock.utils.reorder_item

View File

@ -1,3 +1,21 @@
erpnext.patches.4_0.update_user_properties erpnext.patches.4_0.update_user_properties
erpnext.patches.4_0.move_warehouse_user_to_restrictions erpnext.patches.4_0.move_warehouse_user_to_restrictions
erpnext.patches.4_0.new_permissions 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

View File

@ -172,18 +172,18 @@ patch_list = [
"patches.july_2013.p05_custom_doctypes_in_list_view", "patches.july_2013.p05_custom_doctypes_in_list_view",
"patches.july_2013.p06_same_sales_rate", "patches.july_2013.p06_same_sales_rate",
"patches.july_2013.p07_repost_billed_amt_in_sales_cycle", "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 Classic') # 2013-12-26",
"execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Modern') # 2013-07-22", "execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Modern') # 2013-12-26",
"execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Spartan') # 2013-07-22", "execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Spartan') # 2013-12-26",
"execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Classic') # 2013-07-22", "execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Classic') # 2013-12-26",
"execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Modern') # 2013-07-22", "execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Modern') # 2013-12-26",
"execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Spartan') # 2013-07-22", "execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Spartan') # 2013-12-26",
"execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Classic') # 2013-07-22", "execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Classic') # 2013-12-26",
"execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Modern') # 2013-07-22", "execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Modern') # 2013-12-26",
"execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Spartan') # 2013-07-22", "execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Spartan') # 2013-12-26",
"execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Classic') # 2013-07-22", "execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Classic') # 2013-12-26",
"execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Modern') # 2013-07-22", "execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Modern') # 2013-12-26",
"execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Spartan') # 2013-07-22", "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.p08_custom_print_format_net_total_export",
"patches.july_2013.p09_remove_website_pyc", "patches.july_2013.p09_remove_website_pyc",
"patches.july_2013.p10_change_partner_user_to_website_user", "patches.july_2013.p10_change_partner_user_to_website_user",
@ -265,4 +265,9 @@ patch_list = [
"patches.1401.p01_move_related_property_setters_to_custom_field", "patches.1401.p01_move_related_property_setters_to_custom_field",
"patches.1401.p01_make_buying_selling_as_check_box_in_price_list", "patches.1401.p01_make_buying_selling_as_check_box_in_price_list",
"patches.1401.update_billing_status_for_zero_value_order", "patches.1401.update_billing_status_for_zero_value_order",
"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",
] ]

View File

@ -508,6 +508,13 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
}, },
calculate_taxes_and_totals: function() { 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.validate_conversion_rate();
this.frm.item_doclist = this.get_item_doclist(); this.frm.item_doclist = this.get_item_doclist();
this.frm.tax_doclist = this.get_tax_doclist(); this.frm.tax_doclist = this.get_tax_doclist();
@ -525,12 +532,17 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
initialize_taxes: function() { initialize_taxes: function() {
var me = this; var me = this;
$.each(this.frm.tax_doclist, function(i, tax) { $.each(this.frm.tax_doclist, function(i, tax) {
tax.item_wise_tax_detail = {}; 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_amount_for_current_item", "grand_total_for_current_item",
"tax_fraction_for_current_item", "grand_total_fraction_for_current_item"], "tax_fraction_for_current_item", "grand_total_fraction_for_current_item"]
function(i, fieldname) { tax[fieldname] = 0.0 });
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_on_previous_row(tax);
me.validate_inclusive_tax(tax); me.validate_inclusive_tax(tax);
@ -556,8 +568,6 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
// tax_amount represents the amount of tax for the current step // 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); 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);
// Adjust divisional loss to the last item // Adjust divisional loss to the last item
if (tax.charge_type == "Actual") { if (tax.charge_type == "Actual") {
actual_tax_dict[tax.idx] -= current_tax_amount; actual_tax_dict[tax.idx] -= current_tax_amount;
@ -566,14 +576,16 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
} }
} }
// store tax_amount for current item as it will be used for // store tax_amount for current item as it will be used for
// charge type = 'On Previous Row Amount' // charge type = 'On Previous Row Amount'
tax.tax_amount_for_current_item = current_tax_amount; tax.tax_amount_for_current_item = current_tax_amount;
// accumulate tax amount into tax.tax_amount // accumulate tax amount into tax.tax_amount
if (!me.discount_amount_applied)
tax.tax_amount += current_tax_amount; tax.tax_amount += current_tax_amount;
tax.tax_amount_after_discount_amount += current_tax_amount;
// for buying // for buying
if(tax.category) { if(tax.category) {
// if just for valuation, do not add the tax amount in total // if just for valuation, do not add the tax amount in total
@ -598,14 +610,32 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
// in tax.total, accumulate grand total for each item // in tax.total, accumulate grand total for each item
tax.total += tax.grand_total_for_current_item; tax.total += tax.grand_total_for_current_item;
// set precision in the last item iteration
if (n == me.frm.item_doclist.length - 1) { if (n == me.frm.item_doclist.length - 1) {
tax.total = flt(tax.total, precision("total", tax)); me.round_off_totals(tax);
tax.tax_amount = flt(tax.tax_amount, precision("tax_amount", 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) { get_current_tax_amount: function(item, tax, item_tax_map) {
var tax_rate = this._get_tax_rate(tax, item_tax_map); var tax_rate = this._get_tax_rate(tax, item_tax_map);
var current_tax_amount = 0.0; var current_tax_amount = 0.0;
@ -627,7 +657,6 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
} else if(tax.charge_type == "On Previous Row Total") { } else if(tax.charge_type == "On Previous Row Total") {
current_tax_amount = (tax_rate / 100.0) * current_tax_amount = (tax_rate / 100.0) *
this.frm.tax_doclist[cint(tax.row_id) - 1].grand_total_for_current_item; 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)); current_tax_amount = flt(current_tax_amount, precision("tax_amount", tax));

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -2,7 +2,7 @@
{ {
"creation": "2013-05-24 19:29:08", "creation": "2013-05-24 19:29:08",
"docstatus": 0, "docstatus": 0,
"modified": "2013-12-20 19:24:25", "modified": "2014-01-03 14:54:05",
"modified_by": "Administrator", "modified_by": "Administrator",
"owner": "Administrator" "owner": "Administrator"
}, },
@ -460,6 +460,13 @@
"print_hide": 1, "print_hide": 1,
"read_only": 1 "read_only": 1
}, },
{
"doctype": "DocField",
"fieldname": "discount_amount",
"fieldtype": "Currency",
"label": "Discount Amount",
"options": "Company:company:default_currency"
},
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "totals", "fieldname": "totals",

View File

@ -2,7 +2,7 @@
{ {
"creation": "2013-06-18 12:39:59", "creation": "2013-06-18 12:39:59",
"docstatus": 0, "docstatus": 0,
"modified": "2013-12-20 19:24:32", "modified": "2014-01-03 14:51:19",
"modified_by": "Administrator", "modified_by": "Administrator",
"owner": "Administrator" "owner": "Administrator"
}, },
@ -480,6 +480,13 @@
"read_only": 1, "read_only": 1,
"width": "150px" "width": "150px"
}, },
{
"doctype": "DocField",
"fieldname": "discount_amount",
"fieldtype": "Currency",
"label": "Discount Amount",
"options": "Company:company:default_currency"
},
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "totals", "fieldname": "totals",

View File

@ -226,6 +226,10 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
this.calculate_taxes_and_totals(); this.calculate_taxes_and_totals();
}, },
discount_amount: function() {
this.calculate_taxes_and_totals();
},
commission_rate: function() { commission_rate: function() {
this.calculate_commission(); this.calculate_commission();
refresh_field("total_commission"); refresh_field("total_commission");
@ -310,6 +314,8 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
calculate_item_values: function() { calculate_item_values: function() {
var me = this; var me = this;
if (!this.discount_amount_applied) {
$.each(this.frm.item_doclist, function(i, item) { $.each(this.frm.item_doclist, function(i, item) {
wn.model.round_floats_in(item); wn.model.round_floats_in(item);
item.export_amount = flt(item.export_rate * item.qty, precision("export_amount", item)); item.export_amount = flt(item.export_rate * item.qty, precision("export_amount", item));
@ -318,7 +324,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
me._set_in_company_currency(item, "export_rate", "basic_rate"); me._set_in_company_currency(item, "export_rate", "basic_rate");
me._set_in_company_currency(item, "export_amount", "amount"); me._set_in_company_currency(item, "export_amount", "amount");
}); });
}
}, },
determine_exclusive_rate: function() { determine_exclusive_rate: function() {
@ -341,7 +347,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
cumulated_tax_fraction += tax.tax_fraction_for_current_item; 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.amount = flt(
(item.export_amount * me.frm.doc.conversion_rate) / (1 + cumulated_tax_fraction), (item.export_amount * me.frm.doc.conversion_rate) / (1 + cumulated_tax_fraction),
precision("amount", item)); precision("amount", item));
@ -385,8 +391,8 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
calculate_net_total: function() { calculate_net_total: function() {
var me = this; var me = this;
this.frm.doc.net_total = this.frm.doc.net_total_export = 0.0; this.frm.doc.net_total = this.frm.doc.net_total_export = 0.0;
$.each(this.frm.item_doclist, function(i, item) { $.each(this.frm.item_doclist, function(i, item) {
me.frm.doc.net_total += item.amount; me.frm.doc.net_total += item.amount;
me.frm.doc.net_total_export += item.export_amount; me.frm.doc.net_total_export += item.export_amount;
@ -396,7 +402,9 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
}, },
calculate_totals: function() { calculate_totals: function() {
var me = this;
var tax_count = this.frm.tax_doclist.length; var tax_count = this.frm.tax_doclist.length;
this.frm.doc.grand_total = flt( this.frm.doc.grand_total = flt(
tax_count ? this.frm.tax_doclist[tax_count - 1].total : this.frm.doc.net_total, tax_count ? this.frm.tax_doclist[tax_count - 1].total : this.frm.doc.net_total,
precision("grand_total")); precision("grand_total"));
@ -405,14 +413,57 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
this.frm.doc.other_charges_total = flt(this.frm.doc.grand_total - this.frm.doc.net_total, this.frm.doc.other_charges_total = flt(this.frm.doc.grand_total - this.frm.doc.net_total,
precision("other_charges_total")); precision("other_charges_total"));
this.frm.doc.other_charges_total_export = flt( this.frm.doc.other_charges_total_export = flt(this.frm.doc.grand_total_export -
this.frm.doc.grand_total_export - this.frm.doc.net_total_export, this.frm.doc.net_total_export + flt(this.frm.doc.discount_amount),
precision("other_charges_total_export")); precision("other_charges_total_export"));
this.frm.doc.rounded_total = Math.round(this.frm.doc.grand_total); 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); 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() { calculate_outstanding_amount: function() {
// NOTE: // NOTE:
// paid_amount and write_off_amount is only for POS Invoice // paid_amount and write_off_amount is only for POS Invoice

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -2,7 +2,7 @@
{ {
"creation": "2013-05-24 19:29:09", "creation": "2013-05-24 19:29:09",
"docstatus": 0, "docstatus": 0,
"modified": "2013-12-20 19:24:02", "modified": "2014-01-03 14:53:03",
"modified_by": "Administrator", "modified_by": "Administrator",
"owner": "Administrator" "owner": "Administrator"
}, },
@ -468,7 +468,7 @@
"fieldname": "other_charges_total_export", "fieldname": "other_charges_total_export",
"fieldtype": "Currency", "fieldtype": "Currency",
"label": "Taxes and Charges Total", "label": "Taxes and Charges Total",
"options": "company", "options": "Company:company:default_currency",
"print_hide": 1, "print_hide": 1,
"read_only": 1 "read_only": 1
}, },
@ -490,6 +490,13 @@
"read_only": 1, "read_only": 1,
"width": "150px" "width": "150px"
}, },
{
"doctype": "DocField",
"fieldname": "discount_amount",
"fieldtype": "Currency",
"label": "Discount Amount",
"options": "Company:company:default_currency"
},
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "totals", "fieldname": "totals",

View File

@ -94,7 +94,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) { cur_frm.fields_dict['item_tax'].grid.get_field("tax_type").get_query = function(doc, cdt, cdn) {
return{ return{
filters:[ filters:[
['Account', 'account_type', 'in', 'Tax, Chargeable'], ['Account', 'account_type', 'in',
'Tax, Chargeable, Income Account, Expense Account'],
['Account', 'docstatus', '!=', 2] ['Account', 'docstatus', '!=', 2]
] ]
} }

View File

@ -151,8 +151,8 @@ class DocType(DocListController, WebsiteGenerator):
if d.tax_type: if d.tax_type:
account_type = webnotes.conn.get_value("Account", d.tax_type, "account_type") account_type = webnotes.conn.get_value("Account", d.tax_type, "account_type")
if account_type not in ['Tax', 'Chargeable']: if account_type not in ['Tax', 'Chargeable', 'Income Account', 'Expense Account']:
msgprint("'%s' is not Tax / Chargeable Account" % d.tax_type, raise_exception=1) msgprint("'%s' is not Tax / Chargeable / Income / Expense Account" % d.tax_type, raise_exception=1)
else: else:
if d.tax_type in check_list: if d.tax_type in check_list:
msgprint("Rate is entered twice for: '%s'" % d.tax_type, raise_exception=1) msgprint("Rate is entered twice for: '%s'" % d.tax_type, raise_exception=1)