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')
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')
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
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
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')
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')
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')
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')