예제 #1
0
 def _add_filings(con, json_data: dict, filing_list: list, identifier: str,
                  corp_types: list) -> list:
     """Process all parts of the filing."""
     filings_added = []
     for filing_type in filing_list:
         filing = Filing()
         filing.header = json_data['header']
         filing.filing_date = filing.header['date']
         filing.filing_type = filing_type
         filing.body = filing_list[filing_type]
         print('body: ', filing.body)
         # get utc lear effective date and convert to pacific time for insert into oracle
         filing.effective_date = convert_to_pacific_time(
             filing.header['learEffectiveDate'])
         if filing_type != 'incorporationApplication':
             filing.business = Business.find_by_identifier(
                 identifier, corp_types, con)
         else:
             filing.business = Business.create_corporation(con, json_data)
         # add the new filing
         event_id = Filing.add_filing(con, filing)
         filings_added.append({
             'event_id': event_id,
             'filing_type': filing_type
         })
     return filings_added
예제 #2
0
    def get(identifier=None):
        """Return the complete business info."""
        if not identifier:
            try:
                con = DB.connection
                con.begin()
                corp_type = request.args.get('legal_type', None).upper()
                corp_num = Business.get_next_corp_num(corp_type, con)
                con.commit()
            except Exception as err:  # pylint: disable=broad-except; want to catch all errors
                current_app.logger.error(err.with_traceback(None))
                if con:
                    con.rollback()

            if corp_num:
                return jsonify({'corpNum': corp_num}), 200

            return jsonify({'message': 'Identifier required'}), 404

        try:
            business = Business.find_by_identifier(identifier)
            if not business:
                return jsonify({'message': f'{identifier} not found'}), 404
            return jsonify(business.as_dict())

        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 all errors
            # general catch-all exception
            current_app.logger.error(err.with_traceback(None))
            return jsonify(
                {'message': 'Error when trying to retrieve business record from COLIN'}), 500
예제 #3
0
    def post(identifier, **kwargs):  # pylint: disable=unused-argument; filing_type is only used for the get
        """Create a new filing."""
        try:
            json_data = request.get_json()
            if not json_data:
                return jsonify({'message': 'No input data provided'}), 400

            # validate schema
            is_valid, errors = validate(json_data, 'filing', validate_schema=True)
            if not is_valid:
                for err in errors:
                    print(err.message)
                return jsonify(
                    {'message': 'Error: Invalid Filing schema'}), 400

            json_data = json_data.get('filing', None)

            filing_list = {'changeOfAddress': json_data.get('changeOfAddress', None),
                           'changeOfDirectors': json_data.get('changeOfDirectors', None),
                           'annualReport': json_data.get('annualReport', None)}

            # ensure that the business in the AR matches the business in the URL
            if identifier != json_data['business']['identifier']:
                return jsonify(
                    {'message': 'Error: Identifier in URL does not match identifier in filing data'}), 400

            filings_added = []
            for filing_type in filing_list:
                if filing_list[filing_type]:
                    filing = Filing()
                    filing.business = Business.find_by_identifier(identifier)
                    filing.header = json_data['header']
                    filing.filing_type = filing_type
                    filing.body = filing_list[filing_type]

                    # add the new filing
                    event_id = Filing.add_filing(filing)
                    filings_added.append({'event_id': event_id, 'filing_type': filing_type})

            # return the completed filing data
            completed_filing = Filing()
            completed_filing.header = json_data['header']
            # get business info again - could have changed since filings were applied
            completed_filing.business = Business.find_by_identifier(identifier)
            completed_filing.body = {}
            for filing_info in filings_added:
                filing = Filing.find_filing(business=completed_filing.business, event_id=filing_info['event_id'],
                                            filing_type=filing_info['filing_type'])
                if not filing:
                    raise FilingNotFoundException(identifier=identifier, filing_type=filing_info['filing_type'],
                                                  event_id=filing_info['event_id'])
                completed_filing.body.update({filing_info['filing_type']: filing.body})

            return jsonify(completed_filing.as_dict()), 201

        except Exception as err:  # pylint: disable=broad-except; want to catch all errors
            # general catch-all exception
            current_app.logger.error(err.with_traceback(None))
            return jsonify(
                {'message': 'Error when trying to retrieve business record from COLIN'}), 500
예제 #4
0
    def get(info_type,
            legal_type=None,
            identifier=None):  # pylint: disable = too-many-return-statements;
        """Return specific business info for businesses."""
        try:
            con = DB.connection
            con.begin()
            cursor = con.cursor()

            if info_type == 'tax_ids':
                json_data = request.get_json()
                if not json_data or not json_data['identifiers']:
                    return jsonify({'message': 'No input data provided'
                                    }), HTTPStatus.BAD_REQUEST
                # remove the BC prefix
                identifiers = [x[-7:] for x in json_data['identifiers']]
                bn_15s = Business._get_bn_15s(  # pylint: disable = protected-access; internal call
                    cursor=cursor,
                    identifiers=identifiers)
                return jsonify(bn_15s), HTTPStatus.OK

            if info_type == 'resolutions':
                if not legal_type or legal_type not in [
                        x.value for x in Business.LearBusinessTypes
                ]:
                    return jsonify({
                        'message':
                        'Must provide a valid legal type.'
                    }), HTTPStatus.BAD_REQUEST

                if not identifier:
                    return jsonify({
                        'message':
                        f'Must provide a business identifier for {info_type}.'
                    }), HTTPStatus.BAD_REQUEST

                # convert identifier if BC legal_type
                if legal_type in Business.CORP_TYPE_CONVERSION[
                        Business.LearBusinessTypes.BCOMP.value]:
                    identifier = identifier[-7:]

                return jsonify({
                    'resolutionDates':
                    Business.get_resolutions(cursor=cursor,
                                             corp_num=identifier)
                }), HTTPStatus.OK

            return jsonify({'message': f'{info_type} not implemented.'
                            }), HTTPStatus.NOT_IMPLEMENTED

        except Exception as err:  # pylint: disable=broad-except; want to catch all errors
            current_app.logger.error(err.with_traceback(None))
            return jsonify({'message': 'Something went wrong.'
                            }), HTTPStatus.INTERNAL_SERVER_ERROR
예제 #5
0
 def _add_filings(con, json_data, filing_list, identifier):
     filings_added = []
     for filing_type in filing_list:
         filing = Filing()
         if filing_type != 'incorporationApplication':
             filing.business = Business.find_by_identifier(identifier, con)
         else:
             filing.business = Business.insert_new_business(con, filing_list[filing_type])
         filing.header = json_data['header']
         filing.filing_type = filing_type
         filing.body = filing_list[filing_type]
         filing.business.business['legalName'] = json_data['business']['legalName']
         # add the new filing
         event_id = Filing.add_filing(con, filing)
         filings_added.append({'event_id': event_id, 'filing_type': filing_type})
     return filings_added
예제 #6
0
파일: filing.py 프로젝트: sumesh-aot/lear
    def find_filing(cls, business: Business = None, filing_type: str = None, year: int = None):
        """Return a Filing."""
        if not business or not filing_type:
            return None

        try:
            identifier = business.get_corp_num()

            # set filing type code from filing_type (string)
            if filing_type == 'annualReport':
                filing_type_code = 'OTANN'
                filing_obj = cls.find_ar(business, identifier, year)

            elif filing_type == 'changeOfAddress':
                filing_obj = cls.find_change_of_addr(business, identifier, year)
            else:
                # default value
                filing_type_code = 'FILE'
                raise InvalidFilingTypeException

            return filing_obj

        except FilingNotFoundException as err:
            # pass through exception to caller
            raise err

        except Exception as err:
            # general catch-all exception
            current_app.logger.error(err.with_traceback(None))

            # pass through exception to caller
            raise err
예제 #7
0
파일: filing.py 프로젝트: kulpree/lear
    def get(identifier, filing_type):
        """Return the complete filing info or historic (pre-bob-date=2019-03-08) filings."""
        try:
            # get optional parameters (event_id / year)
            event_id = request.args.get('eventId', None)
            year = request.args.get('year', None)
            if year:
                year = int(year)

            # get business
            business = Business.find_by_identifier(identifier)

            # get filings history from before bob-date
            if filing_type == 'historic':
                historic_filings_info = Filing.get_historic_filings(
                    business=business)
                return jsonify(historic_filings_info)

            # else get filing
            filing = Filing.get_filing(business=business,
                                       event_id=event_id,
                                       filing_type=filing_type,
                                       year=year)
            return jsonify(filing.as_dict())

        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 all errors
            # general catch-all exception
            current_app.logger.error(err.with_traceback(None))
            return jsonify({
                'message':
                'Error when trying to retrieve business record from COLIN'
            }), 500
예제 #8
0
파일: business.py 프로젝트: ochiu/lear
    def get(info_type):
        """Return specific business info for businesses."""
        if info_type == 'tax_ids':
            json_data = request.get_json()
            if not json_data or not json_data['identifiers']:
                return jsonify({'message': 'No input data provided'
                                }), HTTPStatus.BAD_REQUEST
            # remove the BC prefix
            identifiers = [x[-7:] for x in json_data['identifiers']]
            try:
                con = DB.connection
                con.begin()
                cursor = con.cursor()
                bn_15s = Business._get_bn_15s(  # pylint: disable = protected-access; internal call
                    cursor=cursor,
                    identifiers=identifiers)
                return jsonify(bn_15s), HTTPStatus.OK

            except Exception as err:  # pylint: disable=broad-except; want to catch all errors
                current_app.logger.error(err.with_traceback(None))
                return jsonify({'message': 'Something went wrong.'
                                }), HTTPStatus.INTERNAL_SERVER_ERROR

        return jsonify({'message': f'{info_type} not implemented.'
                        }), HTTPStatus.NOT_IMPLEMENTED
예제 #9
0
    def get(legal_type: str, identifier: str):
        """Return the complete business info."""
        if legal_type not in [x.value for x in Business.LearBusinessTypes]:
            return jsonify({'message': 'Must provide a valid legal type.'
                            }), HTTPStatus.BAD_REQUEST

        try:
            # convert identifier if BC legal_type
            if legal_type in Business.CORP_TYPE_CONVERSION[
                    Business.LearBusinessTypes.BCOMP.value]:
                identifier = identifier[-7:]

            # get business
            corp_types = Business.CORP_TYPE_CONVERSION[legal_type]
            business = Business.find_by_identifier(identifier, corp_types)
            if not business:
                return jsonify({'message': f'{identifier} not found'
                                }), HTTPStatus.NOT_FOUND
            return jsonify(business.as_dict()), 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 all errors
            # general catch-all exception
            current_app.logger.error(err.with_traceback(None))
            return jsonify({
                'message':
                'Error when trying to retrieve business record from COLIN'
            }), HTTPStatus.INTERNAL_SERVER_ERROR
예제 #10
0
    def get_historic_filings(cls, business: Business = None):
        """Get list all filings from before the bob-date=2019-03-08."""
        if not business:
            return None

        try:
            historic_filings = []
            cursor = DB.connection.cursor()
            cursor.execute("""
                select event.event_id, event_timestmp, filing_typ_cd, effective_dt, period_end_dt, agm_date
                from event join filing on event.event_id = filing.event_id
                where corp_num=:identifier
                order by event_timestmp
                """,
                           identifier=business.get_corp_num()
                           )
            filings_info_list = []
            for filing_info in cursor:
                filings_info_list.append(dict(zip([x[0].lower() for x in cursor.description], filing_info)))
            for filing_info in filings_info_list:
                if not cls.FILING_TYPES[filing_info['filing_typ_cd']]:
                    raise InvalidFilingTypeException(filing_type=filing_info['filing_typ_cd'])
                filing_info['filing_type'] = cls.FILING_TYPES[filing_info['filing_typ_cd']]
                date = convert_to_json_date(filing_info['event_timestmp'])
                if date < '2019-03-08':
                    filing = Filing()
                    filing.business = business
                    filing.header = {
                        'date': date,
                        'name': filing_info['filing_type'],
                        'effectiveDate': convert_to_json_date(filing_info['effective_dt']),
                        'historic': True,
                        'availableOnPaperOnly': True,
                        'colinIds': [filing_info['event_id']]
                    }
                    filing.body = {
                        filing_info['filing_type']: {
                            'annualReportDate': convert_to_json_date(filing_info['period_end_dt']),
                            'annualGeneralMeetingDate': convert_to_json_date(filing_info['agm_date'])
                        }
                    }
                    historic_filings.append(filing.as_dict())
            return historic_filings

        except InvalidFilingTypeException as err:
            current_app.logger.error('Unknown filing type found when getting historic filings for '
                                     f'{business.get_corp_num()}.')
            # pass through exception to caller
            raise err

        except Exception as err:
            # general catch-all exception
            current_app.logger.error(err.with_traceback(None))

            # pass through exception to caller
            raise err
예제 #11
0
    def get(legal_type, identifier, filing_type):
        """Return the complete filing info or historic (pre-bob-date=2019-03-08) filings."""
        try:
            if legal_type not in [x.value for x in Business.LearBusinessTypes]:
                return jsonify({'message': 'Must provide a valid legal type.'
                                }), HTTPStatus.BAD_REQUEST

            # get optional parameters (event_id / year)
            event_id = request.args.get('eventId', None)
            year = request.args.get('year', None)
            if year:
                year = int(year)

            # convert identifier if BC legal_type
            if legal_type in Business.CORP_TYPE_CONVERSION[
                    Business.LearBusinessTypes.BCOMP.value]:
                identifier = identifier[-7:]

            # get business
            corp_types = Business.CORP_TYPE_CONVERSION[legal_type]
            business = Business.find_by_identifier(identifier, corp_types)

            # get filings history from before bob-date
            if filing_type == 'historic':
                historic_filings_info = Filing.get_historic_filings(
                    business=business)
                return jsonify(historic_filings_info)

            # else get filing
            filing = Filing()
            filing.business = business
            filing.filing_type = filing_type
            filing.event_id = event_id
            filing = Filing.get_filing(filing=filing, year=year)
            return jsonify(filing.as_dict())

        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 all errors
            # general catch-all exception
            current_app.logger.error(err.with_traceback(None))
            return jsonify({
                'message':
                'Error when trying to retrieve business record from COLIN'
            }), HTTPStatus.INTERNAL_SERVER_ERROR
예제 #12
0
    def _build_parties_list(cls,
                            cursor,
                            corp_num: str,
                            event_id: int = None) -> Optional[List]:
        parties = cursor.fetchall()

        if not parties:
            return None

        completing_parties = {}
        party_list = []
        description = cursor.description
        for row in parties:
            party = Party()
            party.title = ''
            row = dict(zip([x[0].lower() for x in description], row))
            if not row['appointment_dt']:
                row['appointment_dt'] = Business.get_founding_date(
                    cursor=cursor, corp_num=corp_num)
            party.officer = cls._get_officer(row)
            if (row.get('party_typ_cd', None) == cls.role_types['Director']
                ) and not row['delivery_addr_id']:
                current_app.logger.error(
                    f"Bad director data for {party.officer.get('firstName')} {party.officer.get('lastName')} {corp_num}"
                )
            else:
                if row['delivery_addr_id']:
                    party.delivery_address = Address.get_by_address_id(
                        cursor, row['delivery_addr_id']).as_dict()
                party.mailing_address = Address.get_by_address_id(cursor, row['mailing_addr_id']).as_dict() \
                    if row['mailing_addr_id'] else party.delivery_address
                party.appointment_date =\
                    convert_to_json_date(row.get('appointment_dt', None))
                party.cessation_date = convert_to_json_date(
                    row.get('cessation_dt', None))
                party.start_event_id = (row.get('start_event_id', '')) or ''
                party.end_event_id = (row.get('end_event_id', '')) or ''
                party.role_type = (row.get('party_typ_cd', '')) or ''
                party.corp_party_id = row.get('corp_party_id', None)

                party_list.append(party)
        if event_id:
            completing_parties = cls.get_completing_parties(cursor, event_id)
        return cls.group_parties(party_list, completing_parties)
예제 #13
0
파일: filing.py 프로젝트: kulpree/lear
    def get_filing(cls,
                   business: Business = None,
                   event_id: str = None,
                   filing_type: str = None,
                   year: int = None):
        """Get a Filing."""
        if not business or not filing_type:
            return None

        try:
            identifier = business.get_corp_num()

            if filing_type == 'annualReport':
                filing_obj = cls._get_ar(identifier=identifier,
                                         event_id=event_id,
                                         year=year)

            elif filing_type == 'changeOfAddress':
                filing_obj = cls._get_coa(identifier=identifier,
                                          event_id=event_id,
                                          year=year)

            elif filing_type == 'changeOfDirectors':
                filing_obj = cls._get_cod(identifier=identifier,
                                          event_id=event_id,
                                          year=year)

            else:
                raise InvalidFilingTypeException(filing_type=filing_type)

            filing_obj.business = business

            return filing_obj

        except FilingNotFoundException as err:
            # pass through exception to caller
            raise err

        except Exception as err:
            # general catch-all exception
            current_app.logger.error(err.with_traceback(None))

            # pass through exception to caller
            raise err
예제 #14
0
    def get(identifier):
        """Return the complete business info."""
        if not identifier:
            return jsonify({'message': 'Identifier required'}), 404

        try:
            business = Business.find_by_identifier(identifier)
            if not business:
                return jsonify({'message': f'{identifier} not found'}), 404
            return jsonify(business.as_dict())

        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 all errors
            # general catch-all exception
            current_app.logger.error(err.with_traceback(None))
            return jsonify({
                'message':
                'Error when trying to retrieve business record from COLIN'
            }), 500
예제 #15
0
    def post(legal_type: str):
        """Create and return a new corp number for the given legal type."""
        if legal_type not in [x.value for x in Business.LearBusinessTypes]:
            return jsonify({'message': 'Must provide a valid legal type.'
                            }), HTTPStatus.BAD_REQUEST

        try:
            con = DB.connection
            con.begin()
            corp_num = Business.get_next_corp_num(con=con,
                                                  corp_type=legal_type)
            con.commit()
        except Exception as err:  # pylint: disable=broad-except; want to catch all errors
            current_app.logger.error(err.with_traceback(None))
            if con:
                con.rollback()

        if corp_num:
            return jsonify({'corpNum': corp_num}), HTTPStatus.OK

        return jsonify({'message': 'Failed to get new corp number'
                        }), HTTPStatus.INTERNAL_SERVER_ERROR
예제 #16
0
파일: filing.py 프로젝트: kulpree/lear
    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
예제 #17
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()
            legal_type = corp_num[:2]
            user_id = Filing.USERS[legal_type] if legal_type in ('CP', 'BC') 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

                cls._add_office_from_filing(cursor, event_id, corp_num, user_id, filing)
                # 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']:
                        Party.create_new_corp_party(cursor=cursor, event_id=event_id, party=director,
                                                    business=filing.business.as_dict())

                    if 'ceased' in director['actions'] and not any(elem in ['nameChanged', 'addressChanged']
                                                                   for elem in director['actions']):
                        Party.end_director_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'] = ''
                        Party.end_director_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:
                    Party.create_new_corp_party(cursor=cursor, event_id=event_id, party=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)
            elif filing.filing_type == 'incorporationApplication':
                # Add business, update business info
                # Add offices
                date = None
                filing_type_cd = 'OTINC'
                cls._create_filing(cursor, event_id, corp_num, date, None, filing_type_cd)
                # Do incorporation here
                Business.create_corp_name(cursor, corp_num, 'test name', event_id)
                Business.create_corp_state(cursor, corp_num, event_id)

                cls._add_office_from_filing(cursor, event_id, corp_num, user_id, filing)
                cls._add_parties_from_filing(cursor, event_id, filing)
                cls._add_shares_from_filing(cursor, event_id, corp_num, filing)

            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
예제 #18
0
    def get_filing(cls, con=None,  # pylint: disable=too-many-arguments, too-many-branches;
                   business: Business = None, event_id: str = None, filing_type: str = None, year: int = None):
        """Get a Filing."""
        if not business or not filing_type:
            return None

        try:
            if not con:
                con = DB.connection
                con.begin()
            cursor = con.cursor()
            identifier = business.get_corp_num()

            # get the filing types corresponding filing code
            code = [key for key in cls.FILING_TYPES if cls.FILING_TYPES[key] == filing_type]
            if len(code) < 1:
                raise InvalidFilingTypeException(filing_type=filing_type)

            # get the filing event info
            filing_event_info = cls._get_filing_event_info(identifier=identifier, event_id=event_id,
                                                           filing_type_cd=code[0], year=year, cursor=cursor)
            if not filing_event_info:
                raise FilingNotFoundException(identifier=identifier, filing_type=filing_type, event_id=event_id)

            if filing_type == 'annualReport':
                filing_obj = cls._get_ar(identifier=identifier, filing_event_info=filing_event_info, cursor=cursor)

            elif filing_type == 'changeOfAddress':
                filing_obj = cls._get_coa(identifier=identifier, filing_event_info=filing_event_info, cursor=cursor)

            elif filing_type == 'changeOfDirectors':
                filing_obj = cls._get_cod(identifier=identifier, filing_event_info=filing_event_info, cursor=cursor)

            elif filing_type == 'changeOfName':
                filing_obj = cls._get_con(identifier=identifier, filing_event_info=filing_event_info, cursor=cursor)

            elif filing_type == 'specialResolution':
                filing_obj = cls._get_sr(identifier=identifier, filing_event_info=filing_event_info, cursor=cursor)

            elif filing_type == 'voluntaryDissolution':
                filing_obj = cls._get_vd(identifier=identifier, filing_event_info=filing_event_info, cursor=cursor)

            elif filing_type == 'incorporationApplication':
                filing_obj = cls._get_inc(identifier=identifier, filing_event_info=filing_event_info, cursor=cursor)

            else:
                # uncomment to bring in other filings as available on paper only
                # filing_obj = cls._get_other(identifier=identifier, filing_event_info=filing_event_info, cursor=cursor)
                raise InvalidFilingTypeException(filing_type=filing_type)

            filing_obj.header = {
                'availableOnPaperOnly': filing_obj.paper_only,
                'certifiedBy': filing_event_info['certifiedBy'],
                'colinIds': [filing_obj.body['eventId']],
                'date': convert_to_json_date(filing_event_info['event_timestmp']),
                'effectiveDate': convert_to_json_datetime(filing_obj.effective_date),
                'email': filing_event_info['email'],
                'name': filing_type
            }
            filing_obj.business = business

            return filing_obj

        except FilingNotFoundException as err:
            # pass through exception to caller
            raise err

        except Exception as err:
            # general catch-all exception
            current_app.logger.error(err.with_traceback(None))

            # pass through exception to caller
            raise err
예제 #19
0
    def post(identifier, **kwargs):
        """Create a new filing."""
        # pylint: disable=unused-argument,too-many-branches; filing_type is only used for the get
        try:
            json_data = request.get_json()
            if not json_data:
                return jsonify({'message': 'No input data provided'}), 400

            # validate schema
            is_valid, errors = validate(json_data, 'filing', validate_schema=True)
            if not is_valid:
                for err in errors:
                    print(err.message)
                return jsonify(
                    {'message': 'Error: Invalid Filing schema'}), 400

            json_data = json_data.get('filing', None)

            filing_list = {'changeOfAddress': json_data.get('changeOfAddress', None),
                           'changeOfDirectors': json_data.get('changeOfDirectors', None),
                           'annualReport': json_data.get('annualReport', None),
                           'incorporationApplication': json_data.get('incorporationApplication', None)}

            # Filter out null-values in the filing_list dictionary
            filing_list = {k: v for k, v in filing_list.items() if filing_list[k]}

            # ensure that the business in the AR matches the business in the URL
            if identifier != json_data['business']['identifier']:
                return jsonify(
                    {'message': 'Error: Identifier in URL does not match identifier in filing data'}), 400

            try:
                # get db connection and start a session, in case we need to roll back
                con = DB.connection
                con.begin()
                filings_added = FilingInfo._add_filings(con, json_data, filing_list, identifier)

                # return the completed filing data
                completed_filing = Filing()
                completed_filing.header = json_data['header']
                completed_filing.header['colinIds'] = []
                search_corp_num = json_data['business']['identifier']
                if search_corp_num[:2] != 'CP':
                    search_corp_num = search_corp_num[-7:]
                # get business info again - could have changed since filings were applied
                completed_filing.business = Business.find_by_identifier(search_corp_num, con)
                completed_filing.body = {}
                for filing_info in filings_added:
                    filing = Filing.get_filing(con=con, business=completed_filing.business,
                                               event_id=filing_info['event_id'], filing_type=filing_info['filing_type'])
                    if not filing:
                        raise FilingNotFoundException(identifier=identifier, filing_type=filing_info['filing_type'],
                                                      event_id=filing_info['event_id'])
                    completed_filing.body.update({filing_info['filing_type']: filing.body})
                    completed_filing.header['colinIds'].append(filing_info['event_id'])

                # success! commit the db changes
                con.commit()
                return jsonify(completed_filing.as_dict()), 201

            except Exception as db_err:
                current_app.logger.error(db_err.with_traceback(None))
                if con:
                    con.rollback()
                raise db_err

        except Exception as err:  # pylint: disable=broad-except; want to catch all errors
            # general catch-all exception
            current_app.logger.error(err.with_traceback(None))
            return jsonify(
                {'message': 'Error when trying to retrieve business record from COLIN'}), 500
예제 #20
0
    def get_filing(cls,
                   business: Business = None,
                   event_id: str = None,
                   filing_type: str = None,
                   year: int = None):
        """Get a Filing."""
        if not business or not filing_type:
            return None

        try:
            identifier = business.get_corp_num()

            # get the filing types corresponding filing code
            code = [
                key for key in cls.FILING_TYPES
                if cls.FILING_TYPES[key] == filing_type
            ]
            if len(code) < 1:
                raise InvalidFilingTypeException(filing_type=filing_type)

            # get the filing event info
            filing_event_info = cls._get_filing_event_info(
                identifier=identifier,
                event_id=event_id,
                filing_type_cd=code[0],
                year=year)
            if not filing_event_info:
                raise FilingNotFoundException(identifier=identifier,
                                              filing_type=filing_type,
                                              event_id=event_id)

            if filing_type == 'annualReport':
                filing_obj = cls._get_ar(identifier=identifier,
                                         filing_event_info=filing_event_info)

            elif filing_type == 'changeOfAddress':
                filing_obj = cls._get_coa(identifier=identifier,
                                          filing_event_info=filing_event_info)

            elif filing_type == 'changeOfDirectors':
                filing_obj = cls._get_cod(identifier=identifier,
                                          filing_event_info=filing_event_info)

            elif filing_type == 'changeOfName':
                filing_obj = cls._get_con(identifier=identifier,
                                          filing_event_info=filing_event_info)

            elif filing_type == 'specialResolution':
                filing_obj = cls._get_sr(identifier=identifier,
                                         filing_event_info=filing_event_info)

            elif filing_type == 'voluntaryDissolution':
                filing_obj = cls._get_vd(identifier=identifier,
                                         filing_event_info=filing_event_info)

            else:
                raise InvalidFilingTypeException(filing_type=filing_type)

            filing_obj.header = {
                'date':
                convert_to_json_date(filing_event_info['event_timestmp']),
                'name':
                filing_type,
                'certifiedBy':
                filing_event_info['certifiedBy'],
                'email':
                filing_event_info['email'],
                'availableOnPaperOnly':
                filing_obj.filing_type
                in ['voluntaryDissolution', 'specialResolution']
            }
            filing_obj.business = business

            return filing_obj

        except FilingNotFoundException as err:
            # pass through exception to caller
            raise err

        except Exception as err:
            # general catch-all exception
            current_app.logger.error(err.with_traceback(None))

            # pass through exception to caller
            raise err
예제 #21
0
    def post(legal_type, identifier, **kwargs):
        """Create a new filing."""
        # pylint: disable=unused-argument,too-many-branches; filing_type is only used for the get
        try:
            if legal_type not in [x.value for x in Business.LearBusinessTypes]:
                return jsonify({'message': 'Must provide a valid legal type.'
                                }), HTTPStatus.BAD_REQUEST

            json_data = request.get_json()
            if not json_data:
                return jsonify({'message': 'No input data provided'
                                }), HTTPStatus.BAD_REQUEST

            # validate schema
            is_valid, errors = validate(json_data,
                                        'filing',
                                        validate_schema=True)
            if not is_valid:
                for err in errors:
                    print(err.message)
                return jsonify({'message': 'Error: Invalid Filing schema'
                                }), HTTPStatus.BAD_REQUEST

            json_data = json_data.get('filing', None)

            # ensure that the business in the AR matches the business in the URL
            if identifier != json_data['business']['identifier']:
                return jsonify({
                    'message':
                    'Error: Identifier in URL does not match identifier in filing data'
                }), HTTPStatus.BAD_REQUEST

            # convert identifier if BC legal_type
            if legal_type in Business.CORP_TYPE_CONVERSION[
                    Business.LearBusinessTypes.BCOMP.value]:
                identifier = identifier[-7:]

            corp_types = Business.CORP_TYPE_CONVERSION[legal_type]
            if json_data.get('correction', None):
                filing_list = {'correction': json_data['correction']}
            else:
                filing_list = {
                    'changeOfAddress':
                    json_data.get('changeOfAddress', None),
                    'changeOfDirectors':
                    json_data.get('changeOfDirectors', None),
                    'annualReport':
                    json_data.get('annualReport', None),
                    'incorporationApplication':
                    json_data.get('incorporationApplication', None),
                    'alteration':
                    json_data.get('alteration', None),
                    'transition':
                    json_data.get('transition', None)
                }

            # Filter out null-values in the filing_list dictionary
            filing_list = {
                k: v
                for k, v in filing_list.items() if filing_list[k]
            }
            print('filing list: ', filing_list)
            try:
                # get db connection and start a session, in case we need to roll back
                con = DB.connection
                con.begin()
                filings_added = FilingInfo._add_filings(
                    con, json_data, filing_list, identifier, corp_types)

                # return the completed filing data
                completed_filing = Filing()
                # get business info again - could have changed since filings were applied
                completed_filing.business = Business.find_by_identifier(
                    identifier, corp_types, con)
                completed_filing.body = {}
                for filing_info in filings_added:
                    sub_filing = Filing()
                    sub_filing.business = completed_filing.business
                    sub_filing.filing_type = filing_info['filing_type']
                    sub_filing.event_id = filing_info['event_id']
                    sub_filing = Filing.get_filing(filing=sub_filing, con=con)

                    if completed_filing.header:
                        completed_filing.header['colinIds'].append(
                            sub_filing.event_id)
                        # annual report is the only filing with sub filings underneath it
                        if sub_filing.filing_type == 'annualReport':
                            completed_filing.header['name'] = 'annualReport'
                    else:
                        completed_filing.header = sub_filing.header
                    completed_filing.body.update(
                        {sub_filing.filing_type: sub_filing.body})

                # success! commit the db changes
                con.commit()
                return jsonify(completed_filing.as_dict()), HTTPStatus.CREATED

            except Exception as db_err:
                current_app.logger.error(
                    'failed to file - rolling back partial db changes.')
                if con:
                    con.rollback()
                raise db_err

        except Exception as err:  # pylint: disable=broad-except; want to catch all errors
            # general catch-all exception
            current_app.logger.error(err.with_traceback(None))
            return jsonify({
                'message':
                f'Error when trying to file for business {identifier}'
            }), HTTPStatus.INTERNAL_SERVER_ERROR