Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial implementation register Securities Act financing statement. #1847

Merged
merged 1 commit into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading