aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet
diff options
context:
space:
mode:
Diffstat (limited to 'perllib/FixMyStreet')
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin.pm46
-rw-r--r--perllib/FixMyStreet/App/Controller/Council.pm7
-rw-r--r--perllib/FixMyStreet/App/Controller/Report/New.pm13
-rw-r--r--perllib/FixMyStreet/Cobrand/Buckinghamshire.pm304
-rw-r--r--perllib/FixMyStreet/Cobrand/Default.pm1
-rw-r--r--perllib/FixMyStreet/Map/Buckinghamshire.pm19
-rw-r--r--perllib/FixMyStreet/Script/Reports.pm1
-rw-r--r--perllib/FixMyStreet/TestAppProve.pm8
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;