Skip to content

Commit 184763b

Browse files
[Bexley][WW] Implement Agile call to 'cancel'
1 parent 81bde08 commit 184763b

File tree

5 files changed

+179
-6
lines changed

5 files changed

+179
-6
lines changed

perllib/Integrations/Agile.pm

+11
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use HTTP::Request;
1919
use JSON::MaybeXS;
2020
use LWP::UserAgent;
2121
use Moo;
22+
use URI;
2223

2324
with 'Role::Config';
2425
with 'Role::Logger';
@@ -69,6 +70,16 @@ sub api_call {
6970
}
7071
}
7172

73+
sub Cancel {
74+
my ( $self, $params ) = @_;
75+
76+
return $self->api_call(
77+
action => 'cancel',
78+
controller => 'servicecontract',
79+
data => $params,
80+
);
81+
}
82+
7283
sub IsAddressFree {
7384
my ( $self, $uprn ) = @_;
7485

perllib/Open311/Endpoint/Integration/Agile.pm

+48
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ has agile => (
4747
},
4848
);
4949

50+
use constant SERVICE_TO_SUB_MAPPING => {
51+
garden_subscription => \&_garden_subscription,
52+
garden_subscription_cancel => \&_garden_subscription_cancel,
53+
};
54+
5055
use constant PAYMENT_METHOD_MAPPING => {
5156
credit_card => 'CREDITCARD',
5257
direct_debit => 'DIRECTDEBIT',
@@ -87,6 +92,16 @@ sub post_service_request {
8792
$self->logger->debug(
8893
"post_service_request arguments: " . encode_json($args) );
8994

95+
my $sub = SERVICE_TO_SUB_MAPPING->{$service->service_code};
96+
97+
die 'Service \'' . $service->service_code . '\' not handled' unless $sub;
98+
99+
return &$sub( $self, $args );
100+
}
101+
102+
sub _garden_subscription {
103+
my ( $self, $args) = @_;
104+
90105
my $integration = $self->get_integration;
91106

92107
my $is_free = $integration->IsAddressFree( $args->{attributes}{uprn} );
@@ -133,4 +148,37 @@ sub post_service_request {
133148
}
134149
}
135150

151+
sub _garden_subscription_cancel {
152+
my ( $self, $args ) = @_;
153+
154+
my $integration = $self->get_integration;
155+
156+
my $is_free = $integration->IsAddressFree( $args->{attributes}{uprn} );
157+
158+
if ( $is_free->{IsFree} eq 'False' ) {
159+
my $res = $integration->Cancel( {
160+
CustomerExternalReference => $args->{attributes}{customer_external_ref},
161+
ServiceContractUPRN => $args->{attributes}{uprn},
162+
Reason => $args->{attributes}{reason},
163+
DueDate => $args->{attributes}{due_date},
164+
} );
165+
166+
# Expected response:
167+
# {
168+
# Reference: string,
169+
# Status: string,
170+
# }
171+
my $request = $self->new_request(
172+
service_request_id => $res->{Reference},
173+
);
174+
175+
return $request;
176+
177+
} else {
178+
die 'UPRN '
179+
. $args->{attributes}{uprn}
180+
. ' does not have a subscription to be cancelled, or is invalid';
181+
}
182+
}
183+
136184
1;

perllib/Open311/Endpoint/Service/UKCouncil/Agile.pm

+30
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ sub _build_attributes {
2626
required => 0,
2727
automated => 'hidden_field',
2828
),
29+
Open311::Endpoint::Service::Attribute->new(
30+
code => "property_id",
31+
description => "Property ID",
32+
datatype => "string",
33+
required => 0,
34+
automated => 'hidden_field',
35+
),
2936
Open311::Endpoint::Service::Attribute->new(
3037
code => 'current_containers',
3138
description => 'Number of current containers',
@@ -47,6 +54,29 @@ sub _build_attributes {
4754
required => 0,
4855
automated => 'hidden_field',
4956
),
57+
58+
# For cancellations
59+
Open311::Endpoint::Service::Attribute->new(
60+
code => 'reason',
61+
description => 'Cancellation reason',
62+
datatype => 'string',
63+
required => 0,
64+
automated => 'hidden_field',
65+
),
66+
Open311::Endpoint::Service::Attribute->new(
67+
code => 'due_date',
68+
description => 'Cancellation date',
69+
datatype => 'string',
70+
required => 0,
71+
automated => 'hidden_field',
72+
),
73+
Open311::Endpoint::Service::Attribute->new(
74+
code => 'customer_external_ref',
75+
description => 'Customer external ref',
76+
datatype => 'string',
77+
required => 0,
78+
automated => 'hidden_field',
79+
),
5080
);
5181

5282
return \@attributes;

t/open311/endpoint/agile.t

+87-6
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ $integration->mock( api_call => sub {
5959
ServiceContractReference => 'GW-SERV-001',
6060
};
6161
}
62+
} elsif ( $action eq 'cancel' ) {
63+
return {
64+
Reference => 'GWIT2025-001-001',
65+
Status => 'Hold',
66+
};
6267
}
6368
} );
6469

@@ -69,7 +74,10 @@ subtest 'GET services' => sub {
6974
ok $res->is_success, 'valid request'
7075
or diag $res->content;
7176

72-
is_deeply decode_json($res->content), [
77+
my @got = sort { $a->{service_code} cmp $b->{service_code} }
78+
@{ decode_json( $res->content ) };
79+
80+
is_deeply \@got, [
7381
{
7482
group => "Waste",
7583
service_code => "garden_subscription",
@@ -78,7 +86,16 @@ subtest 'GET services' => sub {
7886
type => "realtime",
7987
service_name => "Garden Subscription",
8088
metadata => "true"
81-
}
89+
},
90+
{
91+
group => "Waste",
92+
service_code => "garden_subscription_cancel",
93+
description => "Cancel Garden Subscription",
94+
keywords => "waste_only",
95+
type => "realtime",
96+
service_name => "Cancel Garden Subscription",
97+
metadata => "true"
98+
},
8299
], 'correct json returned';
83100
};
84101

@@ -113,21 +130,42 @@ subtest 'GET service' => sub {
113130
description => 'UPRN reference',
114131
order => 2,
115132
},
133+
{ %defaults,
134+
code => 'property_id',
135+
description => 'Property ID',
136+
order => 3,
137+
},
116138
{ %defaults,
117139
code => 'current_containers',
118140
description => 'Number of current containers',
119-
order => 3,
141+
order => 4,
120142
},
121143
{ %defaults,
122144
code => 'new_containers',
123145
description => 'Number of new containers',
124-
order => 4,
146+
order => 5,
125147
},
126148
{ %defaults,
127149
code => 'payment_method',
128150
description => 'Payment method: credit card or direct debit',
129-
order => 5,
130-
}
151+
order => 6,
152+
},
153+
{ %defaults,
154+
code => 'reason',
155+
description => 'Cancellation reason',
156+
order => 7,
157+
},
158+
{ %defaults,
159+
code => 'due_date',
160+
description => 'Cancellation date',
161+
order => 8,
162+
},
163+
{ %defaults,
164+
code => 'customer_external_ref',
165+
description => 'Customer external ref',
166+
order => 9,
167+
},
168+
131169
],
132170
}, 'correct json returned';
133171
};
@@ -206,4 +244,47 @@ subtest 'handle unknown error' => sub {
206244
'Dies with error msg';
207245
};
208246

247+
subtest 'successfully cancel a garden subscription' => sub {
248+
my $res = $endpoint->run_test_request(
249+
POST => '/requests.json',
250+
api_key => 'test',
251+
service_code => 'garden_subscription_cancel',
252+
lat => 51,
253+
long => -1,
254+
'attribute[fixmystreet_id]' => 2000002,
255+
'attribute[customer_external_ref]' => 'customer_ABC',
256+
'attribute[uprn]' => '234_has_sub',
257+
'attribute[reason]' => 'I used all my garden waste for a bonfire',
258+
'attribute[due_date]' => '01/01/2025',
259+
);
260+
261+
ok $res->is_success, 'valid request'
262+
or diag $res->content;
263+
264+
is_deeply decode_json($res->content), [ {
265+
service_request_id => 'GWIT2025-001-001',
266+
} ], 'correct json returned';
267+
};
268+
269+
subtest 'try to cancel when no subscription' => sub {
270+
my $res = $endpoint->run_test_request(
271+
POST => '/requests.json',
272+
api_key => 'test',
273+
service_code => 'garden_subscription_cancel',
274+
lat => 51,
275+
long => -1,
276+
'attribute[fixmystreet_id]' => 2000002,
277+
'attribute[customer_external_ref]' => 'customer_ABC',
278+
'attribute[uprn]' => '123_no_sub',
279+
'attribute[reason]' => 'I used all my garden waste for a bonfire',
280+
'attribute[due_date]' => '01/01/2025',
281+
);
282+
283+
my $content = decode_json($res->content);
284+
is $content->[0]{code}, 500;
285+
like $content->[0]{description},
286+
qr/UPRN 123_no_sub does not have a subscription to be cancelled/,
287+
'Dies with error msg';
288+
};
289+
209290
done_testing;

t/open311/endpoint/agile.yml

+3
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@ category_mapping:
44
garden_subscription:
55
name: Garden Subscription
66
group: Waste
7+
garden_subscription_cancel:
8+
name: Cancel Garden Subscription
9+
group: Waste

0 commit comments

Comments
 (0)