Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
chrismytton committed Feb 13, 2025
1 parent b2518f4 commit 9dd1054
Show file tree
Hide file tree
Showing 10 changed files with 695 additions and 5 deletions.
55 changes: 55 additions & 0 deletions bin/create-access-paysuite-dd
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env perl

use strict;
use warnings;

BEGIN { # set all the paths to the perl code
use File::Basename qw(dirname);
use File::Spec;
my $d = dirname(File::Spec->rel2abs($0));
require "$d/../setenv.pl";
}

use Integrations::AccessPaySuite;

my $client = Integrations::AccessPaySuite->new(
config => {
endpoint => 'https://playpen.accesspaysuite.com',
client_code => 'APIRTM',
api_key => $ENV{ACCESS_PAYSUITE_API_KEY}
}
);

# Create a customer
my $customer = $client->create_customer({
customerRef => '[email protected]',
email => '[email protected]',
title => 'Mr',
firstName => 'John',
surname => 'Doe',
postCode => 'SE1 1AA',
accountNumber => '12345678',
bankSortCode => '123456',
accountHolderName => 'John Doe',
line1 => '123 Main St',
line2 => 'Apt 1',
});
use Devel::Dwarn;
::Dwarn($customer);

# Set up a direct debit
my $contract = $client->create_contract($customer->{Id}, {
scheduleId => '38491b98-e3dd-45c1-80e7-e44941e481c6',
start => '2025-03-01T00:00:00.000',
isGiftAid => 0,
terminationType => "Until further notice",
atTheEnd => "Switch to further notice",
paymentMonthInYear => 3,
additionalReference => 'BEXLEY GGW',
paymentDayInMonth => 28,
amount => 50.00,
});
::Dwarn($contract);

print "Customer ID: $customer->{Id}\n";
print "Contract ID: $contract->{Id}\n";
74 changes: 73 additions & 1 deletion perllib/FixMyStreet/App/Controller/Waste.pm
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use FixMyStreet::App::Form::Waste::Garden::Cancel;
use FixMyStreet::App::Form::Waste::Garden::Renew;
use FixMyStreet::App::Form::Waste::Garden::Sacks::Purchase;
use FixMyStreet::App::Form::Waste::Garden::Transfer;
use FixMyStreet::App::Form::Waste::BankDetails;
use WasteWorks::Costs;
use Memcached;
use JSON::MaybeXS;
Expand Down Expand Up @@ -390,6 +391,34 @@ sub populate_dd_details : Private {
$c->cobrand->call_hook( 'garden_waste_dd_munge_form_details' => $c );

$c->stash->{redirect} = $c->cobrand->call_hook( 'garden_waste_dd_redirect_url' => $p ) || '';

if ($c->cobrand->direct_debit_collection_method eq 'internal') {
my $form = FixMyStreet::App::Form::Waste::BankDetails->new(
c => $c,
page_name => 'bank_details',
);

if ($c->req->method eq 'POST') {
$form->process(params => $c->req->params);
if ($form->validated) {
my $success = $c->cobrand->call_hook('setup_direct_debit', [$form->value]);
if ($success) {
$c->res->redirect($c->uri_for('/waste/dd_complete', {
token => $c->stash->{reference},
id => $c->stash->{report}->id
}));
$c->detach;
} else {
$form->add_form_error('Failed to setup direct debit');
}
}
}

$c->stash->{form} = $form;
}

$c->stash->{template} = 'waste/dd.html';
$c->detach;
}

sub direct_debit : Path('dd') : Args(0) {
Expand All @@ -398,7 +427,50 @@ sub direct_debit : Path('dd') : Args(0) {
$c->cobrand->call_hook('waste_report_extra_dd_data');
$c->forward('populate_dd_details');
$c->stash->{template} = 'waste/dd.html';
$c->detach;
}

sub direct_debit_bank_details : Path('dd_bank_details') : Args(0) {
my ($self, $c) = @_;

my $form = FixMyStreet::App::Form::Waste::BankDetails->new(
c => $c,
page_name => 'bank_details',
);

if ($c->req->method eq 'POST') {
$form->process(params => $c->req->params);
if ($form->validated) {
my $success = $c->cobrand->call_hook('setup_direct_debit', [$form->value]);
if ($success) {
$c->res->redirect($c->uri_for('/waste/dd_complete', {
token => $c->stash->{reference},
id => $c->stash->{report}->id
}));
$c->detach;
} else {
$form->add_form_error('Failed to setup direct debit');
}
}
}

$c->stash->{form} = $form;
$c->stash->{template} = 'waste/dd.html';
}

sub process_bank_details : Private {
my ($self, $c, $form) = @_;

my $success = $c->cobrand->setup_direct_debit($form->saved_data);
if ($success) {
$c->res->redirect($c->uri_for('/waste/dd_complete', {
token => $c->stash->{reference},
id => $c->stash->{report}->id
}));
return 1;
}

$form->add_form_error('Failed to setup direct debit');
return;
}

# we process direct debit payments when they happen so this page
Expand Down
156 changes: 156 additions & 0 deletions perllib/FixMyStreet/App/Form/Waste/BankDetails.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
package FixMyStreet::App::Form::Waste::BankDetails;

use utf8;
use HTML::FormHandler::Moose;
use mySociety::PostcodeUtil;
extends 'FixMyStreet::App::Form::Waste';

has_field name_title => (
type => 'Text',
required => 1,
label => 'Title (e.g. Mr, Mrs, Ms, Dr, etc.)',
);

has_field first_name => (
type => 'Text',
required => 1,
label => 'First name',
validate_method => sub {
my $self = shift;
return unless $self->value;
$self->add_error('First name must be 255 characters or less') if length($self->value) > 255;
},
);

has_field surname => (
type => 'Text',
required => 1,
label => 'Surname',
validate_method => sub {
my $self = shift;
return unless $self->value;
$self->add_error('Surname must be 255 characters or less') if length($self->value) > 255;
},
);

has_field address1 => (
type => 'Text',
required => 1,
label => 'Address line 1',
validate_method => sub {
my $self = shift;
return unless $self->value;
$self->add_error('Address line 1 must be 50 characters or less')
if length($self->value) > 50;
},
);

has_field address2 => (
type => 'Text',
required => 1,
label => 'Address line 2',
validate_method => sub {
my $self = shift;
return unless $self->value;
$self->add_error('Address line 2 must be 30 characters or less')
if length($self->value) > 30;
},
);

has_field address3 => (
type => 'Text',
required => 0,
label => 'Address line 3',
validate_method => sub {
my $self = shift;
return unless $self->value;
$self->add_error('Address line 3 must be 30 characters or less')
if length($self->value) > 30;
},
);

has_field address4 => (
type => 'Text',
required => 0,
label => 'Address line 4',
validate_method => sub {
my $self = shift;
return unless $self->value;
$self->add_error('Address line 4 must be 30 characters or less')
if length($self->value) > 30;
},
);

has_field post_code => (
type => 'Text',
required => 1,
label => 'Post code',
validate_method => sub {
my $self = shift;
return unless $self->value;
$self->add_error('Please enter a valid postcode')
unless mySociety::PostcodeUtil::is_valid_postcode($self->value);
},
);

has_field account_holder => (
type => 'Text',
required => 1,
label => 'Name of account holder',
validate_method => sub {
my $self = shift;
return unless $self->value;
my $value = $self->value;
# Remove any special characters, keeping only alphanumeric and spaces
$value =~ s/[^a-zA-Z0-9 ]//g;
$self->add_error('Account holder name must be 18 characters or less')
if length($value) > 18;
# Update the value to the cleaned version
$self->value($value);
},
);

has_field account_number => (
type => 'Text',
required => 1,
label => 'Account number',
validate_method => sub {
my $self = shift;
return unless $self->value;
$self->add_error('Please enter a valid 8 digit account number')
unless $self->value =~ /^\d{8}$/;
},
);

has_field sort_code => (
type => 'Text',
required => 1,
label => 'Sort code',
validate_method => sub {
my $self = shift;
return unless $self->value;
my $sort_code = $self->value;
$sort_code =~ s/[^0-9]//g;
$self->add_error('Please enter a valid 6 digit sort code')
unless $sort_code =~ /^\d{6}$/;
},
);

# Create a dedicated page for entering bank details.
has_page bank_details => (
title => 'Enter Your Bank Details',
template => 'waste/bank_details.html',
fields => ['account_holder', 'account_number', 'sort_code', 'reference', 'amount', 'report_id', 'submit'],
next => sub {
my $form = shift;
return $form->wizard_finished('process_bank_details');
},
);

has_field submit => (
type => 'Submit',
value => 'Set up Direct Debit',
element_attr => { class => 'govuk-button' },
);

1;
46 changes: 45 additions & 1 deletion perllib/FixMyStreet/Cobrand/Bexley/Garden.pm
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ package FixMyStreet::Cobrand::Bexley::Garden;

use Moo::Role;
with 'FixMyStreet::Roles::Cobrand::SCP',
'FixMyStreet::Roles::Cobrand::Paye';
'FixMyStreet::Roles::Cobrand::Paye',
'FixMyStreet::Roles::Cobrand::AccessPaySuite';

sub garden_service_name { 'garden waste collection service' }

Expand Down Expand Up @@ -37,4 +38,47 @@ sub waste_cc_payment_line_item_ref {
return $p->id;
}

sub waste_payment_ref_council_code { "BEX" }

sub direct_debit_collection_method { 'internal' }

sub setup_direct_debit {
my ($self, $form) = @_;
my $c = $self->{c};
my $data = $form->value;

my $i = $self->get_dd_integration;
my $customer = $i->create_customer({
customerRef => $data->{email},
email => $data->{email},
title => $data->{name_title},
firstName => $data->{first_name},
surname => $data->{surname},
postCode => $data->{post_code},
accountNumber => $data->{account_number},
bankSortCode => $data->{sort_code},
accountHolderName => $data->{account_holder},
line1 => $data->{address1},
line2 => $data->{address2},
line3 => $data->{address3},
line4 => $data->{address4},
});
my $contract = $i->create_contract($customer->{Id}, {
scheduleId => '38491b98-e3dd-45c1-80e7-e44941e481c6',
start => '2025-03-01T00:00:00.000',
isGiftAid => 0,
terminationType => "Until further notice",
atTheEnd => "Switch to further notice",
paymentMonthInYear => 3,
paymentDayInMonth => 28,
amount => 50.00,
additionalReference => 'BEXLEY GGW',
});

::Dwarn($data);
::Dwarn($customer);
::Dwarn($contract);
return 1;
}

1;
8 changes: 8 additions & 0 deletions perllib/FixMyStreet/Cobrand/Default.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1551,4 +1551,12 @@ Returns true when staff can assign a report to a disabled category.

sub staff_can_assign_reports_to_disabled_categories { 1; }

=item direct_debit_collection_method
Returns the method of collection for Direct Debit payments.
=cut

sub direct_debit_collection_method { 'redirect' }

1;
Loading

0 comments on commit 9dd1054

Please sign in to comment.