aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet/App/Controller/Admin/Templates.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perllib/FixMyStreet/App/Controller/Admin/Templates.pm')
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin/Templates.pm176
1 files changed, 176 insertions, 0 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Admin/Templates.pm b/perllib/FixMyStreet/App/Controller/Admin/Templates.pm
new file mode 100644
index 000000000..1a7381c0b
--- /dev/null
+++ b/perllib/FixMyStreet/App/Controller/Admin/Templates.pm
@@ -0,0 +1,176 @@
+package FixMyStreet::App::Controller::Admin::Templates;
+use Moose;
+use namespace::autoclean;
+
+BEGIN { extends 'Catalyst::Controller'; }
+
+=head1 NAME
+
+FixMyStreet::App::Controller::Admin::Templates - Catalyst Controller
+
+=head1 DESCRIPTION
+
+Admin pages for response templates
+
+=head1 METHODS
+
+=cut
+
+sub index : Path : Args(0) {
+ my ( $self, $c ) = @_;
+
+ my $user = $c->user;
+
+ if ($user->is_superuser) {
+ $c->forward('/admin/fetch_all_bodies');
+ } elsif ( $user->from_body ) {
+ $c->forward('load_template_body', [ $user->from_body->id ]);
+ $c->res->redirect( $c->uri_for_action( '/admin/templates/view', $c->stash->{body}->id ) );
+ } else {
+ $c->detach( '/page_error_404_not_found', [] );
+ }
+}
+
+sub view : Path : Args(1) {
+ my ($self, $c, $body_id) = @_;
+
+ $c->forward('load_template_body', [ $body_id ]);
+
+ my @templates = $c->stash->{body}->response_templates->search(
+ undef,
+ {
+ order_by => 'title'
+ }
+ );
+
+ $c->stash->{response_templates} = \@templates;
+}
+
+sub edit : Path : Args(2) {
+ my ( $self, $c, $body_id, $template_id ) = @_;
+
+ $c->forward('load_template_body', [ $body_id ]);
+
+ my $template;
+ if ($template_id eq 'new') {
+ $template = $c->stash->{body}->response_templates->new({});
+ }
+ else {
+ $template = $c->stash->{body}->response_templates->find( $template_id )
+ or $c->detach( '/page_error_404_not_found', [] );
+ }
+
+ $c->forward('/admin/fetch_contacts');
+ my @contacts = $template->contacts->all;
+ my @live_contacts = $c->stash->{live_contacts}->all;
+ my %active_contacts = map { $_->id => 1 } @contacts;
+ my @all_contacts = map { {
+ id => $_->id,
+ category => $_->category_display,
+ active => $active_contacts{$_->id},
+ email => $_->email,
+ } } @live_contacts;
+ $c->stash->{contacts} = \@all_contacts;
+
+ # bare block to use 'last' if form is invalid.
+ if ($c->req->method eq 'POST') { {
+ if ($c->get_param('delete_template') && $c->get_param('delete_template') eq _("Delete template")) {
+ $template->contact_response_templates->delete_all;
+ $template->delete;
+ } else {
+ my @live_contact_ids = map { $_->id } @live_contacts;
+ my @new_contact_ids = grep { $c->get_param("contacts[$_]") } @live_contact_ids;
+ my %new_contacts = map { $_ => 1 } @new_contact_ids;
+ for my $contact (@all_contacts) {
+ $contact->{active} = $new_contacts{$contact->{id}};
+ }
+
+ $template->title( $c->get_param('title') );
+ my $query = { title => $template->title };
+ if ($template->in_storage) {
+ $query->{id} = { '!=', $template->id };
+ }
+ if ($c->stash->{body}->response_templates->search($query)->count) {
+ $c->stash->{errors} ||= {};
+ $c->stash->{errors}->{title} = _("There is already a template with that title.");
+ }
+
+ $template->text( $c->get_param('text') );
+ $template->state( $c->get_param('state') );
+ $template->external_status_code( $c->get_param('external_status_code') );
+
+ if ( $template->state && $template->external_status_code ) {
+ $c->stash->{errors} ||= {};
+ $c->stash->{errors}->{state} = _("State and external status code cannot be used simultaneously.");
+ $c->stash->{errors}->{external_status_code} = _("State and external status code cannot be used simultaneously.");
+ }
+
+ $template->auto_response( $c->get_param('auto_response') && ( $template->state || $template->external_status_code ) ? 1 : 0 );
+ if ($template->auto_response) {
+ my @check_contact_ids = @new_contact_ids;
+ # If the new template has not specific categories (i.e. it
+ # applies to all categories) then we need to check each of those
+ # category ids for existing auto-response templates.
+ if (!scalar @check_contact_ids) {
+ @check_contact_ids = @live_contact_ids;
+ }
+ my $query = {
+ 'auto_response' => 1,
+ 'contact.id' => [ @check_contact_ids, undef ],
+ -or => {
+ $template->state ? ('me.state' => $template->state) : (),
+ $template->external_status_code ? ('me.external_status_code' => $template->external_status_code) : (),
+ },
+ };
+ if ($template->in_storage) {
+ $query->{'me.id'} = { '!=', $template->id };
+ }
+ if ($c->stash->{body}->response_templates->search($query, {
+ join => { 'contact_response_templates' => 'contact' },
+ })->count) {
+ $c->stash->{errors} ||= {};
+ $c->stash->{errors}->{auto_response} = _("There is already an auto-response template for this category/state.");
+ }
+ }
+
+ last if $c->stash->{errors};
+
+ $template->update_or_insert;
+ $template->contact_response_templates->search({
+ contact_id => { -not_in => \@new_contact_ids },
+ })->delete;
+ foreach my $contact_id (@new_contact_ids) {
+ $template->contact_response_templates->find_or_create({
+ contact_id => $contact_id,
+ });
+ }
+ }
+
+ $c->res->redirect( $c->uri_for_action( '/admin/templates/view', $c->stash->{body}->id ) );
+ } }
+
+ $c->stash->{response_template} = $template;
+}
+
+sub load_template_body : Private {
+ my ($self, $c, $body_id) = @_;
+
+ my $zurich_user = $c->user->from_body && $c->cobrand->moniker eq 'zurich';
+ my $has_permission = $c->user->has_body_permission_to('template_edit', $body_id);
+
+ unless ( $zurich_user || $has_permission ) {
+ $c->detach( '/page_error_404_not_found', [] );
+ }
+
+ # Regular users can only view their own body's templates
+ if ( !$c->user->is_superuser && $body_id ne $c->user->from_body->id ) {
+ $c->res->redirect( $c->uri_for_action( '/admin/templates/view', $c->user->from_body->id ) );
+ }
+
+ $c->stash->{body} = $c->model('DB::Body')->find($body_id)
+ or $c->detach( '/page_error_404_not_found', [] );
+}
+
+__PACKAGE__->meta->make_immutable;
+
+1;