コード例 #1
0
ファイル: payment.py プロジェクト: vysakh-menon-aot/namex
    def request_refund(self, nr_model: RequestDAO, payment_id: int):
        """
        Processes a SINGLE refund request.
        This is different from the 'refund' in the NameRequest resource PATCH namerequests/{nrId}/REQUEST_REFUND
        which cancels the NR and refunds any associated payments.
        :param nr_model:
        :param payment_id:
        :return:
        """
        # Handle the payments
        valid_states = [
            PaymentState.APPROVED.value, PaymentState.COMPLETED.value,
            PaymentState.PARTIAL.value
        ]
        if nr_model.stateCd not in [State.DRAFT]:
            raise PaymentServiceError(
                message='Invalid NR state for cancel and refund')
        # Cancel any payments associated with the NR
        for payment in nr_model.payments.all():
            if payment.payment_status_code in valid_states and payment.id == payment_id:
                # refund_payment(payment.payment_token, {'reason': 'Name Request user requested refund'})
                refund_payment(payment.payment_token, {})
                payment.payment_status_code = PaymentState.REFUND_REQUESTED.value
                payment.save_to_db()
                nr_svc = self.nr_service
                EventRecorder.record(
                    nr_svc.user, Event.PATCH +
                    f' [payment refunded] {payment.payment_action}', nr_model,
                    nr_model.json())

        return nr_model
コード例 #2
0
    def handle_patch_rollback(self, nr_model: Request, action: str):
        """
        Roll back the Name Request.
        :param nr_model:
        :param action:
        :return:
        """
        nr_svc = self.nr_service

        # This handles updates if the NR state is 'patchable'
        nr_model = self.update_nr(nr_model, State.CANCELLED,
                                  self.handle_nr_patch)
        # Only update the record in NRO if it's a real NR, otherwise the record won't exist
        if not is_temp_nr_num(nr_model.nrNum):
            # This handles the updates for NRO and Solr, if necessary
            # self.update_records_in_network_services(nr_model, update_solr=True)
            nr_model = self.update_request_in_nro(nr_model, self.save_nr)

        # Delete in solr for temp or real NR because it is cancelled
        if nr_model.entity_type_cd in [
                'CR', 'UL', 'BC', 'CP', 'PA', 'XCR', 'XUL', 'XCP', 'CC', 'FI',
                'XCR', 'XUL', 'XCP'
        ]:
            SOLR_CORE = 'possible.conflicts'
            self.delete_solr_doc(SOLR_CORE, nr_model.nrNum)

        # Record the event
        EventRecorder.record(nr_svc.user, Event.PATCH + ' [rollback]',
                             nr_model, nr_model.json())

        return nr_model
コード例 #3
0
def test_edit_inprogress_event_history(client, jwt, app):
    from namex.models import Request as RequestDAO, State, Name as NameDAO, User, Event
    from namex.services import EventRecorder

    # add a user for the comment
    user = User('test-user', '', '', '43e6a245-0bf7-4ccf-9bd0-e7fb85fd18cc',
                'https://sso-dev.pathfinder.gov.bc.ca/auth/realms/sbc')
    user.save_to_db()

    headers = create_header(jwt, [User.EDITOR])

    nr = RequestDAO()
    nr.nrNum = 'NR 0000002'
    nr.stateCd = State.DRAFT
    nr.requestId = 1460775
    nr._source = 'NRO'
    name1 = NameDAO()
    name1.choice = 1
    name1.name = 'TEST NAME ONE'
    nr.names = [name1]
    nr.save_to_db()

    EventRecorder.record(user, Event.POST, nr, nr.json())

    nr.stateCd = State.INPROGRESS
    nr.save_to_db()
    EventRecorder.record(user, Event.PUT, nr, {"additional": "additional","furnished": "N"})

    # get the resource (this is the test)
    rv = client.get('/api/v1/events/NR%200000002', headers=headers)
    assert rv.status_code == 200

    assert b'"user_action": "Edit NR Details (NameX)"' in rv.data
コード例 #4
0
ファイル: payment.py プロジェクト: vysakh-menon-aot/namex
    def complete_reservation_payment(self, nr_model: RequestDAO,
                                     payment_id: int):
        """
        Invoked when completing an in-progress Name Request reservation.
        :param nr_model:
        :param payment_id:
        :return:
        """
        nr_svc = self.nr_service

        # Update the state of the payment
        payment = get_active_payment(nr_model, payment_id)
        sbc_payment_response = get_payment(payment.payment_token)

        # TODO: Throw errors if this fails!
        if sbc_payment_response.statusCode in [
                PaymentStatusCode.COMPLETED.value,
                PaymentStatusCode.APPROVED.value
        ]:
            payment.payment_status_code = sbc_payment_response.statusCode
            payment.payment_completion_date = sbc_payment_response.createdOn
            payment.save_to_db()

            # This handles updates if the NR state is DRAFT, COND_RESERVE or RESERVED
            # If the state is COND_RESERVE update state to CONDITIONAL
            # If the state is RESERVED update state to APPROVED
            # Then update the name request as required

            if nr_model.stateCd == State.DRAFT:
                # If the state is DRAFT, leave it as a DRAFT
                nr_model = self.update_nr(nr_model, State.DRAFT,
                                          self.handle_nr_approve)
            if nr_model.stateCd == State.COND_RESERVE:
                # If the state is COND_RESERVE update state to CONDITIONAL, and update the name request as required
                nr_model = self.update_nr(nr_model, State.CONDITIONAL,
                                          self.handle_nr_approve)
            elif nr_model.stateCd == State.RESERVED:
                # If the state is RESERVED update state to APPROVED, and update the name request as required
                nr_model = self.update_nr(nr_model, State.APPROVED,
                                          self.handle_nr_approve)

            # Save the name request
            nr_model.save_to_db()

            # Record the event
            EventRecorder.record(nr_svc.user,
                                 Event.PATCH + ' [payment completed] RESERVE',
                                 nr_model, nr_model.json())

        # Update the actions, as things change once the payment is successful
        self.nr_service.current_state_actions = get_nr_state_actions(
            nr_model.stateCd, nr_model)

        return nr_model
コード例 #5
0
    def complete_reapply_payment(self, nr_model: RequestDAO, payment_id: int):
        """
        Invoked when re-applying for an existing Name Request reservation.
        Extend the Name Request's expiration date by 56 days. 
        If the request action is set to REH, REN or REST, OR request type is 
        'RCR', 'RUL', 'BERE', 'RCC', 'RCP', 'RFI', 'XRCR', 'RLC', 'XRCP','RSO','XRSO'
        extend the expiration by an additional year (plus the default 56 days).
        :param nr_model:
        :param payment_id:
        :return:
        """
        nr_svc = self.nr_service

        # Update the state of the payment
        payment = get_active_payment(nr_model, payment_id)
        sbc_payment_response = get_payment(payment.payment_token)

        # TODO: Throw errors if this fails!
        if sbc_payment_response.statusCode in [
                PaymentStatusCode.COMPLETED.value,
                PaymentStatusCode.APPROVED.value
        ]:
            payment.payment_status_code = sbc_payment_response.statusCode
            payment.payment_completion_date = sbc_payment_response.createdOn
            payment.save_to_db()

            if nr_model.submitCount < 3:
                nr_model = nr_svc.extend_expiry_date(nr_model,
                                                     datetime.utcnow())
                nr_model = nr_svc.update_request_submit_count(nr_model)
                nr_model.save_to_db()
            else:
                # TODO: Make a custom exception for this?
                raise PaymentServiceError(
                    message=
                    'Submit count maximum of 3 retries has been reached!')

        # This (optionally) handles the updates for NRO and Solr, if necessary
        update_solr = False
        nr_model = self.update_records_in_network_services(
            nr_model, update_solr)

        # Update the actions, as things change once the payment is successful
        self.nr_service.current_state_actions = get_nr_state_actions(
            nr_model.stateCd, nr_model)

        # Record the event
        EventRecorder.record(nr_svc.user,
                             Event.PATCH + ' [payment completed] REAPPLY',
                             nr_model, nr_model.json())

        return nr_model
コード例 #6
0
    def handle_patch_request_refund(self, nr_model: Request):
        """
        Can the NR and request a refund for ALL associated Name Request payments.
        :param nr_model:
        :return:
        """
        nr_svc = self.nr_service

        # This handles updates if the NR state is 'patchable'
        nr_model = self.update_nr(nr_model, State.REFUND_REQUESTED,
                                  self.handle_nr_patch)

        # Handle the payments
        valid_states = [
            PaymentState.APPROVED.value, PaymentState.COMPLETED.value,
            PaymentState.PARTIAL.value
        ]

        refund_value = 0

        # Check for NR that has been renewed - do not refund any payments.
        # UI should not order refund for an NR renewed/reapplied it.
        if not any(
                payment.payment_action == Payment.PaymentActions.REAPPLY.value
                for payment in nr_model.payments.all()):
            # Try to refund all payments associated with the NR
            for payment in nr_model.payments.all():
                if payment.payment_status_code in valid_states:
                    # Some refunds may fail. Some payment methods are not refundable and return HTTP 400 at the refund.
                    # The refund status is checked from the payment_response and a appropriate message is displayed by the UI.
                    refund_payment(payment.payment_token, {})
                    payment_response = get_payment(payment.payment_token)
                    payment.payment_status_code = PaymentState.REFUND_REQUESTED.value
                    payment.save_to_db()
                    refund_value += payment_response.receipts[0][
                        'receiptAmount'] if len(
                            payment_response.receipts) else 0

        publish_email_notification(nr_model.nrNum, 'refund',
                                   '{:.2f}'.format(refund_value))

        # This handles the updates for NRO and Solr, if necessary
        nr_model = self.update_records_in_network_services(nr_model,
                                                           update_solr=True)

        # Record the event
        EventRecorder.record(nr_svc.user, Event.PATCH + ' [request-refund]',
                             nr_model, nr_model.json())

        return nr_model
コード例 #7
0
ファイル: payment.py プロジェクト: vysakh-menon-aot/namex
    def complete_upgrade_payment(self, nr_model: RequestDAO, payment_id: int):
        """
        Invoked when upgrading an existing Name Request reservation to PRIORITY status.
        :param nr_model:
        :param payment_id:
        :return:
        """
        nr_svc = self.nr_service

        if nr_model.stateCd not in [State.DRAFT, State.PENDING_PAYMENT]:
            raise PaymentServiceError(
                message=
                'Error upgrading Name Request, request is in an invalid state!'
            )

        # Update the state of the payment
        payment = get_active_payment(nr_model, payment_id)
        sbc_payment_response = get_payment(payment.payment_token)

        # TODO: Throw errors if this fails!
        if sbc_payment_response.statusCode in [
                PaymentStatusCode.COMPLETED.value,
                PaymentStatusCode.APPROVED.value
        ]:
            payment.payment_status_code = sbc_payment_response.statusCode
            payment.payment_completion_date = sbc_payment_response.createdOn
            payment.save_to_db()

            nr_model.priorityCd = 'Y'
            nr_model.priorityDate = datetime.utcnow()

            # Save the name request
            nr_model.save_to_db()

        # This (optionally) handles the updates for NRO and Solr, if necessary
        update_solr = False
        nr_model = self.update_records_in_network_services(
            nr_model, update_solr)

        # Update the actions, as things change once the payment is successful
        self.nr_service.current_state_actions = get_nr_state_actions(
            nr_model.stateCd, nr_model)

        # Record the event
        EventRecorder.record(nr_svc.user,
                             Event.PATCH + ' [payment completed] UPGRADE',
                             nr_model, nr_model.json())

        return nr_model
コード例 #8
0
def test_update_nr_header_with_mutating_priority(freeze_datetime_utcnow,
                                                 test_name,
                                                 initial_priority_cd,
                                                 second_priority_code,
                                                 expected_cd, expected_dt):

    from namex.services.nro.request_utils import add_nr_header

    nr = Request()
    user = User('idir/bob', 'bob', 'last', 'idir', 'localhost')
    nr_submitter = {
        'submitted_date': EPOCH_DATETIME,
        'submitter': 'doesnt matter'
    }

    nr_header = {
        'priority_cd': initial_priority_cd,
        'state_type_cd': 'H',
        'nr_num': 'NR 0000001',
        'request_id': 1,
        'previous_request_id': None,
        'submit_count': 0,
        'request_type_cd': 'REQ',
        'expiration_date': None,
        'additional_info': None,
        'nature_business_info': 'N/A',
        'xpro_jurisdiction': None,
        'submitted_date': EPOCH_DATETIME,
        'last_update': EPOCH_DATETIME
    }

    print(nr.json())

    add_nr_header(nr, nr_header, nr_submitter, user)

    nr_header['priority_cd'] = second_priority_code
    add_nr_header(nr, nr_header, nr_submitter, user)

    assert expected_cd == nr.priorityCd
    assert expected_dt == nr.priorityDate
コード例 #9
0
    def handle_patch_request_refund(self, nr_model: Request):
        """
        Can the NR and request a refund for ALL associated Name Request payments.
        :param nr_model:
        :return:
        """
        nr_svc = self.nr_service

        # This handles updates if the NR state is 'patchable'
        nr_model = self.update_nr(nr_model, State.REFUND_REQUESTED,
                                  self.handle_nr_patch)

        # Handle the payments
        valid_states = [
            PaymentState.APPROVED.value, PaymentState.COMPLETED.value,
            PaymentState.PARTIAL.value
        ]
        # Cancel any payments associated with the NR
        for payment in nr_model.payments.all():
            if payment.payment_status_code in valid_states:
                if NameRequestFields._should_refund_sbc_payment(
                        payment.payment_token):
                    # refund_payment(payment.payment_token, {'reason': 'Name Request user requested refund'})
                    refund_payment(payment.payment_token, {})
                payment.payment_status_code = PaymentState.REFUND_REQUESTED.value
                payment.save_to_db()

        # This handles the updates for NRO and Solr, if necessary
        nr_model = self.update_records_in_network_services(nr_model,
                                                           update_solr=True)

        # Record the event
        EventRecorder.record(nr_svc.user, Event.PATCH + ' [request-refund]',
                             nr_model, nr_model.json())

        return nr_model
コード例 #10
0
ファイル: payment.py プロジェクト: vysakh-menon-aot/namex
 def cancel_payment(self, nr_model: RequestDAO, payment_id: int):
     # Cancel payment with specified id.
     valid_states = [PaymentState.CREATED.value]
     for payment in nr_model.payments.all():
         if payment.id == payment_id and payment.payment_status_code in valid_states:
             sbc_payment_response = get_payment(payment.payment_token)
             if sbc_payment_response.statusCode in [
                     PaymentStatusCode.COMPLETED.value,
                     PaymentStatusCode.APPROVED.value
             ]:
                 raise PaymentServiceError(
                     message=
                     'Error cancelling payment. Payment is in a completed state!'
                 )
             cancel_payment(payment.payment_token)
             payment.payment_status_code = PaymentState.CANCELLED.value
             payment.save_to_db()
             # record the event
             nr_svc = self.nr_service
             EventRecorder.record(
                 nr_svc.user, Event.DELETE +
                 f' [payment cancelled] {payment.payment_action}', nr_model,
                 nr_model.json())
     return nr_model
コード例 #11
0
ファイル: name_requests.py プロジェクト: rarmitag/namex
    def post(*args, **kwargs):

        app_config = current_app.config.get('SOLR_SYNONYMS_API_URL', None)
        if not app_config:
            current_app.logger.error('ENV is not set')
            return None, 'Internal server error', 500

        test_env = 'prod'
        if test_env in app_config:
            current_app.logger.info(
                'Someone is trying to post a new request. Not available.')
            return jsonify(
                {'message': 'Not Implemented in the current environment'}), 501

        json_data = request.get_json()
        if not json_data:
            current_app.logger.error("Error when getting json input")
            return jsonify({'message': 'No input data provided'}), 400

        try:

            restricted = VirtualWordConditionService()
        except Exception as error:
            current_app.logger.error(
                "'Error initializing VirtualWordCondition Service: Error:{0}".
                format(error))
            return jsonify({"message":
                            "Virtual Word Condition Service error"}), 404

        try:
            user = User.find_by_username('name_request_service_account')
            user_id = user.id
        except Exception as error:
            current_app.logger.error(
                "Error getting user id: Error:{0}".format(error))
            return jsonify({"message": "Get User Error"}), 404

        try:
            name_request = Request()
        except Exception as error:
            current_app.logger.error(
                "Error initializing name_request object Error:{0}".format(
                    error))
            return jsonify({"message": "Name Request object error"}), 404

        try:
            nr_num = generate_nr()
            nr_id = get_request_sequence()
        except Exception as error:
            current_app.logger.error(
                "Error getting nr number. Error:{0}".format(error))
            return jsonify({"message": "Error getting nr number"}), 404

        #set the request attributes
        try:
            name_request.id = nr_id
            name_request.submittedDate = datetime.utcnow()
            name_request.requestTypeCd = set_request_type(
                json_data['entity_type'], json_data['request_action'])
            name_request.nrNum = nr_num
        except Exception as error:
            current_app.logger.error(
                "Error setting request header attributes. Error:{0}".format(
                    error))
            return jsonify(
                {"message": "Error setting request header attributes"}), 404

        try:

            if (json_data['stateCd'] == 'COND-RESERVE'):
                name_request.consentFlag = 'Y'

            if json_data['stateCd'] in [State.RESERVED, State.COND_RESERVE]:
                name_request.expirationDate = create_expiry_date(
                    start=name_request.submittedDate,
                    expires_in_days=56,
                    tz=timezone('UTC'))

            name_request.stateCd = json_data['stateCd']
            name_request.entity_type_cd = json_data['entity_type']
            name_request.request_action_cd = json_data['request_action']
        except Exception as error:
            current_app.logger.error(
                "Error setting reserve state and expiration date. Error:{0}".
                format(error))
            return jsonify(
                {"message":
                 "Error setting reserve state and expiration date"}), 404

        #set this to name_request_service_account
        name_request.userId = user_id
        try:
            lang_comment = add_language_comment(json_data['english'], user_id,
                                                nr_id)
            name_request.comments.append(lang_comment)
        except Exception as error:
            current_app.logger.error(
                "Error setting language comment. Error:{0}".format(error))
            return jsonify({"message": "Error setting language comment."}), 404

        try:
            if json_data['nameFlag'] == True:
                name_comment = add_name_comment(user_id, nr_id)
                name_request.comments.append(name_comment)

        except Exception as error:
            current_app.logger.error(
                "Error setting person name comment. Error:{0}".format(error))
            return jsonify({"message":
                            "Error setting person name comment."}), 404

        try:
            if json_data['submit_count'] is None:
                name_request.submitCount = 1
            else:
                name_request.submitCount = +1
        except Exception as error:
            current_app.logger.error(
                "Error setting submit count. Error:{0}".format(error))
            return jsonify({"message": "Error setting submit count."}), 404

        try:
            if json_data['stateCd'] == State.DRAFT:
                # set request header attributes
                name_request = set_draft_attributes(name_request, json_data,
                                                    user_id)
                name_request.save_to_db()
                nrd = Request.find_by_nr(name_request.nrNum)
                try:
                    # set applicant attributes
                    nrd_app = set_applicant_attributes(json_data, nr_id)
                    nrd.applicants.append(nrd_app)

                except Exception as error:
                    current_app.logger.error(
                        "Error setting applicant. Error:{0}".format(error))
                    return jsonify({"message":
                                    "Error setting applicant."}), 404

        except Exception as error:
            current_app.logger.error(
                "Error setting DRAFT attributes. Error:{0}".format(error))
            return jsonify({"message": "Error setting DRAFT attributes."}), 404

        try:

            if json_data['stateCd'] in [
                    State.RESERVED, State.COND_RESERVE, State.DRAFT
            ]:
                name_request.save_to_db()
                nrd = Request.find_by_nr(name_request.nrNum)

        except Exception as error:
            current_app.logger.error(
                "Error saving reservation to db. Error:{0}".format(error))
            return jsonify({"message": "Error saving reservation to db."}), 404

        try:
            nrd = Request.find_by_nr(name_request.nrNum)
        except Exception as error:
            current_app.logger.error(
                "Error retrieving the New NR from the db. Error:{0}".format(
                    error))
            return jsonify(
                {"message": "Error retrieving the New NR from the db."}), 404

        try:
            for name in json_data.get('names', None):
                try:
                    submitted_name = Name()
                    name_id = get_name_sequence()
                    submitted_name.id = name_id
                except Exception as error:
                    current_app.logger.error(
                        "Error on submitted Name object. Error:{0}".format(
                            error))
                    return jsonify(
                        {"message":
                         "Error on submitted_name and sequence."}), 404

                #common name attributes
                try:
                    submitted_name.choice = name['choice']
                    submitted_name.name = name['name']

                    if (name['name_type_cd']):
                        submitted_name.name_type_cd = name['name_type_cd']
                    else:
                        submitted_name.name_type_cd = 'CO'

                    if (json_data['stateCd'] == State.DRAFT):
                        submitted_name.state = 'NE'
                    else:
                        submitted_name.state = json_data['stateCd']

                    if name['designation']:
                        submitted_name.designation = name['designation']

                    submitted_name.nrId = nr_id
                except Exception as error:
                    current_app.logger.error(
                        "Error on common name attributes. Error:{0}".format(
                            error))
                    return jsonify(
                        {"message": "Error on common name attributes."}), 404

                decision_text = None

                if json_data['stateCd'] in [
                        State.RESERVED, State.COND_RESERVE
                ]:
                    try:
                        # only capturing one conflict
                        if (name['conflict1_num']):
                            submitted_name.conflict1_num = name[
                                'conflict1_num']
                        if name['conflict1']:
                            submitted_name.conflict1 = name['conflict1']
                        #conflict text same as Namex
                        decision_text = 'Consent is required from ' + name[
                            'conflict1'] + '\n' + '\n'
                    except Exception as error:
                        current_app.logger.error(
                            "Error on reserved conflict info. Error:{0}".
                            format(error))
                        return jsonify(
                            {"message":
                             "Error on reserved conflict info."}), 404

                else:
                    try:
                        submitted_name.conflict1_num = None
                        submitted_name.conflict1 = None
                    except Exception as error:
                        current_app.logger.error(
                            "Error on draft empty conflict info. Error:{0}".
                            format(error))
                        return jsonify(
                            {"message":
                             "Error on draft empty conflict info."}), 404

                consent_list = name['consent_words']
                if len(consent_list) > 0:
                    for consent in consent_list:
                        try:
                            cnd_instructions = None
                            if consent != "" or len(consent) > 0:
                                cnd_instructions = restricted.get_word_condition_instructions(
                                    consent)
                        except Exception as error:
                            current_app.logger.error(
                                "Error on get consent word. Consent Word[0], Error:{1}"
                                .format(consent, error))
                            return jsonify(
                                {"message":
                                 "Error on get consent words."}), 404

                        try:
                            if (decision_text is None):
                                decision_text = cnd_instructions + '\n'
                            else:
                                decision_text += consent + '- ' + cnd_instructions + '\n'

                            submitted_name.decision_text = decision_text
                        except Exception as error:
                            current_app.logger.error(
                                "Error on adding consent words to decision. Error:{0}"
                                .format(error))
                            return jsonify({
                                "message":
                                "Error on adding consent words to decision text"
                            }), 404
                try:
                    nrd.names.append(submitted_name)
                except Exception as error:
                    current_app.logger.error(
                        "Error appending names. Error:{0}".format(error))
                    return jsonify({"message": "Error appending names"}), 404

            try:
                #save names
                nrd.save_to_db()
            except Exception as error:
                current_app.logger.error(
                    "Error saving the whole nr and names. Error:{0}".format(
                        error))
                return jsonify({"message":
                                "Error saving names to the db"}), 404

        except Exception as error:
            current_app.logger.error(
                "Error setting name. Error:{0}".format(error))
            return jsonify({"message": "Error setting name."}), 404

        #TODO: Need to add verification that the save was successful.

    #update solr for reservation
        try:
            if (json_data['stateCd'] in ['RESERVED', 'COND-RESERVE']):
                solr_name = nrd.names[0].name
                solr_docs = []
                nr_doc = {
                    "id":
                    name_request.nrNum,
                    "name":
                    solr_name,
                    "source":
                    "NR",
                    "start_date":
                    name_request.submittedDate.strftime("%Y-%m-%dT%H:%M:00Z")
                }

                solr_docs.append(nr_doc)
                update_solr('possible.conflicts', solr_docs)
        except Exception as error:
            current_app.logger.error(
                "Error updating solr for reservation. Error:{0}".format(error))
            return jsonify({"message":
                            "Error updating solr for reservation."}), 404

        current_app.logger.debug(name_request.json())
        return jsonify(name_request.json()), 200