Exemplo n.º 1
0
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)
        )
Exemplo n.º 2
0
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|'
Exemplo n.º 3
0
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))
Exemplo n.º 4
0
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)
Exemplo n.º 5
0
 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))
Exemplo n.º 6
0
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}
                    """)
Exemplo n.º 7
0
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
Exemplo n.º 8
0
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}
                    """
                )
Exemplo n.º 9
0
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)
Exemplo n.º 10
0
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}')
Exemplo n.º 11
0
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: