diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index 59631e7..6b513a1 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -190,6 +190,9 @@ sub startup { $admin_routes->post('/organisations/add')->to('admin-organisations#add_org_submit'); $admin_routes->get('/organisations/:id')->to('admin-organisations#valid_read'); $admin_routes->post('/organisations/:id')->to('admin-organisations#valid_edit'); + $admin_routes->get('/organisations/:id/merge')->to('admin-organisations#merge_list'); + $admin_routes->get('/organisations/:id/merge/:target_id')->to('admin-organisations#merge_detail'); + $admin_routes->post('/organisations/:id/merge/:target_id')->to('admin-organisations#merge_confirm'); $admin_routes->get('/feedback')->to('admin-feedback#index'); $admin_routes->get('/feedback/:id')->to('admin-feedback#read'); diff --git a/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm index 2cb3660..8a4eb5f 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm @@ -3,6 +3,11 @@ use Mojo::Base 'Mojolicious::Controller'; use Try::Tiny; +has result_set => sub { + my $c = shift; + return $c->schema->resultset('Organisation'); +}; + sub list { my $c = shift; @@ -127,4 +132,104 @@ sub valid_edit { $c->redirect_to( '/admin/organisations/'); } +sub merge_list { + my $c = shift; + + my $org_id = $c->param('id'); + my $org_result = $c->result_set->find($org_id); + + if ( defined $org_result->entity->user ) { + $c->flash( error => 'Cannot merge from user-owned organisation!' ); + $c->redirect_to( '/admin/organisations/' . $org_id ); + return; + } + + my $org_rs = $c->result_set->search( + { + id => { '!=' => $org_id }, + }, + { + page => $c->param('page') || 1, + rows => 10, + order_by => { '-asc' => 'name' }, + } + ); + + $c->stash( + org_result => $org_result, + org_rs => $org_rs, + ); +} + +sub merge_detail { + my $c = shift; + + my $org_id = $c->param('id'); + my $org_result = $c->result_set->find($org_id); + + if ( defined $org_result->entity->user ) { + $c->flash( error => 'Cannot merge from user-owned organisation!' ); + $c->redirect_to( '/admin/organisations/' . $org_id ); + return; + } + + my $target_id = $c->param('target_id'); + my $target_result = $c->result_set->find($target_id); + + unless ( defined $target_result ) { + $c->flash( error => 'Unknown target organisation' ); + $c->redirect_to( '/admin/organisations/' . $org_id . '/merge' ); + return; + } + + $c->stash( + org_result => $org_result, + target_result => $target_result, + ); +} + +sub merge_confirm { + my $c = shift; + + my $org_id = $c->param('id'); + my $org_result = $c->result_set->find($org_id); + + if ( defined $org_result->entity->user ) { + $c->flash( error => 'Cannot merge from user-owned organisation!' ); + $c->redirect_to( '/admin/organisations/' . $org_id ); + return; + } + + my $target_id = $c->param('target_id'); + my $target_result = $c->result_set->find($target_id); + my $confirm = $c->param('confirm'); + + if ( $confirm eq 'checked' && defined $org_result && defined $target_result ) { + try { + $c->schema->txn_do( sub { + # Done as an update, not update_all, so its damn fast - we're only + # editing an id which is guaranteed to be an integer here, and this + # makes it only one update statement. + $org_result->entity->sales->update( + { seller_id => $target_result->entity->id } + ); + my $count = $org_result->entity->sales->count; + die "Failed to migrate all sales" if $count; + $org_result->entity->delete; + $c->schema->resultset('ImportLookup')->search({ entity_id => $org_result->entity->id })->delete; + my $org_count = $c->result_set->search({id => $org_result->id })->count; + my $entity_count = $c->schema->resultset('Entity')->search({id => $org_result->entity->id })->count; + die "Failed to remove org" if $org_count; + die "Failed to remove entity" if $entity_count; + }); + } catch { + $c->app->log->warn($_); + }; + $c->flash( error => 'Engage' ); + } else { + $c->flash( error => 'You must tick the confirmation box to proceed' ); + } + $c->redirect_to( '/admin/organisations/' . $org_id . '/merge/' . $target_id ); +} + 1; diff --git a/lib/Pear/LocalLoop/Plugin/Currency.pm b/lib/Pear/LocalLoop/Plugin/Currency.pm index 842cf89..f256f80 100644 --- a/lib/Pear/LocalLoop/Plugin/Currency.pm +++ b/lib/Pear/LocalLoop/Plugin/Currency.pm @@ -12,6 +12,11 @@ sub register { } return $value; }); + + $app->helper( format_currency_from_db => sub { + my ( $c, $value ) = @_; + return sprintf( '£%.2f', $value / 100000 ); + }); } 1; diff --git a/templates/admin/organisations/merge_detail.html.ep b/templates/admin/organisations/merge_detail.html.ep new file mode 100644 index 0000000..4b3afce --- /dev/null +++ b/templates/admin/organisations/merge_detail.html.ep @@ -0,0 +1,81 @@ +% layout 'admin_errors'; +% title 'Organisations'; +
+
+

Merging <%= $org_result->name %> into <%= $target_result->name %>

+ Back +
+ % for my $org ( $org_result, $target_result ) { +
+
+

+ <%= $org->name %> +

+
+
+
+ Street Name +
+
+ %= $org->street_name +
+
+ Town/City +
+
+ %= $org->town +
+
+ Sector +
+
+ %= $org->sector +
+
+ Postcode +
+
+ %= $org->postcode +
+
+ Validated +
+
+ %= $org->pending ? 'no' : 'yes' +
+
+ Is Local +
+
+ %= $org->is_local ? 'yes' : 'no' +
+
+
+
+
+ Transaction Count: <%= $org->entity->sales->count %> +
+
+
+
+ % } +
+
+
+

+ Warning: Cannot be undone! +

+

+ This will discard all basic information about this organisation, and + merge all transactions into the target organisation. This process has + no way of being undone. +

+
+ + + +
+
+
+
+
diff --git a/templates/admin/organisations/merge_list.html.ep b/templates/admin/organisations/merge_list.html.ep new file mode 100644 index 0000000..0a0dc49 --- /dev/null +++ b/templates/admin/organisations/merge_list.html.ep @@ -0,0 +1,25 @@ +% layout 'admin_errors'; +% title 'Organisations'; +
+
+

Target to merge into for <%= $org_result->name %>

+
+
+
+

+ Organisations + Back +

+
+ % for my $org ( $org_rs->all ) { + + %= $org->name + + % } +
+
+
+
+ %= bootstrap_pagination( $c->param('page') || 1, $org_rs->pager->last_page, { class => 'justify-content-center' } ); +
+