Skip to content

Commit

Permalink
[Merton] Initial setup.
Browse files Browse the repository at this point in the history
  • Loading branch information
dracos committed Apr 10, 2024
1 parent 512defc commit f9c6e88
Show file tree
Hide file tree
Showing 12 changed files with 559 additions and 0 deletions.
11 changes: 11 additions & 0 deletions conf/council-merton_echo.yml-example
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
url: ""
username: ""
password: ""

client_reference_prefix: "MRT"
service_whitelist: {}
service_to_event_type: {}
service_id_override: {}
data_key_open311_map: {}
default_data_all: {}
default_data_event_type: {}
2 changes: 2 additions & 0 deletions conf/council-www.merton.gov.uk.yml-example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
endpoint: https://localhost:4000/
api_key: 123
3 changes: 3 additions & 0 deletions perllib/Open311/Endpoint/Integration/Passthrough.pm
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ sub services {
my %ignore = map { $_ => 1 } @{$self->ignore_services};
foreach (@{$xml->{service}}) {
next if $ignore{$_->{service_code}};
$_->{groups} = delete $_->{group} if $_->{group};
$_->{description} ||= '';
my $service = Open311::Endpoint::Service->new(%$_);
if ($_->{metadata} eq 'true') {
# An empty one is enough to get the metadata true passed out
Expand Down Expand Up @@ -158,6 +160,7 @@ sub service {
# Need to maintain the order
$_->{values_sorted} = [ map { $_->{key} } @{$_->{values}} ];
$_->{values} = { map { $_->{key} => $_->{name} } @{$_->{values}} };
$_->{description} ||= '';
my $attribute = Open311::Endpoint::Service::Attribute->new(%$_);
push @{ $service->attributes }, $attribute;
}
Expand Down
67 changes: 67 additions & 0 deletions perllib/Open311/Endpoint/Integration/UK/Merton.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
=head1 NAME
Open311::Endpoint::Integration::UK::Merton - Merton integration set-up
=head1 SYNOPSIS
Merton has multiple backends, so is set up as a subclass
of the Multi integration.
=head1 DESCRIPTION
=cut

package Open311::Endpoint::Integration::UK::Merton;

use Moo;
extends 'Open311::Endpoint::Integration::Multi';

use Module::Pluggable
search_path => ['Open311::Endpoint::Integration::UK::Merton'],
instantiate => 'new';

has jurisdiction_id => (
is => 'ro',
default => 'merton',
);

=pod
Merton's two endpoints do not overlap in IDs (one GUID, one not) or service
codes, so there is no need to prefix them. This code overrides the default
Multi code to not change anything, and cope accordingly.
=cut

sub _map_with_new_id {
my ($self, $attributes, @results) = @_;
@results = map {
my ($name, $result) = @$_;
$result;
} @results;
return @results;
}

my $guid_regex = qr/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;

sub _map_from_new_id {
my ($self, $code, $type) = @_;

my $integration;
if ($type eq 'request') {
if ($code =~ /$guid_regex/) {
$integration = 'Echo';
} else {
$integration = 'Passthrough';
}
} elsif ($type eq 'service') {
if ($code =~ /^\d+/ || $code eq 'missed') {
$integration = 'Echo';
} else {
$integration = 'Passthrough';
}
}
return ($integration, $code);
}

__PACKAGE__->run_if_script;
58 changes: 58 additions & 0 deletions perllib/Open311/Endpoint/Integration/UK/Merton/Echo.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
=head1 NAME
Open311::Endpoint::Integration::UK::Merton::Echo - Merton-specific Echo backend configuration
=head1 SYNOPSIS
Merton specifics for its Echo backend
=head1 DESCRIPTION
=cut

package Open311::Endpoint::Integration::UK::Merton::Echo;

use DateTime;
use Moo;
extends 'Open311::Endpoint::Integration::Echo';

around BUILDARGS => sub {
my ($orig, $class, %args) = @_;
$args{jurisdiction_id} = 'merton_echo';
return $class->$orig(%args);
};

around check_for_data_value => sub {
my ($orig, $class, $name, $args, $request, $parent_name) = @_;

my $service = $args->{attributes}{service_id} || '';

return 1 if $name eq 'Container Mix' && ($service eq '2241' || $service eq '2250' || $service eq '2246' || $service eq '3571');
return 1 if $name eq 'Paper' && ($service eq '2240' || $service eq '2249' || $service eq '2632');
return 1 if $name eq 'Food' && ($service eq '2239' || $service eq '2248');
return 1 if $name eq 'Garden' && $service eq '2247';
return 1 if $name eq 'Refuse Bag' && $service eq '2242';
return 1 if $name eq 'Refuse Bin' && ($service eq '2238' || $service eq '2243' || $service eq '3576');

# Garden waste
if ($args->{service_code} eq '1638') {
my $method = $args->{attributes}{LastPayMethod} || '';
return 2 if $name eq 'Payment Type' && $method eq 3; # DD
return 3 if $name eq 'Payment Type' && $method eq 4; # 'cheque' (or phone)
}

# Bulky items
if ($args->{service_code} eq '1636') {
# Default in configuration is Payment Type 1 (Card), Payment Method 2 (Website)
my $method = $args->{attributes}{payment_method} || '';
return 2 if $name eq 'Payment Type' && $method eq 'cheque'; # Cheque
if ($name eq 'Payment Method') {
return 1 if $method eq 'csc' || $method eq 'cheque'; # Borough Phone Payment
return 2 if $method eq 'credit_card'; # Borough Website Payment
}
}

return $class->$orig($name, $args, $request, $parent_name);
};

1;
23 changes: 23 additions & 0 deletions perllib/Open311/Endpoint/Integration/UK/Merton/Passthrough.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
=head1 NAME
Open311::Endpoint::Integration::UK::Merton::Passthrough - Merton Passthrough backend
=head1 SUMMARY
This is the Merton-specific Passthrough integration. It is a standard
Open311 server.
=cut

package Open311::Endpoint::Integration::UK::Merton::Passthrough;

use Moo;
extends 'Open311::Endpoint::Integration::Passthrough';

around BUILDARGS => sub {
my ($orig, $class, %args) = @_;
$args{jurisdiction_id} = 'www.merton.gov.uk';
return $class->$orig(%args);
};

1;
119 changes: 119 additions & 0 deletions t/open311/endpoint/merton.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Override the original to provide a config_file
package Open311::Endpoint::Integration::UK::Merton::Echo;
use Path::Tiny;
use Moo;
extends 'Open311::Endpoint::Integration::Echo';
around BUILDARGS => sub {
my ($orig, $class, %args) = @_;
$args{jurisdiction_id} = 'merton_dummy';
$args{config_file} = path(__FILE__)->sibling("merton.yml")->stringify;
return $class->$orig(%args);
};

package main;

use strict;
use warnings;

BEGIN { $ENV{TEST_MODE} = 1; }

use Test::More;
use Test::MockModule;
use JSON::MaybeXS;
use Path::Tiny;

my $pt = Test::MockModule->new('Open311::Endpoint::Integration::UK::Merton::Passthrough');
$pt->mock(endpoint => sub { '' });

my $ua = Test::MockModule->new('LWP::UserAgent');
$ua->mock(get => sub {
my $file;
if ($_[1] eq 'services.xml') {
$file = 'xml/merton/services.xml';
} elsif ($_[1] eq 'services/TEST.xml') {
$file = 'xml/merton/service.xml';
}
return HTTP::Response->new(200, 'OK', [], path(__FILE__)->sibling($file)->slurp);
});

use_ok 'Open311::Endpoint::Integration::UK::Merton';

my $endpoint = Open311::Endpoint::Integration::UK::Merton->new;

subtest "Get service definition with no prefix" => sub {
my $res = $endpoint->run_test_request( GET => '/services/1635.json' );
ok $res->is_success, 'valid request' or diag $res->content;
my $i = 1;
is_deeply decode_json($res->content), {
'service_code' => '1635',
'attributes' => [
(map { {
'automated' => 'hidden_field',
'datatype_description' => '',
'datatype' => 'string',
'order' => $i++,
'required' => 'false',
'variable' => 'true',
%$_,
} }
{ 'code' => 'uprn', 'description' => 'UPRN reference', },
{ 'code' => 'property_id', 'description' => 'Property ID', },
{ 'code' => 'service_id', 'description' => 'Service ID', },
{
'required' => 'true',
'automated' => 'server_set',
'variable' => 'false',
'code' => 'fixmystreet_id',
'description' => 'external system ID'
},
{ 'code' => 'Action', 'description' => 'Action' },
{ 'code' => 'Container_Type', 'description' => 'Container_Type' },
{ 'code' => 'Notes', 'description' => 'Notes' },
{ 'code' => 'Reason', 'description' => 'Reason' },
),
]
}, 'correct json returned';
};


subtest "Get service definition with a group" => sub {
my $res = $endpoint->run_test_request( GET => '/services.xml' );
ok $res->is_success, 'valid request' or diag $res->content;
my @codes = $res->content =~ /<service_code>(.*?)<\/service_code>/g;
is_deeply \@codes, [ '1635', '1636', '1638', 'missed', 'GR' ];

$res = $endpoint->run_test_request( GET => '/services/TEST.json' );
ok $res->is_success, 'valid request' or diag $res->content;
my $i = 1;
is_deeply decode_json($res->content), {
'service_code' => 'TEST',
'attributes' => [
(map { {
'automated' => 'hidden_field',
'datatype' => 'string',
'datatype_description' => '',
'order' => $i++,
'required' => 'true',
'variable' => 'true',
'description' => '',
'code' => $_,
} } qw/service usrn/),
(map { {
'automated' => 'server_set',
'datatype' => 'string',
'datatype_description' => '',
'order' => $i++,
'required' => 'false',
'variable' => 'false',
%$_,
} }
{ 'code' => 'fixmystreet_id', 'description' => 'FixMyStreet ID', required => 'true' },
{ 'code' => 'easting', 'description' => 'Easting', datatype => 'number' },
{ 'code' => 'northing', 'description' => 'Northing', datatype => 'number' },
{ 'code' => 'closest_address', 'description' => 'Closest address' },
),
]
}, 'correct json returned';
};

done_testing;
62 changes: 62 additions & 0 deletions t/open311/endpoint/merton.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
url: http://merton.example.org/
username: username
password: password

client_reference_prefix: MRT

service_whitelist:
missed: 'Report missed collection'
1635: 'Request new container'
1638: 'Garden Subscription'
1636: 'Bulky collection'

service_extra_data:
missed:
Exact_Location: 1
1635:
Action: 1
Reason: 1
Notes: 1
Container_Type: 1

waste_services:
- missed
- 1635
- 1636
- 1638

service_mapping:
2238: 405
2242: 405
2239: 408
2240: 408
2241: 408
2247: 409

service_id_override:
1635: 412
1636: 413
1638: 409

service_to_event_type:
missed:
405: 1566
408: 1568
409: 1568

data_key_open311_map:
First Name: 'first_name'
Surname: 'last_name'
Email: 'email'
Telephone: 'phone'

default_data_all:
Resident Requires Feedback: 1

default_data_event_type:
1636:
Payment Type: 1
Payment Method: 2
1635:
Action: 1 # Deliver
Reason: 3 # Change Capacity
Loading

0 comments on commit f9c6e88

Please sign in to comment.