Merge branch 'master' into develop
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index b9e3cfc..83c6069 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -5,7 +5,7 @@
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'''
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index bbe1a12..c1df2b5 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -38,6 +38,7 @@
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()
@@ -660,6 +661,14 @@
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 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 get_items_from_bom(item_code, bom, exploded_item=1):
doctype = "BOM Item" if not exploded_item else "BOM Explosion Item"
@@ -709,3 +718,24 @@
asset_items_data.setdefault(d.name, d)
return asset_items_data
+
+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)))
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index 4a358a4..1fcd11d 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -35,6 +35,7 @@
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 @@
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:
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.py b/erpnext/hr/doctype/expense_claim/expense_claim.py
index 3a4d360..801a0ef 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.py
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.py
@@ -41,8 +41,9 @@
}[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':
diff --git a/erpnext/public/js/utils/party.js b/erpnext/public/js/utils/party.js
index 5480aed..378a803 100644
--- a/erpnext/public/js/utils/party.js
+++ b/erpnext/public/js/utils/party.js
@@ -170,21 +170,25 @@
}
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
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index 5a95b55..b5961a9 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -76,7 +76,7 @@
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):
diff --git a/erpnext/setup/doctype/authorization_control/authorization_control.py b/erpnext/setup/doctype/authorization_control/authorization_control.py
index 7d5e80b..2240e0c 100644
--- a/erpnext/setup/doctype/authorization_control/authorization_control.py
+++ b/erpnext/setup/doctype/authorization_control/authorization_control.py
@@ -40,7 +40,7 @@
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""" %
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 1b22f13..29c4193 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",