diff --git a/app/controllers/support/cases/additional_contacts_controller.rb b/app/controllers/support/cases/additional_contacts_controller.rb index f7d543cdd..f55faaf02 100644 --- a/app/controllers/support/cases/additional_contacts_controller.rb +++ b/app/controllers/support/cases/additional_contacts_controller.rb @@ -8,34 +8,35 @@ class Cases::AdditionalContactsController < Cases::ApplicationController def index; end def new - @additional_contact = @current_case&.case_additional_contacts&.build + @case_additional_contact_form = CaseAdditionalContactForm.new(@current_case) end def create - @current_case = Support::Case.find(additional_contact_params[:support_case_id]) if @current_case.blank? - @additional_contact = Support::CaseAdditionalContact.build(additional_contact_params) - - if validation.success? && !@emails.include?(additional_contact_params[:email]) - @additional_contact.save! + @case_additional_contact_form = CaseAdditionalContactForm.from_validation(validation) + @current_case = Support::Case.find(case_additional_contact_form_params[:support_case_id]) if @current_case.blank? + @emails = @current_case.case_additional_contacts&.pluck(:email) + if validation.success? && !@emails.include?(case_additional_contact_form_params[:email]) + Support::CaseAdditionalContact.create!(case_additional_contact_form_params) redirect_to support_case_additional_contacts_path(case_id: @current_case.id), notice: I18n.t("support.case_contact_details.flash.success") else - flash.now[:notice] = I18n.t("support.case_contact_details.flash.already_a_contact") if @emails.include?(additional_contact_params[:email]) + flash[:error] = { message: I18n.t("support.case_contact_details.flash.already_a_contact"), class: "govuk-error" } if @emails.include?(case_additional_contact_form_params[:email]) render :new end end def edit - @current_case = Support::Case.find(@additional_contact.support_case_id) + @case_additional_contact_form = CaseAdditionalContactForm.from_case(@additional_contact) end def update + @case_additional_contact_form = CaseAdditionalContactForm.from_validation(validation) @emails.delete(@additional_contact.email) - if validation.success? && !@emails.include?(additional_contact_params[:email]) - @additional_contact.update!(additional_contact_params) - redirect_to support_case_additional_contacts_path(case_id: @current_case.id), notice: I18n.t("support.case.label.non_participating_schools.success.message") if @additional_contact.update(additional_contact_params) + if validation.success? && !@emails.include?(case_additional_contact_form_params[:email]) + @additional_contact.update!(case_additional_contact_form_params) + redirect_to support_case_additional_contacts_path(case_id: @current_case.id), notice: I18n.t("support.case_contact_details.flash.update_success") if @additional_contact.update(case_additional_contact_form_params) else - flash.now[:notice] = I18n.t("support.case_contact_details.flash.already_a_contact") if @emails.include?(additional_contact_params[:email]) + flash[:error] = { message: I18n.t("support.case_contact_details.flash.already_a_contact"), class: "govuk-error" } if @emails.include?(case_additional_contact_form_params[:email]) render :edit end end @@ -52,7 +53,7 @@ def set_current_case end def validation - CaseAdditionalContactFormSchema.new.call(**additional_contact_params) + CaseAdditionalContactFormSchema.new.call(**case_additional_contact_form_params) end def set_additional_contact @@ -60,7 +61,8 @@ def set_additional_contact end def set_additional_contacts - @additional_contacts = @current_case.case_additional_contacts + @back_url = support_case_path(@current_case, anchor: "school-details") + @additional_contacts = @current_case.case_additional_contacts.order(:created_at) end def get_emails_of_contacts @@ -68,8 +70,8 @@ def get_emails_of_contacts @emails << @current_case.email end - def additional_contact_params - params.require(:support_case_additional_contact).permit(:first_name, :last_name, :email, :phone_number, :extension_number, :support_case_id, :organisation_id, role: []).tap do |p| + def case_additional_contact_form_params + params.require(:case_additional_contacts_form).permit(:first_name, :last_name, :email, :phone_number, :extension_number, :support_case_id, :organisation_id, role: []).tap do |p| p[:role].reject!(&:blank?) end end diff --git a/app/controllers/support/cases/contact_details_controller.rb b/app/controllers/support/cases/contact_details_controller.rb index f91ccb401..d446ec2c8 100644 --- a/app/controllers/support/cases/contact_details_controller.rb +++ b/app/controllers/support/cases/contact_details_controller.rb @@ -6,11 +6,15 @@ def edit def update @case_contact_details_form = CaseContactDetailsForm.from_validation(validation) - - if validation.success? && @case_contact_details_form.update_contact_details(current_case, current_agent.id) - redirect_to support_case_path(current_case, anchor: "school-details"), - notice: I18n.t("support.case_contact_details.flash.updated") + @emails = current_case.case_additional_contacts&.pluck(:email) + case_contact_details_form_params[:is_evaluator] = params[:is_evaluator] == "true" ? "true" : "false" + if validation.success? && !@emails.include?(case_contact_details_form_params[:email]) + if @current_case.update!(case_contact_details_form_params) + redirect_to support_case_path(current_case, anchor: "school-details"), + notice: I18n.t("support.case_contact_details.flash.updated") + end else + flash[:error] = { message: "Already a contact", class: "govuk-error" } if @emails.include?(case_contact_details_form_params[:email]) render :edit end end @@ -22,7 +26,7 @@ def validation end def case_contact_details_form_params - params.require(:case_contact_details_form).permit(:first_name, :last_name, :phone, :email, :extension_number) + params.require(:case_contact_details_form).permit(:first_name, :last_name, :phone_number, :email, :extension_number, :is_evaluator, :organisation_id, :organisation_type) end end end diff --git a/app/cores/case_management/update_case_additional_contacts.rb b/app/cores/case_management/update_case_additional_contacts.rb new file mode 100644 index 000000000..57081da1c --- /dev/null +++ b/app/cores/case_management/update_case_additional_contacts.rb @@ -0,0 +1,27 @@ +module CaseManagement + class UpdateCaseAdditionalContacts + include Wisper::Publisher + + def call(support_case_id:, first_name:, last_name:, phone:, email:, extension_number:, role:) + support_case = Support::Case.find(support_case_id) + support_case.update!( + first_name:, + last_name:, + phone_number: phone, + email:, + extension_number:, + role:, + ) + + broadcast(:case_additional_contacts_changed, { + case_id: support_case_id, + first_name:, + last_name:, + phone_number: phone, + email:, + extension_number:, + role:, + }) + end + end +end diff --git a/app/forms/support/case_additional_contact_form.rb b/app/forms/support/case_additional_contact_form.rb new file mode 100644 index 000000000..9b8554f67 --- /dev/null +++ b/app/forms/support/case_additional_contact_form.rb @@ -0,0 +1,29 @@ +module Support + class CaseAdditionalContactForm + extend Dry::Initializer + include Concerns::ValidatableForm + + option :first_name, Types::Params::String | Types::Nil, optional: true + option :last_name, Types::Params::String | Types::Nil, optional: true + option :email, Types::Params::String, optional: true, default: proc { "" } + option :phone_number, Types::Params::String | Types::Nil, optional: true + option :extension_number, Types::Params::String | Types::Nil, optional: true + option :role, Types::Params::String | Types::Array, optional: true + + def self.from_case(additional_contact) + new(first_name: additional_contact.first_name, last_name: additional_contact.last_name, email: additional_contact.email, phone: additional_contact.phone_number, extension_number: additional_contact.extension_number, role: additional_contact.role) + end + + def update_contact_details(kase) + CaseManagement::UpdateCaseAdditionalContacts.new.call( + support_case_id: kase.id, + first_name:, + last_name:, + phone:, + email:, + extension_number:, + role:, + ) + end + end +end diff --git a/app/forms/support/case_additional_contact_form_schema.rb b/app/forms/support/case_additional_contact_form_schema.rb new file mode 100644 index 000000000..9e634307e --- /dev/null +++ b/app/forms/support/case_additional_contact_form_schema.rb @@ -0,0 +1,21 @@ +module Support + class CaseAdditionalContactFormSchema < Dry::Validation::Contract + include Concerns::TranslatableFormSchema + + params do + required(:first_name).value(:string) + required(:last_name).value(:string) + optional(:phone_number).value(:string) + required(:email).value(:string) + optional(:extension_number).value(:string) + end + + rule(:email) do + if value.blank? + key(:email).failure(:missing) + else + key(:email).failure(:invalid_format) unless value.scan(URI::MailTo::EMAIL_REGEXP).any? + end + end + end +end diff --git a/app/forms/support/case_contact_details_form.rb b/app/forms/support/case_contact_details_form.rb index 1aecb6a0f..f362ebbb2 100644 --- a/app/forms/support/case_contact_details_form.rb +++ b/app/forms/support/case_contact_details_form.rb @@ -6,11 +6,17 @@ class CaseContactDetailsForm option :first_name, Types::Params::String | Types::Nil, optional: true option :last_name, Types::Params::String | Types::Nil, optional: true option :email, Types::Params::String, optional: true, default: proc { "" } - option :phone, Types::Params::String | Types::Nil, optional: true + option :phone_number, Types::Params::String | Types::Nil, optional: true option :extension_number, Types::Params::String | Types::Nil, optional: true def self.from_case(kase) - new(first_name: kase.first_name, last_name: kase.last_name, email: kase.email, phone: kase.phone_number, extension_number: kase.extension_number) + new( + first_name: kase.first_name, + last_name: kase.last_name, + email: kase.email, + phone_number: kase.phone_number, + extension_number: kase.extension_number, + ) end def update_contact_details(kase, agent_id) @@ -19,7 +25,7 @@ def update_contact_details(kase, agent_id) agent_id:, first_name:, last_name:, - phone:, + phone_number:, email:, extension_number:, ) diff --git a/app/helpers/support/case_additional_contacts_helper.rb b/app/helpers/support/case_additional_contacts_helper.rb new file mode 100644 index 000000000..5570f3793 --- /dev/null +++ b/app/helpers/support/case_additional_contacts_helper.rb @@ -0,0 +1,7 @@ +module Support + module CaseAdditionalContactsHelper + def role_options + CheckboxOption.from(I18nOption.from("support.case_additional_contact.role.options.%%key%%", Support::CaseAdditionalContact.role_values), exclusive_fields: %w[none]) + end + end +end diff --git a/app/models/support/case.rb b/app/models/support/case.rb index 785d8a4ff..3146768dd 100644 --- a/app/models/support/case.rb +++ b/app/models/support/case.rb @@ -57,6 +57,8 @@ class Case < ApplicationRecord has_one :framework_request, class_name: "FrameworkRequest", foreign_key: :support_case_id has_one :case_request, class_name: "CaseRequest", foreign_key: :support_case_id + has_many :case_additional_contacts, class_name: "Support::CaseAdditionalContact", foreign_key: :support_case_id + accepts_nested_attributes_for :hub_transition, allow_destroy: true, reject_if: :all_blank # Support level diff --git a/app/models/support/case_additional_contact.rb b/app/models/support/case_additional_contact.rb new file mode 100644 index 000000000..9aab783ac --- /dev/null +++ b/app/models/support/case_additional_contact.rb @@ -0,0 +1,12 @@ +module Support + class CaseAdditionalContact < ApplicationRecord + belongs_to :case, class_name: "Support::Case", foreign_key: "support_case_id" + belongs_to :organisation, class_name: "Support::Organisation", optional: true + + validates :first_name, :last_name, :email, presence: true + + def self.role_values + %w[lead evaluator] + end + end +end diff --git a/app/models/support/organisation.rb b/app/models/support/organisation.rb index 9605a9ba6..47c675861 100644 --- a/app/models/support/organisation.rb +++ b/app/models/support/organisation.rb @@ -22,6 +22,8 @@ class Organisation < ApplicationRecord belongs_to :local_authority, class_name: "LocalAuthority" + has_many :case_additional_contacts, class_name: "Support::CaseAdditionalContact" + has_many :cases, class_name: "Support::Case", as: :organisation validates :urn, uniqueness: true diff --git a/app/views/layouts/_messages.html.erb b/app/views/layouts/_messages.html.erb index e700a12d3..48af1d7f1 100644 --- a/app/views/layouts/_messages.html.erb +++ b/app/views/layouts/_messages.html.erb @@ -1,22 +1,20 @@ <% flash.each do |name, msg| %> <% if flash[:error].present? && flash[:error][:class].present? %> - <%if flash[:error][:class]!= "remove-message"%> -
<%= I18n.t("support.case_contact_details.description") %>
+<%= form_with(model: @case_additional_contact_form, scope: :case_additional_contacts_form, url: new_contact ? support_case_additional_contacts_path(@current_case) : support_case_additional_contact_path(@current_case, support_case_additional_contact), method: new_contact ? :post : :put, remote: true) do |form| %> + <%= form.govuk_error_summary %> + + <%= form.govuk_text_field :first_name, autofocus: true, width: 'one-half', label: { text: I18n.t("support.case_contact_details.label.first_name") } %> + <%= form.govuk_text_field :last_name, width: 'one-half', label: { text: I18n.t("support.case_contact_details.label.last_name") } %> + <%= form.govuk_text_field :email, width: 'one-half', label: { text: I18n.t("support.case_contact_details.label.email") } %> + <%= form.govuk_text_field :phone_number, width: 'one-quarter', label: { text: I18n.t("support.case_contact_details.label.phone") } %> + <%= form.govuk_text_field :extension_number, width: 'one-quarter', label: { text: I18n.t("support.case_contact_details.label.extension_number") } %> + + <% + +=begin%> + #below code is commented because it can be used later. It is a field for organisation selection. + <%= render "components/autocomplete", + container_id: "case-contacts-organisation-field", + label_text: I18n.t("support.case_additional_contact.organisation.header"), + label_class: "govuk_text_field", + element_id: "additional_contacts-autocomplete", + element_name: "organisation_name", + template_suggestion: "{{autocomplete_template}}", + value_field: :name, + default_value: form.object.organisation&.name, + hidden_fields: { + 'support_case_additional_contact[organisation_id]' => [:id, form.object.organisation&.id], + # 'case_request[organisation_type]' => [:source, form.object.organisation.class&.name], + }, + query_url: support_establishments_path(format: :json, q: "{{QUERY}}") %> +<% +=end%> + + +<%= I18n.t("support.case_contact_details.listing_description") %>
+ + + <%= link_to 'Add', new_support_case_additional_contact_path(@current_case), class: 'govuk-button' %> + \ No newline at end of file diff --git a/app/views/support/cases/additional_contacts/new.html.erb b/app/views/support/cases/additional_contacts/new.html.erb new file mode 100644 index 000000000..ee43dc29d --- /dev/null +++ b/app/views/support/cases/additional_contacts/new.html.erb @@ -0,0 +1 @@ +<%= render 'form', support_case_additional_contact: @additional_contact %> \ No newline at end of file diff --git a/app/views/support/cases/contact_details/edit.html.erb b/app/views/support/cases/contact_details/edit.html.erb index 56b1a6e2b..173cf8888 100644 --- a/app/views/support/cases/contact_details/edit.html.erb +++ b/app/views/support/cases/contact_details/edit.html.erb @@ -5,9 +5,41 @@ <%= form.govuk_text_field :first_name, autofocus: true, width: 'one-half', label: { text: I18n.t("support.case_contact_details.label.first_name") } %> <%= form.govuk_text_field :last_name, width: 'one-half', label: { text: I18n.t("support.case_contact_details.label.last_name") } %> - <%= form.govuk_text_field :phone, width: 'one-quarter', label: { text: I18n.t("support.case_contact_details.label.phone") } %> + <%= form.govuk_text_field :phone_number, width: 'one-quarter', label: { text: I18n.t("support.case_contact_details.label.phone") } %> <%= form.govuk_text_field :extension_number, width: 'one-quarter', label: { text: I18n.t("support.case_contact_details.label.extension_number") } %> <%= form.govuk_text_field :email, width: 'one-half', label: { text: I18n.t("support.case_contact_details.label.email") } %> + <% + +=begin%> + #below code is commented because it can be used later. It is a field for organisation selection. + <%= render "components/autocomplete", + container_id: "case-contacts-organisation-field", + label_text: I18n.t("support.case_additional_contact.organisation.header"), + label_class: "govuk_text_field", + element_id: "additional_contacts-autocomplete", + element_name: "organisation_name", + template_suggestion: "{{autocomplete_template}}", + value_field: :name, + default_value: @current_case&.organisation&.name, + hidden_fields: { + 'case_contact_details_form[organisation_id]' => :id, + 'case_contact_details_form[organisation_type]' => :source, + }, + query_url: support_establishments_path(format: :json, q: "{{QUERY}}") %> +<% +=end%> + +