Merge branch 'hotfix'

This commit is contained in:
Ameya Shenoy 2018-06-06 05:41:37 +00:00
commit a02d5d1104
No known key found for this signature in database
GPG Key ID: AC016A555657D0A3
10 changed files with 68 additions and 26 deletions

View File

@ -5,7 +5,7 @@ import frappe
from erpnext.hooks import regional_overrides from erpnext.hooks import regional_overrides
from frappe.utils import getdate from frappe.utils import getdate
__version__ = '10.1.36' __version__ = '10.1.37'
def get_default_company(user=None): def get_default_company(user=None):
'''Get default company for user''' '''Get default company for user'''

View File

@ -35,6 +35,7 @@ class BuyingController(StockController):
if getattr(self, "supplier", None) and not self.supplier_name: if getattr(self, "supplier", None) and not self.supplier_name:
self.supplier_name = frappe.db.get_value("Supplier", self.supplier, "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.set_qty_as_per_stock_uom()
self.validate_stock_or_nonstock_items() self.validate_stock_or_nonstock_items()
self.validate_warehouse() self.validate_warehouse()
@ -456,3 +457,31 @@ class BuyingController(StockController):
else: else:
frappe.throw(_("Please enter Reqd by Date")) 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 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")
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 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("""
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)))

View File

@ -35,6 +35,7 @@ class SellingController(StockController):
def validate(self): def validate(self):
super(SellingController, self).validate() super(SellingController, self).validate()
self.validate_items()
self.validate_max_discount() self.validate_max_discount()
self.validate_selling_price() self.validate_selling_price()
self.set_qty_as_per_stock_uom() 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)}) 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]))) 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): def check_active_sales_items(obj):
for d in obj.get("items"): for d in obj.get("items"):
if d.item_code: if d.item_code:

View File

@ -45,8 +45,9 @@ class ExpenseClaim(AccountsController):
}[cstr(self.docstatus or 0)] }[cstr(self.docstatus or 0)]
paid_amount = flt(self.total_amount_reimbursed) + flt(self.total_advance_amount) 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 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': and self.docstatus == 1 and self.approval_status == 'Approved':
self.status = "Paid" self.status = "Paid"
elif flt(self.total_sanctioned_amount) > 0 and self.docstatus == 1 and self.approval_status == 'Approved': elif flt(self.total_sanctioned_amount) > 0 and self.docstatus == 1 and self.approval_status == 'Approved':

View File

@ -169,21 +169,25 @@ erpnext.utils.validate_mandatory = function(frm, label, value, trigger_on) {
} }
erpnext.utils.get_shipping_address = function(frm, callback){ erpnext.utils.get_shipping_address = function(frm, callback){
frappe.call({ if (frm.doc.company) {
method: "frappe.contacts.doctype.address.address.get_shipping_address", frappe.call({
args: { method: "frappe.contacts.doctype.address.address.get_shipping_address",
company: frm.doc.company, args: {
address: frm.doc.shipping_address company: frm.doc.company,
}, address: frm.doc.shipping_address
callback: function(r){ },
if(r.message){ callback: function(r){
frm.set_value("shipping_address", r.message[0]) //Address title or name if(r.message){
frm.set_value("shipping_address_display", r.message[1]) //Address to be displayed on the page 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){ if(callback){
return callback(); return callback();
}
} }
} });
}); } else {
frappe.msgprint(__("Select company first"));
}
} }

View File

@ -79,7 +79,7 @@ class Customer(TransactionBase):
def update_customer_groups(self): def update_customer_groups(self):
ignore_doctypes = ["Lead", "Opportunity", "POS Profile", "Tax Rule", "Pricing Rule"] ignore_doctypes = ["Lead", "Opportunity", "POS Profile", "Tax Rule", "Pricing Rule"]
if frappe.flags.customer_group_changed: 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) self.customer_group, ignore_doctypes)
def create_primary_contact(self): def create_primary_contact(self):

View File

@ -40,7 +40,7 @@ class AuthorizationControl(TransactionBase):
chk = 1 chk = 1
add_cond1,add_cond2 = '','' add_cond1,add_cond2 = '',''
if based_on == 'Itemwise Discount': 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` itemwise_exists = frappe.db.sql("""select value from `tabAuthorization Rule`
where transaction = %s and value <= %s where transaction = %s and value <= %s
and based_on = %s and company = %s and docstatus != 2 %s %s""" % and based_on = %s and company = %s and docstatus != 2 %s %s""" %

View File

@ -2,6 +2,7 @@
# 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 frappe, unittest import frappe, unittest
from frappe.utils import flt
from erpnext.setup.utils import get_exchange_rate from erpnext.setup.utils import get_exchange_rate
test_records = frappe.get_test_records('Currency Exchange') test_records = frappe.get_test_records('Currency Exchange')
@ -44,7 +45,7 @@ class TestCurrencyExchange(unittest.TestCase):
# Start with allow_stale is True # Start with allow_stale is True
exchange_rate = get_exchange_rate("USD", "INR", "2016-01-01") 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") exchange_rate = get_exchange_rate("USD", "INR", "2016-01-15")
self.assertEqual(exchange_rate, 65.1) self.assertEqual(exchange_rate, 65.1)
@ -56,7 +57,7 @@ class TestCurrencyExchange(unittest.TestCase):
self.clear_cache() self.clear_cache()
exchange_rate = get_exchange_rate("USD", "INR", "2015-12-15") exchange_rate = get_exchange_rate("USD", "INR", "2015-12-15")
self.assertFalse(exchange_rate == 60) 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): def test_exchange_rate_strict(self):
# strict currency settings # strict currency settings
@ -69,7 +70,7 @@ class TestCurrencyExchange(unittest.TestCase):
# Will fetch from fixer.io # Will fetch from fixer.io
self.clear_cache() self.clear_cache()
exchange_rate = get_exchange_rate("USD", "INR", "2016-01-15") 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") exchange_rate = get_exchange_rate("USD", "INR", "2016-01-30")
self.assertEqual(exchange_rate, 62.9) 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 # Exchange rate as on 15th Dec, 2015, should be fetched from fixer.io
self.clear_cache() self.clear_cache()
exchange_rate = get_exchange_rate("USD", "INR", "2015-12-15") 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") exchange_rate = get_exchange_rate("INR", "NGN", "2016-01-10")
self.assertEqual(exchange_rate, 65.1) self.assertEqual(exchange_rate, 65.1)
@ -100,4 +101,4 @@ class TestCurrencyExchange(unittest.TestCase):
# Will fetch from fixer.io # Will fetch from fixer.io
self.clear_cache() self.clear_cache()
exchange_rate = get_exchange_rate("USD", "INR", "2016-01-15") exchange_rate = get_exchange_rate("USD", "INR", "2016-01-15")
self.assertEqual(exchange_rate, 67.79) self.assertEqual(flt(exchange_rate, 3), 67.79)

View File

@ -95,7 +95,7 @@ def get_exchange_rate(from_currency, to_currency, transaction_date=None):
if not value: if not value:
import requests 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={ response = requests.get(api_url, params={
"base": from_currency, "base": from_currency,
"symbols": to_currency "symbols": to_currency

View File

@ -88,6 +88,7 @@
"label": "Item Name", "label": "Item Name",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"options": "item_code.item_name",
"permlevel": 0, "permlevel": 0,
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0, "print_hide_if_no_value": 0,
@ -435,7 +436,7 @@
"issingle": 0, "issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "max_attachments": 0,
"modified": "2017-02-20 13:30:26.818408", "modified": "2018-06-01 07:21:58.220980",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Stock", "module": "Stock",
"name": "Packing Slip Item", "name": "Packing Slip Item",