From 03abaf706fdbb23a9d22bb04c7ab28d788e8ef90 Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Tue, 15 Aug 2023 21:01:15 +0100 Subject: [PATCH] [Waste] Allow two bulky collection payment bands. --- .../FixMyStreet/App/Controller/Admin/Waste.pm | 8 ++-- .../FixMyStreet/Roles/CobrandBulkyWaste.pm | 28 ++++++++++++ t/app/controller/waste_peterborough.t | 2 + t/app/controller/waste_peterborough_bulky.t | 4 +- templates/web/base/admin/waste/edit.html | 42 ++++++++++++----- templates/web/base/waste/bulky/items.html | 6 +-- web/js/waste.js | 45 ++++++++++++++----- 7 files changed, 102 insertions(+), 33 deletions(-) diff --git a/perllib/FixMyStreet/App/Controller/Admin/Waste.pm b/perllib/FixMyStreet/App/Controller/Admin/Waste.pm index f2a5a28f2bf..f3ef0b37812 100644 --- a/perllib/FixMyStreet/App/Controller/Admin/Waste.pm +++ b/perllib/FixMyStreet/App/Controller/Admin/Waste.pm @@ -85,11 +85,13 @@ sub edit : Chained('body') : PathPart('') : Args(0) { } else { $new_cfg = $c->stash->{body}->get_extra_metadata("wasteworks_config", {}); my %keys = ( - free_mode => 'bool', per_item_costs => 'bool', base_price => 'int', daily_slots => 'int', items_per_collection_max => 'int', + band1_price => 'int', + band1_max => 'int', + free_mode => 'bool', food_bags_disabled => 'bool', show_location_page => 'sel' ); @@ -98,7 +100,7 @@ sub edit : Chained('body') : PathPart('') : Args(0) { if ($keys{$_} eq 'bool') { $new_cfg->{$_} = $val ? 1 : 0; } elsif ($keys{$_} eq 'int') { - if ($val ne $val+0) { + if ($val && $val ne $val+0) { $c->stash->{errors}->{site_wide} = "Not an integer"; } elsif ($_ eq 'items_per_collection_max' && $val > 200) { $c->stash->{errors}->{site_wide} = "Maximum items per collection cannot be more than 200"; @@ -215,7 +217,7 @@ sub stash_body_config_json : Private { } else { $c->stash->{body_config_json} = JSON->new->utf8(1)->pretty->canonical->encode($cfg); } - foreach (qw(free_mode per_item_costs base_price daily_slots items_per_collection_max food_bags_disabled show_location_page)) { + foreach (qw(free_mode per_item_costs base_price daily_slots items_per_collection_max food_bags_disabled show_location_page band1_price band1_max)) { $c->stash->{$_} = $c->get_param($_) || $cfg->{$_}; } } diff --git a/perllib/FixMyStreet/Roles/CobrandBulkyWaste.pm b/perllib/FixMyStreet/Roles/CobrandBulkyWaste.pm index e345dadb582..1ae032048f6 100644 --- a/perllib/FixMyStreet/Roles/CobrandBulkyWaste.pm +++ b/perllib/FixMyStreet/Roles/CobrandBulkyWaste.pm @@ -66,6 +66,20 @@ sub bulky_show_location_page { }; sub bulky_show_location_field_mandatory { 0 } +sub bulky_pricing_strategy { + my $self = shift; + my $base_price = $self->wasteworks_config->{base_price}; + my $band1_max = $self->wasteworks_config->{band1_max}; + my $max = $self->bulky_items_maximum; + if ($self->bulky_per_item_costs) { + return encode_json({ strategy => 'per_item' }); + } elsif (my $band1_price = $self->wasteworks_config->{band1_price}) { + return encode_json({ strategy => 'banded', bands => [ { max => $band1_max, price => $band1_price }, { max => $max, price => $base_price } ] }); + } else { + return encode_json({ strategy => 'single' }); + } +} + =head2 Requirements Users of this role must supply the following: @@ -127,6 +141,8 @@ sub bulky_minimum_cost { map { $_->{price} } @{ $self->bulky_items_master_list }; return $sorted[0] // 0; + } elsif ( $cfg->{band1_price} ) { + return $cfg->{band1_price}; } else { return $cfg->{base_price} // 0; } @@ -152,6 +168,18 @@ sub bulky_total_cost { $total += $prices{$item}; } $c->stash->{payment} = $total; + } elsif ($cfg->{band1_price}) { + my $count = 0; + my $max = $self->bulky_items_maximum; + for (1..$max) { + my $item = $data->{"item_$_"} or next; + $count++; + } + if ($count <= $cfg->{band1_max}) { + $c->stash->{payment} = $cfg->{band1_price}; + } else { + $c->stash->{payment} = $cfg->{base_price}; + } } else { $c->stash->{payment} = $cfg->{base_price}; } diff --git a/t/app/controller/waste_peterborough.t b/t/app/controller/waste_peterborough.t index 1535f96c9fb..cde91057b0d 100644 --- a/t/app/controller/waste_peterborough.t +++ b/t/app/controller/waste_peterborough.t @@ -798,6 +798,8 @@ FixMyStreet::override_config { $body->discard_changes; is_deeply $body->get_extra_metadata('wasteworks_config'), { show_location_page => 'noshow', + band1_max => '', + band1_price => '', daily_slots => 50, free_mode => 0, # not checked food_bags_disabled => 0, # not checked diff --git a/t/app/controller/waste_peterborough_bulky.t b/t/app/controller/waste_peterborough_bulky.t index 7cc4e2f0e65..ed9e73e4872 100644 --- a/t/app/controller/waste_peterborough_bulky.t +++ b/t/app/controller/waste_peterborough_bulky.t @@ -1376,7 +1376,7 @@ FixMyStreet::override_config { $mech->submit_form_ok({ with_fields => { resident => 'Yes' } }); $mech->submit_form_ok({ with_fields => { name => 'Bob Marge', email => $user->email }}); $mech->submit_form_ok({ with_fields => { chosen_date => '2022-08-26T00:00:00' } }); - $mech->content_contains('£0.00'); + $mech->content_like(qr/£<[^>]*>0\.00/); $mech->submit_form_ok({ with_fields => { 'item_1' => 'Amplifiers', 'item_2' => 'High chairs' } }); $mech->submit_form_ok({ with_fields => { tandc => 1 } }); @@ -1438,7 +1438,7 @@ FixMyStreet::override_config { $mech->submit_form_ok({ with_fields => { resident => 'Yes' } }); $mech->submit_form_ok({ with_fields => { name => 'Bob Marge', email => $user->email }}); $mech->submit_form_ok({ with_fields => { chosen_date => '2022-08-26T00:00:00' } }); - $mech->content_contains('£23.50'); + $mech->content_like(qr/£<[^>]*>23\.50/); $mech->submit_form_ok({ with_fields => { 'item_1' => 'Amplifiers', 'item_2' => 'High chairs' } }); $mech->submit_form_ok({ with_fields => { tandc => 1 } }); my ( $token, $report, $report_id ) = get_report_from_redirect( $sent_params->{returnUrl} ); diff --git a/templates/web/base/admin/waste/edit.html b/templates/web/base/admin/waste/edit.html index 7c02169d7b7..b41ecbbf6ff 100644 --- a/templates/web/base/admin/waste/edit.html +++ b/templates/web/base/admin/waste/edit.html @@ -22,26 +22,38 @@

Bulky Collections

[% errors.site_wide %]
[% END %] -

- - - -

+

+
+
+ +
+ + +
+
+ +
+
+ + +
+
+ + +
+

-

- - -

@@ -59,13 +71,19 @@

Bulky Collections

[% 'checked' IF per_item_costs %]> + [% IF c.cobrand.moniker == 'peterborough' %] +

+ + +

General Options

- + [% END %]


diff --git a/templates/web/base/waste/bulky/items.html b/templates/web/base/waste/bulky/items.html index 98d2aada7db..f9aac01bd86 100644 --- a/templates/web/base/waste/bulky/items.html +++ b/templates/web/base/waste/bulky/items.html @@ -85,11 +85,7 @@

- [% IF c.cobrand.bulky_per_item_costs %] - Total cost: £[% pounds(total) %] - [% ELSE %] - Total cost: £[% pounds(total) %] - [% END %] + Total cost: £[% pounds(total) %]

[% PROCESS form override_fields = [ 'continue', 'saved_data', 'token', 'process', 'unique_id' ] %] diff --git a/web/js/waste.js b/web/js/waste.js index a74fe5f07bd..e9a707bb26c 100644 --- a/web/js/waste.js +++ b/web/js/waste.js @@ -77,7 +77,7 @@ $(function() { var firstItem = $('.bulky-item-wrapper').first(); function disableAddItemButton() { - // It will disable button if the first item is empty and the max number of items has been reached. + // It will disable button if the first item is empty or the max number of items has been reached. if (numItemsVisible == maxNumItems || $('.bulky-item-wrapper').first().find('ul.autocomplete__menu').children().length == 0) { $("#add-new-item").prop('disabled', true); } else { @@ -85,6 +85,37 @@ $(function() { } } + function updateTotal() { + var totalId = $('#js-bulky-total'); + var pricing = totalId.data('pricing'); + // Update total + var total = 0; + if (pricing.strategy === 'per_item') { + $('.govuk-select[name^="item_"] option:selected').each(function(i, e) { + var extra = $(this).data('extra'); + var price = extra ? parseFloat(extra.price) : 0; + if (!isNaN(price)) { + total += price; + } + }); + totalId.text((total / 100).toFixed(2)); + } else if (pricing.strategy === 'banded') { + var count = 0; + $('.govuk-select[name^="item_"] option:selected').each(function(i, e) { + if ($(this).val()) { + count++; + } + }); + for (var i=0; i