From 7e0e85912baef48d484f0762b69a0a4541dad00e Mon Sep 17 00:00:00 2001 From: Zarrar Date: Fri, 1 Jun 2018 15:10:33 +0530 Subject: [PATCH 01/11] item_name not fetched in packing slip (#14310) --- erpnext/stock/doctype/packing_slip_item/packing_slip_item.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/packing_slip_item/packing_slip_item.json b/erpnext/stock/doctype/packing_slip_item/packing_slip_item.json index 009244ce5e..d240b7d840 100644 --- a/erpnext/stock/doctype/packing_slip_item/packing_slip_item.json +++ b/erpnext/stock/doctype/packing_slip_item/packing_slip_item.json @@ -88,6 +88,7 @@ "label": "Item Name", "length": 0, "no_copy": 0, + "options": "item_code.item_name", "permlevel": 0, "print_hide": 0, "print_hide_if_no_value": 0, @@ -435,7 +436,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2017-02-20 13:30:26.818408", + "modified": "2018-06-01 07:21:58.220980", "modified_by": "Administrator", "module": "Stock", "name": "Packing Slip Item", From 2fa057e4ad830d0b8afe9adf4a8ec7a1affffde2 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Fri, 1 Jun 2018 15:10:55 +0530 Subject: [PATCH 02/11] [Fix] Expense claim showing status as Unpaid even if Total Advance Amount and Total Sanctioned Amount is same (#14311) --- erpnext/hr/doctype/expense_claim/expense_claim.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.py b/erpnext/hr/doctype/expense_claim/expense_claim.py index d0c4a46e3e..f674a61d91 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.py +++ b/erpnext/hr/doctype/expense_claim/expense_claim.py @@ -45,8 +45,9 @@ class ExpenseClaim(AccountsController): }[cstr(self.docstatus or 0)] paid_amount = flt(self.total_amount_reimbursed) + flt(self.total_advance_amount) + precision = self.precision("total_sanctioned_amount") if (self.is_paid or (flt(self.total_sanctioned_amount) > 0 - and flt(self.total_sanctioned_amount) == paid_amount)) \ + and flt(self.total_sanctioned_amount, precision) == flt(paid_amount, precision))) \ and self.docstatus == 1 and self.approval_status == 'Approved': self.status = "Paid" elif flt(self.total_sanctioned_amount) > 0 and self.docstatus == 1 and self.approval_status == 'Approved': From ce642d73cb092618197fad03394b930a4ecb7654 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Fri, 1 Jun 2018 15:11:21 +0530 Subject: [PATCH 03/11] [Fix] Special character issue while upadting customer group in customer (#14312) --- erpnext/selling/doctype/customer/customer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py index 7232fadb56..b17345c2e7 100644 --- a/erpnext/selling/doctype/customer/customer.py +++ b/erpnext/selling/doctype/customer/customer.py @@ -79,7 +79,7 @@ class Customer(TransactionBase): def update_customer_groups(self): ignore_doctypes = ["Lead", "Opportunity", "POS Profile", "Tax Rule", "Pricing Rule"] if frappe.flags.customer_group_changed: - update_linked_doctypes('Customer', self.name, 'Customer Group', + update_linked_doctypes('Customer', frappe.db.escape(self.name), 'Customer Group', self.customer_group, ignore_doctypes) def create_primary_contact(self): From c1cf495a93b16a0e01a632cbb2ecf0e79c92c851 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Sun, 3 Jun 2018 16:00:31 +0530 Subject: [PATCH 04/11] [Fix] Special character issue (#14322) --- .../doctype/authorization_control/authorization_control.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/setup/doctype/authorization_control/authorization_control.py b/erpnext/setup/doctype/authorization_control/authorization_control.py index 7d5e80b8f2..2240e0c28b 100644 --- a/erpnext/setup/doctype/authorization_control/authorization_control.py +++ b/erpnext/setup/doctype/authorization_control/authorization_control.py @@ -40,7 +40,7 @@ class AuthorizationControl(TransactionBase): chk = 1 add_cond1,add_cond2 = '','' if based_on == 'Itemwise Discount': - add_cond1 += " and master_name = '"+cstr(item).replace("'", "\\'")+"'" + add_cond1 += " and master_name = '"+cstr(frappe.db.escape(item)).replace("'", "\\'")+"'" itemwise_exists = frappe.db.sql("""select value from `tabAuthorization Rule` where transaction = %s and value <= %s and based_on = %s and company = %s and docstatus != 2 %s %s""" % From 5ecc26bf153428a2a993a8a6e52253452299993d Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Mon, 4 Jun 2018 11:00:24 +0530 Subject: [PATCH 05/11] [Fix] get_shipping_address() takes at least 1 argument (0 given) (#14328) --- erpnext/public/js/utils/party.js | 34 ++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/erpnext/public/js/utils/party.js b/erpnext/public/js/utils/party.js index 75d5ce9e21..0f28d4e3ba 100644 --- a/erpnext/public/js/utils/party.js +++ b/erpnext/public/js/utils/party.js @@ -169,21 +169,25 @@ erpnext.utils.validate_mandatory = function(frm, label, value, trigger_on) { } erpnext.utils.get_shipping_address = function(frm, callback){ - frappe.call({ - method: "frappe.contacts.doctype.address.address.get_shipping_address", - args: { - company: frm.doc.company, - address: frm.doc.shipping_address - }, - callback: function(r){ - if(r.message){ - frm.set_value("shipping_address", r.message[0]) //Address title or name - frm.set_value("shipping_address_display", r.message[1]) //Address to be displayed on the page - } + if (frm.doc.company) { + frappe.call({ + method: "frappe.contacts.doctype.address.address.get_shipping_address", + args: { + company: frm.doc.company, + address: frm.doc.shipping_address + }, + callback: function(r){ + if(r.message){ + frm.set_value("shipping_address", r.message[0]) //Address title or name + frm.set_value("shipping_address_display", r.message[1]) //Address to be displayed on the page + } - if(callback){ - return callback(); + if(callback){ + return callback(); + } } - } - }); + }); + } else { + frappe.msgprint(__("Select company first")); + } } \ No newline at end of file From fc03a0463c0611c5ed48a878b5c042ce2348e4cd Mon Sep 17 00:00:00 2001 From: Zarrar Date: Mon, 4 Jun 2018 12:52:52 +0530 Subject: [PATCH 06/11] [Fix] Validate items for saleable, purchaseable or subcontractable in transactions (#14316) * validate items to see if they are saleable * check if items are subcontractable or saleable * improvise name,error message and code Validate type function validates item if they are of proper type for that transaction and throws descriptive error. --- erpnext/controllers/buying_controller.py | 24 +++++++++++++++++++++++ erpnext/controllers/selling_controller.py | 6 ++++++ 2 files changed, 30 insertions(+) diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index 4b7b43cc19..3536233fc8 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -35,6 +35,7 @@ class BuyingController(StockController): if getattr(self, "supplier", None) and not self.supplier_name: self.supplier_name = frappe.db.get_value("Supplier", self.supplier, "supplier_name") + self.validate_items() self.set_qty_as_per_stock_uom() self.validate_stock_or_nonstock_items() self.validate_warehouse() @@ -456,3 +457,26 @@ class BuyingController(StockController): else: frappe.throw(_("Please enter Reqd by Date")) + def validate_items(self): + # validate items to see if they have is_purchase_item or is_subcontracted_item enabled + + if self.is_subcontracted: + validate_item_type(self, "is_sub_contracted_item", "subcontracted") + else: + validate_item_type(self, "is_purchase_item", "purchase") + +def validate_item_type(doc, fieldname, message): + # iterate through items and check if they are valid sales or purchase items + items = [d.item_code for d in doc.items] + item_list = ", ".join(["'%s'" % frappe.db.escape(d) for d in items]) + + invalid_items = [d[0] for d in frappe.db.sql(""" + select item_code from tabItem where name in ({0}) and {1}=0 + """.format(item_list, fieldname), as_list=True)] + + if invalid_items: + frappe.throw(_("Following item {items} {verb} not marked as {message} item.\ + You can enable them as {message} item from its Item master".format( + items = ", ".join([d for d in invalid_items]), + verb = "are" if len(invalid_items) > 1 else "is", + message = message))) diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index 2a22b32637..fcc9d75e79 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -35,6 +35,7 @@ class SellingController(StockController): def validate(self): super(SellingController, self).validate() + self.validate_items() self.validate_max_discount() self.validate_selling_price() self.set_qty_as_per_stock_uom() @@ -337,6 +338,11 @@ class SellingController(StockController): po_nos = frappe.get_all('Sales Order', 'po_no', filters = {'name': ('in', sales_orders)}) self.po_no = ', '.join(list(set([d.po_no for d in po_nos if d.po_no]))) + def validate_items(self): + # validate items to see if they have is_sales_item enabled + from erpnext.controllers.buying_controller import validate_item_type + validate_item_type(self, "is_sales_item", "sales") + def check_active_sales_items(obj): for d in obj.get("items"): if d.item_code: From 7cf01e7c75e4e8d28e4f3f7e71f670b9dd0a6534 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Tue, 5 Jun 2018 10:30:20 +0530 Subject: [PATCH 07/11] Replaced fixer api with exchangeratesapi (#14347) --- erpnext/setup/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/setup/utils.py b/erpnext/setup/utils.py index 5fcc3a2c68..4f62815f90 100644 --- a/erpnext/setup/utils.py +++ b/erpnext/setup/utils.py @@ -95,7 +95,7 @@ def get_exchange_rate(from_currency, to_currency, transaction_date=None): if not value: import requests - api_url = "http://api.fixer.io/{0}".format(transaction_date) + api_url = "https://exchangeratesapi.io/api/{0}".format(transaction_date) response = requests.get(api_url, params={ "base": from_currency, "symbols": to_currency From 7c088ff6233a651b868a57cbfa44c917e5ddd70f Mon Sep 17 00:00:00 2001 From: Zarrar Date: Tue, 5 Jun 2018 10:32:09 +0530 Subject: [PATCH 08/11] dont validate items if item_code not found (#14344) item_code field is not set when created using invoice creation tool --- erpnext/controllers/buying_controller.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index 3536233fc8..b0d1e348b9 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -467,7 +467,12 @@ class BuyingController(StockController): def validate_item_type(doc, fieldname, message): # iterate through items and check if they are valid sales or purchase items - items = [d.item_code for d in doc.items] + items = [d.item_code for d in doc.items if d.item_code] + + # No validation check inase of creating transaction using 'Opening Invoice Creation Tool' + if not items: + return + item_list = ", ".join(["'%s'" % frappe.db.escape(d) for d in items]) invalid_items = [d[0] for d in frappe.db.sql(""" From 50d8c4a10fa9cf11df36f339a9dcce9317c49bdf Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Tue, 5 Jun 2018 13:08:10 +0530 Subject: [PATCH 09/11] [Fix] Not able to save purchase invoice, due to invalid condition (#14355) --- erpnext/controllers/buying_controller.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index b0d1e348b9..48b82bde40 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -460,7 +460,7 @@ class BuyingController(StockController): def validate_items(self): # validate items to see if they have is_purchase_item or is_subcontracted_item enabled - if self.is_subcontracted: + if hasattr(self, "is_subcontracted") and self.is_subcontracted == 'Yes': validate_item_type(self, "is_sub_contracted_item", "subcontracted") else: validate_item_type(self, "is_purchase_item", "purchase") From 6ff3a094e20148dc0be185684a9bea2675976142 Mon Sep 17 00:00:00 2001 From: Shreya Shah Date: Tue, 5 Jun 2018 14:16:10 +0530 Subject: [PATCH 10/11] Fix currency exchange tests (#14356) --- .../currency_exchange/test_currency_exchange.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/erpnext/setup/doctype/currency_exchange/test_currency_exchange.py b/erpnext/setup/doctype/currency_exchange/test_currency_exchange.py index 6d5848ad78..c488b996ff 100644 --- a/erpnext/setup/doctype/currency_exchange/test_currency_exchange.py +++ b/erpnext/setup/doctype/currency_exchange/test_currency_exchange.py @@ -2,6 +2,7 @@ # License: GNU General Public License v3. See license.txt from __future__ import unicode_literals import frappe, unittest +from frappe.utils import flt from erpnext.setup.utils import get_exchange_rate test_records = frappe.get_test_records('Currency Exchange') @@ -44,7 +45,7 @@ class TestCurrencyExchange(unittest.TestCase): # Start with allow_stale is True exchange_rate = get_exchange_rate("USD", "INR", "2016-01-01") - self.assertEqual(exchange_rate, 60.0) + self.assertEqual(flt(exchange_rate, 3), 60.0) exchange_rate = get_exchange_rate("USD", "INR", "2016-01-15") self.assertEqual(exchange_rate, 65.1) @@ -56,7 +57,7 @@ class TestCurrencyExchange(unittest.TestCase): self.clear_cache() exchange_rate = get_exchange_rate("USD", "INR", "2015-12-15") self.assertFalse(exchange_rate == 60) - self.assertEqual(exchange_rate, 66.894) + self.assertEqual(flt(exchange_rate, 3), 66.894) def test_exchange_rate_strict(self): # strict currency settings @@ -69,7 +70,7 @@ class TestCurrencyExchange(unittest.TestCase): # Will fetch from fixer.io self.clear_cache() exchange_rate = get_exchange_rate("USD", "INR", "2016-01-15") - self.assertEqual(exchange_rate, 67.79) + self.assertEqual(flt(exchange_rate, 3), 67.79) exchange_rate = get_exchange_rate("USD", "INR", "2016-01-30") self.assertEqual(exchange_rate, 62.9) @@ -77,7 +78,7 @@ class TestCurrencyExchange(unittest.TestCase): # Exchange rate as on 15th Dec, 2015, should be fetched from fixer.io self.clear_cache() exchange_rate = get_exchange_rate("USD", "INR", "2015-12-15") - self.assertEqual(exchange_rate, 66.894) + self.assertEqual(flt(exchange_rate, 3), 66.894) exchange_rate = get_exchange_rate("INR", "NGN", "2016-01-10") self.assertEqual(exchange_rate, 65.1) @@ -100,4 +101,4 @@ class TestCurrencyExchange(unittest.TestCase): # Will fetch from fixer.io self.clear_cache() exchange_rate = get_exchange_rate("USD", "INR", "2016-01-15") - self.assertEqual(exchange_rate, 67.79) \ No newline at end of file + self.assertEqual(flt(exchange_rate, 3), 67.79) \ No newline at end of file From 36cd43399911fc6085d09e2edde6f82664d6ab2f Mon Sep 17 00:00:00 2001 From: Ameya Shenoy Date: Wed, 6 Jun 2018 05:41:37 +0000 Subject: [PATCH 11/11] bumped to version 10.1.37 --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 6503508c4e..ba42d34e23 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -5,7 +5,7 @@ import frappe from erpnext.hooks import regional_overrides from frappe.utils import getdate -__version__ = '10.1.36' +__version__ = '10.1.37' def get_default_company(user=None): '''Get default company for user'''