Beispiel #1
0
def history(charge_id):

    llc_service = LocalLandChargeService(current_app.config)
    validate_charge_id(charge_id)

    history_response = llc_service.get_history_for_charge(charge_id)
    search_response = llc_service.get_by_charge_number(charge_id)

    if history_response.status_code == 404 or search_response.status_code == 404:
        current_app.logger.warning("Charge not found for charge_id='{}' - Returning not found".format(charge_id))
        raise ApplicationError(404)

    if history_response.status_code == 500 or search_response.status_code == 500:
        current_app.logger.error("Server error occurred when getting details for charge_id''{}".format(charge_id))
        raise ApplicationError(500)

    history_response.raise_for_status()
    search_response.raise_for_status()

    history_items = list(reversed(LocalLandChargeHistoryItem.from_json(history_response.json())))

    charge_data = search_response.json()[0]['item']
    land_charge = LocalLandChargeItem.from_json(charge_data)

    return render_template('view_charge_history.html', charge_id=charge_id,
                           history=history_items, local_land_charge=land_charge,
                           format_date_bst=DateFormatter.format_date_bst)
    def test_modify_confirm_charge_inside_authority(self,
                                                    mock_maintain_api_service,
                                                    mock_audit):
        self.client.set_cookie('localhost', Session.session_cookie_name,
                               'cookie_value')
        self.mock_session.return_value.user.permissions = [
            Permissions.vary_llc
        ]
        self.mock_session.return_value.charge_added_outside_users_authority = False
        self.mock_session.return_value.other_authority_update_permission = False

        state = LocalLandChargeItem.from_json(local_land_charge_1)
        self.mock_session.return_value.add_charge_state = state

        response = self.client.post(
            url_for('modify_land_charge.modify_land_charge_confirm'))

        self.assert_status(response, 200)
        self.assert_template_used('modify_confirmation.html')
        self.assert_context(
            'charge_id',
            'LLC-{}'.format(local_land_charge_1['local-land-charge']))

        for calls in mock_audit.mock_calls:
            self.assertNotEqual(
                calls[1],
                "Charge location varied, extent(s) modified to be outside users authority."
            )
    def test_modify_redirect_when_different_id_in_session(
            self, mock_llc_service, mock_features, mock_la_service):
        self.client.set_cookie('localhost', Session.session_cookie_name,
                               'cookie_value')
        self.mock_session.return_value.user.permissions = [
            Permissions.vary_llc
        ]
        mock_la_service.return_value.get_authorities_by_extent.return_value = [
            'test'
        ]

        state = LocalLandChargeItem.from_json(local_land_charge_1)
        self.mock_session.return_value.add_charge_state = state

        charge_id_from_url = 'LLC-98765'
        mock_response = MagicMock()
        mock_llc_service.return_value.get_by_charge_number.return_value = mock_response
        mock_response.status_code = 200
        mock_llc_service.return_value.get_history_for_charge.return_value = mock_response
        mock_response.status_code = 200
        mock_response.json.return_value = [{
            "item": local_land_charge_2,
            "display_id": charge_id_from_url,
            "cancelled": False
        }]

        response = self.client.get(
            url_for('modify_land_charge.modify_land_charge',
                    local_land_charge=charge_id_from_url))

        self.assert_status(response, 200)
        mock_llc_service.return_value.get_by_charge_number.assert_called_with(
            charge_id_from_url)
Beispiel #4
0
def view_land_charge(local_land_charge):
    current_app.logger.info("Endpoint called - Clearing session charge")

    local_land_charge_service = LocalLandChargeService(current_app.config)

    # Clear these session values if someone quit an edit back to the view page
    g.session.add_charge_state = None
    g.session.edited_fields = None
    g.session.charge_added_outside_users_authority = None
    g.session.other_authority_update_permission = None
    g.session.other_authority_cancel_permission = None
    g.session.commit()
    current_app.logger.info("Charge cleared from session")

    validate_charge_id(local_land_charge)

    current_app.logger.info(
        "Retrieving charge for local_land_charge='{}'".format(
            local_land_charge))
    response = local_land_charge_service.get_by_charge_number(
        local_land_charge)

    if response.status_code == 404:
        current_app.logger.info(
            "Search service reports '{}' not found - Returning error".format(
                local_land_charge))
        raise ApplicationError(404)

    response.raise_for_status()
    current_app.logger.info(
        "Retrieved charge for local_land_charge='{}'".format(
            local_land_charge))

    charge_data = response.json()[0]['item']
    charge_item = LocalLandChargeItem.from_json(charge_data)

    # Let the LON blueprint handle LONS
    if charge_item.charge_type == LonDefaults.charge_type:
        return redirect(
            url_for('view_lon.view_lon', charge_id=local_land_charge))

    current_app.logger.info(
        "Retrieving charge history for local_land_charge='{}'".format(
            local_land_charge))
    updated, updated_date = get_history_update_info_by_charge_id(
        local_land_charge, local_land_charge_service)

    current_app.logger.info(
        "Rendering template for local_land_charge='{}'".format(
            local_land_charge))
    AuditAPIService.audit_event(
        "User viewing charge: {}".format(local_land_charge))

    return render_template('view_charge.html',
                           charge_item=charge_item,
                           charge_id=response.json()[0]['display_id'],
                           updated_date=updated_date,
                           updated=updated,
                           geometry=json.dumps(charge_item.geometry))
def cancel_charge(charge_id):
    current_app.logger.info("Endpoint called with charge_id='{}'".format(charge_id))
    local_land_charge_service = LocalLandChargeService(current_app.config)
    current_app.logger.info("Retrieving charge information from charge_id='{}'".format(charge_id))
    response = local_land_charge_service.get_by_charge_number(charge_id)
    if response.status_code == 404:
        current_app.logger.warning("Charge not found for charge_id='{}' - Returning not found".format(charge_id))
        raise ApplicationError(404)
    response.raise_for_status()

    charge_data = response.json()[0]['item']
    charge_item = LocalLandChargeItem.from_json(charge_data)

    # add the charge to the session for checking the geometry is within the user's authority
    g.session.add_charge_state = charge_item
    g.session.commit()

    current_app.logger.info("Charge information retrieved for charge_id='{}'".format(charge_id))
    if request.method == 'GET':
        # Check if the charge is outside of the user's authority
        extent = build_extents_from_features(charge_item.geometry)
        result = LocalAuthorityService(current_app.config).get_authorities_by_extent(extent)

        if should_show_confirmation_warning(result):
            # In this case the charge is outside of the user's authority
            if Permissions.add_extent_anywhere in g.session.user.permissions:
                # If the user has permission to add a charge anywhere, give them cancel permission without asking
                g.session.other_authority_cancel_permission = True
                g.session.commit()

            if not g.session.other_authority_cancel_permission:
                # if the user has not confirmed that they can edit charges outside of their authority, make them
                return redirect(url_for('cancel_land_charge.get_cancel_location_confirmation'))

        current_app.logger.info("Rendering response for charge_id='{}'".format(charge_id))
        return render_template('cancel.html', charge_id=charge_id, charge_item=charge_item,
                               geometry=json.dumps(charge_item.geometry))
    else:
        charge_item.end_date = date.today()
        current_app.logger.info("Updating charge with cancellation date for charge_id='{}'".format(charge_id))
        AuditAPIService.audit_event("Cancelling charge", supporting_info={'id': charge_id})
        if g.session.other_authority_cancel_permission:
            AuditAPIService.audit_event(
                "Charge cancelled outside users authority.",
                supporting_info={'originating-authority': g.session.user.organisation})
        MaintainApiService.update_charge(charge_item)
        current_app.logger.info("Rendering response for charge_id='{}'".format(charge_id))
        # This is required because if the render_template is called from this post method then the flow won't be able
        # to return to the confirmation page if the user goes to the feedback form from the confirmation page
        return redirect(url_for('cancel_land_charge.cancel_confirmation', charge_id=charge_id))
    def test_modify_confirm_charge_outside_authority(self,
                                                     mock_maintain_api_service,
                                                     mock_audit):
        self.client.set_cookie('localhost', Session.session_cookie_name,
                               'cookie_value')
        self.mock_session.return_value.user.permissions = [
            Permissions.vary_llc
        ]
        self.mock_session.return_value.user.organisation = 'test org'
        self.mock_session.return_value.charge_added_outside_users_authority = True
        self.mock_session.return_value.other_authority_update_permission = False

        state = LocalLandChargeItem.from_json(local_land_charge_1)
        self.mock_session.return_value.add_charge_state = state

        response = self.client.post(
            url_for('modify_land_charge.modify_land_charge_confirm'))

        self.assert_status(response, 200)
        self.assert_template_used('modify_confirmation.html')
        self.assert_context(
            'charge_id',
            'LLC-{}'.format(local_land_charge_1['local-land-charge']))
        expected_call = [
            call("Vary request submitted.",
                 supporting_info={
                     'id':
                     calc_display_id(local_land_charge_1['local-land-charge'])
                 }),
            call(
                "Charge location varied, extent(s) modified to be outside users authority.",
                supporting_info={
                    'originating-authority':
                    self.mock_session.return_value.user.organisation,
                    'id':
                    calc_display_id(local_land_charge_1['local-land-charge'])
                })
        ]

        mock_audit.audit_event.assert_has_calls(expected_call)
    def test_put_update_land_charge_validation_error(self, mock_app, mock_audit):
        with main.app.test_request_context():
            g.requests = MagicMock()
            g.trace_id = '123'
            g.session = self.mock_session
            response = MagicMock()
            response.status_code = 500
            response.text = "response"
            g.requests.put.return_value = response

            try:
                MaintainApiService.update_charge(LocalLandChargeItem.from_json(s8))
            except Exception as ex:
                self.assertEqual(ex.http_code, 500)
                mock_app.logger.exception.assert_called()
                mock_app.logger.exception.assert_called_with(
                    'Failed to send land charge to maintain-api. TraceID : 123 - Status: 500, Message: response')
                mock_audit.audit_event.assert_called_with('Failed to send land charge to maintain-api',
                                                          supporting_info={
                                                              'id': calc_display_id(s8['local-land-charge'])
                                                          })
                return
            self.fail()
    def test_put_update_land_charge_success(self, mock_app):
        with main.app.test_request_context():
            g.requests = MagicMock()
            g.trace_id = '123'
            g.session = self.mock_session
            user = User()
            user.username = "******"
            self.mock_session = user
            response = MagicMock()
            response.status_code = 202
            response.json.return_value = {
                "entry_number": "1", "land_charge_id": "4", "registration_date": "2012-12-12"
            }
            response.text = 'Success'
            g.requests.put.return_value = response

            MaintainApiService.update_charge(LocalLandChargeItem.from_json(s8))

            self.assertIsNotNone(g.session.last_created_charge)
            self.assertEqual(g.session.last_created_charge.charge_id, "4")
            self.assertEqual(g.session.last_created_charge.registration_date, "12/12/2012")
            self.assertEqual(g.session.last_created_charge.entry_number, "1")
            self.assertEqual(g.requests.put.call_count, 1)
 def populate_state(self):
     """Populates the add charge from session state."""
     current_app.logger.info(
         "Method called, getting session state from session api")
     response = SessionAPIService.get_session_state(
         self.session_key, Session.session_state_key)
     if response is not None:
         current_app.logger.info("Non-empty session state contents")
         if 'add_charge_state' in response:
             current_app.logger.info("add_charge_state in session state")
             self.add_charge_state = LocalLandChargeItem.from_json(
                 response['add_charge_state'])
         if 'add_lon_charge_state' in response:
             current_app.logger.info(
                 "add_lon_charge_state in session state")
             self.add_lon_charge_state = LightObstructionNoticeItem.from_json(
                 response['add_lon_charge_state'])
         if 'last_created_charge' in response:
             current_app.logger.info("last_created_charge in session state")
             self.last_created_charge = LastCreatedCharge.from_dict(
                 response['last_created_charge'])
         if 'statutory_provision_list' in response:
             current_app.logger.info(
                 "statutory_provision_list in session state")
             self.statutory_provision_list = response[
                 'statutory_provision_list']
         if 'edited_fields' in response:
             current_app.logger.info("edited_fields in session state")
             self.edited_fields = response['edited_fields']
         if 'llc1_state' in response:
             current_app.logger.info("llc1_state in session state")
             self.llc1_state = LLC1Search.from_json(response['llc1_state'])
         if 'redirect_route' in response:
             current_app.logger.info('redirect_route in session state')
             self.redirect_route = response['redirect_route']
         if 'search_extent' in response:
             current_app.logger.info('search_extent in session state')
             self.search_extent = response['search_extent']
         if 'filenames' in response:
             current_app.logger.info('filenames in session state')
             self.filenames = response['filenames']
         if 'previously_selected_address' in response:
             current_app.logger.info(
                 'previously_selected_address in session state')
             self.previously_selected_address = response[
                 'previously_selected_address']
         if 'adding_charge_for_other_authority' in response:
             current_app.logger.info(
                 'adding_charge_for_other_authority in session state')
             self.adding_charge_for_other_authority = response[
                 'adding_charge_for_other_authority']
         if 'submit_token' in response:
             current_app.logger.info('submit token in session state')
             self.submit_token = response['submit_token']
         if 'upload_shapefile_processed' in response:
             current_app.logger.info(
                 'upload_shapefile_processed in session state')
             self.upload_shapefile_processed = response[
                 'upload_shapefile_processed']
         if 'category_details' in response:
             self.category_details = Category.from_dict(
                 response['category_details'])
         if 'category_confirmation' in response:
             self.category_confirmation = response['category_confirmation']
         if 'charge_added_outside_users_authority' in response:
             self.charge_added_outside_users_authority = response[
                 'charge_added_outside_users_authority']
         if 'other_authority_update_permission' in response:
             self.other_authority_update_permission = response[
                 'other_authority_update_permission']
         if 'other_authority_cancel_permission' in response:
             self.other_authority_cancel_permission = response[
                 'other_authority_cancel_permission']
         if 'source_information' in response:
             self.source_information = response['source_information']
         if 'source_information_id' in response:
             self.source_information_id = response['source_information_id']
         if 'send_payment_link_info' in response:
             current_app.logger.info(
                 "send_payment_link_info in session state")
             self.send_payment_link_info = PaymentLink.from_json(
                 response['send_payment_link_info'])
         if 'payment_info' in response:
             current_app.logger.info("payment_info in session state")
             self.payment_info = PaymentInfo.from_json(
                 response['payment_info'])
         if 'search_details' in response:
             self.search_details = SearchDetails.from_json(
                 response['search_details'])
Beispiel #10
0
def modify_land_charge(local_land_charge):
    current_app.logger.info(
        "Endpoint called with local_land_charge='{}'".format(
            local_land_charge))

    validate_charge_id(local_land_charge)

    local_land_charge_service = LocalLandChargeService(current_app.config)
    response = local_land_charge_service.get_by_charge_number(
        local_land_charge)

    if response.status_code == 404:
        current_app.logger.warning(
            "Charge not found for local_land_charge='{}' - Returning not found"
            .format(local_land_charge))
        raise ApplicationError(404)

    response.raise_for_status()

    updated, updated_date = get_history_update_info_by_charge_id(
        local_land_charge, local_land_charge_service)

    if not g.session.add_charge_state:
        current_app.logger.info(
            "Retrieving charge with local_land_charge='{}'".format(
                local_land_charge))
        # If the charge does not exist in the session, load it from the database, otherwise we are in the
        # process of updating it and as such it should be loaded from the session data

        charge_data = response.json()[0]['item']
        charge_item = LocalLandChargeItem.from_json(charge_data)

        current_app.logger.info(
            "Charge information retrieved for local_land_charge='{}' - Updating session charge"
            .format(local_land_charge))

        g.session.add_charge_state = charge_item
        g.session.edited_fields = []
        g.session.commit()

        current_app.logger.info("Session charge updated - Rendering Template")
    else:
        charge_id = calc_display_id(
            g.session.add_charge_state.local_land_charge)
        current_app.logger.info('charge_id: {}'.format(charge_id))
        current_app.logger.info(
            'local_land_charge: {}'.format(local_land_charge))

        # Check that charge ID in session and URL match.
        # If they don't, redirect user to the charge ID they entered and clear session
        if charge_id != local_land_charge:
            g.session.add_charge_state = None
            g.session.edited_fields = None
            g.session.commit()
            return modify_land_charge(local_land_charge)

        charge_item = g.session.add_charge_state

        current_app.logger.info("Session charge updated - Rendering Template")

    # Check that charge hasn't been cancelled in case user attempts to navigate to update URL manually
    if charge_item.end_date:
        current_app.logger.error(
            'Attempted to update a cancelled charge.  Charge ID: {}'.format(
                local_land_charge))
        raise ApplicationError(500)

    # Check if the charge is outside of the user's authority, if user hasn't already updated the map
    if not g.session.charge_added_outside_users_authority:
        extent = build_extents_from_features(charge_item.geometry)
        result = LocalAuthorityService(
            current_app.config).get_authorities_by_extent(extent)

        if should_show_confirmation_warning(result):
            # In this case the charge is outside of the user's authority
            if Permissions.add_extent_anywhere in g.session.user.permissions:
                # If the user has permission to add a charge anywhere, give them update permission without asking
                g.session.other_authority_update_permission = True
                g.session.commit()

            if not g.session.other_authority_update_permission:
                # if the user has not confirmed that they can edit charges outside of their authority, make them
                return redirect(
                    url_for(
                        'modify_land_charge.get_update_location_confirmation'))

    return render_template('modify_charge.html',
                           charge_item=charge_item,
                           updated=updated,
                           updated_date=updated_date,
                           charge_id=response.json()[0]['display_id'],
                           geometry=json.dumps(charge_item.geometry),
                           edited_fields=get_ordered_edited_fields(
                               g.session.edited_fields, ReviewMap),
                           map=ReviewMap)