diff options
author | Matthew Somerville <matthew-github@dracos.co.uk> | 2019-01-17 15:54:56 +0000 |
---|---|---|
committer | Matthew Somerville <matthew-github@dracos.co.uk> | 2019-01-23 10:10:30 +0000 |
commit | 2f02c377f44bd2b7cc16f3fdbefb85ed5fa25fdb (patch) | |
tree | f42e906998ed0d1789b023f98cc3ec138501ea9e | |
parent | f44ad2f067346cb3b03d3711fd658a5516e9fd0c (diff) |
[Buckinghamshire] Question for on-road flytipping.
This adds a question to check whether a flytipping report concerns
flytipping on a road or not. Client-side, it is asked when a road is
selected and destination adjusted according to the answer; server side
it uses the answer to direct any both-tier submissions (from e.g.
non-JavaScript or phone app).
-rw-r--r-- | perllib/FixMyStreet/Cobrand/Buckinghamshire.pm | 52 | ||||
-rw-r--r-- | t/cobrand/bucks.t | 27 | ||||
-rw-r--r-- | t/open311/populate-service-list.t | 145 | ||||
-rw-r--r-- | web/cobrands/buckinghamshire/assets.js | 28 |
4 files changed, 221 insertions, 31 deletions
diff --git a/perllib/FixMyStreet/Cobrand/Buckinghamshire.pm b/perllib/FixMyStreet/Cobrand/Buckinghamshire.pm index c8432c4d7..75564fddd 100644 --- a/perllib/FixMyStreet/Cobrand/Buckinghamshire.pm +++ b/perllib/FixMyStreet/Cobrand/Buckinghamshire.pm @@ -109,6 +109,58 @@ sub open311_config_updates { $params->{mark_reopen} = 1; } +sub open311_contact_meta_override { + my ($self, $service, $contact, $meta) = @_; + + push @$meta, { + code => 'road-placement', + datatype => 'singlevaluelist', + description => 'Is the fly-tip located on', + order => 100, + required => 'true', + variable => 'true', + values => [ + { key => 'road', name => 'The road' }, + { key => 'off-road', name => 'Off the road/on a verge' }, + ], + } if $service->{service_name} eq 'Flytipping'; +} + +sub process_open311_extras { + my ($self, $c, $body, $extra) = @_; + + $self->flytipping_body_fix( + $c->stash->{report}, + $c->get_param('road-placement'), + $c->stash->{field_errors}, + ); +} + +sub flytipping_body_fix { + my ($self, $report, $road_placement, $errors) = @_; + + return unless $report->category eq 'Flytipping'; + + if ($report->bodies_str =~ /,/) { + # Sent to both councils in the area + my @bodies = values %{$report->bodies}; + my $county = (grep { $_->name =~ /^Buckinghamshire/ } @bodies)[0]; + my $district = (grep { $_->name !~ /^Buckinghamshire/ } @bodies)[0]; + # Decide which to send to based upon the answer to the extra question: + if ($road_placement eq 'road') { + $report->bodies_str($county->id); + } elsif ($road_placement eq 'off-road') { + $report->bodies_str($district->id); + } + } else { + # If the report is only being sent to the district, we do + # not care about the road question, if it is missing + if (!$report->to_body_named('Buckinghamshire')) { + delete $errors->{'road-placement'}; + } + } +} + sub filter_report_description { my ($self, $description) = @_; diff --git a/t/cobrand/bucks.t b/t/cobrand/bucks.t index a894bd377..d9273fbf8 100644 --- a/t/cobrand/bucks.t +++ b/t/cobrand/bucks.t @@ -80,10 +80,31 @@ subtest 'flytipping off road sent to extra email' => sub { is $report->external_id, undef, 'Report has right external ID'; }; -}; - $cobrand = FixMyStreet::Cobrand::Buckinghamshire->new(); +subtest 'Flytipping extra question used if necessary' => sub { + my $errors = { 'road-placement' => 'This field is required' }; + + $report->update({ bodies_str => $body->id }); + $cobrand->flytipping_body_fix($report, 'road', $errors); + is $errors->{'road-placement'}, 'This field is required', 'Error stays if sent to county'; + + $report->update({ bodies_str => $district->id }); + $report->discard_changes; # As e.g. ->bodies has been remembered. + $cobrand->flytipping_body_fix($report, 'road', $errors); + is $errors->{'road-placement'}, undef, 'Error removed if sent to district'; + + $report->update({ bodies_str => $body->id . ',' . $district->id }); + $report->discard_changes; # As e.g. ->bodies has been remembered. + $cobrand->flytipping_body_fix($report, 'road', $errors); + is $report->bodies_str, $body->id, 'Sent to both becomes sent to county on-road'; + + $report->update({ bodies_str => $district->id . ',' . $body->id }); + $report->discard_changes; # As e.g. ->bodies has been remembered. + $cobrand->flytipping_body_fix($report, 'off-road', $errors); + is $report->bodies_str, $district->id, 'Sent to both becomes sent to district off-road'; +}; + for my $test ( { desc => 'filters basic emails', @@ -151,6 +172,6 @@ for my $test ( }; } - +}; done_testing(); diff --git a/t/open311/populate-service-list.t b/t/open311/populate-service-list.t index 340a91ac5..9747dfd2f 100644 --- a/t/open311/populate-service-list.t +++ b/t/open311/populate-service-list.t @@ -27,24 +27,28 @@ use_ok( 'Open311' ); my $processor = Open311::PopulateServiceList->new(); ok $processor, 'created object'; -my $body = FixMyStreet::DB->resultset('Body')->find_or_create( { - id => 1, +my $body = FixMyStreet::DB->resultset('Body')->create({ name => 'Body Numero Uno', } ); -$body->body_areas->find_or_create({ +$body->body_areas->create({ area_id => 1 } ); my $BROMLEY = 'Bromley Council'; -my $bromley = FixMyStreet::DB->resultset('Body')->find_or_create( { - id => 2482, +my $bromley = FixMyStreet::DB->resultset('Body')->create( { name => $BROMLEY, } ); -$bromley->update({ name => $BROMLEY }); -$bromley->body_areas->find_or_create({ +$bromley->body_areas->create({ area_id => 2482 } ); +my $bucks = FixMyStreet::DB->resultset('Body')->create({ + name => 'Buckinghamshire County Council', +}); +$bucks->body_areas->create({ + area_id => 2217 +}); + for my $test ( { desc => 'groups not set for new contacts', cobrand => 'tester', groups => 0, delete => 1 }, { desc => 'groups set for new contacts', cobrand => 'testergroups', groups => 1, delete => 1}, @@ -55,7 +59,7 @@ for my $test ( ALLOWED_COBRANDS => [ $test->{cobrand} ], }, sub { subtest 'check basic functionality, ' . $test->{desc} => sub { - FixMyStreet::DB->resultset('Contact')->search( { body_id => 1 } )->delete() if $test->{delete}; + FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->delete() if $test->{delete}; my $service_list = get_xml_simple_object( get_standard_xml() ); @@ -63,7 +67,7 @@ for my $test ( $processor->_current_body( $body ); $processor->process_services( $service_list ); - my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => 1 } )->count(); + my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->count(); is $contact_count, 3, 'correct number of contacts'; for my $expects ( @@ -71,7 +75,7 @@ for my $test ( { code => "002", group => $test->{groups} ? "street" : undef }, { code => "003", group => $test->{groups} ? "street" : undef }, ) { - my $contact = FixMyStreet::DB->resultset('Contact')->search( { body_id => 1, email => $expects->{code} } )->first; + my $contact = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id, email => $expects->{code} } )->first; is $contact->get_extra->{group}, $expects->{group}, "Group set correctly"; } }; @@ -79,11 +83,11 @@ for my $test ( } subtest 'check non open311 contacts marked as deleted' => sub { - FixMyStreet::DB->resultset('Contact')->search( { body_id => 1 } )->delete(); + FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->delete(); my $contact = FixMyStreet::DB->resultset('Contact')->create( { - body_id => 1, + body_id => $body->id, email => 'contact@example.com', category => 'An old category', state => 'confirmed', @@ -99,19 +103,19 @@ subtest 'check non open311 contacts marked as deleted' => sub { $processor->_current_body( $body ); $processor->process_services( $service_list ); - my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => 1 } )->count(); + my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->count(); is $contact_count, 4, 'correct number of contacts'; - $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => 1, state => 'deleted' } )->count(); + $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id, state => 'deleted' } )->count(); is $contact_count, 1, 'correct number of deleted contacts'; }; subtest 'check email changed if matching category' => sub { - FixMyStreet::DB->resultset('Contact')->search( { body_id => 1 } )->delete(); + FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->delete(); my $contact = FixMyStreet::DB->resultset('Contact')->create( { - body_id => 1, + body_id => $body->id, email => '009', category => 'Cans left out 24x7', state => 'confirmed', @@ -133,16 +137,16 @@ subtest 'check email changed if matching category' => sub { is $contact->email, '001', 'email unchanged'; is $contact->state, 'confirmed', 'contact still confirmed'; - my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => 1 } )->count(); + my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->count(); is $contact_count, 3, 'correct number of contacts'; }; subtest 'check category name changed if updated' => sub { - FixMyStreet::DB->resultset('Contact')->search( { body_id => 1 } )->delete(); + FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->delete(); my $contact = FixMyStreet::DB->resultset('Contact')->create( { - body_id => 1, + body_id => $body->id, email => '001', category => 'Bins left out 24x7', state => 'confirmed', @@ -165,16 +169,16 @@ subtest 'check category name changed if updated' => sub { is $contact->category, 'Cans left out 24x7', 'category changed'; is $contact->state, 'confirmed', 'contact still confirmed'; - my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => 1 } )->count(); + my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->count(); is $contact_count, 3, 'correct number of contacts'; }; subtest 'check conflicting contacts not changed' => sub { - FixMyStreet::DB->resultset('Contact')->search( { body_id => 1 } )->delete(); + FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->delete(); my $contact = FixMyStreet::DB->resultset('Contact')->create( { - body_id => 1, + body_id => $body->id, email => 'existing@example.com', category => 'Cans left out 24x7', state => 'confirmed', @@ -188,7 +192,7 @@ subtest 'check conflicting contacts not changed' => sub { my $contact2 = FixMyStreet::DB->resultset('Contact')->create( { - body_id => 1, + body_id => $body->id, email => '001', category => 'Bins left out 24x7', state => 'confirmed', @@ -216,7 +220,7 @@ subtest 'check conflicting contacts not changed' => sub { is $contact2->category, 'Bins left out 24x7', 'second contact category unchanged'; is $contact2->state, 'confirmed', 'second contact still confirmed'; - my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => 1 } )->count(); + my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->count(); is $contact_count, 4, 'correct number of contacts'; }; @@ -360,7 +364,7 @@ for my $test ( my $contact = FixMyStreet::DB->resultset('Contact')->find_or_create( { - body_id => 1, + body_id => $body->id, email => '100', category => 'Cans left out 24x7', state => 'confirmed', @@ -433,7 +437,7 @@ subtest 'check attribute ordering' => sub { my $contact = FixMyStreet::DB->resultset('Contact')->find_or_create( { - body_id => 1, + body_id => $body->id, email => '001', category => 'Bins left out 24x7', state => 'confirmed', @@ -534,7 +538,7 @@ subtest 'check Bromley skip code' => sub { my $contact = FixMyStreet::DB->resultset('Contact')->find_or_create( { - body_id => 1, + body_id => $body->id, email => '001', category => 'Bins left out 24x7', state => 'confirmed', @@ -624,6 +628,93 @@ subtest 'check Bromley skip code' => sub { is_deeply $contact->get_extra_fields, $extra, 'all meta data saved for non bromley'; }; +subtest 'check Buckinghamshire extra code' => sub { + my $processor = Open311::PopulateServiceList->new(); + + my $meta_xml = '<?xml version="1.0" encoding="utf-8"?> +<service_definition> + <service_code>100</service_code> + <attributes> + <attribute> + <variable>true</variable> + <code>type</code> + <datatype>string</datatype> + <required>true</required> + <datatype_description>Type of bin</datatype_description> + <order>1</order> + <description>Type of bin</description> + </attribute> + </attributes> +</service_definition> + '; + + my $contact = FixMyStreet::DB->resultset('Contact')->find_or_create({ + body_id => $body->id, + email => '001', + category => 'Flytipping', + state => 'confirmed', + editor => $0, + whenedited => \'current_timestamp', + note => 'test contact', + }); + + my $o = Open311->new( + jurisdiction => 'mysociety', + endpoint => 'http://example.com', + test_mode => 1, + test_get_returns => { 'services/100.xml' => $meta_xml } + ); + + $processor->_current_open311( $o ); + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'buckinghamshire' ], + }, sub { + $processor->_current_body( $bucks ); + }; + $processor->_current_service( { service_code => 100, service_name => 'Flytipping' } ); + $processor->_add_meta_to_contact( $contact ); + + my $extra = [ { + variable => 'true', + code => 'type', + datatype => 'string', + required => 'true', + datatype_description => 'Type of bin', + order => 1, + description => 'Type of bin' + }, { + variable => 'true', + code => 'road-placement', + datatype => 'singlevaluelist', + required => 'true', + order => 100, + description => 'Is the fly-tip located on', + values => [ + { key => 'road', name => 'The road' }, + { key => 'off-road', name => 'Off the road/on a verge' }, + ], + } ]; + + $contact->discard_changes; + is_deeply $contact->get_extra_fields, $extra, 'extra Bucks field returned for flytipping'; + + $processor->_current_service( { service_code => 100, service_name => 'Street lights' } ); + $processor->_add_meta_to_contact( $contact ); + + $extra = [ { + variable => 'true', + code => 'type', + datatype => 'string', + required => 'true', + datatype_description => 'Type of bin', + order => 1, + description => 'Type of bin' + } ]; + + $contact->discard_changes; + is_deeply $contact->get_extra_fields, $extra, 'no extra Bucks field returned otherwise'; +}; + sub get_standard_xml { return qq{<?xml version="1.0" encoding="utf-8"?> <services> diff --git a/web/cobrands/buckinghamshire/assets.js b/web/cobrands/buckinghamshire/assets.js index 32c551d1a..2f69ba6f6 100644 --- a/web/cobrands/buckinghamshire/assets.js +++ b/web/cobrands/buckinghamshire/assets.js @@ -377,6 +377,11 @@ fixmystreet.assets.add($.extend(true, {}, defaults, { found: function(layer, feature) { fixmystreet.body_overrides.allow_send(layer.fixmystreet.body); fixmystreet.body_overrides.remove_only_send(); + + // Make sure Flytipping related things reset + $('#category_meta').show(); + $('#form_road-placement').attr('required', ''); + if (fixmystreet.assets.selectedFeature()) { hide_responsibility_errors(); enable_report_form(); @@ -414,10 +419,19 @@ fixmystreet.assets.add($.extend(true, {}, defaults, { fixmystreet.body_overrides.allow_send(layer.fixmystreet.body); hide_responsibility_errors(); enable_report_form(); - } else if (is_only_body(layer.fixmystreet.body)){ + } else if (is_only_body(layer.fixmystreet.body)) { show_responsibility_error("#js-not-a-road"); disable_report_form(); } + + // If flytipping is picked, we don't want to ask the extra question + var cat = $('select#form_category').val(); + if (cat === 'Flytipping') { + $('#category_meta').hide(); + $('#form_road-placement').removeAttr('required'); + } else { + $('#category_meta').show(); + } } }, usrn: { @@ -428,6 +442,18 @@ fixmystreet.assets.add($.extend(true, {}, defaults, { filter_value: types_to_show, })); +// As with the road found/not_found above, we want to change the destination +// depending upon the answer to the extra question shown when on a road +$("#problem_form").on("change", "#form_road-placement", function() { + if (this.value == 'road') { + fixmystreet.body_overrides.allow_send(defaults.body); + fixmystreet.body_overrides.only_send(defaults.body); + } else if (this.value == 'off-road') { + fixmystreet.body_overrides.do_not_send(defaults.body); + fixmystreet.body_overrides.remove_only_send(); + } +}); + fixmystreet.assets.add($.extend(true, {}, defaults, { http_options: { params: { |