def find_by_registration_number(cls, registration_num: str = None, staff: bool = False, allow_historical: bool = False): """Return a financing statement by registration number.""" statement = None if registration_num: # statement = cls.query.filter(FinancingStatement.financing_id == Registration.financing_id, # Registration.registration_num == registration_num, # Registration.registration_type_cl.in_(['PPSALIEN', 'MISCLIEN'])).one_or_none() statement = db.session.query(FinancingStatement).\ filter(FinancingStatement.financing_id == Registration.financing_id, Registration.registration_num == registration_num, Registration.registration_type_cl.in_(['PPSALIEN', 'MISCLIEN', 'CROWNLIEN'])).\ one_or_none() if not statement: raise BusinessException( error= f'No Financing Statement found for registration number {registration_num}.', status_code=HTTPStatus.NOT_FOUND) if not allow_historical and not staff and statement.state_type_cd != model_utils.STATE_ACTIVE: raise BusinessException( error= f'The Financing Statement for registration number {registration_num} has been discharged.', status_code=HTTPStatus.BAD_REQUEST) return statement
def validate_delete_ids(json_data, financing_statement): """Perform non-schema extra validation on a change amendment delete party, collateral ID's.""" error_msg = party_validator.validate_party_ids(json_data, financing_statement) error_msg += registration_validator.validate_collateral_ids( json_data, financing_statement) if error_msg != '': raise BusinessException(error=error_msg, status_code=HTTPStatus.BAD_REQUEST)
def save(self): """Render a search results detail information to the local cache.""" try: db.session.add(self) db.session.commit() except Exception as db_exception: # noqa: B902; just logging current_app.logger.error('DB search_result save exception: ' + repr(db_exception)) raise BusinessException( error='Database search_result save failed: ' + repr(db_exception), status_code=HTTPStatus.INTERNAL_SERVER_ERROR)
def save(self): """Render a search query to the local cache.""" try: db.session.add(self) db.session.commit() except Exception as db_exception: current_app.logger.error('DB search_client save exception: ' + repr(db_exception)) raise BusinessException( error='Database search_client save failed: ' + repr(db_exception), status_code=HTTPStatus.INTERNAL_SERVER_ERROR)
def find_by_document_number(cls, document_number: str = None, allow_used: bool = False): """Return a draft statement by document ID.""" draft = None if document_number: draft = cls.query.filter( Draft.document_number == document_number).one_or_none() if not draft: raise BusinessException( error= f'No Draft Statement found for Document ID {document_number}.', status_code=HTTPStatus.NOT_FOUND) if draft.registration and not allow_used: raise BusinessException( error= f'Draft Statement for Document ID {document_number} has been used.', status_code=HTTPStatus.BAD_REQUEST) return draft
def find_by_registration_number(cls, registration_num: str, account_id: str, staff: bool = False, base_reg_num: str = None): """Return the registration matching the registration number.""" registration = None if registration_num: registration = cls.query.filter(Registration.registration_num == registration_num).one_or_none() if not registration: raise BusinessException( error=model_utils.ERR_REGISTRATION_NOT_FOUND.format(registration_num=registration_num), status_code=HTTPStatus.NOT_FOUND ) if not staff and account_id and registration.account_id != account_id: # Check extra registrations extra_reg = UserExtraRegistration.find_by_registration_number(base_reg_num, account_id) if not extra_reg: raise BusinessException( error=model_utils.ERR_REGISTRATION_ACCOUNT.format(account_id=account_id, registration_num=registration_num), status_code=HTTPStatus.UNAUTHORIZED ) if not staff and model_utils.is_historical(registration.financing_statement, False): raise BusinessException( error=model_utils.ERR_FINANCING_HISTORICAL.format(registration_num=registration_num), status_code=HTTPStatus.BAD_REQUEST ) if not staff and base_reg_num and base_reg_num != registration.base_registration_num: raise BusinessException( error=model_utils.ERR_REGISTRATION_MISMATCH.format(registration_num=registration_num, base_reg_num=base_reg_num), status_code=HTTPStatus.BAD_REQUEST ) return registration
def validate(json_data): """Perform any extra data validation here, either because it is too complicated for the schema. Or because it requires existing data (client party codes). """ error_msg = '' # Verify the party codes. error_msg = error_msg + FinancingStatement.validate_parties(json_data) if error_msg != '': raise BusinessException(error=error_msg, status_code=HTTPStatus.BAD_REQUEST)
def find_by_registration_number(cls, registration_num: str, account_id: str, staff: bool = False, create: bool = False): """Return a financing statement by registration number.""" statement = None if registration_num: statement = db.session.query(FinancingStatement).\ filter(FinancingStatement.id == Registration.financing_id, Registration.registration_num == registration_num, Registration.registration_type_cl.in_(['PPSALIEN', 'MISCLIEN', 'CROWNLIEN'])).\ one_or_none() if not statement: raise BusinessException( error=model_utils.ERR_FINANCING_NOT_FOUND.format(registration_num=registration_num), status_code=HTTPStatus.NOT_FOUND ) if not staff and account_id and statement.registration[0].account_id != account_id: # Check extra registrations extra_reg = UserExtraRegistration.find_by_registration_number(statement.registration[0].registration_num, account_id) if not extra_reg: raise BusinessException( error=model_utils.ERR_REGISTRATION_ACCOUNT.format(account_id=account_id, registration_num=registration_num), status_code=HTTPStatus.UNAUTHORIZED ) # Skip historical check if staff and not creating if staff and not create: return statement if model_utils.is_historical(statement, create): # and (not staff or create): raise BusinessException( error=model_utils.ERR_FINANCING_HISTORICAL.format(registration_num=registration_num), status_code=HTTPStatus.BAD_REQUEST ) return statement
def save(self): """Render a user profile to the local cache.""" try: db.session.add(self) db.session.commit() current_app.logger.debug('Created/updated user profile: {}'.format( self.json)) except Exception as db_exception: # noqa: B902; just logging and wrapping current_app.logger.error('DB user_profile save exception: ' + repr(db_exception)) raise BusinessException( error='Database user_profile save failed: ' + repr(db_exception), status_code=HTTPStatus.INTERNAL_SERVER_ERROR)
def get_callback_pdf(report_data, account_id, report_type, token, account_name): """Event callback generate a PDF of the provided report type using the provided data.""" try: return Report(report_data, account_id, report_type, account_name).get_pdf(token=token) except FileNotFoundError: # We don't have a template for it, so it must only be available on paper. return jsonify({'message': _('No PDF report found.')}), HTTPStatus.NOT_FOUND except Exception as err: # noqa: B902; return nicer default error current_app.logger.error( f'Generate report failed for account {account_id}, type {report_type}: ' + repr(err)) raise BusinessException(error=DEFAULT_ERROR_MSG, status_code=HTTPStatus.INTERNAL_SERVER_ERROR)
def get_or_create_user_by_jwt(cls, jwt_oidc_token, account_id: str = None): """Return a valid user for audit tracking purposes.""" # GET existing or CREATE new user based on the JWT info try: user = User.find_by_jwt_token(jwt_oidc_token) current_app.logger.debug(f'finding user: {jwt_oidc_token}') if not user: current_app.logger.debug(f'didnt find user, attempting to create new user:{jwt_oidc_token}') user = User.create_from_jwt_token(jwt_oidc_token, account_id) return user except Exception as err: # noqa: B902; just logging and wrapping as BusinessException current_app.logger.error(err.with_traceback(None)) raise BusinessException('unable_to_get_or_create_user', '{"code": "unable_to_get_or_create_user",' '"description": "Unable to get or create user from the JWT, ABORT"}' )
def validate(json_data, financing_statement, registration_type_cl: str): """Perform any extra data validation here, either because it is too complicated for the schema. Or because it requires existing data. """ error_msg = '' # Verify the party codes and delete party ID's. error_msg = error_msg + Registration.validate_parties(json_data, financing_statement) if registration_type_cl in (model_utils.REG_CLASS_AMEND, model_utils.REG_CLASS_AMEND_COURT, model_utils.REG_CLASS_CHANGE): # Check delete vehicle ID's if 'deleteVehicleCollateral' in json_data: for collateral in json_data['deleteVehicleCollateral']: if 'vehicleId' not in collateral: error_msg = error_msg + 'Required vehicleId missing in deleteVehicleCollateral. ' else: collateral_id = collateral['vehicleId'] existing = Registration.find_vehicle_collateral_by_id(collateral_id, financing_statement.vehicle_collateral) if not existing: error_msg = error_msg + 'Invalid vehicleId ' + str(collateral_id) + \ ' in deleteVehicleCollateral. ' # Check delete general collateral ID's if 'deleteGeneralCollateral' in json_data: for collateral in json_data['deleteGeneralCollateral']: if 'collateralId' not in collateral: error_msg = error_msg + 'Required collateralId missing in deleteGeneralCollateral. ' else: collateral_id = collateral['collateralId'] existing = Registration.find_general_collateral_by_id(collateral_id, financing_statement.general_collateral) if not existing: error_msg = error_msg + 'Invalid collateralId ' + str(collateral_id) + \ ' in deleteGeneralCollateral. ' if error_msg != '': raise BusinessException( error=error_msg, status_code=HTTPStatus.BAD_REQUEST )
def validate_query(json_data): """Perform any extra data validation here, either because it is too complicated for the schema. Or because it requires existing data. """ error_msg = '' # validate search type - criteria combinations search_type = json_data['type'] if search_type not in ('INDIVIDUAL_DEBTOR', 'BUSINESS_DEBTOR'): if 'value' not in json_data['criteria']: error_msg += f'Search criteria value is required for search type {search_type}. ' else: if 'debtorName' not in json_data['criteria']: error_msg += f'Search criteria debtorName is required for search type {search_type}. ' elif search_type == 'INDIVIDUAL_DEBTOR' and 'last' not in json_data[ 'criteria']['debtorName']: error_msg += f'Search criteria debtorName last is required for search type {search_type}. ' elif search_type == 'BUSINESS_DEBTOR' and 'business' not in json_data[ 'criteria']['debtorName']: error_msg += f'Search criteria debtorName businessName is required for search type {search_type}. ' # Verify the start and end dates. if 'startDateTime' in json_data or 'startDateTime' in json_data: now = model_utils.now_ts() ts_start = None ts_end = None if 'startDateTime' in json_data: ts_start = model_utils.ts_from_iso_format( json_data['startDateTime']) if ts_start > now: error_msg = error_msg + 'Search startDateTime invalid: it cannot be in the future. ' if 'endDateTime' in json_data: ts_end = model_utils.ts_from_iso_format( json_data['endDateTime']) if ts_end > now: error_msg = error_msg + 'Search endDateTime invalid: it cannot be in the future. ' if ts_start and ts_end and ts_start > ts_end: error_msg = error_msg + 'Search date range invalid: startDateTime cannot be after endDateTime. ' if error_msg != '': raise BusinessException(error=error_msg, status_code=HTTPStatus.BAD_REQUEST)
def validate_search_select(select_json, search_id: int): # pylint: disable=unused-argument """Perform any extra data validation here. Either because it is too complicated for the schema, or because it requires existing data. Also fetch the existing search_detail record and verify a previous search detail request on the same search ID has not been submitted. """ error_msg = '' search_result = SearchResult.find_by_search_id(search_id) if not search_result: error_msg = f'Search select results failed: invalid search ID {search_id}.' elif search_result.search_select: # Search detail request already submitted. error_msg = f'Search select results failed: results already provided for search ID {search_id}.' if error_msg != '': raise BusinessException(error=error_msg, status_code=HTTPStatus.BAD_REQUEST) return search_result
def check_access_registration(token: str, staff: bool, account_id: str, statement): """Extra check on account access to a registration.""" if staff or (account_id and statement.account_id == account_id): return account_name = get_account_name(token, account_id) access = False if account_name: for party in statement.financing_statement.parties: if party.party_type in (PARTY_REGISTERING, PARTY_SECURED) and \ party.business_name and party.business_name == account_name: access = True elif party.client_code and party.client_code.name == account_name: access = True if not access: reg_num = statement.registration_num current_app.logger.error('Account name ' + account_name + ' cannot access registration ' + reg_num) raise BusinessException(error=ACCOUNT_ACCESS.format( account_id=account_id, registration_num=reg_num), status_code=HTTPStatus.UNAUTHORIZED)
def find_by_search_id(cls, search_id: int, limit_by_date: bool = False): """Return the search detail record matching the search_id.""" search_detail = None error_msg = '' if search_id and not limit_by_date: search_detail = db.session.query(SearchResult).filter( SearchResult.search_id == search_id).one_or_none() elif search_id and limit_by_date: min_allowed_date = model_utils.today_ts_offset( GET_DETAIL_DAYS_LIMIT, False) search_detail = db.session.query(SearchResult).filter( SearchResult.search_id == search_id).one_or_none() if search_detail and search_detail.search and \ search_detail.search.search_ts.timestamp() < min_allowed_date.timestamp(): min_ts = model_utils.format_ts(min_allowed_date) error_msg = f'Search get details search ID {search_id} timestamp too old: must be after {min_ts}.' if error_msg != '': raise BusinessException(error=error_msg, status_code=HTTPStatus.BAD_REQUEST) return search_detail