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
Exemple #3
0
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
Exemple #6
0
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