def get_land_compensation_land_sold(): current_app.logger.info('Endpoint called') if g.session.add_charge_state is None: current_app.logger.error("Charge state not found in session - Returning error") raise ApplicationError(500) request_body = { 'land-sold-description': g.session.add_charge_state.land_sold_description, 'land-works-particulars': g.session.add_charge_state.land_works_particulars } current_app.logger.info("Displaying page 'land_compensation_land_sold.html'") return render_template('land_compensation_land_sold.html', request_body=request_body, submit_url=url_for('modify_land_charge.post_land_compensation_land_sold'))
def get_source_information_for_organisation(self, organisation): request_path = self.url + "organisations/{}/source-information".format( organisation) current_app.logger.info("Calling local authority api via this URL: %s", request_path) response = g.requests.get(request_path) if response.status_code == 200: current_app.logger.info( "Successfully retrieved source information for organisation") return response.json() else: current_app.logger.error( "Failed to retrieve source information for organisation") raise ApplicationError(500)
def post_location(): current_app.logger.info("Endpoint called") if g.session.add_charge_state is None: current_app.logger.error( "Charge state not found in session - Returning error") raise ApplicationError(500) information = None if 'saved-features' in request.form: information = json.loads(request.form['saved-features'].strip()) current_app.logger.info("Validating location geometry") validation_errors = AddLocationMapValidator.validate(information) if validation_errors.errors: current_app.logger.warning( "Validation errors present - Rendering page with validation errors" ) return render_template( 'location.html', validation_errors=validation_errors.errors, validation_summary_heading=validation_errors.summary_heading_text, information=information, submit_url=url_for('modify_land_charge.post_location')), 400 current_app.logger.info("Field values validated - Updating session charge") if has_value_changed(g.session.add_charge_state.geometry, information): g.session.edited_fields.append('location_info') g.session.add_charge_state.geometry = information g.session.commit() if 'LLC LR Admins' not in g.session.user.roles and 'LLC LR Users' not in g.session.user.roles: result = LocalAuthorityService( current_app.config).get_authorities_by_extent( build_extents_from_features(information)) if len(result) != 1 or g.session.user.organisation not in result: return redirect( url_for('modify_land_charge.get_location_confirmation')) charge_display_id = calc_display_id( g.session.add_charge_state.local_land_charge) current_app.logger.info( "Session charge updated - Redirecting back to modify_land_charge with local_land_charge='{}'" .format(charge_display_id)) return redirect( url_for("modify_land_charge.modify_land_charge", local_land_charge=charge_display_id))
def edit_dominant_building_extent_post(): if g.session.add_lon_charge_state is None: current_app.logger.error( "Charge state not found in session - Returning error") raise ApplicationError(500) information = None postcode_to_zoom = '' if g.session.add_lon_charge_state.charge_address: postcode_to_zoom = g.session.add_lon_charge_state.charge_address[ 'postcode'] if 'saved-features' in request.form: information = json.loads(request.form['saved-features'].strip()) validation_errors = AddLocationMapValidator.validate( information, "Draw the extent", "Draw the extent") if validation_errors.errors: current_app.logger.warning( "Validation errors present - Rendering page with validation errors" ) return render_template( 'dominant_building_extent.html', validation_errors=validation_errors.errors, validation_summary_heading=validation_errors.summary_heading_text, information=information, postcode=postcode_to_zoom, submit_url=url_for( 'modify_lon.edit_dominant_building_extent_post')), 400 if g.session.add_lon_charge_state.geometry != information: g.session.edited_fields['geometry'] = 'Extent' g.session.add_lon_charge_state.geometry = information g.session.commit() charge_display_id = calc_display_id( g.session.add_lon_charge_state.local_land_charge) current_app.logger.info( "Session charge updated - Redirecting back to modify_land_charge with local_land_charge='{}'" .format(charge_display_id)) return redirect( url_for("modify_lon.modify_lon_details_get", charge_id=charge_display_id))
def get_lon_by_charge_id(charge_id, local_land_charge_service): validate_charge_id(charge_id) 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.info("Search service reports '{}' not found - Returning error".format(charge_id)) raise ApplicationError(404) response.raise_for_status() charge_item = LightObstructionNoticeItem.from_json(response.json()[0]['item']) display_id = response.json()[0]['display_id'] current_app.logger.info("Retrieved charge for local_land_charge='{}'".format(charge_id)) return display_id, charge_item
def get_history_update_info_by_charge_id(charge_id, local_land_charge_service): hist_response = local_land_charge_service.get_history_for_charge(charge_id) if hist_response.status_code == 404: current_app.logger.info("Search service reports '{}' not found - Returning error".format(charge_id)) raise ApplicationError(404) hist_response.raise_for_status() history_items = list(reversed(LocalLandChargeHistoryItem.from_json(hist_response.json()))) if len(history_items) > 1: updated_date = history_items[0].entry_timestamp.strftime('%-d %B %Y') updated = True else: updated_date = None updated = False return updated, updated_date
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)
def post_land_compensation_land_sold(): current_app.logger.info("Endpoint called with land-sold-description = '%s' and land-works-particulars = '%s'", request.form.get('land-sold-description', ''), request.form.get('land-works-particulars', '')) if g.session.add_charge_state is None: current_app.logger.error("Charge state not found in session - Returning error") raise ApplicationError(500) description = request.form['land-sold-description'].strip() land_works_particulars = request.form['land-works-particulars'].strip() current_app.logger.info('Running validation') validation_errors = LandCompensationLandSoldValidator.validate(description, land_works_particulars) if validation_errors.errors: current_app.logger.warning('Validation errors occurred') return render_template('land_compensation_land_sold.html', validation_errors=validation_errors.errors, validation_summary_heading=validation_errors.summary_heading_text, request_body=request.form, submit_url=url_for('modify_land_charge.post_land_compensation_land_sold')), 400 current_app.logger.info("Updating session object with land-sold-description = '%s' and " "land-works-particulars = '%s'", description, land_works_particulars) charge_display_id = calc_display_id(g.session.add_charge_state.local_land_charge) edited = False if has_value_changed(g.session.add_charge_state.land_sold_description, description): edited = True g.session.edited_fields.append('land_sold_description') g.session.add_charge_state.land_sold_description = description if has_value_changed(g.session.add_charge_state.land_works_particulars, land_works_particulars): edited = True g.session.edited_fields.append('land_works_particulars') g.session.add_charge_state.land_works_particulars = land_works_particulars if edited: g.session.commit() current_app.logger.info("Redirecting to next step: %s", url_for("modify_land_charge.modify_land_charge", local_land_charge=charge_display_id)) return redirect(url_for("modify_land_charge.modify_land_charge", local_land_charge=charge_display_id))
def post_charge_date(): current_app.logger.info("Endpoint called") if g.session.add_charge_state is None: current_app.logger.error( "Charge state not found in session - Returning error") raise ApplicationError(500) day = request.form.get('date-day') month = request.form.get('date-month') year = request.form.get('date-year') current_app.logger.info("Validating charge date") validation_errors = ChargeDateValidator.validate(day, month, year) if validation_errors.errors: current_app.logger.warning( "Validation errors present - Rendering page with validation errors" ) charge_date = {'day': day, 'month': month, 'year': year} return render_template( 'charge_date.html', validation_errors=validation_errors.errors, validation_summary_heading=validation_errors.summary_heading_text, submit_url=url_for('modify_land_charge.post_charge_date'), request=request, date=charge_date) current_app.logger.info("Field values validated - Updating session charge") if year and month and day: new_date = date(int(year), int(month), int(day)) else: new_date = None if g.session.add_charge_state.charge_creation_date != new_date: g.session.add_charge_state.charge_creation_date = new_date g.session.edited_fields.append('charge_creation_date') g.session.commit() charge_display_id = calc_display_id( g.session.add_charge_state.local_land_charge) current_app.logger.info( "Session charge updated - Redirecting back to modify_land_charge with local_land_charge='{}'" .format(charge_display_id)) return redirect( url_for("modify_land_charge.modify_land_charge", local_land_charge=charge_display_id))
def generate(self, description, extents): payload = { 'description': description, 'extents': extents, 'source': 'MAINTAIN' } current_app.logger.info("Submit LLC1 search request") response = g.requests.post( self.url, json=payload, headers={'Content-Type': 'application/json'}) if response.status_code != 201: current_app.logger.warning('Failed to create LLC1') raise ApplicationError('Failed to create LLC1') return response.json()
def get_authorities_by_extent(self, bounding_box): request_path = self.url + 'local-authorities' current_app.logger.info( "Calling local authority api by area via this URL: %s", request_path) response = g.requests.post( request_path, data=json.dumps(bounding_box), headers={'Content-Type': 'application/json'}) if response.status_code == 200: current_app.logger.info("Authorities found") return response.json() elif response.status_code == 404: current_app.logger.info("No authorities found") return {} else: current_app.logger.error("Error occurred when getting authorities") raise ApplicationError(500)
def add_source_information_for_organisation(self, source_information, organisation): request_path = self.url + "organisations/{}/source-information".format( organisation) current_app.logger.info("Calling local authority api via this URL: %s", request_path) response = g.requests.post( request_path, data=json.dumps({'source-information': source_information}), headers={'Content-Type': 'application/json'}) if response.status_code == 201: current_app.logger.info( "Successfully added source information for organisation") return response.json() else: current_app.logger.error( "Failed to add source information for organisation") raise ApplicationError(500)
def get_charge_date(): current_app.logger.info("Endpoint called") if g.session.add_charge_state is None: current_app.logger.error( "Charge state not found in session - Returning error") raise ApplicationError(500) create_date = g.session.add_charge_state.charge_creation_date if create_date: charge_date = { 'day': str(create_date.day), 'month': str(create_date.month), 'year': str(create_date.year) } else: charge_date = None current_app.logger.info("Rendering template") return render_template( 'charge_date.html', submit_url=url_for('modify_land_charge.post_charge_date'), date=charge_date)
def test_cancel_post_fail(self, mock_maintain, mock_llcservice): self.client.set_cookie('localhost', Session.session_cookie_name, 'cookie_value') self.mock_session.return_value.user.permissions = [ Permissions.cancel_llc ] mock_response = MagicMock() mock_llcservice.return_value.get_by_charge_number.return_value = mock_response mock_response.status_code = 200 mock_response.json.return_value = [{ "item": { "actual_charge": s8 }, "display_id": "LLC-TST" }] mock_maintain.update_charge.side_effect = ApplicationError(500) response = self.client.post( url_for('cancel_land_charge.cancel_charge', charge_id='LLC-TST')) self.assert_status(response, 302)
def get_charge_description(): current_app.logger.info('Endpoint called') try: if g.session.add_charge_state is None: current_app.logger.info('Redirecting to: {}'.format(url_for('add_land_charge.new'))) return redirect(url_for('add_land_charge.new')) current_app.logger.info("Displaying page 'charge_description.html'") return render_template('charge_description.html', data=g.session.add_charge_state.supplementary_information, submit_url=url_for('add_land_charge.post_charge_description')) except Exception as ex: error_message = 'Failed getting add_land_charge description page. ' \ 'TraceID: {} - Exception - {}' \ .format(g.trace_id, ex) current_app.logger.error(error_message) raise ApplicationError(error_message)
def edit_applicant_info_post(): if g.session.add_lon_charge_state is None: current_app.logger.error("Charge state not found in session - Returning error") raise ApplicationError(500) address_form = request.form current_app.logger.info("Running validation") validation_error_builder = ApplicantInfoValidator.validate(address_form) if validation_error_builder.errors: current_app.logger.warning("Validation errors occurred") return render_template('applicant_info.html', validation_errors=validation_error_builder.errors, validation_summary_heading=validation_error_builder.summary_heading_text, submit_url=url_for('modify_lon.edit_applicant_info_post'), country_list=get_sorted_countries(), request_body=request.form), 400 applicant_address = AddressConverter.condense_address(address_form) applicant_name = address_form.get('applicant_name') current_app.logger.info("Updating session object") if applicant_name != g.session.add_lon_charge_state.applicant_name: g.session.add_lon_charge_state.applicant_name = applicant_name g.session.edited_fields['applicant-name'] = 'Name' if applicant_address != g.session.add_lon_charge_state.applicant_address: g.session.add_lon_charge_state.applicant_address = applicant_address g.session.edited_fields['applicant-address'] = 'Address' g.session.commit() charge_display_id = calc_display_id(g.session.add_lon_charge_state.local_land_charge) current_app.logger.info( "Session charge updated - Redirecting back to modify_lon with charge_id='{}'".format(charge_display_id) ) return redirect(url_for("modify_lon.modify_lon_details_get", charge_id=charge_display_id))
def process_search_response(self, response): if response.status_code == 200: self.logger.info("Search results found") response_data = { "data": response.json(), "status": "success" } return response_data elif response.status_code == 404: self.logger.info("Valid search format but no results found") response_data = { "search_message": "No results found", "status": "error" } return response_data else: self.logger.error("Error returned from a get_by function") raise ApplicationError(500)
def is_extent_within_migrated_area(self, extent): request_path = self.url + 'local-authorities/is_extent_within_migrated_area' current_app.logger.info( "Calling local authority api via this URL: {}".format( request_path)) response = g.requests.post( request_path, data=extent, headers={'Content-Type': 'application/json'}) if response.status_code == 200: current_app.logger.info( "Succesfully determined if the given extent is within a migrated area" ) return response.json() else: current_app.logger.error( "Failed to determine if the given extent is within a migrated area" ) raise ApplicationError(500)
def get_category_parent_info(category): request_path = "{0}/categories/{1}".format(MAINTAIN_API_URL, category) current_app.logger.info("Calling search api via this URL: %s", request_path) response = g.requests.get(request_path) if response.status_code != 200: current_app.logger.warning( 'Failed to retrieve sub categories with status code {}'.format( response.status_code)) raise ApplicationError('Failed to retrieve sub categories') category_details = response.json() return Category( category_details["name"], category_details["display-name"], CategoryService.filter_categories_by_permissions( category_details["sub-categories"]), category_details["statutory-provisions"], category_details["instruments"], None)
def send_message_notify(email_address, template_id, personalisation): request_body = { "email_address": email_address, "template_id": template_id, "personalisation": personalisation, "reference": None } response = g.requests.post(config.NOTIFICATION_API_URL + '/v1/notifications', data=json.dumps(request_body), headers={ "Content-Type": "application/json", "Accept": "application/json" }) if response.status_code != 201: raise ApplicationError() current_app.logger.info( "Email message sent. Template ID: '{}'".format(template_id))
def get_location(): current_app.logger.info("Endpoint called") if g.session.add_charge_state is None: current_app.logger.error( "Charge state not found in session - Returning error") raise ApplicationError(500) g.session.charge_added_outside_users_authority = False g.session.commit() if g.session.add_charge_state.geometry is not None: current_app.logger.info( "Rendering template with session charge geometry") return render_template( 'location.html', information=g.session.add_charge_state.geometry, submit_url=url_for('modify_land_charge.post_location')) current_app.logger.info("Rendering template with no geometry") return render_template( 'location.html', submit_url=url_for('modify_land_charge.post_location'))
def edit_servient_structure_position_get(): if g.session.add_lon_charge_state is None: current_app.logger.error( "Charge state not found in session - Returning error") raise ApplicationError(500) structure_position_and_dimension = g.session.add_lon_charge_state.structure_position_and_dimension request_body = {} if structure_position_and_dimension[ 'extent-covered'] == 'All of the extent': request_body['extent'] = "All of the extent" else: request_body['extent'] = "Part of the extent" request_body['part_extent_detail'] = structure_position_and_dimension[ 'part-explanatory-text'] return render_template( 'servient_structure_position.html', submit_url=url_for('modify_lon.edit_servient_structure_position_post'), request_body=request_body)
def test_add_location_post_redirects_to_error(self, mock_review_router, mock_la_api): self.client.set_cookie('localhost', Session.session_cookie_name, 'cookie_value') mock_review_router.get_redirect_url.return_value = url_for( 'add_land_charge.get_address_confirmation') input = '{"type":"FeatureCollection",' \ '"features":[' \ '{"type":"Feature",' \ '"geometry":{' \ '"type":"Polygon",' \ '"coordinates":[' \ '[[511076.08598934463,381319.1389185938],' \ '[502935.0162093069,344754.81621829123],' \ '[460299.51643357374,365124.6766137525],' \ '[478395.29646112275,392099.3797708411],' \ '[511076.08598934463,381319.1389185938]]]},' \ '"properties":{"id":1}}]}' state = LocalLandChargeItem() self.mock_session.return_value.add_charge_state = state self.mock_session.return_value.user.permissions = [Permissions.add_llc] self.mock_session.return_value.user.roles = ['LLC LA Admins'] self.mock_session.return_value.user.organisation = 'Abc' mock_la_api.return_value.get_authorities_by_extent.side_effect = ApplicationError( 500) response = self.client.post(url_for('add_land_charge.post_location'), data={'saved-features': input}) mock_review_router.update_edited_field.assert_called_with( 'geometry', json.loads(input.strip())) self.assert_status(response, 302) self.assertRedirects(response, '/error')
def edit_servient_structure_height_get(): if g.session.add_lon_charge_state is None: current_app.logger.error( "Charge state not found in session - Returning error") raise ApplicationError(500) structure_position_and_dimension = g.session.add_lon_charge_state.structure_position_and_dimension request_body = {} if 'height' in structure_position_and_dimension: if structure_position_and_dimension['height'] == "Unlimited height": request_body['measurement'] = "Unlimited height" else: request_body['measurement'] = "I have measurements for the height" request_body['height'] = structure_position_and_dimension['height'] request_body['unit'] = structure_position_and_dimension['units'] return render_template( 'servient_structure_height.html', submit_url=url_for('modify_lon.edit_servient_structure_height_post'), request_body=request_body)
def search_by_area_endpoint(): current_app.logger.info("Search by Land Charge requested") g.session.search_extent = None g.session.commit() if not request.is_xhr: current_app.logger.error("Search request not xhr") raise ApplicationError(500) bounding_box = request.get_data().decode() search_by_area_processor = SearchByArea(current_app.logger, current_app.config) response = search_by_area_processor.process(bounding_box) if response['status'] == 200: g.session.search_extent = SearchByArea.build_bounding_box_json( bounding_box) g.session.commit() return jsonify(response)
def edit_dominant_building_get(): if g.session.add_lon_charge_state is None: current_app.logger.error( "Charge state not found in session - Returning error") raise ApplicationError(500) if g.session.add_lon_charge_state.charge_address: dominant_address = g.session.add_lon_charge_state.charge_address request_body = { 'address_line_1': dominant_address['line-1'], 'postcode': dominant_address['postcode'] } if 'line-2' in dominant_address: request_body['address_line_2'] = dominant_address['line-2'] if 'line-3' in dominant_address: request_body['address_line_3'] = dominant_address['line-3'] if 'line-4' in dominant_address: request_body['address_line_4'] = dominant_address['line-4'] if 'line-5' in dominant_address: request_body['address_line_5'] = dominant_address['line-5'] if 'line-6' in dominant_address: request_body['address_line_6'] = dominant_address['line-6'] if 'unique-property-reference-number' in dominant_address: request_body['uprn'] = dominant_address[ 'unique-property-reference-number'] elif g.session.add_lon_charge_state.charge_geographic_description: request_body = { 'charge_geographic_description': g.session.add_lon_charge_state.charge_geographic_description } current_app.logger.info("Rendering template") return render_template( 'dominant_building.html', submit_url=url_for('modify_lon.edit_dominant_building_post'), request_body=request_body)
def get_land_compensation_payment(): current_app.logger.info("Endpoint called") if g.session.add_charge_state is None: current_app.logger.error( "Charge state not found in session - Returning error") raise ApplicationError(500) request_body = { 'land-compensation-paid': g.session.add_charge_state.land_compensation_paid, 'amount-of-compensation': g.session.add_charge_state.amount_of_compensation, 'land-compensation-amount-type': g.session.add_charge_state.land_compensation_amount_type } current_app.logger.info("Displaying page 'land_compensation_payment.html'") return render_template( 'land_compensation_payment.html', request_body=request_body, submit_url=url_for( 'modify_land_charge.post_land_compensation_payment'))
def post_charge_description(): current_app.logger.info("Endpoint called") if g.session.add_charge_state is None: current_app.logger.error( "Charge state not found in session - Returning error") raise ApplicationError(500) description = request.form['charge-description'].strip() current_app.logger.info("Validating charge reason") validation_errors = ChargeDescriptionValidator.validate(description) if validation_errors.errors: current_app.logger.warning( "Validation errors present - Rendering page with validation errors" ) return render_template( 'charge_description.html', data=description, validation_errors=validation_errors.errors, validation_summary_heading=validation_errors.summary_heading_text, submit_url=url_for( 'modify_land_charge.post_charge_description')), 400 current_app.logger.info("Field values validated - Updating session charge") if has_value_changed(g.session.add_charge_state.supplementary_information, description): g.session.add_charge_state.supplementary_information = description g.session.edited_fields.append('charge_description') g.session.commit() charge_display_id = calc_display_id( g.session.add_charge_state.local_land_charge) current_app.logger.info( "Session charge updated - Redirecting back to modify_land_charge with local_land_charge='{}'" .format(charge_display_id)) return redirect( url_for("modify_land_charge.modify_land_charge", local_land_charge=charge_display_id))
def get_external_url_from_path(self, path): current_app.logger.info("Generate external URL for path {}".format(path)) params = None if urlparse(path).query: params = dict(parse_qsl(urlparse(path).query)) request_path = "{}/{}/external-url".format(self.url, path[:path.find('?')]) else: request_path = "{}/{}/external-url".format(self.url, path) current_app.logger.info("Calling storage api via this URL: {}".format(request_path)) response = g.requests.get(request_path, params=params) if response.status_code == 200: json = response.json() return json['external_reference'] if response.status_code == 404: return None current_app.logger.warning( 'Failed to get external url - TraceID : {} - Status: {}, Message: {}'.format( g.trace_id, response.status_code, response.text)) raise ApplicationError(500)
def get_expiry(): current_app.logger.info("Endpoint called") if g.session.add_charge_state is None: current_app.logger.error("Charge state not found in session - Returning error") raise ApplicationError(500) current_app.logger.info("Extracting expiry information from session charge") expires = g.session.add_charge_state.expiry_date is not None request_body = { "does_charge_expire": "yes" if expires else "no", "charge_expiry_day": "", "charge_expiry_month": "", "charge_expiry_year": "" } if g.session.add_charge_state.expiry_date is not None: request_body['charge_expiry_day'] = g.session.add_charge_state.expiry_date.day request_body['charge_expiry_month'] = g.session.add_charge_state.expiry_date.month request_body['charge_expiry_year'] = g.session.add_charge_state.expiry_date.year current_app.logger.info("Expiry information extracted - Rendering response") return render_template('expiry.html', request_body=request_body, submit_url=url_for('modify_land_charge.post_expiry') )