def update_nr_name_search(mapper, connection, target): """Add any changes to the name to the request.nameSearch column.""" from namex.models import Request name = target nr = Request.find_by_id(name.nrId) if nr: # get the names associated with the NR names_q = connection.execute( f""" SELECT names.name from names JOIN requests on requests.id = names.nr_id WHERE requests.id={nr.id} """ ) # format the names into a string like: |1<name1>|2<name2>|3<name3> names = [x[0] for x in names_q.all()] name_search = '' for item, index in zip(names, range(len(names))): name_search += f'|{index + 1}{item}{index + 1}|' # update the name_search field of the nr with the formatted string connection.execute( """ UPDATE requests SET name_search=%s WHERE id=%s """, ('(' + name_search + ')', nr.id) )
def test_name_search_populated_by_name(): """Tests changing a name updates the nameSearch column.""" from namex.models import Name, Request as RequestDAO, State name = Name() name.choice = 1 name.name = 'TEST' name.state = 'NE' nr = RequestDAO() nr.nrNum = 'NR 0000001' nr.stateCd = State.DRAFT nr.names.append(name) nr.save_to_db() test = RequestDAO.find_by_id(nr.id) # sanity check names = test.names.all() assert len(names) == 1 assert names[0].name == 'TEST' # check nameSearch assert nr.nameSearch == '|1TEST1|' # alter name name.name = 'CHANGED' name.save_to_db() # check nameSearch assert nr.nameSearch == '|1CHANGED1|'
def update_nr_name_search(mapper, connection, target): """Add any changes to the name to the request.nameSearch column and publish name state changes where applicable.""" from flask.globals import current_app from namex.models import Event, Request, State from namex.services.audit_trail.event_recorder import EventRecorder name = target nr = Request.find_by_id(name.nrId) if nr: # get the names associated with the NR names_q = connection.execute(f""" SELECT names.name from names JOIN requests on requests.id = names.nr_id WHERE requests.id={nr.id} """) # format the names into a string like: |1<name1>|2<name2>|3<name3> names = [x[0] for x in names_q.all()] name_search = '' for item, index in zip(names, range(len(names))): name_search += f'|{index + 1}{item}{index + 1}|' # update the name_search field of the nr with the formatted string connection.execute( """ UPDATE requests SET name_search=%s WHERE id=%s """, ('(' + name_search + ')', nr.id)) # set nr state to consumed name_consume_history = get_history(name, 'consumptionDate') current_app.logger\ .debug('name_consume_history check - nrNum: {}, consumptionDate: {}, corpNum: {}, state: {}' .format(nr.nrNum, name.consumptionDate, name.corpNum, name.state)) # Note: we cannot just check for a corpNum addition due to some Society change of name NRs coming over from # NRO extractor providing a value for the corpNum field. if len(name_consume_history.added) \ and name.consumptionDate \ and name.corpNum \ and name.state in ['APPROVED', 'CONDITION']: # Adding an after_flush_postexec to avoid connection and transaction closed issue's # Creating one time execution event when ever corpNum is added to a name # corpNum sets from nro-extractor job @event.listens_for(db.session, 'after_flush_postexec', once=True) def receive_after_flush_postexec(session, flush_context): nr = Request.find_by_id(name.nrId) nr.stateCd = State.CONSUMED nr.add_to_db() current_app.logger.debug('moved to CONSUMED state {}'.format( name.corpNum)) EventRecorder.record_as_system(Event.UPDATE_FROM_NRO, nr, { 'id': nr.id, 'nrNum': nr.nrNum, 'stateCd': nr.stateCd }, True) current_app.logger.debug( 'moved to CONSUMED state event logged {}'.format(nr.nrNum))
def after_update_payment(mapper, connection, target): """Publish email notification.""" from namex.models import Request nr = Request.find_by_id(target.nrId) payment_completion_date_history = get_history(target, '_payment_completion_date') if target.payment_action in [Payment.PaymentActions.REAPPLY.value, Payment.PaymentActions.UPGRADE.value] \ and len(payment_completion_date_history.added) > 0: option = 'renewal' if target.payment_action == Payment.PaymentActions.REAPPLY.value else 'upgrade' queue_util.publish_email_notification(nr.nrNum, option)
def receive_after_flush_postexec(session, flush_context): nr = Request.find_by_id(name.nrId) nr.stateCd = State.CONSUMED nr.add_to_db() current_app.logger.debug('moved to CONSUMED state {}'.format( name.corpNum)) EventRecorder.record_as_system(Event.UPDATE_FROM_NRO, nr, { 'id': nr.id, 'nrNum': nr.nrNum, 'stateCd': nr.stateCd }, True) current_app.logger.debug( 'moved to CONSUMED state event logged {}'.format(nr.nrNum))
def update_nr_state(mapper, connection, target): """Set the state of the NR based on payment_status_code.""" from namex.models import Request payment = target nr = Request.find_by_id(payment.nrId) if nr: # could not make this update properly via the model so used raw sql if payment.payment_status_code != 'REFUND_REQUESTED': if payment.payment_status_code == 'COMPLETED' and nr.stateCd == 'PENDING_PAYMENT': connection.execute(f""" UPDATE requests SET state_cd='{State.DRAFT}' WHERE id={nr.id} """)
async def furnish_receipt_message(qsm: QueueServiceManager, payment: Payment): # pylint: disable=redefined-outer-name """Send receipt info to the mail queue if it hasn't yet been done.""" if payment.furnished == 'Y': logger.debug( 'Queue Issue: Duplicate, already furnished receipt for payment.id=%s', payment.id) capture_message( f'Queue Issue: Duplicate, already furnished receipt for payment.id={payment.id}' ) return nr = None logger.debug('Start of the furnishing of receipt for payment record:%s', payment.as_dict()) try: payment.furnished = True payment.save_to_db() except Exception as err: # noqa: B902; bare exception to catch all raise Exception('Unable to alter payment record.') from err try: nr = RequestDAO.find_by_id(payment.nrId) cloud_event_msg = create_cloud_event_msg( msg_id=str(uuid.uuid4()), msg_type='bc.registry.names.request', source=f'/requests/{nr.nrNum}', time=datetime.utcfromtimestamp( time.time()).replace(tzinfo=timezone.utc).isoformat(), identifier=nr.nrNum, json_data_body={ 'request': { 'header': { 'nrNum': nr.nrNum }, 'paymentToken': payment.payment_token, 'statusCode': nr.stateCd } }) logger.debug('About to publish email for payment.id=%s', payment.id) await publish_email_message(qsm, cloud_event_msg) except Exception as err: # noqa: B902; bare exception to catch all payment.furnished = False payment.save_to_db() logger.debug('Reset payment furnish status payment.id= %s', payment.id) raise QueueException(f'Unable to furnish NR info. {err}') from err
def update_nr_state(mapper, connection, target): """Set the state of the NR based on payment_status_code.""" from namex.models import Request payment = target nr = Request.find_by_id(payment.nrId) completed_payment_status = [PaymentState.COMPLETED.value, PaymentState.APPROVED.value] if nr: # TODO: take this out since the queue does this if payment.payment_status_code != 'REFUND_REQUESTED': if payment.payment_status_code in completed_payment_status and nr.stateCd == 'PENDING_PAYMENT': connection.execute( f""" UPDATE requests SET state_cd='{State.DRAFT}' WHERE id={nr.id} """ )
def update_nr_state(mapper, connection, target): """Set the state of the NR based on payment_status_code.""" from namex.models import Request payment = target nr = Request.find_by_id(payment.nrId) completed_payment_status = [ PaymentState.COMPLETED.value, PaymentState.APPROVED.value ] if nr: # TODO: take this out since the queue does this if payment.payment_status_code != 'REFUND_REQUESTED': if payment.payment_status_code in completed_payment_status and nr.stateCd == State.PENDING_PAYMENT: connection.execute(f""" UPDATE requests SET state_cd='{State.DRAFT}' WHERE id={nr.id} """) if current_app.config.get('DISABLE_NAMEREQUEST_NATS_UPDATES', 0) != 1: queue_util.send_name_request_state_msg( nr.nrNum, State.DRAFT, State.PENDING_PAYMENT)
async def update_payment_record(payment: Payment) -> Optional[Payment]: """Update the payment record in the database. Alter the NR state as required based on the payment action. Payment NR Action - One of [COMPLETE, UPGRADE, REAPPLY] COMPLETE - set NR to DRAFT IFF nr.state == PENDING_PAYMENT UPGRADE - set the nr.priority to True/'Y' REAPPLY - add REAPPLY_EXTENSION to expiry date of NR IFF it hasn't expired """ if payment.payment_completion_date: msg = f'Queue Issue: Duplicate, payment already processed for payment.id={payment.id}' logger.debug(msg) capture_message(msg) return None payment_action = payment.payment_action nr = RequestDAO.find_by_id(payment.nrId) if payment_action == Payment.PaymentActions.CREATE.value: # pylint: disable=R1705 if nr.stateCd == State.PENDING_PAYMENT: nr.stateCd = State.DRAFT payment.payment_completion_date = datetime.utcnow() payment.payment_status_code = State.COMPLETED nr.save_to_db() payment.save_to_db() return payment elif payment_action == Payment.PaymentActions.UPGRADE.value: if nr.stateCd == State.PENDING_PAYMENT: msg = f'Queue Issue: Upgrading a non-DRAFT NR for payment.id={payment.id}' logger.debug(msg) capture_message(msg) raise QueueException(msg) nr.priorityCd = 'Y' nr.priorityDate = datetime.utcnow() payment.payment_completion_date = datetime.utcnow() payment.payment_status_code = State.COMPLETED nr.save_to_db() payment.save_to_db() return payment elif payment_action == Payment.PaymentActions.REAPPLY.value: if nr.stateCd != State.APPROVED \ and nr.expirationDate + timedelta(hours=NAME_REQUEST_EXTENSION_PAD_HOURS) < datetime.utcnow(): msg = f'Queue Issue: Failed attempt to extend NR for payment.id={payment.id} '\ 'nr.state{nr.stateCd}, nr.expires:{nr.expirationDate}' logger.debug(msg) capture_message(msg) raise QueueException(msg) nr.expirationDate = nr.expirationDate + timedelta(days=NAME_REQUEST_LIFESPAN_DAYS) payment.payment_completion_date = datetime.utcnow() payment.payment_status_code = State.COMPLETED nr.save_to_db() payment.save_to_db() return payment msg = f'Queue Issue: Unknown action:{payment_action} for payment.id={payment.id}' logger.debug(msg) capture_message(msg) raise QueueException(f'Unknown action:{payment_action} for payment.id={payment.id}')
async def process_payment(pay_msg: dict, flask_app: Flask): """Render the payment status.""" if not flask_app or not pay_msg: raise QueueException('Flask App or token not available.') with flask_app.app_context(): logger.debug('entering process payment: %s', pay_msg) # capture_message(f'Queue Issue: Unable to find payment.id={payment_id} to place on email queue') # return if pay_msg.get( 'paymentToken', {}).get('statusCode') == PaymentState.TRANSACTION_FAILED.value: # TODO: The customer has cancelled out of paying, so we could note this better # technically the payment for this service is still pending logger.debug('Failed transaction on queue:%s', pay_msg) return complete_payment_status = [ PaymentState.COMPLETED.value, PaymentState.APPROVED.value ] if pay_msg.get('paymentToken', {}).get('statusCode') in complete_payment_status: # pylint: disable=R1702 logger.debug('COMPLETED transaction on queue: %s', pay_msg) if payment_token := pay_msg.get('paymentToken', {}).get('id'): if payment := Payment.find_by_payment_token(payment_token): if update_payment := await update_payment_record(payment): payment = update_payment # record event nr = RequestDAO.find_by_id(payment.nrId) # TODO: create a namex_pay user for this user = User.find_by_username( 'name_request_service_account') EventRecorder.record( user, Event.NAMEX_PAY + f' [payment completed] { payment.payment_action }', nr, nr.json()) # try to update NRO otherwise send a sentry msg for OPS if payment.payment_action in \ [payment.PaymentActions.UPGRADE.value, payment.PaymentActions.REAPPLY.value]: change_flags = { 'is_changed__request': True, 'is_changed__previous_request': False, 'is_changed__applicant': False, 'is_changed__address': False, 'is_changed__name1': False, 'is_changed__name2': False, 'is_changed__name3': False, 'is_changed__nwpta_ab': False, 'is_changed__nwpta_sk': False, 'is_changed__request_state': False, 'is_changed_consent': False } warnings = nro.change_nr(nr, change_flags) if warnings: logger.error( 'Queue Error: Unable to update NRO :%s', warnings) capture_message( f'Queue Error: Unable to update NRO for {nr} {payment.payment_action} :{warnings}', level='error') await furnish_receipt_message(qsm, payment) else: