Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ use Data::Dumper;
use Text::CSV;
use CXGN::List::Validate;

#
# DEPRECATED: This plugin has been replaced by the SeedlotInventoryGeneric plugin
#


sub _validate_with_plugin {
my $self = shift;
my $filename = $self->get_filename();
Expand Down
139 changes: 139 additions & 0 deletions lib/CXGN/Stock/Seedlot/ParseUpload/Plugin/SeedlotInventoryGeneric.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package CXGN::Stock::Seedlot::ParseUpload::Plugin::SeedlotInventoryGeneric;

use Moose::Role;
use CXGN::File::Parse;
use CXGN::Stock::StockLookup;
use SGN::Model::Cvterm;
use Data::Dumper;
use CXGN::List::Validate;

sub _validate_with_plugin {
my $self = shift;

my $filename = $self->get_filename();
my $schema = $self->get_chado_schema();

my @error_messages;
my %errors;
my %missing_seedlots;

my $parser = CXGN::File::Parse->new (
file => $filename,
required_columns => [ 'box_id', 'seed_id', 'inventory_date', 'inventory_person'],
optional_columns => ['weight_gram', 'amount'],
column_aliases => {
'box_id' => ['box id', 'box name', 'box_name'],
'seed_id' => ['seed id', 'seedlot_name', 'seedlot name'],
'inventory_date' => ['inventory date'],
'inventory_person' => ['inventory person'],
'weight_gram' => ['weight(g)', 'weight gram'],
'amount' => ['count'],

},
);

my $parsed = $parser->parse();
my $parsed_errors = $parsed->{errors};
my $parsed_columns = $parsed->{columns};
my $parsed_data = $parsed->{data};
my $parsed_values = $parsed->{values};
my $additional_columns = $parsed->{additional_columns};

if ( $parsed_errors && scalar(@$parsed_errors) > 0 ) {
$errors{'error_messages'} = $parsed_errors;
$self->_set_parse_errors(\%errors);
return;
}

if ( $additional_columns && scalar(@$additional_columns) > 0 ) {
$errors{'error_messages'} = [
"The following columns are not recognized: " . join(', ', @$additional_columns) . ". Please check the spreadsheet format for the allowed columns."
];
$self->_set_parse_errors(\%errors);
return;
}

for my $row ( @$parsed_data ) {
my $row_num = $row->{_row};
my $seedlot_name = $row->{'seed_id'};
my $amount = $row->{'amount'};
my $weight = $row->{'weight_gram'};

if (!defined $amount && !defined $weight) {
push @error_messages, "On row:$row_num you must provide either a weight in grams or a seed count amount.";
}
}

my $seen_seedlot_names = $parsed_values->{'seed_id'};

my $seedlot_validator = CXGN::List::Validate->new();
my @seedlots_missing = @{$seedlot_validator->validate($schema,'seedlots',$seen_seedlot_names)->{'missing'}};
if (scalar(@seedlots_missing) > 0) {
push @error_messages, "The following seedlots are not in the database as uniquenames: ".join(',',@seedlots_missing);
}

if (scalar(@error_messages) >= 1) {
$errors{'error_messages'} = \@error_messages;
$self->_set_parse_errors(\%errors);
return;
} else {
$self->_set_parsed_data($parsed);
}

return 1;

}

sub _parse_with_plugin {
my $self = shift;
my $schema = $self->get_chado_schema();
my $parsed = $self->_parsed_data();
my $parsed_data = $parsed->{data};
my $parsed_values = $parsed->{values};
my %parsed_result;
my %seen_seedlot_names;

my $accession_names = $parsed_values->{'accession_name'};
my $seedlot_names = $parsed_values->{'seedlot_name'};

for my $row (@$parsed_data) {
my $row_num;
my $seed_id;
my $box_id;
my $inventory_date;
my $inventory_person;
my $weight;
my $amount;
$row_num = $row->{_row};
$seed_id = $row->{'seed_id'};
$box_id = $row->{'box_id'};
$inventory_date = $row->{'inventory_date'};
$inventory_person = $row->{'inventory_person'};
$weight = $row->{'weight_gram'};
$amount = $row->{'amount'};
$seen_seedlot_names{$seed_id}++;

$parsed_result{$seed_id} = {
box_id => $box_id,
seedlot_name => $seed_id,
inventory_date => $inventory_date,
inventory_person => $inventory_person,
weight_gram => $weight,
amount => $amount
};
}

my @seedlot_names = keys %seen_seedlot_names;
my $seedlots_rs = $schema->resultset("Stock::Stock")->search({uniquename => {-in => \@seedlot_names}});
while (my $r = $seedlots_rs->next){
$parsed_result{$r->uniquename}{seedlot_id} = $r->stock_id;
}

$self->_set_parsed_data(\%parsed_result);

return 1;

}


1;
58 changes: 33 additions & 25 deletions lib/SGN/Controller/AJAX/Seedlot.pm
Original file line number Diff line number Diff line change
Expand Up @@ -887,7 +887,7 @@ sub upload_seedlots_inventory_POST : Args(0) {
}
unlink $upload_tempfile;
my $parser = CXGN::Stock::Seedlot::ParseUpload->new(chado_schema => $schema, filename => $archived_filename_with_path);
$parser->load_plugin('SeedlotInventoryCSV');
$parser->load_plugin('SeedlotInventoryGeneric');
my $parsed_data = $parser->parse();
#print STDERR Dumper $parsed_data;

Expand All @@ -907,46 +907,54 @@ sub upload_seedlots_inventory_POST : Args(0) {
$c->stash->{rest} = {error_string => $return_error, missing_seedlots => $parse_errors->{'missing_seedlots'} };
$c->detach();
}

eval {
while (my ($key, $val) = each(%$parsed_data)){
my $sl = CXGN::Stock::Seedlot->new(schema => $schema, seedlot_id => $val->{seedlot_id});
$sl->box_name($val->{box_id});
$sl->description($val->{description});

print STDERR "QUALITY: $val->{quality}\n";
$sl->quality($val->{quality});

my $return = $sl->store();

my $current_stored_count = $sl->get_current_count_property();
my $current_stored_count = $sl->get_current_count_property();
my $current_stored_weight = $sl->get_current_weight_property();

my $weight_difference = $val->{weight_gram} - $current_stored_weight;
my $weight_difference;
my $amount_difference;
my $factor;
if ($weight_difference >= 0){
$factor = 1;
} else {
$factor = -1;
$weight_difference = $weight_difference * -1; #Store positive values only
my $inventory_weight = $val->{weight_gram};
my $inventory_amount = $val->{amount};

if (defined $inventory_weight) {
$weight_difference = $inventory_weight - $current_stored_weight;
if ($weight_difference >= 0){
$factor = 1;
} else {
$factor = -1;
$weight_difference = $weight_difference * -1; #Store positive values only
}
}

if (defined $inventory_amount) {
$amount_difference = $inventory_amount - $current_stored_count;
if ($amount_difference >= 0){
$factor = 1;
} else {
$factor = -1;
$amount_difference = $amount_difference * -1; #Store positive values only
}
}

my $transaction = CXGN::Stock::Seedlot::Transaction->new(schema => $schema);
$transaction->factor($factor);

my $from_stock_id = $val->{seedlot_id};
my $from_stock_name = $val->{seedlot_name};

if ($val->{source_id}) {
$from_stock_id = $val->{source_id};
$from_stock_name = $val->{source};
}

my $from_stock_id = $val->{seedlot_id};
my $from_stock_name = $val->{seedlot_name};
$transaction->from_stock([ $from_stock_id, $from_stock_name ]);
$transaction->to_stock([$val->{seedlot_id}, $val->{seedlot_name}]);
$transaction->weight_gram($weight_difference);
if (defined $inventory_weight) {
$transaction->weight_gram($weight_difference);
} elsif (defined $inventory_amount) {
$transaction->amount($amount_difference);
}
$transaction->timestamp($val->{inventory_date});
$transaction->description('Seed inventory CSV upload.');
$transaction->description('Seed inventory upload.');
$transaction->operator($val->{inventory_person});
$transaction->store();

Expand Down
14 changes: 8 additions & 6 deletions mason/breeders_toolbox/upload_seedlots_inventory_dialogs.mas
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,6 @@
</div>
<div class="modal-body">
<div class="container-fluid">
<b>Seedlots may be uploaded in a CSV file (.csv)</b>
<br />
(Excel .xls and .xlsx format not supported)
<br /><br />
<b>Header:</b>
<br>
The first row (header) should contain the following:
Expand All @@ -175,17 +171,23 @@
</tr>
</tbody>
</table>

<b>Note: If you would like to upload number of materials in seedlot instead of weight, you can replace the header 'weight_gram' with 'amount'</b>
<br/>
<br/>
<b>Required fields:</b>
<ul>
<li>box_id (the name of the box that the seedlot is in. also called box_name.)</li>
<li>seed_id (unique identifier for the seedlot. must exist in the database. also called seedlot_name)</li>
<li>inventory_date (a timestamp for when the seedlot was inventoried)</li>
<li>inventory_person (the name of the person doing the inventory. can be any name. also called operator_name)</li>
<li>weight_gram (the weight in grams of the seedlot)</li>
<li>weight_gram (the weight in grams of the seedlot)
<br/><b>OR</b><br/>
amount (number of materials in seedlot.)</li>

</ul>

</div>
<& /help/file_upload_type.mas, type => "Seedlot Inventory", optional_column => 0 &>
</div>
<div class="modal-footer">
<button id="close_seedlot_info_upload_inventory_dialog" type="button" class="btn btn-default" data-dismiss="modal">Close</button>
Expand Down
Binary file added t/data/stock/seedlot_inventory_amount.xlsx
Binary file not shown.
47 changes: 44 additions & 3 deletions t/unit_mech/AJAX/Stocks/UploadSeedlots.t
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,14 @@ my $message_hash = JSON::XS->new()->decode($message);
is_deeply($message_hash->{'success'}, 1);
my $added_seedlot2 = $message_hash->{'added_seedlot'};

$file = $f->config->{basepath}."/t/data/stock/seedlot_inventory_android_app";
#test seedlot_inventory csv upload with weight info
$file = $f->config->{basepath}."/t/data/stock/seedlot_inventory_android_app.csv";
$ua = LWP::UserAgent->new;
$response = $ua->post(
'http://localhost:3010/ajax/breeders/seedlot-inventory-upload',
Content_Type => 'form-data',
Content => [
seedlot_uploaded_inventory_file => [ $file, 'seedlot_inventory_upload', Content_Type => 'application/vnd.ms-excel', ],
seedlot_uploaded_inventory_file => [ $file, 'seedlot_inventory_android_app.csv'],
"sgn_session_id"=>$sgn_session_id
]
);
Expand All @@ -120,9 +121,49 @@ $response = $ua->post(
ok($response->is_success);
$message = $response->decoded_content;
$message_hash = JSON::XS->new()->decode($message);
print STDERR Dumper $message_hash;
#print STDERR Dumper $message_hash;
is_deeply($message_hash, {'success' => 1});

my $seedlot4_stock_id = $schema->resultset('Stock::Stock')->find({ name => 'test_accession4_001' })->stock_id();
my $seedlot4 = CXGN::Stock::Seedlot->new(schema => $schema, seedlot_id => $seedlot4_stock_id);
my $seedlot4_weight = $seedlot4->current_weight;
is($seedlot4_weight, 10);

my $seedlot3_stock_id = $schema->resultset('Stock::Stock')->find({ name => 'test_accession3_001' })->stock_id();
my $seedlot3 = CXGN::Stock::Seedlot->new(schema => $schema, seedlot_id => $seedlot3_stock_id);
my $seedlot3_weight = $seedlot3->current_weight;
is($seedlot3_weight, 12);

my $seedlot2_stock_id = $schema->resultset('Stock::Stock')->find({ name => 'test_accession2_001' })->stock_id();
my $seedlot2 = CXGN::Stock::Seedlot->new(schema => $schema, seedlot_id => $seedlot2_stock_id);
my $seedlot2_weight = $seedlot2->current_weight;
is($seedlot2_weight, 0);

#test seedlot_inventory xlsx upload with amount info
$file = $f->config->{basepath}."/t/data/stock/seedlot_inventory_amount.xlsx";
$ua = LWP::UserAgent->new;
$response = $ua->post(
'http://localhost:3010/ajax/breeders/seedlot-inventory-upload',
Content_Type => 'form-data',
Content => [
seedlot_uploaded_inventory_file => [ $file, 'seedlot_inventory_amount.xlsx', Content_Type => 'application/vnd.ms-excel'],
"sgn_session_id"=>$sgn_session_id
]
);

ok($response->is_success);
$message = $response->decoded_content;
$message_hash = JSON::XS->new()->decode($message);
is_deeply($message_hash, {'success' => 1});

my $seedlot3_2 = CXGN::Stock::Seedlot->new(schema => $schema, seedlot_id => $seedlot3_stock_id);
my $seedlot3_count = $seedlot3_2->current_count;
is($seedlot3_count, 110);

my $seedlot2_2 = CXGN::Stock::Seedlot->new(schema => $schema, seedlot_id => $seedlot2_stock_id);
my $seedlot2_count = $seedlot2_2->current_count;
is($seedlot2_count, 120);

#test seedlot list details
my $seedlot_list_id = CXGN::List::create_list($f->dbh(), 'test_seedlot_list', 'test_desc', 41);
my $seedlot_list = CXGN::List->new( { dbh => $f->dbh(), list_id => $seedlot_list_id } );
Expand Down