def validate_incorporation_effective_date(incorporation_json) -> Error: """Return an error or warning message based on the effective date validation rules. Rules: - The effective date must be the correct format. - The effective date must be a minimum of 2 minutes in the future. - The effective date must be a maximum of 10 days in the future. """ # Setup msg = [] now = dt.utcnow() now_plus_2_minutes = now + timedelta(minutes=2) now_plus_10_days = now + timedelta(days=10) try: filing_effective_date = incorporation_json['filing']['header']['effectiveDate'] except KeyError: return msg try: effective_date = dt.fromisoformat(filing_effective_date) except ValueError: msg.append({'error': babel('%s is an invalid ISO format for effective_date.') % filing_effective_date}) return msg if effective_date < now_plus_2_minutes: msg.append({'error': babel('Invalid Datetime, effective date must be a minimum of 2 minutes ahead.')}) if effective_date > now_plus_10_days: msg.append({'error': babel('Invalid Datetime, effective date must be a maximum of 10 days ahead.')}) if msg: return msg return None
def validate_effective_date(business: Business, cod: Dict) -> List: """Return an error or warning message based on the effective date validation rules. Rules: - The effective date of change cannot be in the future. - The effective date cannot be a date prior to their Incorporation Date - The effective date of change cannot be a date that is farther in the past as a previous COD filing (Standalone or AR). - The effective date can be the same effective date as another COD filing (standalone OR AR). If this is the case: - COD filing that was filed most recently as the most current director information. """ try: filing_effective_date = cod['filing']['header']['effectiveDate'] except KeyError: try: # we'll assume the filing is at 0 hours UTC filing_effective_date = cod['filing']['header'][ 'date'] + 'T00:00:00+00:00' except KeyError: return { 'error': babel('No effective_date or filing date provided.') } try: effective_date = datetime.fromisoformat(filing_effective_date) except ValueError: return { 'error': babel('Invalid ISO format for effective_date or filing date.') } msg = [] # The effective date of change cannot be in the future if effective_date > datetime.utcnow(): msg.append( {'error': babel('Filing cannot have a future effective date.')}) # The effective date cannot be a date prior to their Incorporation Date if effective_date < business.founding_date: msg.append({ 'error': babel('Filing cannot be before a businesses founding date.') }) last_cod_filing = Filing.get_most_recent_legal_filing( business.id, Filing.FILINGS['changeOfDirectors']['name']) if last_cod_filing: if effective_date < last_cod_filing.effective_date: msg.append({ 'error': babel( "Filing's effective date cannot be before another Change of Director filing." ) }) return msg
def update_filing_court_order(filing_submission: Filing, court_order_json: Dict) -> Optional[Dict]: """Update the court_order info for a Filing.""" if not Filing: return {'error': babel('Filing required before alternate names can be set.')} filing_submission.court_order_file_number = court_order_json.get('fileNumber') filing_submission.court_order_effect_of_order = court_order_json.get('effectOfOrder') with suppress(IndexError, KeyError, TypeError, ValueError): filing_submission.court_order_date = datetime.fromisoformat(court_order_json.get('orderDate')) return None
def validate_court_order(court_order_path, court_order): """Validate the courtOrder data of the filing.""" msg = [] # TODO remove it when the issue with schema validation is fixed if 'fileNumber' not in court_order: err_path = court_order_path + '/fileNumber' msg.append({ 'error': 'Court order file number is required.', 'path': err_path }) else: if len(court_order['fileNumber']) < 5 or len( court_order['fileNumber']) > 20: err_path = court_order_path + '/fileNumber' msg.append({ 'error': 'Length of court order file number must be from 5 to 20 characters.', 'path': err_path }) if 'effectOfOrder' in court_order and ( len(court_order['effectOfOrder']) < 5 or len(court_order['effectOfOrder']) > 500): err_path = court_order_path + '/effectOfOrder' msg.append({ 'error': 'Length of court order effect of order must be from 5 to 500 characters.', 'path': err_path }) court_order_date_path = court_order_path + '/orderDate' if 'orderDate' in court_order: try: court_order_date = dt.fromisoformat(court_order['orderDate']) if court_order_date.timestamp() > datetime.utcnow().timestamp(): err_path = court_order_date_path msg.append({ 'error': 'Court order date cannot be in the future.', 'path': err_path }) except ValueError: err_path = court_order_date_path msg.append({ 'error': 'Invalid court order date format.', 'path': err_path }) if msg: return msg return None
def validate_effective_date(business: Business, cod: Dict) -> List: """Return an error or warning message based on the effective date validation rules. Rules: (text from the BA rules document) - The effective date of change cannot be in the future. - The effective date cannot be a date prior to their Incorporation Date. - The effective date of change cannot be a date that is farther in the past than a previous COD filing (standalone or AR). - The effective date can be the same effective date as another COD filing (standalone or AR). If this is the case: - COD filing that was filed most recently is the most current director information. """ msg = [] # get effective datetime string from filing try: effective_datetime_str = cod['filing']['header']['effectiveDate'] except KeyError: return {'error': babel('No effective date provided.')} # convert string to datetime try: effective_datetime_utc = datetime.fromisoformat(effective_datetime_str) except ValueError: return {'error': babel('Invalid ISO format for effective date.')} # check if effective datetime is in the future if effective_datetime_utc > datetime.utcnow(): msg.append({'error': babel('Filing cannot have a future effective date.')}) # convert to legislation timezone and then get date only effective_date_leg = LegislationDatetime.as_legislation_timezone(effective_datetime_utc).date() # check if effective date is before their incorporation date founding_date_leg = LegislationDatetime.as_legislation_timezone(business.founding_date).date() if effective_date_leg < founding_date_leg: msg.append({'error': babel('Effective date cannot be before businesses founding date.')}) # check if effective date is before their most recent COD or AR date last_cod_filing = Filing.get_most_recent_legal_filing(business.id, Filing.FILINGS['changeOfDirectors']['name']) if last_cod_filing: last_cod_date_leg = LegislationDatetime.as_legislation_timezone(last_cod_filing.effective_date).date() if effective_date_leg < last_cod_date_leg: msg.append({'error': babel('Effective date cannot be before another Change of Director filing.')}) return msg
from legal_api.models import Business, Filing from legal_api.utils.datetime import datetime from entity_filer.filing_meta import FilingMeta from entity_filer.filing_processors.filing_components import create_office, filings from entity_filer.filing_processors.filing_components.parties import update_parties def process(business: Business, filing: Dict, filing_meta: FilingMeta): """Render the dissolution filing unto the model objects.""" if not (dissolution_filing := filing.get('dissolution')): logger.error('Could not find Dissolution in: %s', filing) raise QueueException(f'legal_filing:Dissolution missing from {filing}') logger.debug('processing dissolution: %s', filing) dissolution_date = datetime.fromisoformat( dissolution_filing.get('dissolutionDate')) # Currently we don't use this for anything? # has_liabilities = filing['dissolution'].get('hasLiabilities') business.dissolution_date = dissolution_date # remove all directors and add custodial party if in filing if parties := dissolution_filing.get('parties'): update_parties(business, parties) # add custodial office if provided if custodial_office := dissolution_filing.get('custodialOffice'): if office := create_office(business, 'custodialOffice', custodial_office): business.offices.append(office) else: logger.error(
'error': 'Length of court order file number must be from 5 to 20 characters.', 'path': err_path }) if (effect_of_order := court_order.get( 'effectOfOrder', None)) and effect_of_order != 'planOfArrangement': msg.append({ 'error': 'Invalid effectOfOrder.', 'path': f'{court_order_path}/effectOfOrder' }) court_order_date_path = court_order_path + '/orderDate' if 'orderDate' in court_order: try: court_order_date = dt.fromisoformat(court_order['orderDate']) if court_order_date.timestamp() > datetime.utcnow().timestamp(): err_path = court_order_date_path msg.append({ 'error': 'Court order date cannot be in the future.', 'path': err_path }) except ValueError: err_path = court_order_date_path msg.append({ 'error': 'Invalid court order date format.', 'path': err_path }) if msg: return msg