From 81e1c6a67f5d1e858eb66dbf6119eb54037b13eb Mon Sep 17 00:00:00 2001 From: Edwin Kruglov Date: Fri, 29 Sep 2023 17:08:57 +0100 Subject: [PATCH] feat: create case requests --- .../engagement/case_requests_controller.rb | 57 +++++ .../support/case_requests_controller.rb | 51 ++++ app/models/case_request.rb | 62 +++++ app/models/support/case.rb | 5 + app/models/support/establishment_group.rb | 4 + .../_new_case_request_components.html.erb | 50 ++++ .../engagement/case_requests/new.html.erb | 72 ++++++ app/views/engagement/cases/index.html.erb | 2 +- app/views/support/case_requests/new.html.erb | 22 ++ app/views/support/case_requests/show.html.erb | 242 ++++++++++++++++++ app/views/support/cases/index.html.erb | 2 +- config/locales/en.yml | 4 + config/locales/validation/en.yml | 29 +++ config/routes.rb | 9 + .../20230928103125_create_case_requests.rb | 28 ++ db/schema.rb | 38 ++- 16 files changed, 673 insertions(+), 4 deletions(-) create mode 100644 app/controllers/engagement/case_requests_controller.rb create mode 100644 app/controllers/support/case_requests_controller.rb create mode 100644 app/models/case_request.rb create mode 100644 app/views/components/_new_case_request_components.html.erb create mode 100644 app/views/engagement/case_requests/new.html.erb create mode 100644 app/views/support/case_requests/new.html.erb create mode 100644 app/views/support/case_requests/show.html.erb create mode 100644 db/migrate/20230928103125_create_case_requests.rb diff --git a/app/controllers/engagement/case_requests_controller.rb b/app/controllers/engagement/case_requests_controller.rb new file mode 100644 index 000000000..80947abdc --- /dev/null +++ b/app/controllers/engagement/case_requests_controller.rb @@ -0,0 +1,57 @@ +module Engagement + class CaseRequestsController < ApplicationController + before_action -> { @back_url = engagement_cases_path }, only: %i[new create] + + def new + @case_request = CaseRequest.new + @upload_reference = SecureRandom.hex + end + + def create + @case_request = CaseRequest.new(form_params.except(:upload_reference)) + @case_request.created_by = current_agent + + if @case_request.valid? + @case_request.save! + # kase = @case_request.create_case + + # CaseFiles::SubmitCaseUpload.new.call(upload_reference: form_params[:upload_reference], support_case_id: kase.id) + + # create_interaction(kase.id, "create_case", "Case created", @case_request.attributes.slice(:source, :category)) + + redirect_to @case_request.eligible_for_school_picker? ? edit_support_case_request_school_picker_path(@case_request) : engagement_case_request_path(@case_request) + else + render :new + end + end + + def submit + end + + private + + def form_params + params.require(:case_request).permit( + :organisation_id, + :organisation_type, + :first_name, + :last_name, + :email, + :phone_number, + :extension_number, + :discovery_method, + :discovery_method_other_text, + :category_id, + :query_id, + :request_text, + :other_category, + :other_query, + :procurement_amount, + :upload_reference, + ).merge({ + source: :engagement_and_outreach_cms.to_s, + creation_source: :engagement_and_outreach_team.to_s, + }) + end + end +end diff --git a/app/controllers/support/case_requests_controller.rb b/app/controllers/support/case_requests_controller.rb new file mode 100644 index 000000000..0d3b10d88 --- /dev/null +++ b/app/controllers/support/case_requests_controller.rb @@ -0,0 +1,51 @@ +module Support + class CaseRequestsController < ApplicationController + before_action -> { @back_url = support_cases_path }, only: %i[new create] + + def new + @case_request = CaseRequest.new + end + + def create + @case_request = CaseRequest.new(form_params.except(:upload_reference)) + @case_request.created_by = current_agent + + if @case_request.valid? + @case_request.save! + # kase = @case_request.create_case + + # create_interaction(kase.id, "create_case", "Case created", @case_request.attributes.slice(:source, :category)) + + redirect_to support_case_request_path(@case_request) + else + render :new + end + end + + def submit + end + + private + + def form_params + params.require(:case_request).permit( + :organisation_id, + :organisation_type, + :first_name, + :last_name, + :email, + :phone_number, + :extension_number, + :discovery_method, + :discovery_method_other_text, + :category_id, + :query_id, + :source, + :request_text, + :other_category, + :other_query, + :procurement_amount, + ) + end + end +end diff --git a/app/models/case_request.rb b/app/models/case_request.rb new file mode 100644 index 000000000..72b7b6a93 --- /dev/null +++ b/app/models/case_request.rb @@ -0,0 +1,62 @@ +class CaseRequest < ApplicationRecord + belongs_to :category, class_name: "Support::Category", optional: true + belongs_to :query, class_name: "Support::Query", optional: true + belongs_to :organisation, polymorphic: true, optional: true + belongs_to :created_by, class_name: "Support::Agent", optional: true + belongs_to :support_case, class_name: "Support::Case", optional: true + + enum source: { digital: 0, nw_hub: 1, sw_hub: 2, incoming_email: 3, faf: 4, engagement_and_outreach: 5, schools_commercial_team: 6, engagement_and_outreach_cms: 7 } + enum creation_source: { default: 0, engagement_and_outreach_team: 5 } + + validates :first_name, :last_name, :email, :source, presence: true + validates :phone_number, length: { maximum: 12 } + validates :phone_number, format: /\A(0|\+?44)[12378]\d{8,9}\z/, if: -> { phone_number.present? } + validate :discovery_method_validation + validates :discovery_method_other_text, presence: true, if: -> { discovery_method == Support::Case.discovery_methods[:other] } + validate :request_type_validation + validates :procurement_amount, presence: true, numericality: { greater_than: 0.99 } + validates :other_category, presence: true, if: -> { category_id == Support::Category.other_category_id } + validates :other_query, presence: true, if: -> { query_id == Support::Query.other_query_id } + + def organisation_name + return nil unless organisation + + organisation.name + end + + def organisation_urn + return nil unless organisation + + organisation.urn + end + + def request_type + return nil unless category.present? || query.present? + + category.present? + end + + def eligible_for_school_picker? + return false unless organisation.is_a?(Support::EstablishmentGroup) + + organisation.eligible_for_school_picker? + end + + def create_case + CreateCase.new(attributes).call + end + +private + + def request_type_validation + return if category.present? || query.present? + + errors.add(:request_type, I18n.t("case_requests.validation.request_type")) + end + + def discovery_method_validation + return if Support::Case.discovery_methods.value?(discovery_method) + + errors.add(:discovery_method, I18n.t("case_requests.validation.discovery_method")) + end +end diff --git a/app/models/support/case.rb b/app/models/support/case.rb index 3a42722d4..05cc65ce2 100644 --- a/app/models/support/case.rb +++ b/app/models/support/case.rb @@ -51,6 +51,7 @@ class Case < ApplicationRecord belongs_to :procurement_stage, class_name: "Support::ProcurementStage", optional: true has_one :framework_request, class_name: "FrameworkRequest", foreign_key: :support_case_id + has_one :case_request, class_name: "CaseRequest", foreign_key: :support_case_id accepts_nested_attributes_for :hub_transition, allow_destroy: true, reject_if: :all_blank @@ -146,5 +147,9 @@ def generate_ref def support_request interactions&.support_request&.first end + + def request + framework_request || case_request + end end end diff --git a/app/models/support/establishment_group.rb b/app/models/support/establishment_group.rb index cee0f320f..a373ebddf 100644 --- a/app/models/support/establishment_group.rb +++ b/app/models/support/establishment_group.rb @@ -18,4 +18,8 @@ def organisations end def mat_or_trust? = establishment_group_type.mat? || establishment_group_type.trust? + + def eligible_for_school_picker? + (mat_or_trust? || federation?) && organisations.count > 1 + end end diff --git a/app/views/components/_new_case_request_components.html.erb b/app/views/components/_new_case_request_components.html.erb new file mode 100644 index 000000000..1eb51d761 --- /dev/null +++ b/app/views/components/_new_case_request_components.html.erb @@ -0,0 +1,50 @@ +

+ <%= I18n.t("support.case.label.create") %> +

+<%= render "components/autocomplete", + container_id: "case-request-school-urn-field", + label_text: I18n.t("support.case_hub_migration.label.school_name"), + label_class: "govuk-hint", + element_id: "school-urn-autocomplete", + element_name: "case_request[organisation_name]", + template_suggestion: "{{name}}, {{postcode}}
{{establishment_type}}
URN: {{urn}} - UKPRN: {{ukprn}}", + value_field: :name, + default_value: form.object.organisation_name, + hidden_fields: { + 'case_request[organisation_id]' => [:id, form.object.organisation_id], + 'case_request[organisation_type]' => [:source, form.object.organisation_type], + 'case_request[organisation_urn]' => [:urn, form.object.organisation_urn], + }, + query_url: support_establishments_path(format: :json, q: "{{QUERY}}") %> + + + +<%= form.govuk_text_field :first_name, + label: { text: I18n.t("support.case_hub_migration.label.first_name") } +%> + +<%= form.govuk_text_field :last_name, + label: { text: I18n.t("support.case_hub_migration.label.last_name") } +%> + +<%= form.govuk_email_field :email, + label: { text: I18n.t("support.case_hub_migration.label.email") } +%> + +<%= form.govuk_phone_field :phone_number, + label: { text: I18n.t("support.case_hub_migration.label.phone_number", optional: I18n.t("support.generic.form.optional")) } +%> + +<%= form.govuk_phone_field :extension_number, + label: { text: I18n.t("support.case_hub_migration.label.extension_number", optional: I18n.t("support.generic.form.optional")) } +%> + +<%= render "support/cases/discovery_method/discovery_method", form: form %> + +<%= render "support/cases/request_details/form_fields", form: form, show_request_text: false %> + +<%= form.govuk_text_field :procurement_amount, width: 5, + label: { text: I18n.t("support.case.label.procurement_value"), size: "m" }, + prefix_text: "£" %> + + diff --git a/app/views/engagement/case_requests/new.html.erb b/app/views/engagement/case_requests/new.html.erb new file mode 100644 index 000000000..b86a4cfb7 --- /dev/null +++ b/app/views/engagement/case_requests/new.html.erb @@ -0,0 +1,72 @@ +
+
+ <%= form_with model: @case_request, scope: :case_request, url: engagement_case_requests_path, html: { + "data-controller" => "case-attachment", + "data-action" => "submit->case-attachment#onFormSubmitted", + "data-case-attachment-target" => "form", + "data-case-attachment-dropzone-outlet" => ".drop-zone-container", + "data-case-attachment-error-summary-outlet" => ".govuk-error-summary", + "data-case-attachment-reference-value" => @upload_reference + } do |form| %> + <%= form.govuk_error_summary %> + + <%= render "components/new_case_request_components", form: %> + +

+ <%= I18n.t("support.case.label.files") %> +

+
+
+
+
+

()

+ Remove +
+
+

+ +
+
+
+
+
+
+ +
+

Drag and drop files here or

+ + + Choose files + +
+ +
+
+

+ Files added +

+
+ +
+

+ Files already uploaded +

+
+
+
+ +
+ <%= form.hidden_field :upload_reference, :value => @upload_reference %> + <%= form.submit I18n.t("support.case_hub_migration.submit"), class: "govuk-button", role: "button", "data-prevent-double-click" => true, "data-case-attachment-target" => "btnSubmit" %> +
+ <% end %> +
+
diff --git a/app/views/engagement/cases/index.html.erb b/app/views/engagement/cases/index.html.erb index 46b399b92..0bd38794e 100644 --- a/app/views/engagement/cases/index.html.erb +++ b/app/views/engagement/cases/index.html.erb @@ -1,4 +1,4 @@ -<%= link_to I18n.t("support.case.label.create"), new_engagement_case_path, class: "govuk-button", role: "button" %> +<%= link_to I18n.t("support.case.label.create"), new_engagement_case_request_path, class: "govuk-button", role: "button" %>