aboutsummaryrefslogtreecommitdiffstats
path: root/perllib
diff options
context:
space:
mode:
Diffstat (limited to 'perllib')
-rw-r--r--perllib/FixMyStreet/Cobrand/Bromley.pm19
-rw-r--r--perllib/FixMyStreet/Cobrand/Buckinghamshire.pm5
-rw-r--r--perllib/FixMyStreet/Cobrand/Lewisham.pm15
-rw-r--r--perllib/FixMyStreet/Cobrand/Oxfordshire.pm13
-rw-r--r--perllib/FixMyStreet/DB/Result/Comment.pm20
-rw-r--r--perllib/FixMyStreet/DB/Result/Problem.pm10
-rw-r--r--perllib/FixMyStreet/Script/Questionnaires.pm2
-rw-r--r--perllib/FixMyStreet/Script/Reports.pm2
-rw-r--r--perllib/FixMyStreet/SendReport/Email.pm2
-rw-r--r--perllib/Open311.pm2
-rw-r--r--perllib/Open311/GetServiceRequestUpdates.pm24
-rwxr-xr-xperllib/Open311/PostServiceRequestUpdates.pm128
12 files changed, 220 insertions, 22 deletions
diff --git a/perllib/FixMyStreet/Cobrand/Bromley.pm b/perllib/FixMyStreet/Cobrand/Bromley.pm
index a6d58504c..e1021eda9 100644
--- a/perllib/FixMyStreet/Cobrand/Bromley.pm
+++ b/perllib/FixMyStreet/Cobrand/Bromley.pm
@@ -165,5 +165,24 @@ sub open311_config {
$params->{extended_description} = 0;
}
+sub open311_config_updates {
+ my ($self, $params) = @_;
+ $params->{use_extended_updates} = 1;
+ $params->{endpoints} = {
+ service_request_updates => 'update.xml',
+ update => 'update.xml'
+ };
+}
+
+sub open311_pre_send {
+ my ($self, $row, $open311) = @_;
+
+ my $extra = $row->extra || {};
+ unless ( $extra->{title} ) {
+ $extra->{title} = $row->user->title;
+ $row->extra( $extra );
+ }
+}
+
1;
diff --git a/perllib/FixMyStreet/Cobrand/Buckinghamshire.pm b/perllib/FixMyStreet/Cobrand/Buckinghamshire.pm
index 783a565f1..fb074da85 100644
--- a/perllib/FixMyStreet/Cobrand/Buckinghamshire.pm
+++ b/perllib/FixMyStreet/Cobrand/Buckinghamshire.pm
@@ -100,6 +100,11 @@ sub open311_post_send {
$sender->send($row, $h);
}
+sub open311_config_updates {
+ my ($self, $params) = @_;
+ $params->{mark_reopen} = 1;
+}
+
sub map_type { 'Buckinghamshire' }
sub default_map_zoom { 3 }
diff --git a/perllib/FixMyStreet/Cobrand/Lewisham.pm b/perllib/FixMyStreet/Cobrand/Lewisham.pm
new file mode 100644
index 000000000..325f6e833
--- /dev/null
+++ b/perllib/FixMyStreet/Cobrand/Lewisham.pm
@@ -0,0 +1,15 @@
+package FixMyStreet::Cobrand::Lewisham;
+use base 'FixMyStreet::Cobrand::UK';
+
+use strict;
+use warnings;
+
+sub council_area_id { 2492 }
+
+sub open311_post_update_skip {
+ my ($self) = @_;
+ return 1;
+}
+
+1;
+
diff --git a/perllib/FixMyStreet/Cobrand/Oxfordshire.pm b/perllib/FixMyStreet/Cobrand/Oxfordshire.pm
index f03f1b605..4d627c756 100644
--- a/perllib/FixMyStreet/Cobrand/Oxfordshire.pm
+++ b/perllib/FixMyStreet/Cobrand/Oxfordshire.pm
@@ -171,6 +171,19 @@ sub open311_config {
$params->{extended_description} = 'oxfordshire';
}
+sub open311_config_updates {
+ my ($self, $params) = @_;
+ $params->{use_customer_reference} = 1;
+}
+
+sub should_skip_sending_update {
+ my ($self, $update ) = @_;
+
+ # Oxfordshire stores the external id of the problem as a customer reference
+ # in metadata
+ return 1 if !$update->problem->get_extra_metadata('customer_reference');
+}
+
sub on_map_default_status { return 'open'; }
sub contact_email {
diff --git a/perllib/FixMyStreet/DB/Result/Comment.pm b/perllib/FixMyStreet/DB/Result/Comment.pm
index b4e42b456..d27c5ea8c 100644
--- a/perllib/FixMyStreet/DB/Result/Comment.pm
+++ b/perllib/FixMyStreet/DB/Result/Comment.pm
@@ -115,6 +115,26 @@ my $stz = sub {
around created => $stz;
around confirmed => $stz;
+=head2 get_cobrand_logged
+
+Get a cobrand object for the cobrand the update was made on.
+
+e.g. if an update was logged at www.fixmystreet.com, this will be a
+FixMyStreet::Cobrand::FixMyStreet object.
+
+=cut
+
+has get_cobrand_logged => (
+ is => 'ro',
+ lazy => 1,
+ default => sub {
+ my $self = shift;
+ my $cobrand_class = FixMyStreet::Cobrand->get_class_for_moniker( $self->cobrand );
+ return $cobrand_class->new;
+ },
+);
+
+
# You can replace this text with custom code or comments, and it will be preserved on regeneration
sub check_for_errors {
diff --git a/perllib/FixMyStreet/DB/Result/Problem.pm b/perllib/FixMyStreet/DB/Result/Problem.pm
index 76a6f72fb..2192158d3 100644
--- a/perllib/FixMyStreet/DB/Result/Problem.pm
+++ b/perllib/FixMyStreet/DB/Result/Problem.pm
@@ -780,7 +780,7 @@ sub duration_string {
sub local_coords {
my $self = shift;
- my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($self->cobrand)->new;
+ my $cobrand = $self->get_cobrand_logged;
if ($cobrand->moniker eq 'zurich') {
my ($x, $y) = Geo::Coordinates::CH1903Plus::from_latlon($self->latitude, $self->longitude);
return ( int($x+0.5), int($y+0.5) );
@@ -896,8 +896,9 @@ sub updates_sent_to_body {
return unless $self->send_method_used && $self->send_method_used eq 'Open311';
# Some bodies only send updates *to* FMS, they don't receive updates.
- # NB See also the list in bin/send-comments
- my $excluded = qr{Lewisham|Oxfordshire};
+ my $cobrand = $self->get_cobrand_logged;
+ my $handler = $cobrand->call_hook(get_body_handler_for_problem => $self);
+ return 0 if $handler && $handler->call_hook('open311_post_update_skip');
my @bodies = values %{ $self->bodies };
my @updates_sent = grep {
@@ -905,8 +906,7 @@ sub updates_sent_to_body {
(
$_->send_method eq 'Open311' ||
$_->send_method eq 'Noop' # Sending might be temporarily disabled
- ) &&
- !($_->name =~ /$excluded/)
+ )
} @bodies;
return scalar @updates_sent;
}
diff --git a/perllib/FixMyStreet/Script/Questionnaires.pm b/perllib/FixMyStreet/Script/Questionnaires.pm
index d89f1bcf8..bcdaa06d6 100644
--- a/perllib/FixMyStreet/Script/Questionnaires.pm
+++ b/perllib/FixMyStreet/Script/Questionnaires.pm
@@ -43,7 +43,7 @@ sub send_questionnaires_period {
while (my $row = $unsent->next) {
- my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($row->cobrand)->new();
+ my $cobrand = $row->get_cobrand_logged;
$cobrand->set_lang_and_domain($row->lang, 1);
FixMyStreet::Map::set_map_class($cobrand->map_type);
diff --git a/perllib/FixMyStreet/Script/Reports.pm b/perllib/FixMyStreet/Script/Reports.pm
index 87f9fd124..dd8f4e370 100644
--- a/perllib/FixMyStreet/Script/Reports.pm
+++ b/perllib/FixMyStreet/Script/Reports.pm
@@ -44,7 +44,7 @@ sub send(;$) {
debug_print("starting to loop through unsent problem reports...") if $debug_mode;
while (my $row = $unsent->next) {
- my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($row->cobrand)->new();
+ my $cobrand = $row->get_cobrand_logged;
FixMyStreet::DB->schema->cobrand($cobrand);
if ($debug_mode) {
diff --git a/perllib/FixMyStreet/SendReport/Email.pm b/perllib/FixMyStreet/SendReport/Email.pm
index 4307694a1..1b484aefe 100644
--- a/perllib/FixMyStreet/SendReport/Email.pm
+++ b/perllib/FixMyStreet/SendReport/Email.pm
@@ -71,7 +71,7 @@ sub send {
}
my ($verbose, $nomail) = CronFns::options();
- my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($row->cobrand)->new();
+ my $cobrand = $row->get_cobrand_logged;
$cobrand = $cobrand->call_hook(get_body_handler_for_problem => $row) || $cobrand;
my $params = {
diff --git a/perllib/Open311.pm b/perllib/Open311.pm
index 6c6ec59cc..56fe567c5 100644
--- a/perllib/Open311.pm
+++ b/perllib/Open311.pm
@@ -397,7 +397,7 @@ sub _populate_service_request_update_params {
}
if ( $comment->photo ) {
- my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($comment->cobrand)->new();
+ my $cobrand = $comment->get_cobrand_logged;
my $email_base_url = $cobrand->base_url($comment->cobrand_data);
my $url = $email_base_url . $comment->photos->[0]->{url_full};
$params->{media_url} = $url;
diff --git a/perllib/Open311/GetServiceRequestUpdates.pm b/perllib/Open311/GetServiceRequestUpdates.pm
index bef1aca67..c6da37790 100644
--- a/perllib/Open311/GetServiceRequestUpdates.pm
+++ b/perllib/Open311/GetServiceRequestUpdates.pm
@@ -18,7 +18,7 @@ Readonly::Scalar my $AREA_ID_BROMLEY => 2482;
Readonly::Scalar my $AREA_ID_OXFORDSHIRE => 2237;
sub fetch {
- my $self = shift;
+ my ($self, $open311) = @_;
my $bodies = $self->schema->resultset('Body')->search(
{
@@ -31,25 +31,23 @@ sub fetch {
while ( my $body = $bodies->next ) {
- my $o = Open311->new(
- endpoint => $body->endpoint,
- api_key => $body->api_key,
- jurisdiction => $body->jurisdiction,
+ my %open311_conf = (
+ endpoint => $body->endpoint,
+ api_key => $body->api_key,
+ jurisdiction => $body->jurisdiction,
extended_statuses => $body->send_extended_statuses,
);
- # custom endpoint URLs because these councils have non-standard paths
- if ( $body->areas->{$AREA_ID_BROMLEY} ) {
- my $endpoints = $o->endpoints;
- $endpoints->{update} = 'update.xml';
- $endpoints->{service_request_updates} = 'update.xml';
- $o->endpoints( $endpoints );
- }
+ my $cobrand = $body->get_cobrand_handler;
+ $cobrand->call_hook(open311_config_updates => \%open311_conf)
+ if $cobrand;
+
+ $open311 //= Open311->new(%open311_conf);
$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 );
+ $self->update_comments( $open311, $body );
}
}
diff --git a/perllib/Open311/PostServiceRequestUpdates.pm b/perllib/Open311/PostServiceRequestUpdates.pm
new file mode 100755
index 000000000..63e149ece
--- /dev/null
+++ b/perllib/Open311/PostServiceRequestUpdates.pm
@@ -0,0 +1,128 @@
+package Open311::PostServiceRequestUpdates;
+
+use strict;
+use warnings;
+use v5.14;
+
+use DateTime;
+use Moo;
+use FixMyStreet;
+use FixMyStreet::Cobrand;
+use FixMyStreet::DB;
+use Open311;
+
+use constant SEND_METHOD_OPEN311 => 'Open311';
+
+has verbose => ( is => 'ro', default => 0 );
+
+sub send {
+ my $self = shift;
+
+ my $bodies = FixMyStreet::DB->resultset('Body')->search( {
+ send_method => SEND_METHOD_OPEN311,
+ send_comments => 1,
+ } );
+
+ while ( my $body = $bodies->next ) {
+ my $cobrand = $body->get_cobrand_handler;
+ next if $cobrand && $cobrand->call_hook('open311_post_update_skip');
+ $self->process_body($body);
+ }
+}
+
+sub open311_params {
+ my ($self, $body) = @_;
+
+ my %open311_conf = (
+ endpoint => $body->endpoint,
+ jurisdiction => $body->jurisdiction,
+ api_key => $body->api_key,
+ extended_statuses => $body->send_extended_statuses,
+ );
+
+ my $cobrand = $body->get_cobrand_handler;
+ $cobrand->call_hook(open311_config_updates => \%open311_conf)
+ if $cobrand;
+
+ return %open311_conf;
+}
+
+sub process_body {
+ my ($self, $body) = @_;
+
+ my $o = Open311->new( $self->open311_params($body) );
+
+ my $comments = FixMyStreet::DB->resultset('Comment')->search( {
+ 'me.whensent' => undef,
+ 'me.external_id' => undef,
+ 'me.state' => 'confirmed',
+ 'me.confirmed' => { '!=' => undef },
+ 'problem.whensent' => { '!=' => undef },
+ 'problem.external_id' => { '!=' => undef },
+ 'problem.bodies_str' => { -like => '%' . $body->id . '%' },
+ 'problem.send_method_used' => 'Open311',
+ },
+ {
+ join => 'problem',
+ order_by => [ 'confirmed', 'id' ],
+ }
+ );
+
+ while ( my $comment = $comments->next ) {
+ my $cobrand = $body->get_cobrand_handler || $comment->get_cobrand_logged;
+
+ # Some cobrands (e.g. Buckinghamshire) don't want to receive updates
+ # from anyone except the original problem reporter.
+ if ($cobrand->call_hook(should_skip_sending_update => $comment)) {
+ unless (defined $comment->get_extra_metadata('cobrand_skipped_sending')) {
+ $comment->set_extra_metadata(cobrand_skipped_sending => 1);
+ $comment->update;
+ }
+ next;
+ }
+
+ next if !$self->verbose && $comment->send_fail_count && retry_timeout($comment);
+
+ $self->process_update($body, $o, $comment, $cobrand);
+ }
+}
+
+sub process_update {
+ my ($self, $body, $o, $comment, $cobrand) = @_;
+
+ $cobrand->call_hook(open311_pre_send => $comment, $o);
+
+ my $id = $o->post_service_request_update( $comment );
+
+ if ( $id ) {
+ $comment->update( {
+ external_id => $id,
+ whensent => \'current_timestamp',
+ } );
+ } else {
+ $comment->update( {
+ send_fail_count => $comment->send_fail_count + 1,
+ send_fail_timestamp => \'current_timestamp',
+ send_fail_reason => "Failed to post over Open311\n\n" . $o->error,
+ } );
+
+ if ( $self->verbose && $o->error ) {
+ warn $o->error;
+ }
+ }
+}
+
+sub retry_timeout {
+ my $row = shift;
+
+ my $tz = FixMyStreet->local_time_zone;
+ my $now = DateTime->now( time_zone => $tz );
+ my $diff = $now - $row->send_fail_timestamp;
+ if ( $diff->in_units( 'minutes' ) < 30 ) {
+ return 1;
+ }
+
+ return 0;
+}
+
+1;