diff --git a/app/forms/tasks/confirm_press_notice_form.rb b/app/forms/tasks/confirm_press_notice_form.rb new file mode 100644 index 0000000000..080a07e102 --- /dev/null +++ b/app/forms/tasks/confirm_press_notice_form.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +module Tasks + class ConfirmPressNoticeForm < Form + include PublicityPermittable + include DateValidateable + + self.task_actions = %w[save_and_complete confirm_publication] + + attribute :published_at, :date + attribute :documents, array: true + attribute :comment, :string + + delegate :consultation_end_date, :consultation_start_date, :requested_at, to: :press_notice + + after_initialize do + if params[:id].present? + pn = press_notices.find(params[:id]) + self.published_at ||= pn.published_at + self.comment ||= pn.comment + self.documents ||= pn.documents + end + end + + with_options on: :confirm_publication do + validates :published_at, presence: {message: "Please select when press notice was published"} + validates :published_at, date: {on_or_before: :consultation_end_date, message: "Date must be on or before the consultation end date"} + validates :published_at, date: {on_or_after: :consultation_start_date, message: "Date must be on or after the consultation start date"} + end + + def press_notices + planning_application.press_notices + end + + def press_notice + @press_notice ||= if params[:id].present? + press_notices.find(params[:id]) + else + press_notices.last + end + end + + def edit_press_notice_url(press_notice) + route_for(:edit_task_component, planning_application, slug: task.full_slug, id: press_notice.id, only_path: true) + end + + def press_notice_task_url + route_for(:task, planning_application, slug: task.full_slug.sub("confirm-press-notice", "press-notice"), new: true, only_path: true) + end + + private + + def form_params(params) + params.fetch(param_key, {}).permit( + :published_at, + :comment, + documents: [] + ) + end + + def confirm_publication + transaction do + press_notice.update!( + published_at: published_at, + documents: documents, + comment: comment + ) + task.in_progress! + end + end + end +end diff --git a/app/forms/tasks/press_notice_form.rb b/app/forms/tasks/press_notice_form.rb new file mode 100644 index 0000000000..6d661cee9d --- /dev/null +++ b/app/forms/tasks/press_notice_form.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +module Tasks + class PressNoticeForm < Form + self.task_actions = %w[save_and_complete edit_form] + + attribute :required, :boolean + attribute :reasons, :list, default: [] + attribute :other_reason, :string, default: nil + + after_initialize do + @press_notice = planning_application.press_notices.where(published_at: nil).by_created_at_desc.first || + (params[:new].present? ? planning_application.press_notices.new : nil) || + planning_application.press_notices.by_created_at_desc.first || + planning_application.press_notices.new + if press_notice.persisted? + self.required = press_notice.required if required.nil? + self.reasons = press_notice.reasons if reasons.empty? + self.other_reason ||= press_notice.other_reason + end + end + + with_options on: :save_and_complete do + validates :required, inclusion: {in: [true, false], message: "Select whether a press notice is required"} + validates :reasons, presence: {message: "Select a reason for the press notice"}, if: :press_notice_required? + validates :other_reason, presence: {message: "Provide other reason for press notice"}, if: :other_reason_selected? + end + + attr_reader :press_notice + + def new_press_notice_url + route_for(:task, planning_application, slug: task.full_slug, new: true, only_path: true) + end + + private + + def press_notice_required? + required == true + end + + def other_reason_selected? + reasons.include?("other") + end + + def form_params(params) + params.fetch(param_key, {}).permit( + :required, + :other_reason, + reasons: [] + ) + end + + def save_and_complete + super do + reasons.each do |reason| + press_notice.update!( + required: required, + reasons: reasons.flatten, + other_reason: other_reason + ) + SendPressNoticeEmailJob.perform_later(@press_notice, Current.user) + end + end + end + end +end diff --git a/app/jobs/send_press_notice_email_job.rb b/app/jobs/send_press_notice_email_job.rb index 408d3a85bf..26cc1bca7c 100644 --- a/app/jobs/send_press_notice_email_job.rb +++ b/app/jobs/send_press_notice_email_job.rb @@ -8,8 +8,7 @@ def perform(press_notice, user) return if press_notice.press_notice_email.blank? ApplicationRecord.transaction do - PlanningApplicationMailer.press_notice_mail(press_notice).deliver_now - + PlanningApplicationMailer.press_notice_mail(press_notice).deliver_later press_notice.touch(:requested_at) press_notice.audits.create!( user: user, diff --git a/app/mailers/planning_application_mailer.rb b/app/mailers/planning_application_mailer.rb index e7aa7fa551..073e7c5a3b 100644 --- a/app/mailers/planning_application_mailer.rb +++ b/app/mailers/planning_application_mailer.rb @@ -149,6 +149,7 @@ def internal_team_site_notice_mail(planning_application, email) def press_notice_mail(press_notice) @press_notice = press_notice @planning_application = press_notice.planning_application + @confirm_press_notice_task = @planning_application.case_record.find_task_by_slug_path!("consultees-neighbours-and-publicity/publicity/confirm-press-notice") email = press_notice.press_notice_email view_mail(email_template_id, headers_for(subject(:press_notice_mail), email)) diff --git a/app/views/planning_application_mailer/press_notice_mail.text.erb b/app/views/planning_application_mailer/press_notice_mail.text.erb index 9606ec3ad3..827c94d4a6 100644 --- a/app/views/planning_application_mailer/press_notice_mail.text.erb +++ b/app/views/planning_application_mailer/press_notice_mail.text.erb @@ -18,7 +18,12 @@ This application requires a press notice with the following reasons: This application is subject to an Environmental Impact Assessment (EIA). <% end -%> -You can view the application<% if @planning_application.environment_impact_assessment_required? %> and Environmental Statement<% end %> at <%= planning_application_press_notice_confirmation_url(@planning_application, subdomain: @planning_application.local_authority.subdomain) %>. +You can view the application<% if @planning_application.environment_impact_assessment_required? %> and Environmental Statement<% end %> at +<% if @confirm_press_notice_task %> + <%= task_path(@planning_application, @confirm_press_notice_task) %> +<% else %> + <%= planning_application_press_notice_confirmation_url(@planning_application, subdomain: @planning_application.local_authority.subdomain) %>. +<% end %> <% if @planning_application.environment_impact_assessment_required? %> <%= request_eia_copy(@planning_application.environment_impact_assessment) %> diff --git a/app/views/tasks/consultees-neighbours-and-publicity/publicity/confirm-press-notice/edit.html.erb b/app/views/tasks/consultees-neighbours-and-publicity/publicity/confirm-press-notice/edit.html.erb new file mode 100644 index 0000000000..cd0a7bd00a --- /dev/null +++ b/app/views/tasks/consultees-neighbours-and-publicity/publicity/confirm-press-notice/edit.html.erb @@ -0,0 +1,69 @@ +<%= render "task_header", task: @task %> + +

Confirm publication details

+ +<% unless @form.published_at %> +
+

+ <%= time_tag(@form.requested_at, format: t(".requested_on")) %> +

+

+ Emailed +

+
+<% end %> + +
+

Reasons selected:

+ +
+ +<%= form_with model: @form, url: @form.url do |form| %> + <%= hidden_field_tag :id, @form.press_notice.id %> + <%= form.govuk_error_summary %> + +
+
+ <%= form.govuk_date_field(:published_at, + rows: 6, + id: "published-at-field", + legend: {size: "s", text: t(".published_at")}, + hint: {text: "Consultation dates: #{@planning_application.consultation.start_date.to_fs} to #{@planning_application.consultation.end_date.to_fs} "}) %> + + <% if @form.press_notice.documents.with_file_attachment.any? %> +
+

Uploaded photos

+ <% @form.press_notice.documents.with_file_attachment.each do |document| %> +

+ <%= document_thumbnail_link(document, thumbnail_args: {resize: "300x212"}) %> +

+ <% end %> +
+ <% end %> + + <%= form.govuk_file_field :documents, + label: {size: "s", text: t(".upload_photos")}, + hint: {text: t(".photos_hint")}, + accept: acceptable_file_mime_types, + multiple: true %> + + <%= form.govuk_text_area(:comment, + rows: 3, + label: {size: "s", + text: t(".optional_comment")}) %> +
+ + <%= form.govuk_task_button "Confirm publication", action: "confirm_publication" %> + <%= back_link %> +
+<% end %> diff --git a/app/views/tasks/consultees-neighbours-and-publicity/publicity/confirm-press-notice/show.html.erb b/app/views/tasks/consultees-neighbours-and-publicity/publicity/confirm-press-notice/show.html.erb new file mode 100644 index 0000000000..3b1ba40ebb --- /dev/null +++ b/app/views/tasks/consultees-neighbours-and-publicity/publicity/confirm-press-notice/show.html.erb @@ -0,0 +1,62 @@ +<%= render "task_header", task: @task %> + +<% unless @form.press_notice.published_at %> + <% if @form.press_notice.requested_at? %> +
+

+ <%= time_tag(@form.press_notice.requested_at, format: t(".requested_on")) %> +

+

+ Emailed +

+
+ <% end %> +<% end %> + +<%= govuk_table do |table| + table.with_head do |head| + head.with_row do |row| + row.with_cell(text: "Document") + row.with_cell(text: "Status") + row.with_cell(text: "Date requested") + row.with_cell(text: "Date published") + row.with_cell(text: "Actions") + end + end + + table.with_body do |body| + @form.press_notices.each do |press_notice| + body.with_row do |row| + row.with_cell do + if press_notice.documents.with_file_attachment.any? + press_notice.documents.with_file_attachment.each do |document| + concat(content_tag(:p, document_thumbnail_link(document, thumbnail_args: {resize: "300x212"}), class: "govuk-!-margin-bottom-1")) + end + else + concat(content_tag(:p, "No document provided", class: "govuk-body")) + end + end + row.with_cell { press_notice.published_at? ? govuk_tag(text: "Published", colour: "green") : govuk_tag(text: "Not yet published", colour: "grey") } + row.with_cell(text: press_notice.requested_at&.strftime("%-d %b %Y") || "–") + row.with_cell(text: press_notice.published_at&.strftime("%-d %b %Y") || "–") + row.with_cell do + govuk_link_to( + press_notice.published_at? ? "Edit publication details" : "Confirm publication", + @form.edit_press_notice_url(press_notice) + ) + end + end + end + end + end %> + +

+ <%= govuk_link_to "Add a new press notice response", @form.press_notice_task_url %> +

+ +<%= form_with model: @form, url: @form.url do |form| %> + <%= form.govuk_error_summary %> +
+ <%= render "task_submit_buttons", form: form, save_draft: false %> +
+<% end %> diff --git a/app/views/tasks/consultees-neighbours-and-publicity/publicity/press-notice/show.html.erb b/app/views/tasks/consultees-neighbours-and-publicity/publicity/press-notice/show.html.erb new file mode 100644 index 0000000000..56988740be --- /dev/null +++ b/app/views/tasks/consultees-neighbours-and-publicity/publicity/press-notice/show.html.erb @@ -0,0 +1,70 @@ +<%= render "task_header", task: @task %> + +<% unless @form.press_notice.new_record? %> +
+ Press notice has been marked as <%= @form.press_notice.required ? "required and email notification has been sent to #{@planning_application.local_authority.press_notice_email}." : "not required" %> +
+<% end %> + +<%= form_with model: @form, url: @form.url do |form| %> + <%= hidden_field_tag :new, true if @form.press_notice.new_record? %> + <%= form.govuk_error_summary %> + + <%= form.govuk_radio_buttons_fieldset( + :required, + legend: -> { + if @form.press_notice.new_record? + content_tag(:h2, "Does this application require a press notice?", class: "govuk-heading-m") + else + content_tag(:h2, "Press notice details", class: "govuk-heading-m") + end + } + ) do %> + + <%= form.govuk_radio_button( + :required, true, disabled: @form.press_notice.published_at?, label: {text: "Yes"} + ) do %> + + <%= form.govuk_check_boxes_fieldset :reasons, legend: -> { "" } do %> + <% PressNotice::REASONS.each do |reason| %> + <% if reason == :other %> + <%= form.govuk_check_box_divider "or" %> + <%= form.govuk_check_box :reasons, reason.to_s, disabled: @form.press_notice.published_at?, label: {text: t(reason, scope: :press_notice_reasons)} do %> + <%= form.govuk_text_area :other_reason, disabled: @form.press_notice.published_at?, label: {text: t("press_notice_reasons.other_reason")} %> + <% end %> + <% else %> + <%= form.govuk_check_box :reasons, reason.to_s, disabled: @form.press_notice.published_at?, label: {text: t(reason, scope: :press_notice_reasons)} %> + <% end %> + <% end %> + <% end %> + + <% unless @form.press_notice.published_at? %> +
+ <% if @form.press_notice.new_record? %> +
+ <% if @form.press_notice.press_notice_email.present? %> + An email notification will be sent to <%= @planning_application.local_authority.press_notice_email %> if a press notice is required. + <% else %> + No press notice email has been set. This can be done by an administrator in the admin dashboard. + <% end %> +
+ <% end %> +
+ <% end %> + <% end %> + + <%= form.govuk_radio_button( + :required, false, disabled: @form.press_notice.published_at?, label: {text: "No"} + ) %> + <% end %> + + <% if @form.press_notice.published_at? %> +

+ <%= govuk_link_to "Add a new press notice response", @form.new_press_notice_url %> +

+ <% end %> + +
+ <%= render "task_submit_buttons", form: form, save_draft: false %> +
+<% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 44bff286da..751d1c29d5 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2795,6 +2795,21 @@ en: no_recommended_html: No (recommended based on submission data) 'yes': 'Yes' yes_recommended_html: Yes (recommended based on submission data) + consultees-neighbours-and-publicity: + publicity: + confirm-press-notice: + edit: + optional_comment: Optional comment + photos_hint: Provide documentary evidence of the press notice being published + published_at: What date was the press notice published? + requested_on: Press notice requested on %-d %B %Y + upload_photos: Upload photo(s) + show: + optional_comment: Optional comment + photos_hint: Provide documentary evidence of the press notice being published + published_at: What date was the press notice published? + requested_on: Press notice requested on %-d %B %Y + upload_photos: Upload photo(s) update: add-conditions: add_condition: Condition was successfully added @@ -2867,7 +2882,10 @@ en: success: Site history was successfully marked as reviewed confirm-community-infrastructure-levy-cil: failure: Failed to confirm CIL liability check - success: Successfully confirmed CIL liabilityß + success: Successfully confirmed CIL liability + confirm-press-notice: + failure: Failed to confirm press notice publication + success: Successfully confimed press notice publication draw-red-line-boundary: failure: Draw a red line boundary success: Red line boundary was successfully saved @@ -2884,6 +2902,9 @@ en: permitted-development-rights: failure: Failed to update permitted development rights success: Successfully confirmed permitted development rights + press-notice: + failure: Failed to save press notice requirement + success: Successfully saved press notice requirement review-and-submit-recommendation: failure: Failed to submit recommendation success: Successfully submitted recommendation for review diff --git a/config/task_workflows/planning_permission.yml b/config/task_workflows/planning_permission.yml index 26d977d531..f800feb6bd 100644 --- a/config/task_workflows/planning_permission.yml +++ b/config/task_workflows/planning_permission.yml @@ -35,6 +35,12 @@ - name: Send validation decision - name: "Consultees, neighbours and publicity" section: "Consultation" + tasks: + - name: Publicity + section: Publicity + tasks: + - name: Press notice + - name: Confirm press notice - name: "Check and assess" section: "Assessment" tasks: diff --git a/engines/bops_core/app/controllers/concerns/bops_core/tasks_controller.rb b/engines/bops_core/app/controllers/concerns/bops_core/tasks_controller.rb index 09c96d9f3b..6de236a7d4 100644 --- a/engines/bops_core/app/controllers/concerns/bops_core/tasks_controller.rb +++ b/engines/bops_core/app/controllers/concerns/bops_core/tasks_controller.rb @@ -88,7 +88,7 @@ def template_for(action) end def failure_template - return :edit if params[:task_action].in?(%w[update_site_visit update_condition]) + return :edit if params[:task_action].in?(%w[update_site_visit update_condition confirm_publication]) :show end