예제 #1
0
async def publish_mailer_events(message_type: str, org_id: str):
    """Publish payment message to the mailer queue."""
    # Publish message to the Queue, saying account has been created. Using the event spec.

    queue_data = {
        'accountId': org_id,
    }
    payload = {
        'specversion': '1.x-wip',
        'type': message_type,
        'source': f'https://api.pay.bcregistry.gov.bc.ca/v1/accounts/{org_id}',
        'id': org_id,
        'time': f'{datetime.now()}',
        'datacontenttype': 'application/json',
        'data': queue_data
    }
    try:
        await publish(payload=payload,
                      client_name=APP_CONFIG.NATS_MAILER_CLIENT_NAME,
                      subject=APP_CONFIG.NATS_MAILER_SUBJECT)
    except Exception as e:  # pylint: disable=broad-except
        logger.error(e)
        logger.warning(
            'Notification to Queue failed for the Account Mailer %s - %s',
            org_id, payload)
        capture_message(
            'Notification to Queue failed for the Account Mailer {auth_account_id}, {msg}.'
            .format(auth_account_id=org_id, msg=payload),
            level='error')
예제 #2
0
async def _publish_online_banking_mailer_events(rows: List[Dict[str, str]],
                                                paid_amount: float):
    """Publish payment message to the mailer queue."""
    # Publish message to the Queue, saying account has been created. Using the event spec.
    pay_account = _get_payment_account(
        rows[0])  # All rows are for same account.
    # Check for credit, or fully paid or under paid payment
    credit_rows = list(
        filter(
            lambda r: (_get_row_value(r, Column.TARGET_TXN) ==
                       TargetTransaction.RECEIPT.value), rows))
    under_pay_rows = list(
        filter(
            lambda r: (_get_row_value(r, Column.TARGET_TXN_STATUS).lower() ==
                       Status.PARTIAL.value.lower()), rows))

    credit_amount: float = 0
    if credit_rows:
        message_type = 'bc.registry.payment.OverPaid'
        for row in credit_rows:
            credit_amount += float(_get_row_value(row, Column.APP_AMOUNT))
    elif under_pay_rows:
        message_type = 'bc.registry.payment.UnderPaid'
    else:
        message_type = 'bc.registry.payment.Payment'

    queue_data = {
        'accountId': pay_account.auth_account_id,
        'paymentMethod': PaymentMethod.ONLINE_BANKING.value,
        'amount': '{:.2f}'.format(
            paid_amount),  # pylint: disable = consider-using-f-string
        'creditAmount': '{:.2f}'.format(
            credit_amount)  # pylint: disable = consider-using-f-string
    }

    payload = {
        'specversion': '1.x-wip',
        'type': message_type,
        'source':
        f'https://api.pay.bcregistry.gov.bc.ca/v1/accounts/{pay_account.auth_account_id}',
        'id': f'{pay_account.auth_account_id}',
        'time': f'{datetime.now()}',
        'datacontenttype': 'application/json',
        'data': queue_data
    }

    try:
        await publish(payload=payload,
                      client_name=APP_CONFIG.NATS_MAILER_CLIENT_NAME,
                      subject=APP_CONFIG.NATS_MAILER_SUBJECT)
    except Exception as e:  # NOQA pylint: disable=broad-except
        logger.error(e)
        logger.warning(
            'Notification to Queue failed for the Account Mailer %s - %s',
            pay_account.auth_account_id, payload)
        capture_message(
            'Notification to Queue failed for the Account Mailer {auth_account_id}, {msg}.'
            .format(auth_account_id=pay_account.auth_account_id, msg=payload),
            level='error')
예제 #3
0
def process_filing(filing_msg: Dict, flask_app: Flask):
    """Render the filings contained in the submission."""
    if not flask_app:
        raise QueueException('Flask App not available.')

    with flask_app.app_context():

        filing_submission = Filing.find_by_id(filing_msg['filing']['id'])

        if not filing_submission:
            raise QueueException

        if filing_submission.status == Filing.Status.COMPLETED.value:
            logger.warning('QueueFiler: Attempting to reprocess business.id=%s, filing.id=%s filing=%s',
                           filing_submission.business_id, filing_submission.id, filing_msg)
            return

        legal_filings = filing_submission.legal_filings()

        if legal_filings:

            uow = versioning_manager.unit_of_work(db.session)
            transaction = uow.create_transaction(db.session)

            business = Business.find_by_internal_id(filing_submission.business_id)

            for filing in legal_filings:
                if filing.get('annualReport'):
                    annual_report.process(business, filing)

                elif filing.get('changeOfAddress'):
                    change_of_address.process(business, filing)

                elif filing.get('changeOfDirectors'):
                    filing['colinIds'] = filing_submission.colin_event_ids
                    change_of_directors.process(business, filing)

                elif filing.get('changeOfName'):
                    change_of_name.process(business, filing)

                elif filing.get('specialResolution'):
                    pass  # nothing to do here

                elif filing.get('voluntaryDissolution'):
                    voluntary_dissolution.process(business, filing)

                elif filing.get('incorporationApplication'):
                    incorporation_filing.process(business, filing, flask_app)

            filing_submission.transaction_id = transaction.id
            filing_submission.set_processed()

            db.session.add(business)
            db.session.add(filing_submission)
            db.session.commit()

            publish_event(business, filing_submission)
        return
예제 #4
0
async def process_payment(payment_token, flask_app):
    """Render the payment status."""
    if not flask_app:
        raise QueueException('Flask App not available.')

    with flask_app.app_context():

        # try to find the filing 5 times before putting back on the queue - in case payment token ends up on the queue
        # before it is assigned to filing.
        counter = 1
        filing_submission = None
        while not filing_submission and counter <= 5:
            filing_submission = get_filing_by_payment_id(payment_token['paymentToken'].get('id'))
            counter += 1
            if not filing_submission:
                await asyncio.sleep(0.2)
        if not filing_submission:
            raise FilingException

        if filing_submission.status == Filing.Status.COMPLETED.value:
            # log and skip this
            # it shouldn't be an error, but there could be something to investigate if
            # multiple retries are happening on something that should have been completed.
            logger.warning('Queue: Attempting to reprocess business.id=%s, filing.id=%s payment=%s',
                           filing_submission.business_id, filing_submission.id, payment_token)
            capture_message(f'Queue Issue: Attempting to reprocess business.id={filing_submission.business_id},'
                            'filing.id={filing_submission.id} payment={payment_token}')
            return

        if payment_token['paymentToken'].get('statusCode') == 'TRANSACTION_FAILED':
            # TODO: The customer has cancelled out of paying, so we could note this better
            # technically the filing is still pending payment/processing
            return

        if payment_token['paymentToken'].get('statusCode') == Filing.Status.COMPLETED.value:
            filing_submission.payment_completion_date = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)
            db.session.add(filing_submission)
            db.session.commit()

            if not filing_submission.effective_date or \
                    filing_submission.effective_date <= \
                    datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc):
                # if we're not a future effective date, then submit for processing
                try:
                    await publish_filing(filing_submission)
                except Exception as err:  # pylint: disable=broad-except, unused-variable # noqa F841;
                    # mark any failure for human review
                    capture_message(
                        'Queue Error: Failied to place filing:{filing_submission.id} on Queue with error:{err}',
                        level='error')

            return

        # if we're here and haven't been able to action it,
        # then we've received an unknown status and should throw an error
        logger.error('Unknown payment status given: %s', payment_token['paymentToken'].get('statusCode'))
        raise QueueException
예제 #5
0
async def _publish_account_events(message_type: str,
                                  pay_account: PaymentAccountModel,
                                  row: Dict[str, str]):
    """Publish payment message to the mailer queue."""
    # Publish message to the Queue, saying account has been created. Using the event spec.
    payload = _create_event_payload(message_type, pay_account, row)

    try:
        await publish(payload=payload,
                      client_name=APP_CONFIG.NATS_ACCOUNT_CLIENT_NAME,
                      subject=APP_CONFIG.NATS_ACCOUNT_SUBJECT)
    except Exception as e:  # NOQA pylint: disable=broad-except
        logger.error(e)
        logger.warning('Notification to Queue failed for the Account %s - %s',
                       pay_account.auth_account_id, pay_account.name)
        capture_message(
            'Notification to Queue failed for the Account {auth_account_id}, {msg}.'
            .format(auth_account_id=pay_account.auth_account_id, msg=payload),
            level='error')
예제 #6
0
async def _publish_payment_event(inv: InvoiceModel):
    """Publish payment message to the queue."""
    payment_event_payload = PaymentTransactionService.create_event_payload(
        invoice=inv, status_code=PaymentStatus.COMPLETED.value)
    try:

        await publish(payload=payment_event_payload,
                      client_name=APP_CONFIG.NATS_PAYMENT_CLIENT_NAME,
                      subject=get_pay_subject_name(
                          inv.corp_type_code,
                          subject_format=APP_CONFIG.NATS_PAYMENT_SUBJECT))
    except Exception as e:  # NOQA pylint: disable=broad-except
        logger.error(e)
        logger.warning(
            'Notification to Queue failed for the Payment Event - %s',
            payment_event_payload)
        capture_message(
            f'Notification to Queue failed for the Payment Event {payment_event_payload}.',
            level='error')
예제 #7
0
async def process_filing(filing_msg: Dict, flask_app: Flask):  # pylint: disable=too-many-branches,too-many-statements
    """Render the filings contained in the submission."""
    if not flask_app:
        raise QueueException('Flask App not available.')

    with flask_app.app_context():
        filing_submission = Filing.find_by_id(filing_msg['filing']['id'])

        if not filing_submission:
            raise QueueException

        if filing_submission.status == Filing.Status.COMPLETED.value:
            logger.warning(
                'QueueFiler: Attempting to reprocess business.id=%s, filing.id=%s filing=%s',
                filing_submission.business_id, filing_submission.id,
                filing_msg)
            return None, None

        if legal_filings := filing_submission.legal_filings():
            uow = versioning_manager.unit_of_work(db.session)
            transaction = uow.create_transaction(db.session)

            business = Business.find_by_internal_id(
                filing_submission.business_id)

            for filing in legal_filings:
                if filing.get('alteration'):
                    alteration.process(business, filing_submission, filing)

                if filing.get('annualReport'):
                    annual_report.process(business, filing)

                elif filing.get('changeOfAddress'):
                    change_of_address.process(business, filing)

                elif filing.get('changeOfDirectors'):
                    filing['colinIds'] = filing_submission.colin_event_ids
                    change_of_directors.process(business, filing)

                elif filing.get('changeOfName'):
                    change_of_name.process(business, filing)

                elif filing.get('voluntaryDissolution'):
                    voluntary_dissolution.process(business, filing)

                elif filing.get('incorporationApplication'):
                    business, filing_submission = incorporation_filing.process(
                        business, filing, filing_submission)

                if filing.get('correction'):
                    filing_submission = correction.process(
                        filing_submission, filing)

                if filing.get('transition'):
                    filing_submission = transition.process(
                        business, filing_submission, filing)

            filing_submission.transaction_id = transaction.id
            filing_submission.set_processed()

            db.session.add(business)
            db.session.add(filing_submission)
            db.session.commit()

            # post filing changes to other services
            if any('alteration' in x for x in legal_filings):
                if name_request.has_new_nr_for_alteration(
                        business, filing_submission.filing_json):
                    name_request.consume_nr(
                        business, filing_submission,
                        '/filing/alteration/nameRequest/nrNumber')
                alteration.post_process(business, filing_submission)
                db.session.add(business)
                db.session.commit()
                AccountService.update_entity(
                    business_registration=business.identifier,
                    business_name=business.legal_name,
                    corp_type_code=business.legal_type)

            if any('incorporationApplication' in x for x in legal_filings):
                if any('correction' in x for x in legal_filings):
                    if name_request.has_new_nr_for_correction(
                            filing_submission.filing_json):
                        name_request.consume_nr(business, filing_submission)
                else:
                    filing_submission.business_id = business.id
                    db.session.add(filing_submission)
                    db.session.commit()
                    incorporation_filing.update_affiliation(
                        business, filing_submission)
                    name_request.consume_nr(business, filing_submission)
                    incorporation_filing.post_process(business,
                                                      filing_submission)
                    try:
                        await publish_email_message(
                            qsm, APP_CONFIG.EMAIL_PUBLISH_OPTIONS['subject'],
                            filing_submission, 'mras')
                    except Exception as err:  # pylint: disable=broad-except, unused-variable # noqa F841;
                        # mark any failure for human review
                        capture_message(
                            f'Queue Error: Failed to place email for filing:{filing_submission.id}'
                            f'on Queue with error:{err}',
                            level='error')

            try:
                await publish_email_message(
                    qsm, APP_CONFIG.EMAIL_PUBLISH_OPTIONS['subject'],
                    filing_submission, filing_submission.status)
            except Exception as err:  # pylint: disable=broad-except, unused-variable # noqa F841;
                # mark any failure for human review
                capture_message(
                    f'Queue Error: Failed to place email for filing:{filing_submission.id}'
                    f'on Queue with error:{err}',
                    level='error')

            try:
                await publish_event(business, filing_submission)
            except Exception as err:  # pylint: disable=broad-except, unused-variable # noqa F841;
                # mark any failure for human review
                capture_message(
                    f'Queue Error: Failed to publish event for filing:{filing_submission.id}'
                    f'on Queue with error:{err}',
                    level='error')
예제 #8
0
async def process_filing(filing_msg: Dict, flask_app: Flask):  # pylint: disable=too-many-branches,too-many-statements
    """Render the filings contained in the submission.

    Start the migration to using core/Filing
    """
    if not flask_app:
        raise QueueException('Flask App not available.')

    with flask_app.app_context():
        # filing_submission = Filing.find_by_id(filing_msg['filing']['id'])
        filing_core_submission = FilingCore.find_by_id(
            filing_msg['filing']['id'])

        if not filing_core_submission:
            raise QueueException

        filing_submission = filing_core_submission.storage

        if filing_core_submission.status == Filing.Status.COMPLETED:
            logger.warning(
                'QueueFiler: Attempting to reprocess business.id=%s, filing.id=%s filing=%s',
                filing_submission.business_id, filing_submission.id,
                filing_msg)
            return None, None

        # convenience flag to set that the envelope is a correction
        is_correction = (filing_core_submission.filing_type ==
                         FilingCore.FilingTypes.CORRECTION)

        if legal_filings := filing_core_submission.legal_filings(
                with_diff=False):
            uow = versioning_manager.unit_of_work(db.session)
            transaction = uow.create_transaction(db.session)

            business = Business.find_by_internal_id(
                filing_submission.business_id)

            filing_meta = FilingMeta(
                application_date=filing_submission.effective_date,
                legal_filings=[
                    item
                    for sublist in [list(x.keys()) for x in legal_filings]
                    for item in sublist
                ])

            for filing in legal_filings:
                if filing.get('alteration'):
                    alteration.process(business, filing_submission, filing,
                                       filing_meta, is_correction)

                elif filing.get('annualReport'):
                    annual_report.process(business, filing, filing_meta)

                elif filing.get('changeOfAddress'):
                    change_of_address.process(business, filing, filing_meta)

                elif filing.get('changeOfDirectors'):
                    filing['colinIds'] = filing_submission.colin_event_ids
                    change_of_directors.process(business, filing, filing_meta)

                elif filing.get('changeOfName'):
                    change_of_name.process(business, filing, filing_meta)

                elif filing.get('dissolution'):
                    dissolution.process(business, filing, filing_meta)

                elif filing.get('incorporationApplication'):
                    business, filing_submission, filing_meta = incorporation_filing.process(
                        business, filing_core_submission.json,
                        filing_submission, filing_meta)

                elif filing.get('conversion'):
                    business, filing_submission = conversion.process(
                        business, filing_core_submission.json,
                        filing_submission, filing_meta)

                elif filing.get('courtOrder'):
                    court_order.process(filing_submission, filing, filing_meta)

                elif filing.get('registrarsNotation'):
                    registrars_notation.process(filing_submission, filing,
                                                filing_meta)

                elif filing.get('registrarsOrder'):
                    registrars_order.process(filing_submission, filing,
                                             filing_meta)

                elif filing.get('correction'):
                    filing_submission = correction.process(
                        filing_submission, filing, filing_meta)

                elif filing.get('transition'):
                    filing_submission = transition.process(
                        business, filing_submission, filing, filing_meta)

            filing_submission.transaction_id = transaction.id
            filing_submission.set_processed()
            filing_submission._meta_data = json.loads(  # pylint: disable=W0212
                json.dumps(filing_meta.asjson, default=json_serial))

            db.session.add(business)
            db.session.add(filing_submission)
            db.session.commit()

            # post filing changes to other services
            if any('alteration' in x for x in legal_filings):

                alteration.post_process(business, filing_submission,
                                        correction)
                db.session.add(business)
                db.session.commit()
                AccountService.update_entity(
                    business_registration=business.identifier,
                    business_name=business.legal_name,
                    corp_type_code=business.legal_type)

            if any('incorporationApplication' in x for x in legal_filings):
                if any('correction' in x for x in legal_filings):
                    if name_request.has_new_nr_for_correction(
                            filing_submission.filing_json):
                        name_request.consume_nr(business, filing_submission)
                else:
                    filing_submission.business_id = business.id
                    db.session.add(filing_submission)
                    db.session.commit()
                    incorporation_filing.update_affiliation(
                        business, filing_submission)
                    name_request.consume_nr(business, filing_submission)
                    incorporation_filing.post_process(business,
                                                      filing_submission)
                    try:
                        await publish_email_message(
                            qsm, APP_CONFIG.EMAIL_PUBLISH_OPTIONS['subject'],
                            filing_submission, 'mras')
                    except Exception as err:  # pylint: disable=broad-except, unused-variable # noqa F841;
                        # mark any failure for human review
                        capture_message(
                            f'Queue Error: Failed to place email for filing:{filing_submission.id}'
                            f'on Queue with error:{err}',
                            level='error')

            if any('conversion' in x for x in legal_filings):
                filing_submission.business_id = business.id
                db.session.add(filing_submission)
                db.session.commit()
                conversion.post_process(business, filing_submission)

            try:
                await publish_email_message(
                    qsm, APP_CONFIG.EMAIL_PUBLISH_OPTIONS['subject'],
                    filing_submission, filing_submission.status)
            except Exception as err:  # pylint: disable=broad-except, unused-variable # noqa F841;
                # mark any failure for human review
                capture_message(
                    f'Queue Error: Failed to place email for filing:{filing_submission.id}'
                    f'on Queue with error:{err}',
                    level='error')

            try:
                await publish_event(business, filing_submission)
            except Exception as err:  # pylint: disable=broad-except, unused-variable # noqa F841;
                # mark any failure for human review
                print(err)
                capture_message(
                    f'Queue Error: Failed to publish event for filing:{filing_submission.id}'
                    f'on Queue with error:{err}',
                    level='error')