package LIMS::Controller::Roles::ULISA; use Moose::Role; use Data::Dumper; use IO::All; use XML::Simple qw(:strict); # need to specify ForceArray & KeyAttr if using :strict here use LIMS::Local::ScriptHelpers; # ftp_file() method - not needed if using local dir has xs_options => ( is => 'ro', isa => 'HashRef', lazy_build => 1 ); has ulisa_ref => ( is => 'rw', isa => 'Int' ); has script_helpers => ( is => 'ro', isa => 'LIMS::Local::ScriptHelpers', lazy_build => 1 ); # provides ftp_file() method - don't need if using local dir sub send_xml { my ($self, $data) = @_; # warn Dumper $data; $self->ulisa_ref($data->{request}->{id}); # request.id # $self->_example_data(); # uncomment to dump data structure for example xml my $xs = XML::Simple->new(); # options for XMLout (needs array or hash): my %xs_opts = %{ $self->xs_options }; # warn Dumper \%xs_opts; # manipulate $data into hashref format expected by XMLout: my $ref = $self->_format($data); # warn Dumper $ref; # enclose xml in outer block; add ulisa 'version' inline: my $input = { add => $ref, version => 2 }; my $xml_out = $xs->XMLout( $input, %xs_opts ); # warn Dumper $xml_out; my $rtn = $self->_dispatch($xml_out); return $rtn; } sub _dispatch { my ($self, $xml) = @_; # XMLout string my $req_id = $self->ulisa_ref; # warn $req_id; my $tools = $self->script_helpers(); # warn Dumper $tools; my $cfg = $self->cfg('settings'); # warn Dumper $cfg; my $filename = sprintf '%s.xml', $req_id; my $src_path = '/tmp/' . $filename; # $xml > io($src_path); # gives 'Useless use of numeric gt (>) in void context' # warning on 1st call to Local::Labels after server startup; alt. syntax: io($src_path)->print($xml); my %params = ( remote_filename => $filename, local_filename => $src_path, passive_mode => 1, # otherwise get 'FTP error - STOR command started' with CoreFTP server_addr => $cfg->{dako_link_addr}, username => $cfg->{dako_link_user}, password => $cfg->{dako_link_pwd}, ); # warn Dumper \%params; # ftp file (returns str on failure, undef on success): my $rtn = $tools->ftp_file(\%params); if ($rtn) { # warn Dumper $rtn; return $rtn; } else { io($src_path)->unlink; return 0; } } sub _format { # returns hashref: my ($self, $data) = @_; my $request = $data->{request}; my $patient = $data->{patient}; my $lab_test = $data->{lab_test}; my $now = LIMS::Local::Utils::time_now->epoch; # warn $now; my $lab_number = join '/', $request->{request_number}, $request->{year} - 2000; =begin # set XMLout option "NoAttr => 0" data values as arrayref produces nested output: eg case => { caseid => [ $caseid ] } produces: 1234 data values as string produces inline: eg case => { caseid => $caseid } produces =cut my @slides; for my $ref (@$lab_test) { # warn Dumper $ref; # create unique slide ID from request.id, test.id & epoch (max 32 chars): my $slide_id = sprintf 'R%sT%sE%s', $request->{id}, $ref->{test_id}, $now; push @slides, { slideid => [ $slide_id ], # nested protocol => [ $ref->{test_name} ], # nested slidetype => [ 2 ], # IHC # nested }; } my %slides = ( caseid => $lab_number, # inline slide => \@slides, ); my %case = ( requestid => [ $request->{id} ], # nested firstname => [ $patient->{first_name} ], # nested lastname => [ $patient->{last_name} ], # nested caseid => $lab_number, # inline ); my %h = ( # hash data structure for input to XMLout case => \%case, slides => \%slides, ); # warn Dumper \%h; return \%h; } sub _build_xs_options { my %opts = ( SuppressEmpty => 0, # ? only works for xml_in RootName => 'ulisa', XMLDecl => q!!, KeyAttr => [], NoAttr => 0, # gives inline (scalar) AND nested (arrayref) attributes ); return \%opts; } sub _build_script_helpers { LIMS::Local::ScriptHelpers->new } sub _example_data { my $self = shift; my $xs = XML::Simple->new(); my %opts = %{ $self->xs_options }; # warn Dumper $opts; my $data; $data .= $_ for ; warn $data; my $href = XMLin($data, ForceArray => 1, KeyAttr => []); warn Dumper $href; my $xml = $xs->XMLout( $href, %opts ); warn Dumper $xml; } 1; __DATA__ Norbert Colon 87 2 CD20 88 2 ki-67