aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet/App
diff options
context:
space:
mode:
Diffstat (limited to 'perllib/FixMyStreet/App')
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin.pm3
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin/Triage.pm163
-rw-r--r--perllib/FixMyStreet/App/Controller/Around.pm14
-rw-r--r--perllib/FixMyStreet/App/Controller/Report.pm11
-rw-r--r--perllib/FixMyStreet/App/Controller/Report/New.pm19
-rw-r--r--perllib/FixMyStreet/App/Controller/Reports.pm5
6 files changed, 202 insertions, 13 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm
index 5373220a7..c2c4e7588 100644
--- a/perllib/FixMyStreet/App/Controller/Admin.pm
+++ b/perllib/FixMyStreet/App/Controller/Admin.pm
@@ -678,6 +678,9 @@ sub categories_for_point : Private {
shift @{$c->stash->{category_options}} if @{$c->stash->{category_options}};
$c->stash->{categories_hash} = { map { $_->category => 1 } @{$c->stash->{category_options}} };
+
+ $c->forward('/admin/triage/setup_categories');
+
}
sub alerts_for_report : Private {
diff --git a/perllib/FixMyStreet/App/Controller/Admin/Triage.pm b/perllib/FixMyStreet/App/Controller/Admin/Triage.pm
new file mode 100644
index 000000000..385248cd1
--- /dev/null
+++ b/perllib/FixMyStreet/App/Controller/Admin/Triage.pm
@@ -0,0 +1,163 @@
+package FixMyStreet::App::Controller::Admin::Triage;
+use Moose;
+use namespace::autoclean;
+
+BEGIN { extends 'Catalyst::Controller'; }
+
+=head1 NAME
+
+FixMyStreet::App::Controller::Admin::Triage - Catalyst Controller
+
+=head1 DESCRIPTION
+
+Admin pages for triaging reports.
+
+This allows reports to be triaged before being sent to the council. It works
+by having a set of categories with a send_method of Triage which sets the report
+state to 'for_triage'. Any reports with the state are then show on '/admin/triage'
+which is available to users with the 'triage' permission.
+
+Clicking on reports on this list will then allow a user to change the category of
+the report to one that has an alternative send method, which will trigger the report
+to be resent.
+
+In order for this to work additional work needs to be done to the cobrand to only
+display triageable categories to the user.
+
+=head1 METHODS
+
+=cut
+
+sub auto : Private {
+ my ( $self, $c ) = @_;
+
+ unless ( $c->user->has_body_permission_to('triage') ) {
+ $c->detach('/page_error_403_access_denied', []);
+ }
+}
+
+sub index : Path : Args(0) {
+ my ( $self, $c ) = @_;
+
+ # default sort to oldest
+ unless ( $c->get_param('sort') ) {
+ $c->set_param('sort', 'created-asc');
+ }
+ $c->stash->{body} = $c->forward('/reports/body_find', [ $c->cobrand->council_area ]);
+ $c->forward( 'stash_report_filter_status' );
+ $c->forward( '/reports/load_and_group_problems' );
+ $c->stash->{page} = 'reports'; # So the map knows to make clickable pins
+
+ if ($c->get_param('ajax')) {
+ my $ajax_template = $c->stash->{ajax_template} || 'reports/_problem-list.html';
+ $c->detach('/reports/ajax', [ $ajax_template ]);
+ }
+
+ my @categories = $c->stash->{body}->contacts->not_deleted->search( undef, {
+ columns => [ 'id', 'category', 'extra' ],
+ distinct => 1,
+ order_by => [ 'category' ],
+ } )->all;
+ $c->stash->{filter_categories} = \@categories;
+ $c->stash->{filter_category} = { map { $_ => 1 } $c->get_param_list('filter_category', 1) };
+ my $pins = $c->stash->{pins} || [];
+
+ my %map_params = (
+ latitude => @$pins ? $pins->[0]{latitude} : 0,
+ longitude => @$pins ? $pins->[0]{longitude} : 0,
+ area => [ $c->stash->{wards} ? map { $_->{id} } @{$c->stash->{wards}} : keys %{$c->stash->{body}->areas} ],
+ any_zoom => 1,
+ );
+ FixMyStreet::Map::display_map(
+ $c, %map_params, pins => $pins,
+ );
+}
+
+sub stash_report_filter_status : Private {
+ my ( $self, $c ) = @_;
+ $c->stash->{filter_problem_states} = { 'for triage' => 1 };
+ return 1;
+}
+
+sub setup_categories : Private {
+ my ( $self, $c ) = @_;
+
+ if ( $c->stash->{problem}->state eq 'for triage' ) {
+ $c->stash->{holding_options} = [ grep { $_->send_method && $_->send_method eq 'Triage' } @{$c->stash->{category_options}} ];
+ $c->stash->{holding_categories} = { map { $_->category => 1 } @{$c->stash->{holding_options}} };
+ $c->stash->{end_options} = [ grep { !$_->send_method || $_->send_method ne 'Triage' } @{$c->stash->{category_options}} ];
+ $c->stash->{end_categories} = { map { $_->category => 1 } @{$c->stash->{end_options}} };
+ delete $c->stash->{categories_hash};
+ my %category_groups = ();
+ for my $category (@{$c->stash->{end_options}}) {
+ my $group = $category->{group} // $category->get_extra_metadata('group') // [''];
+ # this could be an array ref or a string
+ my @groups = ref $group eq 'ARRAY' ? @$group : ($group);
+ push( @{$category_groups{$_}}, $category ) for @groups;
+ }
+ my @category_groups = ();
+ for my $group ( grep { $_ ne _('Other') } sort keys %category_groups ) {
+ push @category_groups, { name => $group, categories => $category_groups{$group} };
+ }
+ $c->stash->{end_groups} = \@category_groups;
+ }
+
+ return 1;
+}
+
+sub update : Private {
+ my ($self, $c) = @_;
+
+ my $problem = $c->stash->{problem};
+
+ my $current_category = $problem->category;
+ my $new_category = $c->get_param('category');
+
+ my $changed = $c->forward('/admin/report_edit_category', [ $problem, 1 ] );
+
+ if ( $changed ) {
+ $c->stash->{problem}->update( { state => 'confirmed' } );
+ $c->forward( '/admin/log_edit', [ $problem->id, 'problem', 'triage' ] );
+
+ my $name = $c->user->moderating_user_name;
+ my $extra = { is_superuser => 1 };
+ if ($c->user->from_body) {
+ delete $extra->{is_superuser};
+ $extra->{is_body_user} = $c->user->from_body->id;
+ }
+
+ $extra->{triage_report} = 1;
+ $extra->{holding_category} = $current_category;
+ $extra->{new_category} = $new_category;
+
+ my $timestamp = \'current_timestamp';
+ my $comment = $problem->add_to_comments( {
+ text => "Report triaged from $current_category to $new_category",
+ created => $timestamp,
+ confirmed => $timestamp,
+ user_id => $c->user->id,
+ name => $name,
+ mark_fixed => 0,
+ anonymous => 0,
+ state => 'confirmed',
+ problem_state => $problem->state,
+ extra => $extra,
+ whensent => \'current_timestamp',
+ } );
+
+ my @alerts = FixMyStreet::DB->resultset('Alert')->search( {
+ alert_type => 'new_updates',
+ parameter => $problem->id,
+ confirmed => 1,
+ } );
+
+ for my $alert (@alerts) {
+ my $alerts_sent = FixMyStreet::DB->resultset('AlertSent')->find_or_create( {
+ alert_id => $alert->id,
+ parameter => $comment->id,
+ } );
+ }
+ }
+}
+
+1;
diff --git a/perllib/FixMyStreet/App/Controller/Around.pm b/perllib/FixMyStreet/App/Controller/Around.pm
index 203296c4d..ebb3d4839 100644
--- a/perllib/FixMyStreet/App/Controller/Around.pm
+++ b/perllib/FixMyStreet/App/Controller/Around.pm
@@ -234,12 +234,18 @@ sub check_and_stash_category : Private {
my @list_of_names = map { $_->name } values %bodies;
my $csv = Text::CSV->new();
$csv->combine(@list_of_names);
+ $c->stash->{bodies} = \@bodies;
$c->{stash}->{list_of_names_as_string} = $csv->string;
+ my $where = { body_id => [ keys %bodies ], };
+
+ my $cobrand_where = $c->cobrand->call_hook('munge_around_category_where', $where );
+ if ( $cobrand_where ) {
+ $where = $cobrand_where;
+ }
+
my @categories = $c->model('DB::Contact')->not_deleted->search(
- {
- body_id => [ keys %bodies ],
- },
+ $where,
{
columns => [ 'category', 'extra' ],
order_by => [ 'category' ],
@@ -252,6 +258,7 @@ sub check_and_stash_category : Private {
my $categories = [ $c->get_param_list('filter_category', 1) ];
my %valid_categories = map { $_ => 1 } grep { $_ && $categories_mapped{$_} } @$categories;
$c->stash->{filter_category} = \%valid_categories;
+ $c->cobrand->call_hook('munge_around_filter_category_list');
}
sub map_features : Private {
@@ -312,6 +319,7 @@ sub ajax : Path('/ajax') {
my %valid_categories = map { $_ => 1 } $c->get_param_list('filter_category', 1);
$c->stash->{filter_category} = \%valid_categories;
+ $c->cobrand->call_hook('munge_around_filter_category_list');
$c->forward('map_features', [ { bbox => $c->stash->{bbox} } ]);
$c->forward('/reports/ajax', [ 'around/on_map_list_items.html' ]);
diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm
index 9b90da161..eb6050fde 100644
--- a/perllib/FixMyStreet/App/Controller/Report.pm
+++ b/perllib/FixMyStreet/App/Controller/Report.pm
@@ -86,7 +86,7 @@ sub display :PathPart('') :Chained('id') :Args(0) {
$c->forward( 'format_problem_for_display' );
my $permissions = $c->stash->{_permissions} ||= $c->forward( 'check_has_permission_to',
- [ qw/report_inspect report_edit_category report_edit_priority report_mark_private/ ] );
+ [ qw/report_inspect report_edit_category report_edit_priority report_mark_private triage/ ] );
if (any { $_ } values %$permissions) {
$c->stash->{template} = 'report/inspect.html';
$c->forward('inspect');
@@ -396,7 +396,14 @@ sub inspect : Private {
$c->stash->{max_detailed_info_length} = $c->cobrand->max_detailed_info_length;
- if ( $c->get_param('save') ) {
+ if ( $c->get_param('triage') ) {
+ $c->forward('/auth/check_csrf_token');
+ $c->forward('/admin/triage/update');
+ my $redirect_uri = $c->uri_for( '/admin/triage' );
+ $c->log->debug( "Redirecting to: " . $redirect_uri );
+ $c->res->redirect( $redirect_uri );
+ }
+ elsif ( $c->get_param('save') ) {
$c->forward('/auth/check_csrf_token');
my $valid = 1;
diff --git a/perllib/FixMyStreet/App/Controller/Report/New.pm b/perllib/FixMyStreet/App/Controller/Report/New.pm
index 554fbc3b7..9b7a925b8 100644
--- a/perllib/FixMyStreet/App/Controller/Report/New.pm
+++ b/perllib/FixMyStreet/App/Controller/Report/New.pm
@@ -261,15 +261,20 @@ sub category_extras_ajax : Path('category_extras') : Args(0) {
sub by_category_ajax_data : Private {
my ($self, $c, $type, $category) = @_;
- my $bodies = $c->forward('contacts_to_bodies', [ $category ]);
- my $list_of_names = [ map { $_->name } ($category ? @$bodies : values %{$c->stash->{bodies_to_list}}) ];
- my $vars = {
- $category ? (list_of_names => $list_of_names) : (),
- };
+ my @bodies;
+ my $bodies = [];
+ my $vars = {};
+ if ($category) {
+ $bodies = $c->forward('contacts_to_bodies', [ $category ]);
+ @bodies = @$bodies;
+ $vars->{list_of_names} = [ map { $_->cobrand_name } @bodies ];
+ } else {
+ @bodies = values %{$c->stash->{bodies_to_list}};
+ }
my $non_public = $c->stash->{non_public_categories}->{$category};
my $body = {
- bodies => $list_of_names,
+ bodies => [ map { $_->name } @bodies ],
$non_public ? ( non_public => JSON->true ) : (),
};
@@ -743,7 +748,7 @@ sub setup_categories_and_bodies : Private {
push @category_options, $seen{_('Other')} if $seen{_('Other')};
}
- $c->cobrand->call_hook(munge_category_list => \@category_options, \@contacts, \%category_extras);
+ $c->cobrand->call_hook(munge_report_new_category_list => \@category_options, \@contacts, \%category_extras);
# put results onto stash for display
$c->stash->{bodies} = \%bodies;
diff --git a/perllib/FixMyStreet/App/Controller/Reports.pm b/perllib/FixMyStreet/App/Controller/Reports.pm
index d8d52a2d9..741cbb60f 100644
--- a/perllib/FixMyStreet/App/Controller/Reports.pm
+++ b/perllib/FixMyStreet/App/Controller/Reports.pm
@@ -165,10 +165,13 @@ sub ward : Path : Args(2) {
$c->stash->{stats} = $c->cobrand->get_report_stats();
my @categories = $c->stash->{body}->contacts->not_deleted->search( undef, {
- columns => [ 'id', 'category', 'extra' ],
+ columns => [ 'id', 'category', 'extra', 'body_id', 'send_method' ],
distinct => 1,
order_by => [ 'category' ],
} )->all;
+
+ $c->cobrand->call_hook('munge_reports_category_list', \@categories);
+
$c->stash->{filter_categories} = \@categories;
$c->stash->{filter_category} = { map { $_ => 1 } $c->get_param_list('filter_category', 1) };