From d23ae108ae4537748ac4e0aade597423c71aae5a Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 14 Jan 2014 15:52:09 +0530 Subject: [PATCH 1/5] Fixes in Comment, if comment by not mentioned, consider owner --- startup/event_handlers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/startup/event_handlers.py b/startup/event_handlers.py index f0323ea36a..b04b588505 100644 --- a/startup/event_handlers.py +++ b/startup/event_handlers.py @@ -70,6 +70,6 @@ def on_build(): def comment_added(doc): """add comment to feed""" - home.make_feed('Comment', doc.comment_doctype, doc.comment_docname, doc.comment_by, - '"' + doc.comment + '"', '#6B24B3') + home.make_feed('Comment', doc.comment_doctype, doc.comment_docname, + doc.comment_by or doc.owner, '"' + doc.comment + '"', '#6B24B3') From d91af2853eff03635fcb69f1ffff3fab847bd4f4 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 14 Jan 2014 15:56:52 +0530 Subject: [PATCH 2/5] Allowed import for customer issue --- support/doctype/customer_issue/customer_issue.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/support/doctype/customer_issue/customer_issue.txt b/support/doctype/customer_issue/customer_issue.txt index f9fbc6bd6a..76d49a8199 100644 --- a/support/doctype/customer_issue/customer_issue.txt +++ b/support/doctype/customer_issue/customer_issue.txt @@ -2,11 +2,12 @@ { "creation": "2013-01-10 16:34:30", "docstatus": 0, - "modified": "2013-11-02 16:59:22", + "modified": "2014-01-14 15:56:22", "modified_by": "Administrator", "owner": "harshada@webnotestech.com" }, { + "allow_import": 1, "autoname": "naming_series:", "doctype": "DocType", "icon": "icon-bug", From 3a193708927cee8b5c788c75221ec47a0f54e24e Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 14 Jan 2014 17:44:34 +0530 Subject: [PATCH 3/5] Rounding issue and divisional loss adjustment --- .../purchase_invoice/purchase_invoice.py | 3 +- controllers/accounts_controller.py | 28 +++++++++++------- controllers/buying_controller.py | 16 +++++++--- .../production_order/test_production_order.py | 2 ++ public/js/transaction.js | 29 ++++++++++++++----- 5 files changed, 55 insertions(+), 23 deletions(-) diff --git a/accounts/doctype/purchase_invoice/purchase_invoice.py b/accounts/doctype/purchase_invoice/purchase_invoice.py index 0b8ad46dd0..06b7a3ad2e 100644 --- a/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -358,7 +358,8 @@ class DocType(BuyingController): # expense will be booked in sales invoice stock_item_and_auto_accounting_for_stock = True - valuation_amt = item.amount + item.item_tax_amount + item.rm_supp_cost + valuation_amt = flt(item.amount + item.item_tax_amount + item.rm_supp_cost, + self.precision("amount", item)) gl_entries.append( self.get_gl_dict({ diff --git a/controllers/accounts_controller.py b/controllers/accounts_controller.py index 8d33327569..e5b0b9d75b 100644 --- a/controllers/accounts_controller.py +++ b/controllers/accounts_controller.py @@ -223,20 +223,22 @@ class AccountsController(TransactionBase): _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) - - # 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 + + # 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] # store tax_amount for current item as it will be used for # charge type = 'On Previous Row Amount' @@ -248,7 +250,8 @@ class AccountsController(TransactionBase): if tax.category: # if just for valuation, do not add the tax amount in total # hence, setting it as 0 for further steps - current_tax_amount = 0.0 if (tax.category == "Valuation") else current_tax_amount + current_tax_amount = 0.0 if (tax.category == "Valuation") \ + else current_tax_amount current_tax_amount *= -1.0 if (tax.add_deduct_tax == "Deduct") else 1.0 @@ -267,6 +270,11 @@ class AccountsController(TransactionBase): # 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: + tax.total = flt(tax.total, self.precision("total", tax)) + tax.tax_amount = flt(tax.tax_amount, self.precision("tax_amount", 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 diff --git a/controllers/buying_controller.py b/controllers/buying_controller.py index 3c6981d6cb..7954ca0abb 100644 --- a/controllers/buying_controller.py +++ b/controllers/buying_controller.py @@ -175,23 +175,31 @@ class BuyingController(StockController): stock_items = self.get_stock_items() stock_items_qty, stock_items_amount = 0, 0 + last_stock_item_idx = 1 for d in self.doclist.get({"parentfield": parentfield}): if d.item_code and d.item_code in stock_items: stock_items_qty += flt(d.qty) stock_items_amount += flt(d.amount) + last_stock_item_idx = d.idx total_valuation_amount = sum([flt(d.tax_amount) for d in self.doclist.get({"parentfield": "purchase_tax_details"}) if d.category in ["Valuation", "Valuation and Total"]]) - - for item in self.doclist.get({"parentfield": parentfield}): + + valuation_amount_adjustment = total_valuation_amount + for i, item in enumerate(self.doclist.get({"parentfield": parentfield})): if item.item_code and item.qty and item.item_code in stock_items: item_proportion = flt(item.amount) / stock_items_amount if stock_items_amount \ else flt(item.qty) / stock_items_qty - item.item_tax_amount = flt(item_proportion * total_valuation_amount, - self.precision("item_tax_amount", item)) + if i == (last_stock_item_idx - 1): + item.item_tax_amount = flt(valuation_amount_adjustment, + self.precision("item_tax_amount", item)) + else: + item.item_tax_amount = flt(item_proportion * total_valuation_amount, + self.precision("item_tax_amount", item)) + valuation_amount_adjustment -= item.item_tax_amount self.round_floats_in(item) diff --git a/manufacturing/doctype/production_order/test_production_order.py b/manufacturing/doctype/production_order/test_production_order.py index ca28708cc1..da45a9bdb6 100644 --- a/manufacturing/doctype/production_order/test_production_order.py +++ b/manufacturing/doctype/production_order/test_production_order.py @@ -35,6 +35,7 @@ class TestProductionOrder(unittest.TestCase): stock_entry.doc.fg_completed_qty = 4 stock_entry.doc.posting_date = "2013-05-12" + stock_entry.doc.fiscal_year = "_Test Fiscal Year 2013" stock_entry.run_method("get_items") stock_entry.submit() @@ -52,6 +53,7 @@ class TestProductionOrder(unittest.TestCase): stock_entry = make_stock_entry(pro_order, "Manufacture/Repack") stock_entry = webnotes.bean(stock_entry) stock_entry.doc.posting_date = "2013-05-12" + stock_entry.doc.fiscal_year = "_Test Fiscal Year 2013" stock_entry.doc.fg_completed_qty = 15 stock_entry.run_method("get_items") stock_entry.insert() diff --git a/public/js/transaction.js b/public/js/transaction.js index 0fe0535c6b..1e03833bd6 100644 --- a/public/js/transaction.js +++ b/public/js/transaction.js @@ -540,6 +540,14 @@ 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); @@ -549,15 +557,15 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({ 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] } + } + // store tax_amount for current item as it will be used for // charge type = 'On Previous Row Amount' @@ -589,6 +597,11 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({ // in tax.total, accumulate grand total for each item tax.total += tax.grand_total_for_current_item; + + if (n == me.frm.item_doclist.length - 1) { + tax.total = flt(tax.total, precision("total", tax)); + tax.tax_amount = flt(tax.tax_amount, precision("tax_amount", tax)); + } }); }); }, From ee6200576a53ad6ca8de685b028ddb44c2b30e96 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 14 Jan 2014 18:34:10 +0530 Subject: [PATCH 4/5] Highest priority to user properties while fetching warehouse from item --- selling/utils/__init__.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/selling/utils/__init__.py b/selling/utils/__init__.py index 85c20e86d8..f495f58e44 100644 --- a/selling/utils/__init__.py +++ b/selling/utils/__init__.py @@ -3,8 +3,8 @@ from __future__ import unicode_literals import webnotes -from webnotes import msgprint, _, throw -from webnotes.utils import flt, cint, comma_and +from webnotes import _, throw +from webnotes.utils import flt, cint import json def get_customer_list(doctype, txt, searchfield, start, page_len, filters): @@ -121,10 +121,16 @@ def _validate_item_details(args, item): def _get_basic_details(args, item_bean, warehouse_fieldname): item = item_bean.doc + from webnotes.defaults import get_user_default_as_list + user_default_warehouse_list = get_user_default_as_list('warehouse') + user_default_warehouse = user_default_warehouse_list[0] \ + if len(user_default_warehouse_list)==1 else "" + out = webnotes._dict({ "item_code": item.name, "description": item.description_html or item.description, - warehouse_fieldname: item.default_warehouse or args.get(warehouse_fieldname), + warehouse_fieldname: user_default_warehouse or item.default_warehouse \ + or args.get(warehouse_fieldname), "income_account": item.default_income_account or args.income_account \ or webnotes.conn.get_value("Company", args.company, "default_income_account"), "expense_account": item.purchase_account or args.expense_account \ From f55d9414cd23612bc2e5c29907b63e0e439dfcd3 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Tue, 14 Jan 2014 19:19:14 +0600 Subject: [PATCH 5/5] bumped to version 3.6.1 --- config.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.json b/config.json index 8e033d52a2..45acaf2cd3 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,6 @@ { "app_name": "ERPNext", - "app_version": "3.6.0", + "app_version": "3.6.1", "base_template": "app/portal/templates/base.html", "modules": { "Accounts": { @@ -74,5 +74,5 @@ "type": "module" } }, - "requires_framework_version": "==3.7.0" + "requires_framework_version": "==3.7.1" } \ No newline at end of file