diff options
Diffstat (limited to 'perllib/FixMyStreet')
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Admin.pm | 46 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Council.pm | 7 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Report/New.pm | 13 | ||||
-rw-r--r-- | perllib/FixMyStreet/Cobrand/Buckinghamshire.pm | 304 | ||||
-rw-r--r-- | perllib/FixMyStreet/Cobrand/Default.pm | 1 | ||||
-rw-r--r-- | perllib/FixMyStreet/Map/Buckinghamshire.pm | 19 | ||||
-rw-r--r-- | perllib/FixMyStreet/Script/Reports.pm | 1 | ||||
-rw-r--r-- | perllib/FixMyStreet/TestAppProve.pm | 8 |
8 files changed, 390 insertions, 9 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm index 96fe086c3..1256ae3b7 100644 --- a/perllib/FixMyStreet/App/Controller/Admin.pm +++ b/perllib/FixMyStreet/App/Controller/Admin.pm @@ -12,6 +12,7 @@ use DateTime::Format::Strptime; use List::Util 'first'; use List::MoreUtils 'uniq'; use mySociety::ArrayUtils; +use Text::CSV; use FixMyStreet::SendReport; use FixMyStreet::SMS; @@ -1636,6 +1637,51 @@ sub user_edit : Path('user_edit') : Args(1) { return 1; } +sub user_import : Path('user_import') { + my ( $self, $c, $id ) = @_; + + $c->forward('/auth/get_csrf_token'); + return unless $c->user_exists && $c->user->is_superuser; + + if ($c->req->method eq 'POST') { + $c->forward('/auth/check_csrf_token'); + $c->stash->{new_users} = []; + $c->stash->{existing_users} = []; + + my @all_permissions = map { keys %$_ } values %{ $c->cobrand->available_permissions }; + my %available_permissions = map { $_ => 1 } @all_permissions; + + my $csv = Text::CSV->new({ binary => 1}); + my $fh = $c->req->upload('csvfile')->fh; + $csv->getline($fh); # discard the header + while (my $row = $csv->getline($fh)) { + my ($name, $email, $from_body, $permissions) = @$row; + my @permissions = split(/:/, $permissions); + + my $user = FixMyStreet::DB->resultset("User")->find_or_new({ email => $email, email_verified => 1 }); + if ($user->in_storage) { + push @{$c->stash->{existing_users}}, $user; + next; + } + + $user->name($name); + $user->from_body($from_body || undef); + $user->update_or_insert; + + my @user_permissions = grep { $available_permissions{$_} } @permissions; + foreach my $permission_type (@user_permissions) { + $user->user_body_permissions->find_or_create({ + body_id => $user->from_body->id, + permission_type => $permission_type, + }); + } + + push @{$c->stash->{new_users}}, $user; + } + + } +} + sub contact_cobrand_extra_fields : Private { my ( $self, $c, $contact ) = @_; diff --git a/perllib/FixMyStreet/App/Controller/Council.pm b/perllib/FixMyStreet/App/Controller/Council.pm index 85976ae45..2e2dce0f7 100644 --- a/perllib/FixMyStreet/App/Controller/Council.pm +++ b/perllib/FixMyStreet/App/Controller/Council.pm @@ -51,8 +51,11 @@ sub load_and_check_areas : Private { # Cobrand may wish to add area types to look up for a point at runtime. # This can be used for, e.g., parish councils on a particular council - # cobrand. - $area_types = $c->cobrand->call_hook("add_extra_area_types" => $area_types) || $area_types; + # cobrand. NB three-tier councils break the alerts pages, so don't run the + # hook if we're on an alerts page. + unless ($c->stash->{area_check_action} eq 'alert') { + $area_types = $c->cobrand->call_hook("add_extra_area_types" => $area_types) || $area_types; + } my $all_areas; diff --git a/perllib/FixMyStreet/App/Controller/Report/New.pm b/perllib/FixMyStreet/App/Controller/Report/New.pm index 82787e9da..312268f65 100644 --- a/perllib/FixMyStreet/App/Controller/Report/New.pm +++ b/perllib/FixMyStreet/App/Controller/Report/New.pm @@ -875,6 +875,7 @@ sub process_report : Private { 'partial', # 'service', # 'non_public', + 'single_body_only' ); # load the report @@ -932,7 +933,7 @@ sub process_report : Private { return 1; } - my $bodies = $c->forward('contacts_to_bodies', [ $report->category ]); + my $bodies = $c->forward('contacts_to_bodies', [ $report->category, $params{single_body_only} ]); my $body_string = join(',', map { $_->id } @$bodies) || '-1'; $report->bodies_str($body_string); @@ -982,10 +983,18 @@ sub process_report : Private { } sub contacts_to_bodies : Private { - my ($self, $c, $category) = @_; + my ($self, $c, $category, $single_body_only) = @_; my @contacts = grep { $_->category eq $category } @{$c->stash->{contacts}}; + # check that we've not indicated we only want to sent to a single body + # and if we find a matching one then only send to that. e.g. if we clicked + # on a TfL road on the map. + if ($single_body_only) { + my @contacts_filtered = grep { $_->body->name eq $single_body_only } @contacts; + @contacts = @contacts_filtered if scalar @contacts_filtered; + } + if ($c->stash->{unresponsive}{$category} || $c->stash->{unresponsive}{ALL} || !@contacts) { []; } else { diff --git a/perllib/FixMyStreet/Cobrand/Buckinghamshire.pm b/perllib/FixMyStreet/Cobrand/Buckinghamshire.pm new file mode 100644 index 000000000..f045b530f --- /dev/null +++ b/perllib/FixMyStreet/Cobrand/Buckinghamshire.pm @@ -0,0 +1,304 @@ +package FixMyStreet::Cobrand::Buckinghamshire; +use parent 'FixMyStreet::Cobrand::UKCouncils'; + +use strict; +use warnings; + +sub council_area_id { return 2217; } +sub council_area { return 'Buckinghamshire'; } +sub council_name { return 'Buckinghamshire County Council'; } +sub council_url { return 'buckinghamshire'; } + +sub example_places { + return ( 'HP19 7QF', "Walton Road" ); +} + +sub base_url { + my $self = shift; + return $self->next::method() if FixMyStreet->config('STAGING_SITE'); + return 'https://fixmystreet.buckscc.gov.uk'; +} + +sub disambiguate_location { + my $self = shift; + my $string = shift; + + my $town = 'Buckinghamshire'; + + # The geocoder returns two results for 'Aylesbury', so force the better + # result to be used. + $town = "$town, HP20 2NH" if $string =~ /[\s]*aylesbury[\s]*/i; + + return { + %{ $self->SUPER::disambiguate_location() }, + town => $town, + centre => '51.7852948471218,-0.812140044990842', + span => '0.596065946222112,0.664092167105497', + bounds => [ 51.4854160129405, -1.1406945585036, 52.0814819591626, -0.476602391398098 ], + }; +} + +sub pin_colour { + my ( $self, $p, $context ) = @_; + return 'grey' if $p->state eq 'not responsible'; + return 'green' if $p->is_fixed || $p->is_closed; + return 'red' if $p->state eq 'confirmed'; + return 'yellow'; +} + +sub contact_email { + my $self = shift; + return join( '@', 'maverill', 'buckscc.gov.uk' ); +} + +sub send_questionnaires { + return 0; +} + +sub open311_config { + my ($self, $row, $h, $params) = @_; + + my $extra = $row->get_extra_fields; + push @$extra, + { name => 'report_url', + value => $h->{url} }, + { name => 'title', + value => $row->title }, + { name => 'description', + value => $row->detail }; + + $row->set_extra_fields(@$extra); +} + +sub map_type { 'Buckinghamshire' } + +sub default_map_zoom { 3 } + +sub enable_category_groups { 1 } + +# Enable adding/editing of parish councils in the admin +sub add_extra_areas { + my ($self, $areas) = @_; + + # This is a list of all Parish Councils within Buckinghamshire, + # taken from https://mapit.mysociety.org/area/2217/covers.json?type=CPC + my $parish_ids = [ + "135493", + "135494", + "148713", + "148714", + "53319", + "53360", + "53390", + "53404", + "53453", + "53486", + "53515", + "53542", + "53612", + "53822", + "53874", + "53887", + "53942", + "53991", + "54003", + "54014", + "54158", + "54174", + "54178", + "54207", + "54289", + "54305", + "54342", + "54355", + "54402", + "54465", + "54479", + "54493", + "54590", + "54615", + "54672", + "54691", + "54721", + "54731", + "54787", + "54846", + "54879", + "54971", + "55290", + "55326", + "55534", + "55638", + "55724", + "55775", + "55896", + "55900", + "55915", + "55945", + "55973", + "56007", + "56091", + "56154", + "56268", + "56350", + "56379", + "56418", + "56432", + "56498", + "56524", + "56592", + "56609", + "56641", + "56659", + "56664", + "56709", + "56758", + "56781", + "57099", + "57138", + "57330", + "57332", + "57366", + "57367", + "57507", + "57529", + "57582", + "57585", + "57666", + "57701", + "58166", + "58208", + "58229", + "58279", + "58312", + "58333", + "58405", + "58523", + "58659", + "58815", + "58844", + "58891", + "58965", + "58980", + "59003", + "59007", + "59012", + "59067", + "59144", + "59152", + "59179", + "59211", + "59235", + "59288", + "59353", + "59491", + "59518", + "59727", + "59763", + "59971", + "60027", + "60137", + "60321", + "60322", + "60438", + "60456", + "60462", + "60532", + "60549", + "60598", + "60622", + "60640", + "60731", + "60777", + "60806", + "60860", + "60954", + "61100", + "61102", + "61107", + "61142", + "61144", + "61167", + "61172", + "61249", + "61268", + "61269", + "61405", + "61445", + "61471", + "61479", + "61898", + "61902", + "61920", + "61964", + "62226", + "62267", + "62296", + "62311", + "62321", + "62431", + "62454", + "62640", + "62657", + "62938", + "63040", + "63053", + "63068", + "63470", + "63476", + "63501", + "63507", + "63517", + "63554", + "63715", + "63723" + ]; + my $ids_string = join ",", @{ $parish_ids }; + + my $extra_areas = mySociety::MaPit::call('areas', [ $ids_string ]); + + my %all_areas = ( + %$areas, + %$extra_areas + ); + return \%all_areas; +} + +# Make sure CPC areas are included in point lookups for new reports +sub add_extra_area_types { + my ($self, $types) = @_; + + my @types = ( + @$types, + 'CPC', + ); + return \@types; +} + +sub is_two_tier { 1 } + +sub should_skip_sending_update { + my ($self, $update ) = @_; + + # Bucks don't want to receive updates into Confirm that were made by anyone + # except the original problem reporter. + return $update->user_id != $update->problem->user_id; +} + +sub disable_phone_number_entry { 1 } + +sub report_sent_confirmation_email { 1 } + +sub is_council_with_case_management { 1 } + +# Try OSM for Bucks as it provides better disamiguation descriptions. +sub get_geocoder { 'OSM' } + +sub categories_restriction { + my ($self, $rs) = @_; + # Buckinghamshire is a two-tier council, but only want to display + # county-level categories on their cobrand. + return $rs->search( { 'body.id' => 2217 } ); +} + +1; diff --git a/perllib/FixMyStreet/Cobrand/Default.pm b/perllib/FixMyStreet/Cobrand/Default.pm index 8c4d8be53..99b247412 100644 --- a/perllib/FixMyStreet/Cobrand/Default.pm +++ b/perllib/FixMyStreet/Cobrand/Default.pm @@ -645,6 +645,7 @@ sub admin_pages { $pages->{flagged} = [ _('Flagged'), 7 ]; $pages->{states} = [ _('States'), 8 ]; $pages->{config} = [ _('Configuration'), 9]; + $pages->{user_import} = [ undef, undef ]; }; # And some that need special permissions if ( $user->has_body_permission_to('category_edit') ) { diff --git a/perllib/FixMyStreet/Map/Buckinghamshire.pm b/perllib/FixMyStreet/Map/Buckinghamshire.pm new file mode 100644 index 000000000..b6d86d4b9 --- /dev/null +++ b/perllib/FixMyStreet/Map/Buckinghamshire.pm @@ -0,0 +1,19 @@ +# FixMyStreet:Map::Buckinghamshire +# More JavaScript, for street assets + +package FixMyStreet::Map::Buckinghamshire; +use base 'FixMyStreet::Map::OSM'; + +use strict; + +sub map_javascript { [ + '/vendor/OpenLayers/OpenLayers.buckinghamshire.js', + '/vendor/OpenLayers.Projection.OrdnanceSurvey.js', + '/js/map-OpenLayers.js', + '/js/map-OpenStreetMap.js', + '/cobrands/fixmystreet-uk-councils/roadworks.js', + '/cobrands/fixmystreet/assets.js', + '/cobrands/buckinghamshire/js.js', +] } + +1; diff --git a/perllib/FixMyStreet/Script/Reports.pm b/perllib/FixMyStreet/Script/Reports.pm index 1d19ee283..5e8c99037 100644 --- a/perllib/FixMyStreet/Script/Reports.pm +++ b/perllib/FixMyStreet/Script/Reports.pm @@ -78,6 +78,7 @@ sub send(;$) { my $email_base_url = $cobrand->base_url_for_report($row); my %h = map { $_ => $row->$_ } qw/id title detail name category latitude longitude used_map/; $h{report} = $row; + $h{cobrand} = $cobrand; map { $h{$_} = $row->user->$_ || '' } qw/email phone/; $h{confirmed} = DateTime::Format::Pg->format_datetime( $row->confirmed->truncate (to => 'second' ) ) if $row->confirmed; diff --git a/perllib/FixMyStreet/TestAppProve.pm b/perllib/FixMyStreet/TestAppProve.pm index 4a55d587b..f0f5cab59 100644 --- a/perllib/FixMyStreet/TestAppProve.pm +++ b/perllib/FixMyStreet/TestAppProve.pm @@ -38,12 +38,10 @@ my $pg; sub spin_up_database { warn "Spinning up a Pg cluster/database...\n"; $pg = Test::PostgreSQL->new( - seed_scripts => [ - 'db/schema.sql', - 'db/fixture.sql', - 'db/generate_secret.sql', - ], + run_psql_args => '-1Xq -v ON_ERROR_STOP=1', # No -b on 9.1 ); + $pg->run_psql_scripts('db/schema.sql'); # On 9.1, must create tables separately + $pg->run_psql_scripts('db/fixture.sql', 'db/generate_secret.sql'); warn sprintf "# Connected to %s\n", $pg->dsn; |