aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet
diff options
context:
space:
mode:
authorDave Arter <davea@mysociety.org>2016-07-19 15:56:26 +0100
committerDave Arter <davea@mysociety.org>2016-09-06 15:05:09 +0100
commit6f82bb9e094d679d24a6286259e7652fd1304639 (patch)
tree82e1375a50daacd03750328a1bdaef7568a48d38 /perllib/FixMyStreet
parentd3ce66d0add6754dd54624f1d35efc922054ce9b (diff)
Add inspector report detail view
Users with the `report_inspect` permission can click a new 'inspect' button on a report page to input more detailed problem information into a new form that appears in a column alongside the report detail. - Inspector data is stored in problem's 'extra' field - Report category/state can be edited - Location can be changed by dragging the pin or HTML5 geolocation (Factored out Zurich admin pin drag into own function) For mysociety/fixmystreetforcouncils#22
Diffstat (limited to 'perllib/FixMyStreet')
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin.pm71
-rw-r--r--perllib/FixMyStreet/App/Controller/Location.pm2
-rw-r--r--perllib/FixMyStreet/App/Controller/Report.pm98
-rw-r--r--perllib/FixMyStreet/Cobrand/Oxfordshire.pm9
4 files changed, 171 insertions, 9 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm
index 63414b555..652113734 100644
--- a/perllib/FixMyStreet/App/Controller/Admin.pm
+++ b/perllib/FixMyStreet/App/Controller/Admin.pm
@@ -764,12 +764,7 @@ sub report_edit : Path('report_edit') : Args(1) {
}
$problem->set_inflated_columns(\%columns);
- if ((my $category = $c->get_param('category')) ne $problem->category) {
- $problem->category($category);
- my @contacts = grep { $_->category eq $problem->category } @{$c->stash->{contacts}};
- my $bs = join( ',', map { $_->body_id } @contacts );
- $problem->bodies_str($bs);
- }
+ $c->forward( '/admin/report_edit_category', [ $problem ] );
if ( $c->get_param('email') ne $problem->user->email ) {
my $user = $c->model('DB::User')->find_or_create(
@@ -813,6 +808,70 @@ sub report_edit : Path('report_edit') : Args(1) {
return 1;
}
+=head2 report_edit_category
+
+Handles changing a problem's category and the complexity that comes with it.
+
+=cut
+
+sub report_edit_category : Private {
+ my ($self, $c, $problem) = @_;
+
+ # TODO: It's possible to assign a category belonging to a district
+ # council, meaning a 404 when the page is reloaded because the
+ # problem is no longer included in the current cobrand's
+ # problem_restriction.
+ # See mysociety/fixmystreetforcouncils#44
+ # We could
+ # a) only allow the current body's categories to be chosen,
+ # b) show a warning about the impending change of body
+ # c) bounce the user to the report page on fms.com
+ # Not too worried about this right now, as it forms part of a bigger
+ # concern outlined in the above ticket and
+ # mysociety/fixmystreetforcouncils#17
+ if ((my $category = $c->get_param('category')) ne $problem->category) {
+ $problem->category($category);
+ my @contacts = grep { $_->category eq $problem->category } @{$c->stash->{contacts}};
+ my $bs = join( ',', map { $_->body_id } @contacts );
+ $problem->bodies_str($bs);
+ }
+}
+
+=head2 report_edit_location
+
+Handles changing a problem's location and the complexity that comes with it.
+For now, we reject the new location if the new location and old locations aren't
+covered by the same body.
+
+Returns 1 if the new position (if any) is acceptable, undef otherwise.
+
+NB: This must be called before report_edit_category, as that might modify
+$problem->bodies_str.
+
+=cut
+
+sub report_edit_location : Private {
+ my ($self, $c, $problem) = @_;
+
+ return 1 unless $c->forward('/report/new/determine_location');
+
+ if ( $c->stash->{latitude} != $problem->latitude || $c->stash->{longitude} != $problem->longitude ) {
+ delete $c->stash->{prefetched_all_areas};
+ delete $c->stash->{all_areas};
+ delete $c->stash->{fetch_all_areas};
+ delete $c->stash->{all_areas_mapit};
+ $c->forward('/council/load_and_check_areas');
+ $c->forward('/report/new/setup_categories_and_bodies');
+ my %allowed_bodies = map { $_ => 1 } @{$problem->bodies_str_ids};
+ my @new_bodies = @{$c->stash->{bodies_to_list}};
+ my $bodies_match = grep { exists( $allowed_bodies{$_} ) } @new_bodies;
+ return unless $bodies_match;
+ $problem->latitude($c->stash->{latitude});
+ $problem->longitude($c->stash->{longitude});
+ }
+ return 1;
+}
+
sub categories_for_point : Private {
my ($self, $c) = @_;
diff --git a/perllib/FixMyStreet/App/Controller/Location.pm b/perllib/FixMyStreet/App/Controller/Location.pm
index c457c8fce..6a0f2c0ec 100644
--- a/perllib/FixMyStreet/App/Controller/Location.pm
+++ b/perllib/FixMyStreet/App/Controller/Location.pm
@@ -31,6 +31,8 @@ sub determine_location_from_coords : Private {
my $latitude = $c->get_param('latitude') || $c->get_param('lat');
my $longitude = $c->get_param('longitude') || $c->get_param('lon');
+ $c->log->debug($longitude);
+ $c->log->debug($latitude);
if ( defined $latitude && defined $longitude ) {
($c->stash->{latitude}, $c->stash->{longitude}) =
diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm
index 6ac3c8ea1..2f6418886 100644
--- a/perllib/FixMyStreet/App/Controller/Report.pm
+++ b/perllib/FixMyStreet/App/Controller/Report.pm
@@ -278,10 +278,85 @@ sub delete :Local :Args(1) {
return $c->res->redirect($uri);
}
-sub map : Path('') : Args(2) {
- my ( $self, $c, $id, $map ) = @_;
+=head2 action_router
+
+A router for dispatching handlers for sub-actions on a particular report,
+e.g. /report/1/inspect
+
+=cut
+
+sub action_router : Path('') : Args(2) {
+ my ( $self, $c, $id, $action ) = @_;
+
+ $c->go( 'inspect', [ $id ] ) if $action eq 'inspect';
+ $c->go( 'map', [ $id ] ) if $action eq 'map';
+
+ $c->detach( '/page_error_404_not_found', [] );
+}
+
+sub inspect : Private {
+ my ( $self, $c, $id ) = @_;
+
+ $c->forward('/auth/get_csrf_token');
+ $c->forward( 'load_problem_or_display_error', [ $id ] );
+ $c->forward( 'check_has_permission_to', [ 'report_inspect' ] );
+ $c->forward( 'load_updates' );
+ $c->forward( 'format_problem_for_display' );
+
+ my $problem = $c->stash->{problem};
+
+ $c->stash->{categories} = $c->forward('/admin/categories_for_point');
+
+ # The available priorities for this problem are dependent on the cobrand it
+ # was reported to, not necessarily the active cobrand (e.g. inspecting a
+ # report on fms.com that was sent to Oxfordshire), so make sure the correct
+ # priorities are available for selection.
+ if ( $c->cobrand->can('get_body_handler_for_problem') ) {
+ my $handler = $c->cobrand->get_body_handler_for_problem($c->stash->{problem});
+ if ( $handler->can('problem_response_priorities') ) {
+ $c->stash->{priorities} = $handler->problem_response_priorities;
+ }
+ }
+
+ if ( $c->get_param('save') ) {
+ $c->forward('/auth/check_csrf_token');
+
+ foreach (qw/priority detailed_location detailed_information traffic_information/) {
+ $problem->set_extra_metadata( $_ => $c->get_param($_) );
+ }
+
+ # Handle the state changing
+ my $old_state = $problem->state;
+ $problem->state($c->get_param('state'));
+ if ( $problem->is_visible() and $old_state eq 'unconfirmed' ) {
+ $problem->confirmed( \'current_timestamp' );
+ }
+ if ( $problem->state eq 'hidden' ) {
+ $problem->get_photoset->delete_cached;
+ }
+ if ( $problem->state ne $old_state ) {
+ $c->forward( '/admin/log_edit', [ $id, 'problem', 'state_change' ] );
+ }
+
+ my $valid = 1;
+ if ( !$c->forward( '/admin/report_edit_location', [ $problem ] ) ) {
+ # New lat/lon isn't valid, show an error
+ $valid = 0;
+ $c->stash->{errors} = [ _('Invalid location. New location must be covered by the same council.') ];
+ }
+
+ $c->forward( '/admin/report_edit_category', [ $problem ] );
+
+ if ($valid) {
+ $problem->update;
+ $c->res->redirect( $c->uri_for( '/report', $problem->id, 'inspect' ) );
+ }
+ }
+};
+
+sub map : Private {
+ my ( $self, $c, $id ) = @_;
- $c->detach( '/page_error_404_not_found', [] ) unless $map eq 'map';
$c->forward( 'load_problem_or_display_error', [ $id ] );
my $image = $c->stash->{problem}->static_map;
@@ -289,6 +364,23 @@ sub map : Path('') : Args(2) {
$c->res->body($image->{data});
}
+
+=head2 check_has_permission_to
+
+Ensure the currently logged-in user has a particular permission that applies
+to the current Problem in $c->stash->{problem}. Shows the 403 page if not.
+
+=cut
+
+sub check_has_permission_to : Private {
+ my ( $self, $c, $permission ) = @_;
+
+ my $bodies = $c->stash->{problem}->bodies_str;
+
+ $c->detach('/page_error_403_access_denied', [ _("Sorry, you don't have permission to do that.") ] )
+ unless $c->user_exists && $c->user->has_permission_to($permission, $bodies);
+};
+
__PACKAGE__->meta->make_immutable;
1;
diff --git a/perllib/FixMyStreet/Cobrand/Oxfordshire.pm b/perllib/FixMyStreet/Cobrand/Oxfordshire.pm
index d127f5e13..8def4fb06 100644
--- a/perllib/FixMyStreet/Cobrand/Oxfordshire.pm
+++ b/perllib/FixMyStreet/Cobrand/Oxfordshire.pm
@@ -92,6 +92,15 @@ sub problem_response_days {
return undef;
}
+sub problem_response_priorities {
+ return {
+ cat1a => 'Cat 1A (4 hours)',
+ cat1b => 'Cat 1B (24 hours)',
+ cat2 => 'Cat 2 (2 days)',
+ cat3 => 'Cat 3 (10 days)',
+ };
+}
+
sub reports_ordering {
return { -desc => 'confirmed' };
}