diff --git a/perllib/FixMyStreet/App/Controller/Dashboard.pm b/perllib/FixMyStreet/App/Controller/Dashboard.pm
index 8202a471bbd..c3cb07f6074 100644
--- a/perllib/FixMyStreet/App/Controller/Dashboard.pm
+++ b/perllib/FixMyStreet/App/Controller/Dashboard.pm
@@ -126,11 +126,25 @@ sub index : Path : Args(0) {
$c->stash->{contacts} = [ $c->stash->{contacts}->all ];
$c->forward('/report/stash_category_groups', [ $c->stash->{contacts} ]);
+ my %group_names = map { $_->{name} => $_->{categories} } @{$c->stash->{category_groups}};
# See if we've had anything from the body dropdowns
$c->stash->{category} = [ $c->get_param_list('category') ];
+ my @remove_from_display;
+
+ foreach (@{$c->stash->{category}}) {
+ next unless /^group-(.*)/;
+ for my $contact (@{$group_names{$1}}) {
+ push @{ $c->stash->{category} }, $contact->category;
+ push @remove_from_display, $contact->category;
+ }
+ }
+
my %display_categories = map { $_ => 1 } @{$c->stash->{category}};
+ delete $display_categories{$_} for (@remove_from_display);
$c->stash->{display_categories} = \%display_categories;
+ @{$c->stash->{category}} = grep { $_ !~ /^group-/} @{$c->stash->{category}};
+
$c->stash->{ward} = [ $c->get_param_list('ward') ];
if ($c->user_exists) {
@@ -190,7 +204,7 @@ sub construct_rs_filter : Private {
my $reporting = FixMyStreet::Reporting->new(
type => $updates ? 'updates' : 'problems',
- category => $c->stash->{category},
+ category => $c->stash->{category} || [],
state => $c->stash->{q_state},
wards => $c->stash->{ward},
body => $c->stash->{body} || undef,
diff --git a/perllib/FixMyStreet/Reporting.pm b/perllib/FixMyStreet/Reporting.pm
index 215526f737b..5807286164e 100644
--- a/perllib/FixMyStreet/Reporting.pm
+++ b/perllib/FixMyStreet/Reporting.pm
@@ -18,7 +18,7 @@ has on_updates => ( is => 'lazy', default => sub { $_[0]->type eq 'updates' } );
has body => ( is => 'ro', isa => Maybe[InstanceOf['FixMyStreet::DB::Result::Body']] );
has wards => ( is => 'ro', isa => ArrayRef[Int], default => sub { [] } );
-has category => ( is => 'ro', isa => Maybe[ArrayRef[Maybe[Str]]], default => sub { [] } );
+has category => ( is => 'ro', isa => ArrayRef[Str], default => sub { [] } );
has state => ( is => 'ro', isa => Maybe[Str] );
has start_date => ( is => 'ro',
isa => Str,
@@ -95,9 +95,7 @@ has filename => ( is => 'rw', isa => Str, lazy => 1, default => sub {
start_date => $self->start_date,
end_date => $self->end_date,
);
- if ($self->category) {
- $where{category} = @{$self->category} < 3 ? join(',', @{$self->category}) : 'multiple-categories';
- }
+ $where{category} = @{$self->category} < 3 ? join(',', @{$self->category}) : 'multiple-categories';
$where{body} = $self->body->id if $self->body;
$where{role} = $self->role_id if $self->role_id;
my $host = URI->new($self->cobrand->base_url)->host;
@@ -123,7 +121,7 @@ sub construct_rs_filter {
$where{areas} = [ map { { 'like', "%,$_,%" } } @{$self->wards} ]
if @{$self->wards};
$where{"$table_name.category"} = $self->category
- if $self->category && @{$self->category};
+ if @{$self->category};
my $all_states = $self->cobrand->call_hook('dashboard_export_include_all_states');
if ( $self->state && FixMyStreet::DB::Result::Problem->fixed_states->{$self->state} ) { # Probably fixed - council
@@ -380,7 +378,7 @@ sub kick_off_process {
foreach (qw(type state start_date end_date)) {
$cmd .= " --$_ " . quotemeta($self->$_) if $self->$_;
}
- $cmd .= " --category " . join('::', map { quotemeta } @{$self->category}) if ($self->category && @{$self->category});
+ $cmd .= " --category " . join('::', map { quotemeta } @{$self->category}) if @{$self->category};
foreach (qw(body user)) {
$cmd .= " --$_ " . $self->$_->id if $self->$_;
}
@@ -493,7 +491,7 @@ sub filter_premade_csv {
}
my $category = $row->{Subcategory} || $row->{Category};
- next if ($self->category && @{$self->category}) && !grep { /$category/ } @{$self->category};
+ next if @{$self->category} && !grep { /$category/ } @{$self->category};
if ( $self->state && $fixed_states->{$self->state} ) { # Probably fixed - council
next unless $fixed_states->{$row->{$state_column}};
diff --git a/t/app/controller/admin/report_edit.t b/t/app/controller/admin/report_edit.t
index bb7cc26372b..a2c820225b5 100644
--- a/t/app/controller/admin/report_edit.t
+++ b/t/app/controller/admin/report_edit.t
@@ -10,8 +10,10 @@ my $superuser = $mech->create_user_ok('superuser@example.com', name => 'Super Us
my $oxfordshire = $mech->create_body_ok(2237, 'Oxfordshire County Council');
my $user3 = $mech->create_user_ok('body_user@example.com', name => 'Body User', from_body => $oxfordshire);
-my $oxfordshirecontact = $mech->create_contact_ok( body_id => $oxfordshire->id, category => 'Potholes', email => 'potholes@example.com' );
+my $oxfordshirecontact = $mech->create_contact_ok( body_id => $oxfordshire->id, category => 'Potholes', email => 'potholes@example.com', extra => { group => 'Road' } );
$mech->create_contact_ok( body_id => $oxfordshire->id, category => 'Traffic lights', email => 'lights@example.com' );
+$mech->create_contact_ok( body_id => $oxfordshire->id, category => 'Yellow lines', email => 'yellow@example.com', extra => { group => 'Road' } );
+
my $oxford = $mech->create_body_ok(2421, 'Oxford City Council');
$mech->create_contact_ok( body_id => $oxford->id, category => 'Graffiti', email => 'graffiti@example.net' );
@@ -58,7 +60,7 @@ my $log_entries = FixMyStreet::DB->resultset('AdminLog')->search(
object_type => 'problem',
object_id => $report->id
},
- {
+ {
order_by => { -desc => 'id' },
}
);
@@ -455,7 +457,8 @@ subtest 'change report category' => sub {
whensent => \'current_timestamp',
});
$mech->get_ok("/admin/report_edit/" . $ox_report->id);
-
+ $mech->content_contains('
diff --git a/templates/web/base/report/new/_category_select.html b/templates/web/base/report/new/_category_select.html
index 263b2432797..6f2c9c18d58 100644
--- a/templates/web/base/report/new/_category_select.html
+++ b/templates/web/base/report/new/_category_select.html
@@ -1,5 +1,10 @@
[%~ FOREACH group IN category_groups ~%]
- [% IF group.name %][% END %]
+ [% IF group.name AND include_group_option %]
+ [% SET pseudo_category = "group-" _ group.name %]
+
+ [% ELSIF group.name %]
+
+ [% END %]
[%~ FOREACH cat IN group.categories ~%]
[% INCLUDE category_option %]
[%~ END ~%]