James Rose
2 years ago
committed by
GitHub
191 changed files with 3887 additions and 1319 deletions
@ -1,18 +1,18 @@
|
||||
class CheckAnswersSummaryListCardComponent < ViewComponent::Base |
||||
attr_reader :questions, :lettings_log, :user |
||||
attr_reader :questions, :log, :user |
||||
|
||||
def initialize(questions:, lettings_log:, user:) |
||||
def initialize(questions:, log:, user:) |
||||
@questions = questions |
||||
@lettings_log = lettings_log |
||||
@log = log |
||||
@user = user |
||||
super |
||||
end |
||||
|
||||
def applicable_questions |
||||
questions.reject { |q| q.hidden_in_check_answers?(lettings_log, user) } |
||||
questions.reject { |q| q.hidden_in_check_answers?(log, user) } |
||||
end |
||||
|
||||
def get_answer_label(question) |
||||
question.answer_label(lettings_log).presence || "<span class=\"app-!-colour-muted\">You didn’t answer this question</span>".html_safe |
||||
question.answer_label(log).presence || "<span class=\"app-!-colour-muted\">You didn’t answer this question</span>".html_safe |
||||
end |
||||
end |
||||
|
@ -0,0 +1,73 @@
|
||||
class LogsController < ApplicationController |
||||
include Pagy::Backend |
||||
include Modules::LogsFilter |
||||
include Modules::SearchFilter |
||||
|
||||
skip_before_action :verify_authenticity_token, if: :json_api_request? |
||||
before_action :authenticate, if: :json_api_request? |
||||
before_action :authenticate_user!, unless: :json_api_request? |
||||
|
||||
private |
||||
|
||||
def create |
||||
log = yield |
||||
raise "Caller must pass a block that implements model creation" if log.blank? |
||||
|
||||
respond_to do |format| |
||||
format.html do |
||||
log.save! |
||||
redirect_to post_create_redirect_url(log) |
||||
end |
||||
format.json do |
||||
if log.save |
||||
render json: log, status: :created |
||||
else |
||||
render json: { errors: log.errors.messages }, status: :unprocessable_entity |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
def post_create_redirect_url |
||||
raise "implement in sub class" |
||||
end |
||||
|
||||
API_ACTIONS = %w[create show update destroy].freeze |
||||
|
||||
def json_api_request? |
||||
API_ACTIONS.include?(request["action"]) && request.format.json? |
||||
end |
||||
|
||||
def authenticate |
||||
http_basic_authenticate_or_request_with name: ENV["API_USER"], password: ENV["API_KEY"] |
||||
end |
||||
|
||||
def log_params |
||||
if current_user && !current_user.support? |
||||
org_params.merge(api_log_params) |
||||
else |
||||
api_log_params |
||||
end |
||||
end |
||||
|
||||
def api_log_params |
||||
return {} unless params[:lettings_log] || params[:sales_log] |
||||
|
||||
permitted = permitted_log_params |
||||
owning_id = permitted["owning_organisation_id"] |
||||
permitted["owning_organisation"] = Organisation.find(owning_id) if owning_id |
||||
permitted |
||||
end |
||||
|
||||
def org_params |
||||
{ |
||||
"owning_organisation_id" => current_user.organisation.id, |
||||
"managing_organisation_id" => current_user.organisation.id, |
||||
"created_by_id" => current_user.id, |
||||
} |
||||
end |
||||
|
||||
def search_term |
||||
params["search"] |
||||
end |
||||
end |
@ -1,23 +0,0 @@
|
||||
module Modules::LettingsLogsFilter |
||||
def filtered_lettings_logs(logs) |
||||
if session[:lettings_logs_filters].present? |
||||
filters = JSON.parse(session[:lettings_logs_filters]) |
||||
filters.each do |category, values| |
||||
next if Array(values).reject(&:empty?).blank? |
||||
next if category == "organisation" && params["organisation_select"] == "all" |
||||
|
||||
logs = logs.public_send("filter_by_#{category}", values, current_user) |
||||
end |
||||
end |
||||
logs = logs.order(created_at: :desc) |
||||
current_user.support? ? logs.all.includes(:owning_organisation, :managing_organisation) : logs |
||||
end |
||||
|
||||
def set_session_filters(specific_org: false) |
||||
new_filters = session[:lettings_logs_filters].present? ? JSON.parse(session[:lettings_logs_filters]) : {} |
||||
current_user.lettings_logs_filters(specific_org:).each { |filter| new_filters[filter] = params[filter] if params[filter].present? } |
||||
new_filters = new_filters.except("organisation") if params["organisation_select"] == "all" |
||||
|
||||
session[:lettings_logs_filters] = new_filters.to_json |
||||
end |
||||
end |
@ -0,0 +1,21 @@
|
||||
module Modules::LogsFilter |
||||
def filtered_logs(logs, search_term, filters) |
||||
all_orgs = params["organisation_select"] == "all" |
||||
FilterService.filter_logs(logs, search_term, filters, all_orgs, current_user) |
||||
end |
||||
|
||||
def load_session_filters(specific_org: false) |
||||
current_filters = session[:logs_filters] |
||||
new_filters = current_filters.present? ? JSON.parse(current_filters) : {} |
||||
current_user.logs_filters(specific_org:).each { |filter| new_filters[filter] = params[filter] if params[filter].present? } |
||||
params["organisation_select"] == "all" ? new_filters.except("organisation") : new_filters |
||||
end |
||||
|
||||
def session_filters(specific_org: false) |
||||
@session_filters ||= load_session_filters(specific_org:) |
||||
end |
||||
|
||||
def set_session_filters |
||||
session[:logs_filters] = @session_filters.to_json |
||||
end |
||||
end |
@ -1,13 +1,9 @@
|
||||
module Modules::SearchFilter |
||||
def filtered_collection(base_collection, search_term = nil) |
||||
if search_term.present? |
||||
base_collection.search_by(search_term) |
||||
else |
||||
base_collection |
||||
end |
||||
FilterService.filter_by_search(base_collection, search_term) |
||||
end |
||||
|
||||
def filtered_users(base_collection, search_term = nil) |
||||
filtered_collection(base_collection, search_term).includes(:organisation) |
||||
FilterService.filter_by_search(base_collection, search_term).includes(:organisation) |
||||
end |
||||
end |
||||
|
@ -0,0 +1,46 @@
|
||||
class SalesLogsController < LogsController |
||||
before_action :session_filters, if: :current_user |
||||
before_action :set_session_filters, if: :current_user |
||||
|
||||
def create |
||||
super { SalesLog.new(log_params) } |
||||
end |
||||
|
||||
def index |
||||
respond_to do |format| |
||||
format.html do |
||||
all_logs = current_user.sales_logs |
||||
unpaginated_filtered_logs = filtered_logs(all_logs, search_term, @session_filters) |
||||
|
||||
@search_term = search_term |
||||
@pagy, @logs = pagy(unpaginated_filtered_logs) |
||||
@searched = search_term.presence |
||||
@total_count = all_logs.size |
||||
render "logs/index" |
||||
end |
||||
end |
||||
end |
||||
|
||||
def show |
||||
respond_to do |format| |
||||
format.html { edit } |
||||
end |
||||
end |
||||
|
||||
def edit |
||||
@log = current_user.sales_logs.find_by(id: params[:id]) |
||||
if @log |
||||
render "logs/edit", locals: { current_user: } |
||||
else |
||||
render_not_found |
||||
end |
||||
end |
||||
|
||||
def post_create_redirect_url(log) |
||||
sales_log_url(log) |
||||
end |
||||
|
||||
def permitted_log_params |
||||
params.require(:sales_log).permit(SalesLog.editable_fields) |
||||
end |
||||
end |
@ -0,0 +1,21 @@
|
||||
class EmailCsvJob < ApplicationJob |
||||
queue_as :default |
||||
|
||||
BYTE_ORDER_MARK = "\uFEFF".freeze # Required to ensure Excel always reads CSV as UTF-8 |
||||
|
||||
EXPIRATION_TIME = 3.hours.to_i |
||||
|
||||
def perform(user, search_term = nil, filters = {}, all_orgs = false, organisation = nil) # rubocop:disable Style/OptionalBooleanParameter - sidekiq can't serialise named params |
||||
unfiltered_logs = organisation.present? && user.support? ? LettingsLog.where(owning_organisation_id: organisation.id) : user.lettings_logs |
||||
filtered_logs = FilterService.filter_logs(unfiltered_logs, search_term, filters, all_orgs, user) |
||||
|
||||
filename = organisation.present? ? "logs-#{organisation.name}-#{Time.zone.now}.csv" : "logs-#{Time.zone.now}.csv" |
||||
|
||||
storage_service = Storage::S3Service.new(Configuration::EnvConfigurationService.new, ENV["CSV_DOWNLOAD_PAAS_INSTANCE"]) |
||||
storage_service.write_file(filename, BYTE_ORDER_MARK + filtered_logs.to_csv(user)) |
||||
|
||||
url = storage_service.get_presigned_url(filename, EXPIRATION_TIME) |
||||
|
||||
CsvDownloadMailer.new.send_csv_download_mail(user, url, EXPIRATION_TIME) |
||||
end |
||||
end |
@ -0,0 +1,11 @@
|
||||
class CsvDownloadMailer < NotifyMailer |
||||
CSV_DOWNLOAD_TEMPLATE_ID = "7890e3b9-8c0d-4d08-bafe-427fd7cd95bf".freeze |
||||
|
||||
def send_csv_download_mail(user, link, duration) |
||||
send_email( |
||||
user.email, |
||||
CSV_DOWNLOAD_TEMPLATE_ID, |
||||
{ name: user.name, link:, duration: ActiveSupport::Duration.build(duration).inspect }, |
||||
) |
||||
end |
||||
end |
@ -0,0 +1,37 @@
|
||||
class NotifyMailer |
||||
require "notifications/client" |
||||
|
||||
def notify_client |
||||
@notify_client ||= ::Notifications::Client.new(ENV["GOVUK_NOTIFY_API_KEY"]) |
||||
end |
||||
|
||||
def send_email(email, template_id, personalisation) |
||||
return true if intercept_send?(email) |
||||
|
||||
notify_client.send_email( |
||||
email_address: email, |
||||
template_id:, |
||||
personalisation:, |
||||
) |
||||
end |
||||
|
||||
def personalisation(record, token, url, username: false) |
||||
{ |
||||
name: record.name || record.email, |
||||
email: username || record.email, |
||||
organisation: record.respond_to?(:organisation) ? record.organisation.name : "", |
||||
link: "#{url}#{token}", |
||||
} |
||||
end |
||||
|
||||
def intercept_send?(email) |
||||
return false unless email_allowlist |
||||
|
||||
email_domain = email.split("@").last.downcase |
||||
!(Rails.env.production? || Rails.env.test?) && email_allowlist.exclude?(email_domain) |
||||
end |
||||
|
||||
def email_allowlist |
||||
Rails.application.credentials[:email_allowlist] |
||||
end |
||||
end |
@ -1,4 +1,4 @@
|
||||
class Form::Setup::Questions::IrproductOther < ::Form::Question |
||||
class Form::Lettings::Questions::IrproductOther < ::Form::Question |
||||
def initialize(id, hsh, page) |
||||
super |
||||
@id = "irproduct_other" |
@ -1,4 +1,4 @@
|
||||
class Form::Setup::Questions::LocationId < ::Form::Question |
||||
class Form::Lettings::Questions::LocationId < ::Form::Question |
||||
def initialize(_id, hsh, page) |
||||
super("location_id", hsh, page) |
||||
@check_answer_label = "Location" |
@ -1,4 +1,4 @@
|
||||
class Form::Setup::Questions::NeedsType < ::Form::Question |
||||
class Form::Lettings::Questions::NeedsType < ::Form::Question |
||||
def initialize(id, hsh, page) |
||||
super |
||||
@id = "needstype" |
@ -1,4 +1,4 @@
|
||||
class Form::Setup::Questions::PropertyReference < ::Form::Question |
||||
class Form::Lettings::Questions::PropertyReference < ::Form::Question |
||||
def initialize(id, hsh, page) |
||||
super |
||||
@id = "propcode" |
@ -1,4 +1,4 @@
|
||||
class Form::Setup::Questions::Renewal < ::Form::Question |
||||
class Form::Lettings::Questions::Renewal < ::Form::Question |
||||
def initialize(id, hsh, page) |
||||
super |
||||
@id = "renewal" |
@ -1,4 +1,4 @@
|
||||
class Form::Setup::Questions::RentType < ::Form::Question |
||||
class Form::Lettings::Questions::RentType < ::Form::Question |
||||
def initialize(id, hsh, page) |
||||
super |
||||
@id = "rent_type" |
@ -1,4 +1,4 @@
|
||||
class Form::Setup::Questions::SchemeId < ::Form::Question |
||||
class Form::Lettings::Questions::SchemeId < ::Form::Question |
||||
def initialize(_id, hsh, page) |
||||
super("scheme_id", hsh, page) |
||||
@check_answer_label = "Scheme name" |
@ -1,4 +1,4 @@
|
||||
class Form::Setup::Questions::TenancyStartDate < ::Form::Question |
||||
class Form::Lettings::Questions::TenancyStartDate < ::Form::Question |
||||
def initialize(id, hsh, page) |
||||
super |
||||
@id = "startdate" |
@ -1,4 +1,4 @@
|
||||
class Form::Setup::Questions::TenantCode < ::Form::Question |
||||
class Form::Lettings::Questions::TenantCode < ::Form::Question |
||||
def initialize(id, hsh, page) |
||||
super |
||||
@id = "tenancycode" |
@ -1,10 +1,10 @@
|
||||
class Form::Sections::Setup < ::Form::Section |
||||
class Form::Lettings::Sections::Setup < ::Form::Section |
||||
def initialize(id, hsh, form) |
||||
super |
||||
@id = "setup" |
||||
@label = "Before you start" |
||||
@description = "" |
||||
@form = form |
||||
@subsections = [Form::Setup::Subsections::Setup.new(nil, nil, self)] |
||||
@subsections = [Form::Lettings::Subsections::Setup.new(nil, nil, self)] |
||||
end |
||||
end |
@ -0,0 +1,37 @@
|
||||
class Form::Lettings::Subsections::Setup < ::Form::Subsection |
||||
def initialize(id, hsh, section) |
||||
super |
||||
@id = "setup" |
||||
@label = "Set up this lettings log" |
||||
@section = section |
||||
end |
||||
|
||||
def pages |
||||
@pages ||= [ |
||||
Form::Common::Pages::Organisation.new(nil, nil, self), |
||||
Form::Common::Pages::CreatedBy.new(nil, nil, self), |
||||
Form::Lettings::Pages::NeedsType.new(nil, nil, self), |
||||
Form::Lettings::Pages::Scheme.new(nil, nil, self), |
||||
Form::Lettings::Pages::Location.new(nil, nil, self), |
||||
Form::Lettings::Pages::Renewal.new(nil, nil, self), |
||||
Form::Lettings::Pages::TenancyStartDate.new(nil, nil, self), |
||||
Form::Lettings::Pages::RentType.new(nil, nil, self), |
||||
Form::Lettings::Pages::TenantCode.new(nil, nil, self), |
||||
Form::Lettings::Pages::PropertyReference.new(nil, nil, self), |
||||
] |
||||
end |
||||
|
||||
def applicable_questions(lettings_log) |
||||
questions.select { |q| support_only_questions.include?(q.id) } + super |
||||
end |
||||
|
||||
def enabled?(_lettings_log) |
||||
true |
||||
end |
||||
|
||||
private |
||||
|
||||
def support_only_questions |
||||
%w[owning_organisation_id created_by_id].freeze |
||||
end |
||||
end |
@ -0,0 +1,15 @@
|
||||
class Form::Sales::Pages::PurchaserCode < ::Form::Page |
||||
def initialize(id, hsh, subsection) |
||||
super |
||||
@id = "purchaser_code" |
||||
@header = "" |
||||
@description = "" |
||||
@subsection = subsection |
||||
end |
||||
|
||||
def questions |
||||
@questions ||= [ |
||||
Form::Sales::Questions::PurchaserCode.new(nil, nil, self), |
||||
] |
||||
end |
||||
end |
@ -0,0 +1,15 @@
|
||||
class Form::Sales::Pages::SaleDate < ::Form::Page |
||||
def initialize(id, hsh, subsection) |
||||
super |
||||
@id = "completion_date" |
||||
@header = "" |
||||
@description = "" |
||||
@subsection = subsection |
||||
end |
||||
|
||||
def questions |
||||
@questions ||= [ |
||||
Form::Sales::Questions::SaleDate.new(nil, nil, self), |
||||
] |
||||
end |
||||
end |
@ -0,0 +1,18 @@
|
||||
class Form::Sales::Pages::SharedOwnershipType < ::Form::Page |
||||
def initialize(id, hsh, subsection) |
||||
super |
||||
@id = "shared_ownership_type" |
||||
@header = "" |
||||
@description = "" |
||||
@subsection = subsection |
||||
@depends_on = [{ |
||||
"ownershipsch" => 1, |
||||
}] |
||||
end |
||||
|
||||
def questions |
||||
@questions ||= [ |
||||
Form::Sales::Questions::SharedOwnershipType.new(nil, nil, self), |
||||
] |
||||
end |
||||
end |
@ -0,0 +1,12 @@
|
||||
class Form::Sales::Questions::PurchaserCode < ::Form::Question |
||||
def initialize(id, hsh, page) |
||||
super |
||||
@id = "purchid" |
||||
@check_answer_label = "Purchaser code" |
||||
@header = "What is the purchaser code?" |
||||
@hint_text = "This is how you usually refer to the purchaser on your own systems." |
||||
@type = "text" |
||||
@width = 10 |
||||
@page = page |
||||
end |
||||
end |
@ -0,0 +1,10 @@
|
||||
class Form::Sales::Questions::SaleDate < ::Form::Question |
||||
def initialize(id, hsh, page) |
||||
super |
||||
@id = "saledate" |
||||
@check_answer_label = "Sale completion date" |
||||
@header = "What is the sale completion date?" |
||||
@type = "date" |
||||
@page = page |
||||
end |
||||
end |
@ -0,0 +1,22 @@
|
||||
class Form::Sales::Questions::SharedOwnershipType < ::Form::Question |
||||
def initialize(id, hsh, page) |
||||
super |
||||
@id = "type" |
||||
@check_answer_label = "Type of shared ownership sale" |
||||
@header = "What is the type of shared ownership sale?" |
||||
@hint_text = "A shared ownership sale is when the purchaser buys up to 75% of the property value and pays rent to the Private Registered Provider (PRP) on the remaining portion" |
||||
@type = "radio" |
||||
@answer_options = ANSWER_OPTIONS |
||||
@page = page |
||||
end |
||||
|
||||
ANSWER_OPTIONS = { |
||||
"2" => { "value" => "Shared Ownership" }, |
||||
"24" => { "value" => "Old Persons Shared Ownership" }, |
||||
"18" => { "value" => "Social HomeBuy (shared ownership purchase)" }, |
||||
"16" => { "value" => "Home Ownership for people with Long Term Disabilities (HOLD)" }, |
||||
"28" => { "value" => "Rent to Buy - Shared Ownership" }, |
||||
"31" => { "value" => "Right to Shared Ownership" }, |
||||
"30" => { "value" => "Shared Ownership - 2021 model lease" }, |
||||
}.freeze |
||||
end |
@ -0,0 +1,10 @@
|
||||
class Form::Sales::Sections::Setup < ::Form::Section |
||||
def initialize(id, hsh, form) |
||||
super |
||||
@id = "setup" |
||||
@label = "Before you start" |
||||
@description = "" |
||||
@form = form |
||||
@subsections = [Form::Sales::Subsections::Setup.new(nil, nil, self)] || [] |
||||
end |
||||
end |
@ -0,0 +1,18 @@
|
||||
class Form::Sales::Subsections::Setup < ::Form::Subsection |
||||
def initialize(id, hsh, section) |
||||
super |
||||
@id = "setup" |
||||
@label = "Set up this sales log" |
||||
@section = section |
||||
end |
||||
|
||||
def pages |
||||
@pages ||= [ |
||||
Form::Common::Pages::Organisation.new(nil, nil, self), |
||||
Form::Common::Pages::CreatedBy.new(nil, nil, self), |
||||
Form::Sales::Pages::SaleDate.new(nil, nil, self), |
||||
Form::Sales::Pages::PurchaserCode.new(nil, nil, self), |
||||
Form::Sales::Pages::SharedOwnershipType.new(nil, nil, self), |
||||
] |
||||
end |
||||
end |
@ -1,37 +0,0 @@
|
||||
class Form::Subsections::Setup < ::Form::Subsection |
||||
def initialize(id, hsh, section) |
||||
super |
||||
@id = "setup" |
||||
@label = "Set up this lettings log" |
||||
@section = section |
||||
end |
||||
|
||||
def pages |
||||
@pages ||= [ |
||||
Form::Setup::Pages::Organisation.new(nil, nil, self), |
||||
Form::Setup::Pages::CreatedBy.new(nil, nil, self), |
||||
Form::Setup::Pages::NeedsType.new(nil, nil, self), |
||||
Form::Setup::Pages::Scheme.new(nil, nil, self), |
||||
Form::Setup::Pages::Location.new(nil, nil, self), |
||||
Form::Setup::Pages::Renewal.new(nil, nil, self), |
||||
Form::Setup::Pages::TenancyStartDate.new(nil, nil, self), |
||||
Form::Setup::Pages::RentType.new(nil, nil, self), |
||||
Form::Setup::Pages::TenantCode.new(nil, nil, self), |
||||
Form::Setup::Pages::PropertyReference.new(nil, nil, self), |
||||
] |
||||
end |
||||
|
||||
def applicable_questions(lettings_log) |
||||
questions.select { |q| support_only_questions.include?(q.id) } + super |
||||
end |
||||
|
||||
def enabled?(_lettings_log) |
||||
true |
||||
end |
||||
|
||||
private |
||||
|
||||
def support_only_questions |
||||
%w[owning_organisation_id created_by_id].freeze |
||||
end |
||||
end |
@ -0,0 +1,73 @@
|
||||
class Log < ApplicationRecord |
||||
self.abstract_class = true |
||||
|
||||
belongs_to :owning_organisation, class_name: "Organisation", optional: true |
||||
belongs_to :managing_organisation, class_name: "Organisation", optional: true |
||||
belongs_to :created_by, class_name: "User", optional: true |
||||
before_save :update_status! |
||||
|
||||
STATUS = { "not_started" => 0, "in_progress" => 1, "completed" => 2 }.freeze |
||||
enum status: STATUS |
||||
|
||||
scope :filter_by_organisation, ->(org, _user = nil) { where(owning_organisation: org).or(where(managing_organisation: org)) } |
||||
scope :filter_by_status, ->(status, _user = nil) { where status: } |
||||
scope :filter_by_years, lambda { |years, _user = nil| |
||||
first_year = years.shift |
||||
query = filter_by_year(first_year) |
||||
years.each { |year| query = query.or(filter_by_year(year)) } |
||||
query.all |
||||
} |
||||
scope :filter_by_id, ->(id) { where(id:) } |
||||
scope :filter_by_user, lambda { |selected_user, user| |
||||
if !selected_user.include?("all") && user.present? |
||||
where(created_by: user) |
||||
end |
||||
} |
||||
|
||||
def collection_start_year |
||||
return @start_year if @start_year |
||||
return unless startdate |
||||
|
||||
window_end_date = Time.zone.local(startdate.year, 4, 1) |
||||
@start_year = startdate < window_end_date ? startdate.year - 1 : startdate.year |
||||
end |
||||
|
||||
def lettings? |
||||
false |
||||
end |
||||
|
||||
private |
||||
|
||||
def update_status! |
||||
self.status = if all_fields_completed? && errors.empty? |
||||
"completed" |
||||
elsif all_fields_nil? |
||||
"not_started" |
||||
else |
||||
"in_progress" |
||||
end |
||||
end |
||||
|
||||
def all_fields_completed? |
||||
subsection_statuses = form.subsections.map { |subsection| subsection.status(self) }.uniq |
||||
subsection_statuses == [:completed] |
||||
end |
||||
|
||||
def all_fields_nil? |
||||
not_started_statuses = %i[not_started cannot_start_yet] |
||||
subsection_statuses = form.subsections.map { |subsection| subsection.status(self) }.uniq |
||||
subsection_statuses.all? { |status| not_started_statuses.include?(status) } |
||||
end |
||||
|
||||
def reset_created_by |
||||
return unless created_by && owning_organisation |
||||
|
||||
self.created_by = nil if created_by.organisation != owning_organisation |
||||
end |
||||
|
||||
def reset_invalidated_dependent_fields! |
||||
return unless form |
||||
|
||||
form.reset_not_routed_questions(self) |
||||
end |
||||
end |
@ -1,5 +1,5 @@
|
||||
class RentPeriod |
||||
def self.rent_period_mappings |
||||
FormHandler.instance.current_form.get_question("period", nil).answer_options |
||||
FormHandler.instance.current_lettings_form.get_question("period", nil).answer_options |
||||
end |
||||
end |
||||
|
@ -0,0 +1,45 @@
|
||||
class SalesLogValidator < ActiveModel::Validator |
||||
def validate(record); end |
||||
end |
||||
|
||||
class SalesLog < Log |
||||
self.inheritance_column = :_type_disabled |
||||
has_paper_trail |
||||
|
||||
validates_with SalesLogValidator |
||||
|
||||
scope :filter_by_year, ->(year) { where(saledate: Time.zone.local(year.to_i, 4, 1)...Time.zone.local(year.to_i + 1, 4, 1)) } |
||||
scope :search_by, ->(param) { filter_by_id(param) } |
||||
|
||||
OPTIONAL_FIELDS = [].freeze |
||||
|
||||
def startdate |
||||
saledate |
||||
end |
||||
|
||||
def self.editable_fields |
||||
attribute_names |
||||
end |
||||
|
||||
def form_name |
||||
return unless saledate |
||||
|
||||
FormHandler.instance.form_name_from_start_year(collection_start_year, "sales") |
||||
end |
||||
|
||||
def form |
||||
FormHandler.instance.get_form(form_name) || FormHandler.instance.current_sales_form |
||||
end |
||||
|
||||
def optional_fields |
||||
[] |
||||
end |
||||
|
||||
def not_started? |
||||
status == "not_started" |
||||
end |
||||
|
||||
def completed? |
||||
status == "completed" |
||||
end |
||||
end |
@ -0,0 +1,22 @@
|
||||
class FilterService |
||||
def self.filter_by_search(base_collection, search_term = nil) |
||||
if search_term.present? |
||||
base_collection.search_by(search_term) |
||||
else |
||||
base_collection |
||||
end |
||||
end |
||||
|
||||
def self.filter_logs(logs, search_term, filters, all_orgs, user) |
||||
logs = filter_by_search(logs, search_term) |
||||
|
||||
filters.each do |category, values| |
||||
next if Array(values).reject(&:empty?).blank? |
||||
next if category == "organisation" && all_orgs |
||||
|
||||
logs = logs.public_send("filter_by_#{category}", values, user) |
||||
end |
||||
logs = logs.order(created_at: :desc) |
||||
user.support? ? logs.all.includes(:owning_organisation, :managing_organisation) : logs |
||||
end |
||||
end |
@ -1,8 +1,7 @@
|
||||
<h2 class="govuk-body"> |
||||
<%= render(SearchResultCaptionComponent.new(searched:, count: pagy.count, item_label:, total_count:, item: "logs", path: request.path)) %> |
||||
<%= govuk_link_to "Download (CSV)", "#{request.path}.csv", type: "text/csv" %> |
||||
<%= govuk_link_to "Download (CSV)", csv_download_url, type: "text/csv" %> |
||||
</h2> |
||||
|
||||
<% lettings_logs.map do |log| %> |
||||
<% logs.map do |log| %> |
||||
<%= render(LogSummaryComponent.new(current_user:, log:)) %> |
||||
<% end %> |
@ -0,0 +1,15 @@
|
||||
<% content_for :title, "We’re sending you an email" %> |
||||
<div class="govuk-grid-row"> |
||||
<div class="govuk-grid-column-two-thirds"> |
||||
<%= govuk_panel(title_text: "We’re sending you an email") %> |
||||
|
||||
<p class="govuk-body">It should arrive in a few minutes, but it could take longer.</p> |
||||
|
||||
<h2 class="govuk-heading-m">What happens next</h2> |
||||
<p class="govuk-body">Open your email inbox and click the link to download your CSV file.</p> |
||||
|
||||
<p class="govuk-body"> |
||||
<%= govuk_link_to "Return to logs", lettings_logs_path %> |
||||
</p> |
||||
</div> |
||||
</div> |
@ -0,0 +1,16 @@
|
||||
<% content_for :title, "Download CSV" %> |
||||
|
||||
<% content_for :before_content do %> |
||||
<%= govuk_back_link(href: :back) %> |
||||
<% end %> |
||||
|
||||
<div class="govuk-grid-row"> |
||||
<div class="govuk-grid-column-two-thirds"> |
||||
<h1 class="govuk-heading-l">Download CSV</h2> |
||||
|
||||
<p class="govuk-body">We'll send a secure download link to your email address <strong><%= @current_user.email %></strong>.</p> |
||||
<p class="govuk-body">You've selected <%= count %> logs.</p> |
||||
|
||||
<%= govuk_button_to "Send email", post_path, method: :post, params: { search: search_term } %> |
||||
</div> |
||||
</div> |
@ -0,0 +1,11 @@
|
||||
if Rails.env.staging? || Rails.env.production? |
||||
redis_url = Configuration::PaasConfigurationService.new.redis_uris[:"dluhc-core-#{Rails.env}-redis"] |
||||
|
||||
Sidekiq.configure_server do |config| |
||||
config.redis = { url: redis_url } |
||||
end |
||||
|
||||
Sidekiq.configure_client do |config| |
||||
config.redis = { url: redis_url } |
||||
end |
||||
end |
@ -0,0 +1,12 @@
|
||||
class AddSalesLog < ActiveRecord::Migration[7.0] |
||||
def change |
||||
create_table :sales_logs do |t| |
||||
t.integer :status, default: 0 |
||||
t.datetime :saledate |
||||
t.timestamps |
||||
t.references :owning_organisation, class_name: "Organisation", foreign_key: { to_table: :organisations, on_delete: :cascade } |
||||
t.references :managing_organisation, class_name: "Organisation" |
||||
t.references :created_by, class_name: "User" |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,5 @@
|
||||
class AddPurchid < ActiveRecord::Migration[7.0] |
||||
def change |
||||
add_column :sales_logs, :purchid, :string |
||||
end |
||||
end |
@ -0,0 +1,5 @@
|
||||
class AddSharedOwnershipType < ActiveRecord::Migration[7.0] |
||||
def change |
||||
add_column :sales_logs, :type, :integer |
||||
end |
||||
end |
@ -0,0 +1,5 @@
|
||||
class AddOwnershipSchemeToSalesLog < ActiveRecord::Migration[7.0] |
||||
def change |
||||
add_column :sales_logs, :ownershipsch, :integer |
||||
end |
||||
end |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue