Files
edgartools/venv/lib/python3.10/site-packages/edgar/muniadvisors.py
2025-12-09 12:13:01 +01:00

884 lines
41 KiB
Python

from dataclasses import dataclass
from datetime import datetime
from typing import List, Optional
from bs4 import BeautifulSoup
from rich import box
from rich.columns import Columns
from rich.console import Group
from rich.panel import Panel
from rich.table import Table
from rich.text import Text
from edgar import Filing
from edgar._party import Address, Name
from edgar.richtools import repr_rich
from edgar.xmltools import child_text, child_texts, child_value
__all__ = [
'MunicipalAdvisorForm'
]
@dataclass(frozen=True)
class Filer:
cik: str
ccc: str
@dataclass(frozen=True)
class Contact:
name: str
phone: str
email: str
@dataclass(frozen=True)
class Employer:
name: str
start_date: str
end_date: Optional[str]
ma_related: bool
investment_related: bool
position: str
address: Address
@dataclass(frozen=True)
class Office:
start_date: str
location_info: str
address: Address
@property
def street1(self):
return self.address.street1 if self.address and self.address.street1 else ""
@property
def street2(self):
return self.address.street2 if self.address and self.address.street2 else ""
@property
def city(self):
return self.address.city if self.address and self.address.city else ""
@property
def state_or_country(self):
return self.address.state_or_country if self.address and self.address.state_or_country else ""
@property
def zipcode(self):
return self.address.zipcode if self.address and self.address.zipcode else ""
@dataclass(frozen=True)
class MunicipalAdvisorOffice:
cik: str
firm_name: str
is_independent_relationship: bool
recent_employment_commenced_date: str
file_number: str
offices: List[Office]
@dataclass(frozen=True)
class CriminalDisclosure:
is_convicted_of_felony: bool
is_charged_with_felony: bool
is_org_convicted_of_felony: bool
is_org_charged_with_felony: bool
is_convicted_of_misdemeanor: bool
is_charged_with_misdemeanor: bool
is_org_convicted_of_misdemeanor: bool
is_org_charged_with_misdemeanor: bool
def any(self):
return any([getattr(self, attr) for attr in dir(self) if attr.startswith('is')])
@dataclass(frozen=True)
class RegulatoryDisclosure:
is_made_false_statement: bool
is_violated_regulation: bool
is_cause_of_denial: bool
is_order_against: bool
is_imposed_penalty: bool
is_un_ethical: bool
is_found_in_violation_of_regulation: bool
is_found_in_cause_of_denial: bool
is_order_against_activity: bool
is_denied_license: bool
is_found_made_false_statement: bool
is_found_in_violation_of_rules: bool
is_found_in_cause_of_suspension: bool
is_discipliend: bool
is_authorized_to_act_attorney: bool
is_regulatory_complaint: bool
is_violated_security_act: bool
is_will_fully_aided: bool
is_failed_to_supervise: bool
is_found_will_fully_aided: bool
is_association_bared: bool
is_final_order: bool
is_will_fully_violated_security_act: bool
is_failed_resonably: bool
def any(self):
return any([getattr(self, attr) for attr in dir(self) if attr.startswith('is')])
@dataclass(frozen=True)
class CivilDisclosure:
is_enjoined: bool
is_found_violation_of_regulation: bool
is_dismissed: bool
is_named_in_civil_proceeding: bool
def any(self):
return any([getattr(self, attr) for attr in dir(self) if attr.startswith('is')])
@dataclass(frozen=True)
class ComplaintDisclosure:
is_complaint_pending: bool
is_complaint_settled: bool
is_fraud_case_pending: bool
is_fraud_case_resulting_award: bool
is_fraud_case_settled: bool
def any(self):
return any([getattr(self, attr) for attr in dir(self) if attr.startswith('is')])
@dataclass(frozen=True)
class TerminationDisclosure:
is_violated_industry_standards: bool
is_involved_in_fraud: bool
is_failed_to_supervise: bool
def any(self):
return any([getattr(self, attr) for attr in dir(self) if attr.startswith('is')])
@dataclass(frozen=True)
class FinancialDisclosure:
is_compromised: bool
is_bankruptcy_petition: bool
is_trustee_appointed: bool
is_bond_revoked: bool
def any(self):
return any([getattr(self, attr) for attr in dir(self) if attr.startswith('is')])
@dataclass(frozen=True)
class JudgementLienDisclosure:
is_lien_against: bool
def any(self):
return self.is_lien_against
@dataclass(frozen=True)
class InvestigationDisclosure:
is_investigated: bool
def employment_date(date: str = None) -> str:
# Convert date from this format 06-2015 to Jun 2015
if not date:
return ""
date_object = datetime.strptime(date, '%m-%Y')
return date_object.strftime('%b %Y')
class EmploymentHistory:
def __init__(self,
current_employer: Employer,
previous_employers: List[Employer]
):
self.current_employer: Employer = current_employer
self.previous_employers: List[Employer] = previous_employers
def __rich__(self):
employment_history_table = Table("From",
"To",
"Employer",
"Position",
"Muni",
"Investment",
"Location",
box=box.SIMPLE)
employer = self.current_employer
employment_history_table.add_row(employer.start_date,
"",
employer.name,
employer.position,
"Yes" if employer.ma_related else "No",
"Yes" if employer.investment_related else "No",
f"{employer.address.city or ''} {employer.address.state_or_country or ''}")
for employer in self.previous_employers:
employment_history_table.add_row(employer.start_date,
employer.end_date,
employer.name,
employer.position,
"Yes" if employer.ma_related else "No",
"Yes" if employer.investment_related else "No",
f"{employer.address.city or ''} {employer.address.state_or_country or ''}")
return employment_history_table
def __repr__(self):
return repr_rich(self.__rich__())
class Applicant:
def __init__(self, name: Name,
other_names: List[Name],
crd: str,
number_of_advisory_firms: int):
self.name: Name = name
self.other_names = other_names
self.crd = crd
self.number_of_advisory_firms: int = number_of_advisory_firms
@property
def full_name(self):
return self.name.full_name
def __repr__(self):
return f"{self.name} (CRD {self.crd})"
@dataclass(frozen=True)
class Disclosures:
criminal_disclosure: CriminalDisclosure
regulatory_disclosure: RegulatoryDisclosure
civil_disclosure: CivilDisclosure
complaint_disclosure: ComplaintDisclosure
termination_disclosure: TerminationDisclosure
financial_disclosure: FinancialDisclosure
judgement_lien_disclosure: JudgementLienDisclosure
investigation_disclosure: InvestigationDisclosure
def any(self):
return (self.criminal_disclosure.any()
or self.regulatory_disclosure.any()
or self.civil_disclosure.any()
or self.civil_disclosure.any()
or self.complaint_disclosure.any()
or self.termination_disclosure.any()
or self.financial_disclosure.any()
or self.judgement_lien_disclosure.any()
or self.investigation_disclosure.is_investigated
)
@dataclass(frozen=True)
class Signature:
date_signed: str
signature: str
title: str
class MunicipalAdvisorForm:
def __init__(self,
filing: Filing,
filer: Filer,
is_amendment: bool,
is_individual: bool,
previous_accession_no: str,
contact: Contact,
applicant: Applicant,
internet_notification_addresses: List[str],
municipal_advisor_offices: List[MunicipalAdvisorOffice],
employment_history: EmploymentHistory,
disclosures: Disclosures,
signature: Signature
):
self.filing: Filing = filing
self.filer: Filer = filer
self.is_amendment: bool = is_amendment
self.is_individual: bool = is_individual
self.previous_accession_no: str = previous_accession_no
self.contact: Contact = contact
self.applicant: Applicant = applicant
self.municipal_advisor_offices: List[MunicipalAdvisorOffice] = municipal_advisor_offices
self.internet_notification_addresses = internet_notification_addresses
self.current_employer: Employer
self.employment_history: EmploymentHistory = employment_history
self.disclosures: Disclosures = disclosures
self.signature = signature
@classmethod
def from_filing(cls, filing):
assert filing.form in ['MA', 'MA/A', 'MA-I', 'MA-I/A'], f"This form should be a Form 144 but was {filing.form}"
xml = filing.xml()
if xml:
ma_objects = cls.from_xml(xml)
return cls(filing=filing, **ma_objects)
@classmethod
def from_xml(cls, xml):
soup = BeautifulSoup(xml, 'xml')
root = soup.find('edgarSubmission')
ma_info = {}
# Header Data
header_data = root.find('headerData')
filer_info_el = header_data.find('filerInfo')
filer_el = filer_info_el.find('filer')
ma_info['filer'] = Filer(
cik=child_text(filer_el, 'filerId'),
ccc=child_text(filer_el, 'filerCcc')
)
contact_el = filer_info_el.find('contact')
ma_info['contact'] = Contact(
name=child_text(contact_el, 'name'),
phone=child_text(contact_el, 'phoneNumber'),
email=child_text(filer_info_el, 'contactEmail')
)
notification_el = root.find('notifications')
if notification_el:
ma_info['internet_notification_addresses'] = child_texts(notification_el, 'internetNotificationAddress')
else:
ma_info['internet_notification_addresses'] = []
# Form Data
form_data_el = root.find('formData')
ma_info['is_amendment'] = child_text(form_data_el, 'isAmendment') == 'Y'
ma_info['is_individual'] = child_text(form_data_el, 'isIndividual') == 'Y'
ma_info['previous_accession_no'] = child_text(form_data_el, 'previousAccessionNumber')
# Applicant
applicant_el = form_data_el.find('applicantName')
applicant = Applicant(
name=Name(
first_name=child_text(applicant_el, 'firstName'),
last_name=child_text(applicant_el, 'lastName'),
middle_name=child_text(applicant_el, 'middleName'),
suffix=child_text(applicant_el, 'suffix')
),
other_names=[],
crd=child_text(form_data_el, 'applicantCrdNum'),
number_of_advisory_firms=int(child_text(form_data_el, 'noOfAdvisoryFirms'))
)
# Other names
other_names_el = form_data_el.find('otherNames')
if other_names_el:
for el in other_names_el.find_all('otherName'):
applicant.other_names.append(
Name(
first_name=child_text(el, 'firstName'),
last_name=child_text(el, 'lastName'),
middle_name=child_text(el, 'middleName'),
suffix=child_text(applicant_el, 'suffix')
)
)
ma_info['applicant'] = applicant
# Municipal Advisor Offices
ma_offices_el = form_data_el.find('municipalAdvisorOffices')
ma_info['municipal_advisor_offices'] = []
for ma_office_el in ma_offices_el.find_all("municipalAdvisorOffice"):
municipal_firm_el = ma_office_el.find('municipalFirm')
filer_el = municipal_firm_el.find('filerId')
sec_registration_el = ma_office_el.find('secRegistration')
advisor_offices_el = ma_office_el.find('advisorOffices')
offices = []
for advisor_office_el in advisor_offices_el.find_all('advisorOffice'):
address_el = advisor_office_el.find('address')
address = Address(
street1=child_text(address_el, 'street1'),
city=child_text(address_el, 'city'),
state_or_country=child_text(address_el, 'stateOrCountry'),
zipcode=child_text(address_el, 'zipCode'),
) if address_el else None
office: Office = Office(
location_info=child_text(advisor_office_el, 'locationInfo'),
start_date=child_text(advisor_office_el, 'startDate'),
address=address
)
offices.append(office)
file_number = child_text(sec_registration_el, 'fileNumber') if sec_registration_el else None
municipal_advisor_office = MunicipalAdvisorOffice(
cik=filer_el.text if filer_el else "",
firm_name=child_text(municipal_firm_el, 'municipalFirmName'),
is_independent_relationship=child_text(municipal_firm_el, 'isIndependentRelationship') == 'Y',
recent_employment_commenced_date=child_text(municipal_firm_el, 'recentEmploymentCommencedDate'),
file_number=file_number,
offices=offices
)
ma_info['municipal_advisor_offices'].append(municipal_advisor_office)
# Employment History
employment_history_el = form_data_el.find('employmentHistory')
# Current Employer
current_employer_el = employment_history_el.find('currentEmployer')
address_el = current_employer_el.find('addressInfo')
state_or_country_el = address_el.find('stateOrCountry')
current_employer = Employer(
name=child_text(current_employer_el, 'name'),
start_date=employment_date(child_text(current_employer_el, 'startDate')),
end_date=None,
address=Address(
city=child_text(address_el, 'city'),
zipcode=child_text(address_el, 'zipCode'),
state_or_country=child_text(state_or_country_el, 'stateOrCountry'),
),
ma_related=child_text(current_employer_el, 'isRelatedToMunicipalAdvisor') == "Y",
investment_related=child_text(current_employer_el, 'isRelatedToInvestment') == "Y",
position=child_text(current_employer_el, 'positionDescription'),
)
# Previous employers
prior_employers_el = employment_history_el.find('priorEmployers')
prior_employers = []
if prior_employers_el:
for prior_employer_el in prior_employers_el.find_all('priorEmployer'):
address_el = prior_employer_el.find('addressInfo')
state_or_country_el = address_el.find('stateOrCountry')
prior_employer = Employer(
name=child_text(prior_employer_el, 'name'),
start_date=employment_date(child_text(prior_employer_el, 'startDate')),
end_date=employment_date(child_text(prior_employer_el, 'endDate')),
address=Address(
city=child_text(address_el, 'city'),
zipcode=child_text(address_el, 'zipCode'),
state_or_country=child_text(state_or_country_el, 'stateOrCountry'),
),
ma_related=child_text(prior_employer_el, 'isRelatedToMunicipalAdvisor') == "Y",
investment_related=child_text(prior_employer_el, 'isRelatedToInvestment') == "Y",
position=child_text(prior_employer_el, 'positionDescription'),
)
prior_employers.append(prior_employer)
ma_info['employment_history'] = EmploymentHistory(
current_employer=current_employer,
previous_employers=prior_employers
)
# Disclosure Questions
disclosure_questions_el = form_data_el.find('disclosureQuestions')
# Criminal Disclosure
criminal_disclosure_el = disclosure_questions_el.find('criminalDisclosure')
criminal_disclosure_common_el = criminal_disclosure_el.find('criminalDisclosureCommonQuestion')
criminal_disclosure = CriminalDisclosure(
is_convicted_of_felony=child_value(criminal_disclosure_common_el, 'isConvictedOfFelony') == "Y",
is_charged_with_felony=child_value(criminal_disclosure_common_el, 'isChargedWithFelony') == "Y",
is_org_convicted_of_felony=child_value(criminal_disclosure_common_el, 'isOrgConvictedOfFelony') == "Y",
is_org_charged_with_felony=child_value(criminal_disclosure_common_el, 'isOrgChargedWithFelony') == "Y",
is_convicted_of_misdemeanor=child_value(criminal_disclosure_el, 'isConvictedOfMisdemeanor') == "Y",
is_charged_with_misdemeanor=child_value(criminal_disclosure_el, 'isChargedWithMisdemeanor') == "Y",
is_org_charged_with_misdemeanor=child_value(criminal_disclosure_el,
'isOrgChargedWithMisdemeanor') == "Y",
is_org_convicted_of_misdemeanor=child_value(criminal_disclosure_el,
'isOrgConvictedOfMisdemeanor') == "Y",
)
criminal_disclosure = criminal_disclosure
# Regulatory Disclosure
regulatory_disclosure_el = disclosure_questions_el.find('regulatoryDisclosure')
regulatory_disclosure_common_el = regulatory_disclosure_el.find('regulatoryDisclosureCommonQuestion')
regulatory_disclosure = RegulatoryDisclosure(
is_made_false_statement=child_value(regulatory_disclosure_common_el, 'isMadeFalseStatement') == "Y",
is_violated_regulation=child_value(regulatory_disclosure_common_el, 'isViolatedRegulation') == "Y",
is_cause_of_denial=child_value(regulatory_disclosure_common_el, 'isCauseOfDenial') == "Y",
is_order_against=child_value(regulatory_disclosure_common_el, 'isOrderAgainst') == "Y",
is_imposed_penalty=child_value(regulatory_disclosure_common_el, 'isImposedPenalty') == "Y",
is_un_ethical=child_value(regulatory_disclosure_common_el, 'isUnEthical') == "Y",
is_found_in_violation_of_regulation=child_value(regulatory_disclosure_common_el,
'isFoundInViolationOfRegulation') == "Y",
is_found_in_violation_of_rules=child_value(regulatory_disclosure_common_el,
'isFoundInViolationOfRules') == "Y",
is_found_in_cause_of_denial=child_value(regulatory_disclosure_common_el,
'isFoundInCauseOfDenial') == "Y",
is_order_against_activity=child_value(regulatory_disclosure_common_el,
'isOrderAgainstActivity') == "Y",
is_denied_license=child_value(regulatory_disclosure_common_el, 'isDeniedLicense') == "Y",
is_found_in_cause_of_suspension=child_value(regulatory_disclosure_common_el,
'isFoundInCauseOfSuspension') == "Y",
is_discipliend=child_value(regulatory_disclosure_common_el, 'isDiscipliend') == "Y",
is_authorized_to_act_attorney=child_value(regulatory_disclosure_common_el,
'isAuthorizedToActAttorney') == "Y",
is_regulatory_complaint=child_value(regulatory_disclosure_common_el, 'isRegulatoryComplaint') == "Y",
is_violated_security_act=child_value(regulatory_disclosure_el, 'isViolatedSecurityAct') == "Y",
is_will_fully_aided=child_value(regulatory_disclosure_el, 'isWillFullyAided') == "Y",
is_failed_to_supervise=child_value(regulatory_disclosure_el, 'isFailedToSupervise') == "Y",
is_found_will_fully_aided=child_value(regulatory_disclosure_el, 'isFoundWillFullyAided') == "Y",
is_association_bared=child_value(regulatory_disclosure_el, 'isAssociationBared') == "Y",
is_final_order=child_value(regulatory_disclosure_el, 'isFinalOrder') == "Y",
is_will_fully_violated_security_act=child_value(regulatory_disclosure_el,
'isWillFullyViolatedSecurityAct') == "Y",
is_failed_resonably=child_value(regulatory_disclosure_el, 'isFailedResonably') == "Y",
is_found_made_false_statement=child_value(regulatory_disclosure_el,
'isFoundMadeFalseStatement') == "Y"
)
regulatory_disclosure = regulatory_disclosure
# Investigation Disclosure
investigation_disclosure_el = disclosure_questions_el.find('investigationDisclosure')
investigation_disclosure = InvestigationDisclosure(
is_investigated=child_text(investigation_disclosure_el, 'isInvestigated') == "Y")
# Civil Disclosure
civil_disclosure_el = disclosure_questions_el.find('civilDisclosure')
civil_disclosure = CivilDisclosure(
is_enjoined=child_value(civil_disclosure_el, 'isEnjoined') == "Y",
is_found_violation_of_regulation=child_value(civil_disclosure_el,
'isFoundViolationOfRegulation') == "Y",
is_dismissed=child_value(civil_disclosure_el, 'isDismissed') == "Y",
is_named_in_civil_proceeding=child_value(civil_disclosure_el,
'isNamedInCivilProceeding') == "Y")
# Complaint Disclosure
complaint_disclosure_el = disclosure_questions_el.find('complaintDisclosure')
complaint_disclosure = ComplaintDisclosure(
is_complaint_pending=child_value(complaint_disclosure_el, 'isComplaintPending') == "Y",
is_complaint_settled=child_value(complaint_disclosure_el, 'isComplaintSettled') == "Y",
is_fraud_case_pending=child_value(complaint_disclosure_el, 'isFraudCasePending') == "Y",
is_fraud_case_resulting_award=child_value(complaint_disclosure_el,
'isFraudCaseResultingAward') == "Y",
is_fraud_case_settled=child_value(complaint_disclosure_el, 'isFraudCaseSettled') == "Y"
)
# Termination Disclosure
termination_disclosure_el = disclosure_questions_el.find('terminationDisclosure')
termination_disclosure = TerminationDisclosure(
is_violated_industry_standards=child_value(termination_disclosure_el,
'isViolatedIndustryStandards') == "Y",
is_involved_in_fraud=child_value(termination_disclosure_el, 'isInvolvedInFraud') == "Y",
is_failed_to_supervise=child_value(termination_disclosure_el, 'isFailedToSupervise') == "Y"
)
# Financial Disclosure
financial_disclosure_el = disclosure_questions_el.find('financialDisclosure')
financial_disclosure = FinancialDisclosure(
is_compromised=child_value(financial_disclosure_el, 'isCompromised') == "Y",
is_bankruptcy_petition=child_value(financial_disclosure_el, 'isBankruptcyPetition') == "Y",
is_trustee_appointed=child_value(financial_disclosure_el, 'isTrusteeAppointed') == "Y",
is_bond_revoked=child_value(financial_disclosure_el, 'isBondRevoked') == "Y"
)
# Judgement Lien Disclosure
judgement_lien_disclosure_el = disclosure_questions_el.find('judgmentLienDisclosure')
judgement_lien_disclosure = JudgementLienDisclosure(
is_lien_against=child_value(judgement_lien_disclosure_el, 'isLienAgainst') == "Y"
)
# Signature
signature_el = form_data_el.find('signature')
ma_info['signature'] = Signature(
signature=child_text(signature_el, 'signature'),
date_signed=child_text(signature_el, 'dateSigned'),
title=child_text(signature_el, 'title')
)
ma_info['disclosures'] = Disclosures(
criminal_disclosure=criminal_disclosure,
regulatory_disclosure=regulatory_disclosure,
civil_disclosure=civil_disclosure,
complaint_disclosure=complaint_disclosure,
termination_disclosure=termination_disclosure,
financial_disclosure=financial_disclosure,
judgement_lien_disclosure=judgement_lien_disclosure,
investigation_disclosure=investigation_disclosure
)
return ma_info
def __rich__(self):
PAD = 80
def text(label: str, value: str) -> Columns:
return Columns([Text(label.ljust(PAD), style="bold"), Text(value)])
def yes_no(label: str, value: bool) -> Columns:
return Columns([Text(label.ljust(PAD), style="bold"), Text("Yes" if value else "No")])
# Other Names
other_names_group = []
for index, other_name in enumerate(self.applicant.other_names):
other_names_group.append(
Group(
Text(f"{'First Name:'.ljust(20)}{'Middle Name:'.ljust(20)}{'Last Name:'.ljust(20)}"),
Text(
(f"{other_name.first_name.ljust(20)}"
f"{other_name.middle_name.ljust(20)}"
f"{other_name.last_name.ljust(20)}")
),
)
)
if index < len(self.applicant.other_names) - 1:
other_names_group.append(Text("-" * 50))
display = Group(
Panel(
Group(
Text(f"Filer CIK: {self.filer.cik.ljust(30)}Filer CCC: {self.filer.ccc}"),
), title=f"Form {self.filing.form} Applicant's Information",
),
Panel(
Group(
Text(f"Name: {self.contact.name.ljust(35)}Phone: {self.contact.phone}"),
), title="Submission Contact Information",
),
Panel(
Group(
*[Text(f"Email Address: {address}", address)
for address in self.internet_notification_addresses]
), title="Notification Information",
),
Panel(
Group(
Text(f"{'First Name:'.ljust(20)}{'Middle Name:'.ljust(20)}{'Last Name:'.ljust(20)}"),
Text(
(f"{self.applicant.name.first_name.ljust(20)}"
f"{self.applicant.name.middle_name.ljust(20)}"
f"{self.applicant.name.last_name.ljust(20)}")
),
), title="The Individual",
),
Panel(
Group(*other_names_group), title="Other Names",
),
Panel(
Group(
text("Number of firms:", str(self.applicant.number_of_advisory_firms)),
text("Municipal firm's CIK:", self.municipal_advisor_offices[0].cik),
text("Full legal name:", self.municipal_advisor_offices[0].firm_name),
text("Employment start date:", self.municipal_advisor_offices[0].recent_employment_commenced_date),
text("Has independent relationship:",
"Yes" if self.municipal_advisor_offices[0].is_independent_relationship else "No")
), title="Municipal Advisory Firms Where The Individual is Employed",
),
Panel(
self.employment_history.__rich__(), title="Employment History"
),
Panel(
Group(
text("Edgar CIK Number", self.municipal_advisor_offices[0].cik),
), title="Municipal Advisory Firms Registration Information"
),
Panel(
Group(
text("Start Date", self.municipal_advisor_offices[0].offices[0].start_date),
text("Street Address 1", self.municipal_advisor_offices[0].offices[0].street1),
text("Street Address 2", self.municipal_advisor_offices[0].offices[0].street2),
text("City", self.municipal_advisor_offices[0].offices[0].city),
text("State", self.municipal_advisor_offices[0].offices[0].state_or_country),
text("Postal Code", self.municipal_advisor_offices[0].offices[0].zipcode),
), title="Office"
),
Panel(
Group(
Text("Has the individual ever:\n"),
yes_no("Been convicted of a felony", self.disclosures.criminal_disclosure.is_convicted_of_felony),
yes_no("Been charged with a felony", self.disclosures.criminal_disclosure.is_charged_with_felony),
yes_no("Caused an organization to be convicted of a felony",
self.disclosures.criminal_disclosure.is_convicted_of_felony),
yes_no("Caused an organization to be charged with a felony",
self.disclosures.criminal_disclosure.is_charged_with_felony),
yes_no("Been convicted of a misdemeanor",
self.disclosures.criminal_disclosure.is_convicted_of_misdemeanor),
yes_no("Been charged with a misdemeanor",
self.disclosures.criminal_disclosure.is_charged_with_misdemeanor),
yes_no("Caused an organization to be convicted of misdemeanor",
self.disclosures.criminal_disclosure.is_convicted_of_misdemeanor),
yes_no("Caused an organization to be charged with misdemeanor",
self.disclosures.criminal_disclosure.is_charged_with_misdemeanor),
), title="Criminal Action Disclosure",
),
Panel(
Group(
Text("Has the SEC or the CFTC ever:\n"),
# <com:isMadeFalseStatement>N</com:isMadeFalseStatement>
yes_no("Found that the individual made a false statement",
self.disclosures.regulatory_disclosure.is_found_made_false_statement),
# <com:isViolatedRegulation>N</com:isViolatedRegulation>
yes_no("Found the individual in violation of an SEC or CFTC regulation",
self.disclosures.regulatory_disclosure.is_violated_regulation),
# <com:isCauseOfDenial>N</com:isCauseOfDenial>
yes_no("Found the individual caused a suspension of a MA business",
self.disclosures.regulatory_disclosure.is_cause_of_denial),
# <com:isOrderAgainst>N</com:isOrderAgainst>
yes_no("Entered an order against the individual connected to MA or investment activity",
self.disclosures.regulatory_disclosure.is_order_against),
# <com:isImposedPenalty>N</com:isImposedPenalty>
yes_no("Imposed a penalty on the individual",
self.disclosures.regulatory_disclosure.is_imposed_penalty),
# <com:isUnEthical>N</com:isUnEthical>
yes_no("Found the individual to have been dishonest or unethical",
self.disclosures.regulatory_disclosure.is_un_ethical),
# <com:isFoundInViolationOfRegulation>N</com:isFoundInViolationOfRegulation>
yes_no("Found the individual to have willfully violated a Securities or Investment Act",
self.disclosures.regulatory_disclosure.is_found_in_violation_of_regulation),
# <com:isFoundInCauseOfDenial>N</com:isFoundInCauseOfDenial>
yes_no("Found the individual a cause of a denial of auth of muni-advisor business",
self.disclosures.regulatory_disclosure.is_found_in_cause_of_denial),
# <com:isOrderAgainstActivity>N</com:isOrderAgainstActivity>
yes_no("Entered an order against the individual's activities",
self.disclosures.regulatory_disclosure.is_order_against_activity),
# <com:isDeniedLicense>N</com:isDeniedLicense>
yes_no("Denied, suspended or revoked the individual's license",
self.disclosures.regulatory_disclosure.is_denied_license),
# <com:isFoundMadeFalseStatement>N</com:isFoundMadeFalseStatement>
yes_no("Found the individual to have made a false statement",
self.disclosures.regulatory_disclosure.is_found_made_false_statement),
# <com:isFoundInViolationOfRules>N</com:isFoundInViolationOfRules>
yes_no("Found the individual to be in violation of rules",
self.disclosures.regulatory_disclosure.is_found_in_violation_of_rules),
# <com:isFoundInCauseOfSuspension>N</com:isFoundInCauseOfSuspension>
yes_no("Found the individual a cause of suspension of a muni-advisor business",
self.disclosures.regulatory_disclosure.is_found_in_cause_of_suspension),
# <com:isDiscipliend>N</com:isDiscipliend>
yes_no("Disciplined the individual by expelling or barring from membership",
self.disclosures.regulatory_disclosure.is_discipliend),
# <com:isAuthorizedToActAttorney>N</com:isAuthorizedToActAttorney>
yes_no("Has the individual ever had an authorization to act as attorney suspended",
self.disclosures.regulatory_disclosure.is_authorized_to_act_attorney),
# <com:isRegulatoryComplaint>N</com:isRegulatoryComplaint>
yes_no("Has the individual ever been notified of a regulatory complaint against them",
self.disclosures.regulatory_disclosure.is_regulatory_complaint),
# <isViolatedSecurityAct>N</isViolatedSecurityAct>
yes_no("Found the individual to have violated the Securities Act",
self.disclosures.regulatory_disclosure.is_violated_security_act),
# <isWillFullyAided>N</isWillFullyAided>
yes_no("Found the individual to have willfully aided a violation",
self.disclosures.regulatory_disclosure.is_will_fully_aided),
# <isFailedToSupervise>N</isFailedToSupervise>
yes_no("Found the individual to have failed to supervise another individual",
self.disclosures.regulatory_disclosure.is_failed_to_supervise),
), title="Regulatory Disclosure",
),
Panel(
Group(
Text("Has any other federal or state or foreign regulatory agency ever:\n"),
# <isWillFullyAided>N</isWillFullyAided>
yes_no("Found the individual to have willfully aided a violation",
self.disclosures.regulatory_disclosure.is_found_will_fully_aided),
# <isAssociationBared>N</isAssociationBared>
yes_no("Barred the individual from association with a regulated agancy",
self.disclosures.regulatory_disclosure.is_association_bared),
# <isFinalOrder>N</isFinalOrder>
yes_no("Entered a final order against the individual",
self.disclosures.regulatory_disclosure.is_final_order),
), title="Regulatory Disclosure",
),
Panel(
yes_no("Is the individual currently being investigated:",
self.disclosures.investigation_disclosure.is_investigated),
title="Investigation Disclosure",
),
Panel(
Group(
Text("Has any domestic of foreign court ever:\n"),
yes_no("Enjoined the individual in connection with a muni advisor business",
self.disclosures.civil_disclosure.is_enjoined),
yes_no("Found the individual to have violated any law or regulation",
self.disclosures.civil_disclosure.is_found_violation_of_regulation),
yes_no("Dismissed with a settleent a civil action against the individual",
self.disclosures.civil_disclosure.is_dismissed),
yes_no("Is the individual named in any current civil proceeding",
self.disclosures.civil_disclosure.is_named_in_civil_proceeding
)
), title="Civil Disclosure"
),
Panel(
Group(
Text("Has the individual ever been the subject of a muni-advisor related complaint which:\n"),
yes_no("Is still pending", self.disclosures.complaint_disclosure.is_complaint_pending),
yes_no("Is settled", self.disclosures.complaint_disclosure.is_complaint_settled),
Text("\n"
"Has the individual ever been the subject of a muni-advisor related fraud proceeding which\n"),
yes_no("Is still pending", self.disclosures.complaint_disclosure.is_fraud_case_pending),
yes_no("Resulted in an award", self.disclosures.complaint_disclosure.is_fraud_case_resulting_award),
yes_no("Is settled", self.disclosures.complaint_disclosure.is_fraud_case_settled),
), title="Complaint Disclosure",
),
Panel(
Group(
Text("Has the individual ever been terminated or permitted to resign after allegations of:\n"),
yes_no("Violations of industry standards",
self.disclosures.termination_disclosure.is_violated_industry_standards),
yes_no("Involvement in fraud", self.disclosures.termination_disclosure.is_involved_in_fraud),
yes_no("Failure to supervise", self.disclosures.termination_disclosure.is_failed_to_supervise),
), title="Termination Disclosure",
),
Panel(
Group(
Text("Within the past 10 years:\n"),
yes_no("Has the individual made a compromise with creditors",
self.disclosures.financial_disclosure.is_compromised),
yes_no("Has an organization under the individual's control ever filed for bankruptcy",
self.disclosures.financial_disclosure.is_bankruptcy_petition),
yes_no("Has an organization under the individual's control ever has a trustee appointed",
self.disclosures.financial_disclosure.is_trustee_appointed),
yes_no("Has a bonding company ever denied/paid out/revoked a bond for the individual",
self.disclosures.financial_disclosure.is_bond_revoked),
), title="Financial Disclosure",
),
Panel(
Group(
yes_no("Are there currently any judgment liens against the individual",
self.disclosures.judgement_lien_disclosure.is_lien_against),
),
title="Judgement/Lien Disclosure",
),
Panel(
Group(
Text(f"{'By:'.ljust(32)}{'Title:'.ljust(60)}{'Date:'}"),
Text((f"{self.signature.signature.ljust(32)}"
f"{self.signature.title.ljust(60)}"
f"{self.signature.date_signed}")),
), title="Signature"
)
)
return display
def __repr__(self):
return repr_rich(self.__rich__())