refactor: Share transfer cancellation and code cleanup

This commit is contained in:
deepeshgarg007 2019-11-18 17:52:19 +05:30
parent 57bd1308eb
commit 9c1c4ef3dd
2 changed files with 247 additions and 681 deletions

View File

@ -13,9 +13,9 @@ from frappe.utils import nowdate
class ShareDontExists(ValidationError): pass class ShareDontExists(ValidationError): pass
class ShareTransfer(Document): class ShareTransfer(Document):
def before_submit(self): def on_submit(self):
if self.transfer_type == 'Issue': if self.transfer_type == 'Issue':
shareholder = self.get_shareholder_doc(self.company) shareholder = self.get_company_shareholder()
shareholder.append('share_balance', { shareholder.append('share_balance', {
'share_type': self.share_type, 'share_type': self.share_type,
'from_no': self.from_no, 'from_no': self.from_no,
@ -28,7 +28,7 @@ class ShareTransfer(Document):
}) })
shareholder.save() shareholder.save()
doc = frappe.get_doc('Shareholder', self.to_shareholder) doc = self.get_shareholder_doc(self.to_shareholder)
doc.append('share_balance', { doc.append('share_balance', {
'share_type': self.share_type, 'share_type': self.share_type,
'from_no': self.from_no, 'from_no': self.from_no,
@ -41,11 +41,11 @@ class ShareTransfer(Document):
elif self.transfer_type == 'Purchase': elif self.transfer_type == 'Purchase':
self.remove_shares(self.from_shareholder) 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': elif self.transfer_type == 'Transfer':
self.remove_shares(self.from_shareholder) 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', { doc.append('share_balance', {
'share_type': self.share_type, 'share_type': self.share_type,
'from_no': self.from_no, 'from_no': self.from_no,
@ -56,26 +56,65 @@ class ShareTransfer(Document):
}) })
doc.save() 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): def validate(self):
self.get_company_shareholder()
self.basic_validations() self.basic_validations()
self.folio_no_validation() self.folio_no_validation()
if self.transfer_type == 'Issue': if self.transfer_type == 'Issue':
if not self.get_shareholder_doc(self.company): # validate share doesn't exist in company
shareholder = frappe.get_doc({ ret_val = self.share_exists(self.get_company_shareholder().name)
'doctype': 'Shareholder', if ret_val:
'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:
frappe.throw(_('The shares already exist'), frappe.DuplicateEntryError) frappe.throw(_('The shares already exist'), frappe.DuplicateEntryError)
else: else:
# validate share exists with from_shareholder # validate share exists with from_shareholder
ret_val = self.share_exists(self.from_shareholder) ret_val = self.share_exists(self.from_shareholder)
if ret_val != True: if not ret_val:
frappe.throw(_("The shares don't exist with the {0}") frappe.throw(_("The shares don't exist with the {0}")
.format(self.from_shareholder), ShareDontExists) .format(self.from_shareholder), ShareDontExists)
@ -113,81 +152,24 @@ class ShareTransfer(Document):
frappe.throw(_('There are inconsistencies between the rate, no of shares and the amount calculated')) frappe.throw(_('There are inconsistencies between the rate, no of shares and the amount calculated'))
def share_exists(self, shareholder): def share_exists(self, shareholder):
# return True if exits, doc = self.get_shareholder_doc(shareholder)
# 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)
for entry in doc.share_balance: for entry in doc.share_balance:
if entry.share_type != share_type or \ if entry.share_type != self.share_type or \
entry.from_no > query['to_no'] or \ entry.from_no > self.to_no or \
entry.to_no < query['from_no']: entry.to_no < self.from_no:
continue # since query lies outside bounds 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: #both inside
return [True] # absolute truth! return True # absolute truth!
elif entry.from_no >= query['from_no'] and entry.to_no <= query['to_no']: elif (entry.from_no <= self.from_no <= self.to_no) or entry.from_no <= self.to_no and entry.to_no:
# split and check return True
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']
}
))
does_share_exist.append(False) return False
return does_share_exist
def folio_no_validation(self): def folio_no_validation(self):
shareholders = ['from_shareholder', 'to_shareholder'] shareholders = ['from_shareholder', 'to_shareholder']
shareholders = [shareholder for shareholder in shareholders if self.get(shareholder) is not ''] shareholders = [shareholder for shareholder in shareholders if self.get(shareholder) is not '']
for shareholder in shareholders: 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: if doc.company != self.company:
frappe.throw(_('The shareholder does not belong to this company')) frappe.throw(_('The shareholder does not belong to this company'))
if not doc.folio_no: if not doc.folio_no:
@ -200,24 +182,14 @@ class ShareTransfer(Document):
def autoname_folio(self, shareholder, is_company=False): def autoname_folio(self, shareholder, is_company=False):
if is_company: if is_company:
doc = self.get_shareholder_doc(shareholder) doc = self.get_company_shareholder()
else: else:
doc = frappe.get_doc('Shareholder' , shareholder) doc = self.get_shareholder_doc(shareholder)
doc.folio_no = make_autoname('FN.#####') doc.folio_no = make_autoname('FN.#####')
doc.save() doc.save()
return doc.folio_no return doc.folio_no
def remove_shares(self, shareholder): 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} # query = {'from_no': share_starting_no, 'to_no': share_ending_no}
# Shares exist for sure # Shares exist for sure
# Iterate over all entries and modify entry if in entry # Iterate over all entries and modify entry if in entry
@ -227,31 +199,31 @@ class ShareTransfer(Document):
for entry in current_entries: for entry in current_entries:
# use spaceage logic here # use spaceage logic here
if entry.share_type != share_type or \ if entry.share_type != self.share_type or \
entry.from_no > query['to_no'] or \ entry.from_no > self.to_no or \
entry.to_no < query['from_no']: entry.to_no < self.from_no:
new_entries.append(entry) new_entries.append(entry)
continue # since query lies outside bounds 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 #split
if entry.from_no == query['from_no']: if entry.from_no == self.from_no:
if entry.to_no == query['to_no']: if entry.to_no == self.to_no:
pass #nothing to append pass #nothing to append
else: 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: else:
if entry.to_no == query['to_no']: if entry.to_no == self.to_no:
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(entry.from_no, self.from_no-1, entry.rate))
else: 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(entry.from_no, self.from_no-1, entry.rate))
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))
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 and check # split and check
pass #nothing to append pass #nothing to append
elif query['from_no'] <= entry.from_no <= query['to_no'] and entry.to_no >= query['to_no']: 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(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))
elif query['from_no'] <= entry.to_no <= query['to_no'] and entry.from_no <= query['from_no']: 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, query['from_no']-1, entry.rate)) new_entries.append(self.return_share_balance_entry(entry.from_no, self.from_no-1, entry.rate))
else: else:
new_entries.append(entry) new_entries.append(entry)
@ -272,16 +244,34 @@ class ShareTransfer(Document):
} }
def get_shareholder_doc(self, shareholder): def get_shareholder_doc(self, shareholder):
# Get Shareholder doc based on the Shareholder title # Get Shareholder doc based on the Shareholder name
doc = frappe.get_list('Shareholder', if shareholder:
filters = [ query_filters = {'name': shareholder}
('Shareholder', 'title', '=', shareholder)
] name = frappe.db.get_value('Shareholder', {'name': shareholder}, 'name')
)
if len(doc) == 1: return frappe.get_doc('Shareholder', name)
return frappe.get_doc('Shareholder', doc[0]['name'])
else: #It will necessarily by 0 indicating it doesn't exist def get_company_shareholder(self):
return False # 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() @frappe.whitelist()
def make_jv_entry( company, account, amount, payment_account,\ def make_jv_entry( company, account, amount, payment_account,\

View File

@ -1,587 +1,163 @@
{ {
"allow_copy": 0, "autoname": "naming_series:",
"allow_guest_to_view": 0, "creation": "2017-12-25 16:50:53.878430",
"allow_import": 0, "doctype": "DocType",
"allow_rename": 0, "editable_grid": 1,
"autoname": "naming_series:", "engine": "InnoDB",
"beta": 0, "field_order": [
"creation": "2017-12-25 16:50:53.878430", "title",
"custom": 0, "column_break_2",
"description": "", "naming_series",
"docstatus": 0, "section_break_2",
"doctype": "DocType", "folio_no",
"document_type": "", "column_break_4",
"editable_grid": 1, "company",
"engine": "InnoDB", "is_company",
"address_contacts",
"address_html",
"column_break_9",
"contact_html",
"section_break_3",
"share_balance",
"contact_list"
],
"fields": [ "fields": [
{ {
"allow_bulk_edit": 0, "fieldname": "title",
"allow_in_quick_entry": 0, "fieldtype": "Data",
"allow_on_submit": 0, "label": "Title",
"bold": 0, "reqd": 1
"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
},
{ {
"allow_bulk_edit": 0, "fieldname": "column_break_2",
"allow_in_quick_entry": 0, "fieldtype": "Column Break"
"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
},
{ {
"allow_bulk_edit": 0, "fieldname": "naming_series",
"allow_in_quick_entry": 0, "fieldtype": "Select",
"allow_on_submit": 0, "options": "ACC-SH-.YYYY.-"
"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
},
{ {
"allow_bulk_edit": 0, "fieldname": "section_break_2",
"allow_in_quick_entry": 0, "fieldtype": "Section Break"
"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
},
{ {
"allow_bulk_edit": 0, "fieldname": "folio_no",
"allow_in_quick_entry": 0, "fieldtype": "Data",
"allow_on_submit": 0, "label": "Folio no.",
"bold": 0, "read_only": 1,
"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,
"unique": 1 "unique": 1
}, },
{ {
"allow_bulk_edit": 0, "fieldname": "column_break_4",
"allow_in_quick_entry": 0, "fieldtype": "Column Break"
"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
},
{ {
"allow_bulk_edit": 0, "fieldname": "company",
"allow_in_quick_entry": 0, "fieldtype": "Link",
"allow_on_submit": 0, "in_list_view": 1,
"bold": 0, "label": "Company",
"collapsible": 0, "options": "Company",
"columns": 0, "reqd": 1
"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
},
{ {
"allow_bulk_edit": 0, "default": "0",
"allow_in_quick_entry": 0, "fieldname": "is_company",
"allow_on_submit": 0, "fieldtype": "Check",
"bold": 0, "hidden": 1,
"collapsible": 0, "label": "Is Company",
"columns": 0, "read_only": 1
"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
},
{ {
"allow_bulk_edit": 0, "fieldname": "address_contacts",
"allow_in_quick_entry": 0, "fieldtype": "Section Break",
"allow_on_submit": 0, "label": "Address and Contacts",
"bold": 0, "options": "fa fa-map-marker"
"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
},
{ {
"allow_bulk_edit": 0, "fieldname": "address_html",
"allow_in_quick_entry": 0, "fieldtype": "HTML",
"allow_on_submit": 0, "label": "Address HTML",
"bold": 0, "read_only": 1
"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
},
{ {
"allow_bulk_edit": 0, "fieldname": "column_break_9",
"allow_in_quick_entry": 0, "fieldtype": "Column Break"
"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
},
{ {
"allow_bulk_edit": 0, "fieldname": "contact_html",
"allow_in_quick_entry": 0, "fieldtype": "HTML",
"allow_on_submit": 0, "label": "Contact HTML",
"bold": 0, "read_only": 1
"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
},
{ {
"allow_bulk_edit": 0, "fieldname": "section_break_3",
"allow_in_quick_entry": 0, "fieldtype": "Section Break",
"allow_on_submit": 0, "label": "Share Balance"
"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
},
{ {
"allow_bulk_edit": 0, "fieldname": "share_balance",
"allow_in_quick_entry": 0, "fieldtype": "Table",
"allow_on_submit": 0, "label": "Share Balance",
"bold": 0, "options": "Share Balance",
"collapsible": 0, "read_only": 1
"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
},
{ {
"allow_bulk_edit": 0, "description": "Hidden list maintaining the list of contacts linked to Shareholder",
"allow_in_quick_entry": 0, "fieldname": "contact_list",
"allow_on_submit": 0, "fieldtype": "Code",
"bold": 0, "hidden": 1,
"collapsible": 0, "label": "Contact List",
"columns": 0, "read_only": 1
"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
} }
], ],
"has_web_view": 0, "modified": "2019-11-17 23:24:11.395882",
"hide_heading": 0, "modified_by": "Administrator",
"hide_toolbar": 0, "module": "Accounts",
"idx": 0, "name": "Shareholder",
"image_view": 0, "name_case": "Title Case",
"in_create": 0, "owner": "Administrator",
"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",
"permissions": [ "permissions": [
{ {
"amend": 0, "create": 1,
"cancel": 0, "delete": 1,
"create": 1, "email": 1,
"delete": 1, "export": 1,
"email": 1, "print": 1,
"export": 1, "read": 1,
"if_owner": 0, "report": 1,
"import": 0, "role": "System Manager",
"permlevel": 0, "share": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1 "write": 1
}, },
{ {
"amend": 0, "create": 1,
"cancel": 0, "delete": 1,
"create": 1, "email": 1,
"delete": 1, "export": 1,
"email": 1, "print": 1,
"export": 1, "read": 1,
"if_owner": 0, "report": 1,
"import": 0, "role": "Accounts Manager",
"permlevel": 0, "share": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1 "write": 1
}, },
{ {
"amend": 0, "create": 1,
"cancel": 0, "delete": 1,
"create": 1, "email": 1,
"delete": 1, "export": 1,
"email": 1, "print": 1,
"export": 1, "read": 1,
"if_owner": 0, "report": 1,
"import": 0, "role": "Accounts User",
"permlevel": 0, "share": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts User",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1 "write": 1
} }
], ],
"quick_entry": 0, "search_fields": "folio_no",
"read_only": 0, "sort_field": "modified",
"read_only_onload": 0, "sort_order": "DESC",
"search_fields": "folio_no", "title_field": "title",
"show_name_in_global_search": 0, "track_changes": 1
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "title",
"track_changes": 1,
"track_seen": 0,
"track_views": 0
} }