Skip to content

Commit

Permalink
Add the buyer journey for MCF4 (first pass)
Browse files Browse the repository at this point in the history
  • Loading branch information
tim-s-ccs committed Feb 17, 2025
1 parent dc3b913 commit 189d667
Show file tree
Hide file tree
Showing 49 changed files with 4,243 additions and 1,299 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.ccs-rates-table {
th:last-child,
td:last-child {
td {
text-align: right;
padding-left: govuk-spacing(2)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
module ManagementConsultancy
module RM6309
class SuppliersController < ManagementConsultancy::FrameworkController
helper :telephone_number
before_action :redirect_if_wrong_lot
before_action :fetch_suppliers, only: %i[index download]
before_action :set_back_path

def index
@journey = ManagementConsultancy::Journey.new(params[:framework], params[:slug], params)
@back_path = @journey.previous_step_path
@lot = Lot.find_by(number: params[:lot])
@suppliers = Kaminari.paginate_array(@all_suppliers).page(params[:page])
end

def show
@supplier = Supplier.find(params[:id])
@lot = Lot.find_by(number: params[:lot])
@rate_cards = if params[:lot] == 'MCF4.10'
RATE_TYPES[:'MCF4.10']
else
RATE_TYPES[:default]
end.index_with do |rate_type|
@supplier.rate_cards.where(lot: params[:lot], rate_type: rate_type).first
end
@lot_contact_detail = @supplier.lot_contact_details.where(lot: params[:lot]).first
end

def download
respond_to do |format|
format.html
format.xlsx do
spreadsheet_builder = SupplierSpreadsheetCreator.new(@all_suppliers, params)
spreadsheet = spreadsheet_builder.build
send_data spreadsheet.to_stream.read, filename: "shortlist_of_management_consultancy_suppliers_#{DateTime.now.getlocal.strftime '%d-%m-%Y'}.xlsx", type: :xlsx
end
end
end

private

def redirect_if_wrong_lot
redirect_to management_consultancy_rm6309_path unless params[:lot].starts_with?('MCF4')
end

def fetch_suppliers
@all_suppliers = Supplier.offering_services(
params[:lot],
params[:services],
).order(:name)
end

def set_back_path
@back_path = :back
end

RATE_TYPES = {
default: ['Advice', 'Delivery'],
'MCF4.10': ['Complex', 'Non-Complex']
}.freeze
end
end
end
3 changes: 3 additions & 0 deletions app/helpers/management_consultancy/rm6309/suppliers_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module ManagementConsultancy::RM6309::SuppliersHelper
include ManagementConsultancy::JourneyHelper
end
9 changes: 8 additions & 1 deletion app/models/management_consultancy/journey.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,14 @@ def start_path
def next_step_path
case next_slug
when 'suppliers'
management_consultancy_rm6187_suppliers_path(journey: self.class.journey_name, params: params)
case @framework
when 'RM6187'
management_consultancy_rm6187_suppliers_path(journey: self.class.journey_name, params: params)
when 'RM3609'
management_consultancy_rm6309_suppliers_path(journey: self.class.journey_name, params: params)
else
super
end
else
super
end
Expand Down
18 changes: 18 additions & 0 deletions app/models/management_consultancy/rm6309/journey/choose_lot.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module ManagementConsultancy
module RM6309
class Journey::ChooseLot
include Steppable

attribute :lot
validates :lot, inclusion: { in: Lot.all_numbers }

def self.mcf4_lots
Lot.where(framework: 'MCF4').sort_by { |lot| lot.number[5..].to_i }
end

def next_step_class
Journey::ChooseServices
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module ManagementConsultancy
module RM6309
class Journey::ChooseServices
include Steppable

attribute :services, Array
validates :services, length: { minimum: 1 }

def services_for_lot(lot_number)
Service.where(lot_number:).sort_by(&:code)
end

def lot(lot_number)
Lot.find_by(number: lot_number)
end

def next_step_class
Journey::Suppliers
end
end
end
end
7 changes: 7 additions & 0 deletions app/models/management_consultancy/rm6309/journey/suppliers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module ManagementConsultancy
module RM6309
class Journey::Suppliers
include Steppable
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
class ManagementConsultancy::RM6309::SupplierSpreadsheetCreator < SupplierSpreadsheetCreator
def initialize(suppliers, params)
super(suppliers, params, ManagementConsultancy::RM6309::Service)
end

def build
super do |shortlist_sheet, audit_sheet|
shortlist_sheet.add_row ['Supplier name', 'Contact name', 'Phone number', 'Email']
add_supplier_details(shortlist_sheet)

lot = ManagementConsultancy::RM6309::Lot.find_by(number: @params['lot'])
audit_sheet.add_row ['Lot', "#{lot.number} - #{lot.description}"]
add_services(audit_sheet)
end
end

private

def add_supplier_details(sheet)
@suppliers.each do |supplier|
lot_contact_detail = supplier.lot_contact_details.where(lot: @params['lot']).first
sheet.add_row(
[
supplier.name,
lot_contact_detail.contact_name,
supplier.telephone_number,
supplier.contact_email
]
)
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<%= add_optional_error_prefix_to_page_title(@journey.errors) %>

<%= content_for :page_title, t('.question') %>


<%= render partial: 'shared/error_summary', locals: { errors: @journey.errors } %>
<%= form_tag @form_path, method: :get do |f|%>
<%= hidden_fields_for_previous_steps_and_responses(@journey) %>
<h1 class="govuk-heading-xl">
<%= t('.question') %>
</h1>

<%= govuk_radios(
:lot,
ManagementConsultancy::RM6309::Journey::ChooseLot.mcf4_lots.map do |lot|
{
value: lot.number,
label: {
text: lot_number_and_description(lot.number,lot.description),
classes: 'govuk-!-font-weight-bold'
},
hint: {
text: govuk_details(t('.service_lines')) do
tag.ul(class: 'govuk-list') do
lot.services.each do |service|
concat(tag.li(service.name))
end
end
end
}
}
end,
model: @journey.current_step,
fieldset: {
legend: {
text: t('.mcf4_heading'),
classes: 'govuk-fieldset__legend--m'
}
}
) %>

<%= govuk_button(t('common.submit'), form: f, attributes: { name: t('common.submit') }) %>
<% end %>
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<%= content_for :page_title, t('.question') %>

<%= add_optional_error_prefix_to_page_title(@journey.errors) %>
<div class="govuk-grid-row">
<%= render partial: 'shared/error_summary', locals: { errors: @journey.errors } %>
<%= form_tag @form_path, method: :get do |f| %>
<%= hidden_fields_for_previous_steps_and_responses(@journey) %>

<div class="govuk-grid-column-two-thirds" id="selection-checkboxes">
<%= govuk_checkboxes(
:services,
@journey.current_step.services_for_lot(@journey.params['lot']).map do |service|
{
value: service.code,
label: {
text: service.name
},
attributes: {
id: "service_#{service.code.gsub('.', '-')}"
}
}
end,
model: @journey.current_step,
fieldset: {
legend: {
text: t('.question'),
classes: 'govuk-fieldset__legend--m',
is_page_heading: true,
caption: {
text: framework_lot_and_description(@journey.current_step.lot(params['lot']).number, @journey.current_step.lot(params['lot']).description),
classes: 'govuk-caption-m'
}
}
}
) %>
</div>
<div class="govuk-grid-column-one-third govuk-!-margin-top-9">
<%= render partial: 'shared/basket', locals: { form: f, data_text_1: t('.services_selected'), data_text_2: t('.no_services_selected'), data_text_3: t('.service_selected') } %>
</div>
<% end %>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<li>
<h2 class="govuk-heading-m">
<%= link_to supplier.name, management_consultancy_rm6309_supplier_path(id: supplier.id, lot: params[:lot]), class: "govuk-!-font-size-20 ccs-no-underline" %>
<% if supplier.sme? %>
<%= govuk_tag(t('sme'), 'grey', classes: 'ccs-tag') %>
<% end %>
</h2>
</li>
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<%= content_for :page_title, t('.heading') %>

<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<h1 class="govuk-heading-xl"><%= t('.heading') %></h1>
<p class="govuk-heading-m govuk-!-margin-bottom-8"><%= t('.lead_text') %></p>
<p class="govuk-body">
<%= link_to_generated_file_for_download(management_consultancy_rm6309_suppliers_download_path(lot: params[:lot], services: params[:services]), :xlsx, t('.download_supplier_shortlist'), true) %>
</p>

<h2 class="govuk-heading-m"><%= t('.other_documents') %></h2>

<ul class="govuk-list govuk-!-margin-top-6 govuk-section-break--visible">
<li class="govuk-!-margin-bottom-3">
<%= link_to_file_for_download(t('.expression_of_interest_template_link'), :odt, t('.expression_of_interest_template'), true) %>
</li>
</ul>
<%= link_to t('common.back_to_start'), management_consultancy_rm6309_path, class: 'govuk-!-margin-top-6 govuk-link govuk-!-font-size-19 govuk-link--no-visited-state' %>
</div>
</div>
40 changes: 40 additions & 0 deletions app/views/management_consultancy/rm6309/suppliers/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<div class="govuk-grid-row">
<div class="govuk-grid-column-full">
<span class="govuk-caption-xl">
<%= framework_lot_and_description(@lot.number, @lot.description) %>
</span>
<% if @all_suppliers.count.zero? %>
<%= content_for :page_title, t('.no_suppliers_found.heading') %>
<h1 class="govuk-heading-xl"><%= t('.no_suppliers_found.heading') %></h1>
<p class="govuk-body govuk-!-font-size-24">
<%=t('.no_suppliers_found.text') %>
</p>
<br>
<p class="govuk-body">
<%= t('.no_suppliers_found.contact_html', contact_link: link_to(t('.no_suppliers_found.contact_link_text'), 'https://www.crowncommercial.gov.uk/contact')) %>
</p>
<% else %>
<%= content_for :page_title, t('.heading') %>
<h1 class="govuk-heading-xl"><%= t('.heading') %></h1>
<p class="govuk-body">
<%= t('.suppliers_found_html',
number: @all_suppliers.count,
suppliers: number_to_human(@all_suppliers.count, units: :companies, format: '%u')) %>
</p>
<%= govuk_button(t('.download_suppliers_list'), href: management_consultancy_rm6309_suppliers_download_path(lot: params[:lot], services: params[:services])) %>
<br>
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds ccs-search-results">
<ul class="ccs-results-list">
<%= render partial: 'supplier', collection: @suppliers %>
</ul>
</div>
</div>
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<%= paginate @suppliers, views_prefix: 'shared', window: 2, outer_window: 1 %>
</div>
</div>
<% end %>
</div>
</div>
Loading

0 comments on commit 189d667

Please sign in to comment.