Merge pull request #19606 from deepeshgarg007/shareholder_refactor
refactor: Share Transfer code cleanup and refactor
This commit is contained in:
		
						commit
						31a4fa5dd3
					
				| @ -13,9 +13,9 @@ from frappe.utils import nowdate | ||||
| class ShareDontExists(ValidationError): pass | ||||
| 
 | ||||
| class ShareTransfer(Document): | ||||
| 	def before_submit(self): | ||||
| 	def on_submit(self): | ||||
| 		if self.transfer_type == 'Issue': | ||||
| 			shareholder = self.get_shareholder_doc(self.company) | ||||
| 			shareholder = self.get_company_shareholder() | ||||
| 			shareholder.append('share_balance', { | ||||
| 				'share_type': self.share_type, | ||||
| 				'from_no': self.from_no, | ||||
| @ -28,7 +28,7 @@ class ShareTransfer(Document): | ||||
| 			}) | ||||
| 			shareholder.save() | ||||
| 
 | ||||
| 			doc = frappe.get_doc('Shareholder', self.to_shareholder) | ||||
| 			doc = self.get_shareholder_doc(self.to_shareholder) | ||||
| 			doc.append('share_balance', { | ||||
| 				'share_type': self.share_type, | ||||
| 				'from_no': self.from_no, | ||||
| @ -41,11 +41,11 @@ class ShareTransfer(Document): | ||||
| 
 | ||||
| 		elif self.transfer_type == 'Purchase': | ||||
| 			self.remove_shares(self.from_shareholder) | ||||
| 			self.remove_shares(self.get_shareholder_doc(self.company).name) | ||||
| 			self.remove_shares(self.get_company_shareholder().name) | ||||
| 
 | ||||
| 		elif self.transfer_type == 'Transfer': | ||||
| 			self.remove_shares(self.from_shareholder) | ||||
| 			doc = frappe.get_doc('Shareholder', self.to_shareholder) | ||||
| 			doc = self.get_shareholder_doc(self.to_shareholder) | ||||
| 			doc.append('share_balance', { | ||||
| 				'share_type': self.share_type, | ||||
| 				'from_no': self.from_no, | ||||
| @ -56,143 +56,127 @@ class ShareTransfer(Document): | ||||
| 			}) | ||||
| 			doc.save() | ||||
| 
 | ||||
| 	def on_cancel(self): | ||||
| 		if self.transfer_type == 'Issue': | ||||
| 			compnay_shareholder = self.get_company_shareholder() | ||||
| 			self.remove_shares(compnay_shareholder.name) | ||||
| 			self.remove_shares(self.to_shareholder) | ||||
| 
 | ||||
| 		elif self.transfer_type == 'Purchase': | ||||
| 			compnay_shareholder = self.get_company_shareholder() | ||||
| 			from_shareholder = self.get_shareholder_doc(self.from_shareholder) | ||||
| 
 | ||||
| 			from_shareholder.append('share_balance', { | ||||
| 				'share_type': self.share_type, | ||||
| 				'from_no': self.from_no, | ||||
| 				'to_no': self.to_no, | ||||
| 				'rate': self.rate, | ||||
| 				'amount': self.amount, | ||||
| 				'no_of_shares': self.no_of_shares | ||||
| 			}) | ||||
| 
 | ||||
| 			from_shareholder.save() | ||||
| 
 | ||||
| 			compnay_shareholder.append('share_balance', { | ||||
| 				'share_type': self.share_type, | ||||
| 				'from_no': self.from_no, | ||||
| 				'to_no': self.to_no, | ||||
| 				'rate': self.rate, | ||||
| 				'amount': self.amount, | ||||
| 				'no_of_shares': self.no_of_shares | ||||
| 			}) | ||||
| 
 | ||||
| 			compnay_shareholder.save() | ||||
| 
 | ||||
| 		elif self.transfer_type == 'Transfer': | ||||
| 			self.remove_shares(self.to_shareholder) | ||||
| 			from_shareholder = self.get_shareholder_doc(self.from_shareholder) | ||||
| 			from_shareholder.append('share_balance', { | ||||
| 				'share_type': self.share_type, | ||||
| 				'from_no': self.from_no, | ||||
| 				'to_no': self.to_no, | ||||
| 				'rate': self.rate, | ||||
| 				'amount': self.amount, | ||||
| 				'no_of_shares': self.no_of_shares | ||||
| 			}) | ||||
| 			from_shareholder.save() | ||||
| 
 | ||||
| 	def validate(self): | ||||
| 		self.get_company_shareholder() | ||||
| 		self.basic_validations() | ||||
| 		self.folio_no_validation() | ||||
| 
 | ||||
| 		if self.transfer_type == 'Issue': | ||||
| 			if not self.get_shareholder_doc(self.company): | ||||
| 				shareholder = frappe.get_doc({ | ||||
| 					'doctype': 'Shareholder', | ||||
| 					'title': self.company, | ||||
| 					'company': self.company, | ||||
| 					'is_company': 1 | ||||
| 				}) | ||||
| 				shareholder.insert() | ||||
| 			# validate share doesnt exist in company | ||||
| 			ret_val = self.share_exists(self.get_shareholder_doc(self.company).name) | ||||
| 			if ret_val != False: | ||||
| 			# validate share doesn't exist in company | ||||
| 			ret_val = self.share_exists(self.get_company_shareholder().name) | ||||
| 			if ret_val in ('Complete', 'Partial'): | ||||
| 				frappe.throw(_('The shares already exist'), frappe.DuplicateEntryError) | ||||
| 		else: | ||||
| 			# validate share exists with from_shareholder | ||||
| 			ret_val = self.share_exists(self.from_shareholder) | ||||
| 			if ret_val != True: | ||||
| 			if ret_val in ('Outside', 'Partial'): | ||||
| 				frappe.throw(_("The shares don't exist with the {0}") | ||||
| 					.format(self.from_shareholder), ShareDontExists) | ||||
| 
 | ||||
| 	def basic_validations(self): | ||||
| 		if self.transfer_type == 'Purchase': | ||||
| 			self.to_shareholder = '' | ||||
| 			if self.from_shareholder is None or self.from_shareholder is '': | ||||
| 			if not self.from_shareholder: | ||||
| 				frappe.throw(_('The field From Shareholder cannot be blank')) | ||||
| 			if self.from_folio_no is None or self.from_folio_no is '': | ||||
| 			if not self.from_folio_no: | ||||
| 				self.to_folio_no = self.autoname_folio(self.to_shareholder) | ||||
| 			if self.asset_account is None: | ||||
| 			if not self.asset_account: | ||||
| 				frappe.throw(_('The field Asset Account cannot be blank')) | ||||
| 		elif (self.transfer_type == 'Issue'): | ||||
| 			self.from_shareholder = '' | ||||
| 			if self.to_shareholder is None or self.to_shareholder == '': | ||||
| 			if not self.to_shareholder: | ||||
| 				frappe.throw(_('The field To Shareholder cannot be blank')) | ||||
| 			if self.to_folio_no is None or self.to_folio_no is '': | ||||
| 			if not self.to_folio_no: | ||||
| 				self.to_folio_no = self.autoname_folio(self.to_shareholder) | ||||
| 			if self.asset_account is None: | ||||
| 			if not self.asset_account: | ||||
| 				frappe.throw(_('The field Asset Account cannot be blank')) | ||||
| 		else: | ||||
| 			if self.from_shareholder is None or self.to_shareholder is None: | ||||
| 			if not self.from_shareholder or not self.to_shareholder: | ||||
| 				frappe.throw(_('The fields From Shareholder and To Shareholder cannot be blank')) | ||||
| 			if self.to_folio_no is None or self.to_folio_no is '': | ||||
| 			if not self.to_folio_no: | ||||
| 				self.to_folio_no = self.autoname_folio(self.to_shareholder) | ||||
| 		if self.equity_or_liability_account is None: | ||||
| 		if not self.equity_or_liability_account: | ||||
| 				frappe.throw(_('The field Equity/Liability Account cannot be blank')) | ||||
| 		if self.from_shareholder == self.to_shareholder: | ||||
| 			frappe.throw(_('The seller and the buyer cannot be the same')) | ||||
| 		if self.no_of_shares != self.to_no - self.from_no + 1: | ||||
| 			frappe.throw(_('The number of shares and the share numbers are inconsistent')) | ||||
| 		if self.amount is None: | ||||
| 		if not self.amount: | ||||
| 			self.amount = self.rate * self.no_of_shares | ||||
| 		if self.amount != self.rate * self.no_of_shares: | ||||
| 			frappe.throw(_('There are inconsistencies between the rate, no of shares and the amount calculated')) | ||||
| 
 | ||||
| 	def share_exists(self, shareholder): | ||||
| 		# return True if exits, | ||||
| 		# False if completely doesn't exist, | ||||
| 		# 'partially exists' if partailly doesn't exist | ||||
| 		ret_val = self.recursive_share_check(shareholder, self.share_type, | ||||
| 			query = { | ||||
| 				'from_no': self.from_no, | ||||
| 				'to_no': self.to_no | ||||
| 			} | ||||
| 		) | ||||
| 		if all(boolean == True for boolean in ret_val): | ||||
| 			return True | ||||
| 		elif True in ret_val: | ||||
| 			return 'partially exists' | ||||
| 		else: | ||||
| 			return False | ||||
| 
 | ||||
| 	def recursive_share_check(self, shareholder, share_type, query): | ||||
| 		# query = {'from_no': share_starting_no, 'to_no': share_ending_no} | ||||
| 		# Recursive check if a given part of shares is held by the shareholder | ||||
| 		# return a list containing True and False | ||||
| 		# Eg. [True, False, True] | ||||
| 		# All True  implies its completely inside | ||||
| 		# All False implies its completely outside | ||||
| 		# A   mix   implies its partially  inside/outside | ||||
| 		does_share_exist = [] | ||||
| 		doc = frappe.get_doc('Shareholder', shareholder) | ||||
| 		doc = self.get_shareholder_doc(shareholder) | ||||
| 		for entry in doc.share_balance: | ||||
| 			if entry.share_type != share_type or \ | ||||
| 				entry.from_no > query['to_no'] or \ | ||||
| 				entry.to_no < query['from_no']: | ||||
| 			if entry.share_type != self.share_type or \ | ||||
| 				entry.from_no > self.to_no or \ | ||||
| 				entry.to_no < self.from_no: | ||||
| 				continue # since query lies outside bounds | ||||
| 			elif entry.from_no <= query['from_no'] and entry.to_no >= query['to_no']: | ||||
| 				return [True] # absolute truth! | ||||
| 			elif entry.from_no >= query['from_no'] and entry.to_no <= query['to_no']: | ||||
| 				# split and check | ||||
| 				does_share_exist.extend(self.recursive_share_check(shareholder, | ||||
| 					share_type, | ||||
| 					{ | ||||
| 						'from_no': query['from_no'], | ||||
| 						'to_no': entry.from_no - 1 | ||||
| 					} | ||||
| 				)) | ||||
| 				does_share_exist.append(True) | ||||
| 				does_share_exist.extend(self.recursive_share_check(shareholder, | ||||
| 					share_type, | ||||
| 					{ | ||||
| 						'from_no': entry.to_no + 1, | ||||
| 						'to_no': query['to_no'] | ||||
| 					} | ||||
| 				)) | ||||
| 			elif query['from_no'] <= entry.from_no <= query['to_no'] and entry.to_no >= query['to_no']: | ||||
| 				does_share_exist.extend(self.recursive_share_check(shareholder, | ||||
| 					share_type, | ||||
| 					{ | ||||
| 						'from_no': query['from_no'], | ||||
| 						'to_no': entry.from_no - 1 | ||||
| 					} | ||||
| 				)) | ||||
| 			elif query['from_no'] <= entry.to_no <= query['to_no'] and entry.from_no <= query['from_no']: | ||||
| 				does_share_exist.extend(self.recursive_share_check(shareholder, | ||||
| 					share_type, | ||||
| 					{ | ||||
| 						'from_no': entry.to_no + 1, | ||||
| 						'to_no': query['to_no'] | ||||
| 					} | ||||
| 				)) | ||||
| 			elif entry.from_no <= self.from_no and entry.to_no >= self.to_no: #both inside | ||||
| 				return 'Complete' # absolute truth! | ||||
| 			elif entry.from_no <= self.from_no <= self.to_no: | ||||
| 				return 'Partial' | ||||
| 			elif entry.from_no <= self.to_no <= entry.to_no: | ||||
| 				return 'Partial' | ||||
| 
 | ||||
| 		does_share_exist.append(False) | ||||
| 		return does_share_exist | ||||
| 		return 'Outside' | ||||
| 
 | ||||
| 	def folio_no_validation(self): | ||||
| 		shareholders = ['from_shareholder', 'to_shareholder'] | ||||
| 		shareholders = [shareholder for shareholder in shareholders if self.get(shareholder) is not ''] | ||||
| 		for shareholder in shareholders: | ||||
| 			doc = frappe.get_doc('Shareholder', self.get(shareholder)) | ||||
| 			doc = self.get_shareholder_doc(self.get(shareholder)) | ||||
| 			if doc.company != self.company: | ||||
| 				frappe.throw(_('The shareholder does not belong to this company')) | ||||
| 			if doc.folio_no is '' or doc.folio_no is None: | ||||
| 			if not doc.folio_no: | ||||
| 				doc.folio_no = self.from_folio_no \ | ||||
| 					if (shareholder == 'from_shareholder') else self.to_folio_no; | ||||
| 					if (shareholder == 'from_shareholder') else self.to_folio_no | ||||
| 				doc.save() | ||||
| 			else: | ||||
| 				if doc.folio_no and doc.folio_no != (self.from_folio_no if (shareholder == 'from_shareholder') else self.to_folio_no): | ||||
| @ -200,24 +184,14 @@ class ShareTransfer(Document): | ||||
| 
 | ||||
| 	def autoname_folio(self, shareholder, is_company=False): | ||||
| 		if is_company: | ||||
| 			doc = self.get_shareholder_doc(shareholder) | ||||
| 			doc = self.get_company_shareholder() | ||||
| 		else: | ||||
| 			doc = frappe.get_doc('Shareholder' , shareholder) | ||||
| 			doc = self.get_shareholder_doc(shareholder) | ||||
| 		doc.folio_no = make_autoname('FN.#####') | ||||
| 		doc.save() | ||||
| 		return doc.folio_no | ||||
| 
 | ||||
| 	def remove_shares(self, shareholder): | ||||
| 		self.iterative_share_removal(shareholder, self.share_type, | ||||
| 			{ | ||||
| 				'from_no': self.from_no, | ||||
| 				'to_no'  : self.to_no | ||||
| 			}, | ||||
| 			rate = self.rate, | ||||
| 			amount = self.amount | ||||
| 		) | ||||
| 
 | ||||
| 	def iterative_share_removal(self, shareholder, share_type, query, rate, amount): | ||||
| 		# query = {'from_no': share_starting_no, 'to_no': share_ending_no} | ||||
| 		# Shares exist for sure | ||||
| 		# Iterate over all entries and modify entry if in entry | ||||
| @ -227,31 +201,31 @@ class ShareTransfer(Document): | ||||
| 
 | ||||
| 		for entry in current_entries: | ||||
| 			# use spaceage logic here | ||||
| 			if entry.share_type != share_type or \ | ||||
| 				entry.from_no > query['to_no'] or \ | ||||
| 				entry.to_no < query['from_no']: | ||||
| 			if entry.share_type != self.share_type or \ | ||||
| 				entry.from_no > self.to_no or \ | ||||
| 				entry.to_no < self.from_no: | ||||
| 				new_entries.append(entry) | ||||
| 				continue # since query lies outside bounds | ||||
| 			elif entry.from_no <= query['from_no'] and entry.to_no >= query['to_no']: | ||||
| 			elif entry.from_no <= self.from_no and entry.to_no >= self.to_no: | ||||
| 				#split | ||||
| 				if entry.from_no == query['from_no']: | ||||
| 					if entry.to_no == query['to_no']: | ||||
| 				if entry.from_no == self.from_no: | ||||
| 					if entry.to_no == self.to_no: | ||||
| 						pass #nothing to append | ||||
| 					else: | ||||
| 						new_entries.append(self.return_share_balance_entry(query['to_no']+1, entry.to_no, entry.rate)) | ||||
| 						new_entries.append(self.return_share_balance_entry(self.to_no+1, entry.to_no, entry.rate)) | ||||
| 				else: | ||||
| 					if entry.to_no == query['to_no']: | ||||
| 						new_entries.append(self.return_share_balance_entry(entry.from_no, query['from_no']-1, entry.rate)) | ||||
| 					if entry.to_no == self.to_no: | ||||
| 						new_entries.append(self.return_share_balance_entry(entry.from_no, self.from_no-1, entry.rate)) | ||||
| 					else: | ||||
| 						new_entries.append(self.return_share_balance_entry(entry.from_no, query['from_no']-1, entry.rate)) | ||||
| 						new_entries.append(self.return_share_balance_entry(query['to_no']+1, entry.to_no, entry.rate)) | ||||
| 			elif entry.from_no >= query['from_no'] and entry.to_no <= query['to_no']: | ||||
| 						new_entries.append(self.return_share_balance_entry(entry.from_no, self.from_no-1, entry.rate)) | ||||
| 						new_entries.append(self.return_share_balance_entry(self.to_no+1, entry.to_no, entry.rate)) | ||||
| 			elif entry.from_no >= self.from_no and entry.to_no <= self.to_no: | ||||
| 				# split and check | ||||
| 				pass #nothing to append | ||||
| 			elif query['from_no'] <= entry.from_no <= query['to_no'] and entry.to_no >= query['to_no']: | ||||
| 				new_entries.append(self.return_share_balance_entry(query['to_no']+1, entry.to_no, entry.rate)) | ||||
| 			elif query['from_no'] <= entry.to_no <= query['to_no'] and entry.from_no <= query['from_no']: | ||||
| 				new_entries.append(self.return_share_balance_entry(entry.from_no, query['from_no']-1, entry.rate)) | ||||
| 			elif self.from_no <= entry.from_no <= self.to_no and entry.to_no >= self.to_no: | ||||
| 				new_entries.append(self.return_share_balance_entry(self.to_no+1, entry.to_no, entry.rate)) | ||||
| 			elif self.from_no <= entry.to_no <= self.to_no and entry.from_no <= self.from_no: | ||||
| 				new_entries.append(self.return_share_balance_entry(entry.from_no, self.from_no-1, entry.rate)) | ||||
| 			else: | ||||
| 				new_entries.append(entry) | ||||
| 
 | ||||
| @ -272,16 +246,34 @@ class ShareTransfer(Document): | ||||
| 		} | ||||
| 
 | ||||
| 	def get_shareholder_doc(self, shareholder): | ||||
| 		# Get Shareholder doc based on the Shareholder title | ||||
| 		doc = frappe.get_list('Shareholder', | ||||
| 			filters = [ | ||||
| 				('Shareholder', 'title', '=', shareholder) | ||||
| 			] | ||||
| 		) | ||||
| 		if len(doc) == 1: | ||||
| 			return frappe.get_doc('Shareholder', doc[0]['name']) | ||||
| 		else: #It will necessarily by 0 indicating it doesn't exist | ||||
| 			return False | ||||
| 		# Get Shareholder doc based on the Shareholder name | ||||
| 		if shareholder: | ||||
| 			query_filters = {'name': shareholder} | ||||
| 
 | ||||
| 		name = frappe.db.get_value('Shareholder', {'name': shareholder}, 'name') | ||||
| 
 | ||||
| 		return frappe.get_doc('Shareholder', name) | ||||
| 
 | ||||
| 	def get_company_shareholder(self): | ||||
| 		# Get company doc or create one if not present | ||||
| 		company_shareholder = frappe.db.get_value('Shareholder', | ||||
| 			{ | ||||
| 				'company': self.company, | ||||
| 				'is_company': 1 | ||||
| 			}, 'name') | ||||
| 
 | ||||
| 		if company_shareholder: | ||||
| 			return frappe.get_doc('Shareholder', company_shareholder) | ||||
| 		else: | ||||
| 			shareholder = frappe.get_doc({ | ||||
| 					'doctype': 'Shareholder', | ||||
| 					'title': self.company, | ||||
| 					'company': self.company, | ||||
| 					'is_company': 1 | ||||
| 				}) | ||||
| 			shareholder.insert() | ||||
| 
 | ||||
| 			return shareholder | ||||
| 
 | ||||
| @frappe.whitelist() | ||||
| def make_jv_entry( company, account, amount, payment_account,\ | ||||
|  | ||||
| @ -15,73 +15,73 @@ class TestShareTransfer(unittest.TestCase): | ||||
| 		frappe.db.sql("delete from `tabShare Balance`") | ||||
| 		share_transfers = [ | ||||
| 			{ | ||||
| 				"doctype"					 : "Share Transfer", | ||||
| 				"transfer_type"				 : "Issue", | ||||
| 				"date"						 : "2018-01-01", | ||||
| 				"to_shareholder"			 : "SH-00001", | ||||
| 				"share_type"				 : "Equity", | ||||
| 				"from_no"					 : 1, | ||||
| 				"to_no"						 : 500, | ||||
| 				"no_of_shares"				 : 500, | ||||
| 				"rate"						 : 10, | ||||
| 				"company"					 : "_Test Company", | ||||
| 				"asset_account"				 : "Cash - _TC", | ||||
| 				"doctype": "Share Transfer", | ||||
| 				"transfer_type": "Issue", | ||||
| 				"date": "2018-01-01", | ||||
| 				"to_shareholder": "SH-00001", | ||||
| 				"share_type": "Equity", | ||||
| 				"from_no": 1, | ||||
| 				"to_no": 500, | ||||
| 				"no_of_shares": 500, | ||||
| 				"rate": 10, | ||||
| 				"company": "_Test Company", | ||||
| 				"asset_account": "Cash - _TC", | ||||
| 				"equity_or_liability_account": "Creditors - _TC" | ||||
| 			}, | ||||
| 			{ | ||||
| 				"doctype"					 : "Share Transfer", | ||||
| 				"transfer_type"				 : "Transfer", | ||||
| 				"date"						 : "2018-01-02", | ||||
| 				"from_shareholder"			 : "SH-00001", | ||||
| 				"to_shareholder"			 : "SH-00002", | ||||
| 				"share_type"				 : "Equity", | ||||
| 				"from_no"					 : 101, | ||||
| 				"to_no"						 : 200, | ||||
| 				"no_of_shares"				 : 100, | ||||
| 				"rate"						 : 15, | ||||
| 				"company"					 : "_Test Company", | ||||
| 				"doctype": "Share Transfer", | ||||
| 				"transfer_type": "Transfer", | ||||
| 				"date": "2018-01-02", | ||||
| 				"from_shareholder": "SH-00001", | ||||
| 				"to_shareholder": "SH-00002", | ||||
| 				"share_type": "Equity", | ||||
| 				"from_no": 101, | ||||
| 				"to_no": 200, | ||||
| 				"no_of_shares": 100, | ||||
| 				"rate": 15, | ||||
| 				"company": "_Test Company", | ||||
| 				"equity_or_liability_account": "Creditors - _TC" | ||||
| 			}, | ||||
| 			{ | ||||
| 				"doctype"					 : "Share Transfer", | ||||
| 				"transfer_type"				 : "Transfer", | ||||
| 				"date"						 : "2018-01-03", | ||||
| 				"from_shareholder"			 : "SH-00001", | ||||
| 				"to_shareholder"			 : "SH-00003", | ||||
| 				"share_type"				 : "Equity", | ||||
| 				"from_no"					 : 201, | ||||
| 				"to_no"						 : 500, | ||||
| 				"no_of_shares"				 : 300, | ||||
| 				"rate"						 : 20, | ||||
| 				"company"					 : "_Test Company", | ||||
| 				"doctype": "Share Transfer", | ||||
| 				"transfer_type": "Transfer", | ||||
| 				"date": "2018-01-03", | ||||
| 				"from_shareholder": "SH-00001", | ||||
| 				"to_shareholder": "SH-00003", | ||||
| 				"share_type": "Equity", | ||||
| 				"from_no": 201, | ||||
| 				"to_no": 500, | ||||
| 				"no_of_shares": 300, | ||||
| 				"rate": 20, | ||||
| 				"company": "_Test Company", | ||||
| 				"equity_or_liability_account": "Creditors - _TC" | ||||
| 			}, | ||||
| 			{ | ||||
| 				"doctype"					 : "Share Transfer", | ||||
| 				"transfer_type"				 : "Transfer", | ||||
| 				"date"						 : "2018-01-04", | ||||
| 				"from_shareholder"			 : "SH-00003", | ||||
| 				"to_shareholder"			 : "SH-00002", | ||||
| 				"share_type"				 : "Equity", | ||||
| 				"from_no"					 : 201, | ||||
| 				"to_no"						 : 400, | ||||
| 				"no_of_shares"				 : 200, | ||||
| 				"rate"						 : 15, | ||||
| 				"company"					 : "_Test Company", | ||||
| 				"doctype": "Share Transfer", | ||||
| 				"transfer_type": "Transfer", | ||||
| 				"date": "2018-01-04", | ||||
| 				"from_shareholder": "SH-00003", | ||||
| 				"to_shareholder": "SH-00002", | ||||
| 				"share_type": "Equity", | ||||
| 				"from_no": 201, | ||||
| 				"to_no": 400, | ||||
| 				"no_of_shares": 200, | ||||
| 				"rate": 15, | ||||
| 				"company": "_Test Company", | ||||
| 				"equity_or_liability_account": "Creditors - _TC" | ||||
| 			}, | ||||
| 			{ | ||||
| 				"doctype"					 : "Share Transfer", | ||||
| 				"transfer_type"				 : "Purchase", | ||||
| 				"date"						 : "2018-01-05", | ||||
| 				"from_shareholder"			 : "SH-00003", | ||||
| 				"share_type"				 : "Equity", | ||||
| 				"from_no"					 : 401, | ||||
| 				"to_no"						 : 500, | ||||
| 				"no_of_shares"				 : 100, | ||||
| 				"rate"						 : 25, | ||||
| 				"company"					 : "_Test Company", | ||||
| 				"asset_account"				 : "Cash - _TC", | ||||
| 				"doctype": "Share Transfer", | ||||
| 				"transfer_type": "Purchase", | ||||
| 				"date": "2018-01-05", | ||||
| 				"from_shareholder": "SH-00003", | ||||
| 				"share_type": "Equity", | ||||
| 				"from_no": 401, | ||||
| 				"to_no": 500, | ||||
| 				"no_of_shares": 100, | ||||
| 				"rate": 25, | ||||
| 				"company": "_Test Company", | ||||
| 				"asset_account": "Cash - _TC", | ||||
| 				"equity_or_liability_account": "Creditors - _TC" | ||||
| 			} | ||||
| 		] | ||||
| @ -91,33 +91,33 @@ class TestShareTransfer(unittest.TestCase): | ||||
| 
 | ||||
| 	def test_invalid_share_transfer(self): | ||||
| 		doc = frappe.get_doc({ | ||||
| 			"doctype"					 : "Share Transfer", | ||||
| 			"transfer_type"				 : "Transfer", | ||||
| 			"date"						 : "2018-01-05", | ||||
| 			"from_shareholder"			 : "SH-00003", | ||||
| 			"to_shareholder"			 : "SH-00002", | ||||
| 			"share_type"				 : "Equity", | ||||
| 			"from_no"					 : 1, | ||||
| 			"to_no"						 : 100, | ||||
| 			"no_of_shares"				 : 100, | ||||
| 			"rate"						 : 15, | ||||
| 			"company"					 : "_Test Company", | ||||
| 			"doctype": "Share Transfer", | ||||
| 			"transfer_type": "Transfer", | ||||
| 			"date": "2018-01-05", | ||||
| 			"from_shareholder": "SH-00003", | ||||
| 			"to_shareholder": "SH-00002", | ||||
| 			"share_type": "Equity", | ||||
| 			"from_no": 1, | ||||
| 			"to_no": 100, | ||||
| 			"no_of_shares": 100, | ||||
| 			"rate": 15, | ||||
| 			"company": "_Test Company", | ||||
| 			"equity_or_liability_account": "Creditors - _TC" | ||||
| 		}) | ||||
| 		self.assertRaises(ShareDontExists, doc.insert) | ||||
| 
 | ||||
| 		doc = frappe.get_doc({ | ||||
| 			"doctype"					 : "Share Transfer", | ||||
| 			"transfer_type"				 : "Purchase", | ||||
| 			"date"						 : "2018-01-02", | ||||
| 			"from_shareholder"			 : "SH-00001", | ||||
| 			"share_type"				 : "Equity", | ||||
| 			"from_no"					 : 1, | ||||
| 			"to_no"						 : 200, | ||||
| 			"no_of_shares"				 : 200, | ||||
| 			"rate"						 : 15, | ||||
| 			"company"					 : "_Test Company", | ||||
| 			"asset_account"				 : "Cash - _TC", | ||||
| 			"doctype": "Share Transfer", | ||||
| 			"transfer_type": "Purchase", | ||||
| 			"date": "2018-01-02", | ||||
| 			"from_shareholder": "SH-00001", | ||||
| 			"share_type": "Equity", | ||||
| 			"from_no": 1, | ||||
| 			"to_no": 200, | ||||
| 			"no_of_shares": 200, | ||||
| 			"rate": 15, | ||||
| 			"company": "_Test Company", | ||||
| 			"asset_account": "Cash - _TC", | ||||
| 			"equity_or_liability_account": "Creditors - _TC" | ||||
| 		}) | ||||
| 		self.assertRaises(ShareDontExists, doc.insert) | ||||
|  | ||||
| @ -1,587 +1,163 @@ | ||||
| { | ||||
|  "allow_copy": 0,  | ||||
|  "allow_guest_to_view": 0,  | ||||
|  "allow_import": 0,  | ||||
|  "allow_rename": 0,  | ||||
|  "autoname": "naming_series:",  | ||||
|  "beta": 0,  | ||||
|  "creation": "2017-12-25 16:50:53.878430",  | ||||
|  "custom": 0,  | ||||
|  "description": "",  | ||||
|  "docstatus": 0,  | ||||
|  "doctype": "DocType",  | ||||
|  "document_type": "",  | ||||
|  "editable_grid": 1,  | ||||
|  "engine": "InnoDB",  | ||||
|  "autoname": "naming_series:", | ||||
|  "creation": "2017-12-25 16:50:53.878430", | ||||
|  "doctype": "DocType", | ||||
|  "editable_grid": 1, | ||||
|  "engine": "InnoDB", | ||||
|  "field_order": [ | ||||
|   "title", | ||||
|   "column_break_2", | ||||
|   "naming_series", | ||||
|   "section_break_2", | ||||
|   "folio_no", | ||||
|   "column_break_4", | ||||
|   "company", | ||||
|   "is_company", | ||||
|   "address_contacts", | ||||
|   "address_html", | ||||
|   "column_break_9", | ||||
|   "contact_html", | ||||
|   "section_break_3", | ||||
|   "share_balance", | ||||
|   "contact_list" | ||||
|  ], | ||||
|  "fields": [ | ||||
|   { | ||||
|    "allow_bulk_edit": 0,  | ||||
|    "allow_in_quick_entry": 0,  | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
|    "collapsible": 0,  | ||||
|    "columns": 0,  | ||||
|    "fieldname": "title",  | ||||
|    "fieldtype": "Data",  | ||||
|    "hidden": 0,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_global_search": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "in_standard_filter": 0,  | ||||
|    "label": "Title",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 0,  | ||||
|    "remember_last_selected_value": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "translatable": 0,  | ||||
|    "unique": 0 | ||||
|   },  | ||||
|    "fieldname": "title", | ||||
|    "fieldtype": "Data", | ||||
|    "label": "Title", | ||||
|    "reqd": 1 | ||||
|   }, | ||||
|   { | ||||
|    "allow_bulk_edit": 0,  | ||||
|    "allow_in_quick_entry": 0,  | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
|    "collapsible": 0,  | ||||
|    "columns": 0,  | ||||
|    "fieldname": "column_break_2",  | ||||
|    "fieldtype": "Column Break",  | ||||
|    "hidden": 0,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_global_search": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "in_standard_filter": 0,  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 0,  | ||||
|    "remember_last_selected_value": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "translatable": 0,  | ||||
|    "unique": 0 | ||||
|   },  | ||||
|    "fieldname": "column_break_2", | ||||
|    "fieldtype": "Column Break" | ||||
|   }, | ||||
|   { | ||||
|    "allow_bulk_edit": 0,  | ||||
|    "allow_in_quick_entry": 0,  | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
|    "collapsible": 0,  | ||||
|    "columns": 0,  | ||||
|    "default": "",  | ||||
|    "fieldname": "naming_series",  | ||||
|    "fieldtype": "Select",  | ||||
|    "hidden": 0,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_global_search": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "in_standard_filter": 0,  | ||||
|    "label": "",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "options": "ACC-SH-.YYYY.-",  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 0,  | ||||
|    "remember_last_selected_value": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "translatable": 0,  | ||||
|    "unique": 0 | ||||
|   },  | ||||
|    "fieldname": "naming_series", | ||||
|    "fieldtype": "Select", | ||||
|    "options": "ACC-SH-.YYYY.-" | ||||
|   }, | ||||
|   { | ||||
|    "allow_bulk_edit": 0,  | ||||
|    "allow_in_quick_entry": 0,  | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
|    "collapsible": 0,  | ||||
|    "columns": 0,  | ||||
|    "fieldname": "section_break_2",  | ||||
|    "fieldtype": "Section Break",  | ||||
|    "hidden": 0,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_global_search": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "in_standard_filter": 0,  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 0,  | ||||
|    "remember_last_selected_value": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "translatable": 0,  | ||||
|    "unique": 0 | ||||
|   },  | ||||
|    "fieldname": "section_break_2", | ||||
|    "fieldtype": "Section Break" | ||||
|   }, | ||||
|   { | ||||
|    "allow_bulk_edit": 0,  | ||||
|    "allow_in_quick_entry": 0,  | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
|    "collapsible": 0,  | ||||
|    "columns": 0,  | ||||
|    "fieldname": "folio_no",  | ||||
|    "fieldtype": "Data",  | ||||
|    "hidden": 0,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_global_search": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "in_standard_filter": 0,  | ||||
|    "label": "Folio no.",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 1,  | ||||
|    "remember_last_selected_value": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "translatable": 0,  | ||||
|    "fieldname": "folio_no", | ||||
|    "fieldtype": "Data", | ||||
|    "label": "Folio no.", | ||||
|    "read_only": 1, | ||||
|    "unique": 1 | ||||
|   },  | ||||
|   }, | ||||
|   { | ||||
|    "allow_bulk_edit": 0,  | ||||
|    "allow_in_quick_entry": 0,  | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
|    "collapsible": 0,  | ||||
|    "columns": 0,  | ||||
|    "fieldname": "column_break_4",  | ||||
|    "fieldtype": "Column Break",  | ||||
|    "hidden": 0,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_global_search": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "in_standard_filter": 0,  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 0,  | ||||
|    "remember_last_selected_value": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "translatable": 0,  | ||||
|    "unique": 0 | ||||
|   },  | ||||
|    "fieldname": "column_break_4", | ||||
|    "fieldtype": "Column Break" | ||||
|   }, | ||||
|   { | ||||
|    "allow_bulk_edit": 0,  | ||||
|    "allow_in_quick_entry": 0,  | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
|    "collapsible": 0,  | ||||
|    "columns": 0,  | ||||
|    "fieldname": "company",  | ||||
|    "fieldtype": "Link",  | ||||
|    "hidden": 0,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_global_search": 0,  | ||||
|    "in_list_view": 1,  | ||||
|    "in_standard_filter": 0,  | ||||
|    "label": "Company",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "options": "Company",  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 0,  | ||||
|    "remember_last_selected_value": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 1,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "translatable": 0,  | ||||
|    "unique": 0 | ||||
|   },  | ||||
|    "fieldname": "company", | ||||
|    "fieldtype": "Link", | ||||
|    "in_list_view": 1, | ||||
|    "label": "Company", | ||||
|    "options": "Company", | ||||
|    "reqd": 1 | ||||
|   }, | ||||
|   { | ||||
|    "allow_bulk_edit": 0,  | ||||
|    "allow_in_quick_entry": 0,  | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
|    "collapsible": 0,  | ||||
|    "columns": 0,  | ||||
|    "fieldname": "is_company",  | ||||
|    "fieldtype": "Check",  | ||||
|    "hidden": 1,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_global_search": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "in_standard_filter": 0,  | ||||
|    "label": "Is Company",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 1,  | ||||
|    "remember_last_selected_value": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "translatable": 0,  | ||||
|    "unique": 0 | ||||
|   },  | ||||
|    "default": "0", | ||||
|    "fieldname": "is_company", | ||||
|    "fieldtype": "Check", | ||||
|    "hidden": 1, | ||||
|    "label": "Is Company", | ||||
|    "read_only": 1 | ||||
|   }, | ||||
|   { | ||||
|    "allow_bulk_edit": 0,  | ||||
|    "allow_in_quick_entry": 0,  | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
|    "collapsible": 0,  | ||||
|    "columns": 0,  | ||||
|    "fieldname": "address_contacts",  | ||||
|    "fieldtype": "Section Break",  | ||||
|    "hidden": 0,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_global_search": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "in_standard_filter": 0,  | ||||
|    "label": "Address and Contacts",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "options": "fa fa-map-marker",  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 0,  | ||||
|    "remember_last_selected_value": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "translatable": 0,  | ||||
|    "unique": 0 | ||||
|   },  | ||||
|    "fieldname": "address_contacts", | ||||
|    "fieldtype": "Section Break", | ||||
|    "label": "Address and Contacts", | ||||
|    "options": "fa fa-map-marker" | ||||
|   }, | ||||
|   { | ||||
|    "allow_bulk_edit": 0,  | ||||
|    "allow_in_quick_entry": 0,  | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
|    "collapsible": 0,  | ||||
|    "columns": 0,  | ||||
|    "fieldname": "address_html",  | ||||
|    "fieldtype": "HTML",  | ||||
|    "hidden": 0,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_global_search": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "in_standard_filter": 0,  | ||||
|    "label": "Address HTML",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 1,  | ||||
|    "remember_last_selected_value": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "translatable": 0,  | ||||
|    "unique": 0 | ||||
|   },  | ||||
|    "fieldname": "address_html", | ||||
|    "fieldtype": "HTML", | ||||
|    "label": "Address HTML", | ||||
|    "read_only": 1 | ||||
|   }, | ||||
|   { | ||||
|    "allow_bulk_edit": 0,  | ||||
|    "allow_in_quick_entry": 0,  | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
|    "collapsible": 0,  | ||||
|    "columns": 0,  | ||||
|    "fieldname": "column_break_9",  | ||||
|    "fieldtype": "Column Break",  | ||||
|    "hidden": 0,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_global_search": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "in_standard_filter": 0,  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 0,  | ||||
|    "remember_last_selected_value": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "translatable": 0,  | ||||
|    "unique": 0 | ||||
|   },  | ||||
|    "fieldname": "column_break_9", | ||||
|    "fieldtype": "Column Break" | ||||
|   }, | ||||
|   { | ||||
|    "allow_bulk_edit": 0,  | ||||
|    "allow_in_quick_entry": 0,  | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
|    "collapsible": 0,  | ||||
|    "columns": 0,  | ||||
|    "fieldname": "contact_html",  | ||||
|    "fieldtype": "HTML",  | ||||
|    "hidden": 0,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_global_search": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "in_standard_filter": 0,  | ||||
|    "label": "Contact HTML",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "options": "",  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 1,  | ||||
|    "remember_last_selected_value": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "translatable": 0,  | ||||
|    "unique": 0 | ||||
|   },  | ||||
|    "fieldname": "contact_html", | ||||
|    "fieldtype": "HTML", | ||||
|    "label": "Contact HTML", | ||||
|    "read_only": 1 | ||||
|   }, | ||||
|   { | ||||
|    "allow_bulk_edit": 0,  | ||||
|    "allow_in_quick_entry": 0,  | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
|    "collapsible": 0,  | ||||
|    "columns": 0,  | ||||
|    "fieldname": "section_break_3",  | ||||
|    "fieldtype": "Section Break",  | ||||
|    "hidden": 0,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_global_search": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "in_standard_filter": 0,  | ||||
|    "label": "Share Balance",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 0,  | ||||
|    "remember_last_selected_value": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "translatable": 0,  | ||||
|    "unique": 0 | ||||
|   },  | ||||
|    "fieldname": "section_break_3", | ||||
|    "fieldtype": "Section Break", | ||||
|    "label": "Share Balance" | ||||
|   }, | ||||
|   { | ||||
|    "allow_bulk_edit": 0,  | ||||
|    "allow_in_quick_entry": 0,  | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
|    "collapsible": 0,  | ||||
|    "columns": 0,  | ||||
|    "fieldname": "share_balance",  | ||||
|    "fieldtype": "Table",  | ||||
|    "hidden": 0,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_global_search": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "in_standard_filter": 0,  | ||||
|    "label": "Share Balance",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "options": "Share Balance",  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 1,  | ||||
|    "remember_last_selected_value": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "translatable": 0,  | ||||
|    "unique": 0 | ||||
|   },  | ||||
|    "fieldname": "share_balance", | ||||
|    "fieldtype": "Table", | ||||
|    "label": "Share Balance", | ||||
|    "options": "Share Balance", | ||||
|    "read_only": 1 | ||||
|   }, | ||||
|   { | ||||
|    "allow_bulk_edit": 0,  | ||||
|    "allow_in_quick_entry": 0,  | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
|    "collapsible": 0,  | ||||
|    "columns": 0,  | ||||
|    "description": "Hidden list maintaining the list of contacts linked to Shareholder",  | ||||
|    "fieldname": "contact_list",  | ||||
|    "fieldtype": "Code",  | ||||
|    "hidden": 1,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_global_search": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "in_standard_filter": 0,  | ||||
|    "label": "Contact List",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 1,  | ||||
|    "remember_last_selected_value": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "translatable": 0,  | ||||
|    "unique": 0 | ||||
|    "description": "Hidden list maintaining the list of contacts linked to Shareholder", | ||||
|    "fieldname": "contact_list", | ||||
|    "fieldtype": "Code", | ||||
|    "hidden": 1, | ||||
|    "label": "Contact List", | ||||
|    "read_only": 1 | ||||
|   } | ||||
|  ],  | ||||
|  "has_web_view": 0,  | ||||
|  "hide_heading": 0,  | ||||
|  "hide_toolbar": 0,  | ||||
|  "idx": 0,  | ||||
|  "image_view": 0,  | ||||
|  "in_create": 0,  | ||||
|  "is_submittable": 0,  | ||||
|  "issingle": 0,  | ||||
|  "istable": 0,  | ||||
|  "max_attachments": 0,  | ||||
|  "modified": "2018-09-18 14:14:24.953014",  | ||||
|  "modified_by": "Administrator",  | ||||
|  "module": "Accounts",  | ||||
|  "name": "Shareholder",  | ||||
|  "name_case": "Title Case",  | ||||
|  "owner": "Administrator",  | ||||
|  ], | ||||
|  "modified": "2019-11-17 23:24:11.395882", | ||||
|  "modified_by": "Administrator", | ||||
|  "module": "Accounts", | ||||
|  "name": "Shareholder", | ||||
|  "name_case": "Title Case", | ||||
|  "owner": "Administrator", | ||||
|  "permissions": [ | ||||
|   { | ||||
|    "amend": 0,  | ||||
|    "cancel": 0,  | ||||
|    "create": 1,  | ||||
|    "delete": 1,  | ||||
|    "email": 1,  | ||||
|    "export": 1,  | ||||
|    "if_owner": 0,  | ||||
|    "import": 0,  | ||||
|    "permlevel": 0,  | ||||
|    "print": 1,  | ||||
|    "read": 1,  | ||||
|    "report": 1,  | ||||
|    "role": "System Manager",  | ||||
|    "set_user_permissions": 0,  | ||||
|    "share": 1,  | ||||
|    "submit": 0,  | ||||
|    "create": 1, | ||||
|    "delete": 1, | ||||
|    "email": 1, | ||||
|    "export": 1, | ||||
|    "print": 1, | ||||
|    "read": 1, | ||||
|    "report": 1, | ||||
|    "role": "System Manager", | ||||
|    "share": 1, | ||||
|    "write": 1 | ||||
|   },  | ||||
|   }, | ||||
|   { | ||||
|    "amend": 0,  | ||||
|    "cancel": 0,  | ||||
|    "create": 1,  | ||||
|    "delete": 1,  | ||||
|    "email": 1,  | ||||
|    "export": 1,  | ||||
|    "if_owner": 0,  | ||||
|    "import": 0,  | ||||
|    "permlevel": 0,  | ||||
|    "print": 1,  | ||||
|    "read": 1,  | ||||
|    "report": 1,  | ||||
|    "role": "Accounts Manager",  | ||||
|    "set_user_permissions": 0,  | ||||
|    "share": 1,  | ||||
|    "submit": 0,  | ||||
|    "create": 1, | ||||
|    "delete": 1, | ||||
|    "email": 1, | ||||
|    "export": 1, | ||||
|    "print": 1, | ||||
|    "read": 1, | ||||
|    "report": 1, | ||||
|    "role": "Accounts Manager", | ||||
|    "share": 1, | ||||
|    "write": 1 | ||||
|   },  | ||||
|   }, | ||||
|   { | ||||
|    "amend": 0,  | ||||
|    "cancel": 0,  | ||||
|    "create": 1,  | ||||
|    "delete": 1,  | ||||
|    "email": 1,  | ||||
|    "export": 1,  | ||||
|    "if_owner": 0,  | ||||
|    "import": 0,  | ||||
|    "permlevel": 0,  | ||||
|    "print": 1,  | ||||
|    "read": 1,  | ||||
|    "report": 1,  | ||||
|    "role": "Accounts User",  | ||||
|    "set_user_permissions": 0,  | ||||
|    "share": 1,  | ||||
|    "submit": 0,  | ||||
|    "create": 1, | ||||
|    "delete": 1, | ||||
|    "email": 1, | ||||
|    "export": 1, | ||||
|    "print": 1, | ||||
|    "read": 1, | ||||
|    "report": 1, | ||||
|    "role": "Accounts User", | ||||
|    "share": 1, | ||||
|    "write": 1 | ||||
|   } | ||||
|  ],  | ||||
|  "quick_entry": 0,  | ||||
|  "read_only": 0,  | ||||
|  "read_only_onload": 0,  | ||||
|  "search_fields": "folio_no",  | ||||
|  "show_name_in_global_search": 0,  | ||||
|  "sort_field": "modified",  | ||||
|  "sort_order": "DESC",  | ||||
|  "title_field": "title",  | ||||
|  "track_changes": 1,  | ||||
|  "track_seen": 0,  | ||||
|  "track_views": 0 | ||||
|  ], | ||||
|  "search_fields": "folio_no", | ||||
|  "sort_field": "modified", | ||||
|  "sort_order": "DESC", | ||||
|  "title_field": "title", | ||||
|  "track_changes": 1 | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user