Skip to content

Commit

Permalink
Initial implementation register Securities Act financing statement.
Browse files Browse the repository at this point in the history
Signed-off-by: Doug Lovett <[email protected]>
  • Loading branch information
doug-lovett committed Apr 24, 2024
1 parent e0abe43 commit 91bb978
Show file tree
Hide file tree
Showing 35 changed files with 1,182 additions and 104 deletions.
3 changes: 3 additions & 0 deletions ppr-api/report-templates/financingStatementV2.html
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@
[[registration/debtors.html]]
[[registration/vehicleCollateral.html]]
[[registration/generalCollateral.html]]
{% if type == 'SE' %}
[[registration/securitiesActNotice.html]]
{% endif %}
[[registration/registeringParty.html]]
</div>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<div>
{% if securitiesActNotices is defined and change is not defined %}
<div class="separator mt-5"></div>
{% endif %}
<div class="section-title mt-3">Securities Act Notices</div>
{% if securitiesActNotices is defined and change is not defined %}
{% for notice in securitiesActNotices %}
<table class="no-page-break section-data court-order-table mt-3" role="presentation">
<tr>
<td class="section-sub-title">Type of Notice:</td>
<td>{{ notice.securitiesActNoticeType|title }}</td>
</tr>
<tr>
<td class="section-sub-title">Effective Date:</td>
<td>
{% if notice.effectiveDateTime is defined and notice.effectiveDateTime != '' %}
{{ notice.effectiveDateTime }}
{% else %}
N/A
{% endif %}
</td>
</tr>
<tr>
<td class="section-sub-title">Detail Description:</td>
<td>
{% if notice.description is defined and notice.description != '' %}
{{ notice.description }}
{% else %}
N/A
{% endif %}
</td>
</tr>
</table>
{% if notice.securitiesActOrders %}
<div class="section-title mt-1">Notice Court/Commission Order(s)</div>
{% for order in notice.securitiesActOrders %}
<table class="no-page-break section-data court-order-table mt-1" role="presentation">
<tr>
<td class="section-sub-title">Type of Order:</td>
<td>{% if order.courtOrder %}Court{% else %}Commission{% endif %} Order</td>
</tr>
<tr>
<td class="section-sub-title">Name of Court:</td>
<td>{% if order.courtName %}{{ order.courtName }}{% else %}N/A{% endif %}</td>
</tr>
<tr>
<td class="section-sub-title">Registry</td>
<td>{% if order.courtRegistry %}{{ order.courtRegistry }}{% else %}N/A{% endif %}</td>
</tr>
<tr>
<td class="section-sub-title">Date of Order:</td>
<td>{% if order.orderDate %}{{ order.orderDate }}{% else %}N/A{% endif %}</td>
</tr>
<tr>
<td class="section-sub-title">File Number:</td>
<td>{% if order.fileNumber %}{{ order.fileNumber }}{% else %}N/A{% endif %}</td>
</tr>
<tr>
<td class="section-sub-title">Effect of Order:</td>
<td>{% if order.effectOfOrder %}{{ order.effectOfOrder }}{% else %}N/A{% endif %}</td>
</tr>
</table>
{% endfor %}
{% endif %}
{% if not loop.last %}
<div class="separator-table-row mt-3 mb-3"></div>
{% endif %}
{% endfor %}
{% elif change is defined and change.securitiesActNotices is defined %}
{% for notice in change.securitiesActNotices %}
<table class="no-page-break section-data court-order-table mt-3" role="presentation">
<tr>
<td class="section-sub-title">Type of Notice:</td>
<td>{{ notice.securitiesActNoticeType|title }}</td>
</tr>
<tr>
<td class="section-sub-title">Effective Date:</td>
<td>
{% if notice.effectiveDateTime is defined and notice.effectiveDateTime != '' %}
{{ notice.effectiveDateTime }}
{% else %}
N/A
{% endif %}
</td>
</tr>
<tr>
<td class="section-sub-title">Detail Description:</td>
<td>
{% if notice.description is defined and notice.description != '' %}
{{ notice.description }}
{% else %}
N/A
{% endif %}
</td>
</tr>
</table>
{% if notice.securitiesActOrders %}
<div class="section-title mt-1">Notice Court/Commission Order(s)</div>
{% for order in notice.securitiesActOrders %}
<table class="no-page-break section-data court-order-table mt-1" role="presentation">
<tr>
<td class="section-sub-title">Type of Order:</td>
<td>{% if order.courtOrder %}Court{% else %}Commission{% endif %} Order</td>
</tr>
<tr>
<td class="section-sub-title">Name of Court:</td>
<td>{% if order.courtName %}{{ order.courtName }}{% else %}N/A{% endif %}</td>
</tr>
<tr>
<td class="section-sub-title">Registry</td>
<td>{% if order.courtRegistry %}{{ order.courtRegistry }}{% else %}N/A{% endif %}</td>
</tr>
<tr>
<td class="section-sub-title">Date of Order:</td>
<td>{% if order.orderDate %}{{ order.orderDate }}{% else %}N/A{% endif %}</td>
</tr>
<tr>
<td class="section-sub-title">File Number:</td>
<td>{% if order.fileNumber %}{{ order.fileNumber }}{% else %}N/A{% endif %}</td>
</tr>
<tr>
<td class="section-sub-title">Effect of Order:</td>
<td>{% if order.effectOfOrder %}{{ order.effectOfOrder }}{% else %}N/A{% endif %}</td>
</tr>
</table>
{% endfor %}
{% endif %}
{% if not loop.last %}
<div class="separator-table-row mt-3 mb-3"></div>
{% endif %}
{% endfor %}
{% endif %}
</div>
2 changes: 1 addition & 1 deletion ppr-api/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,4 @@ strict-rfc3339==0.7
typing-inspect==0.7.1
typing_extensions==4.9.0
urllib3==1.26.15
git+https://github.com/bcgov/registry-schemas.git@1.7.3#egg=registry_schemas
git+https://github.com/bcgov/registry-schemas.git@1.8.10#egg=registry_schemas
2 changes: 1 addition & 1 deletion ppr-api/requirements/bcregistry-libraries.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
git+https://github.com/bcgov/registry-schemas.git@1.7.3#egg=registry_schemas
git+https://github.com/bcgov/registry-schemas.git@1.8.10#egg=registry_schemas
59 changes: 59 additions & 0 deletions ppr-api/src/database/patch/15187-ppr-securities-act.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
-- 15178 begin release 1.2.5
INSERT INTO registration_types(registration_type, registration_type_cl, registration_desc, registration_act) VALUES
('SE', 'MISCLIEN', 'SECURITIES ACT NOTICE', 'SECURITIES ACT');

ALTER TABLE account_bcol_ids
ADD COLUMN securities_act_ind VARCHAR(1) NULL CHECK (securities_act_ind IN ('Y', 'N'));

CREATE TYPE public.securities_act_type AS ENUM ('LIEN', 'PRESERVATION', 'PROCEEDINGS');
CREATE TABLE public.securities_act_types (
securities_act_type public.securities_act_type PRIMARY KEY,
securities_act_type_desc VARCHAR (100) NOT NULL
);
INSERT INTO securities_act_types(securities_act_type, securities_act_type_desc) VALUES
('LIEN', 'SECURITIES ACT NOTICE OF LIEN'),
('PRESERVATION', 'SECURITIES ACT NOTICE OF PRESERVATION ORDER'),
('PROCEEDINGS', 'SECURITIES ACT NOTICE OF PROCEEDINGS')
;

CREATE SEQUENCE securities_act_notice_id_seq INCREMENT 1 START 1;
CREATE TABLE public.securities_act_notices (
id INTEGER PRIMARY KEY,
registration_id INTEGER NOT NULL,
registration_id_end INTEGER NULL,
securities_act_type public.securities_act_type NOT NULL,
effective_ts TIMESTAMP NOT NULL,
detail_description VARCHAR (4000) NULL,
FOREIGN KEY (securities_act_type)
REFERENCES securities_act_types (securities_act_type),
FOREIGN KEY (registration_id)
REFERENCES registrations (id),
FOREIGN KEY (registration_id_end)
REFERENCES registrations (id)
);
CREATE INDEX ix_sec_notices_registration_id ON public.securities_act_notices USING btree (registration_id);
CREATE INDEX ix_sec_notices_change_registration_id ON public.securities_act_notices USING btree (registration_id_end);

CREATE SEQUENCE securities_act_order_id_seq INCREMENT 1 START 1;
CREATE TABLE public.securities_act_orders (
id INTEGER PRIMARY KEY,
registration_id INTEGER NOT NULL,
securities_act_notice_id INTEGER NOT NULL,
court_order_ind VARCHAR (1) NOT NULL CHECK (court_order_ind IN ('Y', 'N')),
registration_id_end INTEGER NULL,
order_date TIMESTAMP NOT NULL,
court_name VARCHAR (256) NULL,
court_registry VARCHAR (64) NULL,
file_number VARCHAR (20) NULL,
effect_of_order VARCHAR (512) NULL,
FOREIGN KEY (securities_act_notice_id)
REFERENCES securities_act_notices (id),
FOREIGN KEY (registration_id)
REFERENCES registrations (id),
FOREIGN KEY (registration_id_end)
REFERENCES registrations (id)
);
CREATE INDEX ix_sec_orders_sec_id ON public.securities_act_orders USING btree (securities_act_notice_id);
CREATE INDEX ix_sec_orders_registration_id ON public.securities_act_orders USING btree (registration_id);
CREATE INDEX ix_sec_orders_change_registration_id ON public.securities_act_orders USING btree (registration_id_end);
-- 15178 end release 1.2.5
4 changes: 4 additions & 0 deletions ppr-api/src/ppr_api/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
from .party import Party
from .previous_financing_statement import PreviousFinancingStatement
from .registration import Registration
from .securities_act_notice import SecuritiesActNotice
from .securities_act_order import SecuritiesActOrder
from .search_request import SearchRequest
from .search_result import SearchResult
from .trust_indenture import TrustIndenture
Expand All @@ -39,6 +41,7 @@
ProvinceType,
RegistrationType,
RegistrationTypeClass,
SecuritiesActType,
SearchType,
SerialType,
StateType,
Expand All @@ -54,5 +57,6 @@
'EventTrackingType', 'FinancingStatement', 'GeneralCollateral', 'GeneralCollateralLegacy', 'MailReport',
'Party', 'PartyType', 'PreviousFinancingStatement', 'ProvinceType', 'Registration', 'RegistrationType',
'RegistrationTypeClass', 'SearchRequest', 'SearchResult', 'SearchType', 'StateType', 'SerialType',
'SecuritiesActNotice', 'SecuritiesActOrder', 'SecuritiesActType',
'TrustIndenture', 'User', 'UserExtraRegistration', 'UserProfile', 'VehicleCollateral',
'VerificationReport')
16 changes: 14 additions & 2 deletions ppr-api/src/ppr_api/models/account_bcol_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ class AccountBcolId(db.Model):

__versioned__ = {}
__tablename__ = 'account_bcol_ids'
CROWN_CHARGE_YES = 'Y'
INDICATOR_YES: str = 'Y'
CROWN_CHARGE_YES = INDICATOR_YES

id = db.mapped_column('id', db.Integer, db.Sequence('account_bcol_id_seq'), primary_key=True)
account_id = db.mapped_column('account_id', db.String(20), nullable=False, index=True)
bconline_account = db.mapped_column('bconline_account', db.Integer, nullable=False)
# Only set when account is a crown charge account.
crown_charge_ind = db.mapped_column('crown_charge_ind', db.String(1), nullable=True)
securities_act_ind = db.mapped_column('securities_act_ind', db.String(1), nullable=True)

def save(self):
"""Store the User into the local cache."""
Expand Down Expand Up @@ -79,7 +81,17 @@ def crown_charge_account(account_id: str) -> bool:
"""Check if an account is configured for crown charge request types."""
account_mappings = db.session.query(AccountBcolId).\
filter(AccountBcolId.account_id == account_id,
AccountBcolId.crown_charge_ind == AccountBcolId.CROWN_CHARGE_YES).all()
AccountBcolId.crown_charge_ind == AccountBcolId.INDICATOR_YES).all()
if account_mappings:
return True
return False

@staticmethod
def securities_act_account(account_id: str) -> bool:
"""Check if an account is configured to submit securities act related registrations."""
account_mappings = db.session.query(AccountBcolId).\
filter(AccountBcolId.account_id == account_id,
AccountBcolId.securities_act_ind == AccountBcolId.INDICATOR_YES).all()
if account_mappings:
return True
return False
10 changes: 7 additions & 3 deletions ppr-api/src/ppr_api/models/client_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def find_by_head_office_start(cls, head_office_id: str):
return party_codes

@classmethod
def find_by_account_id(cls, account_id: str, crown_charge: bool = True):
def find_by_account_id(cls, account_id: str, crown_charge: bool = True, securities_act: bool = False):
"""Return a list of client parties searching by account ID using the account id - bcol id mapping table."""
party_codes = []
if not account_id:
Expand All @@ -164,9 +164,13 @@ def find_by_account_id(cls, account_id: str, crown_charge: bool = True):
if bcol_accounts:
for account in bcol_accounts:
if crown_charge and account.crown_charge_ind and \
account.crown_charge_ind == AccountBcolId.CROWN_CHARGE_YES:
account.crown_charge_ind == AccountBcolId.INDICATOR_YES:
ids.append(account.bconline_account)
elif not crown_charge and not account.crown_charge_ind:
elif securities_act and account.securities_act_ind and \
account.securities_act_ind == AccountBcolId.INDICATOR_YES:
ids.append(account.bconline_account)
elif not crown_charge and not account.crown_charge_ind and \
not securities_act and not account.securities_act_ind:
ids.append(account.bconline_account)
if not ids:
return party_codes
Expand Down
31 changes: 31 additions & 0 deletions ppr-api/src/ppr_api/models/financing_statement.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
from .general_collateral_legacy import GeneralCollateralLegacy # noqa: F401 pylint: disable=unused-import; see above
from .user_extra_registration import UserExtraRegistration # noqa: F401 pylint: disable=unused-import; needed by the SQLAlchemy relationship
from .vehicle_collateral import VehicleCollateral # noqa: F401 pylint: disable=unused-import; needed by the SQLAlchemy relationship
from .securities_act_notice import SecuritiesActNotice # noqa: F401 pylint: disable=unused-import; needed by the SQLAlchemy relationship


class FinancingStatement(db.Model): # pylint: disable=too-many-instance-attributes
Expand Down Expand Up @@ -145,6 +146,8 @@ def json(self) -> dict:
statement['lienAmount'] = reg.lien_value
if reg.surrender_date:
statement['surrenderDate'] = model_utils.format_ts(reg.surrender_date)
if reg.registration_type == model_utils.REG_TYPE_SECURITIES_NOTICE:
statement['securitiesActNotices'] = self.securities_act_notices_json(registration_id)

if self.trust_indenture:
for trust in self.trust_indenture:
Expand Down Expand Up @@ -351,6 +354,34 @@ def vehicle_collateral_json(self, registration_id):

return collateral_list

def securities_act_notices_json(self, registration_id):
"""Build securities act notices JSON: current_view_json determines if current or original data is included."""
notices_list = []
if not self.registration:
return notices_list
for reg in self.registration:
if not self.current_view_json and reg.id == registration_id and reg.securities_act_notices:
for notice in reg.securities_act_notices:
notices_list.append(notice.json)
return notices_list
if self.current_view_json and reg.securities_act_notices:
for notice in reg.securities_act_notices:
notice_json = None
if not notice.registration_id_end and \
(self.verification_reg_id < 1 or self.verification_reg_id >= notice.registration_id):
notice_json = notice.json
if self.mark_update_json and notice.registration_id != registration_id:
notice_json['added'] = True
elif notice.registration_id_end and self.verification_reg_id > 0 and \
self.verification_reg_id >= notice.registration_id and \
self.verification_reg_id < notice.registration_id_end:
notice_json = notice.json
if self.mark_update_json and notice.registration_id != registration_id:
notice_json['added'] = True
if notice_json:
notices_list.append(notice.json)
return notices_list

def validate_debtor_name(self, debtor_name_json, staff: bool = False):
"""Verify supplied debtor name when registering non-financing statements. Bypass the check for staff.
Debtor name match rules:
Expand Down
7 changes: 5 additions & 2 deletions ppr-api/src/ppr_api/models/registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class MiscellaneousTypes(BaseEnum):
MH_NOTICE = 'MN'
POC_NOTICE = 'PN'
WAGES_UNPAID = 'WL'
SECURITIES_NOTICE = 'SE'


class PPSATypes(BaseEnum):
Expand Down Expand Up @@ -152,6 +153,8 @@ class RegistrationTypes(BaseEnum):
trust_indenture = db.relationship('TrustIndenture', back_populates='registration', uselist=False)
court_order = db.relationship('CourtOrder', back_populates='registration', uselist=False)
verification_report = db.relationship('VerificationReport', back_populates='registration', uselist=False)
securities_act_notices = db.relationship('SecuritiesActNotice', order_by='asc(SecuritiesActNotice.id)',
back_populates='registration')

document_number: str = None

Expand Down Expand Up @@ -539,7 +542,6 @@ def find_all_by_account_id_api_filter(cls, params: AccountRegistrationParams, ne
results = db.session.execute(text(query), query_params)
rows = results.fetchall()
results_json = registration_utils.update_account_reg_results(params, rows, results_json, True)

return results_json

@classmethod
Expand Down Expand Up @@ -791,7 +793,8 @@ def create_financing_from_json(json_data, account_id: str = None, user_id: str =
else:
draft.draft = json_data
registration.draft = draft

if reg_type == model_utils.REG_TYPE_SECURITIES_NOTICE and json_data.get('securitiesActNotices'):
registration = registration_utils.create_securities_act_notices(registration, json_data)
return registration

@staticmethod
Expand Down
Loading

0 comments on commit 91bb978

Please sign in to comment.