diff options
author | Dave Arter <davea@mysociety.org> | 2016-07-19 15:56:26 +0100 |
---|---|---|
committer | Dave Arter <davea@mysociety.org> | 2016-09-06 15:05:09 +0100 |
commit | 6f82bb9e094d679d24a6286259e7652fd1304639 (patch) | |
tree | 82e1375a50daacd03750328a1bdaef7568a48d38 /perllib/FixMyStreet/App/Controller | |
parent | d3ce66d0add6754dd54624f1d35efc922054ce9b (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/App/Controller')
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Admin.pm | 71 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Location.pm | 2 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Report.pm | 98 |
3 files changed, 162 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; |