Пример #1
0
    def _add_office_from_filing(
            cls,
            cursor,  # pylint: disable=too-many-arguments
            event_id,
            corp_num,
            user_id,
            filing):
        office_desc = ''
        text = 'Change to the %s.'

        if filing.filing_type == 'incorporationApplication':
            text = 'Incorporation for %s.'

        for office_type in filing.body['offices']:
            office_arr = filing.body['offices'][office_type]
            delivery_addr_id = Address.create_new_address(
                cursor, office_arr['deliveryAddress'])
            mailing_addr_id = Address.create_new_address(
                cursor, office_arr['mailingAddress'])
            office_desc = (office_type.replace('O', ' O')).title()
            office_code = Office.OFFICE_TYPES_CODES[office_type]
            # update office table to include new addresses
            Office.update_office(cursor, event_id, corp_num, delivery_addr_id,
                                 mailing_addr_id, office_code)
        # create new ledger text for address change
        cls._add_ledger_text(cursor, event_id, text % (office_desc), user_id)
Пример #2
0
    def _get_coa(cls, cursor, identifier: str = None, filing_event_info: dict = None):
        """Get change of address filing for registered and/or records office."""
        office_obj_list = Office.get_by_event(cursor, filing_event_info['event_id'])
        if not office_obj_list:
            raise FilingNotFoundException(identifier=identifier, filing_type='change_of_address',
                                          event_id=filing_event_info['event_id'])

        offices = Office.convert_obj_list(office_obj_list)

        # check to see if this filing was made with an AR -> if it was then set the AR date as the effective date
        effective_date = filing_event_info['event_timestmp']
        annual_reports = cls._get_events(cursor=cursor, identifier=identifier, filing_type_code='OTANN')
        for filing in annual_reports:
            if convert_to_json_date(filing['date']) == convert_to_json_date(effective_date):
                effective_date = filing['annualReportDate']
                break

        filing_obj = Filing()
        filing_obj.body = {
            'offices': offices,
            'eventId': filing_event_info['event_id']
        }
        filing_obj.filing_type = 'changeOfAddress'
        filing_obj.paper_only = False
        filing_obj.effective_date = effective_date

        return filing_obj
Пример #3
0
    def _get_ar(cls, identifier: str = None, filing_event_info: dict = None):
        """Return annual report filing."""
        # get directors and registered office as of this filing
        director_events = cls._get_events(
            identifier=identifier,
            filing_type_code=filing_event_info['filing_type_code'])
        office_events = cls._get_events(
            identifier=identifier,
            filing_type_code=filing_event_info['filing_type_code'])
        director_event_id = None
        office_event_id = None

        tmp_timestamp = datetime.datetime.fromtimestamp(0)
        for event in director_events:
            if filing_event_info['event_timestmp'] >= event[
                    'date'] > tmp_timestamp:
                director_event_id = event['id']
                tmp_timestamp = event['date']
        tmp_timestamp = datetime.datetime.fromtimestamp(0)
        for event in office_events:
            if filing_event_info['event_timestmp'] >= event[
                    'date'] > tmp_timestamp:
                office_event_id = event['id']
                tmp_timestamp = event['date']

        if director_event_id:
            try:
                directors = Director.get_by_event(identifier=identifier,
                                                  event_id=director_event_id)
            except:  # noqa B901; pylint: disable=bare-except;
                # should only get here if event was before the bob date
                directors = Director.get_current(identifier=identifier)
        else:
            directors = Director.get_current(identifier=identifier)
        directors = [x.as_dict() for x in directors]
        if office_event_id:
            try:
                reg_office = Office.get_by_event(event_id=office_event_id)
            except:  # noqa B901; pylint: disable=bare-except;
                # should only get here if event was before the bob date
                reg_office = Office.get_current(identifier=identifier)
        else:
            reg_office = Office.get_current(identifier=identifier)
        reg_office = reg_office.as_dict()
        # convert dates and date-times to correct json format
        agm_date = convert_to_json_date(filing_event_info.get(
            'agm_date', None))
        ar_date = convert_to_json_date(filing_event_info['period_end_dt'])

        filing_obj = Filing()
        filing_obj.body = {
            'annualGeneralMeetingDate': agm_date,
            'annualReportDate': ar_date,
            'directors': directors,
            'eventId': filing_event_info['event_id'],
            **reg_office
        }
        filing_obj.filing_type = 'annualReport'

        return filing_obj
Пример #4
0
    def _get_inc(cls,
                 cursor,
                 identifier: str = None,
                 filing_event_info: dict = None):
        """Get incorporation filing."""
        # business_obj
        office_obj_list = Office.get_by_event(cursor,
                                              filing_event_info['event_id'])
        if not office_obj_list:
            raise FilingNotFoundException(
                identifier=identifier,
                filing_type='change_of_address',
                event_id=filing_event_info['event_id'])

        offices = Office.convert_obj_list(office_obj_list)

        filing_obj = Filing()
        filing_obj.body = {
            'offices': offices,
            'eventId': filing_event_info['event_id']
        }
        filing_obj.filing_type = 'incorporationApplication'
        filing_obj.paper_only = False

        return filing_obj
Пример #5
0
    def get(legal_type: str, identifier: str):
        """Return the registered and/or records office for a corporation."""
        if not identifier:
            return jsonify({'message':
                            'Identifier required'}), HTTPStatus.NOT_FOUND

        try:
            if legal_type in Business.CORP_TYPE_CONVERSION[
                    Business.LearBusinessTypes.BCOMP.value]:
                identifier = identifier[-7:]
            cursor = DB.connection.cursor()
            offices = {}
            office_obj_list = Office.get_current(cursor=cursor,
                                                 identifier=identifier)
            for office_obj in office_obj_list:
                if office_obj.office_type not in offices.keys():
                    offices.update(office_obj.as_dict())
            if not offices.keys():
                return jsonify({
                    'message':
                    f'registered/records office for {identifier} not found'
                }), HTTPStatus.NOT_FOUND
            return {**offices}, HTTPStatus.OK

        except GenericException as err:  # pylint: disable=duplicate-code
            return jsonify({'message': err.error}), err.status_code

        except Exception as err:  # pylint: disable=broad-except; want to catch any exception here
            # general catch-all exception
            current_app.logger.error(err.with_traceback(None))
            return jsonify({
                'message':
                'Error when trying to retrieve registered office from COLIN'
            }), HTTPStatus.INTERNAL_SERVER_ERROR
Пример #6
0
    def get(identifier):
        """Return the registered and/or records office for a corporation."""
        if not identifier:
            return jsonify({'message': 'Identifier required'}), 404

        try:
            offices = {}
            office_obj_list = Office.get_current(identifier=identifier)
            for office_obj in office_obj_list:
                if office_obj.office_type not in offices.keys():
                    offices.update(office_obj.as_dict())
            if len(offices.keys()) < 1:
                return jsonify({
                    'message':
                    f'registered/records office for {identifier} not found'
                }), 404
            return {**offices}, 200

        except GenericException as err:  # pylint: disable=duplicate-code
            return jsonify({'message': err.error}), err.status_code

        except Exception as err:  # pylint: disable=broad-except; want to catch any exception here
            # general catch-all exception
            current_app.logger.error(err.with_traceback(None))
            return jsonify({
                'message':
                'Error when trying to retrieve registered office from COLIN'
            }), 500
Пример #7
0
    def _get_ar(cls, cursor, identifier: str = None, filing_event_info: dict = None):
        """Return annual report filing."""
        # get directors and registered office as of this filing
        director_events = cls._get_events(identifier=identifier, filing_type_code='OTCDR', cursor=cursor)
        office_events = cls._get_events(identifier=identifier, filing_type_code='OTADD', cursor=cursor)
        director_event_id = None
        office_event_id = None

        tmp_timestamp = datetime.datetime.fromtimestamp(0)
        for event in director_events:
            if filing_event_info['event_timestmp'] >= event['date'] > tmp_timestamp:
                director_event_id = event['id']
                tmp_timestamp = event['date']
        tmp_timestamp = datetime.datetime.fromtimestamp(0)
        for event in office_events:
            if filing_event_info['event_timestmp'] >= event['date'] > tmp_timestamp:
                office_event_id = event['id']
                tmp_timestamp = event['date']

        recreated_dirs_and_office = True
        if director_event_id:
            try:
                directors = Party.get_by_event(identifier=identifier, event_id=director_event_id, cursor=cursor)
            except:  # noqa B901; pylint: disable=bare-except;
                # should only get here if agm was before the bob date
                recreated_dirs_and_office = False
                directors = Party.get_current(identifier=identifier, cursor=cursor)
        else:
            directors = Party.get_current(identifier=identifier, cursor=cursor)
        directors = [x.as_dict() for x in directors]
        if office_event_id:
            try:
                office_obj_list = (Office.get_by_event(event_id=office_event_id, cursor=cursor)).as_dict()
                offices = Office.convert_obj_list(office_obj_list)
            except:  # noqa B901; pylint: disable=bare-except;
                # should only get here if agm was before the bob date
                recreated_dirs_and_office = False
                office_obj_list = Office.get_current(identifier=identifier, cursor=cursor)
                offices = Office.convert_obj_list(office_obj_list)

        else:
            office_obj_list = Office.get_current(identifier=identifier, cursor=cursor)
            offices = Office.convert_obj_list(office_obj_list)

        filing_obj = Filing()
        filing_obj.body = {
            'annualGeneralMeetingDate': convert_to_json_date(filing_event_info.get('agm_date', None)),
            'annualReportDate': convert_to_json_date(filing_event_info['period_end_dt']),
            'directors': directors,
            'eventId': filing_event_info['event_id'],
            'offices': offices
        }
        filing_obj.filing_type = 'annualReport'
        filing_obj.paper_only = not recreated_dirs_and_office
        filing_obj.effective_date = filing_event_info['period_end_dt']

        return filing_obj
Пример #8
0
    def _get_inc(cls, cursor, identifier: str = None, filing_event_info: dict = None):
        """Get incorporation filing."""
        # business_obj
        office_obj_list = Office.get_by_event(cursor, filing_event_info['event_id'])
        share_structure = ShareObject.get_all(cursor, identifier, filing_event_info['event_id'])
        parties = Party.get_by_event(cursor, identifier, filing_event_info['event_id'], None)

        if not office_obj_list:
            raise FilingNotFoundException(identifier=identifier, filing_type='change_of_address',
                                          event_id=filing_event_info['event_id'])

        offices = Office.convert_obj_list(office_obj_list)

        filing_obj = Filing()
        filing_obj.body = {
            'offices': offices,
            'eventId': filing_event_info['event_id'],
            'shareClasses': share_structure.to_dict()['shareClasses'],
            'parties': [x.as_dict() for x in parties]
        }
        filing_obj.filing_type = 'incorporationApplication'
        filing_obj.paper_only = False

        return filing_obj
Пример #9
0
    def _get_coa(cls, identifier: str = None, filing_event_info: dict = None):
        """Get change of address filing."""
        registered_office_obj = Office.get_by_event(filing_event_info['event_id'])

        if not registered_office_obj:
            raise FilingNotFoundException(identifier=identifier, filing_type='change_of_address',
                                          event_id=filing_event_info['event_id'])

        filing_obj = Filing()
        filing_obj.body = {
            **registered_office_obj.as_dict(),
            'eventId': filing_event_info['event_id']
        }
        filing_obj.filing_type = 'changeOfAddress'

        return filing_obj
Пример #10
0
    def find_change_of_addr(cls,
                            identifier: str = None,
                            event_id: str = None,
                            year: int = None):  # pylint: disable=unused-argument; will use year later
        """Return change of address filing."""
        if event_id:
            filing_event_info = cls._find_filing_event_info(
                identifier=identifier,
                event_id=event_id,
                filing_type_cd1='OTADD',
                filing_type_cd2='OTARG')
        else:
            filing_event_info = cls._find_filing_event_info(
                identifier=identifier,
                filing_type_cd1='OTADD',
                filing_type_cd2='OTARG')

        registered_office_obj = Office.get_by_event(
            filing_event_info['event_id'])

        if not registered_office_obj:
            raise FilingNotFoundException(identifier=identifier,
                                          filing_type='change_of_address',
                                          event_id=event_id)

        filing_obj = Filing()
        filing_obj.header = {
            'date': convert_to_json_date(filing_event_info['event_timestmp']),
            'name': 'changeOfAddress'
        }
        filing_obj.body = {
            'certifiedBy':
            filing_event_info['certifiedBy'],
            'email':
            filing_event_info['email'],
            **registered_office_obj.as_dict(), 'eventId':
            filing_event_info['event_id']
        }
        filing_obj.filing_type = 'changeOfAddress'

        return filing_obj
Пример #11
0
    def get(identifier):
        """Return the complete business info."""
        if not identifier:
            return jsonify({'message': 'Identifier required'}), 404

        try:
            registered_office = Office.get_current(identifier)
            if not registered_office:
                return jsonify({
                    'message':
                    f'registered office for {identifier} not found'
                }), 404
            return jsonify(registered_office)

        except GenericException as err:  # pylint: disable=duplicate-code
            return jsonify({'message': err.error}), err.status_code

        except Exception as err:  # pylint: disable=broad-except; want to catch any exception here
            # general catch-all exception
            current_app.logger.error(err.with_traceback(None))
            return jsonify({
                'message':
                'Error when trying to retrieve registered office from COLIN'
            }), 500
Пример #12
0
    def add_filing(cls, filing):  # pylint: disable=too-many-locals,too-many-statements,too-many-branches;
        """Add new filing to COLIN tables.

        :param filing: Filing dict.
        :returns (int): the filing ID of the new filing.
        """
        try:
            corp_num = filing.get_corp_num()

            # get db connection and start a session, in case we need to roll back
            con = DB.connection
            con.begin()
            cursor = con.cursor()

            # create new event record, return event ID
            event_id = cls._get_event_id(cursor, corp_num, 'FILE')

            # create new filing user
            cls._create_filing_user(cursor, event_id, filing)
            if filing.filing_type == 'annualReport':
                ar_date = filing.body['annualReportDate']
                agm_date = filing.body['annualGeneralMeetingDate']
                filing_type_cd = 'OTANN'

                # create new filing
                cls._create_filing(cursor, event_id, corp_num, ar_date,
                                   agm_date, filing_type_cd)

                # update corporation record
                Business.update_corporation(cursor, corp_num, agm_date)

                # update corp_state TO ACT (active) if it is in good standing. From CRUD:
                # - the current corp_state != 'ACT' and,
                # - they just filed the last outstanding ARs
                if filing.business.business['corpState'] != 'ACT':
                    agm_year = int(ar_date[:4])
                    last_year = datetime.datetime.now().year - 1
                    if agm_year >= last_year:
                        Business.update_corp_state(cursor,
                                                   event_id,
                                                   corp_num,
                                                   state='ACT')

            elif filing.filing_type == 'changeOfAddress':
                # set date to last ar date + 1
                last_ar_date = filing.business.business['lastArDate']
                day = int(last_ar_date[-2:]) + 1
                try:
                    date = str(
                        datetime.datetime.strptime(
                            last_ar_date[:-2] + ('0' + str(day))[1:],
                            '%Y-%m-%d'))[:10]
                except ValueError:
                    try:
                        day = '-01'
                        month = int(last_ar_date[5:7]) + 1
                        date = str(
                            datetime.datetime.strptime(
                                last_ar_date[:5] + ('0' + str(month))[1:] +
                                day, '%Y-%m-%d'))[:10]
                    except ValueError:
                        mm_dd = '-01-01'
                        yyyy = int(last_ar_date[:4]) + 1
                        date = str(
                            datetime.datetime.strptime(
                                str(yyyy) + mm_dd, '%Y-%m-%d'))[:10]

                # create new filing
                filing_type_cd = 'OTADD'
                cls._create_filing(cursor, event_id, corp_num, date, None,
                                   filing_type_cd)

                # create new addresses for delivery + mailing, return address ids
                delivery_addr_id = Address.create_new_address(
                    cursor, filing.body['deliveryAddress'])
                mailing_addr_id = Address.create_new_address(
                    cursor, filing.body['mailingAddress'])

                # update office table to include new addresses
                Office.update_office(cursor, event_id, corp_num,
                                     delivery_addr_id, mailing_addr_id, 'RG')

                # create new ledger text for address change
                cls._add_ledger_text(
                    cursor, event_id,
                    f'Change to the Registered Office, effective on {date}')
                # update corporation record
                Business.update_corporation(cursor, corp_num)

            elif filing.filing_type == 'changeOfDirectors':
                # create new filing
                date = filing.business.business['lastArDate']
                filing_type_cd = 'OTCDR'
                cls._create_filing(cursor, event_id, corp_num, date, None,
                                   filing_type_cd)

                # create, cease, change directors
                changed_dirs = []
                for director in filing.body['directors']:
                    if 'appointed' in director['actions']:
                        Director.create_new_director(
                            cursor=cursor,
                            event_id=event_id,
                            director=director,
                            business=filing.business.as_dict())

                    if 'ceased' in director['actions'] and not any(
                            elem in ['nameChanged', 'addressChanged']
                            for elem in director['actions']):
                        Director.end_by_name(cursor=cursor,
                                             director=director,
                                             event_id=event_id,
                                             corp_num=corp_num)

                    elif 'nameChanged' in director[
                            'actions'] or 'addressChanged' in director[
                                'actions']:
                        if 'appointed' in director['actions']:
                            current_app.logger.error(
                                f'Director appointed with name/address change: {director}'
                            )
                        changed_dirs.append(director)
                        # end tmp copy of director with no cessation date (will be recreated with changes and cessation
                        # date - otherwise end up with two copies of ended director)
                        tmp = director.copy()
                        tmp['cessationDate'] = ''
                        Director.end_by_name(cursor=cursor,
                                             director=tmp,
                                             event_id=event_id,
                                             corp_num=corp_num)

                # add back changed directors as new row - if ceased director with changes this will add them with
                # cessation date + end event id filled
                for director in changed_dirs:
                    Director.create_new_director(
                        cursor=cursor,
                        event_id=event_id,
                        director=director,
                        business=filing.business.as_dict())

                # create new ledger text for address change
                cls._add_ledger_text(cursor=cursor,
                                     event_id=event_id,
                                     text=f'Director change.')
                # update corporation record
                Business.update_corporation(cursor=cursor, corp_num=corp_num)

            else:
                raise InvalidFilingTypeException(
                    filing_type=filing.filing_type)

            # success! commit the db changes
            con.commit()
            return event_id

        except Exception as err:
            # something went wrong, roll it all back
            current_app.logger.error(err.with_traceback(None))
            if con:
                con.rollback()

            raise err
Пример #13
0
    def _get_ar(
            cls,
            identifier: str = None,
            event_id: str = None,  # pylint: disable=too-many-locals,too-many-branches;
            year: int = None):
        """Return annual report filing."""
        if event_id:
            filing_event_info = cls._get_filing_event_info(
                identifier=identifier,
                event_id=event_id,
                filing_type_cd1='OTANN',
                year=year)
        else:
            filing_event_info = cls._get_filing_event_info(
                identifier=identifier, filing_type_cd1='OTANN', year=year)

        if not filing_event_info:
            raise FilingNotFoundException(identifier=identifier,
                                          filing_type='annualReport',
                                          event_id=event_id)

        # get directors and registered office as of this filing
        director_events = Director.get_events(identifier=identifier)
        office_events = Office.get_events(identifier=identifier)
        director_event_id = None
        office_event_id = None

        tmp_timestamp = datetime.datetime.fromtimestamp(0)
        for event in director_events:
            if filing_event_info['event_timestmp'] >= event[
                    'date'] > tmp_timestamp:
                director_event_id = event['id']
                tmp_timestamp = event['date']
        tmp_timestamp = datetime.datetime.fromtimestamp(0)
        for event in office_events:
            if filing_event_info['event_timestmp'] >= event[
                    'date'] > tmp_timestamp:
                office_event_id = event['id']
                tmp_timestamp = event['date']

        if director_event_id:
            try:
                directors = Director.get_by_event(identifier=identifier,
                                                  event_id=director_event_id)
            except:  # noqa B901; pylint: disable=bare-except;
                # should only get here if event was before the bob date
                directors = Director.get_current(identifier=identifier)
        else:
            directors = Director.get_current(identifier=identifier)
        directors = [x.as_dict() for x in directors]
        if office_event_id:
            try:
                reg_office = Office.get_by_event(event_id=office_event_id)
            except:  # noqa B901; pylint: disable=bare-except;
                # should only get here if event was before the bob date
                reg_office = Office.get_current(identifier=identifier)
        else:
            reg_office = Office.get_current(identifier=identifier)
        reg_office = reg_office.as_dict()
        # convert dates and date-times to correct json format
        filing_event_info['event_timestmp'] = convert_to_json_date(
            filing_event_info['event_timestmp'])
        agm_date = convert_to_json_date(filing_event_info.get(
            'agm_date', None))
        ar_date = convert_to_json_date(filing_event_info['period_end_dt'])

        filing_obj = Filing()

        filing_obj.header = {
            'date': filing_event_info['event_timestmp'],
            'name': 'annualReport',
            'certifiedBy': filing_event_info['certifiedBy'],
            'email': filing_event_info['email']
        }
        filing_obj.body = {
            'annualGeneralMeetingDate': agm_date,
            'annualReportDate': ar_date,
            'directors': directors,
            'eventId': filing_event_info['event_id'],
            **reg_office
        }
        filing_obj.filing_type = 'annualReport'
        filing_obj.event_id = filing_event_info['event_id']  # pylint: disable=attribute-defined-outside-init

        return filing_obj
Пример #14
0
    def _get_ar(cls, identifier: str = None, filing_event_info: dict = None):
        """Return annual report filing."""
        # get directors and registered office as of this filing
        director_events = cls._get_events(identifier=identifier,
                                          filing_type_code='OTCDR')
        office_events = cls._get_events(identifier=identifier,
                                        filing_type_code='OTADD')
        director_event_id = None
        office_event_id = None

        tmp_timestamp = datetime.datetime.fromtimestamp(0)
        for event in director_events:
            if filing_event_info['event_timestmp'] >= event[
                    'date'] > tmp_timestamp:
                director_event_id = event['id']
                tmp_timestamp = event['date']
        tmp_timestamp = datetime.datetime.fromtimestamp(0)
        for event in office_events:
            if filing_event_info['event_timestmp'] >= event[
                    'date'] > tmp_timestamp:
                office_event_id = event['id']
                tmp_timestamp = event['date']

        recreated_dirs_and_office = True
        if director_event_id:
            try:
                directors = Director.get_by_event(identifier=identifier,
                                                  event_id=director_event_id)
            except:  # noqa B901; pylint: disable=bare-except;
                # should only get here if agm was before the bob date
                recreated_dirs_and_office = False
                directors = Director.get_current(identifier=identifier)
        else:
            directors = Director.get_current(identifier=identifier)
        directors = [x.as_dict() for x in directors]
        if office_event_id:
            try:
                reg_office = Office.get_by_event(event_id=office_event_id)
            except:  # noqa B901; pylint: disable=bare-except;
                # should only get here if agm was before the bob date
                recreated_dirs_and_office = False
                reg_office = Office.get_current(identifier=identifier)
        else:
            reg_office = Office.get_current(identifier=identifier)
        reg_office = reg_office.as_dict()
        # convert dates and date-times to correct json format
        agm_date = convert_to_json_date(filing_event_info.get(
            'agm_date', None))
        ar_date = convert_to_json_date(filing_event_info['period_end_dt'])
        # paper filings from colin don't enter in the agm_date and don't have no agm filings in the filings table
        if filing_event_info['user_id'] != 'COOPER' and not agm_date:
            agm_date = ar_date
        filing_obj = Filing()
        filing_obj.body = {
            'annualGeneralMeetingDate': agm_date,
            'annualReportDate': ar_date,
            'directors': directors,
            'eventId': filing_event_info['event_id'],
            **reg_office
        }
        filing_obj.filing_type = 'annualReport'
        filing_obj.paper_only = not recreated_dirs_and_office
        filing_obj.effective_date = filing_event_info['period_end_dt']

        return filing_obj
Пример #15
0
    def add_filing(cls, con, filing):  # pylint: disable=too-many-locals,too-many-statements,too-many-branches;
        """Add new filing to COLIN tables.

        :param con: DB connection
        :param filing: Filing dict.
        :returns (int): the filing ID of the new filing.
        """
        try:
            corp_num = filing.get_corp_num()
            user_id = 'COOPER' if corp_num[:2] == 'CP' else None
            cursor = con.cursor()

            # create new event record, return event ID
            event_id = cls._get_event_id(cursor, corp_num, 'FILE')

            # create new filing user
            cls._create_filing_user(cursor, event_id, filing, user_id)
            if filing.filing_type == 'annualReport':
                ar_date = filing.body['annualReportDate']
                agm_date = filing.body['annualGeneralMeetingDate']
                filing_type_cd = 'OTANN'

                # create new filing
                cls._create_filing(cursor, event_id, corp_num, ar_date,
                                   agm_date, filing_type_cd)

                # update corporation record
                Business.update_corporation(cursor, corp_num, agm_date, True)

                # update corp_state TO ACT (active) if it is in good standing. From CRUD:
                # - the current corp_state != 'ACT' and,
                # - they just filed the last outstanding ARs
                agm_year = int(ar_date[:4])
                if filing.business.business['corpState'] != 'ACT':
                    last_year = datetime.datetime.now().year - 1
                    if agm_year >= last_year:
                        Business.update_corp_state(cursor,
                                                   event_id,
                                                   corp_num,
                                                   state='ACT')

                # create new ledger text for annual report
                text = agm_date if agm_date else f'NO AGM HELD IN {agm_year}'
                cls._add_ledger_text(cursor=cursor,
                                     event_id=event_id,
                                     text=f'ANNUAL REPORT - {text}',
                                     user_id=user_id)

            elif filing.filing_type == 'changeOfAddress':
                # set date to last ar date + 1 -- Bob wants this to be set to null
                # last_ar_date = filing.business.business['lastArDate']
                # day = int(last_ar_date[-2:]) + 1
                # try:
                #     date = str(datetime.datetime.strptime(last_ar_date[:-2] + ('0' + str(day))[1:], '%Y-%m-%d'))[:10]
                # except ValueError:
                #     try:
                #         day = '-01'
                #         month = int(last_ar_date[5:7]) + 1
                #         date = str(datetime.datetime.strptime(last_ar_date[:5] + ('0' + str(month))[1:] + day,
                #                                               '%Y-%m-%d')
                #                    )[:10]
                #     except ValueError:
                #         mm_dd = '-01-01'
                #         yyyy = int(last_ar_date[:4]) + 1
                #         date = str(datetime.datetime.strptime(str(yyyy) + mm_dd, '%Y-%m-%d'))[:10]
                date = None

                # create new filing
                filing_type_cd = 'OTADD'
                cls._create_filing(cursor, event_id, corp_num, date, None,
                                   filing_type_cd)

                # create new addresses for delivery + mailing, return address ids
                for office_type in filing.body['offices']:
                    office_arr = filing.body['offices'][office_type]
                    delivery_addr_id = Address.create_new_address(
                        cursor, office_arr['deliveryAddress'])
                    mailing_addr_id = Address.create_new_address(
                        cursor, office_arr['mailingAddress'])
                    office_desc = (office_type.replace('O', ' O')).title()
                    office_code = Office.OFFICE_TYPES_CODES[office_type]

                    # update office table to include new addresses
                    Office.update_office(cursor, event_id, corp_num,
                                         delivery_addr_id, mailing_addr_id,
                                         office_code)

                    # create new ledger text for address change
                    cls._add_ledger_text(cursor, event_id,
                                         f'Change to the {office_desc}.',
                                         user_id)
                # update corporation record
                Business.update_corporation(cursor, corp_num)

            elif filing.filing_type == 'changeOfDirectors':
                # create new filing
                # bob wants this to be null
                # date = filing.business.business['lastArDate']
                date = None
                filing_type_cd = 'OTCDR'
                cls._create_filing(cursor, event_id, corp_num, date, None,
                                   filing_type_cd)

                # create, cease, change directors
                changed_dirs = []
                for director in filing.body['directors']:
                    if 'appointed' in director['actions']:
                        Director.create_new_director(
                            cursor=cursor,
                            event_id=event_id,
                            director=director,
                            business=filing.business.as_dict())

                    if 'ceased' in director['actions'] and not any(
                            elem in ['nameChanged', 'addressChanged']
                            for elem in director['actions']):
                        Director.end_by_name(cursor=cursor,
                                             director=director,
                                             event_id=event_id,
                                             corp_num=corp_num)

                    elif 'nameChanged' in director[
                            'actions'] or 'addressChanged' in director[
                                'actions']:
                        if 'appointed' in director['actions']:
                            current_app.logger.error(
                                f'Director appointed with name/address change: {director}'
                            )
                        changed_dirs.append(director)
                        # end tmp copy of director with no cessation date (will be recreated with changes and cessation
                        # date - otherwise end up with two copies of ended director)
                        tmp = director.copy()
                        tmp['cessationDate'] = ''
                        Director.end_by_name(cursor=cursor,
                                             director=tmp,
                                             event_id=event_id,
                                             corp_num=corp_num)

                # add back changed directors as new row - if ceased director with changes this will add them with
                # cessation date + end event id filled
                for director in changed_dirs:
                    Director.create_new_director(
                        cursor=cursor,
                        event_id=event_id,
                        director=director,
                        business=filing.business.as_dict())

                # create new ledger text for address change
                cls._add_ledger_text(cursor=cursor,
                                     event_id=event_id,
                                     text=f'Director change.',
                                     user_id=user_id)
                # update corporation record
                Business.update_corporation(cursor=cursor, corp_num=corp_num)

            else:
                raise InvalidFilingTypeException(
                    filing_type=filing.filing_type)

            return event_id

        except Exception as err:
            # something went wrong, roll it all back
            current_app.logger.error(err.with_traceback(None))

            raise err