Skip to content

Commit

Permalink
Search for a contact address by UK postcode (#117)
Browse files Browse the repository at this point in the history
* Search for a contact address by UK postcode

https://eaflood.atlassian.net/browse/WC-112

"What's the address of the person we should contact?" Add forms to allow UK-based users to enter a postcode so they can search for a contact address. Selection and saving of the contact address will be added in a separate PR to keep things manageable.

This should function the same way as the registered address forms earlier in the process.

Non-UK users or users who choose to enter their addresses manually will see a separate form (to be worked on as a separate feature).

* Set up contact postcode form

Currently this is just a copy of the registered address postcode form with names swapped around (and some tweaks to the postcode validator to deal with the two different postcode fields).

References to the manual contact address page have been commented out until that page is created.

Next step is to refactor to remove masses of duplication.

* Rename temp_postcode to temp_company_postcode

This is the attribute used for looking up registered addresses. Now that we have two temporary postcodes, I've renamed this to be a bit clearer.

* Rename and refactor postcode validator

Make it less specific to certain attributes, and also reduce complexity of the validate method.

* Add explanatory text to page

* Postcode forms now inherit from PostcodeForm
  • Loading branch information
irisfaraway committed Apr 10, 2018
1 parent 92f1699 commit 396ff6c
Show file tree
Hide file tree
Showing 34 changed files with 828 additions and 118 deletions.
9 changes: 1 addition & 8 deletions app/controllers/company_postcode_forms_controller.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
class CompanyPostcodeFormsController < FormsController
class CompanyPostcodeFormsController < PostcodeFormsController
def new
super(CompanyPostcodeForm, "company_postcode_form")
end

def create
super(CompanyPostcodeForm, "company_postcode_form")
end

def skip_to_manual_address
set_transient_registration(params[:reg_identifier])

@transient_registration.skip_to_manual_address! if form_matches_state?
redirect_to_correct_form
end
end
9 changes: 9 additions & 0 deletions app/controllers/contact_postcode_forms_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class ContactPostcodeFormsController < PostcodeFormsController
def new
super(ContactPostcodeForm, "contact_postcode_form")
end

def create
super(ContactPostcodeForm, "contact_postcode_form")
end
end
8 changes: 8 additions & 0 deletions app/controllers/postcode_forms_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class PostcodeFormsController < FormsController
def skip_to_manual_address
set_transient_registration(params[:reg_identifier])

@transient_registration.skip_to_manual_address! if form_matches_state?
redirect_to_correct_form
end
end
10 changes: 5 additions & 5 deletions app/forms/company_address_form.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class CompanyAddressForm < BaseForm
attr_accessor :business_type
attr_accessor :temp_postcode
attr_accessor :temp_company_postcode
attr_accessor :temp_addresses
attr_accessor :temp_address
attr_accessor :addresses
Expand All @@ -9,7 +9,7 @@ def initialize(transient_registration)
super
# We only use this for the correct microcopy
self.business_type = @transient_registration.business_type
self.temp_postcode = @transient_registration.temp_postcode
self.temp_company_postcode = @transient_registration.temp_company_postcode

look_up_addresses
preselect_existing_address
Expand All @@ -27,10 +27,10 @@ def submit(params)

private

# Look up addresses based on the temp_postcode
# Look up addresses based on the temp_company_postcode
def look_up_addresses
if temp_postcode.present?
address_finder = AddressFinderService.new(temp_postcode)
if temp_company_postcode.present?
address_finder = AddressFinderService.new(temp_company_postcode)
self.temp_addresses = address_finder.search_by_postcode
else
self.temp_addresses = []
Expand Down
8 changes: 4 additions & 4 deletions app/forms/company_address_manual_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ def initialize(transient_registration)
self.os_places_error = @transient_registration.temp_os_places_error
@transient_registration.update_attributes(temp_os_places_error: nil)

# Prefill the existing address unless the temp_postcode has changed from the saved postcode
# Otherwise, just fill in the temp_postcode
saved_address_still_valid? ? prefill_existing_address : self.postcode = @transient_registration.temp_postcode
# Prefill the existing address unless the temp_company_postcode has changed from the saved postcode
# Otherwise, just fill in the temp_company_postcode
saved_address_still_valid? ? prefill_existing_address : self.postcode = @transient_registration.temp_company_postcode
end

def submit(params)
Expand Down Expand Up @@ -52,7 +52,7 @@ def overseas?
def saved_address_still_valid?
return true if overseas?
return false unless @transient_registration.registered_address
return true if @transient_registration.temp_postcode == @transient_registration.registered_address.postcode
return true if @transient_registration.temp_company_postcode == @transient_registration.registered_address.postcode
false
end

Expand Down
22 changes: 7 additions & 15 deletions app/forms/company_postcode_form.rb
Original file line number Diff line number Diff line change
@@ -1,32 +1,24 @@
class CompanyPostcodeForm < BaseForm
attr_accessor :business_type, :temp_postcode
class CompanyPostcodeForm < PostcodeForm
attr_accessor :business_type, :temp_company_postcode

def initialize(transient_registration)
super
self.temp_postcode = @transient_registration.temp_postcode
self.temp_company_postcode = @transient_registration.temp_company_postcode
# We only use this for the correct microcopy
self.business_type = @transient_registration.business_type
end

def submit(params)
# Assign the params for validation and pass them to the BaseForm method for updating
self.temp_postcode = params[:temp_postcode]
format_postcode
attributes = { temp_postcode: temp_postcode }
self.temp_company_postcode = params[:temp_company_postcode]
format_postcode(temp_company_postcode)
attributes = { temp_company_postcode: temp_company_postcode }

# While we won't proceed if the postcode isn't valid, we should always save it in case it's needed for manual entry
@transient_registration.update_attributes(attributes)

super(attributes, params[:reg_identifier])
end

validates_with TempPostcodeValidator

private

def format_postcode
return unless temp_postcode.present?
temp_postcode.upcase!
temp_postcode.strip!
end
validates_with PostcodeValidator, fields: [:temp_company_postcode]
end
22 changes: 22 additions & 0 deletions app/forms/contact_postcode_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
class ContactPostcodeForm < PostcodeForm
attr_accessor :temp_contact_postcode

def initialize(transient_registration)
super
self.temp_contact_postcode = @transient_registration.temp_contact_postcode
end

def submit(params)
# Assign the params for validation and pass them to the BaseForm method for updating
self.temp_contact_postcode = params[:temp_contact_postcode]
format_postcode(temp_contact_postcode)
attributes = { temp_contact_postcode: temp_contact_postcode }

# While we won't proceed if the postcode isn't valid, we should always save it in case it's needed for manual entry
@transient_registration.update_attributes(attributes)

super(attributes, params[:reg_identifier])
end

validates_with PostcodeValidator, fields: [:temp_contact_postcode]
end
9 changes: 9 additions & 0 deletions app/forms/postcode_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class PostcodeForm < BaseForm
private

def format_postcode(postcode)
return unless postcode.present?
postcode.upcase!
postcode.strip!
end
end
17 changes: 16 additions & 1 deletion app/models/concerns/can_change_workflow_status.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ module CanChangeWorkflowStatus
state :contact_name_form
state :contact_phone_form
state :contact_email_form
state :contact_postcode_form
state :contact_address_form

state :check_your_answers_form
Expand Down Expand Up @@ -198,11 +199,18 @@ module CanChangeWorkflowStatus
to: :contact_email_form

transitions from: :contact_email_form,
to: :contact_postcode_form

# Contact address

transitions from: :contact_postcode_form,
to: :contact_address_form

transitions from: :contact_address_form,
to: :check_your_answers_form

# End contact address

transitions from: :check_your_answers_form,
to: :declaration_form

Expand Down Expand Up @@ -342,12 +350,19 @@ module CanChangeWorkflowStatus
transitions from: :contact_email_form,
to: :contact_phone_form

transitions from: :contact_address_form,
# Contact address

transitions from: :contact_postcode_form,
to: :contact_email_form

transitions from: :contact_address_form,
to: :contact_postcode_form

transitions from: :check_your_answers_form,
to: :contact_address_form

# End contact address

transitions from: :declaration_form,
to: :check_your_answers_form

Expand Down
3 changes: 2 additions & 1 deletion app/models/transient_registration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ class TransientRegistration
after_initialize :copy_data_from_registration

# Attributes specific to the transient object - all others are in CanHaveRegistrationAttributes
field :temp_postcode, type: String
field :temp_company_postcode, type: String
field :temp_contact_postcode, type: String
field :temp_os_places_error, type: Boolean

# Check if the user has changed the registration type, as this incurs an additional 40GBP charge
Expand Down
44 changes: 44 additions & 0 deletions app/validators/postcode_validator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
require "uk_postcode"

class PostcodeValidator < ActiveModel::Validator
def validate(record)
return unless options[:fields].any?
options[:fields].each do |field|
validate_postcode_field(record, field)
end
end

private

def validate_postcode_field(record, field)
return unless value_is_present?(record, field)
return unless value_uses_correct_format?(record, field)
postcode_returns_results?(record, field)
end

def value_is_present?(record, field)
return true if record.send(field).present?
record.errors.add(field, :blank)
false
end

def value_uses_correct_format?(record, field)
return true if UKPostcode.parse(record.send(field)).full_valid?
record.errors.add(field, :wrong_format)
false
end

def postcode_returns_results?(record, field)
address_finder = AddressFinderService.new(record.send(field))
case address_finder.search_by_postcode
when :not_found
record.errors.add(field, :no_results)
false
when :error
record.transient_registration.temp_os_places_error = true
true
else
true
end
end
end
35 changes: 0 additions & 35 deletions app/validators/temp_postcode_validator.rb

This file was deleted.

2 changes: 1 addition & 1 deletion app/views/company_address_forms/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<div class="form-group">
<label class="form-label"><%= t(".postcode_label") %></label>
<span class="postcode"><%= @company_address_form.temp_postcode %></span>
<span class="postcode"><%= @company_address_form.temp_company_postcode %></span>
<%= link_to(t(".postcode_change_link"), back_company_address_forms_path(@company_address_form.reg_identifier)) %>
</div>

Expand Down
18 changes: 9 additions & 9 deletions app/views/company_postcode_forms/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,25 @@

<h1 class="heading-large"><%= t(".heading_#{@company_postcode_form.business_type}") %></h1>

<% if @company_postcode_form.errors[:temp_postcode].any? %>
<% if @company_postcode_form.errors[:temp_company_postcode].any? %>
<div class="form-group form-group-error">
<% else %>
<div class="form-group">
<% end %>
<fieldset id="temp_postcode">
<fieldset id="temp_company_postcode">
<legend class="visuallyhidden">
<%= t(".heading_#{@company_postcode_form.business_type}") %>
</legend>

<% if @company_postcode_form.errors[:temp_postcode].any? %>
<span class="error-message"><%= @company_postcode_form.errors[:temp_postcode].join(", ") %></span>
<% if @company_postcode_form.errors[:temp_company_postcode].any? %>
<span class="error-message"><%= @company_postcode_form.errors[:temp_company_postcode].join(", ") %></span>
<% end %>
<%= f.label :temp_postcode, class: "form-label" do %>
<%= t(".temp_postcode_label") %>
<span class='form-hint'><%= t(".temp_postcode_hint") %></span>
<%= f.label :temp_company_postcode, class: "form-label" do %>
<%= t(".temp_company_postcode_label") %>
<span class='form-hint'><%= t(".temp_company_postcode_hint") %></span>
<% end %>
<%= f.text_field :temp_postcode, value: @company_postcode_form.temp_postcode, class: "form-control" %>
<%= f.text_field :temp_company_postcode, value: @company_postcode_form.temp_company_postcode, class: "form-control" %>

</fieldset>
</div>
Expand All @@ -34,7 +34,7 @@
<%= f.submit t(".next_button"), class: "button" %>
</div>

<% if @company_postcode_form.errors.added?(:temp_postcode, :no_results) %>
<% if @company_postcode_form.errors.added?(:temp_company_postcode, :no_results) %>
<div class="form-group">
<%= link_to(t(".manual_address_link"), skip_to_manual_address_company_postcode_forms_path(@company_postcode_form.reg_identifier)) %>
</div>
Expand Down
Loading

0 comments on commit 396ff6c

Please sign in to comment.