Ejemplo n.º 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)
Ejemplo n.º 2
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))
Ejemplo n.º 3
0
    def process(self, search_query):
        local_land_charge_service = LocalLandChargeService(self.config)

        if self.search_valid(search_query, CHARGE_NUMBER_REGEX):
            self.logger.info("Searching by charge ID: %s", search_query)
            response = local_land_charge_service.get_by_charge_number(search_query)
        else:
            self.logger.info("Searching by reference number: %s", search_query)
            response = local_land_charge_service.get_by_reference_number(search_query)

        return self.process_search_response(response)
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))
Ejemplo n.º 5
0
def modify_lon_details_get(charge_id):
    current_app.logger.info(
        "Endpoint called with charge_id='{}'".format(charge_id))

    # If the charge not in session, redirect to initial upload screen
    if not g.session.add_lon_charge_state:
        return redirect(
            url_for("modify_lon.modify_lon_upload_get", charge_id=charge_id))

    session_charge_id = calc_display_id(
        g.session.add_lon_charge_state.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 session_charge_id != charge_id:
        g.session.add_lon_charge_state = None
        g.session.commit()
        return redirect(
            url_for("modify_lon.modify_lon_upload_get", charge_id=charge_id))

    # Retrieve Light Obstruction Notice Item
    local_land_charge_service = LocalLandChargeService(current_app.config)

    charge_item = g.session.add_lon_charge_state
    updated, updated_date = get_history_update_info_by_charge_id(
        charge_id, local_land_charge_service)

    return render_template("modify_lon_details.html",
                           charge_id=charge_id,
                           charge_item=charge_item,
                           updated=updated,
                           updated_date=updated_date,
                           geometry=json.dumps(charge_item.geometry))
Ejemplo n.º 6
0
def view_lon(charge_id):
    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_lon_charge_state = None
    g.session.edited_fields = None
    g.session.commit()
    current_app.logger.info("Charge cleared from session")

    display_id, charge_item = get_lon_by_charge_id(charge_id,
                                                   local_land_charge_service)
    # Let the LLC blueprint handle LLC's
    if charge_item.charge_type != LonDefaults.charge_type:
        return redirect(
            url_for('view_land_charge.view_land_charge',
                    local_land_charge=charge_id))

    updated, updated_date = get_history_update_info_by_charge_id(
        charge_id, local_land_charge_service)

    AuditAPIService.audit_event("User viewing LON: {}".format(charge_id))

    return render_template(
        'view_lon.html',
        charge_id=display_id,
        charge_item=charge_item,
        updated=updated,
        updated_date=updated_date,
        geometry=json.dumps(charge_item.geometry),
        document_urls=get_external_url_for_docs(charge_item))
    def test_get_with_bounding_box(self, mock_current_app):
        with main.app.test_request_context():
            g.requests = MagicMock()
            response = MagicMock()
            response.status_code = 200
            response.json.return_value = {'results': [{"abc": "def"}]}

            g.requests.post.return_value = response
            search_api = 'abc'
            mock_current_app.config = {'SEARCH_API_URL': search_api}

            local_land_charge_service = LocalLandChargeService(mock_current_app.config)

            response = local_land_charge_service.get(BASE64_BOUNDING_BOX)

            self.assertEqual(response.status_code, 200)

            g.requests.post.assert_called_with(
                "http://{}/v2.0/search/local_land_charges".format(search_api),
                data=BASE64_BOUNDING_BOX,
                headers={'Content-Type': 'application/json'}
            )
    def test_get_history_for_charge(self, mock_current_app):
        with main.app.test_request_context():
            g.requests = MagicMock()
            response = MagicMock()
            response.status_code = 200
            response.json.return_value = {'results': [{"abc": "def"}]}

            g.requests.get.return_value = response
            search_api = 'abc'
            mock_current_app.config = {'SEARCH_API_URL': search_api}
            charge_number = 'LLC-1'

            local_land_charge_service = LocalLandChargeService(mock_current_app.config)

            response = local_land_charge_service.get_history_for_charge(charge_number)

            self.assertEqual(response.status_code, 200)

            g.requests.get.assert_called_with(
                "http://{}/v2.0/search/local_land_charges/{}/history".format(
                    search_api, charge_number),
                params=None
            )
def modify_lon_upload_get(charge_id):
    current_app.logger.info(
        "Endpoint called with charge_id='{}'".format(charge_id))
    local_land_charge_service = LocalLandChargeService(current_app.config)

    # Retrieve Light Obstruction Notice Item
    display_id, charge_item = get_lon_by_charge_id(charge_id,
                                                   local_land_charge_service)
    g.session.edited_fields = {}
    g.session.commit()

    # 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(
                charge_id))
        raise ApplicationError(500)

    # If the charge is in session we are in the process of updating it
    if not g.session.add_lon_charge_state:
        g.session.add_lon_charge_state = charge_item
        g.session.commit()

        current_app.logger.info("Session charge updated - Rendering Template")
        return render_template('modify_lon_upload.html',
                               charge_id=display_id,
                               charge_item=charge_item)

    else:
        session_charge_id = calc_display_id(
            g.session.add_lon_charge_state.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 session_charge_id != display_id:
            g.session.add_lon_charge_state = None
            g.session.commit()
            return redirect(
                url_for("modify_lon.modify_lon_upload_get",
                        charge_id=charge_id))

        return render_template('modify_lon_upload.html',
                               charge_id=display_id,
                               charge_item=charge_item)
Ejemplo n.º 10
0
def confirm(charge_id):
    local_land_charge_service = LocalLandChargeService(current_app.config)
    display_id, charge_item = get_lon_by_charge_id(charge_id,
                                                   local_land_charge_service)

    if request.method == 'GET':
        return render_template('cancel_lon_confirm.html',
                               charge_id=display_id,
                               charge_item=charge_item,
                               geometry=json.dumps(charge_item.geometry))
    if request.method == 'POST':
        current_app.logger.info("Cancelling Charge - {}".format(display_id))
        AuditAPIService.audit_event("Cancelling charge",
                                    supporting_info={'id': display_id})
        MaintainApiService.update_charge(g.session.add_lon_charge_state)
        # 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_lon.charge_cancelled', charge_id=display_id))
Ejemplo n.º 11
0
def cancel_post(charge_id):
    local_land_charge_service = LocalLandChargeService(current_app.config)
    display_id, charge_item = get_lon_by_charge_id(charge_id,
                                                   local_land_charge_service)

    cancel_options = request.form.getlist('cancel-options')
    form_b = request.files.get('form-b-cancel-lon-file-input')
    court_order = request.files.get('court-order-cancel-lon-file-input')

    current_app.logger.info("Running validation")
    validation_error_builder = CancelLonValidator.validate(
        request.form, request.files)

    if validation_error_builder.errors:
        current_app.logger.warning("Validation errors occurred")
        return render_template(
            'cancel_lon.html',
            charge_id=display_id,
            validation_errors=validation_error_builder.errors,
            validation_summary_heading=validation_error_builder.
            summary_heading_text,
            request_body=request.form), 400

    files_to_upload = {}

    if "Form B" in cancel_options and form_b:
        files_to_upload['form-b'] = ('form_b.pdf', form_b, form_b.content_type)

    if "Court Order" in cancel_options and court_order:
        files_to_upload['court-order'] = ("court_order.pdf", court_order,
                                          court_order.content_type)

    if files_to_upload:
        upload_files(files_to_upload, charge_item, charge_id)

    charge_item.end_date = date.today()

    g.session.add_lon_charge_state = charge_item
    g.session.commit()

    return redirect(url_for('cancel_lon.confirm', charge_id=charge_id))
class SearchByArea(object):
    def __init__(self, logger, config):
        self.logger = logger
        self.local_land_charge_service = LocalLandChargeService(config)

    def process(self, bounding_box):
        response = dict()
        search_response = self.process_request(bounding_box)

        response['status'] = search_response.status_code
        if search_response.status_code == 200:
            response['data'] = search_response.json()
        return response

    def process_request(self, bounding_box):
        if bounding_box:
            return self.get_results_for_boundary(bounding_box)

    def get_results_for_boundary(self, bounding_box):
        self.logger.info("Searching area by bounding box")
        return self.local_land_charge_service.get(
            self.prepare_bounding_box(bounding_box))

    @staticmethod
    def prepare_bounding_box(bounding_box):
        return SearchByArea.build_bounding_box_json(bounding_box)

    @staticmethod
    def build_bounding_box_json(bounding_box):
        geo_dict = {
            "type": "Polygon",
            "coordinates": json.loads(bounding_box),
            "crs": {
                "type": "name",
                "properties": {
                    "name": "EPSG:27700"
                }
            }
        }

        return json.dumps(geo_dict)
def modify_lon_upload_post(charge_id):
    # Retrieve Charge
    local_land_charge_service = LocalLandChargeService(current_app.config)
    display_id, charge_item = get_lon_by_charge_id(charge_id,
                                                   local_land_charge_service)

    validation_error_builder = VaryLonValidator.validate(
        request.form, request.files)

    if validation_error_builder.errors:
        current_app.logger.warning("Validation errors occurred")
        return render_template(
            'modify_lon_upload.html',
            charge_id=display_id,
            charge_item=charge_item,
            validation_errors=validation_error_builder.errors,
            validation_summary_heading=validation_error_builder.
            summary_heading_text,
            request_body=request.form), 400

    handle_vary_lon_options_choice(charge_id, charge_item)
    return redirect(
        url_for('modify_lon.modify_lon_details_get', charge_id=charge_id))
Ejemplo n.º 14
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)
Ejemplo n.º 15
0
def cancel_get(charge_id):
    # Retrieve Charge
    local_land_charge_service = LocalLandChargeService(current_app.config)
    display_id, charge_item = get_lon_by_charge_id(charge_id,
                                                   local_land_charge_service)
    return render_template('cancel_lon.html', charge_id=display_id)
 def __init__(self, logger, config):
     self.logger = logger
     self.local_land_charge_service = LocalLandChargeService(config)