def consume_nr( business: Business, filing: Filing, nr_num_path='/filing/incorporationApplication/nameRequest/nrNumber'): """Update the nr to a consumed state.""" try: # skip this if none (nrNumber will not be available for numbered company) if nr_num := get_str(filing.filing_json, nr_num_path): namex_svc_url = current_app.config.get('NAMEX_API') token = AccountService.get_bearer_token() # Create an entity record data = json.dumps({'consume': {'corpNum': business.identifier}}) rv = requests.patch( url=''.join([namex_svc_url, nr_num]), headers={ **AccountService.CONTENT_TYPE_JSON, 'Authorization': AccountService.BEARER + token }, data=data, timeout=AccountService.timeout) if not rv.status_code == HTTPStatus.OK: raise QueueException # remove the NR from the account if filing.temp_reg and (bootstrap := RegistrationBootstrap.find_by_identifier( filing.temp_reg)): AccountService.delete_affiliation(bootstrap.account, nr_num)
def consume_nr( business: Business, filing: Filing, nr_num_path='/filing/incorporationApplication/nameRequest/nrNumber'): """Update the nr to a consumed state.""" try: nr_num = get_str(filing.filing_json, nr_num_path) # skip this if none (nrNumber will not be available for numbered company) if nr_num: bootstrap = RegistrationBootstrap.find_by_identifier( filing.temp_reg) namex_svc_url = current_app.config.get('NAMEX_API') token = AccountService.get_bearer_token() # Create an entity record data = json.dumps({'consume': {'corpNum': business.identifier}}) rv = requests.patch( url=''.join([namex_svc_url, nr_num]), headers={ **AccountService.CONTENT_TYPE_JSON, 'Authorization': AccountService.BEARER + token }, data=data, timeout=AccountService.timeout) if not rv.status_code == HTTPStatus.OK: raise QueueException # remove the NR from the account AccountService.delete_affiliation(bootstrap.account, nr_num) except KeyError: pass # return except Exception: # pylint: disable=broad-except; note out any exception, but don't fail the call sentry_sdk.capture_message( f'Queue Error: Consume NR error for filing:{filing.id}', level='error')
def test_delete_bootstrap_draft_filing(client, jwt, session): """Assert that a draft IA filing can be retrieved.""" account_id = 26 identifier, filing_id = setup_bootstrap_ia_minimal(jwt, session, client, account_id) # # Test that we can get the filing # rv = client.delete(f'/api/v1/businesses/{identifier}/filings/{filing_id}', headers=create_header(jwt, [STAFF_ROLE], None)) assert rv.status_code == HTTPStatus.OK assert not Filing.find_by_id(filing_id) assert not RegistrationBootstrap.find_by_identifier(identifier)
def delete(identifier, filing_id=None): # pylint: disable=too-many-branches """Delete a filing from the business.""" if not filing_id: return ({ 'message': _('No filing id provided for:') + identifier }, HTTPStatus.BAD_REQUEST) # check authorization if not authorized(identifier, jwt, action=['edit']): return jsonify({'message': _('You are not authorized to delete a filing for:') + identifier}),\ HTTPStatus.UNAUTHORIZED if identifier.startswith('T'): filing = Filing.get_temp_reg_filing(identifier, filing_id) else: filing = Business.get_filing_by_id(identifier, filing_id) if not filing: return jsonify({'message': _('Filing Not Found.')}), HTTPStatus.NOT_FOUND if filing.deletion_locked: # should not be deleted return ListFilingResource._create_deletion_locked_response( identifier, filing) try: ListFilingResource._delete_from_minio(filing) filing.delete() except BusinessException as err: return jsonify({'errors': [ { 'error': err.error }, ]}), err.status_code if identifier.startswith('T'): bootstrap = RegistrationBootstrap.find_by_identifier(identifier) if bootstrap: deregister_status = RegistrationBootstrapService.deregister_bootstrap( bootstrap) delete_status = RegistrationBootstrapService.delete_bootstrap( bootstrap) if deregister_status != HTTPStatus.OK or delete_status != HTTPStatus.OK: current_app.logger.error( 'Unable to deregister and delete temp reg:', identifier) return jsonify({'message': _('Filing deleted.')}), HTTPStatus.OK
def update_affiliation(business: Business, filing: Filing): """Create an affiliation for the business and remove the bootstrap.""" try: bootstrap = RegistrationBootstrap.find_by_identifier(filing.temp_reg) rv = AccountService.create_affiliation( account=bootstrap.account, business_registration=business.identifier, business_name=business.legal_name, corp_type_code=business.legal_type) if rv not in (HTTPStatus.OK, HTTPStatus.CREATED): deaffiliation = AccountService.delete_affiliation( bootstrap.account, business.identifier) sentry_sdk.capture_message( f'Queue Error: Unable to affiliate business:{business.identifier} for filing:{filing.id}', level='error') else: # flip the registration # recreate the bootstrap, but point to the new business in the name old_bs_affiliation = AccountService.delete_affiliation( bootstrap.account, bootstrap.identifier) new_bs_affiliation = AccountService.create_affiliation( account=bootstrap.account, business_registration=bootstrap.identifier, business_name=business.identifier, corp_type_code='TMP') reaffiliate = bool( new_bs_affiliation in (HTTPStatus.OK, HTTPStatus.CREATED) and old_bs_affiliation == HTTPStatus.OK) if rv not in (HTTPStatus.OK, HTTPStatus.CREATED) \ or ('deaffiliation' in locals() and deaffiliation != HTTPStatus.OK)\ or ('reaffiliate' in locals() and not reaffiliate): raise QueueException except Exception as err: # pylint: disable=broad-except; note out any exception, but don't fail the call sentry_sdk.capture_message( f'Queue Error: Affiliation error for filing:{filing.id}, with err:{err}', level='error')
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 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 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)