def factory_filing(business, data_dict, filing_date=FROZEN_DATETIME): """Create a filing.""" filing = Filing() filing.business_id = business.id filing.filing_date = filing_date filing.filing_json = data_dict filing.save() return filing
def factory_incorporation_filing(business, data_dict, filing_date=FROZEN_DATETIME, effective_date=FROZEN_DATETIME): """Create a filing.""" filing = Filing() filing.business_id = business.id filing.filing_date = filing_date filing.effective_date = effective_date filing.filing_json = data_dict filing.save() return filing
def factory_pending_filing(business, data_dict, filing_date=FROZEN_DATETIME): """Create a pending filing.""" filing = Filing() filing.business_id = business.id filing.filing_date = filing_date filing.filing_json = data_dict filing.payment_token = 2 filing.save() return filing
def factory_error_filing(business, data_dict): """Create an error filing.""" filing = Filing() filing.business_id = business.id filing.filing_date = FROZEN_DATETIME filing.filing_json = data_dict filing.save() filing.payment_token = 5 filing.payment_completion_date = datetime.now() return filing
def factory_error_filing(business, data_dict, filing_date=FROZEN_DATETIME): """Create an error filing.""" filing = Filing() filing.business_id = business.id filing.filing_date = filing_date filing.filing_json = data_dict filing.save() filing.payment_token = 5 filing.payment_completion_date = (datetime.now()).replace(tzinfo=timezone.utc) return filing
def factory_epoch_filing(business, filing_date=FROZEN_DATETIME): """Create an error filing.""" filing = Filing() filing.business_id = business.id uow = versioning_manager.unit_of_work(db.session) transaction = uow.create_transaction(db.session) filing.transaction_id = transaction.id filing.filing_date = filing_date filing.filing_json = {'filing': {'header': {'name': 'lear_epoch'}}} filing.save() return filing
def _save_incorporation_filing(incorporation_body, client_request, business_id=None): """Create or update an incorporation filing.""" # Check that there is a JSON filing if not incorporation_body: return None, {'message': f'No filing json data in body of post for incorporation'}, \ HTTPStatus.BAD_REQUEST temp_corp_num = incorporation_body['filing'][ 'incorporationApplication']['nameRequest']['nrNumber'] # temp_corp_num = business_id # If this is an update to an incorporation filing, a temporary business identifier is passed in if business_id: business = Business.find_by_identifier(business_id) if not business: return None, {'message': f'No incorporation filing exists for id {business_id}'}, \ HTTPStatus.BAD_REQUEST else: # Ensure there are no current businesses with the NR/random identifier business = Business.find_by_identifier(temp_corp_num) if business: return None, {'message': f'Incorporation filing for {temp_corp_num} already exists'}, \ HTTPStatus.BAD_REQUEST # Create an empty business record, to be updated by the filer business = Business() business.identifier = temp_corp_num business.save() # Ensure the business identifier matches the NR in the filing err = validate(business, incorporation_body) if err: return None, err.msg, err.code filing = Filing.get_filings_by_type(business.id, 'incorporationApplication') # There can only be zero or one incorporation filings, if there are none, this is an # initial request for incorporation. Create and insert a filing. if not filing: filing = Filing() filing.business_id = business.id elif len(filing) > 1: return None, { 'message': 'more than one incorporation filing found for corp' }, HTTPStatus.BAD_REQUEST else: filing = filing[0] filing.filing_json = incorporation_body filing.save() return filing, None, (HTTPStatus.CREATED if (client_request.method == 'POST') else HTTPStatus.ACCEPTED)
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 test_minimal_filing_json(session): """Assert that a minimal filing can be created.""" b = factory_business('CP1234567') data = {'filing': 'not a real filing, fail validation'} filing = Filing() filing.business_id = b.id filing.filing_date = datetime.datetime.utcnow() filing.filing_data = json.dumps(data) filing.save() assert filing.id is not None
def factory_completed_filing(business, data_dict, filing_date=FROZEN_DATETIME): """Create a completed filing.""" 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 = 1 filing.payment_completion_date = datetime.now() return filing
def create_filing(token, json_filing=None, business_id=None): """Return a test filing.""" from legal_api.models import Filing filing = Filing() filing.payment_token = str(token) filing.filing_date = EPOCH_DATETIME if json_filing: filing.filing_json = json_filing if business_id: filing.business_id = business_id filing.save() return filing
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_date = datetime.datetime.utcnow() filing.filing_json = json_input filing.save() except BusinessException as err: return None, None, {'error': err.error}, err.status_code return business, filing, None, None
def test_get_filings_by_status__default_order(session): """Assert that a filing can be retrieved. by status and is returned in the default order. default order is submission_date, and then effective_date. """ # setup base_filing = copy.deepcopy(FILING_HEADER) base_filing['specialResolution'] = SPECIAL_RESOLUTION uow = versioning_manager.unit_of_work(session) business = factory_business('CP1234567') completion_date = datetime.datetime.utcnow().replace( tzinfo=datetime.timezone.utc) # setup - create multiple filings on the same day & time filing_ids = [] file_counter = -1 with freeze_time(completion_date): for i in range(0, 5): transaction = uow.create_transaction(session) payment_token = str(i) effective_date = f'200{i}-04-15T00:00:00+00:00' base_filing['filing']['header']['effectiveDate'] = effective_date filing = Filing() filing._filing_date = completion_date filing.business_id = business.id filing.filing_json = base_filing filing.effective_date = datetime.datetime.fromisoformat( effective_date) filing.payment_token = payment_token filing.transaction_id = transaction.id filing.payment_completion_date = completion_date filing.save() filing_ids.append(filing.id) file_counter += 1 # test rv = Filing.get_filings_by_status(business.id, [Filing.Status.COMPLETED.value]) # check assert rv # filings should be in newest to oldest effective date order for filing in rv: assert filing.id == filing_ids[file_counter] file_counter -= 1
def test_get_current_registrar(session): """Assert that the current registrar is returned.""" b = factory_business('CP1234567') filing = Filing() filing.business_id = b.id filing.filing_date = datetime.datetime.utcnow() filing.filing_data = ANNUAL_REPORT filing.save() registrar_info = RegistrarInfo.get_registrar_info(filing.effective_date) assert registrar_info['startDate'] assert registrar_info['endDate'] is None assert registrar_info['signature'] assert registrar_info['name'] assert registrar_info['title']
def test_filing_orm_delete_allowed_for_in_progress_filing(session): """Assert that attempting to delete a filing will raise a BusinessException.""" from legal_api.exceptions import BusinessException b = factory_business('CP1234567') filing = Filing() filing.business_id = b.id filing.filing_date = datetime.datetime.utcnow() filing.filing_json = ANNUAL_REPORT filing.save() with not_raises(BusinessException): session.delete(filing) session.commit()
def factory_filing(business, data_dict, filing_date=FROZEN_DATETIME, filing_type=None): """Create a filing.""" filing = Filing() filing.business_id = business.id filing.filing_date = filing_date filing.filing_json = data_dict if filing_type: filing._filing_type = filing_type try: filing.save() except Exception as err: print(err) return filing
def create_filing(token=None, filing_json=None, business_id=None, filing_date=EPOCH_DATETIME, bootstrap_id: str = None): """Return a test filing.""" filing = Filing() if token: filing.payment_token = str(token) filing.filing_date = filing_date if filing_json: filing.filing_json = filing_json if business_id: filing.business_id = business_id if bootstrap_id: filing.temp_reg = bootstrap_id filing.save() return filing
def test_get_registrar_for_a_filing(session): """Assert that the registrar effective on that date is returned.""" b = factory_business('CP1234567') filing = Filing() filing.business_id = b.id filing.filing_date = datetime.datetime(2012, 6, 6) filing.effective_date = datetime.datetime(2012, 6, 6) filing.filing_data = ANNUAL_REPORT filing.save() registrar_info = RegistrarInfo.get_registrar_info(filing.effective_date) assert registrar_info['startDate'] assert registrar_info['endDate'] assert registrar_info['signature'] assert registrar_info['name'] == 'ANGELO COCCO' assert registrar_info['title'] == 'A/Registrar of Companies'
def create_filing(token=None, json_filing=None, business_id=None, filing_date=EPOCH_DATETIME, bootstrap_id: str = None): """Return a test filing.""" from legal_api.models import Filing filing = Filing() if token: filing.payment_token = str(token) filing.filing_date = filing_date if json_filing: filing.filing_json = json_filing if business_id: filing.business_id = business_id if bootstrap_id: filing.temp_reg = bootstrap_id filing.save() return filing
def test_get_filings_by_status(session): """Assert that a filing can be retrieved by status.""" uow = versioning_manager.unit_of_work(session) transaction = uow.create_transaction(session) business = factory_business('CP1234567') payment_token = '1000' filing = Filing() filing.business_id = business.id filing.filing_json = ANNUAL_REPORT filing.payment_token = payment_token filing.transaction_id = transaction.id filing.payment_completion_date = datetime.datetime.utcnow() filing.save() rv = Filing.get_filings_by_status(business.id, [Filing.Status.COMPLETED.value]) assert rv assert rv[0].status == Filing.Status.COMPLETED.value
def test_filing_orm_delete_blocked_if_invoiced(session): """Assert that attempting to delete a filing will raise a BusinessException.""" from legal_api.exceptions import BusinessException b = factory_business('CP1234567') filing = Filing() filing.business_id = b.id filing.filing_date = datetime.datetime.utcnow() filing.filing_json = ANNUAL_REPORT filing.payment_token = 'a token' filing.save() with pytest.raises(BusinessException) as excinfo: session.delete(filing) session.commit() assert excinfo.value.status_code == HTTPStatus.FORBIDDEN assert excinfo.value.error == 'Deletion not allowed.'
def test_filing_block_orm_delete(session): """Assert that attempting to delete a filing will raise a BusinessException.""" from legal_api.exceptions import BusinessException b = factory_business('CP1234567') data = {'filing': 'not a real filing, fail validation'} filing = Filing() filing.business_id = b.id filing.filing_date = datetime.datetime.utcnow() filing.filing_data = json.dumps(data) filing.save() with pytest.raises(BusinessException) as excinfo: session.delete(filing) session.commit() assert excinfo.value.status_code == HTTPStatus.FORBIDDEN assert excinfo.value.error == 'Deletion not allowed.'
def factory_completed_filing(business, data_dict, filing_date=FROZEN_DATETIME, payment_token=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 filing.save() return filing
def test_put_incorporation_to_business_fails(session, client, jwt): """Assert that an incorporation cannot be PUT to the business endpoint.""" nr_number = 'NR 1234567' filing_json = copy.deepcopy(INCORPORATION_FILING_TEMPLATE) filing_json['filing']['incorporationApplication']['nameRequest'][ 'nrNumber'] = nr_number business = Business() business.identifier = nr_number business.save() filing = Filing() filing.filing_json = filing_json filing.business_id = business.id filing.save() # Post initial filing rv = client.put(f'/api/v1/businesses/{nr_number}', json=filing_json, headers=create_header(jwt, [STAFF_ROLE], nr_number)) assert HTTPStatus.METHOD_NOT_ALLOWED == rv.status_code
def test_put_draft_incorporation_filing(session, client, jwt): """Assert that an incorporation filing can be put (updated) to filings endpoint.""" nr_number = 'NR 1234567' filing_json = copy.deepcopy(INCORPORATION_FILING_TEMPLATE) filing_json['filing']['incorporationApplication']['nameRequest'][ 'nrNumber'] = nr_number business = Business() business.identifier = nr_number business.save() filing = Filing() filing.filing_json = filing_json filing.business_id = business.id filing.save() # PUT updated filing rv = client.put( f'/api/v1/businesses/{nr_number}/filings/{filing.id}?draft=true', json=filing_json, headers=create_header(jwt, [STAFF_ROLE], nr_number)) assert HTTPStatus.ACCEPTED == rv.status_code
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']) filing.colin_event_id = filing.filing_json['filing'][ 'header']['colinId'] 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() filing.save() except BusinessException as err: return None, None, {'error': err.error}, err.status_code return business, filing, None, None
row['CORP_NUM'] + '/filings/historic', timeout=TIMEOUT) if r.status_code != HTTPStatus.OK or not r.json(): print( f'skipping history for {row["CORP_NUM"]} historic filings not found' ) 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 filing.transaction_id = transaction.id filing_type = historic_filing['filing']['header'][ 'name'] filing.colin_event_id = historic_filing['filing'][ filing_type]['eventId'] filing.paper_only = True db.session.add(filing) db.session.commit() except requests.exceptions.Timeout as timeout: print( 'colin_api request timed out getting historic filings.' ) else: