diff options
author | Struan Donald <struan@exo.org.uk> | 2018-03-15 16:12:58 +0000 |
---|---|---|
committer | Struan Donald <struan@exo.org.uk> | 2018-03-15 16:12:58 +0000 |
commit | 9d9352ca6bbd757b30796d3cebd42f3ba06f6ddc (patch) | |
tree | e587f810b1adf59d6c947e1e887b341cb3e635e5 | |
parent | d5fed14044a348d85061202265dd09e4ce1b776b (diff) | |
parent | 8c23490f465fad0089d77ee362c566d066798d09 (diff) |
Merge branch 'rutland-integration'
37 files changed, 1043 insertions, 41 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index fdfad3359..20a7ce037 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ ## Releases * Unreleased + - New features + - Fetch problems over Open311 #1986 + - Option to send multiple photos over Open311 #1986 + - Allow Open311 service definitions to include automated + attributes #1986 + - Optionally supress blank Open311 update errors #1986 - Front end improvements: - Improve questionnaire process. #1939 #1998 - Increase size of "sub map links" (hide pins, permalink, etc) #2003 diff --git a/bin/fetch-reports b/bin/fetch-reports new file mode 100755 index 000000000..665b4aff0 --- /dev/null +++ b/bin/fetch-reports @@ -0,0 +1,25 @@ +#!/usr/bin/env perl +# +# This script utilises the Open311 extension explained at +# https://github.com/mysociety/FixMyStreet/wiki/Open311-FMS---Proposed-differences-to-Open311 +# to fetch updates on service requests. + +use strict; +use warnings; +require 5.8.0; + +BEGIN { + use File::Basename qw(dirname); + use File::Spec; + my $d = dirname(File::Spec->rel2abs($0)); + require "$d/../setenv.pl"; +} + +use CronFns; +my ($verbose, $nomail) = CronFns::options(); + +use Open311::GetServiceRequests; + +my $reports = Open311::GetServiceRequests->new( verbose => $verbose ); + +$reports->fetch; diff --git a/bin/update-schema b/bin/update-schema index fea316bd6..9660837c6 100755 --- a/bin/update-schema +++ b/bin/update-schema @@ -212,6 +212,8 @@ else { # (assuming schema change files are never half-applied, which should be the case) sub get_db_version { return 'EMPTY' if ! table_exists('problem'); + return '0058' if column_exists('body', 'blank_updates_permitted'); + return '0057' if column_exists('body', 'fetch_problems'); return '0056' if column_exists('users', 'email_verified'); return '0055' if column_exists('response_priorities', 'is_default'); return '0054' if table_exists('state'); diff --git a/db/downgrade_0057---0056.sql b/db/downgrade_0057---0056.sql new file mode 100644 index 000000000..a87488e41 --- /dev/null +++ b/db/downgrade_0057---0056.sql @@ -0,0 +1,5 @@ +BEGIN; + +ALTER TABLE body DROP fetch_problems; + +COMMIT; diff --git a/db/downgrade_0058---0057.sql b/db/downgrade_0058---0057.sql new file mode 100644 index 000000000..1ce8f527c --- /dev/null +++ b/db/downgrade_0058---0057.sql @@ -0,0 +1,5 @@ +BEGIN; + +ALTER TABLE body DROP blank_updates_permitted; + +COMMIT; diff --git a/db/schema.sql b/db/schema.sql index f2197dc52..739090480 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -54,6 +54,8 @@ create table body ( suppress_alerts boolean not null default 'f', can_be_devolved boolean not null default 'f', send_extended_statuses boolean not null default 'f', + fetch_problems boolean not null default 'f', + blank_updates_permitted boolean not null default 'f', deleted boolean not null default 'f' ); diff --git a/db/schema_0057-fetch-problems.sql b/db/schema_0057-fetch-problems.sql new file mode 100644 index 000000000..7419eb032 --- /dev/null +++ b/db/schema_0057-fetch-problems.sql @@ -0,0 +1,5 @@ +BEGIN; + +ALTER TABLE body ADD fetch_problems boolean default 'f' not null; + +COMMIT; diff --git a/db/schema_0058-blank-updates-permitted.sql b/db/schema_0058-blank-updates-permitted.sql new file mode 100644 index 000000000..8b6710bc0 --- /dev/null +++ b/db/schema_0058-blank-updates-permitted.sql @@ -0,0 +1,5 @@ +BEGIN; + +ALTER TABLE body ADD blank_updates_permitted boolean default 'f' not null; + +COMMIT; diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm index 5e69d5bf3..c12fdf9b9 100644 --- a/perllib/FixMyStreet/App/Controller/Admin.pm +++ b/perllib/FixMyStreet/App/Controller/Admin.pm @@ -445,6 +445,8 @@ sub body_params : Private { my %defaults = map { $_ => '' } @fields; %defaults = ( %defaults, send_comments => 0, + fetch_problems => 0, + blank_updates_permitted => 0, suppress_alerts => 0, comment_user_id => undef, send_extended_statuses => 0, diff --git a/perllib/FixMyStreet/App/Controller/Report/New.pm b/perllib/FixMyStreet/App/Controller/Report/New.pm index f7334c115..e4e82f091 100644 --- a/perllib/FixMyStreet/App/Controller/Report/New.pm +++ b/perllib/FixMyStreet/App/Controller/Report/New.pm @@ -1003,7 +1003,7 @@ sub set_report_extras : Private { foreach my $contact (@$contacts) { my $metas = $contact->get_metadata_for_input; foreach my $field ( @$metas ) { - if ( lc( $field->{required} ) eq 'true' && !$c->cobrand->category_extra_hidden($field->{code})) { + if ( lc( $field->{required} ) eq 'true' && !$c->cobrand->category_extra_hidden($field)) { unless ( $c->get_param($param_prefix . $field->{code}) ) { $c->stash->{field_errors}->{ $field->{code} } = _('This information is required'); } @@ -1020,7 +1020,7 @@ sub set_report_extras : Private { my $metas = $extra_fields->get_extra_fields; $param_prefix = "extra[" . $extra_fields->id . "]"; foreach my $field ( @$metas ) { - if ( lc( $field->{required} ) eq 'true' && !$c->cobrand->category_extra_hidden($field->{code})) { + if ( lc( $field->{required} ) eq 'true' && !$c->cobrand->category_extra_hidden($field)) { unless ( $c->get_param($param_prefix . $field->{code}) ) { $c->stash->{field_errors}->{ $field->{code} } = _('This information is required'); } diff --git a/perllib/FixMyStreet/Cobrand/Default.pm b/perllib/FixMyStreet/Cobrand/Default.pm index 03a6c1a83..8c4d8be53 100644 --- a/perllib/FixMyStreet/Cobrand/Default.pm +++ b/perllib/FixMyStreet/Cobrand/Default.pm @@ -1178,7 +1178,7 @@ Return true if an Open311 service attribute should be a hidden field. sub category_extra_hidden { my ($self, $meta) = @_; - return 0; + return 0; } =item reputation_increment_states/reputation_decrement_states diff --git a/perllib/FixMyStreet/Cobrand/Rutland.pm b/perllib/FixMyStreet/Cobrand/Rutland.pm new file mode 100644 index 000000000..c0f9dd197 --- /dev/null +++ b/perllib/FixMyStreet/Cobrand/Rutland.pm @@ -0,0 +1,46 @@ +package FixMyStreet::Cobrand::Rutland; +use base 'FixMyStreet::Cobrand::UKCouncils'; + +use strict; +use warnings; + +sub council_area_id { return 2600; } +sub council_area { return 'Rutland'; } +sub council_name { return 'Rutland County Council'; } +sub council_url { return 'rutland'; } + +sub open311_config { + my ($self, $row, $h, $params) = @_; + + my $extra = $row->get_extra_fields; + push @$extra, { name => 'external_id', value => $row->id }; + push @$extra, { name => 'title', value => $row->title }; + push @$extra, { name => 'description', value => $row->detail }; + + if ($h->{closest_address}) { + push @$extra, { name => 'closest_address', value => $h->{closest_address} } + } + $row->set_extra_fields( @$extra ); + + $params->{multi_photos} = 1; +} + +sub example_places { + return ( 'LE15 6HP', 'High Street', 'Oakham' ); +} + +sub disambiguate_location { + my $self = shift; + my $string = shift; + + return { + bounds => [52.524755166940075, -0.8217480325342802, 52.7597945702699, -0.4283542728893742] + }; +} + +sub pin_colour { + my ( $self, $p, $context ) = @_; + return 'green' if $p->is_fixed || $p->is_closed; + return 'yellow'; +} +1; diff --git a/perllib/FixMyStreet/Cobrand/UK.pm b/perllib/FixMyStreet/Cobrand/UK.pm index e1f5e565f..0ecb6a7c6 100644 --- a/perllib/FixMyStreet/Cobrand/UK.pm +++ b/perllib/FixMyStreet/Cobrand/UK.pm @@ -396,7 +396,8 @@ sub lookup_by_ref_regex { sub category_extra_hidden { my ($self, $meta) = @_; - return 1 if $meta eq 'usrn' || $meta eq 'asset_id'; + return 1 if $meta->{code} eq 'usrn' || $meta->{code} eq 'asset_id'; + return 1 if $meta->{automated} eq 'hidden_field'; return 0; } diff --git a/perllib/FixMyStreet/DB/Result/Body.pm b/perllib/FixMyStreet/DB/Result/Body.pm index 07bea276c..a9df1aeb7 100644 --- a/perllib/FixMyStreet/DB/Result/Body.pm +++ b/perllib/FixMyStreet/DB/Result/Body.pm @@ -44,6 +44,10 @@ __PACKAGE__->add_columns( { data_type => "boolean", default_value => \"false", is_nullable => 0 }, "external_url", { data_type => "text", is_nullable => 1 }, + "fetch_problems", + { data_type => "boolean", default_value => \"false", is_nullable => 0 }, + "blank_updates_permitted", + { data_type => "boolean", default_value => \"false", is_nullable => 0 }, ); __PACKAGE__->set_primary_key("id"); __PACKAGE__->has_many( @@ -118,8 +122,8 @@ __PACKAGE__->has_many( ); -# Created by DBIx::Class::Schema::Loader v0.07035 @ 2017-02-13 15:11:11 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:BOJANVwg3kR/1VjDq0LykA +# Created by DBIx::Class::Schema::Loader v0.07035 @ 2018-03-01 12:27:28 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:dzqgZI1wkGDPS2PfJgDEIg use Moo; use namespace::clean; diff --git a/perllib/FixMyStreet/Script/Reports.pm b/perllib/FixMyStreet/Script/Reports.pm index aa6b64752..b8c3d6d0d 100644 --- a/perllib/FixMyStreet/Script/Reports.pm +++ b/perllib/FixMyStreet/Script/Reports.pm @@ -88,6 +88,8 @@ sub send(;$) { if ($row->photo) { $h{has_photo} = _("This web page also contains a photo of the problem, provided by the user.") . "\n\n"; $h{image_url} = $email_base_url . $row->photos->[0]->{url_full}; + my @all_images = map { $email_base_url . $_->{url_full} } @{ $row->photos }; + $h{all_image_urls} = \@all_images; } else { $h{has_photo} = ''; $h{image_url} = ''; diff --git a/perllib/FixMyStreet/SendReport/Open311.pm b/perllib/FixMyStreet/SendReport/Open311.pm index ecda0bca1..98637dd1f 100644 --- a/perllib/FixMyStreet/SendReport/Open311.pm +++ b/perllib/FixMyStreet/SendReport/Open311.pm @@ -28,6 +28,7 @@ sub send { send_notpinpointed => 0, use_service_as_deviceid => 0, extended_description => 1, + multi_photos => 0, ); my $cobrand = $body->get_cobrand_handler || $row->get_cobrand_logged; diff --git a/perllib/Open311.pm b/perllib/Open311.pm index 44af0b134..577de31ea 100644 --- a/perllib/Open311.pm +++ b/perllib/Open311.pm @@ -32,6 +32,7 @@ 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 ); has always_send_email => ( is => 'ro', isa => Bool, default => 0 ); +has multi_photos => ( is => 'ro', isa => Bool, default => 0 ); before [ qw/get_service_list get_service_meta_info get_service_requests get_service_request_updates @@ -163,7 +164,11 @@ sub _populate_service_request_params { } if ( $extra->{image_url} ) { - $params->{media_url} = $extra->{image_url}; + if ( $self->multi_photos ) { + $params->{media_url} = $extra->{all_image_urls}; + } else { + $params->{media_url} = $extra->{image_url}; + } } if ( $self->use_service_as_deviceid && $problem->service ) { @@ -213,14 +218,20 @@ sub _generate_service_request_description { sub get_service_requests { my $self = shift; - my $report_ids = shift; + my $args = shift; my $params = {}; - if ( $report_ids ) { - $params->{service_request_id} = join ',', @$report_ids; + if ( $args->{report_ids} ) { + $params->{service_request_id} = join ',', @{$args->{report_ids}}; + delete $args->{report_ids}; } + $params = { + %$params, + %$args + }; + my $service_request_xml = $self->_get( $self->endpoints->{requests}, $params || undef ); return $self->_get_xml_object( $service_request_xml ); } @@ -291,6 +302,37 @@ sub post_service_request_update { return 0; } +sub add_media { + my ($self, $url, $object) = @_; + + my $ua = LWP::UserAgent->new; + my $res = $ua->get($url); + if ( $res->is_success && $res->content_type eq 'image/jpeg' ) { + my $photoset = FixMyStreet::App::Model::PhotoSet->new({ + data_items => [ $res->decoded_content ], + }); + $object->photo($photoset->data); + } +} + +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; +} + sub _populate_service_request_update_params { my $self = shift; my $comment = shift; diff --git a/perllib/Open311/GetServiceRequestUpdates.pm b/perllib/Open311/GetServiceRequestUpdates.pm index 2620b176a..f2a319f15 100644 --- a/perllib/Open311/GetServiceRequestUpdates.pm +++ b/perllib/Open311/GetServiceRequestUpdates.pm @@ -12,6 +12,7 @@ has end_date => ( is => 'ro', default => sub { undef } ); has suppress_alerts => ( is => 'rw', default => 0 ); has verbose => ( is => 'ro', default => 0 ); has schema => ( is =>'ro', lazy => 1, default => sub { FixMyStreet::DB->schema->connect } ); +has blank_updates_permitted => ( is => 'rw', default => 0 ); Readonly::Scalar my $AREA_ID_BROMLEY => 2482; Readonly::Scalar my $AREA_ID_OXFORDSHIRE => 2237; @@ -49,6 +50,7 @@ sub fetch { } $self->suppress_alerts( $body->suppress_alerts ); + $self->blank_updates_permitted( $body->blank_updates_permitted ); $self->system_user( $body->comment_user ); $self->update_comments( $o, $body ); } @@ -107,7 +109,7 @@ sub update_comments { my $c = $p->comments->search( { external_id => $request->{update_id} } ); if ( !$c->first ) { - my $state = $self->map_state( $request->{status} ); + my $state = $open311->map_state( $request->{status} ); my $comment = $self->schema->resultset('Comment')->new( { problem => $p, @@ -124,16 +126,8 @@ sub update_comments { } ); - if ($request->{media_url}) { - my $ua = LWP::UserAgent->new; - my $res = $ua->get($request->{media_url}); - if ( $res->is_success && $res->content_type eq 'image/jpeg' ) { - my $photoset = FixMyStreet::App::Model::PhotoSet->new({ - data_items => [ $res->decoded_content ], - }); - $comment->photo($photoset->data); - } - } + $open311->add_media($request->{media_url}, $comment) + if $request->{media_url}; # if the comment is older than the last update # do not change the status of the problem as it's @@ -191,26 +185,10 @@ sub comment_text_for_request { return $template->text; } + return "" if $self->blank_updates_permitted; + print STDERR "Couldn't determine update text for $request->{update_id} (report " . $problem->id . ")\n"; return ""; } -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/perllib/Open311/GetServiceRequests.pm b/perllib/Open311/GetServiceRequests.pm new file mode 100644 index 000000000..2a82c64a1 --- /dev/null +++ b/perllib/Open311/GetServiceRequests.pm @@ -0,0 +1,168 @@ +package Open311::GetServiceRequests; + +use Moo; +use Open311; +use FixMyStreet::DB; +use FixMyStreet::App::Model::PhotoSet; +use DateTime::Format::W3CDTF; + +has system_user => ( is => 'rw' ); +has start_date => ( is => 'ro', default => sub { undef } ); +has end_date => ( is => 'ro', default => sub { undef } ); +has verbose => ( is => 'ro', default => 0 ); +has schema => ( is =>'ro', lazy => 1, default => sub { FixMyStreet::DB->schema->connect } ); + +sub fetch { + my $self = shift; + + my $bodies = $self->schema->resultset('Body')->search( + { + send_method => 'Open311', + fetch_problems => 1, + comment_user_id => { '!=', undef }, + endpoint => { '!=', '' }, + } + ); + + while ( my $body = $bodies->next ) { + + my $o = Open311->new( + endpoint => $body->endpoint, + api_key => $body->api_key, + jurisdiction => $body->jurisdiction, + ); + + $self->system_user( $body->comment_user ); + $self->create_problems( $o, $body ); + } +} + +sub create_problems { + my ( $self, $open311, $body ) = @_; + + my $args = {}; + + if ( $self->start_date || $self->end_date ) { + return 0 unless $self->start_date && $self->end_date; + + + $args->{start_date} = DateTime::Format::W3CDTF->format_datetime( $self->start_date ); + $args->{end_date} = DateTime::Format::W3CDTF->format_datetime( $self->end_date ); + } + + my $requests = $open311->get_service_requests( $args ); + + unless ( $open311->success ) { + warn "Failed to fetch ServiceRequest Updates for " . $body->name . ":\n" . $open311->error + if $self->verbose; + return 0; + } + + my $contacts = $self->schema->resultset('Contact') + ->active + ->search( { body_id => $body->id } ); + + for my $request (@{$requests->{request}}) { + # no point importing if we can't put it on the map + unless ($request->{service_request_id} && $request->{lat} && $request->{long}) { + warn "Not creating request '$request->{description}' for @{[$body->name]} as missing one of id, lat or long" + if $self->verbose; + next; + } + my $request_id = $request->{service_request_id}; + + my %params; + $params{generation} = mySociety::Config::get('MAPIT_GENERATION') + if mySociety::Config::get('MAPIT_GENERATION'); + + my ($latitude, $longitude) = ( $request->{lat}, $request->{long} ); + my $all_areas = + mySociety::MaPit::call( 'point', + "4326/$longitude,$latitude", %params ); + + # skip if it doesn't look like it's for this body + my @areas = grep { $all_areas->{$_->area_id} } $body->body_areas; + unless (@areas) { + warn "Not creating request id $request_id for @{[$body->name]} as outside body area" + if $self->verbose; + next; + } + + my $updated_time = eval { + DateTime::Format::W3CDTF->parse_datetime( + $request->{updated_datetime} || "" + )->set_time_zone( + FixMyStreet->time_zone || FixMyStreet->local_time_zone + ); + }; + if ($@) { + warn "Not creating problem $request_id for @{[$body->name]}, bad update time" + if $self->verbose; + next; + } + + my $updated = DateTime::Format::W3CDTF->format_datetime( + $updated_time->clone->set_time_zone('UTC') + ); + if ($args->{start_date} && $args->{end_date} && ($updated lt $args->{start_date} || $updated gt $args->{end_date}) ) { + warn "Problem id $request_id for @{[$body->name]} has an invalid time, not creating" + if $self->verbose; + next; + } + + my $created_time = eval { + DateTime::Format::W3CDTF->parse_datetime( + $request->{requested_datetime} || "" + )->set_time_zone( + FixMyStreet->time_zone || FixMyStreet->local_time_zone + ); + }; + $created_time = $updated_time if $@; + + my $problems; + my $criteria = { + external_id => $request_id, + }; + $problems = $self->schema->resultset('Problem')->to_body($body)->search( $criteria ); + + my @contacts = grep { $request->{service_code} eq $_->category } $contacts->all; + my $contact = $contacts[0] ? $contacts[0]->category : 'Other'; + + my $state = $open311->map_state($request->{status}); + + unless (my $p = $problems->first) { + my $problem = $self->schema->resultset('Problem')->new( + { + user => $self->system_user, + external_id => $request_id, + detail => $request->{description}, + title => $request->{title} || $request->{service_name} . ' problem', + anonymous => 0, + name => $self->system_user->name, + confirmed => $created_time, + created => $created_time, + lastupdate => $updated_time, + whensent => $created_time, + state => $state, + postcode => '', + used_map => 1, + latitude => $request->{lat}, + longitude => $request->{long}, + areas => ',' . $body->id . ',', + bodies_str => $body->id, + send_method_used => 'Open311', + category => $contact, + } + ); + + $open311->add_media($request->{media_url}, $problem) + if $request->{media_url}; + + $problem->insert(); + } + } + + return 1; +} + +1; diff --git a/perllib/Open311/GetUpdates.pm b/perllib/Open311/GetUpdates.pm index 1b1e339e3..f62acf4a8 100644 --- a/perllib/Open311/GetUpdates.pm +++ b/perllib/Open311/GetUpdates.pm @@ -41,7 +41,7 @@ sub get_updates { sub update_reports { my ( $self, $report_ids, $open311, $body ) = @_; - my $service_requests = $open311->get_service_requests( $report_ids ); + my $service_requests = $open311->get_service_requests( { report_ids => $report_ids } ); my $requests = $service_requests->{request}; for my $request (@$requests) { diff --git a/perllib/Open311/PopulateServiceList.pm b/perllib/Open311/PopulateServiceList.pm index 30d888eb4..af89e3169 100644 --- a/perllib/Open311/PopulateServiceList.pm +++ b/perllib/Open311/PopulateServiceList.pm @@ -267,6 +267,8 @@ sub _add_meta_to_contact { @meta = grep { ! $ignore{ $_->{ code } } } @meta; } + @meta = grep { !defined $_->{automated} || $_->{ automated } eq 'hidden_field' } @meta; + $contact->set_extra_fields(@meta); $contact->update; } diff --git a/t/cobrand/rutland.t b/t/cobrand/rutland.t new file mode 100644 index 000000000..8943e64fc --- /dev/null +++ b/t/cobrand/rutland.t @@ -0,0 +1,60 @@ +use CGI::Simple; +use FixMyStreet::TestMech; +use FixMyStreet::Script::Reports; +my $mech = FixMyStreet::TestMech->new; + +# Create test data +my $user = $mech->create_user_ok( 'rutland@example.com' ); +my $body = $mech->create_body_ok( 2482, 'Rutland County Council'); +my $contact = $mech->create_contact_ok( + body_id => $body->id, + category => 'Other', + email => 'LIGHT', +); +$contact->update; + +my @reports = $mech->create_problems_for_body( 1, $body->id, 'Test', { + cobrand => 'rutland', + user => $user, +}); +my $report = $reports[0]; + +for my $update ('in progress', 'unable to fix') { + FixMyStreet::DB->resultset('Comment')->find_or_create( { + problem_state => $update, + problem_id => $report->id, + user_id => $user->id, + name => 'User', + mark_fixed => 'f', + text => "This update marks it as $update", + state => 'confirmed', + confirmed => 'now()', + anonymous => 'f', + } ); +} + +subtest 'testing special Open311 behaviour', sub { + $report->set_extra_fields(); + $report->update; + $body->update( { send_method => 'Open311', endpoint => 'http://rutland.endpoint.example.com', jurisdiction => 'FMS', api_key => 'test', send_comments => 1 } ); + my $test_data; + FixMyStreet::override_config { + STAGING_FLAGS => { send_reports => 1 }, + ALLOWED_COBRANDS => [ 'fixmystreet', 'rutland' ], + }, sub { + $test_data = FixMyStreet::Script::Reports::send(); + }; + $report->discard_changes; + ok $report->whensent, 'Report marked as sent'; + is $report->send_method_used, 'Open311', 'Report sent via Open311'; + is $report->external_id, 248, 'Report has right external ID'; + + my $req = $test_data->{test_req_used}; + my $c = CGI::Simple->new($req->content); + is $c->param('attribute[title]'), $report->title, 'Request had title'; + is $c->param('attribute[description]'), $report->detail, 'Request had description'; + is $c->param('attribute[external_id]'), $report->id, 'Request had correct ID'; + is $c->param('jurisdiction_id'), 'FMS', 'Request had correct jurisdiction'; +}; + +done_testing(); diff --git a/t/open311/getservicerequests.t b/t/open311/getservicerequests.t new file mode 100644 index 000000000..878c178ef --- /dev/null +++ b/t/open311/getservicerequests.t @@ -0,0 +1,301 @@ +#!/usr/bin/env perl + +use FixMyStreet::TestMech; + +use_ok( 'Open311' ); +use_ok( 'Open311::GetServiceRequests' ); +use DateTime; +use DateTime::Format::W3CDTF; + +my $mech = FixMyStreet::TestMech->new; + +my $user = $mech->create_user_ok('system_user@example.com', name => 'test users'); +my $body = $mech->create_body_ok(2482, 'Bromley'); +my $contact = $mech->create_contact_ok( body_id => $body->id, category => 'sidewalks', email => 'sidewalks@example.com' ); + +my $dtf = DateTime::Format::W3CDTF->new; + +my $requests_xml = qq{<?xml version="1.0" encoding="utf-8"?> +<service_requests> +<request> +<service_request_id>638344</service_request_id> +<status>open</status> +<status_notes>This is a note.</status_notes> +<service_name>Sidewalk and Curb Issues</service_name> +<service_code>sidewalks</service_code> +<description>This is a sidewalk problem</description> +<agency_responsible></agency_responsible> +<service_notice></service_notice> +<requested_datetime>2010-04-14T06:37:38-08:00</requested_datetime> +<updated_datetime>2010-04-14T06:37:38-08:00</updated_datetime> +<expected_datetime>2010-04-15T06:37:38-08:00</expected_datetime> +<lat>51.4021</lat> +<long>0.01578</long> +</request> +<request> +<service_request_id>638345</service_request_id> +<status>investigating</status> +<status_notes>This is a for a different issue.</status_notes> +<service_name>Not Sidewalk and Curb Issues</service_name> +<service_code>not_sidewalks</service_code> +<description>This is a problem</description> +<agency_responsible></agency_responsible> +<service_notice></service_notice> +<requested_datetime>2010-04-15T06:37:38-08:00</requested_datetime> +<updated_datetime>2010-04-15T06:37:38-08:00</updated_datetime> +<expected_datetime>2010-04-15T06:37:38-08:00</expected_datetime> +<lat>51.4021</lat> +<long>0.01578</long> +</request> +</service_requests> +}; + +my $o = Open311->new( + jurisdiction => 'mysociety', + endpoint => 'http://example.com', + test_mode => 1, + test_get_returns => { 'requests.xml' => $requests_xml } +); + +subtest 'basic parsing checks' => sub { + my $update = Open311::GetServiceRequests->new( system_user => $user ); + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $update->create_problems( $o, $body ); + }; + + my $p1_date = $dtf->parse_datetime('2010-04-14T06:37:38-08:00') + ->set_time_zone( + FixMyStreet->time_zone || FixMyStreet->local_time_zone + ); + + my $p = FixMyStreet::DB->resultset('Problem')->search( + { external_id => 638344 } + )->first; + + ok $p, 'Found problem'; + is $p->detail, 'This is a sidewalk problem', 'correct problem description'; + is $p->created, $p1_date, 'Problem has correct creation date'; + is $p->confirmed, $p1_date, 'Problem has correct confirmed date'; + is $p->whensent, $p1_date, 'Problem has whensent set'; + is $p->state, 'confirmed', 'correct problem state'; + is $p->user->id, $user->id, 'user set to system user'; + is $p->category, 'sidewalks', 'correct problem category'; + + my $p2 = FixMyStreet::DB->resultset('Problem')->search( { external_id => 638345 } )->first; + ok $p2, 'second problem found'; + ok $p2->whensent, 'second problem marked sent'; + is $p2->state, 'investigating', 'second problem correct state'; + is $p2->category, 'Other', 'category falls back to Other'; +}; + +subtest 'check problems not re-created' => sub { + my $update = Open311::GetServiceRequests->new( system_user => $user ); + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $update->create_problems( $o, $body ); + }; + + my $count = FixMyStreet::DB->resultset('Problem')->count; + + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $update->create_problems( $o, $body ); + }; + + my $after_count = FixMyStreet::DB->resultset('Problem')->count; + + is $count, $after_count, "problems not re-created"; +}; + +for my $test ( + { + desc => 'problem with no id is not created', + detail => 'This is a problem with no service_code', + subs => { id => '', desc => 'This is a problem with service code' }, + }, + { + desc => 'problem with no lat is not created', + detail => 'This is a problem with no lat', + subs => { lat => '', desc => 'This is a problem with no lat' }, + }, + { + desc => 'problem with no long is not created', + detail => 'This is a problem with no long', + subs => { long => '', desc => 'This is a problem with no long' }, + }, + { + desc => 'problem with bad lat/long is not created', + detail => 'This is a problem with bad lat/long', + subs => { lat => '51', long => 0.1, desc => 'This is a problem with bad lat/long' }, + }, +) { + subtest $test->{desc} => sub { + my $xml = prepare_xml( $test->{subs} ); + my $o = Open311->new( + jurisdiction => 'mysociety', + endpoint => 'http://example.com', + test_mode => 1, + test_get_returns => { 'requests.xml' => $xml} + ); + + my $count = FixMyStreet::DB->resultset('Problem')->count; + my $update = Open311::GetServiceRequests->new( system_user => $user ); + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $update->create_problems( $o, $body ); + }; + my $after_count = FixMyStreet::DB->resultset('Problem')->count; + + warn $count; + is $count, $after_count, "problems not created"; + + my $with_text = FixMyStreet::DB->resultset('Problem')->search( { + detail => $test->{detail} + } )->count; + + is $with_text, 0, 'no matching problem created'; + }; +} + +my $date = DateTime->new( + year => 2010, + month => 4, + day => 14, + hour => 6, + minute => 37 +); + +for my $test ( + { + start_date => '1', + end_date => '', + desc => 'do not process if only a start_date', + subs => {}, + }, + { + start_date => '', + end_date => '1', + desc => 'do not process if only an end_date', + subs => {}, + }, +) { + subtest $test->{desc} => sub { + my $xml = prepare_xml( $test->{subs} ); + my $o = Open311->new( + jurisdiction => 'mysociety', + endpoint => 'http://example.com', + test_mode => 1, + test_get_returns => { 'requests.xml' => $xml} + ); + + my $update = Open311::GetServiceRequests->new( + start_date => $test->{start_date}, + end_date => $test->{end_date}, + system_user => $user, + ); + my $ret = $update->create_problems( $o, $body ); + + is $ret, 0, 'failed correctly' + }; +} + +$date = DateTime->new( + year => 2010, + month => 4, + day => 14, + hour => 6, + minute => 37 +); + +for my $test ( + { + start_date => $date->clone->add(hours => -2), + end_date => $date->clone->add(hours => -1), + desc => 'do not process if update time after end_date', + subs => {}, + }, + { + start_date => $date->clone->add(hours => 2), + end_date => $date->clone->add(hours => 4), + desc => 'do not process if update time before start_date', + subs => {}, + }, + { + start_date => $date->clone->add(hours => -2), + end_date => $date->clone->add(hours => 4), + desc => 'do not process if update time is bad', + subs => { update_time => '2010/12/12' }, + }, +) { + subtest $test->{desc} => sub { + my $xml = prepare_xml( $test->{subs} ); + my $o = Open311->new( + jurisdiction => 'mysociety', + endpoint => 'http://example.com', + test_mode => 1, + test_get_returns => { 'requests.xml' => $xml} + ); + + my $update = Open311::GetServiceRequests->new( + start_date => $test->{start_date}, + end_date => $test->{end_date}, + system_user => $user, + ); + my $count = FixMyStreet::DB->resultset('Problem')->count; + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $update->create_problems( $o, $body ); + }; + my $after = FixMyStreet::DB->resultset('Problem')->count; + + is $count, $after, 'problem not added'; + }; +} + +sub prepare_xml { + my $replacements = shift; + + my %defaults = ( + desc => 'this is a problem', + lat => 51.4021, + long => 0.01578, + id => 123456, + update_time => '2010-04-14T06:37:38-08:00', + %$replacements + ); + + my $xml = qq[<?xml version="1.0" encoding="utf-8"?> +<service_requests> +<request> +<service_request_id>XXX_ID</service_request_id> +<status>open</status> +<status_notes></status_notes> +<service_name>Sidewalk and Curb Issues</service_name> +<service_code>sidewalks</service_code> +<description>XXX_DESC</description> +<agency_responsible></agency_responsible> +<service_notice></service_notice> +<requested_datetime>2010-04-14T06:37:38-08:00</requested_datetime> +<updated_datetime>XXX_UPDATE_TIME</updated_datetime> +<expected_datetime>2010-04-15T06:37:38-08:00</expected_datetime> +<lat>XXX_LAT</lat> +<long>XXX_LONG</long> +</request> +</service_requests> +]; + + for my $key (keys %defaults) { + my $string = 'XXX_' . uc $key; + $xml =~ s/$string/$defaults{$key}/; + } + + return $xml; +} + +done_testing(); diff --git a/t/open311/getservicerequestupdates.t b/t/open311/getservicerequestupdates.t index da427e505..a53354685 100644 --- a/t/open311/getservicerequestupdates.t +++ b/t/open311/getservicerequestupdates.t @@ -1,6 +1,7 @@ #!/usr/bin/env perl use FixMyStreet::Test; +use Test::Output; use CGI::Simple; use LWP::Protocol::PSGI; use t::Mock::Static; @@ -782,6 +783,53 @@ foreach my $test ( { } } +foreach my $test ( { + desc => 'normally blank text produces a warning', + num_alerts => 1, + blank_updates_permitted => 0, + }, + { + desc => 'no warning if blank updates permitted', + num_alerts => 1, + blank_updates_permitted => 1, + }, +) { + subtest $test->{desc} => sub { + my $requests_xml = qq{<?xml version="1.0" encoding="utf-8"?> + <service_requests_updates> + <request_update> + <update_id>638344</update_id> + <service_request_id>@{[ $problem->external_id ]}</service_request_id> + <status>closed</status> + <description></description> + <updated_datetime>UPDATED_DATETIME</updated_datetime> + </request_update> + </service_requests_updates> + }; + + $problem->state( 'confirmed' ); + $problem->lastupdate( $dt->clone->subtract( hours => 3 ) ); + $problem->update; + + $requests_xml =~ s/UPDATED_DATETIME/$dt/; + + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $requests_xml } ); + + my $update = Open311::GetServiceRequestUpdates->new( + system_user => $user, + blank_updates_permitted => $test->{blank_updates_permitted}, + ); + + if ( $test->{blank_updates_permitted} ) { + stderr_is { $update->update_comments( $o, $bodies{2482} ) } '', 'No error message' + } else { + stderr_like { $update->update_comments( $o, $bodies{2482} ) } qr/Couldn't determine update text for/, 'Error message displayed' + } + $problem->discard_changes; + $problem->comments->delete; + } +} + done_testing(); sub setup_xml { diff --git a/t/open311/populate-service-list.t b/t/open311/populate-service-list.t index 7d4f491c6..149fb4b2a 100644 --- a/t/open311/populate-service-list.t +++ b/t/open311/populate-service-list.t @@ -646,6 +646,96 @@ subtest 'check bromely skip code' => sub { is_deeply $contact->get_extra_fields, $extra, 'all meta data saved for non bromley'; }; +subtest 'check automated meta skip 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> + <attribute> + <automated>server_set</automated> + <variable>true</variable> + <code>title</code> + <datatype>string</datatype> + <required>true</required> + <datatype_description>Type of bin</datatype_description> + <order>1</order> + <description>Type of bin</description> + </attribute> + <attribute> + <automated>hidden_field</automated> + <variable>true</variable> + <code>asset_id</code> + <datatype>string</datatype> + <required>true</required> + <datatype_description>Id of bin</datatype_description> + <order>1</order> + <description>Id of bin</description> + </attribute> + </attributes> +</service_definition> + '; + + my $contact = FixMyStreet::DB->resultset('Contact')->find_or_create( + { + body_id => 1, + email => '001', + category => 'Bins left out 24x7', + 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 ); + $processor->_current_body( $body ); + $processor->_current_service( { service_code => 100 } ); + + $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' + }, + { + automated => 'hidden_field', + variable => 'true', + code => 'asset_id', + datatype => 'string', + required => 'true', + datatype_description => 'Id of bin', + order => 1, + description => 'Id of bin' + } ]; + + $contact->discard_changes; + + is_deeply $contact->get_extra_fields, $extra, 'only hidden automated meta data saved'; +}; + sub get_standard_xml { return qq{<?xml version="1.0" encoding="utf-8"?> <services> diff --git a/t/sendreport/open311.t b/t/sendreport/open311.t index 1eb5535aa..23096aaac 100644 --- a/t/sendreport/open311.t +++ b/t/sendreport/open311.t @@ -1,4 +1,16 @@ +package FixMyStreet::Cobrand::Tester; + +use parent 'FixMyStreet::Cobrand::FixMyStreet'; + +sub open311_config { + my ($self, $row, $h, $params) = @_; + $params->{multi_photos} = 1; +} + +package main; + use CGI::Simple; +use Path::Tiny; use FixMyStreet::Script::Reports; use FixMyStreet::TestMech; my $mech = FixMyStreet::TestMech->new; @@ -41,4 +53,73 @@ subtest 'testing Open311 behaviour', sub { is $c->param('jurisdiction_id'), 'FMS', 'Request had correct jurisdiction'; }; +my ($photo_report) = $mech->create_problems_for_body( 1, $body->id, 'Test', { + cobrand => 'fixmystreet', + category => 'Potholes', + user => $user, +}); +my $sample_file = path(__FILE__)->parent->parent->child("app/controller/sample.jpg"); +my $UPLOAD_DIR = File::Temp->newdir(); +my @files = map { $_ x 40 . ".jpeg" } (1..3); +$sample_file->copy(path($UPLOAD_DIR, $_)) for @files; +$photo_report->photo(join(',', @files)); +$photo_report->update; + +subtest 'test report with multiple photos only sends one', sub { + $body->update( { send_method => 'Open311', endpoint => 'http://endpoint.example.com', jurisdiction => 'FMS', api_key => 'test' } ); + my $test_data; + + FixMyStreet::override_config { + STAGING_FLAGS => { send_reports => 1 }, + ALLOWED_COBRANDS => [ 'fixmystreet' ], + }, sub { + $test_data = FixMyStreet::Script::Reports::send(); + }; + $photo_report->discard_changes; + ok $photo_report->whensent, 'Report marked as sent'; + is $photo_report->send_method_used, 'Open311', 'Report sent via Open311'; + is $photo_report->external_id, 248, 'Report has right external ID'; + + my $req = $test_data->{test_req_used}; + my $c = CGI::Simple->new($req->content); + is $c->param('attribute[easting]'), 529025, 'Request had easting'; + is $c->param('attribute[northing]'), 179716, 'Request had northing'; + is $c->param('attribute[fixmystreet_id]'), $photo_report->id, 'Request had correct ID'; + is $c->param('jurisdiction_id'), 'FMS', 'Request had correct jurisdiction'; + my @media = $c->param('media_url'); + is_deeply \@media, [ + 'http://www.example.org/photo/' . $photo_report->id .'.0.full.jpeg?11111111' + ], 'One photo in media_url'; +}; + +$photo_report->whensent(undef); +$photo_report->cobrand('tester'); +$photo_report->send_method_used(''); +$photo_report->update(); + +subtest 'test sending multiple photos', sub { + $body->update( { send_method => 'Open311', endpoint => 'http://endpoint.example.com', jurisdiction => 'FMS', api_key => 'test' } ); + my $test_data; + + FixMyStreet::override_config { + STAGING_FLAGS => { send_reports => 1 }, + ALLOWED_COBRANDS => [ 'tester' ], + }, sub { + $test_data = FixMyStreet::Script::Reports::send(); + }; + $photo_report->discard_changes; + ok $photo_report->whensent, 'Report marked as sent'; + is $photo_report->send_method_used, 'Open311', 'Report sent via Open311'; + is $photo_report->external_id, 248, 'Report has right external ID'; + + my $req = $test_data->{test_req_used}; + my $c = CGI::Simple->new($req->content); + my @media = $c->param('media_url'); + is_deeply \@media, [ + 'http://www.example.org/photo/' . $photo_report->id .'.0.full.jpeg?11111111', + 'http://www.example.org/photo/' . $photo_report->id .'.1.full.jpeg?22222222', + 'http://www.example.org/photo/' . $photo_report->id .'.2.full.jpeg?33333333' + ], 'Multiple photos in media_url'; +}; + done_testing(); diff --git a/templates/email/rutland/_email_color_overrides.html b/templates/email/rutland/_email_color_overrides.html new file mode 100644 index 000000000..12ec97bc3 --- /dev/null +++ b/templates/email/rutland/_email_color_overrides.html @@ -0,0 +1,21 @@ +[% + +color_rutland_dark_green = '#265123' +color_rutland_mid_green = '#A7B980' +color_rutland_pale_green = '#DCE6C9' +color_rutland_dark_grey = '#3C3C3C' + +body_font_family = "'PT Sans', Verdana, sans-serif" + +header_background_color = color_rutland_mid_green +header_text_color = color_black + +secondary_column_background_color = color_rutland_pale_green + +button_background_color = color_rutland_dark_green +button_text_color = color_white + +logo_width = "150" # pixel measurement, but without 'px' suffix +logo_height = "77" # pixel measurement, but without 'px' suffix + +%] diff --git a/templates/web/base/admin/open311-form-fields.html b/templates/web/base/admin/open311-form-fields.html index d1067205c..6e6eb96f0 100644 --- a/templates/web/base/admin/open311-form-fields.html +++ b/templates/web/base/admin/open311-form-fields.html @@ -49,6 +49,17 @@ </p> [% IF show_body_fields %] + <div class="admin-hint"> + <p> + [% loc( + "Enabling this will suppress the error message that is normally emitted when an update has no description" + ) %] + </p> + </div> + <p> + <input type="checkbox" id="blank_updates_permitted" name="blank_updates_permitted"[% ' checked' IF object.blank_updates_permitted %]> + <label for="blank_updates_permitted" class="inline">[% loc('Permit blank updates') %]</label> + </p> [%# These fields aren't shown for contacts %] <div class="admin-hint"> <p> @@ -68,6 +79,21 @@ <div class="admin-hint"> <p> [% loc( + "Enable <strong>Open311 problem-fetching</strong> if you want to display reports created at + the endpoint to FixMyStreet. If you're not sure, you probably do not, so leave this unchecked. + For more information, see + <a href='https://www.mysociety.org/2013/02/20/open311-extended/' class='admin-offsite-link'>this article</a>." + ) %] + </p> + </div> + <p> + <input type="checkbox" id="fetch_problems" name="fetch_problems"[% ' checked' IF object.fetch_problems %]> + <label for="fetch_problems" class="inline">[% loc('Use Open311 problem fetching') %]</label> + </p> + + <div class="admin-hint"> + <p> + [% loc( "If you've enabled Open311 update-sending above, you must identify which FixMyStreet <strong>user</strong> will be attributed as the creator of those updates when they are shown on the site. Enter the ID (number) of that user." diff --git a/templates/web/base/footer.html b/templates/web/base/footer.html index e2bdbb01a..e2bdbb01a 100644..100755 --- a/templates/web/base/footer.html +++ b/templates/web/base/footer.html diff --git a/templates/web/base/report/new/category_extras_fields.html b/templates/web/base/report/new/category_extras_fields.html index 6ed6391c7..cf5cc37b4 100644 --- a/templates/web/base/report/new/category_extras_fields.html +++ b/templates/web/base/report/new/category_extras_fields.html @@ -1,7 +1,7 @@ [%- FOR meta IN metas %] [%- meta_name = meta.code -%] - [% IF c.cobrand.category_extra_hidden(meta_name) AND NOT show_hidden %] + [% IF c.cobrand.category_extra_hidden(meta) AND NOT show_hidden %] <input type="hidden" value="[% report_meta.$meta_name.value | html %]" name="[% cat_prefix %][% meta_name %]" id="[% cat_prefix %]form_[% meta_name %]"> diff --git a/templates/web/rutland/front/footer-marketing.html b/templates/web/rutland/front/footer-marketing.html new file mode 100755 index 000000000..7d998eba6 --- /dev/null +++ b/templates/web/rutland/front/footer-marketing.html @@ -0,0 +1,8 @@ + <div class="tablewrapper bordered footer-marketing"> + <p> + [% loc('') %] + </p> + <p> + [% loc('Powered by <a class="platform-logo" href="http://fixmystreet.org/">FixMyStreet Platform</a>') %] + </p> + </div> diff --git a/templates/web/rutland/site-name.html b/templates/web/rutland/site-name.html new file mode 100755 index 000000000..62188c84a --- /dev/null +++ b/templates/web/rutland/site-name.html @@ -0,0 +1 @@ +Rutland County Council FixMyStreet diff --git a/web/cobrands/rutland/RCCLogo.gif b/web/cobrands/rutland/RCCLogo.gif Binary files differnew file mode 100755 index 000000000..aeacf01f6 --- /dev/null +++ b/web/cobrands/rutland/RCCLogo.gif diff --git a/web/cobrands/rutland/_colours.scss b/web/cobrands/rutland/_colours.scss new file mode 100755 index 000000000..c3666ca17 --- /dev/null +++ b/web/cobrands/rutland/_colours.scss @@ -0,0 +1,34 @@ +/* LAYOUT */ + +// If you are wanting a right-to-left layout, uncomment the following line. +// $direction: right; + +/* COLOURS */ + +$orange: #ff9900; +$bluey: #6688ff; +$RCCGreen: #a7b980; +$RCCGreen_dark: #265123; +$RCCbg: #F1F1F1; + +$primary: $RCCGreen; +$primary_b: #000000; +$primary_text: #222222; + +$base_bg: $RCCbg; +$base_fg: #000; + +$map_nav_bg: $RCCbg; +$nav_fg: #000; +$nav_fg_hover: $primary; + +// Colour used for front page 'how to report a problem' steps +$col_big_numbers: #ccc; + +$col_click_map: $RCCGreen_dark; + +$col_fixed_label: #00BD08; +$col_fixed_label_dark: #4B8304; + +//$image-sprite: '/cobrands/rutland/RCCLogo.gif'; + diff --git a/web/cobrands/rutland/base.scss b/web/cobrands/rutland/base.scss new file mode 100755 index 000000000..4837e970a --- /dev/null +++ b/web/cobrands/rutland/base.scss @@ -0,0 +1,16 @@ +@import "../sass/h5bp"; +@import "./_colours"; +@import "../sass/mixins"; + +@import "../sass/base"; + + +#site-logo { + background: url("/cobrands/rutland/RCCLogo.gif"); + background-size: contain; + height: 50px; + width: 110px; +} + + + diff --git a/web/cobrands/rutland/images/email-logo.gif b/web/cobrands/rutland/images/email-logo.gif Binary files differnew file mode 100644 index 000000000..bab9d2eef --- /dev/null +++ b/web/cobrands/rutland/images/email-logo.gif diff --git a/web/cobrands/rutland/layout.scss b/web/cobrands/rutland/layout.scss new file mode 100755 index 000000000..eb0447be2 --- /dev/null +++ b/web/cobrands/rutland/layout.scss @@ -0,0 +1,15 @@ +@import "_colours"; +@import "../sass/layout"; + + +body.frontpage #site-header { + height: 10em; +} + + +body.frontpage #site-logo { + background: url("/cobrands/rutland/RCCLogo.gif"); + background-size: contain; + height: 100px; + width: 220px; +} |