From f40ce616a71e8064a529f6552bfcc9f8f94ae43b Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 2 Jan 2015 14:36:46 +0530 Subject: [PATCH 01/26] In stock entry, difference account can be non-profit-and-loss account --- erpnext/controllers/stock_controller.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 0a9adc0e050..754a7d8ad7d 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -167,7 +167,7 @@ class StockController(AccountsController): else: is_expense_account = frappe.db.get_value("Account", item.get("expense_account"), "report_type")=="Profit and Loss" - if self.doctype not in ("Purchase Receipt", "Stock Reconciliation") and not is_expense_account: + if self.doctype not in ("Purchase Receipt", "Stock Reconciliation", "Stock Entry") and not is_expense_account: frappe.throw(_("Expense / Difference account ({0}) must be a 'Profit or Loss' account") .format(item.get("expense_account"))) if is_expense_account and not item.get("cost_center"): From 0938b5dec618db231c5fed256d99807a17364634 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 2 Jan 2015 15:12:30 +0530 Subject: [PATCH 02/26] FG item and raw material can not be merged --- erpnext/stock/doctype/item/item.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py index b8a31909ceb..366e8282f1f 100644 --- a/erpnext/stock/doctype/item/item.py +++ b/erpnext/stock/doctype/item/item.py @@ -229,7 +229,7 @@ class Item(WebsiteGenerator): if not frappe.db.exists("Item", newdn): frappe.throw(_("Item {0} does not exist").format(newdn)) - field_list = ["stock_uom", "is_stock_item", "has_serial_no", "has_batch_no"] + field_list = ["stock_uom", "is_stock_item", "has_serial_no", "has_batch_no", "is_manufactured_item"] new_properties = [cstr(d) for d in frappe.db.get_value("Item", newdn, field_list)] if new_properties != [cstr(self.get(fld)) for fld in field_list]: frappe.throw(_("To merge, following properties must be same for both items") From 8a0031996228eae6f82088b74c738a41c47d45e5 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Sun, 4 Jan 2015 17:27:40 +0530 Subject: [PATCH 03/26] minor fix --- erpnext/buying/doctype/purchase_common/purchase_common.js | 3 ++- erpnext/controllers/buying_controller.py | 3 ++- erpnext/controllers/selling_controller.py | 3 ++- erpnext/selling/sales_common.js | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.js b/erpnext/buying/doctype/purchase_common/purchase_common.js index 3681081c955..98667423553 100644 --- a/erpnext/buying/doctype/purchase_common/purchase_common.js +++ b/erpnext/buying/doctype/purchase_common/purchase_common.js @@ -211,7 +211,8 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ 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); - this.frm.doc.grand_total_import = flt(this.frm.doc.grand_total / this.frm.doc.conversion_rate); + this.frm.doc.grand_total_import = flt(tax_count ? + flt(this.frm.doc.grand_total / this.frm.doc.conversion_rate) : this.frm.doc.net_total_import; this.frm.doc.total_tax = flt(this.frm.doc.grand_total - this.frm.doc.net_total, precision("total_tax")); diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index 1e6e65d86b3..f7b5a87d562 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -111,7 +111,8 @@ class BuyingController(StockController): def calculate_totals(self): self.grand_total = flt(self.tax_doclist[-1].total if self.tax_doclist else self.net_total) - self.grand_total_import = flt(self.grand_total / self.conversion_rate) + self.grand_total_import = flt(self.grand_total / self.conversion_rate) \ + if self.tax_doclist else self.net_total_import self.total_tax = flt(self.grand_total - self.net_total, self.precision("total_tax")) diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index 6e93c30797f..68cdf189bd8 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -218,7 +218,8 @@ class SellingController(StockController): def calculate_totals(self): self.grand_total = flt(self.tax_doclist[-1].total if self.tax_doclist else self.net_total) - self.grand_total_export = flt(self.grand_total / self.conversion_rate) + self.grand_total_export = flt(self.grand_total / self.conversion_rate) \ + if self.tax_doclist else self.net_total_export self.other_charges_total = flt(self.grand_total - self.net_total, self.precision("other_charges_total")) diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js index 783474c75f3..f6d811159c0 100644 --- a/erpnext/selling/sales_common.js +++ b/erpnext/selling/sales_common.js @@ -342,7 +342,8 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ 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); - this.frm.doc.grand_total_export = flt(this.frm.doc.grand_total / this.frm.doc.conversion_rate); + this.frm.doc.grand_total_export = flt(tax_count ? + flt(this.frm.doc.grand_total / this.frm.doc.conversion_rate) : this.frm.doc.net_total_export; this.frm.doc.other_charges_total = flt(this.frm.doc.grand_total - this.frm.doc.net_total, precision("other_charges_total")); From 5515b1ea7f8015fdfaac7e7ce5375755b301eba4 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 5 Jan 2015 08:18:15 +0530 Subject: [PATCH 04/26] minor fix --- erpnext/buying/doctype/purchase_common/purchase_common.js | 2 +- erpnext/selling/sales_common.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.js b/erpnext/buying/doctype/purchase_common/purchase_common.js index 98667423553..3011160639b 100644 --- a/erpnext/buying/doctype/purchase_common/purchase_common.js +++ b/erpnext/buying/doctype/purchase_common/purchase_common.js @@ -212,7 +212,7 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ this.frm.doc.grand_total = flt(tax_count ? this.frm.tax_doclist[tax_count - 1].total : this.frm.doc.net_total); this.frm.doc.grand_total_import = flt(tax_count ? - flt(this.frm.doc.grand_total / this.frm.doc.conversion_rate) : this.frm.doc.net_total_import; + flt(this.frm.doc.grand_total / this.frm.doc.conversion_rate) : this.frm.doc.net_total_import); this.frm.doc.total_tax = flt(this.frm.doc.grand_total - this.frm.doc.net_total, precision("total_tax")); diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js index f6d811159c0..c7c21fdda93 100644 --- a/erpnext/selling/sales_common.js +++ b/erpnext/selling/sales_common.js @@ -343,7 +343,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ this.frm.doc.grand_total = flt(tax_count ? this.frm.tax_doclist[tax_count - 1].total : this.frm.doc.net_total); this.frm.doc.grand_total_export = flt(tax_count ? - flt(this.frm.doc.grand_total / this.frm.doc.conversion_rate) : this.frm.doc.net_total_export; + flt(this.frm.doc.grand_total / this.frm.doc.conversion_rate) : this.frm.doc.net_total_export); this.frm.doc.other_charges_total = flt(this.frm.doc.grand_total - this.frm.doc.net_total, precision("other_charges_total")); From e24365f1f42ffff494b5d651fa7618e5d9d014a6 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 6 Jan 2015 12:56:37 +0530 Subject: [PATCH 05/26] message fix --- erpnext/controllers/accounts_controller.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index f6d47dd420b..02fdf2ca996 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -471,7 +471,7 @@ class AccountsController(TransactionBase): max_allowed_amt = flt(ref_amt * (100 + tolerance) / 100) if total_billed_amt - max_allowed_amt > 0.01: - frappe.throw(_("Cannot overbill for Item {0} in row {0} more than {1}. To allow overbilling, please set in Stock Settings").format(item.item_code, item.idx, max_allowed_amt)) + frappe.throw(_("Cannot overbill for Item {0} in row {1} more than {2}. To allow overbilling, please set in Stock Settings").format(item.item_code, item.idx, max_allowed_amt)) def get_company_default(self, fieldname): from erpnext.accounts.utils import get_company_default From 1b7d66fab651595da026be43e75059b1c5713e0b Mon Sep 17 00:00:00 2001 From: Neil Trini Lasrado Date: Wed, 7 Jan 2015 11:16:41 +0530 Subject: [PATCH 06/26] Update leave_application.js --- erpnext/hr/doctype/leave_application/leave_application.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/hr/doctype/leave_application/leave_application.js b/erpnext/hr/doctype/leave_application/leave_application.js index 9ba988e2599..6605c304f38 100755 --- a/erpnext/hr/doctype/leave_application/leave_application.js +++ b/erpnext/hr/doctype/leave_application/leave_application.js @@ -33,7 +33,7 @@ cur_frm.cscript.refresh = function(doc, dt, dn) { cur_frm.set_intro(__("You are the Leave Approver for this record. Please Update the 'Status' and Save")); cur_frm.toggle_enable("status", true); } else { - cur_frm.set_intro(__("This Leave Application is pending approval. Only the Leave Apporver can update status.")) + cur_frm.set_intro(__("This Leave Application is pending approval. Only the Leave Approver can update status.")) cur_frm.toggle_enable("status", false); if(!doc.__islocal) { cur_frm.frm_head.appframe.set_title_right(""); From 6c1773025b4e93d71d3a090e73ba8861001474e0 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 7 Jan 2015 11:33:14 +0530 Subject: [PATCH 07/26] fiscal year error message --- erpnext/accounts/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index c658cdd09ff..0a05275bca6 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -28,7 +28,7 @@ def get_fiscal_years(date=None, fiscal_year=None, label="Date", verbose=1): from `tabFiscal Year` where %s order by year_start_date desc""" % cond) if not fy: - error_msg = _("""{0} {1} not in any Fiscal Year""").format(label, formatdate(date)) + error_msg = _("""{0} {1} not in any Fiscal Year. For more details check {2}.""").format(label, formatdate(date), "https://erpnext.com/kb/accounts/fiscal-year-error") if verbose: frappe.msgprint(error_msg) raise FiscalYearError, error_msg From bdfd0d1ff9ebada521bba81c939f5860eb6d5a25 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Wed, 7 Jan 2015 12:07:22 +0600 Subject: [PATCH 08/26] bumped to version 4.16.0 --- erpnext/__version__.py | 2 +- erpnext/hooks.py | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/__version__.py b/erpnext/__version__.py index 349cc44bd0a..ebfb9bf6b49 100644 --- a/erpnext/__version__.py +++ b/erpnext/__version__.py @@ -1 +1 @@ -__version__ = '4.15.4' +__version__ = '4.16.0' diff --git a/erpnext/hooks.py b/erpnext/hooks.py index f033d687be0..d8b8a2e0239 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -4,7 +4,7 @@ app_publisher = "Web Notes Technologies Pvt. Ltd. and Contributors" app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations" app_icon = "icon-th" app_color = "#e74c3c" -app_version = "4.15.4" +app_version = "4.16.0" error_report_email = "support@erpnext.com" diff --git a/setup.py b/setup.py index 24e0155468a..4df95668d41 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, find_packages import os -version = "4.15.4" +version = "4.16.0" with open("requirements.txt", "r") as f: install_requires = f.readlines() From a17d7cea34974f5a49a383610816dcb41d147ee8 Mon Sep 17 00:00:00 2001 From: Neil Trini Lasrado Date: Wed, 7 Jan 2015 11:55:40 +0530 Subject: [PATCH 09/26] test records fixed --- .../doctype/production_order/test_production_order.py | 6 ++++++ erpnext/selling/doctype/opportunity/test_records.json | 2 ++ erpnext/stock/doctype/stock_entry/test_stock_entry.py | 2 ++ 3 files changed, 10 insertions(+) diff --git a/erpnext/manufacturing/doctype/production_order/test_production_order.py b/erpnext/manufacturing/doctype/production_order/test_production_order.py index a9975c1e6f3..2ccf101c47f 100644 --- a/erpnext/manufacturing/doctype/production_order/test_production_order.py +++ b/erpnext/manufacturing/doctype/production_order/test_production_order.py @@ -27,11 +27,15 @@ class TestProductionOrder(unittest.TestCase): s = frappe.get_doc(make_stock_entry(pro_doc.name, "Material Transfer", 4)) for d in s.get("mtn_details"): d.s_warehouse = "Stores - _TC" + s.fiscal_year = "_Test Fiscal Year 2013" + s.posting_date = "2013-01-01" s.insert() s.submit() # from wip to fg s = frappe.get_doc(make_stock_entry(pro_doc.name, "Manufacture", 4)) + s.fiscal_year = "_Test Fiscal Year 2013" + s.posting_date = "2013-01-01" s.insert() s.submit() @@ -50,6 +54,8 @@ class TestProductionOrder(unittest.TestCase): test_stock_entry.make_stock_entry("_Test Item Home Desktop 100", None, "_Test Warehouse - _TC", 100, 100) s = frappe.get_doc(make_stock_entry(pro_doc.name, "Manufacture", 7)) + s.fiscal_year = "_Test Fiscal Year 2013" + s.posting_date = "2013-01-01" s.insert() self.assertRaises(StockOverProductionError, s.submit) diff --git a/erpnext/selling/doctype/opportunity/test_records.json b/erpnext/selling/doctype/opportunity/test_records.json index 39709036358..43ab55de4fc 100644 --- a/erpnext/selling/doctype/opportunity/test_records.json +++ b/erpnext/selling/doctype/opportunity/test_records.json @@ -5,6 +5,8 @@ "enquiry_from": "Lead", "enquiry_type": "Sales", "lead": "_T-Lead-00001", + "transaction_date": "2013-12-12", + "fiscal_year": "_Test Fiscal Year 2013", "enquiry_details": [{ "item_name": "Test Item", "description": "Some description" diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py index e010bd19b9d..73f1d0a92e0 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -936,6 +936,8 @@ def make_stock_entry(item, source, target, qty, incoming_rate=None): "incoming_rate": incoming_rate, "conversion_factor": 1.0 }) + s.posting_date= "2013-01-01" + s.fiscal_year= "_Test Fiscal Year 2013" s.insert() s.submit() return s From 7778b480fd8df3ba8dce6db16c75b91657a01f61 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 7 Jan 2015 15:44:35 +0530 Subject: [PATCH 10/26] fix reposting gl entries for future vouchers --- erpnext/controllers/stock_controller.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 754a7d8ad7d..15355753ffb 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -245,7 +245,7 @@ def compare_existing_and_expected_gle(existing_gle, expected_gle): for entry in expected_gle: for e in existing_gle: if entry.account==e.account and entry.against_account==e.against_account \ - and entry.cost_center==e.cost_center \ + and (not entry.cost_center or not e.cost_center or entry.cost_center==e.cost_center) \ and (entry.debit != e.debit or entry.credit != e.credit): matched = False break From 1ff3a6cdb898cab4d5b17c19c3efdd417edada53 Mon Sep 17 00:00:00 2001 From: Neil Trini Lasrado Date: Wed, 7 Jan 2015 16:24:52 +0530 Subject: [PATCH 11/26] fix --- .../doctype/production_order/test_production_order.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/erpnext/manufacturing/doctype/production_order/test_production_order.py b/erpnext/manufacturing/doctype/production_order/test_production_order.py index 2ccf101c47f..59e56ef348f 100644 --- a/erpnext/manufacturing/doctype/production_order/test_production_order.py +++ b/erpnext/manufacturing/doctype/production_order/test_production_order.py @@ -10,7 +10,7 @@ from erpnext.manufacturing.doctype.production_order.production_order import make from erpnext.stock.doctype.stock_entry import test_stock_entry class TestProductionOrder(unittest.TestCase): - def test_planned_qty(self): + def check_planned_qty(self): set_perpetual_inventory(0) planned0 = frappe.db.get_value("Bin", {"item_code": "_Test FG Item", "warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty") or 0 @@ -28,14 +28,14 @@ class TestProductionOrder(unittest.TestCase): for d in s.get("mtn_details"): d.s_warehouse = "Stores - _TC" s.fiscal_year = "_Test Fiscal Year 2013" - s.posting_date = "2013-01-01" + s.posting_date = "2013-01-02" s.insert() s.submit() # from wip to fg s = frappe.get_doc(make_stock_entry(pro_doc.name, "Manufacture", 4)) s.fiscal_year = "_Test Fiscal Year 2013" - s.posting_date = "2013-01-01" + s.posting_date = "2013-01-03" s.insert() s.submit() @@ -48,14 +48,14 @@ class TestProductionOrder(unittest.TestCase): def test_over_production(self): from erpnext.manufacturing.doctype.production_order.production_order import StockOverProductionError - pro_doc = self.test_planned_qty() + pro_doc = self.check_planned_qty() test_stock_entry.make_stock_entry("_Test Item", None, "_Test Warehouse - _TC", 100, 100) test_stock_entry.make_stock_entry("_Test Item Home Desktop 100", None, "_Test Warehouse - _TC", 100, 100) s = frappe.get_doc(make_stock_entry(pro_doc.name, "Manufacture", 7)) s.fiscal_year = "_Test Fiscal Year 2013" - s.posting_date = "2013-01-01" + s.posting_date = "2013-01-04" s.insert() self.assertRaises(StockOverProductionError, s.submit) From 015fa7a1d1b60eae863fbe02451c8c523c6c5745 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Thu, 8 Jan 2015 18:26:53 +0530 Subject: [PATCH 12/26] [fix] escape quote in Accounts Receivable --- .../accounts/report/accounts_receivable/accounts_receivable.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py index a2ed86da15f..a546799a5d7 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py @@ -149,7 +149,7 @@ class AccountsReceivableReport(object): if not account_map: frappe.throw(_("No Customer Accounts found.")) else: - accounts_list = ['"{0}"'.format(ac.replace('"', '\"')) for ac in account_map] + accounts_list = ["'{0}'".format(frappe.db.escape(ac)) for ac in account_map] conditions.append("account in ({0})".format(", ".join(accounts_list))) return " and ".join(conditions), values From de5865753753942e24448f6211ad58ab8ebe95b6 Mon Sep 17 00:00:00 2001 From: alexandre-00 Date: Fri, 9 Jan 2015 14:20:43 +0800 Subject: [PATCH 13/26] Update bom.py Hi guys, Just a proposal to sort the Materials Required (Exploded) from the BOM. So the items and sub-assemblies items looks a little bit more organized in the list. Cheers Alexandre --- erpnext/manufacturing/doctype/bom/bom.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index bab1b43b60a..c02576f86d1 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -8,6 +8,8 @@ from frappe.utils import cint, cstr, flt from frappe import _ from frappe.model.document import Document +from operator import itemgetter, attrgetter + class BOM(Document): def autoname(self): @@ -360,7 +362,7 @@ class BOM(Document): "Add items to Flat BOM table" frappe.db.sql("""delete from `tabBOM Explosion Item` where parent=%s""", self.name) self.set('flat_bom_details', []) - for d in self.cur_exploded_items: + for d in sorted(self.cur_exploded_items, key=itemgetter(0)): ch = self.append('flat_bom_details', {}) for i in self.cur_exploded_items[d].keys(): ch.set(i, self.cur_exploded_items[d][i]) From 3ed3a2d176713b37b612418c0df08a0f168fc7af Mon Sep 17 00:00:00 2001 From: alexandre-00 Date: Fri, 9 Jan 2015 14:42:27 +0800 Subject: [PATCH 14/26] Update bom.py removed the attrgetter --- erpnext/manufacturing/doctype/bom/bom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index c02576f86d1..8a19f41f950 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -8,7 +8,7 @@ from frappe.utils import cint, cstr, flt from frappe import _ from frappe.model.document import Document -from operator import itemgetter, attrgetter +from operator import itemgetter class BOM(Document): From 675276b802e822ffa6df2fd325dced4144dbf47a Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Sat, 10 Jan 2015 10:27:02 +0530 Subject: [PATCH 15/26] valuation rate mandatory if item is transacting for the first time --- .../doctype/stock_reconciliation/stock_reconciliation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py index 530ab9af807..9c85277a322 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -153,8 +153,8 @@ class StockReconciliation(StockController): if row.valuation_rate in ("", None): row.valuation_rate = previous_sle.get("valuation_rate") - # if row.qty and not row.valuation_rate: - # frappe.throw(_("Valuation Rate required for Item {0}").format(row.item_code)) + if row.qty and not row.valuation_rate: + frappe.throw(_("Valuation Rate required for Item {0}").format(row.item_code)) self.insert_entries(row) From 873d98be2d8bf9b296c1e70e68c168a9db669a1d Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Sun, 11 Jan 2015 22:01:34 +0530 Subject: [PATCH 16/26] create material request from production planning tool --- .../production_planning_tool/production_planning_tool.js | 7 +++++++ .../production_planning_tool.json | 9 ++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js index e2192157c83..f0616dea686 100644 --- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js +++ b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js @@ -24,6 +24,13 @@ cur_frm.cscript.item_code = function(doc,cdt,cdn) { } } +cur_frm.cscript.raise_purchase_request = function(doc, cdt, cdn) { + return frappe.call({ + method: "raise_purchase_request", + doc:doc + }) +} + cur_frm.cscript.download_materials_required = function(doc, cdt, cdn) { return $c_obj(doc, 'validate_data', '', function(r, rt) { if (!r['exc']) diff --git a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json index bdfab41fba7..c6ec1e2bea7 100644 --- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json +++ b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json @@ -1,5 +1,5 @@ { - "creation": "2013-01-21 12:03:47.000000", + "creation": "2013-01-21 12:03:47", "default_print_format": "Standard", "docstatus": 0, "doctype": "DocType", @@ -20,6 +20,7 @@ { "fieldname": "fg_item", "fieldtype": "Link", + "in_list_view": 1, "label": "Filter based on item", "options": "Item", "permlevel": 0 @@ -27,6 +28,7 @@ { "fieldname": "customer", "fieldtype": "Link", + "in_list_view": 1, "label": "Filter based on customer", "options": "Customer", "permlevel": 0 @@ -34,6 +36,7 @@ { "fieldname": "company", "fieldtype": "Link", + "in_list_view": 1, "label": "Company", "options": "Company", "permlevel": 0, @@ -140,7 +143,7 @@ "fieldname": "raise_purchase_request", "fieldtype": "Button", "label": "Create Material Requests", - "options": "raise_purchase_request", + "options": "", "permlevel": 0 }, { @@ -155,7 +158,7 @@ "idx": 1, "in_create": 1, "issingle": 1, - "modified": "2013-12-20 19:23:25.000000", + "modified": "2015-01-11 21:53:21.253556", "modified_by": "Administrator", "module": "Manufacturing", "name": "Production Planning Tool", From abe69afd6990b2c5267daa55b1b51706a1021806 Mon Sep 17 00:00:00 2001 From: Dale Scott Date: Sun, 11 Jan 2015 10:38:03 -0700 Subject: [PATCH 17/26] corrections and clarifications mostly current websites for user guide, forum, ... --- README.md | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index b9d5a6e5f77..2d1fe701de4 100644 --- a/README.md +++ b/README.md @@ -2,33 +2,30 @@ [https://erpnext.com](https://erpnext.com) -Includes Accounting, Inventory, CRM, Sales, Purchase, Projects, HRMS. Built on Python / MariaDB. +Includes Accounting, Inventory, CRM, Sales, Purchase, Projects, HRMS. Python back-end with Javascript client in browser. Requires MariaDB. -ERPNext is built on [frappe](https://github.com/frappe/frappe) Python Framework. +ERPNext is built on the [Frappe](https://github.com/frappe/frappe) Framework, a full-stack web framework in python & js. -- [User Guide](http://erpnext.org/user-guide.html) +- [User Guide](https://erpnext.com/user-guide) - [Getting Help](http://erpnext.org/getting-help.html) -- [Developer Forum](http://groups.google.com/group/erpnext-developer-forum) -- [User Forum](http://groups.google.com/group/erpnext-user-forum) +- [Discussion Forum](https://discuss.frappe.io/) --- -### Install +### Full Install -Use the bench, https://github.com/frappe/bench +Follow the Easy Way install script for bench, see https://github.com/frappe/bench -### Admin Login +The install script will create new passwords for the ERPNext "Administrator user, MariaDB root user, and frappe user (passwords are both displayed and saved to file ~/frappe_passwords.txt). -1. go to "/login" -1. Administrator user name: "Administrator" -1. Administrator password: "admin" +### Virtual Image -### Download and Install - -##### Virtual Image: +You can download a virtual image to run ERPNext in a virtual machine on your local system. - [ERPNext Download](http://erpnext.com/download) +System and user credentials are listed on the download page. + --- ## License From 354892b1c68fcc34a5255412f5e51ae14ca4d8bf Mon Sep 17 00:00:00 2001 From: Dale Scott Date: Sun, 11 Jan 2015 11:01:01 -0700 Subject: [PATCH 18/26] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2d1fe701de4..1ad0d0c8591 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# ERPNext - Open Source ERP for small, medium sized businesses [![Build Status](https://travis-ci.org/frappe/erpnext.png)](https://travis-ci.org/frappe/erpnext) +# ERPNext - Open source ERP for small and medium-size business [![Build Status](https://travis-ci.org/frappe/erpnext.png)](https://travis-ci.org/frappe/erpnext) -[https://erpnext.com](https://erpnext.com) +Website: [https://erpnext.com](https://erpnext.com) -Includes Accounting, Inventory, CRM, Sales, Purchase, Projects, HRMS. Python back-end with Javascript client in browser. Requires MariaDB. +Includes: Accounting, Inventory, CRM, Sales, Purchase, Projects, HRMS. Python back-end with Javascript client in browser. Requires MariaDB. ERPNext is built on the [Frappe](https://github.com/frappe/frappe) Framework, a full-stack web framework in python & js. From ab2e75e98e05001b98fa4bfb90b6da8e9cc0437c Mon Sep 17 00:00:00 2001 From: Dale Scott Date: Sun, 11 Jan 2015 11:04:43 -0700 Subject: [PATCH 19/26] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 1ad0d0c8591..efa3e330692 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # ERPNext - Open source ERP for small and medium-size business [![Build Status](https://travis-ci.org/frappe/erpnext.png)](https://travis-ci.org/frappe/erpnext) -Website: [https://erpnext.com](https://erpnext.com) +[https://erpnext.com](https://erpnext.com) -Includes: Accounting, Inventory, CRM, Sales, Purchase, Projects, HRMS. Python back-end with Javascript client in browser. Requires MariaDB. +Includes: Accounting, Inventory, CRM, Sales, Purchase, Projects, HRMS. Requires MariaDB. -ERPNext is built on the [Frappe](https://github.com/frappe/frappe) Framework, a full-stack web framework in python & js. +ERPNext is built on the [Frappe](https://github.com/frappe/frappe) Framework, a full-stack web app framework in Python & Javascript. - [User Guide](https://erpnext.com/user-guide) - [Getting Help](http://erpnext.org/getting-help.html) @@ -14,9 +14,9 @@ ERPNext is built on the [Frappe](https://github.com/frappe/frappe) Framework, a ### Full Install -Follow the Easy Way install script for bench, see https://github.com/frappe/bench +The Easy Way install script for bench will install all dependencies (e.g. MariaDB). See https://github.com/frappe/bench -The install script will create new passwords for the ERPNext "Administrator user, MariaDB root user, and frappe user (passwords are both displayed and saved to file ~/frappe_passwords.txt). +New passwords will be created for the ERPNext "Administrator" user, the MariaDB root user, and the frappe user (the script displays the passwords and saves them to ~/frappe_passwords.txt). ### Virtual Image From 4e7cc93af93c5700d83c4a3ebf4ddf7663f742a5 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 12 Jan 2015 10:55:48 +0530 Subject: [PATCH 20/26] minor fix in reposting utility --- erpnext/utilities/repost_stock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/utilities/repost_stock.py b/erpnext/utilities/repost_stock.py index b63493e1307..29857254a05 100644 --- a/erpnext/utilities/repost_stock.py +++ b/erpnext/utilities/repost_stock.py @@ -240,7 +240,7 @@ def repost_all_stock_vouchers(): doc.validate() doc.update_stock_ledger() - doc.make_gl_entries(repost_future_gle=False, allow_negative_stock=True) + doc.make_gl_entries(repost_future_gle=False) frappe.db.commit() except Exception, e: print frappe.get_traceback() From 39c8c9e7b0f9c3fb1cb095caec2e88c7131f8261 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 12 Jan 2015 11:04:07 +0530 Subject: [PATCH 21/26] Fixes in print format css --- .../cheque_printing_format/cheque_printing_format.json | 4 ++-- erpnext/accounts/print_format/credit_note/credit_note.json | 4 ++-- .../payment_receipt_voucher/payment_receipt_voucher.json | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/erpnext/accounts/print_format/cheque_printing_format/cheque_printing_format.json b/erpnext/accounts/print_format/cheque_printing_format/cheque_printing_format.json index ce61fa1fc8c..5b4d2f891de 100755 --- a/erpnext/accounts/print_format/cheque_printing_format/cheque_printing_format.json +++ b/erpnext/accounts/print_format/cheque_printing_format/cheque_printing_format.json @@ -3,9 +3,9 @@ "doc_type": "Journal Voucher", "docstatus": 0, "doctype": "Print Format", - "html": "
\n\n\t{%- from \"templates/print_formats/standard_macros.html\" import add_header -%}\n
\n {%- if not doc.get(\"print_heading\") and not doc.get(\"select_print_heading\") \n and doc.set(\"select_print_heading\", _(\"Payment Advice\")) -%}{%- endif -%}\n {{ add_header(0, 1, doc, letter_head, no_letterhead) }}\n\n{%- for label, value in (\n (_(\"Voucher Date\"), frappe.utils.formatdate(doc.voucher_date)),\n (_(\"Reference / Cheque No.\"), doc.cheque_no),\n (_(\"Reference / Cheque Date\"), frappe.utils.formatdate(doc.cheque_date))\n ) -%}\n
\n
\n
{{ value }}
\n
\n{%- endfor -%}\n\t
\n\t

{{ _(\"This amount is in full / part settlement of the listed bills\") }}:

\n{%- for label, value in (\n (_(\"Amount\"), \"\" + (doc.total_amount or \"\") + \"
\" + (doc.total_amount_in_words or \"\") + \"
\"),\n (_(\"References\"), doc.remark)\n ) -%}\n
\n
\n
{{ value }}
\n
\n {%- endfor -%}\n
\n\t
\n\t\tPrepared By
\n\t
\n\t\tAuthorised Signatory
\n\t
\n\t\tReceived Payment as Above
\n\t
\n\t\t_____________
\n\t
\n\t\tA/C Payee
\n\t
\n\t\t_____________
\n\t
\n\t\t{{ frappe.utils.formatdate(doc.cheque_date) }}
\n\t
\n\t\t{{ doc.pay_to_recd_from }}
\n\t
\n\t\t{{ doc.total_amount_in_words }}
\n\t
\n\t\t{{ doc.total_amount }}
\n
", + "html": "
\n\n\t{%- from \"templates/print_formats/standard_macros.html\" import add_header -%}\n
\n {%- if not doc.get(\"print_heading\") and not doc.get(\"select_print_heading\") \n and doc.set(\"select_print_heading\", _(\"Payment Advice\")) -%}{%- endif -%}\n {{ add_header(0, 1, doc, letter_head, no_letterhead) }}\n\n{%- for label, value in (\n (_(\"Voucher Date\"), frappe.utils.formatdate(doc.voucher_date)),\n (_(\"Reference / Cheque No.\"), doc.cheque_no),\n (_(\"Reference / Cheque Date\"), frappe.utils.formatdate(doc.cheque_date))\n ) -%}\n
\n
\n
{{ value }}
\n
\n{%- endfor -%}\n\t
\n\t

{{ _(\"This amount is in full / part settlement of the listed bills\") }}:

\n{%- for label, value in (\n (_(\"Amount\"), \"\" + (doc.total_amount or \"\") + \"
\" + (doc.total_amount_in_words or \"\") + \"
\"),\n (_(\"References\"), doc.remark)\n ) -%}\n
\n
\n
{{ value }}
\n
\n {%- endfor -%}\n
\n\t
\n\t\tPrepared By
\n\t
\n\t\tAuthorised Signatory
\n\t
\n\t\tReceived Payment as Above
\n\t
\n\t\t_____________
\n\t
\n\t\tA/C Payee
\n\t
\n\t\t_____________
\n\t
\n\t\t{{ frappe.utils.formatdate(doc.cheque_date) }}
\n\t
\n\t\t{{ doc.pay_to_recd_from }}
\n\t
\n\t\t{{ doc.total_amount_in_words }}
\n\t
\n\t\t{{ doc.total_amount }}
\n
", "idx": 1, - "modified": "2014-09-09 03:27:13.708596", + "modified": "2015-01-12 11:03:17.032512", "modified_by": "Administrator", "module": "Accounts", "name": "Cheque Printing Format", diff --git a/erpnext/accounts/print_format/credit_note/credit_note.json b/erpnext/accounts/print_format/credit_note/credit_note.json index ac0de75037f..e6c9e8f7110 100644 --- a/erpnext/accounts/print_format/credit_note/credit_note.json +++ b/erpnext/accounts/print_format/credit_note/credit_note.json @@ -4,9 +4,9 @@ "doc_type": "Journal Voucher", "docstatus": 0, "doctype": "Print Format", - "html": "{%- from \"templates/print_formats/standard_macros.html\" import add_header -%}\n\n
\n {%- if not doc.get(\"print_heading\") and not doc.get(\"select_print_heading\") \n and doc.set(\"select_print_heading\", _(\"Credit Note\")) -%}{%- endif -%}\n {{ add_header(0, 1, doc, letter_head, no_letterhead) }}\n\n {%- for label, value in (\n (_(\"Credit To\"), doc.pay_to_recd_from),\n (_(\"Date\"), frappe.utils.formatdate(doc.voucher_date)),\n (_(\"Amount\"), \"\" + frappe.utils.cstr(doc.total_amount) + \"
\" + (doc.total_amount_in_words or \"\") + \"
\"),\n (_(\"Remarks\"), doc.remark)\n ) -%}\n\n
\n
\n
{{ value }}
\n
\n\n {%- endfor -%}\n\n
\n
\n

\n {{ _(\"For\") }} {{ doc.company }},
\n
\n
\n
\n {{ _(\"Authorized Signatory\") }}\n

\n
\n\n\n", + "html": "{%- from \"templates/print_formats/standard_macros.html\" import add_header -%}\n\n
\n {%- if not doc.get(\"print_heading\") and not doc.get(\"select_print_heading\") \n and doc.set(\"select_print_heading\", _(\"Credit Note\")) -%}{%- endif -%}\n {{ add_header(0, 1, doc, letter_head, no_letterhead) }}\n\n {%- for label, value in (\n (_(\"Credit To\"), doc.pay_to_recd_from),\n (_(\"Date\"), frappe.utils.formatdate(doc.voucher_date)),\n (_(\"Amount\"), \"\" + frappe.utils.cstr(doc.total_amount) + \"
\" + (doc.total_amount_in_words or \"\") + \"
\"),\n (_(\"Remarks\"), doc.remark)\n ) -%}\n\n
\n
\n
{{ value }}
\n
\n\n {%- endfor -%}\n\n
\n
\n

\n {{ _(\"For\") }} {{ doc.company }},
\n
\n
\n
\n {{ _(\"Authorized Signatory\") }}\n

\n
\n\n\n", "idx": 2, - "modified": "2014-10-17 17:20:02.740340", + "modified": "2015-01-12 11:02:25.716825", "modified_by": "Administrator", "module": "Accounts", "name": "Credit Note", diff --git a/erpnext/accounts/print_format/payment_receipt_voucher/payment_receipt_voucher.json b/erpnext/accounts/print_format/payment_receipt_voucher/payment_receipt_voucher.json index 5c0a72a8def..04fe7467800 100755 --- a/erpnext/accounts/print_format/payment_receipt_voucher/payment_receipt_voucher.json +++ b/erpnext/accounts/print_format/payment_receipt_voucher/payment_receipt_voucher.json @@ -3,9 +3,9 @@ "doc_type": "Journal Voucher", "docstatus": 0, "doctype": "Print Format", - "html": "{%- from \"templates/print_formats/standard_macros.html\" import add_header -%}\n
\n {%- if not doc.get(\"print_heading\") and not doc.get(\"select_print_heading\") \n and doc.set(\"select_print_heading\", _(\"Payment Receipt Note\")) -%}{%- endif -%}\n {{ add_header(0, 1, doc, letter_head, no_letterhead) }}\n\n {%- for label, value in (\n (_(\"Received On\"), frappe.utils.formatdate(doc.voucher_date)),\n (_(\"Received From\"), doc.pay_to_recd_from),\n (_(\"Amount\"), \"\" + doc.total_amount or 0 + \"
\" + (doc.total_amount_in_words or \"\") + \"
\"),\n (_(\"Remarks\"), doc.remark)\n ) -%}\n
\n
\n
{{ value }}
\n
\n\n {%- endfor -%}\n\n
\n
\n

\n {{ _(\"For\") }} {{ doc.company }},
\n
\n
\n
\n {{ _(\"Authorized Signatory\") }}\n

\n
\n\n", + "html": "{%- from \"templates/print_formats/standard_macros.html\" import add_header -%}\n
\n {%- if not doc.get(\"print_heading\") and not doc.get(\"select_print_heading\") \n and doc.set(\"select_print_heading\", _(\"Payment Receipt Note\")) -%}{%- endif -%}\n {{ add_header(0, 1, doc, letter_head, no_letterhead) }}\n\n {%- for label, value in (\n (_(\"Received On\"), frappe.utils.formatdate(doc.voucher_date)),\n (_(\"Received From\"), doc.pay_to_recd_from),\n (_(\"Amount\"), \"\" + doc.total_amount or 0 + \"
\" + (doc.total_amount_in_words or \"\") + \"
\"),\n (_(\"Remarks\"), doc.remark)\n ) -%}\n
\n
\n
{{ value }}
\n
\n\n {%- endfor -%}\n\n
\n
\n

\n {{ _(\"For\") }} {{ doc.company }},
\n
\n
\n
\n {{ _(\"Authorized Signatory\") }}\n

\n
\n\n", "idx": 1, - "modified": "2014-11-04 11:25:57.560873", + "modified": "2015-01-12 11:03:22.893209", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Receipt Voucher", From 47a10f5a397946248ad0d20e28b008a801062ecd Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Mon, 12 Jan 2015 12:44:35 +0600 Subject: [PATCH 22/26] bumped to version 4.17.0 --- erpnext/__version__.py | 2 +- erpnext/hooks.py | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/__version__.py b/erpnext/__version__.py index ebfb9bf6b49..1eef0c42ba9 100644 --- a/erpnext/__version__.py +++ b/erpnext/__version__.py @@ -1 +1 @@ -__version__ = '4.16.0' +__version__ = '4.17.0' diff --git a/erpnext/hooks.py b/erpnext/hooks.py index d8b8a2e0239..e3694532c16 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -4,7 +4,7 @@ app_publisher = "Web Notes Technologies Pvt. Ltd. and Contributors" app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations" app_icon = "icon-th" app_color = "#e74c3c" -app_version = "4.16.0" +app_version = "4.17.0" error_report_email = "support@erpnext.com" diff --git a/setup.py b/setup.py index 4df95668d41..eb280084355 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, find_packages import os -version = "4.16.0" +version = "4.17.0" with open("requirements.txt", "r") as f: install_requires = f.readlines() From e4ee5c3f1c36b3b3e2d783995dd7c583d4553ee1 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Mon, 12 Jan 2015 12:48:27 +0530 Subject: [PATCH 23/26] Update .travis.yml --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index c136aa09788..45410d5a05f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,8 +16,9 @@ install: - sudo apt-get install mariadb-server mariadb-common libmariadbclient-dev - ./ci/fix-mariadb.sh - - wget http://downloads.sourceforge.net/project/wkhtmltopdf/0.12.1/wkhtmltox-0.12.1_linux-precise-amd64.deb - - sudo dpkg -i wkhtmltox-0.12.1_linux-precise-amd64.deb + - sudo apt-get install xfonts-75dpi xfonts-base -y + - wget http://downloads.sourceforge.net/project/wkhtmltopdf/0.12.2/wkhtmltox-0.12.2_linux-precise-amd64.deb + - sudo dpkg -i wkhtmltox-0.12.2_linux-precise-amd64.deb - CFLAGS=-O0 pip install git+https://github.com/frappe/frappe.git@develop - CFLAGS=-O0 pip install --editable . From 2244ac4d52a500f89e5c88a451b8cc9dc4e9ebe1 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 12 Jan 2015 17:35:14 +0530 Subject: [PATCH 24/26] Discount amount in party currency --- .../doctype/sales_invoice/sales_invoice.json | 32 +++++++++----- .../sales_taxes_and_charges_master.js | 16 +++---- erpnext/controllers/accounts_controller.py | 2 +- erpnext/controllers/selling_controller.py | 9 ++-- erpnext/patches.txt | 1 + erpnext/patches/v4_2/discount_amount.py | 12 ++++++ erpnext/public/js/transaction.js | 5 +-- .../selling/doctype/quotation/quotation.json | 32 +++++++++----- .../doctype/sales_order/sales_order.json | 42 ++++++++++++------- erpnext/selling/sales_common.js | 16 ++++--- .../doctype/delivery_note/delivery_note.json | 32 +++++++++----- erpnext/stock/get_item_details.py | 4 +- 12 files changed, 132 insertions(+), 71 deletions(-) create mode 100644 erpnext/patches/v4_2/discount_amount.py diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index b27a2abc756..9f70c70d32f 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -422,6 +422,15 @@ "fieldtype": "Section Break", "permlevel": 0 }, + { + "fieldname": "other_charges_total_export", + "fieldtype": "Currency", + "label": "Total Taxes and Charges", + "options": "currency", + "permlevel": 0, + "print_hide": 1, + "read_only": 1 + }, { "fieldname": "other_charges_total", "fieldtype": "Currency", @@ -438,23 +447,24 @@ "fieldtype": "Column Break", "permlevel": 0 }, - { - "fieldname": "other_charges_total_export", - "fieldtype": "Currency", - "label": "Total Taxes and Charges", - "options": "currency", - "permlevel": 0, - "print_hide": 1, - "read_only": 1 - }, { "fieldname": "discount_amount", "fieldtype": "Currency", "label": "Discount Amount", - "options": "Company:company:default_currency", + "options": "currency", "permlevel": 0, "print_hide": 0 }, + { + "fieldname": "base_discount_amount", + "fieldtype": "Currency", + "label": "Discount Amount (Company Currency)", + "options": "Company:company:default_currency", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "read_only": 1 + }, { "fieldname": "totals", "fieldtype": "Section Break", @@ -1192,7 +1202,7 @@ "icon": "icon-file-text", "idx": 1, "is_submittable": 1, - "modified": "2014-12-11 16:26:12.402110", + "modified": "2015-01-12 17:34:36.353241", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice", 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 d11bf294f8b..f4e14b81037 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 @@ -46,17 +46,17 @@ cur_frm.pformat.other_charges= function(doc){ var new_val = flt(val)/flt(doc.conversion_rate); return new_val; } - + function print_hide(fieldname) { var doc_field = frappe.meta.get_docfield(doc.doctype, fieldname, doc.name); return doc_field.print_hide; } - + out =''; if (!doc.print_without_amount) { var cl = doc.other_charges || []; - // outer table + // outer table var out='
'; // main table @@ -77,12 +77,12 @@ 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); + out += make_row('Discount Amount', doc.discount_amount, 0); // grand total if(!print_hide('grand_total_export')) out += make_row('Grand Total', doc.grand_total_export, 1); - + if(!print_hide('rounded_total_export')) out += make_row('Rounded Total', doc.rounded_total_export, 1); @@ -92,7 +92,7 @@ cur_frm.pformat.other_charges= function(doc){ out += ''; out += ''; } - out += '
In Words' + doc.in_words_export + '
'; + out += '
'; } return out; } @@ -139,14 +139,14 @@ cur_frm.fields_dict['other_charges'].grid.get_field("account_head").get_query = "account_type": ["Tax", "Chargeable", "Income Account"], "company": doc.company } - } + } } cur_frm.fields_dict['other_charges'].grid.get_field("cost_center").get_query = function(doc) { return{ 'company': doc.company, 'group_or_ledger': "Ledger" - } + } } cur_frm.cscript.rate = function(doc, cdt, cdn) { diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 02fdf2ca996..52193394768 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -295,7 +295,7 @@ class AccountsController(TransactionBase): self.precision("tax_amount", tax)) def adjust_discount_amount_loss(self, tax): - discount_amount_loss = self.grand_total - flt(self.discount_amount) - tax.total + discount_amount_loss = self.grand_total - flt(self.base_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)) diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index 68cdf189bd8..4b0cd4eeb12 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -218,8 +218,7 @@ class SellingController(StockController): def calculate_totals(self): self.grand_total = flt(self.tax_doclist[-1].total if self.tax_doclist else self.net_total) - self.grand_total_export = flt(self.grand_total / self.conversion_rate) \ - if self.tax_doclist else self.net_total_export + self.grand_total_export = flt(self.grand_total / self.conversion_rate) self.other_charges_total = flt(self.grand_total - self.net_total, self.precision("other_charges_total")) @@ -234,16 +233,20 @@ class SellingController(StockController): def apply_discount_amount(self): if self.discount_amount: + self.base_discount_amount = flt(self.discount_amount * self.conversion_rate, self.precision("base_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.discount_amount) * item.base_amount / grand_total_for_discount_amount + distributed_amount = flt(self.base_discount_amount) * item.base_amount / grand_total_for_discount_amount item.base_amount = flt(item.base_amount - distributed_amount, self.precision("base_amount", item)) self.discount_amount_applied = True self._calculate_taxes_and_totals() + else: + self.base_discount_amount = 0 def get_grand_total_for_discount_amount(self): actual_taxes_dict = {} diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 33fa396649c..7fda960356e 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -90,3 +90,4 @@ erpnext.patches.v4_2.fix_gl_entries_for_stock_transactions erpnext.patches.v4_2.update_requested_and_ordered_qty execute:frappe.delete_doc("DocType", "Contact Control") erpnext.patches.v4_2.recalculate_bom_costs +erpnext.patches.v4_2.discount_amount diff --git a/erpnext/patches/v4_2/discount_amount.py b/erpnext/patches/v4_2/discount_amount.py new file mode 100644 index 00000000000..e23a10e06c3 --- /dev/null +++ b/erpnext/patches/v4_2/discount_amount.py @@ -0,0 +1,12 @@ +# 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 frappe +from frappe.modules import scrub, get_doctype_module + +def execute(): + for dt in ["Quotation", "Sales Order", "Delivery Note", "Sales invoice"]: + frappe.reload_doc(get_doctype_module(dt), "doctype", scrub(dt)) + frappe.db.sql("""update `tab{0}` set base_discount_amount=discount_amount, + discount_amount=discount_amount/conversion_rate""".format(dt)) diff --git a/erpnext/public/js/transaction.js b/erpnext/public/js/transaction.js index acb841b8a0c..6d38b46b782 100644 --- a/erpnext/public/js/transaction.js +++ b/erpnext/public/js/transaction.js @@ -734,7 +734,7 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({ }, adjust_discount_amount_loss: function(tax) { - var discount_amount_loss = this.frm.doc.grand_total - flt(this.frm.doc.discount_amount) - tax.total; + var discount_amount_loss = this.frm.doc.grand_total - flt(this.frm.doc.base_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)); @@ -748,8 +748,7 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({ // distribute the tax amount proportionally to each item row var actual = flt(tax.rate, precision("tax_amount", tax)); current_tax_amount = this.frm.doc.net_total ? - ((item.base_amount / this.frm.doc.net_total) * actual) : - 0.0; + ((item.base_amount / this.frm.doc.net_total) * actual) : 0.0; } else if(tax.charge_type == "On Net Total") { current_tax_amount = (tax_rate / 100.0) * item.base_amount; diff --git a/erpnext/selling/doctype/quotation/quotation.json b/erpnext/selling/doctype/quotation/quotation.json index 5d960e95568..9af5029e799 100644 --- a/erpnext/selling/doctype/quotation/quotation.json +++ b/erpnext/selling/doctype/quotation/quotation.json @@ -405,6 +405,15 @@ "fieldtype": "Section Break", "permlevel": 0 }, + { + "fieldname": "other_charges_total_export", + "fieldtype": "Currency", + "label": "Taxes and Charges Total", + "options": "currency", + "permlevel": 0, + "print_hide": 1, + "read_only": 1 + }, { "fieldname": "other_charges_total", "fieldtype": "Currency", @@ -421,22 +430,23 @@ "fieldtype": "Column Break", "permlevel": 0 }, - { - "fieldname": "other_charges_total_export", - "fieldtype": "Currency", - "label": "Taxes and Charges Total", - "options": "currency", - "permlevel": 0, - "print_hide": 1, - "read_only": 1 - }, { "fieldname": "discount_amount", "fieldtype": "Currency", "label": "Discount Amount", - "options": "Company:company:default_currency", + "options": "currency", "permlevel": 0 }, + { + "fieldname": "base_discount_amount", + "fieldtype": "Currency", + "label": "Discount Amount (Company Currency)", + "options": "Company:company:default_currency", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "read_only": 1 + }, { "fieldname": "totals", "fieldtype": "Section Break", @@ -832,7 +842,7 @@ "idx": 1, "is_submittable": 1, "max_attachments": 1, - "modified": "2014-09-09 05:35:33.413559", + "modified": "2015-01-12 16:57:14.706270", "modified_by": "Administrator", "module": "Selling", "name": "Quotation", diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json index 50647030fe6..4ffc6034663 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.json +++ b/erpnext/selling/doctype/sales_order/sales_order.json @@ -420,11 +420,6 @@ "print_hide": 1, "read_only": 1 }, - { - "fieldname": "column_break_46", - "fieldtype": "Column Break", - "permlevel": 0 - }, { "fieldname": "other_charges_total", "fieldtype": "Currency", @@ -437,12 +432,28 @@ "read_only": 1, "width": "150px" }, + { + "fieldname": "column_break_46", + "fieldtype": "Column Break", + "permlevel": 0 + }, { "fieldname": "discount_amount", "fieldtype": "Currency", "label": "Discount Amount", + "options": "currency", + "permlevel": 0, + "print_hide": 0 + }, + { + "fieldname": "base_discount_amount", + "fieldtype": "Currency", + "label": "Discount Amount (Company Currency)", "options": "Company:company:default_currency", - "permlevel": 0 + "permlevel": 0, + "precision": "", + "print_hide": 1, + "read_only": 1 }, { "fieldname": "totals", @@ -490,14 +501,6 @@ "read_only": 1, "width": "200px" }, - { - "fieldname": "advance_paid", - "fieldtype": "Currency", - "label": "Advance Paid", - "permlevel": 0, - "print_hide": 1, - "read_only": 1 - }, { "fieldname": "column_break3", "fieldtype": "Column Break", @@ -542,6 +545,15 @@ "read_only": 1, "width": "200px" }, + { + "fieldname": "advance_paid", + "fieldtype": "Currency", + "label": "Advance Paid", + "options": "Company:company:default_currency", + "permlevel": 0, + "print_hide": 1, + "read_only": 1 + }, { "fieldname": "view_details", "fieldtype": "Fold", @@ -1021,7 +1033,7 @@ "idx": 1, "is_submittable": 1, "issingle": 0, - "modified": "2014-12-16 10:36:47.295144", + "modified": "2015-01-12 15:16:51.611467", "modified_by": "Administrator", "module": "Selling", "name": "Sales Order", diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js index c7c21fdda93..3a01811ba85 100644 --- a/erpnext/selling/sales_common.js +++ b/erpnext/selling/sales_common.js @@ -342,8 +342,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ 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); - this.frm.doc.grand_total_export = flt(tax_count ? - flt(this.frm.doc.grand_total / this.frm.doc.conversion_rate) : this.frm.doc.net_total_export); + this.frm.doc.grand_total_export = flt(this.frm.doc.grand_total / this.frm.doc.conversion_rate); this.frm.doc.other_charges_total = flt(this.frm.doc.grand_total - this.frm.doc.net_total, precision("other_charges_total")); @@ -363,17 +362,22 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ var distributed_amount = 0.0; if (this.frm.doc.discount_amount) { + this.frm.set_value("base_discount_amount", + flt(this.frm.doc.discount_amount * this.frm.doc.conversion_rate, precision("base_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.base_amount / grand_total_for_discount_amount; + distributed_amount = flt(me.frm.doc.base_discount_amount) * item.base_amount / grand_total_for_discount_amount; item.base_amount = flt(item.base_amount - distributed_amount, precision("base_amount", item)); }); this.discount_amount_applied = true; this._calculate_taxes_and_totals(); } + } else { + this.frm.set_value("base_discount_amount", 0); } }, @@ -507,12 +511,12 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ } }); }; - setup_field_label_map(["net_total", "other_charges_total", "grand_total", + setup_field_label_map(["net_total", "other_charges_total", "base_discount_amount", "grand_total", "rounded_total", "in_words", "outstanding_amount", "total_advance", "paid_amount", "write_off_amount"], company_currency); - setup_field_label_map(["net_total_export", "other_charges_total_export", "grand_total_export", + setup_field_label_map(["net_total_export", "other_charges_total_export", "discount_amount", "grand_total_export", "rounded_total_export", "in_words_export"], this.frm.doc.currency); cur_frm.set_df_property("conversion_rate", "description", "1 " + this.frm.doc.currency @@ -525,7 +529,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ // toggle fields this.frm.toggle_display(["conversion_rate", "net_total", "other_charges_total", - "grand_total", "rounded_total", "in_words"], + "grand_total", "rounded_total", "in_words", "base_discount_amount"], this.frm.doc.currency != company_currency); this.frm.toggle_display(["plc_conversion_rate", "price_list_currency"], diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.json b/erpnext/stock/doctype/delivery_note/delivery_note.json index 98e774804f9..c7a25d2e618 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.json +++ b/erpnext/stock/doctype/delivery_note/delivery_note.json @@ -434,6 +434,15 @@ "fieldtype": "Section Break", "permlevel": 0 }, + { + "fieldname": "other_charges_total_export", + "fieldtype": "Currency", + "label": "Taxes and Charges Total", + "options": "Company:company:default_currency", + "permlevel": 0, + "print_hide": 1, + "read_only": 1 + }, { "fieldname": "other_charges_total", "fieldtype": "Currency", @@ -452,22 +461,23 @@ "fieldtype": "Column Break", "permlevel": 0 }, - { - "fieldname": "other_charges_total_export", - "fieldtype": "Currency", - "label": "Taxes and Charges Total", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": 1, - "read_only": 1 - }, { "fieldname": "discount_amount", "fieldtype": "Currency", "label": "Discount Amount", - "options": "Company:company:default_currency", + "options": "currency", "permlevel": 0 }, + { + "fieldname": "base_discount_amount", + "fieldtype": "Currency", + "label": "Discount Amount (Company Currency)", + "options": "Company:company:default_currency", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "read_only": 1 + }, { "fieldname": "totals", "fieldtype": "Section Break", @@ -1013,7 +1023,7 @@ "idx": 1, "in_create": 0, "is_submittable": 1, - "modified": "2014-12-22 14:58:19.575566", + "modified": "2015-01-12 16:56:39.975961", "modified_by": "Administrator", "module": "Stock", "name": "Delivery Note", diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index fffb52e835f..5145e0ab170 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals import frappe from frappe import _, throw -from frappe.utils import flt, cint, add_days +from frappe.utils import flt, cint, add_days, cstr import json from erpnext.accounts.doctype.pricing_rule.pricing_rule import get_pricing_rule_for_item from erpnext.setup.utils import get_exchange_rate @@ -140,7 +140,7 @@ def get_basic_details(args, item_doc): "item_code": item.name, "item_name": item.item_name, - "description": item.description_html or item.description, + "description": cstr(item.description_html).strip() or cstr(item.description).strip(), "warehouse": user_default_warehouse or args.warehouse or item.default_warehouse, "income_account": (item.income_account or args.income_account From 991962b6fdaa8c6780518dc81f779e1c5e372b90 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Wed, 14 Jan 2015 12:12:45 +0600 Subject: [PATCH 25/26] bumped to version 4.18.0 --- erpnext/__version__.py | 2 +- erpnext/hooks.py | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/__version__.py b/erpnext/__version__.py index 1eef0c42ba9..980bc6f9f1f 100644 --- a/erpnext/__version__.py +++ b/erpnext/__version__.py @@ -1 +1 @@ -__version__ = '4.17.0' +__version__ = '4.18.0' diff --git a/erpnext/hooks.py b/erpnext/hooks.py index e3694532c16..dfa0b2e4049 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -4,7 +4,7 @@ app_publisher = "Web Notes Technologies Pvt. Ltd. and Contributors" app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations" app_icon = "icon-th" app_color = "#e74c3c" -app_version = "4.17.0" +app_version = "4.18.0" error_report_email = "support@erpnext.com" diff --git a/setup.py b/setup.py index eb280084355..e949dd6c3ff 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, find_packages import os -version = "4.17.0" +version = "4.18.0" with open("requirements.txt", "r") as f: install_requires = f.readlines() From f34c96bf7af56d7f55d235ee147ec11b5d17e9de Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 14 Jan 2015 11:48:50 +0530 Subject: [PATCH 26/26] minor fix --- erpnext/patches/v4_2/discount_amount.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/patches/v4_2/discount_amount.py b/erpnext/patches/v4_2/discount_amount.py index e23a10e06c3..3ce10caf892 100644 --- a/erpnext/patches/v4_2/discount_amount.py +++ b/erpnext/patches/v4_2/discount_amount.py @@ -6,7 +6,7 @@ import frappe from frappe.modules import scrub, get_doctype_module def execute(): - for dt in ["Quotation", "Sales Order", "Delivery Note", "Sales invoice"]: + for dt in ["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"]: frappe.reload_doc(get_doctype_module(dt), "doctype", scrub(dt)) frappe.db.sql("""update `tab{0}` set base_discount_amount=discount_amount, discount_amount=discount_amount/conversion_rate""".format(dt))