def test_incorporation_application_pending_documents(app): """Assert that pending incorporation application documents are returned.""" with app.app_context(): filing = { 'filing': { 'header': { 'filingId': 12356, 'status': 'PAID', 'name': 'incorporationApplication', 'availableOnPaperOnly': False, 'effectiveDate': LegislationDatetime.now().isoformat(), 'date': LegislationDatetime.now().isoformat() }, 'business': { 'identifier': 'BC1234567' } } } documents = document_meta.get_documents(filing) assert len(documents) == 1 assert documents[0]['type'] == 'REPORT' assert documents[0]['reportType'] is None assert documents[0]['filingId'] == filing['filing']['header'][ 'filingId'] assert documents[0]['title'] == 'Incorporation Application - Pending' business_identifier = filing['filing']['business']['identifier'] filing_date = filing['filing']['header']['date'] filename = document_meta.get_general_filename( business_identifier, 'Incorporation Application (Pending)', filing_date, 'pdf') assert documents[0]['filename'] == filename
def _set_dates(self, filing): # Filing Date filing_datetime = LegislationDatetime.as_legislation_timezone(self._filing.filing_date) hour = filing_datetime.strftime('%I').lstrip('0') filing['filing_date_time'] = filing_datetime.strftime(f'%B %-d, %Y at {hour}:%M %p Pacific Time') # Effective Date effective_date = filing_datetime if self._filing.effective_date is None \ else LegislationDatetime.as_legislation_timezone(self._filing.effective_date) effective_hour = effective_date.strftime('%I').lstrip('0') filing['effective_date_time'] = effective_date.strftime(f'%B %-d, %Y at {effective_hour}:%M %p Pacific Time') filing['effective_date'] = effective_date.strftime('%B %-d, %Y') # Recognition Date if self._business: recognition_datetime = LegislationDatetime.as_legislation_timezone(self._business.founding_date) recognition_hour = recognition_datetime.strftime('%I').lstrip('0') filing['recognition_date_time'] = \ recognition_datetime.strftime(f'%B %-d, %Y at {recognition_hour}:%M %p Pacific Time') # For Annual Report - Set AGM date as the effective date if self._filing.filing_type == 'annualReport': agm_date_str = filing.get('annualReport', {}).get('annualGeneralMeetingDate', None) if agm_date_str: agm_date = datetime.fromisoformat(agm_date_str) filing['agm_date'] = agm_date.strftime('%B %-d, %Y') # for AR, the effective date is the AGM date filing['effective_date'] = agm_date.strftime('%B %-d, %Y') else: filing['agm_date'] = 'No AGM' if filing.get('correction'): original_filing = Filing.find_by_id(filing.get('correction').get('correctedFilingId')) original_filing_datetime = LegislationDatetime.as_legislation_timezone(original_filing.filing_date) original_filing_hour = original_filing_datetime.strftime('%I').lstrip('0') filing['original_filing_date_time'] = original_filing_datetime. \ strftime(f'%B %-d, %Y at {original_filing_hour}:%M %p Pacific Time')
def as_effective_date(date_time: datetime) -> datetime: """Convert date_time to an effective date with 0 time in the legislation timezone, same as the UI does.""" # 1. convert to legislation datetime # 2. zero out the time # 3. convert back to a UTC datetime date_time = LegislationDatetime.as_legislation_timezone(date_time) date_time = date_time.replace(hour=0, minute=0, second=0, microsecond=0) return LegislationDatetime.as_utc_timezone(date_time)
def test_incorporation_application_documents(app): """Assert that incorporation documents are returned.""" with app.app_context(): filing = { 'filing': { 'header': { 'filingId': 12356, 'status': 'COMPLETED', 'name': 'incorporationApplication', 'availableOnPaperOnly': False, 'effectiveDate': LegislationDatetime.now().isoformat(), 'date': LegislationDatetime.now().isoformat() }, 'business': { 'identifier': 'BC1234567' } } } documents = document_meta.get_documents(filing) assert len(documents) == 3 assert documents[0]['type'] == 'REPORT' assert documents[0]['reportType'] is None assert documents[0]['filingId'] == filing['filing']['header'][ 'filingId'] assert documents[0]['title'] == 'Incorporation Application' business_identifier = filing['filing']['business']['identifier'] filing_date = filing['filing']['header']['date'] ia_filename = document_meta.get_general_filename( business_identifier, 'Incorporation Application', filing_date, 'pdf') noa_filename = document_meta.get_general_filename( business_identifier, 'Notice of Articles', filing_date, 'pdf') certificate_filename = document_meta.get_general_filename( business_identifier, 'Certificate', filing_date, 'pdf') assert documents[0]['filename'] == ia_filename assert documents[1]['type'] == 'REPORT' assert documents[1]['reportType'] == 'noa' assert documents[1]['filingId'] == filing['filing']['header'][ 'filingId'] assert documents[1]['title'] == 'Notice of Articles' assert documents[1]['filename'] == noa_filename assert documents[2]['type'] == 'REPORT' assert documents[2]['reportType'] == 'certificate' assert documents[2]['filingId'] == filing['filing']['header'][ 'filingId'] assert documents[2]['title'] == 'Certificate' assert documents[2]['filename'] == certificate_filename
def _populate_business_info_to_filing(filing: Filing, business: Business): founding_datetime = LegislationDatetime.as_legislation_timezone( business.founding_date) if filing.transaction_id: business_json = VersionedBusinessDetailsService.get_business_revision( filing.transaction_id, business) else: business_json = business.json() business_json[ 'formatted_founding_date_time'] = LegislationDatetime.format_as_report_string( founding_datetime) business_json['formatted_founding_date'] = founding_datetime.strftime( '%B %-d, %Y') filing.filing_json['filing']['business'] = business_json filing.filing_json['filing']['header']['filingId'] = filing.id
def test_ar_documents(app): """Assert that annual report documents are returned.""" with app.app_context(): filing = { 'filing': { 'header': { 'filingId': 12356, 'status': 'COMPLETED', 'name': 'annualReport', 'availableOnPaperOnly': False, 'date': LegislationDatetime.now().isoformat() }, 'business': { 'identifier': 'BC1234567' } } } documents = document_meta.get_documents(filing) assert len(documents) == 1 assert documents[0]['type'] == 'REPORT' assert documents[0]['reportType'] is None assert documents[0]['filingId'] == filing['filing']['header'][ 'filingId'] assert documents[0]['title'] == 'Annual Report' business_identifier = filing['filing']['business']['identifier'] filing_date = filing['filing']['header']['date'] filename = document_meta.get_general_filename(business_identifier, 'Annual Report', filing_date, 'pdf') assert documents[0]['filename'] == filename
def test_coa_future_effective(session, client, jwt): """Assert future effective changes do not affect Coops, and that BCORP change of address if future-effective.""" coa = copy.deepcopy(FILING_HEADER) coa['filing']['header']['name'] = 'changeOfAddress' coa['filing']['changeOfAddress'] = CHANGE_OF_ADDRESS coa['filing']['changeOfAddress']['offices']['registeredOffice'][ 'deliveryAddress']['addressCountry'] = 'CA' coa['filing']['changeOfAddress']['offices']['registeredOffice'][ 'mailingAddress']['addressCountry'] = 'CA' identifier = 'CP1234567' b = factory_business(identifier, (datetime.utcnow() - datedelta.YEAR), None) factory_business_mailing_address(b) rv = client.post(f'/api/v1/businesses/{identifier}/filings', json=coa, headers=create_header(jwt, [STAFF_ROLE], identifier)) assert rv.status_code == HTTPStatus.CREATED # assert 'effectiveDate' not in rv.json['filing']['header'] identifier = 'CP7654321' bc = factory_business(identifier, (datetime.utcnow() - datedelta.YEAR), None, Business.LegalTypes.BCOMP.value) factory_business_mailing_address(bc) coa['filing']['business']['identifier'] = identifier rv = client.post(f'/api/v1/businesses/{identifier}/filings', json=coa, headers=create_header(jwt, [STAFF_ROLE], identifier)) assert rv.status_code == HTTPStatus.CREATED assert 'effectiveDate' in rv.json['filing']['header'] effective_date = parse(rv.json['filing']['header']['effectiveDate']) valid_date = LegislationDatetime.tomorrow_midnight() assert effective_date == valid_date
def get_general_filename(business_identifier: str, name: str, filing_date: str, file_extension: str): """Return a general filename string.""" filing_date_str = LegislationDatetime.format_as_legislation_date( filing_date) file_name = f'{business_identifier} - {name} - {filing_date_str}.{file_extension}' return file_name
def create_registrars_stamp(cls, registrars_signature_image, incorp_date, incorp_num): """Create a Registrar's stamp to certify documents.""" buffer = io.BytesIO() can = canvas.Canvas(buffer, pagesize=letter) doc_width = letter[0] doc_height = letter[1] image_x_margin = doc_width - 130 image_y_margin = doc_height - 150 can.drawImage(registrars_signature_image, image_x_margin, image_y_margin, width=100, preserveAspectRatio=True, mask='auto') text = 'Filed on ' + LegislationDatetime.format_as_report_string(incorp_date) \ + '\nIncorporation Number: ' + incorp_num text_x_margin = 32 text_y_margin = doc_height - 42 line_height = 14 can.setFont('BCSans', 10) _write_text(can, text, line_height, text_x_margin, text_y_margin) can.showPage() can.save() buffer.seek(0) return buffer
def get_filing_info(filing_id: str) -> (Filing, dict, dict, str, str): """Get filing info for the email.""" filing = Filing.find_by_id(filing_id) business = (filing.json)['filing']['business'] filing_date = datetime.fromisoformat(filing.filing_date.isoformat()) leg_tmz_filing_date = LegislationDatetime.as_legislation_timezone(filing_date) hour = leg_tmz_filing_date.strftime('%I').lstrip('0') leg_tmz_filing_date = leg_tmz_filing_date.strftime(f'%B %d, %Y {hour}:%M %p Pacific Time') effective_date = datetime.fromisoformat(filing.effective_date.isoformat()) leg_tmz_effective_date = LegislationDatetime.as_legislation_timezone(effective_date) hour = leg_tmz_effective_date.strftime('%I').lstrip('0') leg_tmz_effective_date = leg_tmz_effective_date.strftime(f'%B %d, %Y {hour}:%M %p Pacific Time') return filing, business, leg_tmz_filing_date, leg_tmz_effective_date
def validate_effective_date(business: Business, cod: Dict) -> List: """Return an error or warning message based on the effective date validation rules. Rules: (text from the BA rules document) - The effective date of change cannot be in the future. - The effective date cannot be a date prior to their Incorporation Date. - The effective date of change cannot be a date that is farther in the past than a previous COD filing (standalone or AR). - The effective date can be the same effective date as another COD filing (standalone or AR). If this is the case: - COD filing that was filed most recently is the most current director information. """ msg = [] # get effective datetime string from filing try: effective_datetime_str = cod['filing']['header']['effectiveDate'] except KeyError: return {'error': babel('No effective date provided.')} # convert string to datetime try: effective_datetime_utc = datetime.fromisoformat(effective_datetime_str) except ValueError: return {'error': babel('Invalid ISO format for effective date.')} # check if effective datetime is in the future if effective_datetime_utc > datetime.utcnow(): msg.append({'error': babel('Filing cannot have a future effective date.')}) # convert to legislation timezone and then get date only effective_date_leg = LegislationDatetime.as_legislation_timezone(effective_datetime_utc).date() # check if effective date is before their incorporation date founding_date_leg = LegislationDatetime.as_legislation_timezone(business.founding_date).date() if effective_date_leg < founding_date_leg: msg.append({'error': babel('Effective date cannot be before businesses founding date.')}) # check if effective date is before their most recent COD or AR date last_cod_filing = Filing.get_most_recent_legal_filing(business.id, Filing.FILINGS['changeOfDirectors']['name']) if last_cod_filing: last_cod_date_leg = LegislationDatetime.as_legislation_timezone(last_cod_filing.effective_date).date() if effective_date_leg < last_cod_date_leg: msg.append({'error': babel('Effective date cannot be before another Change of Director filing.')}) return msg
def test_validate_cod_basic(session, test_name, now, delivery_region_1, delivery_country_1, delivery_region_2, delivery_country_2, expected_code, expected_msg): # pylint: disable=too-many-arguments """Assert that a basic COD can be validated.""" # setup identifier = 'CP1234567' founding_date = now - datedelta.YEAR business = Business(identifier=identifier, last_ledger_timestamp=founding_date, founding_date=founding_date) # convert 'now' to an effective date with 0 time in the legislation timezone, same as the UI does effective_date = LegislationDatetime.as_legislation_timezone(now) effective_date = effective_date.replace(hour=0, minute=0, second=0, microsecond=0) effective_date = LegislationDatetime.as_utc_timezone(effective_date) f = copy.deepcopy(FILING_HEADER) f['filing']['header']['date'] = now.date().isoformat() f['filing']['header']['effectiveDate'] = effective_date.isoformat() f['filing']['header']['name'] = 'changeOfDirectors' f['filing']['business']['identifier'] = identifier cod = copy.deepcopy(CHANGE_OF_DIRECTORS) cod['directors'][0]['deliveryAddress'][ 'addressCountry'] = delivery_country_1 cod['directors'][0]['deliveryAddress']['addressRegion'] = delivery_region_1 cod['directors'][1]['deliveryAddress'][ 'addressCountry'] = delivery_country_2 cod['directors'][1]['deliveryAddress']['addressRegion'] = delivery_region_2 f['filing']['changeOfDirectors'] = cod # perform test with freeze_time(now): err = validate(business, f) if err: print(err.msg) # validate outcomes if expected_code: assert err.code == expected_code assert lists_are_equal(err.msg, expected_msg) else: assert err is None
def test_name_request_update_expiration(app, client): """Assert that nr expiration can be updated.""" with app.app_context(): nr_original = namex.query_nr_number('NR 2772704') effective_date = LegislationDatetime.tomorrow_midnight() # expecting a buffer in the date to make sure future effective filings have time to process effective_date = (effective_date + datedelta.datedelta(days=1)).astimezone(pytz.timezone('GMT')) expected_date_string = effective_date.strftime(namex.DATE_FORMAT) nr_response = namex.update_nr_as_future_effective(nr_original.json(), LegislationDatetime.tomorrow_midnight()) json = nr_response.json() # check if expiration is extended assert json['expirationDate'] == expected_date_string # revert to original json nr_response = namex.update_nr(nr_original.json()) assert nr_response.json()['expirationDate'] == nr_original.json()['expirationDate']
def test_nr_notification(app, session, option, nr_number, subject, expiration_date, refund_value, expected_legal_name, names): """Assert that the nr notification can be processed.""" nr_json = { 'expirationDate': expiration_date, 'names': names, 'applicants': { 'emailAddress': '*****@*****.**' } } nr_response = MockResponse(nr_json, 200) token = 'token' # run worker with patch.object(AccountService, 'get_bearer_token', return_value=token): with patch.object(NameXService, 'query_nr_number', return_value=nr_response) \ as mock_query_nr_number: with patch.object(worker, 'send_email', return_value='success') as mock_send_email: worker.process_email( { 'id': '123456789', 'type': 'bc.registry.names.request', 'source': f'/requests/{nr_number}', 'identifier': nr_number, 'data': { 'request': { 'nrNum': nr_number, 'option': option, 'refundValue': refund_value } } }, app) call_args = mock_send_email.call_args assert call_args[0][0]['content'][ 'subject'] == f'{nr_number} - {subject}' assert call_args[0][0]['recipients'] == '*****@*****.**' assert call_args[0][0]['content']['body'] if option == nr_notification.Option.REFUND.value: assert f'${refund_value} CAD' in call_args[0][0][ 'content']['body'] assert call_args[0][0]['content']['attachments'] == [] assert mock_query_nr_number.call_args[0][0] == nr_number assert call_args[0][1] == token if option == nr_notification.Option.BEFORE_EXPIRY.value: assert nr_number in call_args[0][0]['content']['body'] assert expected_legal_name in call_args[0][0]['content'][ 'body'] exp_date = LegislationDatetime.format_as_report_string( datetime.fromisoformat(expiration_date)) assert exp_date in call_args[0][0]['content']['body']
def _populate_business_info_to_filing(filing: Filing, business: Business): founding_datetime = LegislationDatetime.as_legislation_timezone( business.founding_date) hour = founding_datetime.strftime('%I') business_json = business.json() business_json['formatted_founding_date_time'] = \ founding_datetime.strftime(f'%B %-d, %Y at {hour}:%M %p Pacific Time') business_json['formatted_founding_date'] = founding_datetime.strftime( '%B %-d, %Y') filing.filing_json['filing']['business'] = business_json filing.filing_json['filing']['header']['filingId'] = filing.id
def _get_receipt(business: Business, filing: Filing, token): """Get the receipt for the filing.""" if filing.status not in ( Filing.Status.PAID, Filing.Status.COMPLETED, Filing.Status.CORRECTED, ): return {}, HTTPStatus.BAD_REQUEST effective_date = None if filing.storage.effective_date.date() != filing.storage.filing_date.date( ): effective_date = (LegislationDatetime.as_legislation_timezone( filing.storage.effective_date).strftime(OUTPUT_DATE_FORMAT)) headers = {'Authorization': 'Bearer ' + token} url = f'{current_app.config.get("PAYMENT_SVC_URL")}/{filing.storage.payment_token}/receipts' receipt = requests.post( url, json={ 'corpName': business.legal_name if business else filing.storage.temp_reg, 'filingDateTime': (LegislationDatetime.as_legislation_timezone( filing.storage.filing_date).strftime(OUTPUT_DATE_FORMAT)), 'effectiveDateTime': effective_date if effective_date else '', 'filingIdentifier': str(filing.id), 'businessNumber': business.tax_id if business and business.tax_id else '' }, headers=headers) if receipt.status_code != HTTPStatus.CREATED: current_app.logger.error('Failed to get receipt pdf for filing: %s', filing.id) return receipt.content, receipt.status_code
def _format_incorporation_data(self, filing, report_type): filing['header']['reportType'] = report_type filing['header']['filingId'] = self._filing.id filing_datetime = LegislationDatetime.as_legislation_timezone( self._filing.filing_date) effective_date_time = LegislationDatetime.as_legislation_timezone( self._filing.effective_date) effective_hour = effective_date_time.strftime('%I') filing_hour = filing_datetime.strftime('%I') filing['header']['effective_date_time'] = \ effective_date_time.strftime(f'%B %-d, %Y at {effective_hour}:%M %p Pacific Time') filing['header']['filing_date_time'] = \ filing_datetime.strftime(f'%B %-d, %Y at {filing_hour}:%M %p Pacific Time') filing['filing_date_time'] = filing_datetime.strftime( f'%B %d, %Y {filing_hour}:%M %p Pacific Time') self._format_address(filing['incorporationApplication']['offices'] ['registeredOffice']['deliveryAddress']) self._format_address(filing['incorporationApplication']['offices'] ['registeredOffice']['mailingAddress']) self._format_address(filing['incorporationApplication']['offices'] ['recordsOffice']['deliveryAddress']) self._format_address(filing['incorporationApplication']['offices'] ['recordsOffice']['mailingAddress']) self._format_directors(filing['incorporationApplication']['parties'])
def get_incorporation_application_report(self, filing: dict): """Return a incoporation application report document meta object.""" filing_id = filing_id = filing['filing']['header']['filingId'] business_identifier = filing['filing']['business']['identifier'] filing_date = filing['filing']['header']['date'] filing_status = filing['filing']['header']['status'] is_fed = LegislationDatetime.is_future( filing['filing']['header']['effectiveDate']) ia_name = 'Incorporation Application' certificate_name = 'Certificate' noa_name = 'Notice of Articles' if is_fed: return [ self.create_report_object( filing_id, f'{ia_name} - Future Effective Incorporation', self.get_general_filename(business_identifier, f'{ia_name} (Future Effective)', filing_date, 'pdf')) ] if filing_status == Filing.Status.PAID.value: return [ self.create_report_object( filing_id, f'{ia_name} - Pending', self.get_general_filename(business_identifier, f'{ia_name} (Pending)', filing_date, 'pdf')) ] return [ self.create_report_object( filing_id, 'Incorporation Application', self.get_general_filename(business_identifier, 'Incorporation Application', filing_date, 'pdf')), self.create_report_object( filing_id, noa_name, self.get_general_filename(business_identifier, 'Notice of Articles', filing_date, 'pdf'), DocumentMetaService.ReportType.NOTICE_OF_ARTICLES.value), self.create_report_object( filing_id, certificate_name, self.get_general_filename(business_identifier, 'Certificate', filing_date, 'pdf'), DocumentMetaService.ReportType.CERTIFICATE.value) ]
def get_incorporation_application_reports(self, filing: dict): """Return incorporation application meta object(s).""" is_fed = LegislationDatetime.is_future( filing['filing']['header']['effectiveDate']) # return FED instead of PAID or COMPLETED if is_fed: return [ self.create_report_object( 'Incorporation Application - Future Effective Incorporation', self.get_general_filename( 'Incorporation Application (Future Effective)')) ] if self.is_paid(): return [ self.create_report_object( 'Incorporation Application - Pending', self.get_general_filename( 'Incorporation Application (Pending)')) ] filing_data = Filing.find_by_id(filing['filing']['header']['filingId']) has_corrected = filing_data.parent_filing_id is not None # Identify whether it is corrected label_original = ' (Original)' if has_corrected else '' label_certificate_original = ' (Original)' if has_corrected and NameXService.\ has_correction_changed_name(Filing.find_by_id(filing_data.parent_filing_id).json) else '' # else status is COMPLETED return [ self.create_report_object( f'Incorporation Application{label_original}', self.get_general_filename( f'Incorporation Application{label_original}')), self.create_report_object( DocumentMetaService.NOTICE_OF_ARTICLES, self.get_general_filename( DocumentMetaService.NOTICE_OF_ARTICLES), DocumentMetaService.ReportType.NOTICE_OF_ARTICLES.value), self.create_report_object( f'Certificate{label_certificate_original}', self.get_general_filename( f'Certificate{label_certificate_original}'), DocumentMetaService.ReportType.CERTIFICATE.value) ]
def test_coa_paid_documents_empty(app): """Assert that no documents are returned for a not complete change of address.""" with app.app_context(): filing = { 'filing': { 'header': { 'filingId': 12356, 'status': 'PAID', 'name': 'changeOfAddress', 'availableOnPaperOnly': False, 'date': LegislationDatetime.now().isoformat() }, 'business': { 'identifier': 'BC1234567' } } } assert len(document_meta.get_documents(filing)) == 0
def test_paper_only_documents_empty(app): """Assert that no documents are returned for non PAID and COMPLETED filing.""" with app.app_context(): filing = { 'filing': { 'header': { 'filingId': 12356, 'status': 'COMPLETED', 'name': 'changeOfAddress', 'availableOnPaperOnly': True, 'date': LegislationDatetime.now().isoformat() }, 'business': { 'identifier': 'BC1234567' } } } assert len(document_meta.get_documents(filing)) == 0
def _set_effective_date(business: Business, filing: Filing): filing_type = filing.filing_json['filing']['header']['name'] if filing_type == Filing.FILINGS['incorporationApplication'].get( 'name'): fe_date = filing.filing_json['filing']['header'].get( 'futureEffectiveDate') if fe_date: filing.effective_date = datetime.datetime.fromisoformat( fe_date) filing.save() elif business.legal_type != Business.LegalTypes.COOP.value: if filing_type == 'changeOfAddress': effective_date = LegislationDatetime.tomorrow_midnight() filing.filing_json['filing']['header'][ 'futureEffectiveDate'] = effective_date filing.effective_date = effective_date filing.save()
def test_ia_fed(app): """Assert that an IA - FED document is returned for a future effective IA filing.""" from legal_api.utils.legislation_datetime import LegislationDatetime document_meta = DocumentMetaService() with app.app_context(): filing = { 'filing': { 'header': { 'filingId': 12356, 'status': 'PAID', 'name': 'incorporationApplication', 'inColinOnly': False, 'availableOnPaperOnly': False, 'effectiveDate': LegislationDatetime.tomorrow_midnight().isoformat(), 'date': FILING_DATE }, 'business': { 'identifier': 'T12345678' }, 'incorporationApplication': { 'nameRequest': { 'legalType': Business.LegalTypes.BCOMP.value } } } } documents = document_meta.get_documents(filing) assert len(documents) == 1 assert documents[0]['type'] == 'REPORT' assert documents[0]['reportType'] is None assert documents[0]['filingId'] == 12356 assert documents[0][ 'title'] == 'Incorporation Application - Future Effective Incorporation' assert documents[0][ 'filename'] == 'T12345678 - Incorporation Application (Future Effective) - 2020-07-14.pdf'
def test_stamp(app): # pylint:disable=unused-argument """Assert that stamp service is working.""" with app.app_context(): pdf_input = _create_pdf_file() incorp_date = LegislationDatetime.now() registrar_info = RegistrarInfo.get_registrar_info(incorp_date) registrars_signature = registrar_info['signatureAndText'] pdf_service = PdfService() registrars_stamp = pdf_service.create_registrars_stamp( registrars_signature, incorp_date, 'CP00000001') certified_copy = pdf_service.stamp_pdf(pdf_input, registrars_stamp, only_first_page=True) certified_copy_obj = PyPDF2.PdfFileReader(certified_copy) certified_copy_page = certified_copy_obj.getPage(0) text = certified_copy_page.extractText() assert 'Filed on' in text certified_copy_page = certified_copy_obj.getPage(1) text = certified_copy_page.extractText() assert 'Filed on' not in text
def _replace_file_with_certified_copy(_bytes, business, key): open_pdf_file = io.BytesIO(_bytes) pdf_reader = PyPDF2.PdfFileReader(open_pdf_file) pdf_writer = PyPDF2.PdfFileWriter() pdf_writer.appendPagesFromReader(pdf_reader) output_original_pdf = io.BytesIO() pdf_writer.write(output_original_pdf) output_original_pdf.seek(0) registrar_info = RegistrarInfo.get_registrar_info(business.founding_date) registrars_signature = registrar_info['signatureAndText'] pdf_service = PdfService() registrars_stamp = \ pdf_service.create_registrars_stamp(registrars_signature, LegislationDatetime.as_legislation_timezone(business.founding_date), business.identifier) certified_copy = pdf_service.stamp_pdf(output_original_pdf, registrars_stamp, only_first_page=True) MinioService.put_file(key, certified_copy, certified_copy.getbuffer().nbytes) return key
def _set_dates(self, filing): filing_datetime = LegislationDatetime.as_legislation_timezone( self._filing.filing_date) hour = filing_datetime.strftime('%I').lstrip('0') filing['filing_date_time'] = filing_datetime.strftime( f'%B %d, %Y {hour}:%M %p Pacific Time') # Get the effective date effective_date = filing_datetime if self._filing.effective_date is None \ else self._filing.effective_date # TODO: best: custom date/time filters in the report-api. Otherwise: a subclass for filing-specific data. if self._filing.filing_type == 'annualReport': agm_date_str = filing.get('annualReport', {}).get('annualGeneralMeetingDate', None) if agm_date_str: agm_date = datetime.fromisoformat(agm_date_str) filing['agm_date'] = agm_date.strftime('%B %d, %Y') # for AR, the effective date is the AGM date filing['effective_date'] = agm_date.strftime('%B %d, %Y') else: filing['agm_date'] = 'No AGM' elif self._filing.filing_type in ('changeOfAddress', 'changeOfDirectors'): # for standalone filings, the effective date comes from the filing data filing['effective_date'] = effective_date.strftime('%B %d, %Y')
def get_general_filename(self, name: str): """Return a general filename string.""" filing_date_str = LegislationDatetime.format_as_legislation_date( self._filing_date) file_name = f'{self._business_identifier} - {name} - {filing_date_str}.pdf' return file_name
def json(self): """Return the Business as a json object. None fields are not included. """ ar_min_date, ar_max_date = self.get_ar_dates(( self.last_ar_year if self.last_ar_year else self.founding_date.year ) + 1) d = { 'arMinDate': ar_min_date.isoformat(), 'arMaxDate': ar_max_date.isoformat(), 'foundingDate': self.founding_date.isoformat(), 'goodStanding': self.good_standing, 'hasRestrictions': self.restriction_ind, 'identifier': self.identifier, 'lastAnnualGeneralMeetingDate': datetime.date(self.last_agm_date).isoformat() if self.last_agm_date else '', 'lastAnnualReportDate': datetime.date(self.last_ar_date).isoformat() if self.last_ar_date else '', 'lastLedgerTimestamp': self.last_ledger_timestamp.isoformat(), 'lastAddressChangeDate': '', 'lastDirectorChangeDate': '', 'lastModified': self.last_modified.isoformat(), 'legalName': self.legal_name, 'legalType': self.legal_type, 'nextAnnualReport': LegislationDatetime.as_legislation_timezone_from_date( self.next_anniversary).astimezone(timezone.utc).isoformat(), } if self.last_coa_date: d['lastAddressChangeDate'] = datetime.date( LegislationDatetime.as_legislation_timezone( self.last_coa_date)).isoformat() if self.last_cod_date: d['lastDirectorChangeDate'] = datetime.date( LegislationDatetime.as_legislation_timezone( self.last_cod_date)).isoformat() if self.dissolution_date: d['dissolutionDate'] = datetime.date( self.dissolution_date).isoformat() if self.fiscal_year_end_date: d['fiscalYearEndDate'] = datetime.date( self.fiscal_year_end_date).isoformat() if self.tax_id: d['taxId'] = self.tax_id return d
def process(email_info: dict, option) -> dict: # pylint: disable-msg=too-many-locals """ Build the email for Name Request notification. valid values of option: Option """ logger.debug('NR %s notification: %s', option, email_info) nr_number = email_info['identifier'] template = Path(f'{current_app.config.get("TEMPLATE_PATH")}/NR-{option.upper()}.html').read_text() filled_template = substitute_template_parts(template) nr_response = NameXService.query_nr_number(nr_number) if nr_response.status_code != HTTPStatus.OK: logger.error('Failed to get nr info for name request: %s', nr_number) capture_message(f'Email Queue: nr_id={nr_number}, error=receipt generation', level='error') return {} nr_data = nr_response.json() expiration_date = '' if nr_data['expirationDate']: exp_date = datetime.fromisoformat(nr_data['expirationDate']) expiration_date = LegislationDatetime.format_as_report_string(exp_date) refund_value = '' if option == Option.REFUND.value: refund_value = email_info.get('data', {}).get('request', {}).get('refundValue', None) legal_name = '' for n_item in nr_data['names']: if n_item['state'] in ('APPROVED', 'CONDITION'): legal_name = n_item['name'] break # render template with vars mail_template = Template(filled_template, autoescape=True) html_out = mail_template.render( nr_number=nr_number, expiration_date=expiration_date, legal_name=legal_name, refund_value=refund_value ) # get recipients recipients = nr_data['applicants']['emailAddress'] if not recipients: return {} subjects = { Option.BEFORE_EXPIRY.value: 'Expiring Soon', Option.EXPIRED.value: 'Expired', Option.RENEWAL.value: 'Confirmation of Renewal', Option.UPGRADE.value: 'Confirmation of Upgrade', Option.REFUND.value: 'Refund request confirmation' } return { 'recipients': recipients, 'requestBy': '*****@*****.**', 'content': { 'subject': f'{nr_number} - {subjects[option]}', 'body': f'{html_out}', 'attachments': [] } }
return { 'message': 'unable to create invoice for payment.' }, HTTPStatus.PAYMENT_REQUIRED @staticmethod def set_effective_date(business: Business, filing: Filing): """Set the effective date of the Filing.""" filing_type = filing.filing_json['filing']['header']['name'] if filing_type == Filing.FILINGS['incorporationApplication'].get('name') and \ (fe_date := filing.filing_json['filing']['header'].get('futureEffectiveDate')): filing.effective_date = datetime.datetime.fromisoformat(fe_date) filing.save() elif business.legal_type != Business.LegalTypes.COOP.value and filing_type == 'changeOfAddress': effective_date = LegislationDatetime.tomorrow_midnight() filing.filing_json['filing']['header'][ 'futureEffectiveDate'] = effective_date filing.effective_date = effective_date filing.save() @staticmethod def is_future_effective_filing(filing_json: dict) -> bool: """Return True if the filing is a FED.""" is_future_effective = False effective_date = datetime.datetime.fromisoformat(filing_json['filing']['header']['effectiveDate']) \ if filing_json['filing']['header'].get('effectiveDate', None) else None if effective_date: is_future_effective = effective_date > datetime.datetime.utcnow( ).replace(tzinfo=datetime.timezone.utc) return is_future_effective