119 changed files with 2790 additions and 402 deletions
@ -0,0 +1,50 @@ |
|||||||
|
class BulkUploadLettingsLogsController < ApplicationController |
||||||
|
before_action :authenticate_user! |
||||||
|
|
||||||
|
def start |
||||||
|
if in_crossover_period? |
||||||
|
redirect_to bulk_upload_lettings_log_path(id: "year") |
||||||
|
else |
||||||
|
redirect_to bulk_upload_lettings_log_path(id: "prepare-your-file", form: { year: current_year }) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def show |
||||||
|
render form.view_path |
||||||
|
end |
||||||
|
|
||||||
|
def update |
||||||
|
if form.valid? |
||||||
|
redirect_to form.next_path |
||||||
|
else |
||||||
|
render form.view_path |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
private |
||||||
|
|
||||||
|
def current_year |
||||||
|
FormHandler.instance.forms["current_lettings"].start_date.year |
||||||
|
end |
||||||
|
|
||||||
|
def in_crossover_period? |
||||||
|
FormHandler.instance.forms.values.any?(&:in_crossover_period?) |
||||||
|
end |
||||||
|
|
||||||
|
def form |
||||||
|
@form ||= case params[:id] |
||||||
|
when "year" |
||||||
|
Forms::BulkUploadLettings::Year.new(form_params) |
||||||
|
when "prepare-your-file" |
||||||
|
Forms::BulkUploadLettings::PrepareYourFile.new(form_params) |
||||||
|
when "upload-your-file" |
||||||
|
Forms::BulkUploadLettings::UploadYourFile.new(form_params) |
||||||
|
else |
||||||
|
raise "Page not found for path #{params[:id]}" |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def form_params |
||||||
|
params.fetch(:form, {}).permit(:year) |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,50 @@ |
|||||||
|
class BulkUploadSalesLogsController < ApplicationController |
||||||
|
before_action :authenticate_user! |
||||||
|
|
||||||
|
def start |
||||||
|
if in_crossover_period? |
||||||
|
redirect_to bulk_upload_sales_log_path(id: "year") |
||||||
|
else |
||||||
|
redirect_to bulk_upload_sales_log_path(id: "prepare-your-file", form: { year: current_year }) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def show |
||||||
|
render form.view_path |
||||||
|
end |
||||||
|
|
||||||
|
def update |
||||||
|
if form.valid? |
||||||
|
redirect_to form.next_path |
||||||
|
else |
||||||
|
render form.view_path |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
private |
||||||
|
|
||||||
|
def current_year |
||||||
|
FormHandler.instance.forms["current_sales"].start_date.year |
||||||
|
end |
||||||
|
|
||||||
|
def in_crossover_period? |
||||||
|
FormHandler.instance.forms.values.any?(&:in_crossover_period?) |
||||||
|
end |
||||||
|
|
||||||
|
def form |
||||||
|
@form ||= case params[:id] |
||||||
|
when "year" |
||||||
|
Forms::BulkUploadSales::Year.new(form_params) |
||||||
|
when "prepare-your-file" |
||||||
|
Forms::BulkUploadSales::PrepareYourFile.new(form_params) |
||||||
|
when "upload-your-file" |
||||||
|
Forms::BulkUploadSales::UploadYourFile.new(form_params) |
||||||
|
else |
||||||
|
raise "Page not found for path #{params[:id]}" |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def form_params |
||||||
|
params.fetch(:form, {}).permit(:year) |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,57 @@ |
|||||||
|
const cookieBannerEl = document.querySelector('.js-cookie-banner') |
||||||
|
|
||||||
|
if (cookieBannerEl) { |
||||||
|
const cookieFormEl = document.querySelector('.js-cookie-form') |
||||||
|
|
||||||
|
cookieFormEl.addEventListener('click', (e) => { |
||||||
|
if (e.target.tagName !== 'BUTTON') { |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
const body = new window.FormData(cookieFormEl) |
||||||
|
body.append('cookies_form[accept_analytics_cookies]', e.target.value) |
||||||
|
|
||||||
|
fetch(cookieFormEl.action, { |
||||||
|
method: 'PUT', |
||||||
|
headers: { |
||||||
|
Accept: 'application/json' |
||||||
|
}, |
||||||
|
body |
||||||
|
}) |
||||||
|
.then((res) => { |
||||||
|
if (res.status >= 200 && res.status < 300) { |
||||||
|
return res |
||||||
|
} |
||||||
|
|
||||||
|
throw new Error(res) |
||||||
|
}) |
||||||
|
.then((res) => res.json()) |
||||||
|
.then(({ message }) => { |
||||||
|
const messageEl = cookieBannerEl.querySelector('.js-cookie-message') |
||||||
|
messageEl.textContent = message |
||||||
|
|
||||||
|
cookieBannerEl |
||||||
|
.querySelector('.js-cookie-banner__form') |
||||||
|
.setAttribute('hidden', '') |
||||||
|
cookieBannerEl |
||||||
|
.querySelector('.js-cookie-banner__success') |
||||||
|
.removeAttribute('hidden') |
||||||
|
}) |
||||||
|
|
||||||
|
const gaSrc = window.analyticsScript |
||||||
|
if (e.target.value === 'on' && gaSrc) { |
||||||
|
const scriptEl = document.createElement('script') |
||||||
|
scriptEl.src = gaSrc |
||||||
|
document.body.appendChild(scriptEl) |
||||||
|
} |
||||||
|
|
||||||
|
e.preventDefault() |
||||||
|
}) |
||||||
|
|
||||||
|
const hideBannerEl = document.querySelector('.js-hide-cookie-banner') |
||||||
|
hideBannerEl.addEventListener('click', (e) => { |
||||||
|
e.preventDefault() |
||||||
|
|
||||||
|
cookieBannerEl.setAttribute('hidden', '') |
||||||
|
}) |
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
module LogsHelper |
||||||
|
def log_type_for_controller(controller) |
||||||
|
case controller.class.to_s |
||||||
|
when "LettingsLogsController" |
||||||
|
"lettings" |
||||||
|
when "SalesLogsController" |
||||||
|
"sales" |
||||||
|
else |
||||||
|
raise "Log type not found for #{controller.class}" |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def bulk_upload_path_for_controller(controller, id:) |
||||||
|
case log_type_for_controller(controller) |
||||||
|
when "lettings" |
||||||
|
bulk_upload_lettings_log_path(id:) |
||||||
|
when "sales" |
||||||
|
bulk_upload_sales_log_path(id:) |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,17 @@ |
|||||||
|
module ToggleActiveSchemeHelper |
||||||
|
def toggle_scheme_form_path(action, scheme) |
||||||
|
if action == "deactivate" |
||||||
|
scheme_new_deactivation_path(scheme) |
||||||
|
else |
||||||
|
scheme_reactivate_path(scheme) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def date_type_question(action) |
||||||
|
action == "deactivate" ? :deactivation_date_type : :reactivation_date_type |
||||||
|
end |
||||||
|
|
||||||
|
def date_question(action) |
||||||
|
action == "deactivate" ? :deactivation_date : :reactivation_date |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,15 @@ |
|||||||
|
class Form::Sales::Pages::Buyer1Mortgage < ::Form::Page |
||||||
|
def initialize(id, hsh, subsection) |
||||||
|
super |
||||||
|
@id = "buyer_1_mortgage" |
||||||
|
@header = "" |
||||||
|
@description = "" |
||||||
|
@subsection = subsection |
||||||
|
end |
||||||
|
|
||||||
|
def questions |
||||||
|
@questions ||= [ |
||||||
|
Form::Sales::Questions::Buyer1Mortgage.new(nil, nil, self), |
||||||
|
] |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,19 @@ |
|||||||
|
class Form::Sales::Pages::Buyer2Income < ::Form::Page |
||||||
|
def initialize(id, hsh, subsection) |
||||||
|
super |
||||||
|
@id = "buyer_2_income" |
||||||
|
@header = "" |
||||||
|
@description = "" |
||||||
|
@subsection = subsection |
||||||
|
@depends_on = [{ |
||||||
|
"jointpur" => 1, |
||||||
|
}] |
||||||
|
end |
||||||
|
|
||||||
|
def questions |
||||||
|
@questions ||= [ |
||||||
|
Form::Sales::Questions::Buyer2IncomeKnown.new(nil, nil, self), |
||||||
|
Form::Sales::Questions::Buyer2Income.new(nil, nil, self), |
||||||
|
] |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,16 @@ |
|||||||
|
class Form::Sales::Questions::Buyer1Mortgage < ::Form::Question |
||||||
|
def initialize(id, hsh, page) |
||||||
|
super |
||||||
|
@id = "inc1mort" |
||||||
|
@check_answer_label = "Buyer 1's income used for mortgage application" |
||||||
|
@header = "Was buyer 1's income used for a mortgage application" |
||||||
|
@type = "radio" |
||||||
|
@answer_options = ANSWER_OPTIONS |
||||||
|
@page = page |
||||||
|
end |
||||||
|
|
||||||
|
ANSWER_OPTIONS = { |
||||||
|
"1" => { "value" => "Yes" }, |
||||||
|
"2" => { "value" => "No" }, |
||||||
|
}.freeze |
||||||
|
end |
@ -0,0 +1,14 @@ |
|||||||
|
class Form::Sales::Questions::Buyer2Income < ::Form::Question |
||||||
|
def initialize(id, hsh, page) |
||||||
|
super |
||||||
|
@id = "income2" |
||||||
|
@check_answer_label = "Buyer 2’s gross annual income" |
||||||
|
@header = "Buyer 2’s gross annual income" |
||||||
|
@type = "numeric" |
||||||
|
@page = page |
||||||
|
@min = 0 |
||||||
|
@step = 1 |
||||||
|
@width = 5 |
||||||
|
@prefix = "£" |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,21 @@ |
|||||||
|
class Form::Sales::Questions::Buyer2IncomeKnown < ::Form::Question |
||||||
|
def initialize(id, hsh, page) |
||||||
|
super |
||||||
|
@id = "income2nk" |
||||||
|
@check_answer_label = "Buyer 2’s gross annual income" |
||||||
|
@header = "Do you know buyer 2’s annual income?" |
||||||
|
@type = "radio" |
||||||
|
@answer_options = ANSWER_OPTIONS |
||||||
|
@page = page |
||||||
|
@guidance_position = GuidancePosition::BOTTOM |
||||||
|
@guidance_partial = "what_counts_as_income_sales" |
||||||
|
@conditional_for = { |
||||||
|
"income2" => [0], |
||||||
|
} |
||||||
|
end |
||||||
|
|
||||||
|
ANSWER_OPTIONS = { |
||||||
|
"0" => { "value" => "Yes" }, |
||||||
|
"1" => { "value" => "No" }, |
||||||
|
}.freeze |
||||||
|
end |
@ -1,15 +0,0 @@ |
|||||||
class Form::Sales::Subsections::IncomeBenefitsAndOutgoings < ::Form::Subsection |
|
||||||
def initialize(id, hsh, section) |
|
||||||
super |
|
||||||
@id = "income_benefits_and_outgoings" |
|
||||||
@label = "Income, benefits and outgoings" |
|
||||||
@section = section |
|
||||||
@depends_on = [{ "setup_completed?" => true }] |
|
||||||
end |
|
||||||
|
|
||||||
def pages |
|
||||||
@pages ||= [ |
|
||||||
Form::Sales::Pages::Buyer1Income.new(nil, nil, self), |
|
||||||
] |
|
||||||
end |
|
||||||
end |
|
@ -0,0 +1,17 @@ |
|||||||
|
class Form::Sales::Subsections::IncomeBenefitsAndSavings < ::Form::Subsection |
||||||
|
def initialize(id, hsh, section) |
||||||
|
super |
||||||
|
@id = "income_benefits_and_savings" |
||||||
|
@label = "Income, benefits and savings" |
||||||
|
@section = section |
||||||
|
@depends_on = [{ "setup_completed?" => true }] |
||||||
|
end |
||||||
|
|
||||||
|
def pages |
||||||
|
@pages ||= [ |
||||||
|
Form::Sales::Pages::Buyer1Income.new(nil, nil, self), |
||||||
|
Form::Sales::Pages::Buyer1Mortgage.new(nil, nil, self), |
||||||
|
Form::Sales::Pages::Buyer2Income.new(nil, nil, self), |
||||||
|
] |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,41 @@ |
|||||||
|
module Forms |
||||||
|
module BulkUploadLettings |
||||||
|
class PrepareYourFile |
||||||
|
include ActiveModel::Model |
||||||
|
include ActiveModel::Attributes |
||||||
|
include Rails.application.routes.url_helpers |
||||||
|
|
||||||
|
attribute :year, :integer |
||||||
|
|
||||||
|
def view_path |
||||||
|
"bulk_upload_lettings_logs/forms/prepare_your_file" |
||||||
|
end |
||||||
|
|
||||||
|
def back_path |
||||||
|
if in_crossover_period? |
||||||
|
Rails.application.routes.url_helpers.bulk_upload_lettings_log_path(id: "year", form: { year: }) |
||||||
|
else |
||||||
|
Rails.application.routes.url_helpers.lettings_logs_path |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def next_path |
||||||
|
bulk_upload_lettings_log_path(id: "upload-your-file", form: { year: }) |
||||||
|
end |
||||||
|
|
||||||
|
def template_path |
||||||
|
"/files/bulk-upload-lettings-template-v1.xlsx" |
||||||
|
end |
||||||
|
|
||||||
|
def year_combo |
||||||
|
"#{year}/#{year + 1 - 2000}" |
||||||
|
end |
||||||
|
|
||||||
|
private |
||||||
|
|
||||||
|
def in_crossover_period? |
||||||
|
FormHandler.instance.forms.values.any?(&:in_crossover_period?) |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,19 @@ |
|||||||
|
module Forms |
||||||
|
module BulkUploadLettings |
||||||
|
class UploadYourFile |
||||||
|
include ActiveModel::Model |
||||||
|
include ActiveModel::Attributes |
||||||
|
include Rails.application.routes.url_helpers |
||||||
|
|
||||||
|
attribute :year, :integer |
||||||
|
|
||||||
|
def view_path |
||||||
|
"bulk_upload_lettings_logs/forms/upload_your_file" |
||||||
|
end |
||||||
|
|
||||||
|
def back_path |
||||||
|
bulk_upload_lettings_log_path(id: "prepare-your-file", form: { year: }) |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,37 @@ |
|||||||
|
module Forms |
||||||
|
module BulkUploadLettings |
||||||
|
class Year |
||||||
|
include ActiveModel::Model |
||||||
|
include ActiveModel::Attributes |
||||||
|
include Rails.application.routes.url_helpers |
||||||
|
|
||||||
|
attribute :year, :integer |
||||||
|
|
||||||
|
validates :year, presence: true |
||||||
|
|
||||||
|
def view_path |
||||||
|
"bulk_upload_lettings_logs/forms/year" |
||||||
|
end |
||||||
|
|
||||||
|
def options |
||||||
|
possible_years.map do |year| |
||||||
|
OpenStruct.new(id: year, name: "#{year}/#{year + 1}") |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def back_path |
||||||
|
lettings_logs_path |
||||||
|
end |
||||||
|
|
||||||
|
def next_path |
||||||
|
bulk_upload_lettings_log_path(id: "prepare-your-file", form: { year: }) |
||||||
|
end |
||||||
|
|
||||||
|
private |
||||||
|
|
||||||
|
def possible_years |
||||||
|
FormHandler.instance.lettings_forms.values.map { |form| form.start_date.year }.sort.reverse |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,41 @@ |
|||||||
|
module Forms |
||||||
|
module BulkUploadSales |
||||||
|
class PrepareYourFile |
||||||
|
include ActiveModel::Model |
||||||
|
include ActiveModel::Attributes |
||||||
|
include Rails.application.routes.url_helpers |
||||||
|
|
||||||
|
attribute :year, :integer |
||||||
|
|
||||||
|
def view_path |
||||||
|
"bulk_upload_sales_logs/forms/prepare_your_file" |
||||||
|
end |
||||||
|
|
||||||
|
def back_path |
||||||
|
if in_crossover_period? |
||||||
|
Rails.application.routes.url_helpers.bulk_upload_sales_log_path(id: "year", form: { year: }) |
||||||
|
else |
||||||
|
Rails.application.routes.url_helpers.sales_logs_path |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def next_path |
||||||
|
bulk_upload_sales_log_path(id: "upload-your-file", form: { year: }) |
||||||
|
end |
||||||
|
|
||||||
|
def template_path |
||||||
|
"/files/bulk-upload-sales-template-v1.xlsx" |
||||||
|
end |
||||||
|
|
||||||
|
def year_combo |
||||||
|
"#{year}/#{year + 1 - 2000}" |
||||||
|
end |
||||||
|
|
||||||
|
private |
||||||
|
|
||||||
|
def in_crossover_period? |
||||||
|
FormHandler.instance.forms.values.any?(&:in_crossover_period?) |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,19 @@ |
|||||||
|
module Forms |
||||||
|
module BulkUploadSales |
||||||
|
class UploadYourFile |
||||||
|
include ActiveModel::Model |
||||||
|
include ActiveModel::Attributes |
||||||
|
include Rails.application.routes.url_helpers |
||||||
|
|
||||||
|
attribute :year, :integer |
||||||
|
|
||||||
|
def view_path |
||||||
|
"bulk_upload_sales_logs/forms/upload_your_file" |
||||||
|
end |
||||||
|
|
||||||
|
def back_path |
||||||
|
bulk_upload_sales_log_path(id: "prepare-your-file", form: { year: }) |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,37 @@ |
|||||||
|
module Forms |
||||||
|
module BulkUploadSales |
||||||
|
class Year |
||||||
|
include ActiveModel::Model |
||||||
|
include ActiveModel::Attributes |
||||||
|
include Rails.application.routes.url_helpers |
||||||
|
|
||||||
|
attribute :year, :integer |
||||||
|
|
||||||
|
validates :year, presence: true |
||||||
|
|
||||||
|
def view_path |
||||||
|
"bulk_upload_sales_logs/forms/year" |
||||||
|
end |
||||||
|
|
||||||
|
def options |
||||||
|
possible_years.map do |year| |
||||||
|
OpenStruct.new(id: year, name: "#{year}/#{year + 1}") |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def back_path |
||||||
|
sales_logs_path |
||||||
|
end |
||||||
|
|
||||||
|
def next_path |
||||||
|
bulk_upload_sales_log_path(id: "prepare-your-file", form: { year: }) |
||||||
|
end |
||||||
|
|
||||||
|
private |
||||||
|
|
||||||
|
def possible_years |
||||||
|
FormHandler.instance.sales_forms.values.map { |form| form.start_date.year }.sort.reverse |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -1,16 +1,4 @@ |
|||||||
class OrganisationRelationship < ApplicationRecord |
class OrganisationRelationship < ApplicationRecord |
||||||
belongs_to :child_organisation, class_name: "Organisation" |
belongs_to :child_organisation, class_name: "Organisation" |
||||||
belongs_to :parent_organisation, class_name: "Organisation" |
belongs_to :parent_organisation, class_name: "Organisation" |
||||||
|
|
||||||
scope :owning, -> { where(relationship_type: OWNING) } |
|
||||||
scope :managing, -> { where(relationship_type: MANAGING) } |
|
||||||
|
|
||||||
OWNING = "owning".freeze |
|
||||||
MANAGING = "managing".freeze |
|
||||||
RELATIONSHIP_TYPE = { |
|
||||||
OWNING => 0, |
|
||||||
MANAGING => 1, |
|
||||||
}.freeze |
|
||||||
|
|
||||||
enum relationship_type: RELATIONSHIP_TYPE |
|
||||||
end |
end |
||||||
|
@ -0,0 +1,33 @@ |
|||||||
|
<% content_for :before_content do %> |
||||||
|
<%= govuk_back_link href: @form.back_path %> |
||||||
|
<% end %> |
||||||
|
|
||||||
|
<div class="govuk-grid-row"> |
||||||
|
<div class="govuk-grid-column-two-thirds"> |
||||||
|
<%= form_with model: @form, scope: :form, url: bulk_upload_lettings_log_path(id: "prepare-your-file"), method: :patch do |f| %> |
||||||
|
<%= f.hidden_field :year %> |
||||||
|
|
||||||
|
<span class="govuk-caption-l">Upload lettings logs in bulk (<%= @form.year_combo %>)</span> |
||||||
|
<h1 class="govuk-heading-l">Prepare your file</h1> |
||||||
|
|
||||||
|
<h2 class="govuk-heading-m">Create your file</h2> |
||||||
|
<ul class="govuk-list govuk-list--bullet"> |
||||||
|
<li>Download the <%= govuk_link_to "bulk lettings template", @form.template_path %></li> |
||||||
|
<li>Export the data from your housing management system, matching the template</li> |
||||||
|
<li>If you cannot export it in this format, you may have to input it manually</li> |
||||||
|
</ul> |
||||||
|
|
||||||
|
<h2 class="govuk-heading-m">Check your data</h2> |
||||||
|
<ul class="govuk-list govuk-list--bullet"> |
||||||
|
<li>Check data is complete and formatted correctly, using data specifications (opens in a new tab)</li> |
||||||
|
</ul> |
||||||
|
|
||||||
|
<h2 class="govuk-heading-m">Save your file</h2> |
||||||
|
<ul class="govuk-list govuk-list--bullet"> |
||||||
|
<li>Save the file (CSV format <strong>only</strong>)</li> |
||||||
|
</ul> |
||||||
|
|
||||||
|
<%= f.govuk_submit %> |
||||||
|
<% end %> |
||||||
|
</div> |
||||||
|
</div> |
@ -0,0 +1,17 @@ |
|||||||
|
<% content_for :before_content do %> |
||||||
|
<%= govuk_back_link href: @form.back_path %> |
||||||
|
<% end %> |
||||||
|
|
||||||
|
<%= form_with model: @form, scope: :form, url: bulk_upload_lettings_log_path(id: "upload-your-file"), method: :patch do |f| %> |
||||||
|
<%= f.govuk_error_summary %> |
||||||
|
|
||||||
|
<div> |
||||||
|
Upload your file goes here |
||||||
|
</div> |
||||||
|
|
||||||
|
<div> |
||||||
|
year selected <%= @form.year %> |
||||||
|
</div> |
||||||
|
|
||||||
|
<%= f.govuk_submit %> |
||||||
|
<% end %> |
@ -0,0 +1,16 @@ |
|||||||
|
<% content_for :before_content do %> |
||||||
|
<%= govuk_back_link href: @form.back_path %> |
||||||
|
<% end %> |
||||||
|
|
||||||
|
<%= form_with model: @form, scope: :form, url: bulk_upload_lettings_log_path(id: "year"), method: :patch do |f| %> |
||||||
|
<%= f.govuk_error_summary %> |
||||||
|
|
||||||
|
<%= f.govuk_collection_radio_buttons :year, |
||||||
|
@form.options, |
||||||
|
:id, |
||||||
|
:name, |
||||||
|
legend: { text: "Which year are you uploading data for?", size: "l" }, |
||||||
|
caption: { text: "Upload lettings logs in bulk", size: "l" } %> |
||||||
|
|
||||||
|
<%= f.govuk_submit %> |
||||||
|
<% end %> |
@ -0,0 +1,33 @@ |
|||||||
|
<% content_for :before_content do %> |
||||||
|
<%= govuk_back_link href: @form.back_path %> |
||||||
|
<% end %> |
||||||
|
|
||||||
|
<div class="govuk-grid-row"> |
||||||
|
<div class="govuk-grid-column-two-thirds"> |
||||||
|
<%= form_with model: @form, scope: :form, url: bulk_upload_sales_log_path(id: "prepare-your-file"), method: :patch do |f| %> |
||||||
|
<%= f.hidden_field :year %> |
||||||
|
|
||||||
|
<span class="govuk-caption-l">Upload sales logs in bulk (<%= @form.year_combo %>)</span> |
||||||
|
<h1 class="govuk-heading-l">Prepare your file</h1> |
||||||
|
|
||||||
|
<h2 class="govuk-heading-m">Create your file</h2> |
||||||
|
<ul class="govuk-list govuk-list--bullet"> |
||||||
|
<li>Download the <%= govuk_link_to "bulk sales template", @form.template_path %></li> |
||||||
|
<li>Export the data from your housing management system, matching the template</li> |
||||||
|
<li>If you cannot export it in this format, you may have to input it manually</li> |
||||||
|
</ul> |
||||||
|
|
||||||
|
<h2 class="govuk-heading-m">Check your data</h2> |
||||||
|
<ul class="govuk-list govuk-list--bullet"> |
||||||
|
<li>Check data is complete and formatted correctly, using data specifications (opens in a new tab)</li> |
||||||
|
</ul> |
||||||
|
|
||||||
|
<h2 class="govuk-heading-m">Save your file</h2> |
||||||
|
<ul class="govuk-list govuk-list--bullet"> |
||||||
|
<li>Save the file (CSV format <strong>only</strong>)</li> |
||||||
|
</ul> |
||||||
|
|
||||||
|
<%= f.govuk_submit %> |
||||||
|
<% end %> |
||||||
|
</div> |
||||||
|
</div> |
@ -0,0 +1,17 @@ |
|||||||
|
<% content_for :before_content do %> |
||||||
|
<%= govuk_back_link href: @form.back_path %> |
||||||
|
<% end %> |
||||||
|
|
||||||
|
<%= form_with model: @form, scope: :form, url: bulk_upload_sales_log_path(id: "upload-your-file"), method: :patch do |f| %> |
||||||
|
<%= f.govuk_error_summary %> |
||||||
|
|
||||||
|
<div> |
||||||
|
Upload your file goes here |
||||||
|
</div> |
||||||
|
|
||||||
|
<div> |
||||||
|
year selected <%= @form.year %> |
||||||
|
</div> |
||||||
|
|
||||||
|
<%= f.govuk_submit %> |
||||||
|
<% end %> |
@ -0,0 +1,16 @@ |
|||||||
|
<% content_for :before_content do %> |
||||||
|
<%= govuk_back_link href: @form.back_path %> |
||||||
|
<% end %> |
||||||
|
|
||||||
|
<%= form_with model: @form, scope: :form, url: bulk_upload_sales_log_path(id: "year"), method: :patch do |f| %> |
||||||
|
<%= f.govuk_error_summary %> |
||||||
|
|
||||||
|
<%= f.govuk_collection_radio_buttons :year, |
||||||
|
@form.options, |
||||||
|
:id, |
||||||
|
:name, |
||||||
|
legend: { text: "Which year are you uploading data for?", size: "l" }, |
||||||
|
caption: { text: "Upload sales logs in bulk", size: "l" } %> |
||||||
|
|
||||||
|
<%= f.govuk_submit %> |
||||||
|
<% end %> |
@ -0,0 +1,48 @@ |
|||||||
|
<div class="govuk-cookie-banner js-cookie-banner" role="region" aria-label="Cookies on CORE"> |
||||||
|
<div class="govuk-cookie-banner__message govuk-width-container js-cookie-banner__form"> |
||||||
|
<div class="govuk-grid-row"> |
||||||
|
<div class="govuk-grid-column-two-thirds"> |
||||||
|
<h2 class="govuk-cookie-banner__heading govuk-heading-m">Cookies on CORE</h2> |
||||||
|
|
||||||
|
<div class="govuk-cookie-banner__content"> |
||||||
|
<p class="govuk-body">We use some essential cookies to make this service work.</p> |
||||||
|
<p class="govuk-body">We’d like to use analytics cookies so we can understand how you use the service and make improvements.</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<%= form_with url: cookies_path, class: "js-cookie-form", method: :put do |f| %> |
||||||
|
<div class="govuk-button-group"> |
||||||
|
<button type="submit" class="govuk-button" name="cookies_form[analytics_consent]" value="on"> |
||||||
|
Accept analytics cookies |
||||||
|
</button> |
||||||
|
<button type="submit" class="govuk-button" name="cookies_form[analytics_consent]" value="off"> |
||||||
|
Reject analytics cookies |
||||||
|
</button> |
||||||
|
<%= govuk_link_to "View cookies", cookies_path %> |
||||||
|
</div> |
||||||
|
<% end %> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="govuk-cookie-banner__message govuk-width-container js-cookie-banner__success" role="alert" hidden> |
||||||
|
<div class="govuk-grid-row"> |
||||||
|
<div class="govuk-grid-column-two-thirds"> |
||||||
|
|
||||||
|
<div class="govuk-cookie-banner__content"> |
||||||
|
<p class="govuk-body"> |
||||||
|
<span class="js-cookie-message"> |
||||||
|
You’ve set your cookie preferences. |
||||||
|
</span> |
||||||
|
You can <%= govuk_link_to "change your cookie settings", cookies_path %> at any time. |
||||||
|
</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="govuk-button-group"> |
||||||
|
<button class="govuk-button js-hide-cookie-banner"> |
||||||
|
Hide this message |
||||||
|
</button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
@ -0,0 +1,5 @@ |
|||||||
|
class DeleteRelationshipType < ActiveRecord::Migration[7.0] |
||||||
|
def change |
||||||
|
remove_column :organisation_relationships, :relationship_type, :integer, null: false |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,10 @@ |
|||||||
|
class AddOrgRelationIndexes < ActiveRecord::Migration[7.0] |
||||||
|
def change |
||||||
|
add_index :organisation_relationships, :child_organisation_id |
||||||
|
add_index :organisation_relationships, :parent_organisation_id |
||||||
|
add_index :organisation_relationships, %i[parent_organisation_id child_organisation_id], unique: true, name: "index_org_rel_parent_child_uniq" |
||||||
|
|
||||||
|
add_foreign_key :organisation_relationships, :organisations, column: :parent_organisation_id |
||||||
|
add_foreign_key :organisation_relationships, :organisations, column: :child_organisation_id |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,7 @@ |
|||||||
|
class AddMortgage1ToSales < ActiveRecord::Migration[7.0] |
||||||
|
def change |
||||||
|
change_table :sales_logs, bulk: true do |t| |
||||||
|
t.column :inc1mort, :int |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,6 @@ |
|||||||
|
class AddBuyer2ToSales < ActiveRecord::Migration[7.0] |
||||||
|
change_table :sales_logs, bulk: true do |t| |
||||||
|
t.column :income2, :int |
||||||
|
t.column :income2nk, :int |
||||||
|
end |
||||||
|
end |
Binary file not shown.
Binary file not shown.
@ -1,5 +1,6 @@ |
|||||||
FactoryBot.define do |
FactoryBot.define do |
||||||
factory :scheme_deactivation_period do |
factory :scheme_deactivation_period do |
||||||
|
deactivation_date { Time.zone.local(2022, 4, 1) } |
||||||
reactivation_date { nil } |
reactivation_date { nil } |
||||||
end |
end |
||||||
end |
end |
||||||
|
@ -0,0 +1,51 @@ |
|||||||
|
require "rails_helper" |
||||||
|
|
||||||
|
RSpec.describe "Bulk upload lettings log" do |
||||||
|
let(:user) { create(:user) } |
||||||
|
|
||||||
|
before do |
||||||
|
sign_in user |
||||||
|
end |
||||||
|
|
||||||
|
context "when during crossover period" do |
||||||
|
it "shows journey with year option" do |
||||||
|
Timecop.freeze(2023, 6, 1) do |
||||||
|
visit("/lettings-logs") |
||||||
|
expect(page).to have_link("Upload lettings logs in bulk") |
||||||
|
click_link("Upload lettings logs in bulk") |
||||||
|
|
||||||
|
expect(page).to have_content("Which year") |
||||||
|
click_button("Continue") |
||||||
|
|
||||||
|
expect(page).to have_content("You must select a collection period to upload for") |
||||||
|
choose("2022/2023") |
||||||
|
click_button("Continue") |
||||||
|
|
||||||
|
click_link("Back") |
||||||
|
|
||||||
|
expect(page.find_field("form-year-2022-field")).to be_checked |
||||||
|
click_button("Continue") |
||||||
|
|
||||||
|
expect(page).to have_content("Upload lettings logs in bulk (2022/23)") |
||||||
|
click_button("Continue") |
||||||
|
|
||||||
|
expect(page).to have_content("Upload your file") |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
context "when not it crossover period" do |
||||||
|
it "shows journey with year option" do |
||||||
|
Timecop.freeze(2023, 10, 1) do |
||||||
|
visit("/lettings-logs") |
||||||
|
expect(page).to have_link("Upload lettings logs in bulk") |
||||||
|
click_link("Upload lettings logs in bulk") |
||||||
|
|
||||||
|
expect(page).to have_content("Upload lettings logs in bulk (2022/23)") |
||||||
|
click_button("Continue") |
||||||
|
|
||||||
|
expect(page).to have_content("Upload your file") |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,51 @@ |
|||||||
|
require "rails_helper" |
||||||
|
|
||||||
|
RSpec.describe "Bulk upload sales log" do |
||||||
|
let(:user) { create(:user) } |
||||||
|
|
||||||
|
before do |
||||||
|
sign_in user |
||||||
|
end |
||||||
|
|
||||||
|
context "when during crossover period" do |
||||||
|
it "shows journey with year option" do |
||||||
|
Timecop.freeze(2023, 6, 1) do |
||||||
|
visit("/sales-logs") |
||||||
|
expect(page).to have_link("Upload sales logs in bulk") |
||||||
|
click_link("Upload sales logs in bulk") |
||||||
|
|
||||||
|
expect(page).to have_content("Which year") |
||||||
|
click_button("Continue") |
||||||
|
|
||||||
|
expect(page).to have_content("You must select a collection period to upload for") |
||||||
|
choose("2022/2023") |
||||||
|
click_button("Continue") |
||||||
|
|
||||||
|
click_link("Back") |
||||||
|
|
||||||
|
expect(page.find_field("form-year-2022-field")).to be_checked |
||||||
|
click_button("Continue") |
||||||
|
|
||||||
|
expect(page).to have_content("Upload sales logs in bulk (2022/23)") |
||||||
|
click_button("Continue") |
||||||
|
|
||||||
|
expect(page).to have_content("Upload your file") |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
context "when not it crossover period" do |
||||||
|
it "shows journey with year option" do |
||||||
|
Timecop.freeze(2023, 10, 1) do |
||||||
|
visit("/sales-logs") |
||||||
|
expect(page).to have_link("Upload sales logs in bulk") |
||||||
|
click_link("Upload sales logs in bulk") |
||||||
|
|
||||||
|
expect(page).to have_content("Upload sales logs in bulk (2022/23)") |
||||||
|
click_button("Continue") |
||||||
|
|
||||||
|
expect(page).to have_content("Upload your file") |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
|
|
@ -0,0 +1,33 @@ |
|||||||
|
require "rails_helper" |
||||||
|
|
||||||
|
RSpec.describe Form::Sales::Pages::Buyer1Mortgage, 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) } |
||||||
|
|
||||||
|
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[inc1mort]) |
||||||
|
end |
||||||
|
|
||||||
|
it "has the correct id" do |
||||||
|
expect(page.id).to eq("buyer_1_mortgage") |
||||||
|
end |
||||||
|
|
||||||
|
it "has the correct header" do |
||||||
|
expect(page.header).to eq("") |
||||||
|
end |
||||||
|
|
||||||
|
it "has the correct description" do |
||||||
|
expect(page.description).to eq("") |
||||||
|
end |
||||||
|
|
||||||
|
it "has correct depends_on" do |
||||||
|
expect(page.depends_on).to be_nil |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,33 @@ |
|||||||
|
require "rails_helper" |
||||||
|
|
||||||
|
RSpec.describe Form::Sales::Pages::Buyer2Income, 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) } |
||||||
|
|
||||||
|
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[income2nk income2]) |
||||||
|
end |
||||||
|
|
||||||
|
it "has the correct id" do |
||||||
|
expect(page.id).to eq("buyer_2_income") |
||||||
|
end |
||||||
|
|
||||||
|
it "has the correct header" do |
||||||
|
expect(page.header).to eq("") |
||||||
|
end |
||||||
|
|
||||||
|
it "has the correct description" do |
||||||
|
expect(page.description).to eq("") |
||||||
|
end |
||||||
|
|
||||||
|
it "has correct depends_on" do |
||||||
|
expect(page.depends_on).to eq([{ "jointpur" => 1 }]) |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,40 @@ |
|||||||
|
require "rails_helper" |
||||||
|
|
||||||
|
RSpec.describe Form::Sales::Questions::Buyer1Mortgage, 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) } |
||||||
|
|
||||||
|
it "has correct page" do |
||||||
|
expect(question.page).to eq(page) |
||||||
|
end |
||||||
|
|
||||||
|
it "has the correct id" do |
||||||
|
expect(question.id).to eq("inc1mort") |
||||||
|
end |
||||||
|
|
||||||
|
it "has the correct header" do |
||||||
|
expect(question.header).to eq("Was buyer 1's income used for a mortgage application") |
||||||
|
end |
||||||
|
|
||||||
|
it "has the correct check_answer_label" do |
||||||
|
expect(question.check_answer_label).to eq("Buyer 1's income used for mortgage application") |
||||||
|
end |
||||||
|
|
||||||
|
it "has the correct type" do |
||||||
|
expect(question.type).to eq("radio") |
||||||
|
end |
||||||
|
|
||||||
|
it "is not marked as derived" do |
||||||
|
expect(question.derived?).to be false |
||||||
|
end |
||||||
|
|
||||||
|
it "has the correct answer_options" do |
||||||
|
expect(question.answer_options).to eq({ |
||||||
|
"1" => { "value" => "Yes" }, |
||||||
|
"2" => { "value" => "No" }, |
||||||
|
}) |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,55 @@ |
|||||||
|
require "rails_helper" |
||||||
|
|
||||||
|
RSpec.describe Form::Sales::Questions::Buyer2IncomeKnown, 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) } |
||||||
|
|
||||||
|
it "has correct page" do |
||||||
|
expect(question.page).to eq(page) |
||||||
|
end |
||||||
|
|
||||||
|
it "has the correct id" do |
||||||
|
expect(question.id).to eq("income2nk") |
||||||
|
end |
||||||
|
|
||||||
|
it "has the correct header" do |
||||||
|
expect(question.header).to eq("Do you know buyer 2’s annual income?") |
||||||
|
end |
||||||
|
|
||||||
|
it "has the correct check_answer_label" do |
||||||
|
expect(question.check_answer_label).to eq("Buyer 2’s gross annual income") |
||||||
|
end |
||||||
|
|
||||||
|
it "has the correct type" do |
||||||
|
expect(question.type).to eq("radio") |
||||||
|
end |
||||||
|
|
||||||
|
it "is not marked as derived" do |
||||||
|
expect(question.derived?).to be false |
||||||
|
end |
||||||
|
|
||||||
|
it "has the correct answer_options" do |
||||||
|
expect(question.answer_options).to eq({ |
||||||
|
"0" => { "value" => "Yes" }, |
||||||
|
"1" => { "value" => "No" }, |
||||||
|
}) |
||||||
|
end |
||||||
|
|
||||||
|
it "has correct conditional for" do |
||||||
|
expect(question.conditional_for).to eq({ |
||||||
|
"income2" => [0], |
||||||
|
}) |
||||||
|
end |
||||||
|
|
||||||
|
it "has the correct guidance_partial" do |
||||||
|
expect(question.guidance_partial).to eq("what_counts_as_income_sales") |
||||||
|
end |
||||||
|
|
||||||
|
it "has the correct guidance position", :aggregate_failures do |
||||||
|
expect(question.bottom_guidance?).to eq(true) |
||||||
|
expect(question.top_guidance?).to eq(false) |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,53 @@ |
|||||||
|
require "rails_helper" |
||||||
|
|
||||||
|
RSpec.describe Form::Sales::Questions::Buyer2Income, 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) } |
||||||
|
|
||||||
|
it "has correct page" do |
||||||
|
expect(question.page).to eq(page) |
||||||
|
end |
||||||
|
|
||||||
|
it "has the correct id" do |
||||||
|
expect(question.id).to eq("income2") |
||||||
|
end |
||||||
|
|
||||||
|
it "has the correct header" do |
||||||
|
expect(question.header).to eq("Buyer 2’s gross annual income") |
||||||
|
end |
||||||
|
|
||||||
|
it "has the correct check_answer_label" do |
||||||
|
expect(question.check_answer_label).to eq("Buyer 2’s gross annual income") |
||||||
|
end |
||||||
|
|
||||||
|
it "has the correct type" do |
||||||
|
expect(question.type).to eq("numeric") |
||||||
|
end |
||||||
|
|
||||||
|
it "is not marked as derived" do |
||||||
|
expect(question.derived?).to be false |
||||||
|
end |
||||||
|
|
||||||
|
it "has the correct hint" do |
||||||
|
expect(question.hint_text).to be_nil |
||||||
|
end |
||||||
|
|
||||||
|
it "has correct width" do |
||||||
|
expect(question.width).to eq(5) |
||||||
|
end |
||||||
|
|
||||||
|
it "has correct step" do |
||||||
|
expect(question.step).to eq(1) |
||||||
|
end |
||||||
|
|
||||||
|
it "has correct prefix" do |
||||||
|
expect(question.prefix).to eq("£") |
||||||
|
end |
||||||
|
|
||||||
|
it "has correct min" do |
||||||
|
expect(question.min).to eq(0) |
||||||
|
end |
||||||
|
end |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue