117 changed files with 10620 additions and 1350 deletions
@ -0,0 +1,70 @@
|
||||
class AddressSearchController < ApplicationController |
||||
before_action :authenticate_user! |
||||
before_action :set_log, only: %i[manual_input search_input] |
||||
|
||||
def index |
||||
query = params[:query] |
||||
|
||||
if query.match?(/\A\d+\z/) && query.length > 5 |
||||
# Query is all numbers and greater than 5 digits, assume it's a UPRN |
||||
service = UprnClient.new(query) |
||||
service.call |
||||
|
||||
if service.error.present? |
||||
render json: { error: service.error }, status: :not_found |
||||
else |
||||
presenter = UprnDataPresenter.new(service.result) |
||||
render json: [{ text: presenter.address, value: presenter.uprn }] |
||||
end |
||||
elsif query.match?(/[a-zA-Z]/) |
||||
# Query contains letters, assume it's an address |
||||
service = AddressClient.new(query, { minmatch: 0.2 }) |
||||
service.call |
||||
|
||||
if service.error.present? |
||||
render json: { error: service.error }, status: :not_found |
||||
else |
||||
results = service.result.map do |result| |
||||
presenter = AddressDataPresenter.new(result) |
||||
{ text: presenter.address, value: presenter.uprn } |
||||
end |
||||
render json: results |
||||
end |
||||
else |
||||
# Query is ambiguous, use both APIs and merge results |
||||
address_service = AddressClient.new(query, { minmatch: 0.2 }) |
||||
uprn_service = UprnClient.new(query) |
||||
|
||||
address_service.call |
||||
uprn_service.call |
||||
|
||||
results = ([uprn_service.result] || []) + (address_service.result || []) |
||||
|
||||
if address_service.error.present? && uprn_service.error.present? |
||||
render json: { error: "Address and UPRN are not recognised." }, status: :not_found |
||||
else |
||||
formatted_results = results.map do |result| |
||||
presenter = AddressDataPresenter.new(result) |
||||
{ text: presenter.address, value: presenter.uprn } |
||||
end |
||||
render json: formatted_results |
||||
end |
||||
end |
||||
end |
||||
|
||||
def manual_input |
||||
@log.update!(manual_address_entry_selected: true) |
||||
redirect_to polymorphic_url([@log, :address]) |
||||
end |
||||
|
||||
def search_input |
||||
@log.update!(manual_address_entry_selected: false) |
||||
redirect_to polymorphic_url([@log, :address_search]) |
||||
end |
||||
|
||||
private |
||||
|
||||
def set_log |
||||
@log = current_user.send("#{params[:log_type]}s").find(params[:log_id]) |
||||
end |
||||
end |
@ -0,0 +1,73 @@
|
||||
import { Controller } from '@hotwired/stimulus' |
||||
import accessibleAutocomplete from 'accessible-autocomplete' |
||||
import 'accessible-autocomplete/dist/accessible-autocomplete.min.css' |
||||
|
||||
const options = [] |
||||
|
||||
const fetchOptions = async (query, searchUrl) => { |
||||
if (query.length < 2) { |
||||
throw new Error('Query must be at least 2 characters long.') |
||||
} |
||||
try { |
||||
const response = await fetch(`${searchUrl}?query=${encodeURIComponent(query.trim())}`) |
||||
return await response.json() |
||||
} catch (error) { |
||||
return error |
||||
} |
||||
} |
||||
|
||||
const fetchAndPopulateSearchResults = async (query, populateResults, searchUrl, populateOptions, selectEl) => { |
||||
if (/\S/.test(query)) { |
||||
try { |
||||
const results = await fetchOptions(query, searchUrl) |
||||
if (results.length === 0) { |
||||
populateOptions([], selectEl) |
||||
populateResults([]) |
||||
} else { |
||||
populateOptions(results, selectEl) |
||||
populateResults(Object.values(results).map((o) => `${o.text} (${o.value})`)) |
||||
} |
||||
} catch (error) { |
||||
populateOptions([], selectEl) |
||||
populateResults([]) |
||||
} |
||||
} |
||||
} |
||||
|
||||
const populateOptions = (results, selectEl) => { |
||||
selectEl.innerHTML = '' |
||||
|
||||
results.forEach((result) => { |
||||
const option = document.createElement('option') |
||||
option.value = result.value |
||||
option.innerHTML = `${result.text} (${result.value})` |
||||
selectEl.appendChild(option) |
||||
options.push(option) |
||||
}) |
||||
} |
||||
|
||||
export default class extends Controller { |
||||
connect () { |
||||
const searchUrl = JSON.parse(this.element.dataset.info).search_url |
||||
const selectEl = this.element |
||||
|
||||
accessibleAutocomplete.enhanceSelectElement({ |
||||
defaultValue: '', |
||||
selectElement: selectEl, |
||||
minLength: 2, |
||||
source: (query, populateResults) => { |
||||
fetchAndPopulateSearchResults(query, populateResults, searchUrl, populateOptions, selectEl) |
||||
}, |
||||
autoselect: true, |
||||
showNoOptionsFound: true, |
||||
placeholder: 'Start typing to search', |
||||
templates: { suggestion: (value) => value }, |
||||
onConfirm: (val) => { |
||||
const selectedResult = Array.from(selectEl.options).find(option => option.text === val) |
||||
if (selectedResult) { |
||||
selectedResult.selected = true |
||||
} |
||||
} |
||||
}) |
||||
} |
||||
} |
@ -0,0 +1,17 @@
|
||||
class Form::Lettings::Pages::AddressSearch < ::Form::Page |
||||
def initialize(id, hsh, subsection) |
||||
super |
||||
@id = "address_search" |
||||
@copy_key = "sales.property_information.address_search" |
||||
@depends_on = [{ "is_supported_housing?" => false, "manual_address_entry_selected" => false }] |
||||
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] |
||||
end |
||||
|
||||
def questions |
||||
@questions ||= [ |
||||
Form::Lettings::Questions::AddressSearch.new(nil, nil, self), |
||||
] |
||||
end |
||||
|
||||
QUESTION_NUMBER_FROM_YEAR = { 2024 => 12, 2025 => 16 }.freeze |
||||
end |
@ -0,0 +1,44 @@
|
||||
class Form::Lettings::Questions::AddressSearch < ::Form::Question |
||||
def initialize(id, hsh, page) |
||||
super |
||||
@id = "uprn" |
||||
@type = "address_search" |
||||
@copy_key = "lettings.property_information.address_search" |
||||
@plain_label = true |
||||
@bottom_guidance_partial = "address_search" |
||||
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] |
||||
@hide_question_number_on_page = true |
||||
end |
||||
|
||||
def answer_options(log = nil, _user = nil) |
||||
return {} unless ActiveRecord::Base.connected? |
||||
return {} unless log&.address_options&.any? |
||||
|
||||
log.address_options.each_with_object({}) do |option, hash| |
||||
hash[option[:uprn]] = { "value" => "#{option[:address]} (#{option[:uprn]})" } |
||||
end |
||||
end |
||||
|
||||
def get_extra_check_answer_value(log) |
||||
return unless log.uprn_known == 1 |
||||
|
||||
value = [ |
||||
log.address_line1, |
||||
log.address_line2, |
||||
log.town_or_city, |
||||
log.county, |
||||
log.postcode_full, |
||||
(LocalAuthority.find_by(code: log.la)&.name if log.la.present?), |
||||
].select(&:present?) |
||||
|
||||
return unless value.any? |
||||
|
||||
"\n\n#{value.join("\n")}" |
||||
end |
||||
|
||||
def displayed_answer_options(log, user = nil) |
||||
answer_options(log, user).transform_values { |value| value["value"] } || {} |
||||
end |
||||
|
||||
QUESTION_NUMBER_FROM_YEAR = { 2024 => 12, 2025 => 16 }.freeze |
||||
end |
@ -0,0 +1,23 @@
|
||||
class Form::Sales::Pages::AddressSearch < ::Form::Page |
||||
def initialize(id, hsh, subsection) |
||||
super |
||||
@id = "address_search" |
||||
@copy_key = "sales.property_information.address_search" |
||||
@depends_on = [{ "manual_address_entry_selected" => false }] |
||||
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] |
||||
end |
||||
|
||||
def questions |
||||
@questions ||= [ |
||||
Form::Sales::Questions::AddressSearch.new(nil, nil, self), |
||||
] |
||||
end |
||||
|
||||
def skip_href(log = nil) |
||||
return unless log |
||||
|
||||
"/#{log.log_type.dasherize}s/#{log.id}/property-number-of-bedrooms" |
||||
end |
||||
|
||||
QUESTION_NUMBER_FROM_YEAR = { 2024 => 15, 2025 => 13 }.freeze |
||||
end |
@ -0,0 +1,44 @@
|
||||
class Form::Sales::Questions::AddressSearch < ::Form::Question |
||||
def initialize(id, hsh, page) |
||||
super |
||||
@id = "uprn" |
||||
@type = "address_search" |
||||
@copy_key = "sales.property_information.address_search" |
||||
@plain_label = true |
||||
@bottom_guidance_partial = "address_search" |
||||
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] |
||||
@hide_question_number_on_page = true |
||||
end |
||||
|
||||
def answer_options(log = nil, _user = nil) |
||||
return {} unless ActiveRecord::Base.connected? |
||||
return {} unless log&.address_options&.any? |
||||
|
||||
log.address_options.each_with_object({}) do |option, hash| |
||||
hash[option[:uprn]] = { "value" => "#{option[:address]} (#{option[:uprn]})" } |
||||
end |
||||
end |
||||
|
||||
def get_extra_check_answer_value(log) |
||||
return unless log.uprn_known == 1 |
||||
|
||||
value = [ |
||||
log.address_line1, |
||||
log.address_line2, |
||||
log.town_or_city, |
||||
log.county, |
||||
log.postcode_full, |
||||
(LocalAuthority.find_by(code: log.la)&.name if log.la.present?), |
||||
].select(&:present?) |
||||
|
||||
return unless value.any? |
||||
|
||||
"\n\n#{value.join("\n")}" |
||||
end |
||||
|
||||
def displayed_answer_options(log, user = nil) |
||||
answer_options(log, user).transform_values { |value| value["value"] } || {} |
||||
end |
||||
|
||||
QUESTION_NUMBER_FROM_YEAR = { 2024 => 15, 2025 => 13 }.freeze |
||||
end |
@ -0,0 +1,122 @@
|
||||
require "csv" |
||||
|
||||
class BulkUpload::Lettings::Year2025::CsvParser |
||||
include CollectionTimeHelper |
||||
|
||||
FIELDS = 129 |
||||
MAX_COLUMNS = 130 |
||||
FORM_YEAR = 2025 |
||||
|
||||
attr_reader :path |
||||
|
||||
def initialize(path:) |
||||
@path = path |
||||
end |
||||
|
||||
def row_offset |
||||
if with_headers? |
||||
rows.find_index { |row| row[0].present? && row[0].match(/field number/i) } + 1 |
||||
else |
||||
0 |
||||
end |
||||
end |
||||
|
||||
def col_offset |
||||
with_headers? ? 1 : 0 |
||||
end |
||||
|
||||
def cols |
||||
@cols ||= ("A".."DZ").to_a |
||||
end |
||||
|
||||
def row_parsers |
||||
@row_parsers ||= body_rows.map { |row| |
||||
next if row.empty? |
||||
|
||||
stripped_row = row[col_offset..] |
||||
|
||||
hash = Hash[field_numbers.zip(stripped_row)] |
||||
|
||||
BulkUpload::Lettings::Year2025::RowParser.new(hash) |
||||
}.compact |
||||
end |
||||
|
||||
def body_rows |
||||
rows[row_offset..] |
||||
end |
||||
|
||||
def rows |
||||
@rows ||= CSV.parse(normalised_string, row_sep:) |
||||
end |
||||
|
||||
def column_for_field(field) |
||||
cols[field_numbers.find_index(field) + col_offset] |
||||
end |
||||
|
||||
def correct_field_count? |
||||
valid_field_numbers_count = field_numbers.count { |f| f != "field_blank" } |
||||
|
||||
valid_field_numbers_count == FIELDS |
||||
end |
||||
|
||||
def too_many_columns? |
||||
return if with_headers? |
||||
|
||||
max_columns_count = body_rows.map(&:size).max - col_offset |
||||
|
||||
max_columns_count > MAX_COLUMNS |
||||
end |
||||
|
||||
def wrong_template_for_year? |
||||
collection_start_year_for_date(first_record_start_date) != FORM_YEAR |
||||
rescue Date::Error |
||||
false |
||||
end |
||||
|
||||
def missing_required_headers? |
||||
!with_headers? |
||||
end |
||||
|
||||
private |
||||
|
||||
def default_field_numbers |
||||
(1..FIELDS).map { |h| h.present? && h.to_s.match?(/^[0-9]+$/) ? "field_#{h}" : "field_blank" } |
||||
end |
||||
|
||||
def field_numbers |
||||
@field_numbers ||= if with_headers? |
||||
rows[row_offset - 1][col_offset..].map { |h| h.present? && h.match?(/^[0-9]+$/) ? "field_#{h}" : "field_blank" } |
||||
else |
||||
default_field_numbers |
||||
end |
||||
end |
||||
|
||||
def with_headers? |
||||
rows.map { |r| r[0] }.any? { |cell| cell&.match?(/field number/i) } |
||||
end |
||||
|
||||
def row_sep |
||||
"\n" |
||||
end |
||||
|
||||
def normalised_string |
||||
return @normalised_string if @normalised_string |
||||
|
||||
@normalised_string = File.read(path, encoding: "bom|utf-8") |
||||
@normalised_string.gsub!("\r\n", "\n") |
||||
@normalised_string.scrub!("") |
||||
@normalised_string.tr!("\r", "\n") |
||||
|
||||
@normalised_string |
||||
end |
||||
|
||||
def first_record_start_date |
||||
if with_headers? |
||||
year = row_parsers.first.field_10.to_s.strip.length.between?(1, 2) ? row_parsers.first.field_10.to_i + 2000 : row_parsers.first.field_10.to_i |
||||
Date.new(year, row_parsers.first.field_9.to_i, row_parsers.first.field_8.to_i) |
||||
else |
||||
year = rows.first[9].to_s.strip.length.between?(1, 2) ? rows.first[9].to_i + 2000 : rows.first[9].to_i |
||||
Date.new(year, rows.first[8].to_i, rows.first[7].to_i) |
||||
end |
||||
end |
||||
end |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,124 @@
|
||||
require "csv" |
||||
|
||||
class BulkUpload::Sales::Year2025::CsvParser |
||||
include CollectionTimeHelper |
||||
|
||||
FIELDS = 121 |
||||
MAX_COLUMNS = 142 |
||||
FORM_YEAR = 2025 |
||||
|
||||
attr_reader :path |
||||
|
||||
def initialize(path:) |
||||
@path = path |
||||
end |
||||
|
||||
def row_offset |
||||
if with_headers? |
||||
rows.find_index { |row| row[0].present? && row[0].match(/field number/i) } + 1 |
||||
else |
||||
0 |
||||
end |
||||
end |
||||
|
||||
def col_offset |
||||
with_headers? ? 1 : 0 |
||||
end |
||||
|
||||
def cols |
||||
@cols ||= ("A".."DR").to_a |
||||
end |
||||
|
||||
def row_parsers |
||||
@row_parsers ||= body_rows.map { |row| |
||||
next if row.empty? |
||||
|
||||
stripped_row = row[col_offset..] |
||||
hash = Hash[field_numbers.zip(stripped_row)] |
||||
|
||||
BulkUpload::Sales::Year2025::RowParser.new(hash) |
||||
}.compact |
||||
end |
||||
|
||||
def body_rows |
||||
rows[row_offset..] |
||||
end |
||||
|
||||
def rows |
||||
@rows ||= CSV.parse(normalised_string, row_sep:) |
||||
end |
||||
|
||||
def column_for_field(field) |
||||
cols[field_numbers.find_index(field) + col_offset] |
||||
end |
||||
|
||||
def wrong_template_for_year? |
||||
collection_start_year_for_date(first_record_start_date) != FORM_YEAR |
||||
rescue Date::Error |
||||
false |
||||
end |
||||
|
||||
def missing_required_headers? |
||||
!with_headers? |
||||
end |
||||
|
||||
def correct_field_count? |
||||
valid_field_numbers_count = field_numbers.count { |f| f != "field_blank" } |
||||
|
||||
valid_field_numbers_count == FIELDS |
||||
end |
||||
|
||||
private |
||||
|
||||
def default_field_numbers |
||||
(1..FIELDS).map do |number| |
||||
if number.to_s.match?(/^[0-9]+$/) |
||||
"field_#{number}" |
||||
else |
||||
"field_blank" |
||||
end |
||||
end |
||||
end |
||||
|
||||
def field_numbers |
||||
@field_numbers ||= if with_headers? |
||||
rows[row_offset - 1][col_offset..].map { |number| number.to_s.match?(/^[0-9]+$/) ? "field_#{number}" : "field_blank" } |
||||
else |
||||
default_field_numbers |
||||
end |
||||
end |
||||
|
||||
def headers |
||||
@headers ||= ("field_1".."field_#{FIELDS}").to_a |
||||
end |
||||
|
||||
def with_headers? |
||||
# we will eventually want to validate that headers exist for this year |
||||
rows.map { |r| r[0] }.any? { |cell| cell&.match?(/field number/i) } |
||||
end |
||||
|
||||
def row_sep |
||||
"\n" |
||||
end |
||||
|
||||
def normalised_string |
||||
return @normalised_string if @normalised_string |
||||
|
||||
@normalised_string = File.read(path, encoding: "bom|utf-8") |
||||
@normalised_string.gsub!("\r\n", "\n") |
||||
@normalised_string.scrub!("") |
||||
@normalised_string.tr!("\r", "\n") |
||||
|
||||
@normalised_string |
||||
end |
||||
|
||||
def first_record_start_date |
||||
if with_headers? |
||||
year = row_parsers.first.field_3.to_s.strip.length.between?(1, 2) ? row_parsers.first.field_3.to_i + 2000 : row_parsers.first.field_3.to_i |
||||
Date.new(year, row_parsers.first.field_2.to_i, row_parsers.first.field_1.to_i) |
||||
else |
||||
year = rows.first[2].to_s.strip.length.between?(1, 2) ? rows.first[2].to_i + 2000 : rows.first[2].to_i |
||||
Date.new(year, rows.first[1].to_i, rows.first[0].to_i) |
||||
end |
||||
end |
||||
end |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,24 @@
|
||||
<% selected = @log.public_send(question.id) || "" %> |
||||
<% answers = question.displayed_answer_options(@log, current_user).map { |key, value| OpenStruct.new(id: key, name: select_option_name(value), resource: value) } %> |
||||
<%= render partial: "form/guidance/#{question.top_guidance_partial}" if question.top_guidance? %> |
||||
|
||||
<%= f.govuk_select(question.id.to_sym, |
||||
label: legend(question, page_header, conditional), |
||||
"data-controller": "address-search", |
||||
"data-info": { search_url: address_search_url }.to_json, |
||||
caption: caption(caption_text, page_header, conditional), |
||||
hint: { text: question.hint_text&.html_safe }) do %> |
||||
<% if answers.any? %> |
||||
<% answers.each do |answer| %> |
||||
<option value="<%= answer.id %>" |
||||
data-synonyms="<%= answer_option_synonyms(answer.resource) %>" |
||||
data-append="<%= answer_option_append(answer.resource) %>" |
||||
data-hint="<%= answer_option_hint(answer.resource) %>" |
||||
<%= question.answer_selected?(@log, answer) ? "selected" : "" %>><%= answer.name || answer.resource %></option> |
||||
<% end %> |
||||
<% else %> |
||||
<option value="" disabled>Javascript is disabled. Please enter the address manually.</option> |
||||
<% end %> |
||||
<% end %> |
||||
|
||||
<%= render partial: "form/guidance/#{question.bottom_guidance_partial}" if question.bottom_guidance? %> |
@ -0,0 +1,3 @@
|
||||
<div class="govuk-button-group"> |
||||
<%= govuk_link_to "Clear address and search instead", address_search_input_path(@log.log_type, @log.id), class: "govuk-button govuk-button--secondary" %> |
||||
</div> |
@ -0,0 +1,7 @@
|
||||
<%= govuk_details(summary_text: I18n.t("forms.#{@log.form.start_date.year}.#{@log.form.type}.guidance.address_search.title")) do %> |
||||
<%= I18n.t("forms.#{@log.form.start_date.year}.#{@log.form.type}.guidance.address_search.content").html_safe %> |
||||
<% end %> |
||||
|
||||
<div class="govuk-button-group"> |
||||
<%= govuk_link_to "Enter the address manually instead", address_manual_input_path(@log.log_type, @log.id), class: "govuk-button govuk-button--secondary" %> |
||||
</div> |
@ -0,0 +1,60 @@
|
||||
en: |
||||
validations: |
||||
lettings: |
||||
2025: |
||||
bulk_upload: |
||||
not_answered: "You must answer %{question}" |
||||
invalid_option: "Enter a valid value for %{question}" |
||||
invalid_number: "Enter a number for %{question}" |
||||
spreadsheet_dupe: "This is a duplicate of a log in your file." |
||||
duplicate: "This is a duplicate log." |
||||
blank_file: "Template is blank - The template must be filled in for us to create the logs and check if data is correct." |
||||
wrong_template: |
||||
wrong_template: "Incorrect start dates, please ensure you have used the correct template." |
||||
no_headers: "Your file does not contain the required header rows. Add or check the header rows and upload your file again. [Read more about using the template headers](%{guidance_link})." |
||||
wrong_field_numbers_count: "Incorrect number of fields, please ensure you have used the correct template." |
||||
over_max_column_count: "Too many columns, please ensure you have used the correct template." |
||||
owning_organisation: |
||||
not_found: "The owning organisation code is incorrect." |
||||
not_stock_owner: "The owning organisation code provided is for an organisation that does not own stock." |
||||
not_permitted: |
||||
not_support: "You do not have permission to add logs for this owning organisation." |
||||
support: "This owning organisation is not affiliated with %{org_name}." |
||||
managing_organisation: |
||||
no_relationship: "This managing organisation does not have a relationship with the owning organisation." |
||||
not_found: "The managing organisation code is incorrect." |
||||
assigned_to: |
||||
not_found: "User with the specified email could not be found." |
||||
organisation_not_related: "User must be related to owning organisation or managing organisation." |
||||
startdate: |
||||
outside_collection_window: "Enter a date within the %{year_combo} collection year, which is between 1st April %{start_year} and 31st March %{end_year}." |
||||
year_not_two_or_four_digits: "Tenancy start year must be 2 or 4 digits." |
||||
housingneeds: |
||||
no_and_dont_know_disabled_needs_conjunction: "No disabled access needs and don’t know disabled access needs cannot be selected together." |
||||
dont_know_disabled_needs_conjunction: "Don’t know disabled access needs can’t be selected if you have selected fully wheelchair-accessible housing, wheelchair access to essential rooms, level access housing or other disabled access needs." |
||||
no_disabled_needs_conjunction: "No disabled access needs can’t be selected if you have selected fully wheelchair-accessible housing, wheelchair access to essential rooms, level access housing or other disabled access needs." |
||||
housingneeds_type: |
||||
only_one_option_permitted: "Only one disabled access need: fully wheelchair-accessible housing, wheelchair access to essential rooms or level access housing, can be selected." |
||||
condition_effects: |
||||
no_choices: "You cannot answer this question as you told us nobody in the household has a physical or mental health condition (or other illness) expected to last 12 months or more." |
||||
reason: |
||||
renewal_reason_needed: "The reason for leaving must be \"End of social or private sector tenancy - no fault\", \"End of social or private sector tenancy - evicted due to anti-social behaviour (ASB)\", \"End of social or private sector tenancy - evicted due to rent arrears\" or \"End of social or private sector tenancy - evicted for any other reason\"." |
||||
referral: |
||||
general_needs_prp_referred_by_la: "The source of the referral cannot be referred by local authority housing department for a general needs log." |
||||
nominated_by_local_ha_but_la: "The source of the referral cannot be Nominated by local housing authority as your organisation is a local authority." |
||||
scheme: |
||||
must_relate_to_org: "This scheme code does not belong to the owning organisation or managing organisation." |
||||
location: |
||||
must_relate_to_org: "Location code must relate to a location that is owned by the owning organisation or managing organisation." |
||||
age: |
||||
invalid: "Age of person %{person_num} must be a number or the letter R" |
||||
address: |
||||
not_found: "We could not find this address. Check the address data in your CSV file is correct and complete, or find the correct address in the service." |
||||
not_determined: |
||||
one: "There is a possible match for this address which doesn't look right. Check the address data in your CSV file is correct and complete, or confirm the address in the service." |
||||
multiple: "There are multiple matches for this address. Check the address data in your CSV file is correct and complete, or select the correct address in the service." |
||||
not_answered: "Enter either the UPRN or the full address." |
||||
nationality: |
||||
invalid: "Select a valid nationality." |
||||
charges: |
||||
missing_charges: "Please enter the %{sentence_fragment}. If there is no %{sentence_fragment}, please enter '0'." |
@ -0,0 +1,46 @@
|
||||
en: |
||||
validations: |
||||
sales: |
||||
2025: |
||||
bulk_upload: |
||||
not_answered: "You must answer %{question}" |
||||
invalid_option: "Enter a valid value for %{question}" |
||||
spreadsheet_dupe: "This is a duplicate of a log in your file." |
||||
duplicate: "This is a duplicate log." |
||||
blank_file: "Template is blank - The template must be filled in for us to create the logs and check if data is correct." |
||||
wrong_template: |
||||
over_max_column_count: "Too many columns, please ensure you have used the correct template." |
||||
no_headers: "Your file does not contain the required header rows. Add or check the header rows and upload your file again. [Read more about using the template headers](%{guidance_link})." |
||||
wrong_field_numbers_count: "Incorrect number of fields, please ensure you have used the correct template." |
||||
wrong_template: "Incorrect sale dates, please ensure you have used the correct template." |
||||
numeric: |
||||
within_range: "%{field} must be between %{min} and %{max}." |
||||
owning_organisation: |
||||
not_found: "The owning organisation code is incorrect." |
||||
not_stock_owner: "The owning organisation code provided is for an organisation that does not own stock." |
||||
not_permitted: |
||||
support: "This owning organisation is not affiliated with %{name}." |
||||
not_support: "You do not have permission to add logs for this owning organisation." |
||||
assigned_to: |
||||
not_found: "User with the specified email could not be found." |
||||
organisation_not_related: "User must be related to owning organisation or managing organisation." |
||||
managing_organisation_not_related: "This organisation does not have a relationship with the owning organisation." |
||||
saledate: |
||||
outside_collection_window: "Enter a date within the %{year_combo} collection year, which is between 1st April %{start_year} and 31st March %{end_year}." |
||||
year_not_two_or_four_digits: "Sale completion year must be 2 or 4 digits." |
||||
ecstat1: |
||||
buyer_cannot_be_over_16_and_child: "Buyer 1's age cannot be 16 or over if their working situation is child under 16." |
||||
buyer_cannot_be_child: "Buyer 1 cannot have a working situation of child under 16." |
||||
age1: |
||||
buyer_cannot_be_over_16_and_child: "Buyer 1's age cannot be 16 or over if their working situation is child under 16." |
||||
ecstat2: |
||||
buyer_cannot_be_over_16_and_child: "Buyer 2's age cannot be 16 or over if their working situation is child under 16." |
||||
buyer_cannot_be_child: "Buyer 2 cannot have a working situation of child under 16." |
||||
age2: |
||||
buyer_cannot_be_over_16_and_child: "Buyer 2's age cannot be 16 or over if their working situation is child under 16." |
||||
address: |
||||
not_found: "We could not find this address. Check the address data in your CSV file is correct and complete, or select the correct address using the CORE site." |
||||
not_determined: "There are multiple matches for this address. Either select the correct address manually or correct the UPRN in the CSV file." |
||||
not_answered: "Enter either the UPRN or the full address." |
||||
nationality: |
||||
invalid: "Select a valid nationality." |
@ -0,0 +1,6 @@
|
||||
class AddManualAddressEntrySelectedToLogs < ActiveRecord::Migration[7.2] |
||||
def change |
||||
add_column :sales_logs, :manual_address_entry_selected, :boolean, default: false |
||||
add_column :lettings_logs, :manual_address_entry_selected, :boolean, default: false |
||||
end |
||||
end |
@ -0,0 +1,15 @@
|
||||
desc "Correct invalid BU reasonable preference values" |
||||
task correct_reasonpref_values: :environment do |
||||
%w[rp_homeless rp_hardship rp_medwel rp_insan_unsat rp_dontknow].each do |field| |
||||
field_invalid = "#{field} != 1 AND #{field} != 0 AND #{field} is NOT NULL" |
||||
|
||||
LettingsLog.filter_by_year(2024).where(field_invalid).find_each do |lettings_log| |
||||
lettings_log[field] = 0 |
||||
unless lettings_log.save |
||||
Rails.logger.info("Failed to save reasonpref for LettingsLog with id #{lettings_log.id}: #{lettings_log.errors.full_messages}") |
||||
end |
||||
end |
||||
|
||||
LettingsLog.filter_by_year(2023).where(field_invalid).update_all("#{field}": 0) |
||||
end |
||||
end |
Binary file not shown.
@ -0,0 +1,45 @@
|
||||
require "rails_helper" |
||||
require_relative "helpers" |
||||
|
||||
RSpec.describe "Address Search" do |
||||
include Helpers |
||||
let(:user) { FactoryBot.create(:user) } |
||||
let(:sales_log) do |
||||
FactoryBot.create( |
||||
:sales_log, |
||||
:shared_ownership_setup_complete, |
||||
assigned_to: user, |
||||
manual_address_entry_selected: false, |
||||
) |
||||
end |
||||
|
||||
before do |
||||
sign_in user |
||||
end |
||||
|
||||
context "when using address search feature" do |
||||
before do |
||||
visit("/sales-logs/#{sales_log.id}/address-search") |
||||
end |
||||
|
||||
it "allows searching by a UPRN", js: true do |
||||
find("#sales-log-uprn-field").click.native.send_keys("1", "0", "0", "3", "3", "5", "4", "4", "6", "1", "4", :down) |
||||
expect(find("#sales-log-uprn-field").value).to eq("10033544614") |
||||
end |
||||
|
||||
it "allows searching by address", js: true do |
||||
find("#sales-log-uprn-field").click.native.send_keys("S", "W", "1", "5", :down, :enter) |
||||
expect(find("#sales-log-uprn-field").value).to eq("SW15") |
||||
end |
||||
|
||||
it "displays the placeholder text", js: true do |
||||
expect(find("#sales-log-uprn-field")["placeholder"]).to eq("Start typing to search") |
||||
end |
||||
|
||||
it "displays correct bottom guidance text" do |
||||
find("span.govuk-details__summary-text", text: "Can’t find the address you’re looking for?").click |
||||
expect(page).to have_content("Some properties may not be available yet e.g. new builds; you might need to enter them manually instead") |
||||
expect(page).to have_content("For UPRN (Unique Property Reference Number), please enter the full value exactly") |
||||
end |
||||
end |
||||
end |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,111 @@
|
||||
require "rails_helper" |
||||
require "rake" |
||||
|
||||
RSpec.describe "correct_reasonpref_values" do |
||||
describe ":correct_reasonpref_values", type: :task do |
||||
subject(:task) { Rake::Task["correct_reasonpref_values"] } |
||||
|
||||
let(:organisation) { create(:organisation, rent_periods: [2]) } |
||||
let(:user) { create(:user, organisation:) } |
||||
|
||||
before do |
||||
Rake.application.rake_require("tasks/correct_reasonpref_values") |
||||
Rake::Task.define_task(:environment) |
||||
task.reenable |
||||
end |
||||
|
||||
context "when the rake task is run" do |
||||
context "and any of the reasonable_preference_reason options are not 1, 0 or nil" do |
||||
let(:bulk_upload) { create(:bulk_upload, :lettings, year: 2024, rent_type_fix_status: BulkUpload.rent_type_fix_statuses[:not_applied]) } |
||||
|
||||
it "sets the options to 0" do |
||||
log = build(:lettings_log, :completed, reasonpref: 1, rp_homeless: -2, rp_hardship: 2, rp_medwel: 3, rp_insan_unsat: 4, rp_dontknow: 1, |
||||
bulk_upload:, assigned_to: user) |
||||
log.save!(validate: false) |
||||
initial_updated_at = log.updated_at |
||||
|
||||
task.invoke |
||||
log.reload |
||||
|
||||
expect(log.updated_at).not_to eq(initial_updated_at) |
||||
expect(log.status).to eq("completed") |
||||
expect(log.rp_homeless).to be(0) |
||||
expect(log.rp_hardship).to be(0) |
||||
expect(log.rp_medwel).to be(0) |
||||
expect(log.rp_insan_unsat).to be(0) |
||||
expect(log.rp_dontknow).to be(1) |
||||
end |
||||
|
||||
it "updates the reasonable preference reason values on a pending log" do |
||||
log = build(:lettings_log, :completed, status: "pending", reasonpref: 1, rp_homeless: -2, rp_hardship: 1, rp_medwel: 3, rp_insan_unsat: 4, rp_dontknow: 2, bulk_upload:, assigned_to: user) |
||||
log.save!(validate: false) |
||||
initial_updated_at = log.updated_at |
||||
expect(log.status).to eq("pending") |
||||
|
||||
task.invoke |
||||
log.reload |
||||
expect(log.rp_homeless).to be(0) |
||||
expect(log.rp_hardship).to be(1) |
||||
expect(log.rp_medwel).to be(0) |
||||
expect(log.rp_insan_unsat).to be(0) |
||||
expect(log.rp_dontknow).to be(0) |
||||
expect(log.status).to eq("pending") |
||||
expect(log.updated_at).not_to eq(initial_updated_at) |
||||
end |
||||
|
||||
it "does not update logs with valid values" do |
||||
log = build(:lettings_log, :completed, reasonpref: 1, rp_homeless: 0, rp_hardship: 1, rp_medwel: 0, rp_insan_unsat: 0, rp_dontknow: 0, bulk_upload:, assigned_to: user) |
||||
log.save!(validate: false) |
||||
initial_updated_at = log.updated_at |
||||
expect(log.status).to eq("completed") |
||||
|
||||
task.invoke |
||||
log.reload |
||||
|
||||
expect(log.status).to eq("completed") |
||||
expect(log.updated_at).to eq(initial_updated_at) |
||||
end |
||||
|
||||
it "updates the reasonable preference reason values if some of the checkbox values are valid" do |
||||
log = build(:lettings_log, :completed, status: "pending", reasonpref: 1, rp_homeless: 0, rp_hardship: 2, rp_medwel: 1, rp_insan_unsat: 0, rp_dontknow: 0, bulk_upload:, assigned_to: user) |
||||
log.save!(validate: false) |
||||
initial_updated_at = log.updated_at |
||||
expect(log.status).to eq("pending") |
||||
|
||||
task.invoke |
||||
log.reload |
||||
expect(log.rp_homeless).to be(0) |
||||
expect(log.rp_hardship).to be(0) |
||||
expect(log.rp_medwel).to be(1) |
||||
expect(log.rp_insan_unsat).to be(0) |
||||
expect(log.rp_dontknow).to be(0) |
||||
expect(log.status).to eq("pending") |
||||
expect(log.updated_at).not_to eq(initial_updated_at) |
||||
end |
||||
|
||||
it "updates the reasonable preference reason values on a 2023 log" do |
||||
log = build(:lettings_log, :completed, startdate: Time.zone.local(2023, 6, 6), reasonpref: 1, rp_homeless: 0, rp_hardship: 2, rp_medwel: 1, rp_insan_unsat: 0, rp_dontknow: 0, bulk_upload:, assigned_to: user) |
||||
log.save!(validate: false) |
||||
initial_updated_at = log.updated_at |
||||
|
||||
task.invoke |
||||
log.reload |
||||
|
||||
expect(log.updated_at).to eq(initial_updated_at) |
||||
expect(log.rp_hardship).to eq(0) |
||||
end |
||||
|
||||
it "does not update and logs error if a validation triggers" do |
||||
log = build(:lettings_log, :completed, postcode_full: "0", reasonpref: 1, rp_homeless: 0, rp_hardship: 2, rp_medwel: 1, rp_insan_unsat: 0, rp_dontknow: 0, bulk_upload:, assigned_to: user) |
||||
log.save!(validate: false) |
||||
initial_updated_at = log.updated_at |
||||
|
||||
task.invoke |
||||
log.reload |
||||
|
||||
expect(log.updated_at).to eq(initial_updated_at) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,42 @@
|
||||
require "rails_helper" |
||||
|
||||
RSpec.describe Form::Lettings::Pages::AddressSearch, type: :model do |
||||
subject(:page) { described_class.new(page_id, page_definition, subsection) } |
||||
|
||||
let(:page_id) { nil } |
||||
let(:page_definition) { nil } |
||||
let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date:)) } |
||||
let(:start_date) { Time.utc(2024, 4, 1) } |
||||
|
||||
it "has correct subsection" do |
||||
expect(page.subsection).to eq(subsection) |
||||
end |
||||
|
||||
it "has correct questions" do |
||||
expect(page.questions.map(&:id)).to eq(%w[uprn]) |
||||
end |
||||
|
||||
it "has the correct id" do |
||||
expect(page.id).to eq("address_search") |
||||
end |
||||
|
||||
it "has the correct description" do |
||||
expect(page.description).to be_nil |
||||
end |
||||
|
||||
it "has correct depends_on" do |
||||
expect(page.depends_on).to eq([{ "is_supported_housing?" => false, "manual_address_entry_selected" => false }]) |
||||
end |
||||
|
||||
it "has the correct question number" do |
||||
expect(page.question_number).to eq(12) |
||||
end |
||||
|
||||
context "with 2025/26 form" do |
||||
let(:start_date) { Time.utc(2025, 4, 1) } |
||||
|
||||
it "has the correct question number" do |
||||
expect(page.question_number).to eq(16) |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,68 @@
|
||||
require "rails_helper" |
||||
|
||||
RSpec.describe Form::Lettings::Questions::AddressSearch, type: :model do |
||||
subject(:question) { described_class.new(question_id, question_definition, page) } |
||||
|
||||
let(:question_id) { nil } |
||||
let(:question_definition) { nil } |
||||
let(:page) { instance_double(Form::Page, subsection: instance_double(Form::Subsection, form: instance_double(Form, start_date:))) } |
||||
let(:start_date) { Time.utc(2024, 4, 1) } |
||||
|
||||
it "has correct page" do |
||||
expect(question.page).to eq(page) |
||||
end |
||||
|
||||
it "has the correct id" do |
||||
expect(question.id).to eq("uprn") |
||||
end |
||||
|
||||
it "has the correct type" do |
||||
expect(question.type).to eq("address_search") |
||||
end |
||||
|
||||
it "has the correct question number" do |
||||
expect(question.question_number).to eq(12) |
||||
end |
||||
|
||||
context "with 2025/26 form" do |
||||
let(:start_date) { Time.utc(2025, 4, 1) } |
||||
|
||||
it "has the correct question number" do |
||||
expect(question.question_number).to eq(16) |
||||
end |
||||
end |
||||
|
||||
describe "get_extra_check_answer_value" do |
||||
context "when address is not present" do |
||||
let(:log) { build(:lettings_log, manual_address_entry_selected: false) } |
||||
|
||||
it "returns nil" do |
||||
expect(question.get_extra_check_answer_value(log)).to be_nil |
||||
end |
||||
end |
||||
|
||||
context "when address search is present" do |
||||
let(:log) do |
||||
build( |
||||
:lettings_log, |
||||
:completed, |
||||
address_line1: "19, Charlton Gardens", |
||||
town_or_city: "Bristol", |
||||
postcode_full: "BS10 6LU", |
||||
la: "E06000023", |
||||
uprn_known: 1, |
||||
uprn: 107, |
||||
uprn_confirmed: 1, |
||||
) |
||||
end |
||||
|
||||
context "when uprn known" do |
||||
it "returns formatted value" do |
||||
expect(question.get_extra_check_answer_value(log)).to eq( |
||||
"\n\n19, Charlton Gardens\nBristol\nBS10 6LU\nBristol, City of", |
||||
) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,42 @@
|
||||
require "rails_helper" |
||||
|
||||
RSpec.describe Form::Sales::Pages::AddressSearch, type: :model do |
||||
subject(:page) { described_class.new(page_id, page_definition, subsection) } |
||||
|
||||
let(:page_id) { nil } |
||||
let(:page_definition) { nil } |
||||
let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date:)) } |
||||
let(:start_date) { Time.utc(2024, 4, 1) } |
||||
|
||||
it "has correct subsection" do |
||||
expect(page.subsection).to eq(subsection) |
||||
end |
||||
|
||||
it "has correct questions" do |
||||
expect(page.questions.map(&:id)).to eq(%w[uprn]) |
||||
end |
||||
|
||||
it "has the correct id" do |
||||
expect(page.id).to eq("address_search") |
||||
end |
||||
|
||||
it "has the correct description" do |
||||
expect(page.description).to be_nil |
||||
end |
||||
|
||||
it "has correct depends_on" do |
||||
expect(page.depends_on).to eq([{ "manual_address_entry_selected" => false }]) |
||||
end |
||||
|
||||
it "has the correct question number" do |
||||
expect(page.question_number).to eq(15) |
||||
end |
||||
|
||||
context "with 2025/26 form" do |
||||
let(:start_date) { Time.utc(2025, 4, 1) } |
||||
|
||||
it "has the correct question number" do |
||||
expect(page.question_number).to eq(13) |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,68 @@
|
||||
require "rails_helper" |
||||
|
||||
RSpec.describe Form::Sales::Questions::AddressSearch, type: :model do |
||||
subject(:question) { described_class.new(question_id, question_definition, page) } |
||||
|
||||
let(:question_id) { nil } |
||||
let(:question_definition) { nil } |
||||
let(:page) { instance_double(Form::Page, subsection: instance_double(Form::Subsection, form: instance_double(Form, start_date:))) } |
||||
let(:start_date) { Time.utc(2024, 4, 1) } |
||||
|
||||
it "has correct page" do |
||||
expect(question.page).to eq(page) |
||||
end |
||||
|
||||
it "has the correct id" do |
||||
expect(question.id).to eq("uprn") |
||||
end |
||||
|
||||
it "has the correct type" do |
||||
expect(question.type).to eq("address_search") |
||||
end |
||||
|
||||
it "has the correct question number" do |
||||
expect(question.question_number).to eq(15) |
||||
end |
||||
|
||||
context "with 2025/26 form" do |
||||
let(:start_date) { Time.utc(2025, 4, 1) } |
||||
|
||||
it "has the correct question number" do |
||||
expect(question.question_number).to eq(13) |
||||
end |
||||
end |
||||
|
||||
describe "get_extra_check_answer_value" do |
||||
context "when address is not present" do |
||||
let(:log) { build(:sales_log, manual_address_entry_selected: false) } |
||||
|
||||
it "returns nil" do |
||||
expect(question.get_extra_check_answer_value(log)).to be_nil |
||||
end |
||||
end |
||||
|
||||
context "when address search is present" do |
||||
let(:log) do |
||||
build( |
||||
:sales_log, |
||||
:completed, |
||||
address_line1: "19, Charlton Gardens", |
||||
town_or_city: "Bristol", |
||||
postcode_full: "BS10 6LU", |
||||
la: "E06000023", |
||||
uprn_known: 1, |
||||
uprn: 107, |
||||
uprn_confirmed: 1, |
||||
) |
||||
end |
||||
|
||||
context "when uprn known" do |
||||
it "returns formatted value" do |
||||
expect(question.get_extra_check_answer_value(log)).to eq( |
||||
"\n\n19, Charlton Gardens\nBristol\nBS10 6LU\nBristol, City of", |
||||
) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,148 @@
|
||||
require "rails_helper" |
||||
|
||||
RSpec.describe AddressSearchController, type: :request do |
||||
let(:user) { create(:user) } |
||||
|
||||
before do |
||||
sign_in user |
||||
end |
||||
|
||||
describe "#manual input" do |
||||
context "when no address data is given and user chooses to enter address manually" do |
||||
let(:sales_log) { create(:sales_log, :shared_ownership_setup_complete, manual_address_entry_selected: false, assigned_to: user) } |
||||
|
||||
it "correctly sets address fields" do |
||||
sales_log.reload |
||||
expect(sales_log.manual_address_entry_selected).to eq(false) |
||||
expect(sales_log.uprn_known).to eq(nil) |
||||
expect(sales_log.uprn).to eq(nil) |
||||
expect(sales_log.uprn_confirmed).to eq(nil) |
||||
expect(sales_log.uprn_selection).to eq(nil) |
||||
expect(sales_log.pcodenk).to eq(nil) |
||||
expect(sales_log.postcode_full).to eq(nil) |
||||
expect(sales_log.address_line1).to eq(nil) |
||||
expect(sales_log.address_line2).to eq(nil) |
||||
expect(sales_log.town_or_city).to eq(nil) |
||||
expect(sales_log.la).to eq(nil) |
||||
|
||||
get "/address-search/manual-input/sales_log/#{sales_log.id}" |
||||
|
||||
sales_log.reload |
||||
expect(sales_log.manual_address_entry_selected).to eq(true) |
||||
expect(sales_log.uprn_known).to eq(0) |
||||
expect(sales_log.uprn).to eq(nil) |
||||
expect(sales_log.uprn_confirmed).to eq(nil) |
||||
expect(sales_log.uprn_selection).to eq(nil) |
||||
expect(sales_log.pcodenk).to eq(nil) |
||||
expect(sales_log.postcode_full).to eq(nil) |
||||
expect(sales_log.address_line1).to eq(nil) |
||||
expect(sales_log.address_line2).to eq(nil) |
||||
expect(sales_log.town_or_city).to eq(nil) |
||||
expect(sales_log.la).to eq(nil) |
||||
end |
||||
end |
||||
|
||||
context "when choosing to manually input an address for a log that has an address searched value" do |
||||
let(:lettings_log) { create(:lettings_log, :completed, manual_address_entry_selected: false, assigned_to: user) } |
||||
|
||||
it "correctly sets address fields" do |
||||
lettings_log.reload |
||||
expect(lettings_log.uprn_known).to eq(1) |
||||
expect(lettings_log.uprn).to eq("10033558653") |
||||
expect(lettings_log.uprn_confirmed).to eq(1) |
||||
expect(lettings_log.uprn_selection).to eq("10033558653") |
||||
expect(lettings_log.postcode_known).to eq(1) |
||||
expect(lettings_log.postcode_full).to eq("SW1A 1AA") |
||||
expect(lettings_log.address_line1).to eq("The Mall, City Of Westminster") |
||||
expect(lettings_log.address_line2).to eq(nil) |
||||
expect(lettings_log.town_or_city).to eq("London") |
||||
expect(lettings_log.la).to eq("E09000033") |
||||
|
||||
get "/address-search/manual-input/lettings_log/#{lettings_log.id}" |
||||
|
||||
lettings_log.reload |
||||
expect(lettings_log.manual_address_entry_selected).to eq(true) |
||||
expect(lettings_log.uprn_known).to eq(0) |
||||
expect(lettings_log.uprn).to eq(nil) |
||||
expect(lettings_log.uprn_confirmed).to eq(nil) |
||||
expect(lettings_log.uprn_selection).to eq(nil) |
||||
expect(lettings_log.postcode_known).to eq(nil) |
||||
expect(lettings_log.postcode_full).to eq(nil) |
||||
expect(lettings_log.address_line1).to eq(nil) |
||||
expect(lettings_log.address_line2).to eq(nil) |
||||
expect(lettings_log.town_or_city).to eq(nil) |
||||
expect(lettings_log.la).to eq(nil) |
||||
end |
||||
end |
||||
end |
||||
|
||||
describe "#search input" do |
||||
context "when no address is entered manually and choosing to search instead" do |
||||
let(:lettings_log) { create(:lettings_log, :setup_completed, manual_address_entry_selected: true, assigned_to: user) } |
||||
|
||||
it "correctly sets address fields" do |
||||
lettings_log.reload |
||||
expect(lettings_log.manual_address_entry_selected).to eq(true) |
||||
expect(lettings_log.uprn_known).to eq(0) |
||||
expect(lettings_log.uprn).to eq(nil) |
||||
expect(lettings_log.uprn_confirmed).to eq(nil) |
||||
expect(lettings_log.uprn_selection).to eq(nil) |
||||
expect(lettings_log.postcode_known).to eq(nil) |
||||
expect(lettings_log.postcode_full).to eq(nil) |
||||
expect(lettings_log.address_line1).to eq(nil) |
||||
expect(lettings_log.address_line2).to eq(nil) |
||||
expect(lettings_log.town_or_city).to eq(nil) |
||||
expect(lettings_log.la).to eq(nil) |
||||
|
||||
get "/address-search/search-input/lettings_log/#{lettings_log.id}" |
||||
|
||||
lettings_log.reload |
||||
expect(lettings_log.manual_address_entry_selected).to eq(false) |
||||
expect(lettings_log.uprn_known).to eq(nil) |
||||
expect(lettings_log.uprn).to eq(nil) |
||||
expect(lettings_log.uprn_confirmed).to eq(nil) |
||||
expect(lettings_log.uprn_selection).to eq(nil) |
||||
expect(lettings_log.postcode_known).to eq(nil) |
||||
expect(lettings_log.postcode_full).to eq(nil) |
||||
expect(lettings_log.address_line1).to eq(nil) |
||||
expect(lettings_log.address_line2).to eq(nil) |
||||
expect(lettings_log.town_or_city).to eq(nil) |
||||
expect(lettings_log.la).to eq(nil) |
||||
end |
||||
end |
||||
|
||||
context "when choosing to search for an address for a log that has an address searched value" do |
||||
let(:sales_log) { create(:sales_log, :completed, manual_address_entry_selected: true, town_or_city: "Test Town", assigned_to: user) } |
||||
|
||||
it "correctly sets address fields" do |
||||
sales_log.reload |
||||
expect(sales_log.manual_address_entry_selected).to eq(true) |
||||
expect(sales_log.uprn_known).to eq(0) |
||||
expect(sales_log.uprn).to eq(nil) |
||||
expect(sales_log.uprn_confirmed).to eq(nil) |
||||
expect(sales_log.uprn_selection).to eq(nil) |
||||
expect(sales_log.pcodenk).to eq(0) |
||||
expect(sales_log.postcode_full).to eq("SW1A 1AA") |
||||
expect(sales_log.address_line1).to eq("Address line 1") |
||||
expect(sales_log.address_line2).to eq(nil) |
||||
expect(sales_log.town_or_city).to eq("Test Town") |
||||
expect(sales_log.la).to eq("E09000033") |
||||
|
||||
get "/address-search/search-input/sales_log/#{sales_log.id}" |
||||
|
||||
sales_log.reload |
||||
expect(sales_log.manual_address_entry_selected).to eq(false) |
||||
expect(sales_log.uprn_known).to eq(nil) |
||||
expect(sales_log.uprn).to eq(nil) |
||||
expect(sales_log.uprn_confirmed).to eq(nil) |
||||
expect(sales_log.uprn_selection).to eq(nil) |
||||
expect(sales_log.pcodenk).to eq(nil) |
||||
expect(sales_log.postcode_full).to eq(nil) |
||||
expect(sales_log.address_line1).to eq(nil) |
||||
expect(sales_log.address_line2).to eq(nil) |
||||
expect(sales_log.town_or_city).to eq(nil) |
||||
expect(sales_log.la).to eq(nil) |
||||
end |
||||
end |
||||
end |
||||
end |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue