From 37e8f0b46a193ba992034b11216d3df0fd91407f Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Tue, 3 Oct 2017 15:47:05 +0100 Subject: [PATCH] Updated to allow for user updates to change location by postcode --- CHANGELOG.md | 1 + lib/Pear/LocalLoop.pm | 1 + lib/Pear/LocalLoop/Controller/Api/Register.pm | 29 ++-------- lib/Pear/LocalLoop/Controller/Api/User.pm | 7 +++ lib/Pear/LocalLoop/Plugin/Postcodes.pm | 40 ++++++++++++++ t/api/user/postcode.t | 53 +++++++++++++++++++ 6 files changed, 105 insertions(+), 26 deletions(-) create mode 100644 lib/Pear/LocalLoop/Plugin/Postcodes.pm create mode 100644 t/api/user/postcode.t diff --git a/CHANGELOG.md b/CHANGELOG.md index 687ee1e..bdbc69c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Location is now updated on registration. Customers location is truncated to 2 decimal places based on their postcode. +* Location is also updated on changing a users postcode ## Bug Fixes diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index b6f6fcf..9890811 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -39,6 +39,7 @@ sub startup { $self->plugin('Pear::LocalLoop::Plugin::BootstrapPagination', { bootstrap4 => 1 } ); $self->plugin('Pear::LocalLoop::Plugin::Validators'); $self->plugin('Pear::LocalLoop::Plugin::Datetime'); + $self->plugin('Pear::LocalLoop::Plugin::Postcodes'); $self->plugin('Pear::LocalLoop::Plugin::TemplateHelpers'); $self->plugin('Authentication' => { diff --git a/lib/Pear/LocalLoop/Controller/Api/Register.pm b/lib/Pear/LocalLoop/Controller/Api/Register.pm index 9de39d9..fc8ed0b 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Register.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Register.pm @@ -82,34 +82,11 @@ sub post_register { return $c->api_validation_error if $validation->has_error; - my $postcode_obj = Geo::UK::Postcode::Regex->parse( - $validation->param('postcode') + my $location = $c->get_location_from_postcode( + $validation->param('postcode'), + $usertype, ); - my $location; - - unless ( defined $postcode_obj && $postcode_obj->{non_geographical} ) { - my $pc_result = $c->schema->resultset('GbPostcode')->find({ - incode => $postcode_obj->{incode}, - outcode => $postcode_obj->{outcode}, - }); - if ( defined $pc_result ) { - # Force truncation here as SQLite is stupid - $location = { - latitude => ( - $usertype eq 'customer' - ? int($pc_result->latitude * 100 ) / 100 - : $pc_result->latitude - ), - longitude => ( - $usertype eq 'customer' - ? int($pc_result->longitude * 100 ) / 100 - : $pc_result->longitude - ), - }; - } - } - if ($usertype eq 'customer'){ $c->schema->txn_do( sub { diff --git a/lib/Pear/LocalLoop/Controller/Api/User.pm b/lib/Pear/LocalLoop/Controller/Api/User.pm index 85d2be6..c500164 100644 --- a/lib/Pear/LocalLoop/Controller/Api/User.pm +++ b/lib/Pear/LocalLoop/Controller/Api/User.pm @@ -145,6 +145,11 @@ sub post_account_update { return $c->api_validation_error if $validation->has_error; + my $location = $c->get_location_from_postcode( + $validation->param('postcode'), + $user->type, + ); + if ( $user->type eq 'customer' ){ $c->schema->txn_do( sub { @@ -152,6 +157,7 @@ sub post_account_update { full_name => $validation->param('full_name'), display_name => $validation->param('display_name'), postcode => $validation->param('postcode'), + ( defined $location ? ( %$location ) : ( latitude => undef, longitude => undef ) ), }); $user->update({ email => $validation->param('email'), @@ -169,6 +175,7 @@ sub post_account_update { town => $validation->param('town'), sector => $validation->param('sector'), postcode => $validation->param('postcode'), + ( defined $location ? ( %$location ) : ( latitude => undef, longitude => undef ) ), }); $user->update({ email => $validation->param('email'), diff --git a/lib/Pear/LocalLoop/Plugin/Postcodes.pm b/lib/Pear/LocalLoop/Plugin/Postcodes.pm new file mode 100644 index 0000000..2f6e0c9 --- /dev/null +++ b/lib/Pear/LocalLoop/Plugin/Postcodes.pm @@ -0,0 +1,40 @@ +package Pear::LocalLoop::Plugin::Postcodes; +use Mojo::Base 'Mojolicious::Plugin'; + +use DateTime::Format::Strptime; + +sub register { + my ( $plugin, $app, $conf ) = @_; + + $app->helper( get_location_from_postcode => sub { + my ( $c, $postcode, $usertype ) = @_; + my $postcode_obj = Geo::UK::Postcode::Regex->parse( $postcode ); + + my $location; + + unless ( defined $postcode_obj && $postcode_obj->{non_geographical} ) { + my $pc_result = $c->schema->resultset('GbPostcode')->find({ + incode => $postcode_obj->{incode}, + outcode => $postcode_obj->{outcode}, + }); + if ( defined $pc_result ) { + # Force truncation here as SQLite is stupid + $location = { + latitude => ( + $usertype eq 'customer' + ? int($pc_result->latitude * 100 ) / 100 + : $pc_result->latitude + ), + longitude => ( + $usertype eq 'customer' + ? int($pc_result->longitude * 100 ) / 100 + : $pc_result->longitude + ), + }; + } + } + return $location; + }); +} + +1; diff --git a/t/api/user/postcode.t b/t/api/user/postcode.t new file mode 100644 index 0000000..851922c --- /dev/null +++ b/t/api/user/postcode.t @@ -0,0 +1,53 @@ +use Mojo::Base -strict; + +use FindBin qw/ $Bin /; + +use Test::More; +use Mojo::JSON; +use Test::Pear::LocalLoop; + +my $framework = Test::Pear::LocalLoop->new( + etc_dir => "$Bin/../../etc", +); +$framework->install_fixtures('full'); + +my $t = $framework->framework; +my $schema = $t->app->schema; + +my $session_key = $framework->login({ + email => 'test1@example.com', + password => 'abc123', +}); + +$t->post_ok('/api/user', json => { session_key => $session_key }) + ->status_is(200) + ->json_is('/success', Mojo::JSON->true) + ->json_is('/postcode', 'LA1 1AA') + ->json_is('/location', { + latitude => 54.04, + longitude => -2.80, + } + ); + +$t->post_ok('/api/user/account', json => { + session_key => $session_key, + full_name => 'Test User1', + display_name => 'Testing User1', + email => 'test1@example.com', + postcode => 'LA2 0AR', + password => 'abc123', + }) + ->status_is(200)->or($framework->dump_error) + ->json_is('/success', Mojo::JSON->true); + +$t->post_ok('/api/user', json => { session_key => $session_key }) + ->status_is(200) + ->json_is('/success', Mojo::JSON->true) + ->json_is('/postcode', 'LA2 0AR') + ->json_is('/location', { + latitude => 53.99, + longitude => -2.84, + } + ); + +done_testing;