]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/support-scripts/edi_fetcher.pl
Deepen test mode feedback (into top level EDI function)
[working/Evergreen.git] / Open-ILS / src / support-scripts / edi_fetcher.pl
1 #!/usr/bin/perl
2 # ---------------------------------------------------------------
3 # Copyright (C) 2010 Equinox Software, Inc
4 # Author: Joe Atzberger <jatzberger@esilibrary.com>
5 #
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
10
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 # ---------------------------------------------------------------
16
17 use strict;
18 use warnings;
19
20 use Data::Dumper;
21 use vars qw/$debug/;
22
23 use OpenILS::Application::Acq::EDI;
24 use OpenILS::Utils::Cronscript;
25 use File::Spec;
26
27 my $defaults = {
28     "account=i"  => 0,
29     "provider=i" => 0,
30     "inactive"   => 0,
31     "test"       => 0,
32 };
33
34 my $core  = OpenILS::Utils::Cronscript->new($defaults);
35 my $opts  = $core->MyGetOptions() or die "Getting options failed!";
36 my $e     = $core->editor();
37 my $debug = $opts->{debug};
38
39 if ($debug) {
40     print join "\n", "OPTIONS:", map {sprintf "%16s: %s", $_, $opts->{$_}} sort keys %$opts;
41     print "\n\n";
42 }
43
44 sub main_search {
45     my $select = {'+acqpro' => {active => {"in"=>['t','f']}} }; # either way
46     my %args = @_ ? @_ : ();
47     foreach (keys %args) {
48         $select->{$_} = $args{$_};
49     }
50     return $e->search_acq_edi_account([
51         $select,
52         {
53             'join' => 'acqpro',
54             flesh => 1,
55             flesh_fields => {acqedi => ['provider']},
56         }
57     ]);
58 }
59
60 my $set = main_search() or die "No EDI accounts found in database (table: acq.edi_account)";
61
62 my $total_accts = scalar(@$set);
63
64 ($total_accts) or die "No EDI accounts found in database (table: acq.edi_account)";
65
66 print "EDI Accounts Total : $total_accts\n";
67 my $active = [ grep {$_->provider->active eq 't'} @$set ];
68 print "EDI Accounts Active: ", scalar(@$active), "\n";
69
70 my $subset;
71 if ($opts->{inactive} or $opts->{provider} or $opts->{account}) {
72     print "Including inactive accounts\n";
73     $subset = [@$set];
74 } else {
75     $subset = $active;
76 }
77
78 my ($acct, $pro);
79 if ($opts->{provider}) {
80     print "Limiting by provider: " . $opts->{provider} . "\n";
81     $pro  = $e->retrieve_acq_provider($opts->{provider}) or die "provider '" . $opts->{provider} . "' not found";
82     printf "Provider %s found (edi_default %s)\n", $pro->id, $pro->edi_default;
83     $subset = main_search( 'id' => $pro->edi_default );
84     # $subset = [ grep {$_->provider->id == $opts->{provider}} @$subset ];
85     foreach (@$subset) {
86         $_->provider($pro);     # force provider match (short of LEFT JOINing the main_search query and dealing w/ multiple combos)
87     }
88     scalar(@$subset) or die "provider '" . $opts->{provider} . "' edi_default invalid (failed to match acq.edi_account.id)";
89     if ($opts->{account} and $opts->{account} != $pro->edi_default) {
90         die sprintf "ERROR: --provider=%s and --account=%s specify rows that exist, but are not paired by acq.provider.edi_default", $opts->{provider}, $opts->{account};
91     }
92     $acct = $subset->[0]; 
93
94 if ($opts->{account}) {
95     print "Limiting by account: " . $opts->{account} . "\n";
96     $subset = [ grep {$opts->{account}  == $_->id} @$subset ];
97     scalar(@$subset) or die "No acq.provider.edi_default matches option  --account=" . $opts->{account} . " ";
98     scalar(@$subset) > 1 and warn "account '" . $opts->{account} . "' has multiple matches.  Ignoring all but the first.";
99     $acct = $subset->[0]; 
100 }
101 scalar(@$subset) or die "No acq.provider rows match options " .
102     ($opts->{account}  ? ("--account="  . $opts->{account} ) : '') .
103     ($opts->{provider} ? ("--provider=" . $opts->{provider}) : '') ;
104
105 print "Limiting to " . scalar(@$subset) . " account(s)\n"; 
106 foreach (@$subset) {
107     printf "Provider %s - %s, edi_account %s - %s: %s%s\n",
108         $_->provider->id, $_->provider->name, $_->id, $_->label, $_->host, ($_->in_dir ? ('/' . $_->in_dir) : '') ;
109 }
110
111 if (@ARGV) {
112     $opts->{provider} or $opts->{account}
113         or die "ERROR: --account=[ID] or --provider=[ID] option required for local data ingest, with valid edi_account or provider id";
114     print "READING FROM ", scalar(@ARGV), " LOCAL SOURCE(s) ONLY.  NO REMOTE SERVER(s) WILL BE USED\n"; 
115     printf "File will be attributed to edi_account %s - %s: %s\n", $acct->id, $acct->label, $acct->host;
116     my @files = @ARGV; # copy original @ARGV
117     foreach (@files) {
118         @ARGV = ($_);  # We'll use the diamond op, so we can pull from STDIN too
119         my $content = join '', <> or next;
120         $opts->{test} and next;
121         my $in = OpenILS::Application::Acq::EDI->process_retrieval(
122             $content,
123             "localhost:" . File::Spec->rel2abs($_),
124             OpenILS::Application::Acq::EDI->remote_account($acct),
125             $acct,
126             $e
127         );
128     }
129     exit;
130 }
131 # else no args
132
133 my $res = OpenILS::Application::Acq::EDI->retrieve_core($subset,undef,undef,$opts->{test});
134 print "Files retrieved: ", scalar(@$res), "\n";
135 $debug and print "retrieve_core returns ", scalar(@$res),  " ids: " . join(', ', @$res), "\n";
136
137 # $Data::Dumper::Indent = 1;
138 $debug and print map {Dumper($_) . "\n"} @$subset;
139 print "\ndone\n";
140
141 __END__
142
143 =pod
144
145 =head1 NAME
146
147 edi_fetcher.pl - A script for retrieving and processing EDI files from remote accounts.
148
149 =head1 DESCRIPTION
150
151 This script is expected to be run via crontab, for the purpose of retrieving vendor EDI files.
152
153 Note: Depending on your vendors' and your own network environments, you may want to set/export
154 the environmental variable FTP_PASSIVE like:
155
156     export FTP_PASSIVE=1
157     # or
158     FTP_PASSIVE=1 Open-ILS/src/support-scripts/edi_fetcher.pl
159
160 =head1 OPTIONS
161
162     --account=[id]  Target one account, whether or not it is inactive.
163     --inactive      Includes inactive provider accounts (default OFF, forced ON if --account specified)
164
165 =head1 ARGUMENTS
166
167 edi_fetcher can also read from files specified as arguments on the command line, or from STDIN, or both.
168 In such cases, the filename is not used to check whether the file has been loaded or not.  
169
170 =head1 TODO
171
172 More docs here.
173
174 =head1 SEE ALSO
175
176     OpenILS::Utils::Cronscript
177     edi_pusher.pl
178
179 =head1 AUTHOR
180
181 Joe Atzberger <jatzberger@esilibrary.com>
182
183 =cut
184