aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/send-comments9
-rw-r--r--db/schema.sql11
-rw-r--r--db/schema_0025-add_more_statuses_to_problem.sql75
-rw-r--r--db/schema_0026-add_send_extended_comments_to_open311conf.sql6
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin.pm10
-rw-r--r--perllib/FixMyStreet/App/Controller/Dashboard.pm8
-rw-r--r--perllib/FixMyStreet/App/Controller/Report/Update.pm18
-rw-r--r--perllib/FixMyStreet/DB/Result/Comment.pm9
-rw-r--r--perllib/FixMyStreet/DB/Result/Open311conf.pm3
-rw-r--r--perllib/FixMyStreet/DB/Result/Problem.pm96
-rw-r--r--perllib/Open311.pm30
-rw-r--r--perllib/Open311/GetServiceRequestUpdates.pm32
-rw-r--r--t/app/controller/dashboard.t54
-rw-r--r--t/app/controller/questionnaire.t16
-rw-r--r--t/app/controller/report_display.t34
-rw-r--r--t/app/controller/report_updates.t400
-rw-r--r--t/app/model/problem.t28
-rw-r--r--t/app/model/questionnaire.t16
-rw-r--r--t/map/tilma/original.t16
-rw-r--r--t/open311.t105
-rw-r--r--t/open311/getservicerequestupdates.t162
-rw-r--r--templates/web/bromley/report/display.html8
-rw-r--r--templates/web/default/admin/council_contacts.html5
-rw-r--r--templates/web/default/dashboard/index.html16
-rw-r--r--templates/web/default/report/banner.html2
-rw-r--r--templates/web/default/report/update-form.html6
-rw-r--r--templates/web/default/report/updates.html21
-rw-r--r--templates/web/fixmystreet/report/banner.html6
-rw-r--r--templates/web/fixmystreet/report/update-form.html6
-rw-r--r--web/cobrands/fixmystreet/_layout.scss9
30 files changed, 1107 insertions, 110 deletions
diff --git a/bin/send-comments b/bin/send-comments
index 5a14098bf..24b436ac8 100755
--- a/bin/send-comments
+++ b/bin/send-comments
@@ -61,13 +61,20 @@ while ( my $council = $councils->next ) {
$use_extended = 1;
}
- my $o = Open311->new(
+ my %open311_conf = (
endpoint => $council->endpoint,
jurisdiction => $council->jurisdiction,
api_key => $council->api_key,
use_extended_updates => $use_extended,
);
+
+ if ( $council->send_extended_statuses ) {
+ $open311_conf{extended_statuses} = 1;
+ }
+
+ my $o = Open311->new( %open311_conf );
+
if ( $council->area_id =~ /2482/ ) {
my $endpoints = $o->endpoints;
$endpoints->{update} = 'update.xml';
diff --git a/db/schema.sql b/db/schema.sql
index 87e785de2..021c5561d 100644
--- a/db/schema.sql
+++ b/db/schema.sql
@@ -183,12 +183,16 @@ create table problem (
or state = 'investigating'
or state = 'planned'
or state = 'in progress'
+ or state = 'action scheduled'
or state = 'closed'
or state = 'fixed'
or state = 'fixed - council'
or state = 'fixed - user'
or state = 'hidden'
or state = 'partial'
+ or state = 'unable to fix'
+ or state = 'not responsible'
+ or state = 'duplicate'
),
lang text not null default 'en-gb',
service text not null default '',
@@ -331,10 +335,14 @@ create table comment (
or problem_state = 'investigating'
or problem_state = 'planned'
or problem_state = 'in progress'
+ or problem_state = 'action scheduled'
or problem_state = 'closed'
or problem_state = 'fixed'
or problem_state = 'fixed - council'
or problem_state = 'fixed - user'
+ or problem_state = 'unable to fix'
+ or problem_state = 'not responsible'
+ or problem_state = 'duplicate'
),
-- other fields? one to indicate whether this was written by the council
-- and should be highlighted in the display?
@@ -462,5 +470,6 @@ create table open311conf (
send_comments boolean not null default 'f',
comment_user_id int references users(id),
suppress_alerts boolean not null default 'f',
- can_be_devolved boolean not null default 'f'
+ can_be_devolved boolean not null default 'f',
+ send_extended_statuses boolean not null default 'f'
);
diff --git a/db/schema_0025-add_more_statuses_to_problem.sql b/db/schema_0025-add_more_statuses_to_problem.sql
new file mode 100644
index 000000000..9c49c8566
--- /dev/null
+++ b/db/schema_0025-add_more_statuses_to_problem.sql
@@ -0,0 +1,75 @@
+BEGIN;
+
+ ALTER TABLE problem DROP CONSTRAINT problem_state_check;
+
+ ALTER TABLE problem ADD CONSTRAINT problem_state_check CHECK (
+ state = 'unconfirmed'
+ or state = 'confirmed'
+ or state = 'investigating'
+ or state = 'planned'
+ or state = 'in progress'
+ or state = 'action scheduled'
+ or state = 'closed'
+ or state = 'fixed'
+ or state = 'fixed - council'
+ or state = 'fixed - user'
+ or state = 'hidden'
+ or state = 'partial'
+ or state = 'unable to fix'
+ or state = 'not responsible'
+ or state = 'duplicate'
+ );
+
+
+ ALTER TABLE comment DROP CONSTRAINT comment_problem_state_check;
+
+ ALTER TABLE comment ADD CONSTRAINT comment_problem_state_check CHECK (
+ problem_state = 'confirmed'
+ or problem_state = 'investigating'
+ or problem_state = 'planned'
+ or problem_state = 'in progress'
+ or problem_state = 'action scheduled'
+ or problem_state = 'closed'
+ or problem_state = 'fixed'
+ or problem_state = 'fixed - council'
+ or problem_state = 'fixed - user'
+ or problem_state = 'unable to fix'
+ or problem_state = 'not responsible'
+ or problem_state = 'duplicate'
+ );
+
+ UPDATE alert_type set item_where = 'nearby.problem_id = problem.id and problem.state in
+ (''confirmed'', ''investigating'', ''planned'', ''in progress'',
+ ''fixed'', ''fixed - council'', ''fixed - user'', ''closed'',
+ ''action scheduled'', ''not responsible'', ''duplicate'', ''unable to fix'' )'
+ WHERE ref = 'postcode_local_problems';
+ UPDATE alert_type set item_where = 'problem.state in
+ (''confirmed'', ''investigating'', ''planned'', ''in progress'',
+ ''fixed'', ''fixed - council'', ''fixed - user'', ''closed''
+ ''action scheduled'', ''not responsible'', ''duplicate'', ''unable to fix'' )'
+ WHERE ref = 'new_problems';
+ UPDATE alert_type set item_where = 'problem.state in (''fixed'', ''fixed - user'', ''fixed - council'')' WHERE ref = 'new_fixed_problems';
+ UPDATE alert_type set item_where = 'nearby.problem_id = problem.id and problem.state in
+ (''confirmed'', ''investigating'', ''planned'', ''in progress'',
+ ''fixed'', ''fixed - council'', ''fixed - user'', ''closed'',
+ ''action scheduled'', ''not responsible'', ''duplicate'', ''unable to fix'' )'
+ WHERE ref = 'local_problems';
+ UPDATE alert_type set item_where = 'problem.state in
+ (''confirmed'', ''investigating'', ''planned'', ''in progress'',
+ ''fixed'', ''fixed - council'', ''fixed - user'', ''closed'',
+ ''action scheduled'', ''not responsible'', ''duplicate'', ''unable to fix'' ) AND
+ (council like ''%''||?||''%'' or council is null) and
+ areas like ''%,''||?||'',%''' WHERE ref = 'council_problems';
+ UPDATE alert_type set item_where = 'problem.state in
+ (''confirmed'', ''investigating'', ''planned'', ''in progress'',
+ ''fixed'', ''fixed - council'', ''fixed - user'', ''closed'',
+ ''action scheduled'', ''not responsible'', ''duplicate'', ''unable to fix'' ) AND
+ (council like ''%''||?||''%'' or council is null) and
+ areas like ''%,''||?||'',%''' WHERE ref = 'ward_problems';
+ UPDATE alert_type set item_where = 'problem.state in
+ (''confirmed'', ''investigating'', ''planned'', ''in progress'',
+ ''fixed'', ''fixed - council'', ''fixed - user'', ''closed'',
+ ''action scheduled'', ''not responsible'', ''duplicate'', ''unable to fix'' ) AND
+ areas like ''%,''||?||'',%''' WHERE ref = 'area_problems';
+
+COMMIT;
diff --git a/db/schema_0026-add_send_extended_comments_to_open311conf.sql b/db/schema_0026-add_send_extended_comments_to_open311conf.sql
new file mode 100644
index 000000000..ee7b44b75
--- /dev/null
+++ b/db/schema_0026-add_send_extended_comments_to_open311conf.sql
@@ -0,0 +1,6 @@
+begin;
+
+ALTER table open311conf
+ ADD column send_extended_statuses BOOL NOT NULL DEFAULT 'f';
+
+commit;
diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm
index 7a2790b31..e14c7dc66 100644
--- a/perllib/FixMyStreet/App/Controller/Admin.pm
+++ b/perllib/FixMyStreet/App/Controller/Admin.pm
@@ -65,11 +65,9 @@ sub index : Path : Args(0) {
%prob_counts =
map { $_ => $prob_counts{$_} || 0 }
- ('confirmed', 'investigating', 'in progress', 'closed', 'fixed - council',
- 'fixed - user', 'fixed', 'unconfirmed', 'hidden',
- 'partial', 'planned');
+ ( FixMyStreet::DB::Result::Problem->all_states() );
$c->stash->{problems} = \%prob_counts;
- $c->stash->{total_problems_live} += $prob_counts{$_}
+ $c->stash->{total_problems_live} += $prob_counts{$_} ? $prob_counts{$_} : 0
for ( FixMyStreet::DB::Result::Problem->visible_states() );
$c->stash->{total_problems_users} = $c->cobrand->problems->unique_users;
@@ -351,7 +349,7 @@ sub update_contacts : Private {
} elsif ( $posted eq 'open311' ) {
$c->forward('check_token');
- my %params = map { $_ => $c->req->param($_) || '' } qw/open311_id endpoint jurisdiction api_key area_id send_method send_comments suppress_alerts comment_user_id devolved/;
+ my %params = map { $_ => $c->req->param($_) || '' } qw/open311_id endpoint jurisdiction api_key area_id send_method send_comments suppress_alerts extended_statuses comment_user_id devolved/;
if ( $params{open311_id} ) {
my $conf = $c->model('DB::Open311Conf')->find( { id => $params{open311_id} } );
@@ -364,6 +362,7 @@ sub update_contacts : Private {
$conf->suppress_alerts( $params{suppress_alerts} || 0);
$conf->comment_user_id( $params{comment_user_id} || undef );
$conf->can_be_devolved( $params{devolved} || 0 );
+ $conf->send_extended_statuses( $params{extended_statuses} || 0 );
$conf->update();
@@ -379,6 +378,7 @@ sub update_contacts : Private {
$conf->suppress_alerts( $params{suppress_alerts} || 0);
$conf->comment_user_id( $params{comment_user_id} || undef );
$conf->can_be_devolved( $params{devolved} || 0 );
+ $conf->send_extended_statuses( $params{extended_statuses} || 0 );
$conf->insert();
diff --git a/perllib/FixMyStreet/App/Controller/Dashboard.pm b/perllib/FixMyStreet/App/Controller/Dashboard.pm
index a5ba8ff07..17fd8b867 100644
--- a/perllib/FixMyStreet/App/Controller/Dashboard.pm
+++ b/perllib/FixMyStreet/App/Controller/Dashboard.pm
@@ -138,6 +138,8 @@ sub index : Path : Args(0) {
$prob_where->{state} = [ FixMyStreet::DB::Result::Problem->fixed_states() ];
} elsif ( $c->stash->{q_state} ) {
$prob_where->{state} = $c->stash->{q_state};
+ $prob_where->{state} = { IN => [ 'planned', 'action scheduled' ] }
+ if $prob_where->{state} eq 'action scheduled';
}
my $params = {
%$prob_where,
@@ -181,11 +183,13 @@ sub updates_search : Private {
map { $_ => $counts{$_} || 0 }
('confirmed', 'investigating', 'in progress', 'closed', 'fixed - council',
'fixed - user', 'fixed', 'unconfirmed', 'hidden',
- 'partial', 'planned');
+ 'partial', 'action scheduled', 'planned');
+
+ $counts{'action scheduled'} += $counts{planned} || 0;
for my $vars (
[ 'time_to_fix', 'fixed - council' ],
- [ 'time_to_mark', 'in progress', 'planned', 'investigating', 'closed' ],
+ [ 'time_to_mark', 'in progress', 'action scheduled', 'investigating', 'closed' ],
) {
my $col = shift @$vars;
my $substmt = "select min(id) from comment where me.problem_id=comment.problem_id and problem_state in ('"
diff --git a/perllib/FixMyStreet/App/Controller/Report/Update.pm b/perllib/FixMyStreet/App/Controller/Report/Update.pm
index da4cc33ca..5e0d9f388 100644
--- a/perllib/FixMyStreet/App/Controller/Report/Update.pm
+++ b/perllib/FixMyStreet/App/Controller/Report/Update.pm
@@ -203,8 +203,23 @@ sub process_update : Private {
$params{state} = 'fixed - council'
if $params{state} eq 'fixed' && $c->user && $c->user->belongs_to_council( $update->problem->council );
$update->problem_state( $params{state} );
+ } else {
+ # we do this so we have a record of the state of the problem at this point
+ # for use when sending updates to external parties
+ if ( $update->mark_fixed ) {
+ $update->problem_state( 'fixed - user' );
+ } elsif ( $update->mark_open ) {
+ $update->problem_state( 'confirmed' );
+ # if there is not state param and neither of the above conditions apply
+ # then we are not changing the state of the problem so can use the current
+ # problem state
+ } else {
+ my $problem = $c->stash->{problem} || $update->problem;
+ $update->problem_state( $problem->state );
+ }
}
+
my @extra; # Next function fills this, but we don't need it here.
# This is just so that the error checkign for these extra fields runs.
# TODO Use extra here as it is used on reports.
@@ -249,7 +264,8 @@ sub check_for_errors : Private {
$error = 1 unless $c->user && $c->user->belongs_to_council( $c->stash->{update}->problem->council );
my $state = $c->req->param('state');
- $error = 1 unless ( grep { $state eq $_ } ( qw/confirmed closed fixed investigating planned/, 'in progress', 'fixed', 'fixed - user', 'fixed - council' ) );
+ $state = 'fixed - council' if $state eq 'fixed';
+ $error = 1 unless ( grep { $state eq $_ } ( FixMyStreet::DB::Result::Problem->council_states() ) );
if ( $error ) {
$c->stash->{errors} ||= [];
diff --git a/perllib/FixMyStreet/DB/Result/Comment.pm b/perllib/FixMyStreet/DB/Result/Comment.pm
index 8c9fea282..b551be9ef 100644
--- a/perllib/FixMyStreet/DB/Result/Comment.pm
+++ b/perllib/FixMyStreet/DB/Result/Comment.pm
@@ -146,6 +146,11 @@ sub check_for_errors {
$errors{update} = _('Please enter a message')
unless $self->text =~ m/\S/;
+ if ( $self->text && $self->problem && $self->problem->council
+ && $self->problem->council eq '2482' && length($self->text) > 2000 ) {
+ $errors{update} = _('Updates are limited to 2000 characters in length. Please shorten your update');
+ }
+
return \%errors;
}
@@ -186,6 +191,10 @@ sub meta_problem_state {
my $state = $self->problem_state;
$state =~ s/ -.*$//;
+ $state = _("not the council's responsibility")
+ if $state eq 'not responsible';
+ $state = _('duplicate report') if $state eq 'duplicate';
+
return $state;
}
diff --git a/perllib/FixMyStreet/DB/Result/Open311conf.pm b/perllib/FixMyStreet/DB/Result/Open311conf.pm
index 8051e27de..f01a20dec 100644
--- a/perllib/FixMyStreet/DB/Result/Open311conf.pm
+++ b/perllib/FixMyStreet/DB/Result/Open311conf.pm
@@ -36,6 +36,8 @@ __PACKAGE__->add_columns(
{ data_type => "boolean", default_value => \"false", is_nullable => 0 },
"can_be_devolved",
{ data_type => "boolean", default_value => \"false", is_nullable => 0 },
+ "send_extended_statuses",
+ { data_type => "boolean", default_value => \"false", is_nullable => 0 },
);
__PACKAGE__->set_primary_key("id");
__PACKAGE__->add_unique_constraint("open311conf_area_id_key", ["area_id"]);
@@ -55,6 +57,5 @@ __PACKAGE__->belongs_to(
# Created by DBIx::Class::Schema::Loader v0.07017 @ 2012-08-29 14:04:20
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Yoult8K/ldH6DMAKURtr3Q
-
# You can replace this text with custom code or comments, and it will be preserved on regeneration
1;
diff --git a/perllib/FixMyStreet/DB/Result/Problem.pm b/perllib/FixMyStreet/DB/Result/Problem.pm
index dd09ad3c2..b1f59e78a 100644
--- a/perllib/FixMyStreet/DB/Result/Problem.pm
+++ b/perllib/FixMyStreet/DB/Result/Problem.pm
@@ -196,10 +196,11 @@ HASHREF.
sub open_states {
my $states = {
- 'confirmed' => 1,
- 'investigating' => 1,
- 'planned' => 1,
- 'in progress' => 1,
+ 'confirmed' => 1,
+ 'investigating' => 1,
+ 'in progress' => 1,
+ 'planned' => 1,
+ 'action scheduled' => 1,
};
return wantarray ? keys %{$states} : $states;
@@ -237,7 +238,10 @@ HASHREF.
sub closed_states {
my $states = {
- 'closed' => 1,
+ 'closed' => 1,
+ 'unable to fix' => 1,
+ 'not responsible' => 1,
+ 'duplicate' => 1,
};
return wantarray ? keys %{$states} : $states;
@@ -248,7 +252,7 @@ sub closed_states {
@states = FixMyStreet::DB::Problem::visible_states();
-Get a list or states that should be visible on the site. If called in
+Get a list of states that should be visible on the site. If called in
array context then returns an array of names, otherwise returns a
HASHREF.
@@ -256,14 +260,73 @@ HASHREF.
sub visible_states {
my $states = {
- 'confirmed' => 1,
- 'planned' => 1,
- 'investigating' => 1,
- 'in progress' => 1,
- 'fixed' => 1,
- 'fixed - council' => 1,
- 'fixed - user' => 1,
- 'closed' => 1,
+ 'confirmed' => 1,
+ 'investigating' => 1,
+ 'in progress' => 1,
+ 'planned' => 1,
+ 'action scheduled' => 1,
+ 'fixed' => 1,
+ 'fixed - council' => 1,
+ 'fixed - user' => 1,
+ 'unable to fix' => 1,
+ 'not responsible' => 1,
+ 'duplicate' => 1,
+ 'closed' => 1,
+ };
+
+ return wantarray ? keys %{$states} : $states;
+}
+
+=head2
+
+ @states = FixMyStreet::DB::Problem::all_states();
+
+Get a list of all states that a problem can have. If called in
+array context then returns an array of names, otherwise returns a
+HASHREF.
+
+=cut
+
+sub all_states {
+ my $states = {
+ 'hidden' => 1,
+ 'partial' => 1,
+ 'unconfirmed' => 1,
+ 'confirmed' => 1,
+ 'investigating' => 1,
+ 'in progress' => 1,
+ 'action scheduled' => 1,
+ 'fixed' => 1,
+ 'fixed - council' => 1,
+ 'fixed - user' => 1,
+ 'unable to fix' => 1,
+ 'not responsible' => 1,
+ 'duplicate' => 1,
+ 'closed' => 1,
+ };
+
+ return wantarray ? keys %{$states} : $states;
+}
+
+=head2
+
+ @states = FixMyStreet::DB::Problem::council_states();
+
+Get a list of states that are availble to council users. If called in
+array context then returns an array of names, otherwise returns a
+HASHREF.
+
+=cut
+sub council_states {
+ my $states = {
+ 'confirmed' => 1,
+ 'investigating' => 1,
+ 'action scheduled' => 1,
+ 'in progress' => 1,
+ 'fixed - council' => 1,
+ 'unable to fix' => 1,
+ 'not responsible' => 1,
+ 'duplicate' => 1,
};
return wantarray ? keys %{$states} : $states;
@@ -364,6 +427,11 @@ sub check_for_errors {
$self->category(undef);
}
+ if ( $self->council && $self->detail &&
+ $self->council eq '2482' && length($self->detail) > 2000 ) {
+ $errors{detail} = _('Reports are limited to 2000 characters in length. Please shorten your report');
+ }
+
return \%errors;
}
diff --git a/perllib/Open311.pm b/perllib/Open311.pm
index 7a5493704..dee985fca 100644
--- a/perllib/Open311.pm
+++ b/perllib/Open311.pm
@@ -25,6 +25,7 @@ has send_notpinpointed => ( is => 'ro', isa => 'Bool', default => 0 );
has extended_description => ( is => 'ro', isa => 'Str', default => 1 );
has use_service_as_deviceid => ( is => 'ro', isa => 'Bool', default => 0 );
has use_extended_updates => ( is => 'ro', isa => 'Bool', default => 0 );
+has extended_statuses => ( is => 'ro', isa => 'Bool', default => 0 );
before [
qw/get_service_list get_service_meta_info get_service_requests get_service_request_updates
@@ -287,10 +288,37 @@ sub _populate_service_request_update_params {
my $name = $comment->name || $comment->user->name;
my ( $firstname, $lastname ) = ( $name =~ /(\w+)\.?\s+(.+)/ );
+ # fall back to problem state as it's probably correct
+ my $state = $comment->problem_state || $comment->problem->state;
+
+ my $status = 'OPEN';
+ if ( $self->extended_statuses ) {
+ if ( FixMyStreet::DB::Result::Problem->fixed_states()->{$state} ) {
+ $status = 'FIXED';
+ } elsif ( $state eq 'in progress' ) {
+ $status = 'IN_PROGRESS';
+ } elsif ($state eq 'action scheduled'
+ || $state eq 'planned' ) {
+ $status = 'ACTION_SCHEDULED';
+ } elsif ( $state eq 'investigating' ) {
+ $status = 'INVESTIGATING';
+ } elsif ( $state eq 'duplicate' ) {
+ $status = 'DUPLICATE';
+ } elsif ( $state eq 'not responsible' ) {
+ $status = 'NOT_COUNCILS_RESPONSIBILITY';
+ } elsif ( $state eq 'unable to fix' ) {
+ $status = 'NO_FURTHER_ACTION';
+ }
+ } else {
+ if ( !FixMyStreet::DB::Result::Problem->open_states()->{$state} ) {
+ $status = 'CLOSED';
+ }
+ }
+
my $params = {
updated_datetime => DateTime::Format::W3CDTF->format_datetime($comment->confirmed_local->set_nanosecond(0)),
service_request_id => $comment->problem->external_id,
- status => $comment->problem->is_open ? 'OPEN' : 'CLOSED',
+ status => $status,
email => $comment->user->email,
description => $comment->text,
last_name => $lastname,
diff --git a/perllib/Open311/GetServiceRequestUpdates.pm b/perllib/Open311/GetServiceRequestUpdates.pm
index 0b4e037fd..e337c0f57 100644
--- a/perllib/Open311/GetServiceRequestUpdates.pm
+++ b/perllib/Open311/GetServiceRequestUpdates.pm
@@ -113,12 +113,14 @@ sub update_comments {
# do not change the status of the problem as it's
# tricky to determine the right thing to do.
if ( $comment->created_local > $p->lastupdate_local ) {
- if ( $p->is_open and lc($request->{status}) eq 'closed' ) {
- $p->state( 'fixed - council' );
- $comment->problem_state( 'fixed - council' );
- } elsif ( ( $p->is_closed || $p->is_fixed ) and lc($request->{status}) eq 'open' ) {
- $p->state( 'confirmed' );
- $comment->problem_state( 'confirmed' );
+ my $state = $self->map_state( $request->{status} );
+
+ # don't update state unless it's an allowed state and it's
+ # actually changing the state of the problem
+ if ( FixMyStreet::DB::Result::Problem->council_states()->{$state} && $p->state ne $state &&
+ !( $p->is_fixed && FixMyStreet::DB::Result::Problem->fixed_states()->{$state} ) ) {
+ $p->state($state);
+ $comment->problem_state($state);
}
}
@@ -146,4 +148,22 @@ sub update_comments {
return 1;
}
+sub map_state {
+ my $self = shift;
+ my $incoming_state = shift;
+
+ $incoming_state = lc($incoming_state);
+ $incoming_state =~ s/_/ /g;
+
+ my %state_map = (
+ fixed => 'fixed - council',
+ 'not councils responsibility' => 'not responsible',
+ 'no further action' => 'unable to fix',
+ open => 'confirmed',
+ closed => 'fixed - council'
+ );
+
+ return $state_map{$incoming_state} || $incoming_state;
+}
+
1;
diff --git a/t/app/controller/dashboard.t b/t/app/controller/dashboard.t
index 47d10ff5c..25e144464 100644
--- a/t/app/controller/dashboard.t
+++ b/t/app/controller/dashboard.t
@@ -78,7 +78,7 @@ my $categories = scraper {
process "tr[id=fixed_user] > td", 'user[]' => 'TEXT',
process "tr[id=total_fixed] > td", 'total_fixed[]' => 'TEXT',
process "tr[id=in_progress] > td", 'in_progress[]' => 'TEXT',
- process "tr[id=planned] > td", 'planned[]' => 'TEXT',
+ process "tr[id=action_scheduled] > td", 'action_scheduled[]' => 'TEXT',
process "tr[id=investigating] > td", 'investigating[]' => 'TEXT',
process "tr[id=marked] > td", 'marked[]' => 'TEXT',
process "tr[id=avg_marked] > td", 'avg_marked[]' => 'TEXT',
@@ -212,10 +212,10 @@ foreach my $test (
}
},
{
- desc => 'marked as planned today',
+ desc => 'marked as action scheduled today',
confirm_dt => DateTime->now->subtract( days => 1 ),
mark_dt => DateTime->now,
- state => 'planned',
+ state => 'action scheduled',
counts => {
totals => $is_monday ? [ 0,5,5,5] : [5,5,5,5],
user => [1,1,1,1],
@@ -224,15 +224,15 @@ foreach my $test (
avg_marked => [1,1,1,1],
investigating => [1,1,1,1],
in_progress => [1,1,1,1],
- planned => [1,1,1,1],
+ action_scheduled => [1,1,1,1],
marked => [3,3,3,3]
}
},
{
- desc => 'marked as planned today, confirmed a week ago',
+ desc => 'marked as action scheduled today, confirmed a week ago',
confirm_dt => DateTime->now->subtract( days => 8 ),
mark_dt => DateTime->now,
- state => 'planned',
+ state => 'action scheduled',
counts => {
totals => $is_monday ? [0,5,6,6] : [5,5,6,6],
user => [1,1,1,1],
@@ -241,7 +241,7 @@ foreach my $test (
avg_marked => [3,3,3,3],
investigating => [1,1,1,1],
in_progress => [1,1,1,1],
- planned => [2,2,2,2],
+ action_scheduled => [2,2,2,2],
marked => [4,4,4,4]
}
},
@@ -259,7 +259,7 @@ foreach my $test (
avg_marked => [3,3,3,3],
investigating => [1,1,1,1],
in_progress => [1,1,1,1],
- planned => [2,2,2,2],
+ action_scheduled => [2,2,2,2],
marked => [4,4,4,4]
}
},
@@ -277,7 +277,7 @@ foreach my $test (
avg_marked => [3,3,3,3],
investigating => [1,1,1,1],
in_progress => [1,1,1,1],
- planned => [2,2,2,2],
+ action_scheduled => [2,2,2,2],
marked => [4,4,4,4]
}
},
@@ -295,7 +295,7 @@ foreach my $test (
avg_marked => [3,3,3,3],
investigating => [1,1,1,1],
in_progress => [1,1,1,1],
- planned => [2,2,2,2],
+ action_scheduled => [2,2,2,2],
marked => [4,4,4,4]
}
},
@@ -313,11 +313,30 @@ foreach my $test (
avg_marked => [2,2,2,2],
investigating => [1,1,1,1],
in_progress => [1,1,1,1],
- planned => [2,2,2,2],
+ action_scheduled => [2,2,2,2],
closed => [1,1,1,1],
marked => [5,5,5,5]
}
},
+ {
+ desc => 'marked as planned',
+ confirm_dt => DateTime->now->subtract( days => 1 ),
+ mark_dt => DateTime->now,
+ state => 'planned',
+ counts => {
+ totals => $is_monday ? [0,7,10,11] : [7,7,10,11],
+ user => [1,1,1,2],
+ council => [2,2,3,3],
+ total_fixed => [3,3,4,5],
+ avg_fixed => [5,5,7,7],
+ avg_marked => [2,2,2,2],
+ investigating => [1,1,1,1],
+ in_progress => [1,1,1,1],
+ action_scheduled => [3,3,3,3],
+ closed => [1,1,1,1],
+ marked => [6,6,6,6]
+ }
+ },
) {
subtest $test->{desc} => sub {
make_problem(
@@ -528,6 +547,17 @@ for my $test (
report_counts_after => [1,0,0],
},
{
+ desc => 'planned counted as action scheduled',
+ p1 => {
+ state => 'planned',
+ conf_dt => DateTime->now(),
+ category => 'Potholes',
+ },
+ state => 'action scheduled',
+ report_counts => [3,0,0],
+ report_counts_after => [1,0,0],
+ },
+ {
desc => 'All fixed states count as fixed',
p1 => {
state => 'fixed - council',
@@ -540,7 +570,7 @@ for my $test (
category => 'Potholes',
},
state => 'fixed',
- report_counts => [4,0,0],
+ report_counts => [5,0,0],
report_counts_after => [3,0,0],
},
) {
diff --git a/t/app/controller/questionnaire.t b/t/app/controller/questionnaire.t
index 3a6a3d6ad..d8d1eb4f3 100644
--- a/t/app/controller/questionnaire.t
+++ b/t/app/controller/questionnaire.t
@@ -329,6 +329,10 @@ for my $test (
fixed => 0
},
{
+ state => 'action scheduled',
+ fixed => 0
+ },
+ {
state => 'in progress',
fixed => 0
},
@@ -337,6 +341,18 @@ for my $test (
fixed => 0
},
{
+ state => 'duplicate',
+ fixed => 0
+ },
+ {
+ state => 'not responsible',
+ fixed => 0
+ },
+ {
+ state => 'unable to fix',
+ fixed => 0
+ },
+ {
state => 'closed',
fixed => 0
},
diff --git a/t/app/controller/report_display.t b/t/app/controller/report_display.t
index 3bb0913f1..82c98dc5c 100644
--- a/t/app/controller/report_display.t
+++ b/t/app/controller/report_display.t
@@ -283,6 +283,30 @@ for my $test (
fixed => 1
},
{
+ description => 'duplicate report',
+ date => DateTime->now,
+ state => 'duplicate',
+ banner_id => 'closed',
+ banner_text => 'closed',
+ fixed => 0
+ },
+ {
+ description => 'not responsible report',
+ date => DateTime->now,
+ state => 'not responsible',
+ banner_id => 'closed',
+ banner_text => 'closed',
+ fixed => 0
+ },
+ {
+ description => 'unable to fix report',
+ date => DateTime->now,
+ state => 'unable to fix',
+ banner_id => 'closed',
+ banner_text => 'closed',
+ fixed => 0
+ },
+ {
description => 'closed report',
date => DateTime->now,
state => 'closed',
@@ -299,6 +323,14 @@ for my $test (
fixed => 0
},
{
+ description => 'action scheduled report',
+ date => DateTime->now,
+ state => 'action scheduled',
+ banner_id => 'progress',
+ banner_text => 'progress',
+ fixed => 0
+ },
+ {
description => 'planned report',
date => DateTime->now,
state => 'planned',
@@ -307,7 +339,7 @@ for my $test (
fixed => 0
},
{
- description => 'in progressreport',
+ description => 'in progress report',
date => DateTime->now,
state => 'in progress',
banner_id => 'progress',
diff --git a/t/app/controller/report_updates.t b/t/app/controller/report_updates.t
index 82670d6cc..2204a9d99 100644
--- a/t/app/controller/report_updates.t
+++ b/t/app/controller/report_updates.t
@@ -477,64 +477,91 @@ for my $test (
state => 'investigating',
},
{
- desc => 'from authority user marks report as planned',
+ desc => 'from authority user marks report as in progress',
fields => {
name => $user->name,
may_show_name => 1,
add_alert => undef,
photo => '',
- update => 'Set state to planned',
- state => 'planned',
+ update => 'Set state to in progress',
+ state => 'in progress',
},
- state => 'planned',
+ state => 'in progress',
},
{
- desc => 'from authority user marks report as in progress',
+ desc => 'from authority user marks report as fixed',
fields => {
name => $user->name,
may_show_name => 1,
add_alert => undef,
photo => '',
- update => 'Set state to in progress',
- state => 'in progress',
+ update => 'Set state to fixed',
+ state => 'fixed',
},
- state => 'in progress',
+ state => 'fixed - council',
},
{
- desc => 'from authority user marks report as closed',
+ desc => 'from authority user marks report as confirmed',
fields => {
name => $user->name,
may_show_name => 1,
add_alert => undef,
photo => '',
- update => 'Set state to closed',
- state => 'closed',
+ update => 'Set state to confirmed',
+ state => 'confirmed',
},
- state => 'closed',
+ state => 'confirmed',
+ reopened => 1,
},
{
- desc => 'from authority user marks report as fixed',
+ desc => 'from authority user marks report as action scheduled',
fields => {
name => $user->name,
may_show_name => 1,
add_alert => undef,
photo => '',
- update => 'Set state to fixed',
- state => 'fixed',
+ update => 'Set state to action scheduled',
+ state => 'action scheduled',
},
- state => 'fixed - council',
+ state => 'action scheduled',
},
{
- desc => 'from authority user marks report as confirmed',
+ desc => 'from authority user marks report as unable to fix',
fields => {
name => $user->name,
may_show_name => 1,
add_alert => undef,
photo => '',
- update => 'Set state to confirmed',
- state => 'confirmed',
+ update => 'Set state to unable to fix',
+ state => 'unable to fix',
},
- state => 'confirmed',
+ state => 'unable to fix',
+ },
+ {
+ desc => 'from authority user marks report as not responsible',
+ fields => {
+ name => $user->name,
+ may_show_name => 1,
+ add_alert => undef,
+ photo => '',
+ update => 'Set state to not responsible',
+ state => 'not responsible',
+ },
+ state => 'not responsible',
+ meta => "not the council's responsibility"
+ },
+ {
+ desc => 'from authority user marks report as duplicate',
+ fields => {
+ name => $user->name,
+ may_show_name => 1,
+ add_alert => undef,
+ photo => '',
+ update => 'Set state to duplicate',
+ state => 'duplicate',
+ },
+ state => 'duplicate',
+ meta => 'duplicate report',
},
{
desc => 'from authority user marks report sent to two councils as fixed',
@@ -577,11 +604,11 @@ for my $test (
is $update->problem_state, $test->{state}, 'problem state set';
my $update_meta = $mech->extract_update_metas;
- # setting it to confirmed shouldn't say anything
- if ( $test->{fields}->{state} ne 'confirmed' ) {
- like $update_meta->[0], qr/marked as $test->{fields}->{state}$/, 'update meta includes state change';
+ my $meta_state = $test->{meta} || $test->{fields}->{state};
+ if ( $test->{reopened} ) {
+ like $update_meta->[0], qr/reopened$/, 'update meta says reopened';
} else {
- like $update_meta->[0], qr/reopened$/, 'update meta includes state change';
+ like $update_meta->[0], qr/marked as $meta_state$/, 'update meta includes state change';
}
like $update_meta->[0], qr{Test User \(Westminster City Council\)}, 'update meta includes council name';
$mech->content_contains( 'Test User (<strong>Westminster City Council</strong>)', 'council name in bold');
@@ -629,6 +656,105 @@ subtest 'check meta correct for comments marked confirmed but not marked open' =
unlike $update_meta->[0], qr/reopened$/, 'update meta does not say reopened';
};
+subtest "check comment with no status change has not status in meta" => sub {
+ $mech->log_in_ok( $user->email );
+ $user->from_council( 0 );
+ $user->update;
+
+ my $comment = $report->comments->first;
+ $comment->update( { mark_fixed => 1, problem_state => 'fixed - council' } );
+
+ $mech->get_ok("/report/$report_id");
+
+ $mech->submit_form_ok(
+ {
+ with_fields => {
+ name => $user->name,
+ may_show_name => 1,
+ add_alert => undef,
+ photo => '',
+ update => 'Comment that does not change state',
+ },
+ },
+ 'submit update'
+ );
+
+ $report->discard_changes;
+ my @updates = $report->comments->all;
+ is scalar @updates, 2, 'correct number of updates';
+
+ warn $updates[0]->problem_state;
+ warn $updates[1]->problem_state;
+ my $update = pop @updates;
+
+ is $report->state, 'fixed - council', 'correct report state';
+ is $update->problem_state, 'fixed - council', 'corect update state';
+ my $update_meta = $mech->extract_update_metas;
+ unlike $update_meta->[1], qr/marked as/, 'update meta does not include state change';
+
+ $user->from_council( 2504 );
+ $user->update;
+
+ $mech->get_ok("/report/$report_id");
+
+ $mech->submit_form_ok(
+ {
+ with_fields => {
+ name => $user->name,
+ may_show_name => 1,
+ add_alert => undef,
+ photo => '',
+ update => 'Comment that sets state to investigating',
+ state => 'investigating',
+ },
+ },
+ 'submit update'
+ );
+
+ $report->discard_changes;
+ @updates = $report->comments->all;
+ is scalar @updates, 3, 'correct number of updates';
+
+ $update = pop @updates;
+
+ is $report->state, 'investigating', 'correct report state';
+ is $update->problem_state, 'investigating', 'corect update state';
+ $update_meta = $mech->extract_update_metas;
+ like $update_meta->[0], qr/marked as fixed/, 'first update meta says fixed';
+ unlike $update_meta->[1], qr/marked as/, 'second update meta does not include state change';
+ like $update_meta->[2], qr/marked as investigating/, 'third update meta says investigating';
+
+ my $dt = DateTime->now;
+ my $comment = FixMyStreet::App->model('DB::Comment')->find_or_create(
+ {
+ problem_id => $report_id,
+ user_id => $user->id,
+ name => 'Other User',
+ mark_fixed => 'false',
+ text => 'This is some update text',
+ state => 'confirmed',
+ confirmed => $dt->ymd . ' ' . $dt->hms,
+ anonymous => 'f',
+ }
+ );
+
+ $mech->get_ok("/report/$report_id");
+
+ $report->discard_changes;
+ @updates = $report->comments->all;
+ is scalar @updates, 4, 'correct number of updates';
+
+ $update = pop @updates;
+
+ is $report->state, 'investigating', 'correct report state';
+ is $update->problem_state, undef, 'no update state';
+ $update_meta = $mech->extract_update_metas;
+ like $update_meta->[0], qr/marked as fixed/, 'first update meta says fixed';
+ unlike $update_meta->[1], qr/marked as/, 'second update meta does not include state change';
+ like $update_meta->[2], qr/marked as investigating/, 'third update meta says investigating';
+ unlike $update_meta->[3], qr/marked as/, 'fourth update meta has no state change';
+};
+
$user->from_council(0);
$user->update;
@@ -1286,6 +1412,232 @@ for my $test (
};
}
+for my $test (
+ {
+ desc => 'update confirmed without marking as fixed leaves state unchanged',
+ initial_state => 'confirmed',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 0,
+ },
+ end_state => 'confirmed',
+ },
+ {
+ desc => 'update investigating without marking as fixed leaves state unchanged',
+ initial_state => 'investigating',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 0,
+ },
+ end_state => 'investigating',
+ },
+ {
+ desc => 'update in progress without marking as fixed leaves state unchanged',
+ initial_state => 'in progress',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 0,
+ },
+ end_state => 'in progress',
+ },
+ {
+ desc => 'update action scheduled without marking as fixed leaves state unchanged',
+ initial_state => 'action scheduled',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 0,
+ },
+ end_state => 'action scheduled',
+ },
+ {
+ desc => 'update fixed without marking as open leaves state unchanged',
+ initial_state => 'fixed',
+ expected_form_fields => {
+ reopen => undef,
+ },
+ submitted_form_fields => {
+ reopen => 0,
+ },
+ end_state => 'fixed',
+ },
+ {
+ desc => 'update unable to fix without marking as fixed leaves state unchanged',
+ initial_state => 'unable to fix',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 0,
+ },
+ end_state => 'unable to fix',
+ },
+ {
+ desc => 'update not responsible without marking as fixed leaves state unchanged',
+ initial_state => 'not responsible',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 0,
+ },
+ end_state => 'not responsible',
+ },
+ {
+ desc => 'update duplicate without marking as fixed leaves state unchanged',
+ initial_state => 'duplicate',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 0,
+ },
+ end_state => 'duplicate',
+ },
+ {
+ desc => 'can mark confirmed as fixed',
+ initial_state => 'confirmed',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 1,
+ },
+ end_state => 'fixed - user',
+ },
+ {
+ desc => 'can mark investigating as fixed',
+ initial_state => 'investigating',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 1,
+ },
+ end_state => 'fixed - user',
+ },
+ {
+ desc => 'can mark in progress as fixed',
+ initial_state => 'in progress',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 1,
+ },
+ end_state => 'fixed - user',
+ },
+ {
+ desc => 'can mark action scheduled as fixed',
+ initial_state => 'action scheduled',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 1,
+ },
+ end_state => 'fixed - user',
+ },
+ {
+ desc => 'cannot mark fixed as fixed, can mark as not fixed',
+ initial_state => 'fixed',
+ expected_form_fields => {
+ reopen => undef,
+ },
+ submitted_form_fields => {
+ reopen => 1,
+ },
+ end_state => 'confirmed',
+ },
+ {
+ desc => 'can mark unable to fix as fixed, cannot mark not closed',
+ initial_state => 'unable to fix',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 1,
+ },
+ end_state => 'fixed - user',
+ },
+ {
+ desc => 'can mark not responsible as fixed, cannot mark not closed',
+ initial_state => 'not responsible',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 1,
+ },
+ end_state => 'fixed - user',
+ },
+ {
+ desc => 'can mark duplicate as fixed, cannot mark not closed',
+ initial_state => 'duplicate',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 1,
+ },
+ end_state => 'fixed - user',
+ },
+) {
+ subtest $test->{desc} => sub {
+ $mech->log_in_ok( $report->user->email );
+
+ my %standard_fields = (
+ name => $report->user->name,
+ update => 'update text',
+ photo => '',
+ may_show_name => 1,
+ add_alert => 1,
+ );
+
+ my %expected_fields = (
+ %standard_fields,
+ %{ $test->{expected_form_fields} },
+ update => '',
+ );
+
+ my %submitted_fields = (
+ %standard_fields,
+ %{ $test->{submitted_form_fields} },
+ );
+
+ # clear out comments for this problem to make
+ # checking details easier later
+ ok( $_->delete, 'deleted comment ' . $_->id ) for $report->comments;
+
+ $report->discard_changes;
+ $report->state($test->{initial_state});
+ $report->update;
+
+ $mech->get_ok("/report/$report_id");
+
+ my $values = $mech->visible_form_values('updateForm');
+ is_deeply $values, \%expected_fields, 'correct form fields present';
+
+ if ( $test->{submitted_form_fields} ) {
+ $mech->submit_form_ok( {
+ with_fields => \%submitted_fields
+ },
+ 'submit update'
+ );
+
+ $report->discard_changes;
+ is $report->state, $test->{end_state}, 'update sets correct report state';
+ }
+ };
+}
+
subtest 'check have to be logged in for creator fixed questionnaire' => sub {
$mech->log_out_ok();
diff --git a/t/app/model/problem.t b/t/app/model/problem.t
index 63204e05c..040790184 100644
--- a/t/app/model/problem.t
+++ b/t/app/model/problem.t
@@ -302,6 +302,13 @@ for my $test (
is_closed => 0,
},
{
+ state => 'action scheduled',
+ is_visible => 1,
+ is_fixed => 0,
+ is_open => 1,
+ is_closed => 0,
+ },
+ {
state => 'in progress',
is_visible => 1,
is_fixed => 0,
@@ -309,6 +316,27 @@ for my $test (
is_closed => 0,
},
{
+ state => 'duplicate',
+ is_visible => 1,
+ is_fixed => 0,
+ is_open => 0,
+ is_closed => 1,
+ },
+ {
+ state => 'not responsible',
+ is_visible => 1,
+ is_fixed => 0,
+ is_open => 0,
+ is_closed => 1,
+ },
+ {
+ state => 'unable to fix',
+ is_visible => 1,
+ is_fixed => 0,
+ is_open => 0,
+ is_closed => 1,
+ },
+ {
state => 'fixed',
is_visible => 1,
is_fixed => 1,
diff --git a/t/app/model/questionnaire.t b/t/app/model/questionnaire.t
index 60b52043a..86af51c42 100644
--- a/t/app/model/questionnaire.t
+++ b/t/app/model/questionnaire.t
@@ -62,6 +62,10 @@ for my $test (
send_email => 1,
},
{
+ state => 'action scheduled',
+ send_email => 1,
+ },
+ {
state => 'in progress',
send_email => 1,
},
@@ -78,6 +82,18 @@ for my $test (
send_email => 1,
},
{
+ state => 'duplicate',
+ send_email => 1,
+ },
+ {
+ state => 'unable to fix',
+ send_email => 1,
+ },
+ {
+ state => 'not responsible',
+ send_email => 1,
+ },
+ {
state => 'closed',
send_email => 1,
},
diff --git a/t/map/tilma/original.t b/t/map/tilma/original.t
index 04c4d578c..7f68df308 100644
--- a/t/map/tilma/original.t
+++ b/t/map/tilma/original.t
@@ -71,10 +71,26 @@ for my $test (
colour => 'yellow',
},
{
+ state => 'duplicate',
+ colour => 'yellow',
+ },
+ {
+ state => 'unable to fix',
+ colour => 'yellow',
+ },
+ {
+ state => 'not responsible',
+ colour => 'yellow',
+ },
+ {
state => 'investigating',
colour => 'yellow',
},
{
+ state => 'action scheduled',
+ colour => 'yellow',
+ },
+ {
state => 'planned',
colour => 'yellow',
},
diff --git a/t/open311.t b/t/open311.t
index cbc8cf474..4c451d55e 100644
--- a/t/open311.t
+++ b/t/open311.t
@@ -192,6 +192,7 @@ my $comment = FixMyStreet::App->model('DB::Comment')->new( {
anonymous => 0,
text => 'this is a comment',
confirmed => $dt,
+ problem_state => 'confirmed',
extra => { title => 'Mr', email_alerts_requested => 0 },
} );
@@ -216,7 +217,7 @@ subtest 'basic request update post parameters' => sub {
};
subtest 'extended request update post parameters' => sub {
- my $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>', 1 );
+ my $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>', { extended_updates => 1 } );
is $results->{ res }, 248, 'got update id';
@@ -258,16 +259,40 @@ foreach my $test (
desc => 'comment with fixed state sends status of CLOSED',
state => 'fixed',
status => 'CLOSED',
+ extended => 'FIXED',
},
{
desc => 'comment with fixed - user state sends status of CLOSED',
state => 'fixed - user',
status => 'CLOSED',
+ extended => 'FIXED',
},
{
desc => 'comment with fixed - council state sends status of CLOSED',
state => 'fixed - council',
status => 'CLOSED',
+ extended => 'FIXED',
+ },
+ {
+ desc => 'comment with duplicate state sends status of CLOSED',
+ state => 'duplicate',
+ anon => 0,
+ status => 'CLOSED',
+ extended => 'DUPLICATE',
+ },
+ {
+ desc => 'comment with not reponsible state sends status of CLOSED',
+ state => 'not responsible',
+ anon => 0,
+ status => 'CLOSED',
+ extended => 'NOT_COUNCILS_RESPONSIBILITY',
+ },
+ {
+ desc => 'comment with unable to fix state sends status of CLOSED',
+ state => 'unable to fix',
+ anon => 0,
+ status => 'CLOSED',
+ extended => 'NO_FURTHER_ACTION',
},
{
desc => 'comment with closed state sends status of CLOSED',
@@ -278,11 +303,20 @@ foreach my $test (
desc => 'comment with investigating state sends status of OPEN',
state => 'investigating',
status => 'OPEN',
+ extended => 'INVESTIGATING',
},
{
desc => 'comment with planned state sends status of OPEN',
state => 'planned',
status => 'OPEN',
+ extended => 'ACTION_SCHEDULED',
+ },
+ {
+ desc => 'comment with action scheduled state sends status of OPEN',
+ state => 'action scheduled',
+ anon => 0,
+ status => 'OPEN',
+ extended => 'ACTION_SCHEDULED',
},
{
desc => 'comment with in progress state sends status of OPEN',
@@ -310,6 +344,7 @@ for my $test (
state => 'confirmed',
anon => 0,
status => 'OPEN',
+ extended => 'IN_PROGRESS',
},
{
desc => 'anonymous commment sets public_anonymity_required to true',
@@ -319,13 +354,73 @@ for my $test (
},
) {
subtest $test->{desc} => sub {
+ $comment->problem_state( $test->{state} );
$comment->problem->state( $test->{state} );
$comment->anonymous( $test->{anon} );
- my $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>', 1 );
+ my $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>', { extended_updates => 1 } );
my $c = CGI::Simple->new( $results->{ req }->content );
is $c->param('public_anonymity_required'), $test->{anon} ? 'TRUE' : 'FALSE', 'correct anonymity';
+
+ if ( $test->{extended} ) {
+ my $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>', { extended_statuses => 1 } );
+ my $c = CGI::Simple->new( $results->{ req }->content );
+ is $c->param('status'), $test->{extended}, 'correct extended status';
+ }
+ };
+}
+
+my $dt2 = $dt->clone;
+$dt2->add( 'minutes' => 1 );
+
+my $comment2 = FixMyStreet::App->model('DB::Comment')->new( {
+ id => 38363,
+ user => $user,
+ problem => $problem,
+ anonymous => 0,
+ text => 'this is a comment',
+ confirmed => $dt,
+ problem_state => 'confirmed',
+ extra => { title => 'Mr', email_alerts_requested => 0 },
+} );
+
+for my $test (
+ {
+ desc => 'comment with fixed - council state sends status of CLOSED even if problem is open',
+ state => 'fixed - council',
+ problem_state => 'confirmed',
+ status => 'CLOSED',
+ extended => 'FIXED',
+ },
+ {
+ desc => 'comment marked open sends status of OPEN even if problem is closed',
+ state => 'confirmed',
+ problem_state => 'fixed - council',
+ status => 'OPEN',
+ extended => 'OPEN',
+ },
+ {
+ desc => 'comment with no problem state falls back to report state',
+ state => '',
+ problem_state => 'fixed - council',
+ status => 'CLOSED',
+ extended => 'FIXED',
+ },
+) {
+ subtest $test->{desc} => sub {
+ $comment->problem_state( $test->{state} );
+ $comment->problem->state( $test->{problem_state} );
+ my $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>' );
+
+ my $c = CGI::Simple->new( $results->{ req }->content );
+ is $c->param('status'), $test->{status}, 'correct status';
+
+ if ( $test->{extended} ) {
+ my $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>', { extended_statuses => 1 } );
+ my $c = CGI::Simple->new( $results->{ req }->content );
+ is $c->param('status'), $test->{extended}, 'correct extended status';
+ }
};
}
@@ -539,18 +634,16 @@ done_testing();
sub make_update_req {
my $comment = shift;
my $xml = shift;
- my $extended = shift;
+ my $open311conf = shift || {};
my $params = {
object => $comment,
xml => $xml,
method => 'post_service_request_update',
path => 'servicerequestupdates.xml',
+ open311_conf => $open311_args,
};
- if ( $extended ) {
- $params->{ open311_conf } = { use_extended_updates => 1 };
- }
return make_req( $params );
}
diff --git a/t/open311/getservicerequestupdates.t b/t/open311/getservicerequestupdates.t
index aba811e58..3f9c35c32 100644
--- a/t/open311/getservicerequestupdates.t
+++ b/t/open311/getservicerequestupdates.t
@@ -131,63 +131,197 @@ $problem->insert;
for my $test (
{
- desc => 'element with content',
+ desc => 'OPEN status for confirmed problem does not change state',
updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ),
description => 'This is a note',
external_id => 638344,
start_state => 'confirmed',
- close_comment => 0,
+ comment_status => 'OPEN',
mark_fixed=> 0,
mark_open => 0,
problem_state => undef,
end_state => 'confirmed',
},
{
- desc => 'comment closes report',
+ desc => 'bad state does not update states but does create update',
updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ),
description => 'This is a note',
external_id => 638344,
start_state => 'confirmed',
- close_comment => 1,
+ comment_status => 'INVALID_STATE',
+ mark_fixed=> 0,
+ mark_open => 0,
+ problem_state => undef,
+ end_state => 'confirmed',
+ },
+
+ {
+ desc => 'investigating status changes problem status',
+ updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ),
+ description => 'This is a note',
+ external_id => 638344,
+ start_state => 'confirmed',
+ comment_status => 'INVESTIGATING',
+ mark_fixed=> 0,
+ mark_open => 0,
+ problem_state => 'investigating',
+ end_state => 'investigating',
+ },
+ {
+ desc => 'in progress status changes problem status',
+ updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ),
+ description => 'This is a note',
+ external_id => 638344,
+ start_state => 'confirmed',
+ comment_status => 'IN_PROGRESS',
+ mark_fixed=> 0,
+ mark_open => 0,
+ problem_state => 'in progress',
+ end_state => 'in progress',
+ },
+ {
+ desc => 'action scheduled status changes problem status',
+ updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ),
+ description => 'This is a note',
+ external_id => 638344,
+ start_state => 'confirmed',
+ comment_status => 'ACTION_SCHEDULED',
+ mark_fixed=> 0,
+ mark_open => 0,
+ problem_state => 'action scheduled',
+ end_state => 'action scheduled',
+ },
+ {
+ desc => 'not responsible status changes problem status',
+ updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ),
+ description => 'This is a note',
+ external_id => 638344,
+ start_state => 'confirmed',
+ comment_status => 'NOT_COUNCILS_RESPONSIBILITY',
+ mark_fixed=> 0,
+ mark_open => 0,
+ problem_state => 'not responsible',
+ end_state => 'not responsible',
+ },
+ {
+ desc => 'duplicate status changes problem status',
+ updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ),
+ description => 'This is a note',
+ external_id => 638344,
+ start_state => 'confirmed',
+ comment_status => 'DUPLICATE',
+ mark_fixed=> 0,
+ mark_open => 0,
+ problem_state => 'duplicate',
+ end_state => 'duplicate',
+ },
+ {
+ desc => 'fixed status marks report as fixed - council',
+ updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ),
+ description => 'This is a note',
+ external_id => 638344,
+ start_state => 'confirmed',
+ comment_status => 'FIXED',
+ mark_fixed=> 0,
+ mark_open => 0,
+ problem_state => 'fixed - council',
+ end_state => 'fixed - council',
+ },
+ {
+ desc => 'status of CLOSED marks report as fixed - council',
+ updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ),
+ description => 'This is a note',
+ external_id => 638344,
+ start_state => 'confirmed',
+ comment_status => 'CLOSED',
mark_fixed=> 0,
mark_open => 0,
problem_state => 'fixed - council',
end_state => 'fixed - council',
},
{
- desc => 'comment re-opens fixed report',
+ desc => 'status of OPEN re-opens fixed report',
updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ),
description => 'This is a note',
external_id => 638344,
start_state => 'fixed - user',
- close_comment => 0,
+ comment_status => 'OPEN',
mark_fixed => 0,
mark_open => 0,
problem_state => 'confirmed',
end_state => 'confirmed',
},
{
- desc => 'comment re-opens closed report',
+ desc => 'action sheduled re-opens fixed report as action scheduled',
+ updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ),
+ description => 'This is a note',
+ external_id => 638344,
+ start_state => 'fixed - user',
+ comment_status => 'ACTION_SCHEDULED',
+ mark_fixed => 0,
+ mark_open => 0,
+ problem_state => 'action scheduled',
+ end_state => 'action scheduled',
+ },
+ {
+ desc => 'open status re-opens closed report',
updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ),
description => 'This is a note',
external_id => 638344,
- start_state => 'closed',
- close_comment => 0,
+ start_state => 'not responsible',
+ comment_status => 'OPEN',
mark_fixed => 0,
mark_open => 0,
problem_state => 'confirmed',
end_state => 'confirmed',
},
{
- desc => 'comment leaves report closed',
+ desc => 'fixed status leaves fixed - user report as fixed - user',
+ updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ),
+ description => 'This is a note',
+ external_id => 638344,
+ start_state => 'fixed - user',
+ comment_status => 'FIXED',
+ mark_fixed => 0,
+ mark_open => 0,
+ problem_state => undef,
+ end_state => 'fixed - user',
+ },
+ {
+ desc => 'closed status updates fixed report',
+ updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ),
+ description => 'This is a note',
+ external_id => 638344,
+ start_state => 'fixed - user',
+ comment_status => 'NO_FURTHER_ACTION',
+ mark_fixed => 0,
+ mark_open => 0,
+ problem_state => 'unable to fix',
+ end_state => 'unable to fix',
+ },
+ {
+ desc => 'no futher action status closes report',
+ updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ),
+ description => 'This is a note',
+ external_id => 638344,
+ start_state => 'confirmed',
+ comment_status => 'NO_FURTHER_ACTION',
+ mark_fixed => 0,
+ mark_open => 0,
+ problem_state => 'unable to fix',
+ end_state => 'unable to fix',
+ },
+ {
+ desc => 'fixed status sets closed report as fixed',
updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ),
description => 'This is a note',
external_id => 638344,
- start_state => 'closed',
- close_comment => 1,
+ start_state => 'unable to fix',
+ comment_status => 'FIXED',
mark_fixed => 0,
mark_open => 0,
- end_state => 'closed',
+ problem_state => 'fixed - council',
+ end_state => 'fixed - council',
},
) {
subtest $test->{desc} => sub {
@@ -195,7 +329,7 @@ for my $test (
$local_requests_xml =~ s/UPDATED_DATETIME/$test->{updated_datetime}/;
$local_requests_xml =~ s#<service_request_id>\d+</service_request_id>#<service_request_id>@{[$problem->external_id]}</service_request_id>#;
$local_requests_xml =~ s#<service_request_id_ext>\d+</service_request_id_ext>#<service_request_id_ext>@{[$problem->id]}</service_request_id_ext>#;
- $local_requests_xml =~ s#<status>\w+</status>#<status>closed</status># if $test->{close_comment};
+ $local_requests_xml =~ s#<status>\w+</status>#<status>$test->{comment_status}</status># if $test->{comment_status};
my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $local_requests_xml } );
diff --git a/templates/web/bromley/report/display.html b/templates/web/bromley/report/display.html
index 13bc5f960..5288041f9 100644
--- a/templates/web/bromley/report/display.html
+++ b/templates/web/bromley/report/display.html
@@ -77,9 +77,11 @@
[% IF c.user && c.user.belongs_to_council( problem.council ) %]
<label for="form_state">[% loc( 'State' ) %]</label>
<select name="state" id="form_state">
- [% FOREACH state IN [ ['confirmed', loc('Open')], ['investigating',
- loc('Investigating')], ['planned', loc('Planned')], ['in progress',
- loc('In Progress')], ['closed', loc('Closed')], ['fixed', loc('Fixed')] ] %]
+ [% FOREACH state IN [ ['confirmed', loc('Open')], ['investigating',
+ loc('Investigating')], ['action scheduled', loc('Action Scheduled')],
+ ['in progress', loc('In Progress')], ['duplicate', loc('Duplicate')],
+ ['unable to fix', loc('Unable to fix')], ['not responsible', loc('Not Responsible')],
+ ['fixed', loc('Fixed')] ] %]
<option [% 'selected ' IF state.0 == problem.state %] value="[% state.0 %]">[% state.1 %]</option>
[% END %]
</select>
diff --git a/templates/web/default/admin/council_contacts.html b/templates/web/default/admin/council_contacts.html
index be855cb95..56850a82b 100644
--- a/templates/web/default/admin/council_contacts.html
+++ b/templates/web/default/admin/council_contacts.html
@@ -161,6 +161,11 @@
</p>
<p>
+ <label for="extended_statuses">Send extended open311 statuses with service request updates</label>:
+ <input type="checkbox" name="extended_statuses"[% ' checked' IF conf.send_extended_statuses %]>
+ </p>
+
+ <p>
<input type="hidden" name="open311_id" value="[% conf.id %]">
<input type="hidden" name="area_id" value="[% area_id %]">
<input type="hidden" name="posted" value="open311">
diff --git a/templates/web/default/dashboard/index.html b/templates/web/default/dashboard/index.html
index 169d7d3fe..f5a3cfba3 100644
--- a/templates/web/default/dashboard/index.html
+++ b/templates/web/default/dashboard/index.html
@@ -81,7 +81,7 @@
[%
rows = {
'0' => [ "in progress", "Council has marked as in progress" ]
- '1' => [ "planned", "Council has marked as planned" ]
+ '1' => [ "action scheduled", "Council has marked as planned" ]
'2' => [ "investigating", "Council has marked as investigating" ]
'3' => [ "closed", "Council has marked as closed" ]
};
@@ -98,10 +98,14 @@
<tr class='subtotal' id="marked">
<th scope="row">Total marked</th>
- <td>[% problems.wtd.${"in progress"} + problems.wtd.planned + problems.wtd.investigating + problems.wtd.closed %]</td>
- <td>[% problems.week.${"in progress"} + problems.week.planned + problems.week.investigating + problems.wtd.closed %]</td>
- <td>[% problems.weeks.${"in progress"} + problems.weeks.planned + problems.weeks.investigating + problems.wtd.closed %]</td>
- <td>[% problems.ytd.${"in progress"} + problems.ytd.planned + problems.ytd.investigating + problems.wtd.closed %]</td>
+ <td>[% problems.wtd.${"in progress"} + problems.wtd.${"action scheduled"} +
+ problems.wtd.investigating + problems.wtd.closed %]</td>
+ <td>[% problems.week.${"in progress"} + problems.week.${"action scheduled"} +
+ problems.week.investigating + problems.wtd.closed %]</td>
+ <td>[% problems.weeks.${"in progress"} + problems.weeks.${"action scheduled"} +
+ problems.weeks.investigating + problems.wtd.closed %]</td>
+ <td>[% problems.ytd.${"in progress"} + problems.ytd.${"action scheduled"} +
+ problems.ytd.investigating + problems.wtd.closed %]</td>
</tr>
<tr id="avg_fixed">
@@ -136,7 +140,7 @@
<p>Report state: <select name="state">
<option value=''>All</option>
[% FOREACH state IN [ ['confirmed', loc('Open')], ['investigating',
- loc('Investigating')], ['planned', loc('Planned')], ['in progress',
+ loc('Investigating')], ['action scheduled', loc('Planned')], ['in progress',
loc('In Progress')], ['closed', loc('Closed')], ['fixed', loc('Fixed')] ] %]
<option [% 'selected ' IF state.0 == q_state %] value="[% state.0 %]">[% state.1 %]</option>
[% END %]
diff --git a/templates/web/default/report/banner.html b/templates/web/default/report/banner.html
index 85aaed82d..52bfa6e67 100644
--- a/templates/web/default/report/banner.html
+++ b/templates/web/default/report/banner.html
@@ -14,7 +14,7 @@
[% IF problem.is_closed %]
[% INCLUDE banner, id = 'closed', text = loc('This problem has been closed') %]
[% END %]
-[% states = [ 'investigating', 'in progress', 'planned' ];
+[% states = [ 'investigating', 'in progress', 'planned', 'action scheduled' ];
IF states.grep(problem.state).size %]
[% INCLUDE banner, id = 'progress', text = loc('This problem is in progress') %]
[% END %]
diff --git a/templates/web/default/report/update-form.html b/templates/web/default/report/update-form.html
index 7e39f79b7..d993ce28f 100644
--- a/templates/web/default/report/update-form.html
+++ b/templates/web/default/report/update-form.html
@@ -28,8 +28,10 @@
<label for="form_state">[% loc( 'State:' ) %]</label>
<select name="state" id="form_state">
[% FOREACH state IN [ ['confirmed', loc('Open')], ['investigating',
- loc('Investigating')], ['planned', loc('Planned')], ['in progress',
- loc('In Progress')], ['closed', loc('Closed')], ['fixed', loc('Fixed')] ] %]
+ loc('Investigating')], ['action scheduled', loc('Action Scheduled')],
+ ['in progress', loc('In Progress')], ['duplicate', loc('Duplicate')],
+ ['unable to fix', loc('Unable to fix')], ['not responsible', loc('Not Responsible')],
+ ['fixed', loc('Fixed')] ] %]
<option [% 'selected ' IF state.0 == problem.state %] value="[% state.0 %]">[% state.1 %]</option>
[% END %]
</select>
diff --git a/templates/web/default/report/updates.html b/templates/web/default/report/updates.html
index eaf5209ff..736d36528 100644
--- a/templates/web/default/report/updates.html
+++ b/templates/web/default/report/updates.html
@@ -1,3 +1,4 @@
+[% global.last_state = '' %]
[% FOREACH update IN updates %]
[% INCLUDE 'report/update.html' %]
[% END %]
@@ -22,8 +23,20 @@
[%- ELSE %]
[% tprintf( loc( 'Posted by %s at %s' ), update.name, prettify_epoch( update.confirmed_local.epoch ) ) | html -%]
[%- END -%]
- [%- ", " _ loc( 'marked as fixed' ) IF update.mark_fixed %]
- [%- ", " _ loc( 'reopened' ) IF update.mark_open OR update.problem_state == 'confirmed' %]
- [%- ", " _ tprintf(loc( 'marked as %s' ), update.meta_problem_state) IF update.problem_state AND update.problem_state != 'confirmed' %]
+ [%- update_state = '' %]
+ [%- IF update.mark_fixed %][% update_state = ", " _ loc( 'marked as fixed' ) %][% END %]
+ [%- IF update.mark_open %][% update_state = ", " _ loc( 'reopened' ) %][% END %]
+ [%- IF !update_state && update.problem_state %]
+ [%- state = update.meta_problem_state %]
+ [%- IF c.cobrand.moniker == 'bromley' AND update.problem_state == 'unable to fix' %]
+ [%- state = loc('no further action') %]
+ [% END %]
+ [%- IF update.problem_state == 'confirmed' %]
+ [%- update_state = ", " _ loc('reopened') %]
+ [%- ELSE %]
+ [%- update_state = ", " _ tprintf(loc( 'marked as %s' ), state ) %]
+ [% END %]
+ [%- END %]
+ [%- update_state IF update_state != global.last_state %]
+ [%- global.last_state = update_state %]
[% END %]
-
diff --git a/templates/web/fixmystreet/report/banner.html b/templates/web/fixmystreet/report/banner.html
index 58712604e..c6201cafc 100644
--- a/templates/web/fixmystreet/report/banner.html
+++ b/templates/web/fixmystreet/report/banner.html
@@ -5,7 +5,7 @@
</div>
[% END %]
-[% IF problem.is_open AND date.now - problem.lastupdate_local.epoch > 8 * 7 * 24 * 60 * 60 %]
+[% IF c.cobrand.moniker != 'bromley' AND problem.is_open AND date.now - problem.lastupdate_local.epoch > 8 * 7 * 24 * 60 * 60 %]
[% INCLUDE banner, id = 'unknown', text = loc('Unknown') %]
[% END %]
[% IF problem.is_fixed %]
@@ -14,8 +14,8 @@
[% IF problem.is_closed %]
[% INCLUDE banner, id = 'closed', text = loc('Closed') %]
[% END %]
-[% states = [ 'investigating', 'in progress', 'planned' ];
- IF states.grep(problem.state).size %]
+[% states = [ 'investigating', 'in progress', 'planned', 'action scheduled' ];
+ IF c.cobrand.moniker != 'bromley' && states.grep(problem.state).size %]
[% INCLUDE banner, id = 'progress', text = loc('In progress') %]
[% END %]
diff --git a/templates/web/fixmystreet/report/update-form.html b/templates/web/fixmystreet/report/update-form.html
index 14efdb51b..a632cfc4a 100644
--- a/templates/web/fixmystreet/report/update-form.html
+++ b/templates/web/fixmystreet/report/update-form.html
@@ -26,8 +26,10 @@
<label for="form_state">[% loc( 'State' ) %]</label>
<select name="state" id="form_state">
[% FOREACH state IN [ ['confirmed', loc('Open')], ['investigating',
- loc('Investigating')], ['planned', loc('Planned')], ['in progress',
- loc('In Progress')], ['closed', loc('Closed')], ['fixed', loc('Fixed')] ] %]
+ loc('Investigating')], ['action scheduled', loc('Action Scheduled')],
+ ['in progress', loc('In Progress')], ['duplicate', loc('Duplicate')],
+ ['unable to fix', loc('Unable to fix')], ['not responsible', loc('Not Responsible')],
+ ['fixed', loc('Fixed')] ] %]
<option [% 'selected ' IF state.0 == problem.state %] value="[% state.0 %]">[% state.1 %]</option>
[% END %]
</select>
diff --git a/web/cobrands/fixmystreet/_layout.scss b/web/cobrands/fixmystreet/_layout.scss
index 7a84af521..28c1b6cb8 100644
--- a/web/cobrands/fixmystreet/_layout.scss
+++ b/web/cobrands/fixmystreet/_layout.scss
@@ -681,6 +681,15 @@ body.twothirdswidthpage {
border-bottom: 0.75em solid $col_fixed_label_dark;
}
}
+ &#closed {
+ padding-top:5em;
+ background-image:url(/cobrands/fixmystreet/images/sprite.png);
+ background-position:-318px -326px;
+ background-repeat:no-repeat;
+ &:before {
+ border-bottom: 0.75em solid #666;
+ }
+ }
}
}
.ie6 .banner p {