Merge branch 'master' into develop
This commit is contained in:
		
						commit
						873e28d9b8
					
				| @ -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''' | ||||||
|  | |||||||
| @ -38,6 +38,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() | ||||||
| @ -660,6 +661,14 @@ 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 get_items_from_bom(item_code, bom, exploded_item=1): | def get_items_from_bom(item_code, bom, exploded_item=1): | ||||||
| 	doctype = "BOM Item" if not exploded_item else "BOM Explosion Item" | 	doctype = "BOM Item" if not exploded_item else "BOM Explosion Item" | ||||||
| 
 | 
 | ||||||
| @ -709,3 +718,24 @@ def get_asset_item_details(asset_items): | |||||||
| 		asset_items_data.setdefault(d.name, d) | 		asset_items_data.setdefault(d.name, d) | ||||||
| 
 | 
 | ||||||
| 	return asset_items_data | 	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))) | ||||||
|  | |||||||
| @ -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: | ||||||
|  | |||||||
| @ -41,8 +41,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': | ||||||
|  | |||||||
| @ -170,6 +170,7 @@ 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){ | ||||||
|  | 	if (frm.doc.company) { | ||||||
| 		frappe.call({ | 		frappe.call({ | ||||||
| 			method: "frappe.contacts.doctype.address.address.get_shipping_address", | 			method: "frappe.contacts.doctype.address.address.get_shipping_address", | ||||||
| 			args: { | 			args: { | ||||||
| @ -187,4 +188,7 @@ erpnext.utils.get_shipping_address = function(frm, callback){ | |||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
|  | 	} else { | ||||||
|  | 		frappe.msgprint(__("Select company first")); | ||||||
|  | 	} | ||||||
| } | } | ||||||
| @ -76,7 +76,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): | ||||||
|  | |||||||
| @ -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""" % | ||||||
|  | |||||||
| @ -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",  | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user