Skip to content

Commit

Permalink
22502 - furnishings job - generate BCMail+ batch letter (bcgov#2961)
Browse files Browse the repository at this point in the history
* 22502-3 main changes for furnishings job

Signed-off-by: Hongjing Chen <[email protected]>

* add report templates & move xml template

Signed-off-by: Hongjing Chen <[email protected]>

* tweak some loggings

Signed-off-by: Hongjing Chen <[email protected]>

---------

Signed-off-by: Hongjing Chen <[email protected]>
  • Loading branch information
chenhongjing authored Sep 5, 2024
1 parent 36d3525 commit 7468c97
Show file tree
Hide file tree
Showing 21 changed files with 1,743 additions and 18 deletions.
7 changes: 7 additions & 0 deletions jobs/furnishings/devops/vaults.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,12 @@
"entity-service-account",
"furnishings"
]
},
{
"vault": "api",
"application": [
"mras-api",
"report-api-gotenberg"
]
}
]
39 changes: 39 additions & 0 deletions jobs/furnishings/report-templates/dissolutionCover.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Cover for Dissolution/Cancellation Letter</title>
<meta charset="UTF-8">
<meta name="author" content="BC Registries and Online Services">
[[common/v2/styleMail.html]]
</head>
<body>
<div class="cover-container">
<div class="cover-header">
<span>Dissolution / Cancellation Letter<span>
</div>

<table class="cover-statistics">
<tr>
<td class="bold">Number of Letters:</td>
<td>{{ letterCount }}</td>
</tr>
<tr>
<td class="bold">Report Run Date:</td>
<td>{{ reportDate }}</td>
</tr>
<tr>
<td class="bold">Report Batch ID:</td>
<td>{{ customBatchId }}</td>
</tr>
<tr>
<td class="bold">Report Page Count:</td>
<td>{{ pageCount }}</td>
</tr>
</table>

<div class="cover-environment upper-text">
{{ environment }}
</div>
</div>
</body>
</html>
108 changes: 108 additions & 0 deletions jobs/furnishings/report-templates/noticeOfDissolutionCommencement.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Notice of Commencement of Dissolution</title>
<meta charset="UTF-8">
<meta name="author" content="BC Registries and Online Services">
{% if variant == 'default' %}
[[common/v2/style.html]]
{% else %}
[[common/v2/styleMail.html]]
{% endif %}
</head>
<body>
<div class="letter-copy">
{% if furnishing.mailingAddress %}
<div class="container address-container ml-3">
{% if furnishing.mailingAddress.streetAddressAdditional %}
<div class="address-container-additional-info">
{% else %}
<div class="address-container-no-additional-info">
{% endif %}
<div>{{ furnishing.businessName }}</div>
<div>{{ furnishing.mailingAddress.streetAddress }}</div>
<div>{{ furnishing.mailingAddress.streetAddressAdditional }}</div>
<div>
{{ furnishing.mailingAddress.addressCity }}
{{ furnishing.mailingAddress.addressRegion }}
&nbsp;&nbsp;{{ furnishing.mailingAddress.postalCode }}
</div>
</div>
</div>
{% endif %}
<div class="container letter-container ml-3">
{% if 'NO_AR' in furnishing.furnishingName %}
<div class="mt-5"><span class="bold">No Annual Reports Filed Since {{ furnishing.lastARDate }} for {{ furnishing.businessIdentifier }}</span></div>
<div class="mt-4">To file an annual report online, log in to your Business Page at <a href="https://www.business.bcregistry.gov.bc.ca/{{ furnishing.businessIdentifier }}" class="break-url">business.bcregistry.gov.bc.ca/<wbr>{{ furnishing.businessIdentifier }}</a> to file any outstanding annual reports listed.</div>
{% else %}
<div class="mt-5"><span class="bold">No Post Restoration Transition Application Filed Since {{ furnishing.lastARDate }} for {{ furnishing.businessIdentifier }}</span></div>
<div class="mt-4">To file a Post Restoration Transition Application (PRTA) online, log in to your Business Page at &nbsp;&nbsp; <a href="https://www.business.bcregistry.gov.bc.ca/{{ furnishing.businessIdentifier }}" class="break-url">business.bcregistry.gov.bc.ca/<wbr>{{ furnishing.businessIdentifier }}</a> to file any outstanding annual reports listed.</div>
{% endif %}
{% if 'NO_AR' in furnishing.furnishingName %}
{% if 'XPRO' in furnishing.furnishingName %}
<div class="mt-5">Under section 422 of the Business Corporation Act (the Act), this letter is to notify you that your extraprovincial company has for two years failed to file the annual reports required under section 51 of the Act. A company must annually, within two months after each anniversary of the date on which the company was recognized, file an annual report with the Registrar.</div>
<div class="mt-5">If within one month after the date of this letter, the company fails to file the outstanding annual reports, a notice may be published on the BC Laws website <a href="https://www.bclaws.gov.bc.ca/" class="break-url">www.bclaws.ca</a>. This notice will state that, at any time after the expiration of one month after the date of publication of the notice, the company will be cancelled, unless cause is shown to the contrary; I am satisfied the failure has been or is being remedied; or a copy of the entered court order to the contrary has been filed.</div>
{% else %}
<div class="mt-5">Under section 422 of the Business Corporation Act (the Act), this letter is to notify you that your company has for two years failed to file the annual reports required under section 51 of the Act. A company must annually, within two months after each anniversary of the date on which the company was recognized, file an annual report with the Registrar.</div>
<div class="mt-5">If within one month after the date of this letter, the company fails to file the outstanding annual reports, a notice may be published on the BC Laws website <a href="https://www.bclaws.gov.bc.ca/" class="break-url">www.bclaws.ca</a>. This notice will state that, at any time after the expiration of one month after the date of publication of the notice, the company will be dissolved, unless cause is shown to the contrary; I am satisfied the failure has been or is being remedied; or a copy of the entered court order to the contrary has been filed.</div>
{% endif %}
{% else %}
<div class="mt-5">Under section 422 of the Business Corporation Act (the Act), this letter is to notify you that your company has for two years failed to file the PRTA required under section 51 of the Act. A company must annually, within two months after each anniversary of the date on which the company was recognized, file a PRTA with the Registrar.</div>
<div class="mt-5">If within one month after the date of this letter, the company fails to file the outstanding PRTA, a notice may be published on the BC Laws website <a href="https://www.bclaws.gov.bc.ca/" class="break-url">www.bclaws.ca</a>. This notice will state that, at any time after the expiration of one month after the date of publication of the notice, the company will be dissolved, unless cause is shown to the contrary; I am satisfied the failure has been or is being remedied; or a copy of the entered court order to the contrary has been filed.</div>
{% endif %}

{% if furnishing.foreignRegistrations %}
<div class="mt-5">
Our records indicate your company is registered in
{% if furnishing.foreignRegistrations|length == 1 %}
{{ furnishing.foreignRegistrations[0] }}
{% elif furnishing.foreignRegistrations|length == 2 %}
{{ furnishing.foreignRegistrations[0] }} and {{ furnishing.foreignRegistrations[1] }}
{% else %}
{{ furnishing.foreignRegistrations[0] }}, {{ furnishing.foreignRegistrations[1] }}, and {{ furnishing.foreignRegistrations[2] }}
{% endif %}
as an extraprovincial company. Therefore, if your company is dissolved, its registration as an extraprovincial company in
{% if furnishing.foreignRegistrations|length == 1 %}
{{ furnishing.foreignRegistrations[0] }}
{% elif furnishing.foreignRegistrations|length == 2 %}
{{ furnishing.foreignRegistrations[0] }} and {{ furnishing.foreignRegistrations[1] }}
{% else %}
{{ furnishing.foreignRegistrations[0] }}, {{ furnishing.foreignRegistrations[1] }}, and {{ furnishing.foreignRegistrations[2] }}
{% endif %}
will automatically be cancelled as well.
</div>
{% endif %}

{% if 'NO_AR' in furnishing.furnishingName %}
{% if 'XPRO' in furnishing.furnishingName %}
<div class="mt-5">To request a delay of the cancellation, go to <a href="https://www.business.bcregistry.gov.bc.ca/{{ furnishing.businessIdentifier }}" class="break-url">business.bcregistry.gov.bc.ca/{{ furnishing.businessIdentifier }}</a> and request for a Delay of Dissolution or Cancellation under the To Do section. This must be completed prior to the dissolution of the company.</div>
<div class="mt-5">If your company is cancelled under section 422(1)(a) of the Act, section 347 of the Act states the liability of each director, officer, shareholder and liquidator of a company that is cancelled continues and may be enforced as if the company had not been cancelled.</div>
{% else %}
<div class="mt-5">To request a delay of the dissolution, go to <a href="https://www.business.bcregistry.gov.bc.ca/{{ furnishing.businessIdentifier }}" class="break-url">business.bcregistry.gov.bc.ca/{{ furnishing.businessIdentifier }}</a> and request for a Delay of Dissolution or Cancellation under the To Do section. This must be completed prior to the dissolution of the company.</div>
<div class="mt-5">If your company is dissolved under section 422(1)(a) of the Act, section 347 of the Act states the liability of each director, officer, shareholder and liquidator of a company that is dissolved continues and may be enforced as if the company had not been dissolved.</div>
{% endif %}
<div class="mt-5">If you have filed the outstanding annual reports, no further action is required.</div>
<div class="mt-5">If you need help with setting up an account or managing a business, please visit our Resources and Help page at <a href="https://bcreg.ca/resources" class="break-url">bcreg.ca/resources</a></div>
{% else %}
<div class="mt-5">To request a delay of the dissolution, go to <a href="https://www.business.bcregistry.gov.bc.ca/{{ furnishing.businessIdentifier }}" class="break-url">business.bcregistry.gov.bc.ca/{{ furnishing.businessIdentifier }}</a> and request for a Delay of Dissolution or Cancellation under the To Do section. This must be completed prior to the dissolution of the company.</div>
<div class="mt-5">If your company is dissolved under section 422(1)(a) of the Act, section 347 of the Act states the liability of each director, officer, shareholder and liquidator of a company that is dissolved continues and may be enforced as if the company had not been dissolved.</div>
<div class="mt-5">If you have filed the outstanding PRTA, no further action is required.</div>
<div class="mt-5">If you need help with setting up an account or managing a business, please visit our Resources and Help page at <a href="https://bcreg.ca/resources" class="break-url">bcreg.ca/resources</a></div>
{% endif %}

<p class="mt-5"><i><span class="bold">Issued</span> on my behalf on {{ furnishing.processedDate }}</i></p>
<div class="registrar-info">
<div>[[common/certificateRegistrarSignature.html]]</div>
<div>
<div class="registrar-name"><span class="bold">{{ registrarInfo.name }}</span></div>
<div class="registrar-title">{{ registrarInfo.title }}</div>
</div>
<div class="mt-2">
<div class="registry-info"><span class="bold">BC Registries and Online Services</span></div>
<div class="registry-contact"><span class="bold">Toll-Free Phone:</span> 1-877-526-1526</div>
</div>
</div>
</div>
</div>
</body>
</html>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div class="registrar-signature">
<img alt="signature" src={{registrarInfo.signature}}>
</div>

Large diffs are not rendered by default.

Large diffs are not rendered by default.

605 changes: 605 additions & 0 deletions jobs/furnishings/report-templates/template-parts/common/v2/style.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

10 changes: 9 additions & 1 deletion jobs/furnishings/src/furnishings/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,15 @@ class _Config: # pylint: disable=too-few-public-methods

SECOND_NOTICE_DELAY = int(os.getenv('SECOND_NOTICE_DELAY', '5'))
LEGISLATIVE_TIMEZONE = os.getenv('LEGISLATIVE_TIMEZONE', 'America/Vancouver')
TEMPLATE_PATH = os.getenv('TEMPLATE_PATH', 'src/furnishings-templates')
XML_TEMPLATE_PATH = os.getenv('XML_TEMPLATE_PATH', 'furnishings-templates')

# Letter - GCP Gotenberg report service
REPORT_API_GOTENBERG_AUDIENCE = os.getenv('REPORT_API_GOTENBERG_AUDIENCE', '')
REPORT_API_GOTENBERG_URL = os.getenv('REPORT_API_GOTENBERG_URL', 'https://')
REPORT_TEMPLATE_PATH = os.getenv('REPORT_PATH', 'report-templates')
# Letter - MRAS
MRAS_SVC_URL = os.getenv('MRAS_SVC_URL')
MRAS_SVC_API_KEY = os.getenv('MRAS_SVC_API_KEY')


class DevConfig(_Config): # pylint: disable=too-few-public-methods
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def _format_furnishings(self):
def _build_xml_data(xml_data, processed_time):
"""Build XML payload."""
template = Path(
f'{current_app.config.get("TEMPLATE_PATH")}/gazette-notice.xml'
f'{current_app.config.get("XML_TEMPLATE_PATH")}/gazette-notice.xml'
).read_text()
jinja_template = Template(template, autoescape=True)

Expand Down
52 changes: 41 additions & 11 deletions jobs/furnishings/src/furnishings/stage_processors/stage_one.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
import requests
from flask import Flask, current_app
from legal_api.models import Address, Batch, BatchProcessing, Business, Furnishing, db # noqa: I001
from legal_api.reports.report_v2 import ReportTypes
from legal_api.services.bootstrap import AccountService
from legal_api.services.furnishing_documents_service import FurnishingDocumentsService
from legal_api.services.involuntary_dissolution import InvoluntaryDissolutionService
from legal_api.services.queue import QueueService
from legal_api.utils.datetime import datetime as datetime_util
Expand All @@ -37,6 +39,11 @@ def __init__(self, app, qsm):
self._email_furnishing_group_id = None
self._mail_furnishing_group_id = None

self._bc_mail_furnishings = []
self._xpro_mail_furnishings = []
self._bc_letters = None
self._xpro_letters = None

async def process(self, batch_processing: BatchProcessing):
"""Process batch_processing entry."""
furnishings = Furnishing.find_by(
Expand Down Expand Up @@ -71,6 +78,23 @@ async def process(self, batch_processing: BatchProcessing):
if has_elapsed_email_entry and not has_mail_entry:
await self._send_second_round_notification(batch_processing)

def generate_paper_letters(self):
"""Generate merged paper letter with cover for BC/XPRO businesses."""
self._app.logger.debug('Start generating batch letters.')
try:
document_service = FurnishingDocumentsService(ReportTypes.DISSOLUTION, 'greyscale')
if self._bc_mail_furnishings:
self._app.logger.debug('Start generating BC batch letter.')
self._bc_letters = document_service.get_merged_furnishing_document(self._bc_mail_furnishings)
self._app.logger.debug('Finish generating BC batch letter.')
if self._xpro_mail_furnishings:
self._app.logger.debug('Start generating XPRO batch letter.')
self._xpro_letters = document_service.get_merged_furnishing_document(self._xpro_mail_furnishings)
self._app.logger.debug('Finish generating XPRO batch letter.')
except Exception as e:
self._app.logger.error(f'Error generating batch letters: {e}')
self._app.logger.debug('Finish generating batch letters.')

async def _send_first_round_notification(self, batch_processing: BatchProcessing, business: Business):
"""Process first round of notification(email/letter)."""
_, eligible_details = InvoluntaryDissolutionService.check_business_eligibility(
Expand All @@ -92,7 +116,8 @@ async def _send_first_round_notification(self, batch_processing: BatchProcessing
business.legal_name,
email
)
self._app.logger.debug(f'New furnishing has been created with ID (first round): {new_furnishing.id}')
self._app.logger.debug(
f'New furnishing has been created for {business.identifier} with ID (first round): {new_furnishing.id}')

mailing_address = business.mailing_address.one_or_none()
if mailing_address:
Expand All @@ -109,12 +134,12 @@ async def _send_first_round_notification(self, batch_processing: BatchProcessing
new_furnishing.save()
self._app.logger.debug(f'Changed furnishing type to MAIL for funishing with ID: {new_furnishing.id}')

# TODO: create and add letter to either AR or transition pdf
# TODO: send AR and transition pdf to BCMail+
new_furnishing.status = Furnishing.FurnishingStatus.PROCESSED
new_furnishing.processed_date = datetime.utcnow()
if business.legal_type == Business.LegalTypes.EXTRA_PRO_A.value:
self._xpro_mail_furnishings.append(new_furnishing)
else:
self._bc_mail_furnishings.append(new_furnishing)

new_furnishing.save()
self._app.logger.debug(f'Changed furnishing status to PROCESSED for funishing with ID: {new_furnishing.id}')

async def _send_second_round_notification(self, batch_processing: BatchProcessing):
"""Send paper letter if business is still not in good standing after 5 days of email letter sent out."""
Expand All @@ -134,17 +159,19 @@ async def _send_second_round_notification(self, batch_processing: BatchProcessin
business.last_ar_date if business.last_ar_date else business.founding_date,
business.legal_name
)
self._app.logger.debug(f'New furnishing has been created with ID (second round): {new_furnishing.id}')
self._app.logger.debug(
f'New furnishing has been created for {business.identifier} with ID (second round): {new_furnishing.id}')

mailing_address = business.mailing_address.one_or_none()
if mailing_address:
self._create_furnishing_address(mailing_address, new_furnishing.id)
self._app.logger.debug(f'Created address (second round) with furnishing ID: {new_furnishing.id}')

# TODO: create and add letter to either AR or transition pdf
# TODO: send AR and transition pdf to BCMail+
new_furnishing.status = Furnishing.FurnishingStatus.PROCESSED
new_furnishing.processed_date = datetime.utcnow()
if business.legal_type == Business.LegalTypes.EXTRA_PRO_A.value:
self._xpro_mail_furnishings.append(new_furnishing)
else:
self._bc_mail_furnishings.append(new_furnishing)

new_furnishing.save()

def _create_new_furnishing( # pylint: disable=too-many-arguments
Expand Down Expand Up @@ -291,6 +318,9 @@ async def process(app: Flask, qsm: QueueService): # pylint: disable=redefined-o

for batch_processing in batch_processings:
await processor.process(batch_processing)
processor.generate_paper_letters()
# TODO: send AR and transition pdf to BCMail+
# TODO: mark MAIL entries as PROCESSED/FAILED

except Exception as err:
app.logger.error(err)
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,10 @@ def process(app: Flask, xml_furnishings: dict):
business_name=business.legal_name
)
new_furnishing.save()
app.logger.debug(f'Created corp dissolved furnishing entry with ID: {new_furnishing.id}')
app.logger.debug(
f'Created corp dissolved furnishing entry for {new_furnishing.business_identifier} '
f'with ID: {new_furnishing.id}'
)

if business.legal_type != Business.LegalTypes.EXTRA_PRO_A.value:
bc_furnishings.append(new_furnishing)
Expand Down
Loading

0 comments on commit 7468c97

Please sign in to comment.