package Pear::LocalLoop::Controller::Admin::Import; use Mojo::Base 'Mojolicious::Controller'; use Text::CSV; use Try::Tiny; has result_set => sub { my $c = shift; return $c->schema->resultset('ImportSet'); }; sub index { my $c = shift; my $import_rs = $c->result_set->search( undef, { page => $c->param('page') || 1, rows => 10, order_by => { -desc => 'date' }, }, ); $c->stash( import_rs => $import_rs ); } sub list { my $c = shift; my $set_id = $c->param('set_id'); my $import_set = $c->result_set->find($set_id); my $import_value_rs = $c->result_set->get_values($set_id); my $import_users_rs = $c->result_set->get_users($set_id); my $import_org_rs = $c->result_set->get_orgs($set_id); my $import_lookup_rs = $c->result_set->get_lookups($set_id); $c->stash( import_set => $import_set, import_value_rs => $import_value_rs, import_users_rs => $import_users_rs, import_org_rs => $import_org_rs, import_lookup_rs => $import_lookup_rs, ); } sub get_add { my $c = shift; } sub post_add { my $c = shift; my $csv_data = $c->param('csv'); my $date_format = $c->param('date_format'); my $csv = Text::CSV->new({ binary => 1, allow_whitespace => 1, }); open my $fh, '<', \$csv_data; # List context returns the actual headers my @csv_headers; my $error; try { @csv_headers = $csv->header( $fh ); } catch { $error = $_; }; if ( defined $error ) { $c->_csv_flash_error( $error ); $c->redirect_to( '/admin/import/add' ); return; } # Text::CSV Already errors on duplicate columns, so this is fine my @required = grep {/^user$|^value$|^date$|^organisation$/} @csv_headers; unless ( scalar( @required ) == 4 ) { $c->_csv_flash_error( 'Required columns not available' ); $c->redirect_to( '/admin/import/add' ); return; } my $csv_output = $csv->getline_hr_all( $fh ); unless ( scalar( @$csv_output ) ) { $c->_csv_flash_error( "No data found" ); $c->redirect_to( '/admin/import/add' ); return; } for my $data ( @$csv_output ) { for my $key ( qw/ user value organisation / ) { unless ( defined $data->{$key} ) { $c->_csv_flash_error( "Undefined [$key] data found" ); $c->redirect_to( '/admin/import/add' ); return; } } if ( defined $data->{date} ) { my $dtp = DateTime::Format::Strptime->new( pattern => $date_format ); my $dt_obj = $dtp->parse_datetime($data->{date}); unless ( defined $dt_obj ) { $c->_csv_flash_error( "Undefined or incorrect format for [date] data found" ); $c->redirect_to( '/admin/import/add' ); return; } $data->{date} = $dt_obj; } } my $value_set; $c->schema->txn_do( sub { $value_set = $c->result_set->create({}); $value_set->values->populate( [ [ qw/ user_name purchase_value purchase_date org_name / ], ( map { [ @{$_}{qw/ user value date organisation /} ] } @$csv_output ), ] ); } ); unless ( defined $value_set ) { $c->_csv_flash_error( 'Error creating new Value Set' ); $c->redirect_to( '/admin/import/add' ); return; } $c->flash( success => 'Created Value Set' ); $c->redirect_to( '/admin/import/' . $value_set->id ); } sub _csv_flash_error { my ( $c, $error ) = @_; $error //= "An error occurred"; $c->flash( error => $error, csv_data => $c->param('csv'), date_format => $c->param('date_format'), ); } sub get_user { my $c = shift; my $set_id = $c->param('set_id'); my $user_name = $c->param('user'); my $values_rs = $c->result_set->find($set_id)->values->search( { user_name => $user_name, ignore_value => 0, } ); unless ( $values_rs->count > 0 ) { $c->flash( error => 'User not found or all values are ignored' ); return $c->redirect_to( '/admin/import/' . $set_id ); } my $lookup_result = $c->result_set->find($set_id)->lookups->find( { name => $user_name }, ); my $entity_id = $c->param('entity'); my $users_rs = $c->schema->resultset('User'); if ( defined $entity_id && $users_rs->find({ entity_id => $entity_id }) ) { if ( defined $lookup_result ) { $lookup_result->update({ entity_id => $entity_id }); } else { $lookup_result = $c->result_set->find($set_id)->lookups->create( { name => $user_name, entity_id => $entity_id, }, ); } } elsif ( defined $entity_id ) { $c->stash( error => "User does not exist" ); } $c->stash( users_rs => $users_rs, lookup => $lookup_result, user_name => $user_name, ); } sub get_org { my $c = shift; my $set_id = $c->param('set_id'); my $org_name = $c->param('org'); my $values_rs = $c->result_set->find($set_id)->values->search( { org_name => $org_name, ignore_value => 0, } ); unless ( $values_rs->count > 0 ) { $c->flash( error => 'Organisation not found or all values are ignored' ); return $c->redirect_to( '/admin/import/' . $set_id ); } my $lookup_result = $c->result_set->find($set_id)->lookups->find( { name => $org_name }, ); my $entity_id = $c->param('entity'); my $orgs_rs = $c->schema->resultset('Organisation'); if ( defined $entity_id && $orgs_rs->find({ entity_id => $entity_id }) ) { if ( defined $lookup_result ) { $lookup_result->update({ entity_id => $entity_id }); } else { $lookup_result = $c->result_set->find($set_id)->lookups->create( { name => $org_name, entity_id => $entity_id, }, ); } } elsif ( defined $entity_id ) { $c->stash( error => "Organisation does not exist" ); } $c->stash( orgs_rs => $orgs_rs, lookup => $lookup_result, org_name => $org_name, ); } sub get_value { my $c = shift; my $set_id = $c->param('set_id'); } sub post_value { my $c = shift; my $set_id = $c->param('set_id'); } 1;