def test_post_new_draft_incorporation(session, client, jwt): """Assert that an incorporation filing can be posted to businesses.""" nr_number = 'NR 1234567' filing = copy.deepcopy(INCORPORATION_FILING_TEMPLATE) filing['filing']['incorporationApplication']['nameRequest'][ 'nrNumber'] = nr_number # Post initial filing rv = client.post(f'/api/v1/businesses?draft=true', json=filing, headers=create_header(jwt, [STAFF_ROLE], nr_number)) assert HTTPStatus.CREATED == rv.status_code assert 'DRAFT' == rv.json['filing']['header']['status'] # verify business has actually been inserted with NR as identifier business = Business.find_by_identifier(nr_number) assert business
def get_tasks(identifier): """Return a JSON object with meta information about the Service.""" business = Business.find_by_identifier(identifier) is_nr = identifier.startswith('NR') # Check if this is a NR if is_nr: # Fetch NR Data nr_response = namex.query_nr_number(identifier) # Validate NR data validation_result = namex.validate_nr(nr_response.json()) # Return error if the NR is not consumable (invalid) if not validation_result['is_consumable']: return jsonify({ 'message': f'{identifier} is invalid', 'validation': validation_result }), HTTPStatus.FORBIDDEN if not business: # Create Incorporate using NR to-do item if is_nr: rv = [] rv.append(create_incorporate_nr_todo(nr_response.json(), 1, True)) # business does not exist and not an nr so return empty task list else: rv = [] else: rv = construct_task_list(business) if not rv and is_nr: paid_completed_filings = Filing.get_filings_by_status( business.id, [Filing.Status.PAID.value, Filing.Status.COMPLETED.value]) # Append NR todo if there are no tasks and PAID or COMPLETED filings if not paid_completed_filings: rv.append( create_incorporate_nr_todo(nr_response.json(), 1, True)) elif rv == 'pay_connection_error': return { 'message': 'Failed to get payment details for a filing. Please try again later.' }, HTTPStatus.SERVICE_UNAVAILABLE return jsonify(tasks=rv)
def test_correction_incorporation_notification(app, session, status, has_name_change_with_new_nr): """Assert that the legal name is changed.""" # setup filing + business for email original_filing = prep_incorp_filing(session, 'BC1234567', '1', status) token = 'token' business = Business.find_by_identifier('BC1234567') filing = prep_incorporation_correction_filing(session, business, original_filing.id, '1', status, has_name_change_with_new_nr) # test processor with patch.object(filing_notification, '_get_pdfs', return_value=[]) as mock_get_pdfs: email = filing_notification.process( { 'filingId': filing.id, 'type': 'correction', 'option': status }, token) if status == 'PAID': assert '*****@*****.**' in email['recipients'] assert email['content'][ 'subject'] == 'Confirmation of Correction of Incorporation Application' assert 'Incorporation Application (Corrected)' in email['content'][ 'body'] else: assert email['content']['subject'] == \ 'Incorporation Application Correction Documents from the Business Registry' assert '*****@*****.**' in email['recipients'] assert email['content']['body'] if has_name_change_with_new_nr: assert 'Incorporation Certificate (Corrected)' in email['content'][ 'body'] else: assert 'Incorporation Certificate (Corrected)' not in email[ 'content']['body'] assert email['content']['attachments'] == [] assert mock_get_pdfs.call_args[0][0] == status assert mock_get_pdfs.call_args[0][1] == token assert mock_get_pdfs.call_args[0][2] == {'identifier': 'BC1234567'} assert mock_get_pdfs.call_args[0][3] == filing
def get(identifier, share_class_id=None): """Return a JSON of the share classes.""" business = Business.find_by_identifier(identifier) if not business: return jsonify({'message': f'{identifier} not found'}), HTTPStatus.NOT_FOUND # return the matching share class if share_class_id: share_class, msg, code = ShareClassResource._get_share_class( business, share_class_id) return jsonify(share_class or msg), code share_classes = [] for share_class in business.share_classes.all(): share_classes.append(share_class.json) return jsonify(shareClasses=share_classes)
def post(identifier): """Create a new comment for the business.""" # basic checks business = Business.find_by_identifier(identifier) err_msg, err_code = BusinessCommentResource._basic_checks( identifier, business, request) if err_msg: return jsonify(err_msg), err_code json_input = request.get_json() # check authorization if not authorized(identifier, jwt, action=['add_comment']): return jsonify({'message': f'You are not authorized to submit a comment for {identifier}.'}), \ HTTPStatus.UNAUTHORIZED # validate comment err = validate(json_input, False) if err: json_input['errors'] = err.msg return jsonify(json_input), err.code # save comment user = User.get_or_create_user_by_jwt(g.jwt_oidc_token_info) try: comment = Comment() comment.comment = json_input['comment']['comment'] comment.staff_id = user.id comment.business_id = business.id comment.timestamp = datetime.datetime.utcnow() comment.save() except BusinessException as err: reply = json_input reply['errors'] = [ { 'error': err.error }, ] return jsonify(reply), err.status_code # all done return jsonify(comment.json), HTTPStatus.CREATED
def _create_deletion_locked_response(identifier, filing): business = Business.find_by_identifier(identifier) if (filing.status == Filing.Status.DRAFT.value and filing.filing_type == 'alteration' and business.legal_type in [ lt.value for lt in (Business.LIMITED_COMPANIES + Business.UNLIMITED_COMPANIES) ]): response = jsonify({ 'message': _('You must complete this alteration filing to become a BC Benefit Company.' ) }), HTTPStatus.UNAUTHORIZED else: response = jsonify({ 'message': _('This filing cannot be deleted at this moment.') }), HTTPStatus.UNAUTHORIZED return response
def get(identifier: str): """Return a JSON object with meta information about the Service.""" # check authorization # if not authorized(identifier, jwt, action=['view']): # return jsonify({'message': # f'You are not authorized to view business {identifier}.'}), \ # HTTPStatus.UNAUTHORIZED if identifier.startswith('T'): return { 'message': babel('No information on temp registrations.') }, 200 business = Business.find_by_identifier(identifier) if not business: return jsonify({'message': f'{identifier} not found'}), HTTPStatus.NOT_FOUND return jsonify(business=business.json())
def get(identifier, addresses_id=None): """Return a JSON of the addresses on file.""" business = Business.find_by_identifier(identifier) if not business: return jsonify({'message': f'{identifier} not found'}), HTTPStatus.NOT_FOUND address_type = request.args.get('addressType', None) if address_type and address_type not in Address.JSON_ADDRESS_TYPES: return jsonify({ 'message': f'{address_type} not a valid address type' }), HTTPStatus.BAD_REQUEST if addresses_id or address_type: addresses, msg, code = AddressResource._get_address( business, addresses_id, address_type) return jsonify(addresses or msg), code # return all active addresses rv = {} officelist = business.offices.all() if officelist: for i in officelist: rv[i.office_type] = {} for address in i.addresses: rv[i.office_type][ f'{address.address_type}Address'] = address.json else: mailing = business.mailing_address.one_or_none() if mailing: rv[Address.JSON_MAILING] = mailing.json delivery = business.delivery_address.one_or_none() if delivery: rv[Address.JSON_DELIVERY] = delivery.json if not rv: return jsonify({'message': f'{identifier} address not found' }), HTTPStatus.NOT_FOUND return jsonify(rv)
def get(identifier, comment_id=None): """Return a JSON object with meta information about the Service.""" # basic checks business = Business.find_by_identifier(identifier) err_msg, err_code = BusinessCommentResource._basic_checks(identifier, business, request) if err_msg: return jsonify(err_msg), err_code comments = db.session.query(Comment).filter(Comment.business_id == business.id, Comment.filing_id.is_(None)) if comment_id: comment = comments.filter(Comment.id == comment_id).one_or_none() if not comment: return jsonify({'message': f'Comment {comment_id} not found'}), HTTPStatus.NOT_FOUND return jsonify(comment.json) rv = [] for comment in comments: rv.append(comment.json) return jsonify(comments=rv)
def post(): """Set tax ids for businesses for given identifiers.""" 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 ({ 'message': 'No identifiers in body of post.' }, HTTPStatus.BAD_REQUEST) for identifier in json_input.keys(): # json input is a dict -> identifier: tax id business = Business.find_by_identifier(identifier) business.tax_id = json_input[identifier] business.save() return jsonify({'message': 'Successfully updated tax ids.'}), HTTPStatus.CREATED
async def test_technical_correction_ar(app, session): """Assert we can create a business based on transition filing.""" filing_data = copy.deepcopy(ANNUAL_REPORT) business = create_business(filing_data['filing']['business']['identifier']) business_identifier = business.identifier payment_id = str(random.SystemRandom().getrandbits(0x58)) filing = (create_filing(payment_id, filing_data, business.id)) filing_id = filing.id filing_msg = {'filing': {'id': filing.id}} # sanity check # that it is an AR, and it is based on the ANNUAL_REPORT template assert filing.json['filing']['annualReport'] assert filing.json['filing']['annualReport']['annualGeneralMeetingDate'] \ == ANNUAL_REPORT['filing']['annualReport']['annualGeneralMeetingDate'] # and the businesses last AR date is null assert not business.last_ar_date # subvert the filing technical_correction_filing = copy.deepcopy(FILING_HEADER) technical_correction_filing['specialResolution'] = copy.deepcopy( SPECIAL_RESOLUTION) filing.tech_correction_json = technical_correction_filing # over ride the state and skip state setting listeners for this test filing.skip_status_listener = True filing._status = 'PENDING' filing.save() # Test await process_filing(filing_msg, app) # Check outcome business = Business.find_by_identifier(business_identifier) filing = FilingCore.find_by_id(filing_id) assert not business.last_ar_date assert filing.filing_type == 'annualReport'
def get_ledger_listing(identifier: str, user_jwt: JwtManager): """Return the requested ledger for the business identifier provided.""" # Does it make sense to get a PDF of all filings? if str(request.accept_mimetypes) == 'application/pdf': return jsonify({'message': _('Cannot return a single PDF of multiple filing submissions.')}),\ HTTPStatus.NOT_ACCEPTABLE ledger_start = request.args.get('start', default=None, type=int) ledger_size = request.args.get('size', default=None, type=int) business = Business.find_by_identifier(identifier) if not business: return jsonify(filings=[]), HTTPStatus.NOT_FOUND filings = CoreFiling.ledger( business.id, jwt=user_jwt, statuses=[Filing.Status.COMPLETED.value, Filing.Status.PAID.value], start=ledger_start, size=ledger_size) return jsonify(filings=filings)
def test_bn_notificaton(app, session): """Assert that the bn email processor builds the email correctly.""" # setup filing + business for email identifier = 'BC1234567' filing = email_prepped_filing(session, identifier, '1', 'bn') business = Business.find_by_identifier(identifier) # sanity check assert filing.id assert business.id # run processor email = bn_notification.process({ 'filingId': None, 'type': 'businessNumber', 'option': 'bn', 'identifier': 'BC1234567' }) # check email values assert '*****@*****.**' in email['recipients'] assert '*****@*****.**' in email['recipients'] assert email['content'][ 'subject'] == f'{business.legal_name} - Business Number Information' assert email['content']['body'] assert email['content']['attachments'] == []
def get_documents(self, filing: dict): """Return an array of document meta for a filing.""" # look up legal type self._business_identifier = filing['filing']['business']['identifier'] # if this is a temp registration then there is no business, so get legal type from filing if self._business_identifier.startswith('T'): self._legal_type = filing['filing']['incorporationApplication'][ 'nameRequest']['legalType'] else: business = Business.find_by_identifier(self._business_identifier) if not business: return [] # business not found self._legal_type = business.legal_type self._filing_status = filing['filing']['header']['status'] is_paper_only = filing['filing']['header']['availableOnPaperOnly'] is_colin_only = filing['filing']['header']['inColinOnly'] if self._filing_status not in (Filing.Status.COMPLETED.value, Filing.Status.PAID.value) \ or is_paper_only or is_colin_only: return [] # wrong filing status return self.get_documents2(filing)
def get(identifier, filing_id=None): """Return a JSON object with meta information about the Service.""" business = Business.find_by_identifier(identifier) if not business: return jsonify({'message': f'{identifier} not found'}), HTTPStatus.NOT_FOUND if filing_id: rv = db.session.query(Business, Filing). \ filter(Business.id == Filing.business_id).\ filter(Business.identifier == identifier).\ filter(Filing.id == filing_id).\ one_or_none() if not rv: return jsonify({'message': f'{identifier} no filings found' }), HTTPStatus.NOT_FOUND if str(request.accept_mimetypes) == 'application/pdf': return legal_api.reports.get_pdf(rv[1]) return jsonify(rv[1].json) # Does it make sense to get a PDF of all filings? if str(request.accept_mimetypes) == 'application/pdf': return 'Please specify a single filing', HTTPStatus.NOT_ACCEPTABLE rv = [] go_live_date = datetime.date.fromisoformat( current_app.config.get('GO_LIVE_DATE')) filings = Filing.get_filings_by_status(business.id, [Filing.Status.COMPLETED.value], go_live_date) for filing in filings: rv.append(filing.json) return jsonify(filings=rv)
def get(identifier, filing_id=None): """Return a JSON object with meta information about the Service.""" business = Business.find_by_identifier(identifier) if not business: return jsonify({'message': f'{identifier} not found'}), HTTPStatus.NOT_FOUND if filing_id: rv = db.session.query(Business, Filing). \ filter(Business.id == Filing.business_id).\ filter(Business.identifier == identifier).\ filter(Filing.id == filing_id).\ one_or_none() if not rv: return jsonify({'message': f'{identifier} no filings found' }), HTTPStatus.NOT_FOUND if str(request.accept_mimetypes) == 'application/pdf': return legal_api.reports.get_pdf(rv[1]) return jsonify(rv[1].json) # Does it make sense to get a PDF of all filings? if str(request.accept_mimetypes) == 'application/pdf': return jsonify({'message': _('Cannot return a single PDF of multiple filing submissions.')}),\ HTTPStatus.NOT_ACCEPTABLE rv = [] filings = Filing.get_filings_by_status( business.id, [Filing.Status.COMPLETED.value, Filing.Status.PAID.value]) for filing in filings: rv.append(filing.json) return jsonify(filings=rv)
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
def get(identifier, filing_id=None): # pylint: disable=too-many-return-statements; # fix this while refactoring this whole module """Return a JSON object with meta information about the Service.""" if identifier.startswith('T'): q = db.session.query(Filing). \ filter(Filing.temp_reg == identifier) if filing_id: q = q.filter(Filing.id == filing_id) rv = q.one_or_none() if not rv: return jsonify({'message': f'{identifier} no filings found' }), HTTPStatus.NOT_FOUND if str(request.accept_mimetypes ) == 'application/pdf' and filing_id: if rv.filing_type == 'incorporationApplication': return legal_api.reports.get_pdf(rv, None) filing_json = rv.json filing_json['filing']['documents'] = document_meta.get_documents( filing_json) return jsonify(filing_json) business = Business.find_by_identifier(identifier) if not business: return jsonify(filings=[]), HTTPStatus.NOT_FOUND if filing_id: rv = db.session.query(Business, Filing). \ filter(Business.id == Filing.business_id).\ filter(Business.identifier == identifier).\ filter(Filing.id == filing_id).\ one_or_none() if not rv: return jsonify({'message': f'{identifier} no filings found' }), HTTPStatus.NOT_FOUND if str(request.accept_mimetypes) == 'application/pdf': report_type = request.args.get('type', None) if rv[1].filing_type == 'incorporationApplication': ListFilingResource._populate_business_info_to_filing( rv[1], business) return legal_api.reports.get_pdf(rv[1], report_type) return jsonify(rv[1].json) # Does it make sense to get a PDF of all filings? if str(request.accept_mimetypes) == 'application/pdf': return jsonify({'message': _('Cannot return a single PDF of multiple filing submissions.')}),\ HTTPStatus.NOT_ACCEPTABLE rv = [] filings = Filing.get_filings_by_status( business.id, [Filing.Status.COMPLETED.value, Filing.Status.PAID.value]) for filing in filings: filing_json = filing.json filing_json['filing']['documents'] = document_meta.get_documents( filing_json) rv.append(filing_json) return jsonify(filings=rv)
def put(identifier, filing_id): # pylint: disable=too-many-return-statements """Modify an incomplete filing for the business.""" # basic checks err_msg, err_code = ListFilingResource._put_basic_checks( identifier, filing_id, request) if err_msg: return jsonify({'errors': [ err_msg, ]}), err_code json_input = request.get_json() # check authorization if not authorized(identifier, jwt, action=['edit']): return jsonify({'message': f'You are not authorized to submit a filing for {identifier}.'}), \ HTTPStatus.UNAUTHORIZED draft = (request.args.get('draft', None).lower() == 'true') \ if request.args.get('draft', None) else False only_validate = (request.args.get('only_validate', None).lower() == 'true') \ if request.args.get('only_validate', None) else False # validate filing if not draft and not ListFilingResource._is_before_epoch_filing( json_input, Business.find_by_identifier(identifier)): business = Business.find_by_identifier(identifier) err = validate(business, json_input) # err_msg, err_code = ListFilingResource._validate_filing_json(request) if err or only_validate: if err: json_input['errors'] = err.msg return jsonify(json_input), err.code return jsonify(json_input), HTTPStatus.OK # save filing, if it's draft only then bail user = User.get_or_create_user_by_jwt(g.jwt_oidc_token_info) business, filing, err_msg, err_code = ListFilingResource._save_filing( request, identifier, user, filing_id) if err_msg or draft: reply = filing.json if filing else json_input reply['errors'] = [ err_msg, ] return jsonify(reply), err_code or \ (HTTPStatus.CREATED if (request.method == 'POST') else HTTPStatus.ACCEPTED) # if filing is from COLIN, place on queue and return if jwt.validate_roles([COLIN_SVC_ROLE]): err_msg, err_code = ListFilingResource._process_colin_filing( identifier, filing, business) return jsonify(err_msg), err_code # create invoice ?? if not draft: filing_types = ListFilingResource._get_filing_types( filing.filing_json) err_msg, err_code = ListFilingResource._create_invoice( business, filing, filing_types, jwt) if err_code: reply = filing.json reply['errors'] = [ err_msg, ] return jsonify(reply), err_code ListFilingResource._set_effective_date(business, filing) # all done return jsonify(filing.json),\ (HTTPStatus.CREATED if (request.method == 'POST') else HTTPStatus.ACCEPTED)
def load_corps(csv_filepath: str = 'corp_nums/corps_to_load.csv'): """Load corps in given csv file from oracle into postgres.""" global ROWCOUNT with open(csv_filepath, 'r') as csvfile: reader = csv.DictReader(csvfile) with FLASK_APP.app_context(): for row in reader: corp_num = row['CORP_NUM'] print('loading: ', corp_num) added = False ROWCOUNT += 1 try: legal_type = Business.LegalTypes.COOP.value if corp_num[:2] != Business.LegalTypes.COOP.value: legal_type = Business.LegalTypes.BCOMP.value corp_num = 'BC' + corp_num[-7:] business = Business.find_by_identifier(corp_num) if business: added = True print( '-> business info already exists -- skipping corp load' ) else: try: # get current company info business_current_info = {} for info_type in BUSINESS_MODEL_INFO_TYPES[ legal_type]: business_current_info[ info_type] = get_oracle_info( corp_num=corp_num, legal_type=legal_type, info_type=info_type) if business_current_info[info_type].get( 'failed', False): raise Exception( f'could not load {info_type}') except requests.exceptions.Timeout: FAILED_CORPS.append(corp_num) print( 'colin_api request timed out getting corporation details.' ) continue except Exception as err: print(f'exception: {err}') print( f'skipping load for {corp_num}, exception occurred getting company info' ) continue uow = versioning_manager.unit_of_work(db.session) transaction = uow.create_transaction(db.session) try: # add BC prefix to non coop identifiers if legal_type != Business.LegalTypes.COOP.value: business_current_info['business']['business']['identifier'] = 'BC' + \ business_current_info['business']['business']['identifier'] # add company to postgres db business = create_business( business_current_info['business']) add_business_offices( business, business_current_info['office']) add_business_directors( business, business_current_info['parties']) if legal_type == Business.LegalTypes.BCOMP.value: add_business_shares( business, business_current_info['sharestructure']) add_business_resolutions( business, business_current_info['resolutions']) add_business_aliases( business, business_current_info['aliases']) filing = Filing() filing.filing_json = { 'filing': { 'header': { 'name': 'lear_epoch' }, 'business': business.json() } } filing._filing_type = 'lear_epoch' filing.source = Filing.Source.COLIN.value filing.transaction_id = transaction.id business.filings.append(filing) business.save() added = True NEW_CORPS.append(corp_num) except Exception as err: print(err) print(f'skipping {corp_num} missing info') FAILED_CORPS.append(corp_num) if added and history_needed(business=business): load_historic_filings(corp_num=corp_num, business=business, legal_type=legal_type) else: print( '-> historic filings not needed - skipping history load' ) except Exception as err: print(err) exit(-1)
def put(identifier, filing_id): # pylint: disable=too-many-return-statements """Modify an incomplete filing for the business.""" # basic checks err_msg, err_code = ListFilingResource._put_basic_checks( identifier, filing_id, request) if err_msg: return jsonify({'errors': [ err_msg, ]}), err_code json_input = request.get_json() # check authorization if not authorized(identifier, jwt, action=['edit']): return jsonify({'message': f'You are not authorized to submit a filing for {identifier}.'}), \ HTTPStatus.UNAUTHORIZED # get query params draft = (request.args.get('draft', None).lower() == 'true') \ if request.args.get('draft', None) else False only_validate = (request.args.get('only_validate', None).lower() == 'true') \ if request.args.get('only_validate', None) else False # validate filing if not draft and not ListFilingResource._is_before_epoch_filing( json_input, Business.find_by_identifier(identifier)): if identifier.startswith('T'): business_validate = RegistrationBootstrap.find_by_identifier( identifier) else: business_validate = Business.find_by_identifier(identifier) err = validate(business_validate, json_input) # err_msg, err_code = ListFilingResource._validate_filing_json(request) if err or only_validate: if err: json_input['errors'] = err.msg return jsonify(json_input), err.code return jsonify(json_input), HTTPStatus.OK # save filing, if it's draft only then bail user = User.get_or_create_user_by_jwt(g.jwt_oidc_token_info) try: business, filing, err_msg, err_code = ListFilingResource._save_filing( request, identifier, user, filing_id) if err_msg or draft: reply = filing.json if filing else json_input reply['errors'] = [ err_msg, ] return jsonify(reply), err_code or \ (HTTPStatus.CREATED if (request.method == 'POST') else HTTPStatus.ACCEPTED) except Exception as err: print(err) # complete filing response, response_code = ListFilingResource.complete_filing( business, filing, draft) if response: return response, response_code # all done return jsonify(filing.json),\ (HTTPStatus.CREATED if (request.method == 'POST') else HTTPStatus.ACCEPTED)
return True return False rowcount = 0 TIMEOUT = 15 with open('coop_2019_test_data.csv', 'r') as csvfile: reader = csv.DictReader(csvfile) with FLASK_APP.app_context(): for row in reader: rowcount += 1 print('loading: ', row['CORP_NUM']) try: business = Business.find_by_identifier(row['CORP_NUM']) if not business: try: # get business info r = requests.get(COLIN_API + '/api/v1/businesses/' + row['CORP_NUM'], timeout=TIMEOUT) if r.status_code != HTTPStatus.OK \ or not r.json(): print('skipping ' + row['CORP_NUM'] + ' business info not found') continue business_json = r.json() # get business offices
def get(identifier, filing_id=None): # pylint: disable=too-many-return-statements,too-many-branches; # fix this while refactoring this whole module """Return a JSON object with meta information about the Service.""" original_filing = str(request.args.get('original', None)).lower() == 'true' if identifier.startswith('T'): rv = CoreFiling.get(identifier, filing_id) if not rv.storage: return jsonify({'message': f'{identifier} no filings found' }), HTTPStatus.NOT_FOUND if str(request.accept_mimetypes ) == 'application/pdf' and filing_id: if rv.filing_type == 'incorporationApplication': return legal_api.reports.get_pdf(rv.storage, None) if original_filing: filing_json = rv.raw else: filing_json = rv.json filing_json['filing']['documents'] = DocumentMetaService( ).get_documents(filing_json) if filing_json['filing']['header'][ 'status'] == Filing.Status.PENDING.value: try: headers = { 'Authorization': f'Bearer {jwt.get_token_auth_header()}', 'Content-Type': 'application/json' } payment_svc_url = current_app.config.get('PAYMENT_SVC_URL') pay_response = requests.get( url= f'{payment_svc_url}/{filing_json["filing"]["header"]["paymentToken"]}', headers=headers) pay_details = { 'isPaymentActionRequired': pay_response.json().get('isPaymentActionRequired', False), 'paymentMethod': pay_response.json().get('paymentMethod', '') } filing_json['filing']['header'].update(pay_details) except (exceptions.ConnectionError, exceptions.Timeout) as err: current_app.logger.error( f'Payment connection failure for getting {identifier} filing payment details. ', err) return jsonify(filing_json) business = Business.find_by_identifier(identifier) if not business: return jsonify(filings=[]), HTTPStatus.NOT_FOUND if filing_id: rv = CoreFiling.get(identifier, filing_id) if not rv: return jsonify({'message': f'{identifier} no filings found' }), HTTPStatus.NOT_FOUND if str(request.accept_mimetypes) == 'application/pdf': report_type = request.args.get('type', None) if rv.filing_type == CoreFiling.FilingTypes.CORRECTION.value: # This is required until #5302 ticket implements rv.storage._filing_json['filing']['correction'][ 'diff'] = rv.json['filing']['correction']['diff'] # pylint: disable=protected-access; # noqa: E501; return legal_api.reports.get_pdf(rv.storage, report_type) return jsonify(rv.raw if original_filing else rv.json) # Does it make sense to get a PDF of all filings? if str(request.accept_mimetypes) == 'application/pdf': return jsonify({'message': _('Cannot return a single PDF of multiple filing submissions.')}),\ HTTPStatus.NOT_ACCEPTABLE rv = [] filings = CoreFiling.get_filings_by_status( business.id, [Filing.Status.COMPLETED.value, Filing.Status.PAID.value]) for filing in filings: filing_json = filing.raw filing_json['filing']['documents'] = DocumentMetaService( ).get_documents(filing_json) rv.append(filing_json) return jsonify(filings=rv)
def put(identifier, filing_id): # pylint: disable=too-many-return-statements,too-many-locals """Modify an incomplete filing for the business.""" # basic checks err_msg, err_code = ListFilingResource._put_basic_checks( identifier, filing_id, request) if err_msg: return jsonify({'errors': [ err_msg, ]}), err_code json_input = request.get_json() # check authorization response, response_code = ListFilingResource._check_authorization( identifier, json_input) if response: return response, response_code # get query params draft = (request.args.get('draft', None).lower() == 'true') \ if request.args.get('draft', None) else False only_validate = (request.args.get('only_validate', None).lower() == 'true') \ if request.args.get('only_validate', None) else False # get header params payment_account_id = request.headers.get('accountId', None) if not draft \ and not ListFilingResource._is_historical_colin_filing(json_input) \ and not ListFilingResource._is_before_epoch_filing(json_input, Business.find_by_identifier(identifier)): if identifier.startswith('T'): business_validate = RegistrationBootstrap.find_by_identifier( identifier) else: business_validate = Business.find_by_identifier(identifier) err = validate(business_validate, json_input) # err_msg, err_code = ListFilingResource._validate_filing_json(request) if err or only_validate: if err: json_input['errors'] = err.msg return jsonify(json_input), err.code return jsonify(json_input), HTTPStatus.OK # save filing, if it's draft only then bail user = User.get_or_create_user_by_jwt(g.jwt_oidc_token_info) try: business, filing, err_msg, err_code = ListFilingResource._save_filing( request, identifier, user, filing_id) if err_msg or draft: reply = filing.json if filing else json_input reply['errors'] = [ err_msg, ] return jsonify(reply), err_code or \ (HTTPStatus.CREATED if (request.method == 'POST') else HTTPStatus.ACCEPTED) except Exception as err: print(err) # complete filing response, response_code = ListFilingResource.complete_filing( business, filing, draft, payment_account_id) if response and (response_code != HTTPStatus.CREATED or filing.source == Filing.Source.COLIN.value): return response, response_code # all done filing_json = filing.json if response: filing_json['filing']['header'].update(response) return jsonify(filing_json),\ (HTTPStatus.CREATED if (request.method == 'POST') else HTTPStatus.ACCEPTED)
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