aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet/App
diff options
context:
space:
mode:
Diffstat (limited to 'perllib/FixMyStreet/App')
-rw-r--r--perllib/FixMyStreet/App/Controller/Report/New.pm2
-rw-r--r--perllib/FixMyStreet/App/Controller/Waste.pm263
-rw-r--r--perllib/FixMyStreet/App/Form/Page/Waste.pm11
-rw-r--r--perllib/FixMyStreet/App/Form/Waste.pm52
-rw-r--r--perllib/FixMyStreet/App/Form/Waste/AboutYou.pm38
-rw-r--r--perllib/FixMyStreet/App/Form/Waste/Report.pm65
-rw-r--r--perllib/FixMyStreet/App/Form/Waste/Request.pm64
7 files changed, 494 insertions, 1 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Report/New.pm b/perllib/FixMyStreet/App/Controller/Report/New.pm
index 3b42085ff..98ebd4972 100644
--- a/perllib/FixMyStreet/App/Controller/Report/New.pm
+++ b/perllib/FixMyStreet/App/Controller/Report/New.pm
@@ -1140,7 +1140,7 @@ sub process_report : Private {
# save the cobrand and language related information
$report->cobrand( $c->cobrand->moniker );
- $report->cobrand_data( '' );
+ $report->cobrand_data( $c->stash->{cobrand_data} || '' );
$report->lang( $c->stash->{lang_code} );
return 1;
diff --git a/perllib/FixMyStreet/App/Controller/Waste.pm b/perllib/FixMyStreet/App/Controller/Waste.pm
index 6319b5f22..667edad10 100644
--- a/perllib/FixMyStreet/App/Controller/Waste.pm
+++ b/perllib/FixMyStreet/App/Controller/Waste.pm
@@ -5,7 +5,11 @@ use namespace::autoclean;
BEGIN { extends 'Catalyst::Controller' }
use utf8;
+use Lingua::EN::Inflect qw( NUMWORDS );
use FixMyStreet::App::Form::Waste::UPRN;
+use FixMyStreet::App::Form::Waste::AboutYou;
+use FixMyStreet::App::Form::Waste::Request;
+use FixMyStreet::App::Form::Waste::Report;
sub auto : Private {
my ( $self, $c ) = @_;
@@ -55,6 +59,9 @@ sub address_list_form {
sub redirect_to_uprn : Private {
my ($self, $c, $uprn) = @_;
my $uri = '/waste/uprn/' . $uprn;
+ my $type = $c->get_param('type') || '';
+ $uri .= '/request' if $type eq 'request';
+ $uri .= '/report' if $type eq 'report';
$c->res->redirect($uri);
$c->detach;
}
@@ -84,6 +91,262 @@ sub bin_days : Chained('uprn') : PathPart('') : Args(0) {
my ($self, $c) = @_;
}
+sub construct_bin_request_form {
+ my $c = shift;
+
+ my $field_list = [];
+
+ foreach (@{$c->stash->{service_data}}) {
+ next unless $_->{next};
+ my $name = $_->{service_name};
+ my $containers = $_->{request_containers};
+ my $max = $_->{request_max};
+ foreach my $id (@$containers) {
+ push @$field_list, "container-$id" => {
+ type => 'Checkbox',
+ apply => [
+ {
+ when => { "quantity-$id" => sub { $_[0] > 0 } },
+ check => qr/^1$/,
+ message => 'Please tick the box',
+ },
+ ],
+ label => $name,
+ option_label => $c->stash->{containers}->{$id},
+ tags => { toggle => "form-quantity-$id-row" },
+ };
+ $name = ''; # Only on first container
+ push @$field_list, "quantity-$id" => {
+ type => 'Select',
+ label => 'Quantity',
+ tags => {
+ hint => "You can request a maximum of " . NUMWORDS($max) . " containers",
+ initial_hidden => 1,
+ },
+ options => [
+ { value => "", label => '-' },
+ map { { value => $_, label => $_ } } (1..$max),
+ ],
+ required_when => { "container-$id" => 1 },
+ };
+ }
+ }
+
+ return $field_list;
+}
+
+sub request : Chained('uprn') : Args(0) {
+ my ($self, $c) = @_;
+
+ my $field_list = construct_bin_request_form($c);
+
+ $c->stash->{first_page} = 'request';
+ $c->stash->{form_class} = 'FixMyStreet::App::Form::Waste::Request';
+ $c->stash->{page_list} = [
+ request => {
+ fields => [ grep { ! ref $_ } @$field_list, 'submit' ],
+ title => 'Which containers do you need?',
+ next => 'about_you',
+ },
+ ];
+ $c->stash->{field_list} = $field_list;
+ $c->forward('form');
+}
+
+sub process_request_data : Private {
+ my ($self, $c, $form) = @_;
+ my $data = $form->saved_data;
+ my $address = $c->stash->{property}->{address};
+ my @services = grep { /^container-/ && $data->{$_} } keys %$data;
+ foreach (@services) {
+ my ($id) = /container-(.*)/;
+ my $container = $c->stash->{containers}{$id};
+ my $quantity = $data->{"quantity-$id"};
+ $data->{title} = "Request new $container";
+ $data->{detail} = "Quantity: $quantity\n\n$address";
+ $c->set_param('Container_Type', $id);
+ $c->set_param('Quantity', $quantity);
+ $c->forward('add_report', [ $data ]) or return;
+ push @{$c->stash->{report_ids}}, $c->stash->{report}->id;
+ }
+ return 1;
+}
+
+sub construct_bin_report_form {
+ my $c = shift;
+
+ my $field_list = [];
+
+ foreach (@{$c->stash->{service_data}}) {
+ next unless $_->{last};
+ my $id = $_->{service_id};
+ my $name = $_->{service_name};
+ push @$field_list, "service-$id" => {
+ type => 'Checkbox',
+ label => $name,
+ option_label => $name,
+ };
+ }
+
+ return $field_list;
+}
+
+sub report : Chained('uprn') : Args(0) {
+ my ($self, $c) = @_;
+
+ my $field_list = construct_bin_report_form($c);
+
+ $c->stash->{first_page} = 'report';
+ $c->stash->{form_class} = 'FixMyStreet::App::Form::Waste::Report';
+ $c->stash->{page_list} = [
+ report => {
+ fields => [ grep { ! ref $_ } @$field_list, 'submit' ],
+ title => 'Select your missed collection',
+ next => 'about_you',
+ },
+ ];
+ $c->stash->{field_list} = $field_list;
+ $c->forward('form');
+}
+
+sub process_report_data : Private {
+ my ($self, $c, $form) = @_;
+ my $data = $form->saved_data;
+ my $address = $c->stash->{property}->{address};
+ my @services = grep { /^service-/ && $data->{$_} } keys %$data;
+ foreach (@services) {
+ my ($id) = /service-(.*)/;
+ my $service = $c->stash->{services}{$id}{service_name};
+ $data->{title} = "Report missed $service";
+ $data->{detail} = "$data->{title}\n\n$address";
+ $c->set_param('service_id', $id);
+ $c->forward('add_report', [ $data ]) or return;
+ push @{$c->stash->{report_ids}}, $c->stash->{report}->id;
+ }
+ return 1;
+}
+
+sub load_form {
+ my ($c, $previous_form) = @_;
+
+ my $page;
+ if ($previous_form) {
+ $page = $previous_form->next;
+ } else {
+ $page = $c->forward('get_page');
+ }
+
+ my $form = $c->stash->{form_class}->new(
+ page_list => $c->stash->{page_list},
+ $c->stash->{field_list} ? (field_list => $c->stash->{field_list}) : (),
+ page_name => $page,
+ csrf_token => $c->stash->{csrf_token},
+ c => $c,
+ previous_form => $previous_form,
+ saved_data_encoded => $c->get_param('saved_data'),
+ no_preload => 1,
+ );
+
+ if (!$form->has_current_page) {
+ $c->detach('/page_error_400_bad_request', [ 'Bad request' ]);
+ }
+
+ return $form;
+}
+
+sub form : Private {
+ my ($self, $c) = @_;
+
+ my $form = load_form($c);
+ if ($c->get_param('process')) {
+ $c->forward('/auth/check_csrf_token');
+ $form->process(params => $c->req->body_params);
+ if ($form->validated) {
+ $form = load_form($c, $form);
+ }
+ }
+
+ $form->process unless $form->processed;
+
+ $c->stash->{template} = $form->template || 'waste/index.html';
+ $c->stash->{form} = $form;
+}
+
+sub get_page : Private {
+ my ($self, $c) = @_;
+
+ my $goto = $c->get_param('goto') || '';
+ my $process = $c->get_param('process') || '';
+ $goto = $c->stash->{first_page} unless $goto || $process;
+ if ($goto && $process) {
+ $c->detach('/page_error_400_bad_request', [ 'Bad request' ]);
+ }
+
+ return $goto || $process;
+}
+
+sub add_report : Private {
+ my ( $self, $c, $data ) = @_;
+
+ $c->stash->{cobrand_data} = 'waste';
+
+ # XXX Is this best way to do this?
+ if ($c->user_exists && $c->user->from_body && $c->user->email ne $data->{email}) {
+ $c->set_param('form_as', 'another_user');
+ $c->set_param('username', $data->{email} || $data->{phone});
+ } else {
+ $c->set_param('username_register', $data->{email} || $data->{phone});
+ }
+
+ # Set the data as if a new report form has been submitted
+
+ $c->set_param('submit_problem', 1);
+ $c->set_param('pc', '');
+ $c->set_param('non_public', 1);
+
+ $c->set_param('name', $data->{name});
+ $c->set_param('phone', $data->{phone});
+
+ $c->set_param('category', $data->{category});
+ $c->set_param('title', $data->{title});
+ $c->set_param('detail', $data->{detail});
+ $c->set_param('uprn', $c->stash->{uprn});
+
+ $c->forward('setup_categories_and_bodies') unless $c->stash->{contacts};
+ $c->forward('/report/new/non_map_creation', [['/waste/remove_name_errors']]) or return;
+ my $report = $c->stash->{report};
+ $report->confirm;
+ $report->update;
+
+ $c->model('DB::Alert')->find_or_create({
+ user => $report->user,
+ alert_type => 'new_updates',
+ parameter => $report->id,
+ cobrand => $report->cobrand,
+ lang => $report->lang,
+ })->confirm;
+
+ return 1;
+}
+
+sub remove_name_errors : Private {
+ my ($self, $c) = @_;
+ # We do not mind about missing title/split name here
+ my $field_errors = $c->stash->{field_errors};
+ delete $field_errors->{fms_extra_title};
+ delete $field_errors->{first_name};
+ delete $field_errors->{last_name};
+}
+
+sub setup_categories_and_bodies : Private {
+ my ($self, $c) = @_;
+
+ $c->stash->{all_areas} = $c->stash->{all_areas_mapit} = { $c->cobrand->council_area_id => { id => $c->cobrand->council_area_id } };
+ $c->forward('/report/new/setup_categories_and_bodies');
+ my $contacts = $c->stash->{contacts};
+ @$contacts = grep { grep { $_ eq 'Waste' } @{$_->groups} } @$contacts;
+}
+
__PACKAGE__->meta->make_immutable;
1;
diff --git a/perllib/FixMyStreet/App/Form/Page/Waste.pm b/perllib/FixMyStreet/App/Form/Page/Waste.pm
new file mode 100644
index 000000000..5275cae7f
--- /dev/null
+++ b/perllib/FixMyStreet/App/Form/Page/Waste.pm
@@ -0,0 +1,11 @@
+package FixMyStreet::App::Form::Page::Waste;
+use Moose;
+extends 'FixMyStreet::App::Form::Page::Simple';
+
+# Title to use for this page
+has title => ( is => 'ro', isa => 'Str' );
+
+# Special template to use in preference to the default
+has template => ( is => 'ro', isa => 'Str' );
+
+1;
diff --git a/perllib/FixMyStreet/App/Form/Waste.pm b/perllib/FixMyStreet/App/Form/Waste.pm
new file mode 100644
index 000000000..c430506c7
--- /dev/null
+++ b/perllib/FixMyStreet/App/Form/Waste.pm
@@ -0,0 +1,52 @@
+package FixMyStreet::App::Form::Waste;
+
+use HTML::FormHandler::Moose;
+extends 'FixMyStreet::App::Form::Wizard';
+
+has c => ( is => 'ro' );
+
+has default_page_type => ( is => 'ro', isa => 'Str', default => 'Waste' );
+
+has finished_action => ( is => 'ro' );
+
+before _process_page_array => sub {
+ my ($self, $pages) = @_;
+ foreach my $page (@$pages) {
+ $page->{type} = $self->default_page_type
+ unless $page->{type};
+ }
+};
+
+# Add some functions to the form to pass through to the current page
+has '+current_page' => (
+ handles => {
+ title => 'title',
+ template => 'template',
+ }
+);
+
+sub wizard_finished {
+ my ($form, $action) = @_;
+ my $c = $form->c;
+ my $success = $c->forward($action, [ $form ]);
+ if (!$success) {
+ $form->add_form_error('Something went wrong, please try again');
+ foreach (keys %{$c->stash->{field_errors}}) {
+ $form->add_form_error("$_: " . $c->stash->{field_errors}{$_});
+ }
+ }
+ return $success;
+}
+
+# Make sure we can have pre-ticked things on the first page
+before after_build => sub {
+ my $self = shift;
+
+ my $saved_data = $self->previous_form ? $self->previous_form->saved_data : $self->saved_data;
+
+ my $c = $self->c;
+
+ map { $saved_data->{$_} = 1 } grep { /^(service|container)-/ && $c->req->params->{$_} } keys %{$c->req->params};
+};
+
+1;
diff --git a/perllib/FixMyStreet/App/Form/Waste/AboutYou.pm b/perllib/FixMyStreet/App/Form/Waste/AboutYou.pm
new file mode 100644
index 000000000..d5bb3df2b
--- /dev/null
+++ b/perllib/FixMyStreet/App/Form/Waste/AboutYou.pm
@@ -0,0 +1,38 @@
+package FixMyStreet::App::Form::Waste::AboutYou;
+
+use utf8;
+use HTML::FormHandler::Moose::Role;
+use FixMyStreet::SMS;
+
+has_field name => (
+ type => 'Text',
+ label => 'Your name',
+ required => 1,
+ validate_method => sub {
+ my $self = shift;
+ $self->add_error('Please enter your full name.')
+ if length($self->value) < 5
+ || $self->value !~ m/\s/
+ || $self->value =~ m/\ba\s*n+on+((y|o)mo?u?s)?(ly)?\b/i;
+ },
+);
+
+has_field phone => (
+ type => 'Text',
+ label => 'Telephone number',
+ validate_method => sub {
+ my $self = shift;
+ my $parsed = FixMyStreet::SMS->parse_username($self->value);
+ $self->add_error('Please provide a valid phone number')
+ unless $parsed->{phone};
+ }
+);
+
+has_field email => (
+ type => 'Email',
+ tags => {
+ hint => 'If you provide an email address, we can send you order status updates'
+ },
+);
+
+1;
diff --git a/perllib/FixMyStreet/App/Form/Waste/Report.pm b/perllib/FixMyStreet/App/Form/Waste/Report.pm
new file mode 100644
index 000000000..589e75d48
--- /dev/null
+++ b/perllib/FixMyStreet/App/Form/Waste/Report.pm
@@ -0,0 +1,65 @@
+package FixMyStreet::App::Form::Waste::Report;
+
+use utf8;
+use HTML::FormHandler::Moose;
+extends 'FixMyStreet::App::Form::Waste';
+
+# First page has dynamic fields, so is set in code
+
+has_page about_you => (
+ fields => ['name', 'email', 'phone', 'continue'],
+ title => 'About you',
+ next => 'summary',
+);
+
+with 'FixMyStreet::App::Form::Waste::AboutYou';
+
+has_page summary => (
+ fields => ['submit'],
+ title => 'Submit missed collection',
+ template => 'waste/summary_report.html',
+ finished => sub {
+ return $_[0]->wizard_finished('process_report_data');
+ },
+ next => 'done',
+);
+
+has_page done => (
+ title => 'Missed collection sent',
+ template => 'waste/confirmation.html',
+);
+
+has_field category => (
+ type => 'Hidden',
+ default => 'Report missed collection'
+);
+
+has_field continue => (
+ type => 'Submit',
+ value => 'Continue',
+ element_attr => { class => 'govuk-button' },
+);
+
+has_field submit => (
+ type => 'Submit',
+ value => 'Report collection as missed',
+ element_attr => { class => 'govuk-button' },
+ order => 999,
+);
+
+sub validate {
+ my $self = shift;
+ my $any = 0;
+
+ foreach ($self->all_fields) {
+ $any = 1 if $_->name =~ /^service-/ && ($_->value || $self->saved_data->{$_->name});
+ }
+ $self->add_form_error('Please specify what was missed')
+ unless $any;
+
+ $self->add_form_error('Please specify at least one of phone or email')
+ unless $self->field('phone')->is_inactive || $self->field('phone')->value || $self->field('email')->value;
+}
+
+1;
+
diff --git a/perllib/FixMyStreet/App/Form/Waste/Request.pm b/perllib/FixMyStreet/App/Form/Waste/Request.pm
new file mode 100644
index 000000000..e7caaa206
--- /dev/null
+++ b/perllib/FixMyStreet/App/Form/Waste/Request.pm
@@ -0,0 +1,64 @@
+package FixMyStreet::App::Form::Waste::Request;
+
+use utf8;
+use HTML::FormHandler::Moose;
+extends 'FixMyStreet::App::Form::Waste';
+
+# First page has dynamic fields, so is set in code
+
+has_page about_you => (
+ fields => ['name', 'email', 'phone', 'continue'],
+ title => 'About you',
+ next => 'summary',
+);
+
+with 'FixMyStreet::App::Form::Waste::AboutYou';
+
+has_page summary => (
+ fields => ['submit'],
+ title => 'Submit container request',
+ template => 'waste/summary_request.html',
+ finished => sub {
+ return $_[0]->wizard_finished('process_request_data');
+ },
+ next => 'done',
+);
+
+has_page done => (
+ title => 'Container request sent',
+ template => 'waste/confirmation.html',
+);
+
+has_field category => (
+ type => 'Hidden',
+ default => 'Request new container',
+);
+
+has_field continue => (
+ type => 'Submit',
+ value => 'Continue',
+ element_attr => { class => 'govuk-button' },
+);
+
+has_field submit => (
+ type => 'Submit',
+ value => 'Request new containers',
+ element_attr => { class => 'govuk-button' },
+ order => 999,
+);
+
+sub validate {
+ my $self = shift;
+ my $any = 0;
+
+ foreach ($self->all_fields) {
+ $any = 1 if $_->name =~ /^container-/ && ($_->value || $self->saved_data->{$_->name});
+ }
+ $self->add_form_error('Please specify what you need')
+ unless $any;
+
+ $self->add_form_error('Please specify at least one of phone or email')
+ unless $self->field('phone')->is_inactive || $self->field('phone')->value || $self->field('email')->value;
+}
+
+1;