Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Renewal start page and user permissions #11

Merged
merged 12 commits into from
Dec 20, 2017
4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ gem "sdoc", "~> 0.4.0", group: :doc
# Use AASM to manage states and transitions
gem "aasm", "~> 4.12"

# Use CanCanCan for user roles and permissions
# Version 2.0 doesn't support Mongoid, so we're locked to an earlier one
gem "cancancan", "~> 1.10"

# Use Devise for user authentication
gem "devise", "~> 4.3"

Expand Down
4 changes: 4 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ GEM
bson (4.2.2)
builder (3.2.3)
byebug (9.1.0)
cancancan (1.17.0)
coffee-rails (4.1.1)
coffee-script (>= 2.2.0)
railties (>= 4.0.0, < 5.1.x)
Expand Down Expand Up @@ -225,6 +226,7 @@ PLATFORMS
DEPENDENCIES
aasm (~> 4.12)
byebug
cancancan (~> 1.10)
coffee-rails (~> 4.1.0)
database_cleaner
devise (~> 4.3)
Expand All @@ -247,6 +249,8 @@ DEPENDENCIES
uglifier (>= 1.3.0)
web-console (~> 2.0)

RUBY VERSION
ruby 2.4.2p198

BUNDLED WITH
1.16.0.pre.3
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

[![Build Status](https://travis-ci.org/DEFRA/waste-carriers-renewals.svg?branch=master)](https://travis-ci.org/DEFRA/waste-carriers-renewals) [![Maintainability](https://api.codeclimate.com/v1/badges/414c0f88f3f030452da8/maintainability)](https://codeclimate.com/github/DEFRA/waste-carriers-renewals/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/414c0f88f3f030452da8/test_coverage)](https://codeclimate.com/github/DEFRA/waste-carriers-renewals/test_coverage) [![security](https://hakiri.io/github/DEFRA/waste-carriers-renewals/master.svg)](https://hakiri.io/github/DEFRA/waste-carriers-renewals/master) [![Dependency Status](https://dependencyci.com/github/DEFRA/waste-carriers-renewals/badge)](https://dependencyci.com/github/DEFRA/waste-carriers-renewals)

The Waste Carrier Registrations Service allows businesses, who deal with waste and thus have to register according to the regulations, to register online. Once registered, businesses can sign in again to edit their registrations if needed.
The 'Register as a waste carrier' service allows businesses, who deal with waste and have to register according to the regulations, to register online. Once registered, businesses can sign in again to edit their registrations if needed.

The service also allows authorised agency users and NCCC contact centre staff to create and manage registrations on other users behalf, e.g. to support 'Assisted Digital' registrations. The service provides an internal user account management facility which allows authorised administrators to create and manage other agency user accounts.
The service also allows authorised agency users and NCCC staff to create and manage registrations on other users' behalf, e.g. to support 'Assisted Digital' registrations. The service provides an internal user account management facility which allows authorised administrators to create and manage other agency user accounts.

The renewals application allows users who registered using the Waste Carrier Registrations Service to renew their registrations.
The waste-carriers-renewals application allows users who registered using the 'Register as a waste carrier' service to renew their registrations.

## Prerequisites

Expand Down
63 changes: 40 additions & 23 deletions app/controllers/forms_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,35 @@ def go_back
redirect_to_correct_form
end

protected
private

def set_transient_registration(reg_identifier)
@transient_registration = TransientRegistration.where(reg_identifier: reg_identifier).first ||
TransientRegistration.new(reg_identifier: reg_identifier)
end

# Expects a form class name (eg BusinessTypeForm), a snake_case name for the form (eg business_type_form),
# and the reg_identifier param
def set_up_form(form_class, form, reg_identifier)
set_transient_registration(reg_identifier)

unless form_matches_state?
redirect_to_correct_form
return false
end
return false unless transient_registration_is_valid? &&
user_has_permission? &&
state_is_correct?

# Set an instance variable for the form (eg. @business_type_form) using the provided class (eg. BusinessTypeForm)
instance_variable_set("@#{form}", form_class.new(@transient_registration))
end

private

def set_transient_registration(reg_identifier)
@transient_registration = TransientRegistration.where(reg_identifier: reg_identifier).first ||
TransientRegistration.new(reg_identifier: reg_identifier)
end

def form_matches_state?
controller_name == "#{@transient_registration.workflow_state}s"
def submit_form(form, params)
respond_to do |format|
if form.submit(params)
@transient_registration.next!
format.html { redirect_to_correct_form }
else
format.html { render :new }
end
end
end

def redirect_to_correct_form
Expand All @@ -60,14 +64,27 @@ def form_path
send("new_#{@transient_registration.workflow_state}_path".to_sym, @transient_registration.reg_identifier)
end

def submit_form(form, params)
respond_to do |format|
if form.submit(params)
@transient_registration.next!
format.html { redirect_to_correct_form }
else
format.html { render :new }
end
end
# Guards

def transient_registration_is_valid?
return true if @transient_registration.valid?
redirect_to page_path("errors/invalid")
false
end

def user_has_permission?
return true if can? :update, @transient_registration
redirect_to page_path("errors/permission")
false
end

def state_is_correct?
return true if form_matches_state?
redirect_to_correct_form
false
end

def form_matches_state?
controller_name == "#{@transient_registration.workflow_state}s"
end
end
5 changes: 1 addition & 4 deletions app/controllers/renewal_start_forms_controller.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
class RenewalStartFormsController < FormsController

# Unlike other forms, we don't use 'super' for this action because we need to run different validations
def new
return unless set_up_form(RenewalStartForm, "renewal_start_form", params[:reg_identifier])
@renewal_start_form.validate
super(RenewalStartForm, "renewal_start_form")
end

def create
Expand Down
12 changes: 7 additions & 5 deletions app/forms/renewal_start_form.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class RenewalStartForm < BaseForm
include CanCalculateRenewalDates

attr_accessor :reg_identifier

def initialize(transient_registration)
Expand All @@ -11,17 +13,17 @@ def submit(params)
# Define the params which are allowed
self.reg_identifier = params[:reg_identifier]

@transient_registration.reg_identifier = reg_identifier

# Update the transient registration with params from the registration if valid
if valid?
attributes = @transient_registration.renewal_attributes
@transient_registration.assign_attributes(attributes)

@transient_registration.reg_identifier = reg_identifier
@transient_registration.save!
true
else
false
end
end

def projected_renewal_end_date
expiry_date_after_renewal(@transient_registration.expires_on.to_date)
end
end
7 changes: 7 additions & 0 deletions app/models/ability.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class Ability
include CanCan::Ability

def initialize(user)
can :manage, TransientRegistration, account_email: user.email
end
end
7 changes: 7 additions & 0 deletions app/models/concerns/can_calculate_renewal_dates.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module CanCalculateRenewalDates
extend ActiveSupport::Concern

def expiry_date_after_renewal(current_expiry_date)
current_expiry_date + 3.years
end
end
3 changes: 2 additions & 1 deletion app/models/concerns/can_change_registration_status.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module CanChangeRegistrationStatus
extend ActiveSupport::Concern
include Mongoid::Document
include CanCalculateRenewalDates

included do
include AASM
Expand Down Expand Up @@ -61,7 +62,7 @@ def set_expiry_date
end

def extend_expiry_date
new_expiry_date = registration.expires_on + 3.years
new_expiry_date = expiry_date_after_renewal(registration.expires_on)
registration.set(expires_on: new_expiry_date)
end

Expand Down
16 changes: 11 additions & 5 deletions app/models/transient_registration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,20 @@ class TransientRegistration
validates_with RegIdentifierValidator
validate :no_renewal_in_progress?, on: :create

def renewal_attributes
registration = Registration.where(reg_identifier: reg_identifier).first
# Don't return object IDs as Mongo should generate new unique ones
registration.attributes.except("_id")
end
after_initialize :copy_data_from_registration, on: :create

private

def copy_data_from_registration
# Don't try to get Registration data with an invalid reg_identifier
return unless valid?

registration = Registration.where(reg_identifier: reg_identifier).first

# Don't copy object IDs as Mongo should generate new unique ones
assign_attributes(registration.attributes.except("_id"))
end

# Check if a transient renewal already exists for this registration so we don't have
# multiple renewals in progress at once
def no_renewal_in_progress?
Expand Down
4 changes: 4 additions & 0 deletions app/views/pages/errors/invalid.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<div class="text">
<h1 class="heading-large"><%= I18n.t(".invalid_reg_identifier_heading") %></h1>
<p><%= I18n.t(".invalid_reg_identifier_text") %></p>
</div>
4 changes: 4 additions & 0 deletions app/views/pages/errors/permission.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<div class="text">
<h1 class="heading-large"><%= I18n.t(".no_permissions_heading") %></h1>
<p><%= I18n.t(".no_permissions_text") %></p>
</div>
8 changes: 7 additions & 1 deletion app/views/renewal_start_forms/new.html.erb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<div class="text">
<% if @renewal_start_form.errors.any? %>

<h1 class="heading-large"><%= t(".error_heading") %></h1>
Expand All @@ -11,7 +12,11 @@
<%= form_for(@renewal_start_form) do |f| %>
<%= render("shared/errors", object: @renewal_start_form) %>

<h1 class="heading-large"><%= t(".confirmation_text", reg_identifier: @renewal_start_form.reg_identifier) %></h1>
<h1 class="heading-large"><%= t(".heading", reg_identifier: @renewal_start_form.reg_identifier) %></h1>

<p><%= t(".paragraph_1", date: @renewal_start_form.projected_renewal_end_date, renewal_charge: Rails.configuration.renewal_charge, type_change_charge: Rails.configuration.type_change_charge) %></p>
<p><%= t(".paragraph_2") %></p>
<p><%= t(".paragraph_3") %></p>

<%= f.hidden_field :reg_identifier, value: @renewal_start_form.reg_identifier %>
<div class="form-group">
Expand All @@ -20,3 +25,4 @@
<% end %>

<% end %>
</div>
4 changes: 4 additions & 0 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,9 @@ class Application < Rails::Application
application.css
print.css
)

# Fees
config.renewal_charge = 105
config.type_change_charge = 40
end
end
1 change: 1 addition & 0 deletions config/initializers/date_formats.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Date::DATE_FORMATS[:default] = '%e %B %Y'
3 changes: 3 additions & 0 deletions config/initializers/high_voltage.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
HighVoltage.configure do |config|
config.route_drawer = HighVoltage::RouteDrawers::Root
end
7 changes: 7 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,10 @@ en:
shared:
footer:
support_text: 'Environment Agency (England) helpline: 03708 506506'

# Custom error pages
invalid_reg_identifier_heading: The registration number you entered is not valid
invalid_reg_identifier_text: Maybe you should try searching again.

no_permissions_heading: You don't have permission to access that registration
no_permissions_text: Maybe you should try searching again.
7 changes: 5 additions & 2 deletions config/locales/forms/renewal_start_forms/en.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
en:
renewal_start_forms:
new:
confirmation_text: You are about to renew %{reg_identifier}.
heading: You are about to renew %{reg_identifier}
paragraph_1: Renewing this registration will extend its expiry date to %{date}. There is a charge of £%{renewal_charge} to do this, plus a £%{type_change_charge} charge if you change the registration type.
paragraph_2: If your business type has changed, for example from sole trader to limited company, you cannot renew and instead must create a new registration.
paragraph_3: We’ll also check the type of activities you are doing to confirm you still require an upper tier registration. If you don’t you cannot renew and again must create a new lower tier registration.
error_heading: You cannot renew this registration
next_button: Begin renewal
next_button: Continue
activemodel:
errors:
models:
Expand Down
6 changes: 5 additions & 1 deletion spec/factories/registration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
addresses { [build(:address)] }
end

trait :has_expires_on do
trait :expires_soon do
expires_on 2.months.from_now
end

trait :expires_later do
expires_on 2.years.from_now
end

Expand Down
6 changes: 1 addition & 5 deletions spec/factories/transient_registration.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
FactoryBot.define do
factory :transient_registration do
trait :has_required_data do
# Create a registration and use the reg_identifier so validations pass
after(:build) do |transient_registration|
registration = create(:registration, :has_required_data)
transient_registration.reg_identifier = registration.reg_identifier
end
reg_identifier { create(:registration, :has_required_data, :expires_soon).reg_identifier }
end
end
end
2 changes: 1 addition & 1 deletion spec/models/registration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@
end

context "when a registration is active" do
let(:registration) { build(:registration, :has_expires_on, :is_active) }
let(:registration) { build(:registration, :expires_later, :is_active) }

it "has 'active' status" do
expect(registration.metaData).to have_state(:active)
Expand Down
Loading