def test_conversion_coop_from_colin(app, session): """Assert that an existing coop incorporation is loaded corrrectly.""" # setup identifier = 'CP0000001' colind_id = 1 filing = copy.deepcopy(CONVERSION_FILING_TEMPLATE) # Change the template to be a CP == Cooperative filing['filing']['business']['legalType'] = 'CP' filing['filing']['business']['identifier'] = identifier filing['filing']['conversion']['nameRequest']['legalType'] = 'CP' filing['filing']['conversion'].pop('shareStructure') effective_date = datetime.utcnow() # Create the Filing obeject in the DB filing_rec = Filing(effective_date=effective_date, filing_json=filing) colin_event = ColinEventId() colin_event.colin_event_id=colind_id filing_rec.colin_event_ids.append(colin_event) # Override the state setting mechanism filing_rec.skip_status_listener = True filing_rec._status = 'PENDING' filing_rec.save() # test business, filing_rec = conversion.process(None, filing, filing_rec) # Assertions assert business.identifier == identifier assert business.founding_date.replace(tzinfo=None) == effective_date.replace(tzinfo=None) assert business.legal_type == filing['filing']['conversion']['nameRequest']['legalType'] assert business.legal_name == business.identifier[2:] + ' B.C. LTD.' assert len(business.offices.all()) == 2 # One office is created in create_business method.
def test_get_internal_filings(session, client, jwt): """Assert that the get_completed_filings_for_colin returns completed filings with no colin ids set.""" from legal_api.models import Filing from legal_api.models.colin_event_id import ColinEventId from tests.unit.models import factory_completed_filing # setup identifier = 'CP7654321' b = factory_business(identifier) filing = factory_completed_filing(b, ANNUAL_REPORT) assert filing.status == Filing.Status.COMPLETED.value colin_event_id = ColinEventId() colin_event_id.colin_event_id = 12346 filing.colin_event_ids.append(colin_event_id) filing.save() filings = Filing.get_completed_filings_for_colin() # test method # assert doesn't return completed filing with colin_event_ids set assert len(filings) == 0 # assert returns completed filings with colin_event_id not set filing.colin_event_ids.clear() filing.save() filings = Filing.get_completed_filings_for_colin() assert len(filings) == 1 assert filing.id == filings[0].json['filing']['header']['filingId'] assert filings[0].json['filing']['header']['colinIds'] == [] # assert doesn't return non completed filings filing.transaction_id = None filing.save() assert filing.status != Filing.Status.COMPLETED.value filings = Filing.get_completed_filings_for_colin() assert len(filings) == 0
def test_incorporation_filing_bc_company_from_colin(app, session, legal_type): """Assert that an existing bc company(LTD, ULC, CCC) incorporation is loaded corrrectly.""" # setup corp_num = 'BC0000001' colind_id = 1 filing = copy.deepcopy(INCORPORATION_FILING_TEMPLATE) # Change the template to be LTD, ULC or CCC filing['filing']['business']['legalType'] = legal_type filing['filing']['business']['identifier'] = corp_num filing['filing']['incorporationApplication']['nameRequest']['legalType'] = legal_type effective_date = datetime.utcnow() # Create the Filing object in the DB filing_rec = Filing(effective_date=effective_date, filing_json=filing) colin_event = ColinEventId() colin_event.colin_event_id = colind_id filing_rec.colin_event_ids.append(colin_event) # Override the state setting mechanism filing_rec.skip_status_listener = True filing_rec._status = 'PENDING' filing_rec.save() filing_meta = FilingMeta(application_date=filing_rec.effective_date) # test business, filing_rec, filing_meta = incorporation_filing.process(None, filing, filing_rec, filing_meta=filing_meta) # Assertions assert business.identifier == corp_num assert business.founding_date.replace(tzinfo=None) == effective_date assert business.legal_type == filing['filing']['incorporationApplication']['nameRequest']['legalType'] assert business.legal_name == business.identifier[2:] + ' B.C. LTD.' assert len(business.offices.all()) == 2 # One office is created in create_business method. assert len(business.share_classes.all()) == 2 assert len(business.party_roles.all()) == 3
def patch(filing_id): """Patch the colin_event_id for a filing.""" # check authorization try: if not jwt.validate_roles([COLIN_SVC_ROLE]): return jsonify({'message': 'You are not authorized to update the colin id'}), HTTPStatus.UNAUTHORIZED json_input = request.get_json() if not json_input: return None, None, {'message': f'No filing json data in body of patch for {filing_id}.'}, \ HTTPStatus.BAD_REQUEST colin_ids = json_input['colinIds'] filing = Filing.find_by_id(filing_id) if not filing: return {'message': f'{filing_id} no filings found'}, HTTPStatus.NOT_FOUND for colin_id in colin_ids: try: colin_event_id_obj = ColinEventId() colin_event_id_obj.colin_event_id = colin_id filing.colin_event_ids.append(colin_event_id_obj) filing.save() except BusinessException as err: current_app.logger.Error(f'Error adding colin event id {colin_id} to filing with id {filing_id}') return None, None, {'message': err.error}, err.status_code return jsonify(filing.json), HTTPStatus.ACCEPTED except Exception as err: current_app.logger.Error(f'Error patching colin event id for filing with id {filing_id}') raise err
def load_historic_filings(corp_num: str, business: Business, legal_type: str): """Load historic filings for a business.""" try: # get historic filings r = requests.get( f'{COLIN_API}/api/v1/businesses/{legal_type}/{corp_num}/filings/historic', timeout=TIMEOUT) if r.status_code != HTTPStatus.OK or not r.json(): print( f'skipping history for {corp_num} historic filings not found') else: for historic_filing in r.json(): uow = versioning_manager.unit_of_work(db.session) transaction = uow.create_transaction(db.session) filing = Filing() filing_date = historic_filing['filing']['header']['date'] filing.filing_date = datetime.datetime.strptime( filing_date, '%Y-%m-%d') filing.business_id = business.id filing.filing_json = historic_filing for colin_id in filing.filing_json['filing']['header'][ 'colinIds']: colin_event_id = ColinEventId() colin_event_id.colin_event_id = colin_id filing.colin_event_ids.append(colin_event_id) filing.transaction_id = transaction.id filing._filing_type = historic_filing['filing']['header'][ 'name'] filing.paper_only = True filing.effective_date = datetime.datetime.strptime( historic_filing['filing']['header']['effectiveDate'], '%Y-%m-%d') updater_user = User.find_by_username(UPDATER_USERNAME) filing.submitter_id = updater_user.id filing.source = Filing.Source.COLIN.value db.session.add(filing) # only commit after all historic filings were added successfully db.session.commit() LOADED_FILING_HISTORY.append(corp_num) except requests.exceptions.Timeout: print('rolling back partial changes...') db.session.rollback() FAILED_FILING_HISTORY.append(corp_num) print('colin_api request timed out getting historic filings.') except Exception as err: print('rolling back partial changes...') db.session.rollback() FAILED_FILING_HISTORY.append(corp_num) raise err
def json(self): """Return a json representation of this object.""" try: json_submission = copy.deepcopy(self.filing_json) json_submission['filing']['header']['date'] = self._filing_date.isoformat() json_submission['filing']['header']['filingId'] = self.id json_submission['filing']['header']['name'] = self.filing_type json_submission['filing']['header']['status'] = self.status # if availableOnPaper is not defined in filing json, use the flag on the filing record if json_submission['filing']['header'].get('availableOnPaperOnly', None) is None: json_submission['filing']['header']['availableOnPaperOnly'] = self.paper_only if self.effective_date: json_submission['filing']['header']['effectiveDate'] = self.effective_date.isoformat() if self._payment_token: json_submission['filing']['header']['paymentToken'] = self.payment_token if self.submitter_id: json_submission['filing']['header']['submitter'] = self.filing_submitter.username # add colin_event_ids json_submission['filing']['header']['colinIds'] = ColinEventId.get_by_filing_id(self.id) # add comments json_submission['filing']['header']['comments'] = [comment.json for comment in self.comments] return json_submission except Exception: # noqa: B901, E722 raise KeyError
def create_filing(filing_type, colin_filing, colin_event_id, corp_num): """Create legal api filing using colin filing as base""" effective_date = colin_filing['filing']['business']['foundingDate'] colin_filing['filing']['business']['identifier'] = corp_num filing = Filing(effective_date=effective_date, filing_json=colin_filing) filing._filing_type = filing_type filing.filing_date = effective_date colin_event = ColinEventId() colin_event.colin_event_id = colin_event_id filing.colin_event_ids.append(colin_event) # Override the state setting mechanism filing.skip_status_listener = True filing._status = 'PENDING' filing.source = Filing.Source.COLIN.value return filing
def get(colin_id=None): """Get the last colin id updated in legal.""" try: if colin_id: colin_id_obj = ColinEventId.get_by_colin_id(colin_id) if not colin_id_obj: return { 'message': 'No colin ids found' }, HTTPStatus.NOT_FOUND return {'colinId': colin_id_obj.colin_event_id}, HTTPStatus.OK except Exception as err: current_app.logger.Error( f'Failed to get last updated colin event id: {err}') raise err query = db.session.execute(""" select last_event_id from colin_last_update order by id desc """) last_event_id = query.fetchone() if not last_event_id or not last_event_id[0]: return {'message': 'No colin ids found'}, HTTPStatus.NOT_FOUND return { 'maxId': last_event_id[0] }, HTTPStatus.OK if request.method == 'GET' else HTTPStatus.CREATED
def __add_filings(self, business, book): # Get the filings properties and create the filings filings_sheet = book.sheet_by_name(SheetName.FILING.value) iter_filings_rows = iter(filings_sheet.get_rows()) # (skipping the header line) next(iter_filings_rows) for filing_row in iter_filings_rows: transaction_id = None if filing_row[0].value == business.identifier: # If the filing is completed, it has to contain a transaction ID status = self.__get_value_from_row(filing_row, 9) if Filing.Status.COMPLETED.value == status: uow = versioning_manager.unit_of_work(db.session) transaction = uow.create_transaction(db.session) transaction_id = transaction.id filing = Filing( _completion_date=self.__get_value_from_row(filing_row, 2), _filing_date=self.__get_value_from_row(filing_row, 3), _filing_type=self.__get_value_from_row(filing_row, 4), effective_date=self.__get_value_from_row(filing_row, 5), _payment_token=self.__get_value_from_row(filing_row, 6), _payment_completion_date=self.__get_value_from_row( filing_row, 7), _status=status, paper_only=self.__get_value_from_row(filing_row, 10), # transaction_id comes from continuuum transaction_id=transaction_id ) filing.business_id = business.id # need to convert this first before storing filing_value = self.__get_value_from_row(filing_row, 1) if filing_value: filing._filing_json = json.loads(filing_value) # pylint: disable=protected-access business.filings.append(filing) db.session.add(filing) db.session.commit() # add colin event ids colin_event_ids = self.__get_value_from_row(filing_row, 8) if colin_event_ids: # convert string to list colin_event_ids = eval(colin_event_ids) for colin_event_id in colin_event_ids: colin_event_id_obj = ColinEventId( colin_event_id=colin_event_id, filing_id=filing.id ) filing.colin_event_ids.append(colin_event_id_obj) db.session.add(filing) db.session.commit()
def test_get_colin_id(session, client, jwt): """Assert the internal/filings/colin_id get endpoint returns properly.""" from legal_api.models.colin_event_id import ColinEventId # setup identifier = 'CP7654321' b = factory_business(identifier) factory_business_mailing_address(b) filing = factory_completed_filing(b, ANNUAL_REPORT) colin_event_id = ColinEventId() colin_event_id.colin_event_id = 1234 filing.colin_event_ids.append(colin_event_id) filing.save() rv = client.get(f'/api/v1/businesses/internal/filings/colin_id/{colin_event_id.colin_event_id}') assert rv.status_code == HTTPStatus.OK assert rv.json == {'colinId': colin_event_id.colin_event_id} rv = client.get(f'/api/v1/businesses/internal/filings/colin_id/{1}') assert rv.status_code == HTTPStatus.NOT_FOUND
def test_get_internal_filings(session, client, jwt): """Assert that the internal filings get endpoint returns all completed filings without colin ids.""" from legal_api.models import Filing from legal_api.models.colin_event_id import ColinEventId from tests.unit.models import factory_error_filing, factory_pending_filing # setup identifier = 'CP7654321' b = factory_business(identifier) factory_business_mailing_address(b) filing1 = factory_completed_filing(b, ANNUAL_REPORT) filing2 = factory_completed_filing(b, ANNUAL_REPORT) filing3 = factory_pending_filing(b, ANNUAL_REPORT) filing4 = factory_filing(b, ANNUAL_REPORT) filing5 = factory_error_filing(b, ANNUAL_REPORT) filing6 = factory_completed_filing(b, CORRECTION_AR) assert filing1.status == Filing.Status.COMPLETED.value # completed with colin_event_id print(filing2.colin_event_ids) assert len(filing2.colin_event_ids) == 0 colin_event_id = ColinEventId() colin_event_id.colin_event_id = 12345 filing2.colin_event_ids.append(colin_event_id) filing2.save() assert filing2.status == Filing.Status.COMPLETED.value assert filing2.colin_event_ids # pending with no colin_event_ids assert filing3.status == Filing.Status.PENDING.value # draft with no colin_event_ids assert filing4.status == Filing.Status.DRAFT.value # error with no colin_event_ids assert filing5.status == Filing.Status.PAID.value # completed correction with no colin_event_ids assert filing6.status == Filing.Status.COMPLETED.value # test endpoint returned filing1 only (completed, no corrections, with no colin id set) rv = client.get(f'/api/v1/businesses/internal/filings') assert rv.status_code == HTTPStatus.OK assert len(rv.json) == 1 assert rv.json[0]['filingId'] == filing1.id
def factory_completed_filing(business, data_dict, filing_date=FROZEN_DATETIME, payment_token=None, colin_id=None): """Create a completed filing.""" if not payment_token: payment_token = str(base64.urlsafe_b64encode(uuid.uuid4().bytes)).replace('=', '') with freeze_time(filing_date): filing = Filing() filing.business_id = business.id filing.filing_date = filing_date filing.filing_json = data_dict filing.save() uow = versioning_manager.unit_of_work(db.session) transaction = uow.create_transaction(db.session) filing.transaction_id = transaction.id filing.payment_token = payment_token filing.effective_date = filing_date filing.payment_completion_date = filing_date if colin_id: colin_event = ColinEventId() colin_event.colin_event_id = colin_id colin_event.filing_id = filing.id colin_event.save() filing.save() return filing
def json(self): """Return a json representation of this object.""" try: json_submission = copy.deepcopy(self.filing_json) json_submission['filing']['header']['date'] = self._filing_date.isoformat() json_submission['filing']['header']['filingId'] = self.id json_submission['filing']['header']['name'] = self.filing_type json_submission['filing']['header']['status'] = self.status # if availableOnPaper is not defined in filing json, use the flag on the filing record if json_submission['filing']['header'].get('availableOnPaperOnly', None) is None: json_submission['filing']['header']['availableOnPaperOnly'] = self.paper_only if self.effective_date: json_submission['filing']['header']['effectiveDate'] = self.effective_date.isoformat() if self._payment_status_code: json_submission['filing']['header']['paymentStatusCode'] = self.payment_status_code if self._payment_token: json_submission['filing']['header']['paymentToken'] = self.payment_token if self.submitter_id: json_submission['filing']['header']['submitter'] = self.filing_submitter.username if self.payment_account: json_submission['filing']['header']['paymentAccount'] = self.payment_account # add colin_event_ids json_submission['filing']['header']['colinIds'] = ColinEventId.get_by_filing_id(self.id) # add comments json_submission['filing']['header']['comments'] = [comment.json for comment in self.comments] # add affected filings list json_submission['filing']['header']['affectedFilings'] = [filing.id for filing in self.children] # add corrected flags json_submission['filing']['header']['isCorrected'] = self.is_corrected json_submission['filing']['header']['isCorrectionPending'] = self.is_correction_pending return json_submission except Exception as err: # noqa: B901, E722 raise KeyError from err
def test_patch_internal_filings(session, client, jwt): """Assert that the internal filings patch endpoint updates the colin_event_id.""" from legal_api.models.colin_event_id import ColinEventId # setup identifier = 'CP7654321' b = factory_business(identifier) factory_business_mailing_address(b) filing = factory_completed_filing(b, ANNUAL_REPORT) colin_id = 1234 # make request rv = client.patch(f'/api/v1/businesses/internal/filings/{filing.id}', json={'colinIds': [colin_id]}, headers=create_header(jwt, [COLIN_SVC_ROLE]) ) # test result assert rv.status_code == HTTPStatus.ACCEPTED filing = Filing.find_by_id(filing.id) assert colin_id in ColinEventId.get_by_filing_id(filing.id) assert rv.json['filing']['header']['filingId'] == filing.id assert colin_id in rv.json['filing']['header']['colinIds']
def get(status=None): """Get filings by status formatted in json.""" pending_filings = [] filings = [] if status is None: pending_filings = Filing.get_completed_filings_for_colin() for filing in pending_filings: filing_json = filing.filing_json business = Business.find_by_internal_id(filing.business_id) if filing_json and filing.filing_type != 'lear_epoch' and \ (filing.filing_type != 'correction' or business.legal_type != business.LegalTypes.COOP.value): filing_json['filingId'] = filing.id filing_json['filing']['header'][ 'learEffectiveDate'] = filing.effective_date.isoformat( ) if not filing_json['filing']['business'].get('legalName'): business = Business.find_by_internal_id( filing.business_id) filing_json['filing']['business'][ 'legalName'] = business.legal_name if filing.filing_type == 'correction': colin_ids = \ ColinEventId.get_by_filing_id(filing_json['filing']['correction']['correctedFilingId']) if not colin_ids: continue filing_json['filing']['correction'][ 'correctedFilingColinId'] = colin_ids[ 0] # should only be 1 filings.append(filing_json) return jsonify(filings), HTTPStatus.OK pending_filings = Filing.get_all_filings_by_status(status) for filing in pending_filings: filings.append(filing.json) return jsonify(filings), HTTPStatus.OK
else: for historic_filing in r.json(): uow = versioning_manager.unit_of_work( db.session) transaction = uow.create_transaction( db.session) filing = Filing() filing_date = historic_filing['filing'][ 'header']['date'] filing.filing_date = datetime.datetime.strptime( filing_date, '%Y-%m-%d') filing.business_id = business.id filing.filing_json = historic_filing for colin_id in filing.filing_json['filing'][ 'header']['colinIds']: colin_event_id = ColinEventId() colin_event_id.colin_event_id = colin_id filing.colin_event_ids.append( colin_event_id) filing.transaction_id = transaction.id filing_type = historic_filing['filing'][ 'header']['name'] filing.paper_only = True filing.effective_date = datetime.datetime.strptime( historic_filing['filing']['header'] ['effectiveDate'], '%Y-%m-%d') # set user id to updater-job id (this will ensure that filing source is set to COLIN) updater_user = User.find_by_username( UPDATER_USERNAME)
def _save_filing( client_request: LocalProxy, # pylint: disable=too-many-return-statements,too-many-branches business_identifier: str, user: User, filing_id: int ) -> Tuple[Union[Business, RegistrationBootstrap], Filing, dict, int]: """Save the filing to the ledger. If not successful, a dict of errors is returned. Returns: { Business: business model object found for the identifier provided Filing: filing model object for the submitted filing dict: a dict of errors int: the HTTPStatus error code @TODO refactor to a set of single putpose routines } """ json_input = client_request.get_json() if not json_input: return None, None, {'message': f'No filing json data in body of post for {business_identifier}.'}, \ HTTPStatus.BAD_REQUEST if business_identifier.startswith('T'): # bootstrap filing bootstrap = RegistrationBootstrap.find_by_identifier( business_identifier) business = None if not bootstrap: return None, None, { 'message': f'{business_identifier} not found' }, HTTPStatus.NOT_FOUND if client_request.method == 'PUT': rv = db.session.query(Filing). \ filter(Filing.temp_reg == business_identifier). \ filter(Filing.id == filing_id). \ one_or_none() if not rv: return None, None, { 'message': f'{business_identifier} no filings found' }, HTTPStatus.NOT_FOUND filing = rv else: filing = Filing() filing.temp_reg = bootstrap.identifier if not json_input['filing'].get('business'): json_input['filing']['business'] = {} json_input['filing']['business'][ 'identifier'] = bootstrap.identifier else: # regular filing for a business business = Business.find_by_identifier(business_identifier) if not business: return None, None, { 'message': f'{business_identifier} not found' }, HTTPStatus.NOT_FOUND if client_request.method == 'PUT': rv = db.session.query(Business, Filing). \ filter(Business.id == Filing.business_id). \ filter(Business.identifier == business_identifier). \ filter(Filing.id == filing_id). \ one_or_none() if not rv: return None, None, { 'message': f'{business_identifier} no filings found' }, HTTPStatus.NOT_FOUND filing = rv[1] else: filing = Filing() filing.business_id = business.id try: filing.submitter_id = user.id filing.filing_json = json_input filing.source = filing.filing_json['filing']['header'].get( 'source', Filing.Source.LEAR.value) if filing.source == Filing.Source.COLIN.value: try: filing.filing_date = datetime.datetime.fromisoformat( filing.filing_json['filing']['header']['date']) for colin_id in filing.filing_json['filing']['header'][ 'colinIds']: colin_event_id = ColinEventId() colin_event_id.colin_event_id = colin_id filing.colin_event_ids.append(colin_event_id) except KeyError: current_app.logger.error( 'Business:%s missing filing/header values, unable to save', business.identifier) return None, None, { 'message': 'missing filing/header values' }, HTTPStatus.BAD_REQUEST else: filing.filing_date = datetime.datetime.utcnow() # for any legal type, set effective date as set in json; otherwise leave as default filing.effective_date = \ datetime.datetime.fromisoformat(filing.filing_json['filing']['header']['effectiveDate']) \ if filing.filing_json['filing']['header'].get('effectiveDate', None) else datetime.datetime.utcnow() filing.save() except BusinessException as err: return None, None, {'error': err.error}, err.status_code return business or bootstrap, filing, None, None
def _save_filing(client_request: LocalProxy, business_identifier: str, user: User, filing_id: int) -> Tuple[Business, Filing, dict, int]: """Save the filing to the ledger. If not successful, a dict of errors is returned. Returns: { Business: business model object found for the identifier provided Filing: filing model object for the submitted filing dict: a dict of errors int: the HTTPStatus error code } """ json_input = client_request.get_json() if not json_input: return None, None, {'message': f'No filing json data in body of post for {business_identifier}.'}, \ HTTPStatus.BAD_REQUEST business = Business.find_by_identifier(business_identifier) if not business: return None, None, { 'message': f'{business_identifier} not found' }, HTTPStatus.NOT_FOUND if client_request.method == 'PUT': rv = db.session.query(Business, Filing). \ filter(Business.id == Filing.business_id). \ filter(Business.identifier == business_identifier). \ filter(Filing.id == filing_id). \ one_or_none() if not rv: return None, None, { 'message': f'{business_identifier} no filings found' }, HTTPStatus.NOT_FOUND filing = rv[1] else: filing = Filing() filing.business_id = business.id try: filing.submitter_id = user.id filing.filing_json = json_input if user.username == 'coops-updater-job': try: filing.filing_date = datetime.datetime.fromisoformat( filing.filing_json['filing']['header']['date']) for colin_id in filing.filing_json['filing']['header'][ 'colinIds']: colin_event_id = ColinEventId() colin_event_id.colin_event_id = colin_id filing.colin_event_ids.append(colin_event_id) except KeyError: current_app.logger.error( 'Business:%s missing filing/header values, unable to save', business.identifier) return None, None, { 'message': 'missing filing/header values' }, HTTPStatus.BAD_REQUEST else: filing.filing_date = datetime.datetime.utcnow() # for any legal type, set effective date as set in json; otherwise leave as default if filing.filing_json['filing']['header'].get( 'effectiveDate', None): filing.effective_date = \ datetime.datetime.fromisoformat(filing.filing_json['filing']['header']['effectiveDate']) filing.save() except BusinessException as err: return None, None, {'error': err.error}, err.status_code return business, filing, None, None