Skip to content

Commit

Permalink
[Bexley] Handle incoming pushed waste updates.
Browse files Browse the repository at this point in the history
The push does not contain any real information, so we need
to look up the worksheet to get the completion state.
  • Loading branch information
MorayMySoc authored and dracos committed Nov 1, 2024
1 parent 5ba936d commit f60819a
Show file tree
Hide file tree
Showing 3 changed files with 404 additions and 80 deletions.
76 changes: 66 additions & 10 deletions perllib/FixMyStreet/App/Controller/Waste/Whitespace.pm
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,75 @@ has log_ident => (
sub receive_whitespace_event_notification : Path('/waste/whitespace') : Args(0) {
my ($self, $c) = @_;

my %headers = $c->req->headers->flatten;
$self->log($c->req->method);
$self->log(\%headers);
$self->log($c->req->parameters);
if ($c->req->body) {
my $soap = join('', $c->req->body->getlines);
$self->log($soap);
} else {
$self->log('No body');
}
require SOAP::Lite;

$c->detach('/waste/echo/soap_error', [ 'Invalid method', 405 ]) unless $c->req->method eq 'POST';

my $whitespace = $c->cobrand->feature('whitespace');
$c->detach('/waste/echo/soap_error', [ 'Missing config', 500 ]) unless $whitespace;

$c->detach('/waste/echo/soap_error', [ 'Missing body' ]) unless $c->req->body;
my $soap = join('', $c->req->body->getlines);
$self->log($soap);

my $body = $c->cobrand->body;
$c->detach('soap_error', [ 'Bad jurisdiction' ]) unless $body;

my $env = SOAP::Deserializer->deserialize($soap);
if ($env->valueof('//WorksheetPoke/secret') ne $whitespace->{push_secret}) {
return $c->detach('/waste/echo/soap_error', [ 'Unauthorized', 401 ]);
};

# Return okay if we're in endpoint test mode
my $cobrand_check = $c->cobrand->feature('waste');
$c->detach('soap_ok') if $cobrand_check eq 'echo-push-only';

my $worksheet = {
id => $env->valueof('//WorksheetPoke/worksheetId'),
ref => $env->valueof('//WorksheetPoke/worksheetReference'),
completed => $env->valueof('//WorksheetPoke/completedDate'),
};
$c->detach('/waste/echo/soap_error', [ 'Bad request', 400 ]) if _check_params($worksheet);

$c->forward('update_report', [ $worksheet ]);
$c->forward('soap_ok');
}

sub soap_ok : Private {
my ($self, $c) = @_;
$c->response->status(200);
$c->response->body('OK');
}

sub update_report : Private {
my ($self, $c, $worksheet) = @_;

my $request = $c->cobrand->construct_waste_open311_update({}, $worksheet);
return if !$request->{status} || $request->{status} eq 'confirmed';

my $report = delete $request->{report};
return unless $report;

$request->{comment_time} =
DateTime::Format::W3CDTF->parse_datetime($worksheet->{completed})
->set_time_zone(FixMyStreet->local_time_zone);

my $body = $c->cobrand->body;
my $updates = Open311::GetServiceRequestUpdates->new(
current_body => $body,
system_user => $body->comment_user
);

return unless $c->cobrand->waste_check_last_update({}, $report, $request->{status});
$updates->process_update($request, $report);
}

sub _check_params {
my $hash = shift;

for my $key (keys %{$hash}) {
return 1 unless $hash->{$key};
}
}

1;
109 changes: 58 additions & 51 deletions perllib/FixMyStreet/Cobrand/Bexley/Waste.pm
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ C<0001-01-01T00:00:00> represents an undefined date in Whitespace.
=cut

use constant WHITESPACE_UNDEF_DATE => '0001-01-01T00:00:00';
use constant MISSED_COLLECTION_SERVICE_PROPERTY_ID => 68;

sub waste_fetch_events {
my ( $self, $params ) = @_;
Expand All @@ -67,59 +68,18 @@ sub waste_fetch_events {
{ order_by => 'id' },
);

my $missed_collection_service_property_id = 68;
my $db = FixMyStreet::DB->schema->storage;

while ( my $report = $missed_collection_reports->next ) {
print 'Fetching data for report ' . $report->id . "\n" if $params->{verbose};

my $worksheet_id = $report->external_id =~ s/Whitespace-//r;
my $worksheet
= $self->whitespace->GetFullWorksheetDetails($worksheet_id);

# Get info for missed collection
my $missed_collection_properties;
for my $service_properties (
@{ $worksheet->{WSServiceProperties}{WorksheetServiceProperty}
// []
}
) {
next
unless $service_properties->{ServicePropertyID}
== $missed_collection_service_property_id;
my $request = $self->construct_waste_open311_update($params, {
id => $worksheet_id,
report => $report,
});
next if !$request->{status} || $request->{status} eq 'confirmed'; # Still in initial state
next unless $self->waste_check_last_update($params, $report, $request->{status});

$missed_collection_properties = $service_properties;
}

my $whitespace_state_string
= $missed_collection_properties
? $missed_collection_properties->{ServicePropertyValue}
: '';

my $config = $self->feature('whitespace');
my $new_state
= $config->{missed_collection_state_mapping}
{$whitespace_state_string};
unless ($new_state) {
print " No new state, skipping\n" if $params->{verbose};
next;
}

next
unless $self->waste_check_last_update( $params, $report,
$new_state );

my $request = {
description => $new_state->{text},
# No data from Whitespace for this, so make it now
comment_time =>
DateTime->now->set_time_zone( FixMyStreet->local_time_zone ),
external_status_code => $whitespace_state_string,
prefer_template => 1,
status => $new_state->{fms_state},
# TODO Is there an ID for specific worksheet update?
update_id => $report->external_id,
};
$request->{comment_time} = DateTime->now->set_time_zone( FixMyStreet->local_time_zone ),

print
" Updating report to state '$request->{status}' - '$request->{description}' ($request->{external_status_code})\n"
Expand All @@ -132,14 +92,61 @@ sub waste_fetch_events {
}
}

sub construct_waste_open311_update {
my ($self, $params, $worksheet) = @_;

my $report = $worksheet->{report} || $self->problems->find($worksheet->{ref});
return unless $report;

$worksheet = $self->whitespace->GetFullWorksheetDetails($worksheet->{id});

# Get info for missed collection
my $missed_collection_properties;
for my $service_properties (
@{ $worksheet->{WSServiceProperties}{WorksheetServiceProperty}
// []
}
) {
next
unless $service_properties->{ServicePropertyID}
== MISSED_COLLECTION_SERVICE_PROPERTY_ID;

$missed_collection_properties = $service_properties;
}

my $whitespace_state_string
= $missed_collection_properties
? $missed_collection_properties->{ServicePropertyValue}
: '';

my $config = $self->feature('whitespace');
my $new_state
= $config->{missed_collection_state_mapping}
{$whitespace_state_string};
unless ($new_state) {
print " No new state, skipping\n" if $params->{verbose};
return;
}

my $request = {
description => $new_state->{text},
status => $new_state->{fms_state},
update_id => 'waste',
external_status_code => $whitespace_state_string,
prefer_template => 1,
report => $report,
};
return $request;
}

sub waste_check_last_update {
my ( $self, $params, $report, $new_state ) = @_;
my ( $self, $params, $report, $state ) = @_;

my $last_update = $report->comments->search(
{ external_id => { like => 'Whitespace%' } },
{ external_id => 'waste', },
)->order_by('-id')->first;

if ( $last_update && $new_state->{fms_state} eq $last_update->problem_state ) {
if ( $last_update && $state eq $last_update->problem_state ) {
print " Latest update matches fetched state, skipping\n" if $params->{verbose};
return;
}
Expand Down
Loading

0 comments on commit f60819a

Please sign in to comment.