Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bexley ww ggw misc todos #5381

Draft
wants to merge 20 commits into
base: bexley-ww-ggw-text-fixes
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
5518774
[Bexley][WW] Only require extra text for cancellation when 'Other' se…
nephila-nacrea Feb 24, 2025
7e097af
[Bexley] WIP show existing GGW subscription
davea Jan 28, 2025
b4cf103
[Bexley] Show GGW cancel link to all
davea Feb 9, 2025
8b075f9
[Bexley] Show current payment on GGW subscription
davea Feb 9, 2025
f7dd75c
[Bexley] Add lookup for subscription from database
davea Feb 11, 2025
bdbcba7
[Bexley] Show existing GGW sub from Agile if it’s not in Whitespace
davea Feb 12, 2025
f5328e6
[Bexley] Exclude Agile reports from Symology email behaviour
davea Feb 18, 2025
c05365e
[Bexley] Only show active GGW subs from Agile
davea Feb 18, 2025
9013a64
[Bexley][WW] Pass 'total_containers' (=bins_wanted) to O311 for GGW subs
nephila-nacrea Feb 17, 2025
a56106c
[Bexley][WW] GGW renewals
nephila-nacrea Feb 11, 2025
1ac402d
fixup! [Bexley][WW] GGW renewals
nephila-nacrea Feb 20, 2025
c11dd73
fixup! fixup! [Bexley][WW] GGW renewals
nephila-nacrea Feb 26, 2025
c3dce5f
fixup! fixup! fixup! [Bexley][WW] GGW renewals
nephila-nacrea Feb 26, 2025
fedad29
[Bexley][WW] Update GGW intro page text
davea Feb 21, 2025
c56e898
[Bexley][WW] Update GGW bin description text
davea Feb 21, 2025
cbd8e15
[Bexley][WW] Update GGW T&Cs link
davea Feb 21, 2025
78ecf75
[Bexley][WW] Correct bin delivery timeframe
davea Feb 21, 2025
31afc5d
[Bexley][WW] Capitalisation of cancel options
davea Feb 21, 2025
e598c3e
[Bexley][WW] Update GGW cancellation wording
davea Feb 21, 2025
eb40957
[Bexley][WW] Pass total container quantity to garden email templates
nephila-nacrea Feb 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions perllib/FixMyStreet/App/Form/Waste/Garden/Cancel/Bexley.pm
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,14 @@ sub options_reason {

my @options = (
'Price',
'Service Issues',
'Moving Out of Borough',
'Service issues',
'Moving out of borough',
'Other',
);
return map { { label => $_, value => $_ } } @options;
}

has_field reason_further_details => (
required => 1,
type => 'Text',
widget => 'Textarea',
label =>
Expand Down
2 changes: 2 additions & 0 deletions perllib/FixMyStreet/App/Form/Waste/GardenTandC.pm
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ has_field tandc => (
my $text;
if ($cobrand->moniker eq 'brent') {
$text = 'I agree to the <a href="/about/garden_terms" target="_blank">terms and conditions</a> and accept that if my bin does not display a valid bin sticker, it will not be collected';
} elsif ($cobrand->moniker eq 'bexley') {
$text = 'I agree to the <a href="https://www.bexley.gov.uk/services/rubbish-and-recycling/garden-waste-collection-service/sign-garden-waste-collection" target="_blank">terms and conditions</a>';
} else {
$text = 'I agree to the <a href="/about/garden_terms" target="_blank">terms and conditions</a>';
}
Expand Down
2 changes: 1 addition & 1 deletion perllib/FixMyStreet/Cobrand/Bexley.pm
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ sub open311_post_send {
my ($self, $row, $h, $sender) = @_;

# Check Open311 was successful, or if this was the first time a Symology report failed
if ($sender->contact->email !~ /^(Confirm|Uniform)/) { # it's a Symology report
if ($sender->contact->email !~ /^(Confirm|Uniform|Agile)/) { # it's a Symology report
# failed at least once, assume email was sent on first failure
return if $row->send_fail_count;
} else {
Expand Down
175 changes: 148 additions & 27 deletions perllib/FixMyStreet/Cobrand/Bexley/Garden.pm
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
use DateTime::Format::Strptime;
use Integrations::Agile;
use FixMyStreet::App::Form::Waste::Garden::Cancel::Bexley;
use Try::Tiny;
use JSON::MaybeXS;

use Moo::Role;
with 'FixMyStreet::Roles::Cobrand::SCP',
Expand All @@ -32,55 +34,131 @@
return [ 'GA-140', 'GA-240' ];
}

sub lookup_subscription_for_uprn {
my ($self, $uprn) = @_;

Check warning on line 38 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L38

Added line #L38 was not covered by tests

my $sub = {

Check warning on line 40 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L40

Added line #L40 was not covered by tests
row => undef,

email => undef,
cost => undef,
end_date => undef,
customer_external_ref => undef,
bins_count => undef,
};


my ( $customer, $contract );

Check warning on line 51 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L51

Added line #L51 was not covered by tests

my $results = $self->agile->CustomerSearch($uprn);

Check warning on line 53 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L53

Added line #L53 was not covered by tests

# find the first 'ACTIVATED' Customer with an 'ACTIVE'/'PRECONTRACT' contract
my $customers = $results->{Customers} || [];
OUTER: for ( @$customers ) {

Check warning on line 57 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L56-L57

Added lines #L56 - L57 were not covered by tests
next unless ( $_->{CustomertStatus} // '' ) eq 'ACTIVATED'; # CustomertStatus (sic) options seem to be ACTIVATED/INACTIVE
my $contracts = $_->{ServiceContracts} || [];

Check warning on line 59 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L59

Added line #L59 was not covered by tests
next unless $contracts;
$customer = $_;
for ( @$contracts ) {

Check warning on line 62 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L61-L62

Added lines #L61 - L62 were not covered by tests
next unless $_->{ServiceContractStatus} =~ /(ACTIVE|PRECONTRACT|RENEWALDUE)/; # Options seem to be ACTIVE/NOACTIVE/PRECONTRACT/RENEWALDUE
$contract = $_;

Check warning on line 64 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L64

Added line #L64 was not covered by tests
# use the first matching customer/contract
last OUTER if $customer && $contract;
}
}

return unless $customer && $contract;

# XXX should maybe sort by CreatedDate rather than assuming first is OK
$sub->{cost} = try {
my ($payment) = grep { $_->{PaymentStatus} eq 'Paid' } @{ $contract->{Payments} };
return $payment->{Amount};
};

Check warning on line 76 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L74-L76

Added lines #L74 - L76 were not covered by tests

my $parser = DateTime::Format::Strptime->new( pattern => '%d/%m/%Y %H:%M' );
$sub->{end_date} = $parser->parse_datetime( $contract->{EndDate} );

Check warning on line 79 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L78-L79

Added lines #L78 - L79 were not covered by tests

$sub->{customer_external_ref} = $customer->{CustomerExternalReference};

Check warning on line 81 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L81

Added line #L81 was not covered by tests

$sub->{bins_count} = $contract->{WasteContainerQuantity};

Check warning on line 83 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L83

Added line #L83 was not covered by tests

my $c = $self->{c};

Check warning on line 85 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L85

Added line #L85 was not covered by tests
my $p = $c->model('DB::Problem')->search({
category => 'Garden Subscription',
extra => { '@>' => encode_json({ "_fields" => [ { name => "uprn", value => $uprn } ] }) },
state => { '!=' => 'hidden' },
external_id => "Agile-" . ( $contract->{Reference} // '' ),

Check warning on line 90 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L90

Added line #L90 was not covered by tests
})->order_by('-id')->to_body($c->cobrand->body)->first;

if ($p) {
$self->{c}->stash->{orig_sub} = $sub->{row} = $p;

Check warning on line 94 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L94

Added line #L94 was not covered by tests
}

return $sub;

Check warning on line 97 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L97

Added line #L97 was not covered by tests
}

sub garden_current_subscription {
my $self = shift;
my ($self, $services) = @_;

Check warning on line 101 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L101

Added line #L101 was not covered by tests

my $current = $self->{c}->stash->{property}{garden_current_subscription};
return $current if $current;

my $uprn = $self->{c}->stash->{property}{uprn};
return undef unless $uprn;

# TODO Fetch active subscription from DB for UPRN
# (get_original_sub() in Controller/Waste.pm needs to handle Bexley UPRN).
# Could be more than one customer, so match against email.
# Could be more than one contract, so match against reference.

my $results = $self->agile->CustomerSearch($uprn);
return undef unless $results && $results->{Customers};
my $customer = $results->{Customers}[0];
return undef unless $customer && $customer->{ServiceContracts};
my $contract = $customer->{ServiceContracts}[0];
return unless $contract;
my $sub = $self->lookup_subscription_for_uprn($uprn);

Check warning on line 109 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L109

Added line #L109 was not covered by tests
return undef unless $sub;

my $parser
= DateTime::Format::Strptime->new( pattern => '%d/%m/%Y %H:%M' );
my $end_date = $parser->parse_datetime( $contract->{EndDate} );
my $garden_due = $self->waste_sub_due( $sub->{end_date} );

Check warning on line 112 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L112

Added line #L112 was not covered by tests

# Agile says there is a subscription; now get service data from
# Whitespace
my $services = $self->{c}->stash->{services};
my $service_ids = { map { $_->{service_id} => $_ } @$services };

Check warning on line 116 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L116

Added line #L116 was not covered by tests
for ( @{ $self->garden_service_ids } ) {
if ( my $srv = $services->{$_} ) {
$srv->{customer_external_ref}
= $customer->{CustomerExternalReference};
$srv->{end_date} = $end_date;
if ( my $srv = $service_ids->{$_} ) {
$srv->{customer_external_ref} = $sub->{customer_external_ref};
$srv->{end_date} = $sub->{end_date};
$srv->{garden_bins} = $sub->{bins_count};
$srv->{garden_cost} = $sub->{cost};
$srv->{garden_due} = $garden_due;

Check warning on line 123 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L119-L123

Added lines #L119 - L123 were not covered by tests

return $srv;
}
}

return {
# If we reach here then Whitespace doesn't think there's a garden service for this
# property. If Agile does have a subscription then we need to add a service
# to the list for this property so the frontend displays it.
my $service = {
agile_only => 1,
customer_external_ref => $customer->{CustomerExternalReference},
end_date => $end_date,
customer_external_ref => $sub->{customer_external_ref},
end_date => $sub->{end_date},
garden_bins => $sub->{bins_count},
garden_cost => $sub->{cost},
garden_due => $garden_due,

Check warning on line 138 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L138

Added line #L138 was not covered by tests

uprn => $uprn,
garden_waste => 1,
service_description => "Garden waste",
service_name => "Brown wheelie bin",
service_id => "GA-240",
schedule => "Pending",
round_schedule => '',
next => { pending => 1 },
};
push @$services, $service;
$self->{c}->stash->{property}{garden_current_subscription} = $service;
$self->{c}->stash->{property}{has_garden_subscription} = 1;
return $service;

Check warning on line 152 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L149-L152

Added lines #L149 - L152 were not covered by tests
}

# TODO This is a placeholder
sub get_current_garden_bins { 1 }
sub get_current_garden_bins { shift->garden_current_subscription->{garden_bins} }

Check warning on line 155 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L155

Added line #L155 was not covered by tests

sub waste_cancel_asks_staff_for_user_details { 1 }

# TODO Needs to check 14-day window after subscription started
sub waste_garden_allow_cancellation { 'all' }

Check warning on line 160 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L160

Added line #L160 was not covered by tests

sub waste_cancel_form_class {
'FixMyStreet::App::Form::Waste::Garden::Cancel::Bexley';
}
Expand All @@ -89,10 +167,9 @@
my ( $self, $data, $type ) = @_;

my $c = $self->{c};
my $srv = $self->garden_current_subscription;

Check warning on line 170 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L170

Added line #L170 was not covered by tests

if ( $data->{category} eq 'Cancel Garden Subscription' ) {
my $srv = $self->garden_current_subscription;

my $parser = DateTime::Format::Strptime->new( pattern => '%d/%m/%Y' );
my $due_date_str = $parser->format_datetime( DateTime->now->add(days => 1) );

Expand All @@ -103,9 +180,53 @@
$c->set_param( 'customer_external_ref', $srv->{customer_external_ref} );
$c->set_param( 'due_date', $due_date_str );
$c->set_param( 'reason', $reason );

} elsif ( $data->{title} =~ /Renew/ ) {
$c->set_param( 'type', 'renew' );
$c->set_param( 'customer_external_ref', $srv->{customer_external_ref} );
$c->set_param( 'total_containers', $data->{bins_wanted} );

Check warning on line 187 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L185-L187

Added lines #L185 - L187 were not covered by tests

} elsif ( $data->{category} eq 'Garden Subscription' ) {
$c->set_param( 'total_containers', $data->{bins_wanted} );

Check warning on line 190 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L190

Added line #L190 was not covered by tests

}
}

sub garden_due_days { 42 }

Check warning on line 195 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L195

Added line #L195 was not covered by tests

=head2 waste_sub_due

Returns true/false if now is less than garden_due_days before DATE.

=cut

sub waste_sub_due {
my ( $self, $date ) = @_;

Check warning on line 204 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L204

Added line #L204 was not covered by tests

my $now = DateTime->now->set_time_zone( FixMyStreet->local_time_zone );
my $sub_end = DateTime::Format::W3CDTF->parse_datetime($date);

Check warning on line 207 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L206-L207

Added lines #L206 - L207 were not covered by tests

my $diff = $now->delta_days($sub_end)->in_units('days');
return $diff <= $self->garden_due_days;

Check warning on line 210 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L209-L210

Added lines #L209 - L210 were not covered by tests
}

=head2 waste_sub_overdue

Returns true/false if now is past DATE.

=cut

sub waste_sub_overdue {
my ( $self, $date ) = @_;

Check warning on line 220 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L220

Added line #L220 was not covered by tests

my $now = DateTime->now->set_time_zone( FixMyStreet->local_time_zone )

Check warning on line 222 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L222

Added line #L222 was not covered by tests
->truncate( to => 'day' );
my $sub_end = DateTime::Format::W3CDTF->parse_datetime($date)

Check warning on line 224 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L224

Added line #L224 was not covered by tests
->truncate( to => 'day' );

return $now > $sub_end;

Check warning on line 227 in perllib/FixMyStreet/Cobrand/Bexley/Garden.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Garden.pm#L227

Added line #L227 was not covered by tests
}

=item * You can order a maximum of five bins

=cut
Expand Down
9 changes: 5 additions & 4 deletions perllib/FixMyStreet/Cobrand/Bexley/Waste.pm
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@
},
assisted_collection => $assisted_collection,
uprn => $uprn,
garden_waste => $container->{description} eq 'Garden waste' ? 1 : 0,
};

if ($last_dt) {
Expand All @@ -398,7 +399,7 @@
$property->{above_shop} = 1
if $filtered_service->{service_id} eq 'MDR-SACK';
$property->{has_garden_subscription} = 1
if $filtered_service->{service_description} eq 'Garden waste';
if $filtered_service->{garden_waste};

# Frequency of collection
if ( @round_schedules > 1 ) {
Expand Down Expand Up @@ -459,13 +460,13 @@
];
}

$property->{garden_current_subscription}
= $self->garden_current_subscription;

@site_services_filtered = $self->_remove_service_if_assisted_exists(@site_services_filtered);

@site_services_filtered = $self->service_sort(@site_services_filtered);

$property->{garden_current_subscription}
= $self->garden_current_subscription(\@site_services_filtered);

Check warning on line 468 in perllib/FixMyStreet/Cobrand/Bexley/Waste.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/Cobrand/Bexley/Waste.pm#L468

Added line #L468 was not covered by tests

$self->_set_request_containers( $property, @site_services_filtered );

return \@site_services_filtered;
Expand Down
1 change: 1 addition & 0 deletions t/app/controller/waste_bexley.t
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ FixMyStreet::override_config {
date => ignore(),
},
uprn => ignore(),
garden_waste => 0,
);
cmp_deeply \@sorted, [
{ id => 8,
Expand Down
Loading