Bug 22600: Set 'commandline' interface appropriately
[koha.git] / misc / cronjobs / edi_cron.pl
1 #!/usr/bin/perl
2 #
3 # Copyright 2013,2014,2015 PTFS Europe Ltd
4 #
5 # This file is part of Koha.
6 #
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 3 of the License, or (at your option) any later
10 # version.
11 #
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License along
17 # with Koha; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20 use warnings;
21 use strict;
22 use utf8;
23
24 # Handles all the edi processing for a site
25 # loops through the vendor_edifact records and uploads and downloads
26 # edifact files if the appropriate type is enabled
27 # downloaded quotes, invoices and responses are processed here
28 # if orders are enabled and present they are generated and sent
29 # can be run as frequently as required
30 # log messages are appended to logdir/editrace.log
31
32 use Koha::Script -cron;
33 use C4::Context;
34 use Log::Log4perl qw(:easy);
35 use Koha::Database;
36 use Koha::EDI qw( process_quote process_invoice process_ordrsp);
37 use Koha::Edifact::Transport;
38 use Fcntl qw( :DEFAULT :flock :seek );
39
40 my $logdir = C4::Context->config('logdir');
41
42 # logging set to trace as this may be what you
43 # want on implementation
44 Log::Log4perl->easy_init(
45     {
46         level => $TRACE,
47         file  => ">>$logdir/editrace.log",
48     }
49 );
50
51 # we dont have a lock dir in context so use the logdir
52 my $pidfile = "$logdir/edicron.pid";
53
54 my $pid_handle = check_pidfile();
55
56 my $schema = Koha::Database->new()->schema();
57
58 my @edi_accts = $schema->resultset('VendorEdiAccount')->all();
59
60 my $logger = Log::Log4perl->get_logger();
61
62 for my $acct (@edi_accts) {
63     if ( $acct->quotes_enabled ) {
64         my $downloader = Koha::Edifact::Transport->new( $acct->id );
65         $downloader->download_messages('QUOTE');
66
67     }
68
69     if ( $acct->invoices_enabled ) {
70         my $downloader;
71
72         if ( $acct->plugin ) {
73             $downloader = Koha::Plugins::Handler->run(
74                 {
75                     class  => $acct->plugin,
76                     method => 'edifact_transport',
77                     params => {
78                         vendor_edi_account_id => $acct->id,
79                     }
80                 }
81             );
82         }
83
84         $downloader ||= Koha::Edifact::Transport->new( $acct->id );
85
86         $downloader->download_messages('INVOICE');
87
88     }
89     if ( $acct->orders_enabled ) {
90
91         # select pending messages
92         my @pending_orders = $schema->resultset('EdifactMessage')->search(
93             {
94                 message_type => 'ORDERS',
95                 vendor_id    => $acct->vendor_id,
96                 status       => 'Pending',
97             }
98         );
99         my $uploader = Koha::Edifact::Transport->new( $acct->id );
100         $uploader->upload_messages(@pending_orders);
101     }
102     if ( $acct->responses_enabled ) {
103         my $downloader = Koha::Edifact::Transport->new( $acct->id );
104         $downloader->download_messages('ORDRSP');
105     }
106 }
107
108 # process any downloaded quotes
109
110 my @downloaded_quotes = $schema->resultset('EdifactMessage')->search(
111     {
112         message_type => 'QUOTE',
113         status       => 'new',
114     }
115 )->all;
116
117 foreach my $quote_file (@downloaded_quotes) {
118     my $filename = $quote_file->filename;
119     $logger->trace("Processing quote $filename");
120     process_quote($quote_file);
121 }
122
123 # process any downloaded invoices
124
125 my @downloaded_invoices = $schema->resultset('EdifactMessage')->search(
126     {
127         message_type => 'INVOICE',
128         status       => 'new',
129     }
130 )->all;
131
132 foreach my $invoice (@downloaded_invoices) {
133     my $filename = $invoice->filename();
134     $logger->trace("Processing invoice $filename");
135
136     my $plugin_used = 0;
137     if ( my $plugin_class = $invoice->edi_acct->plugin ) {
138         my $plugin = $plugin_class->new();
139         if ( $plugin->can('edifact_process_invoice') ) {
140             $plugin_used = 1;
141             Koha::Plugins::Handler->run(
142                 {
143                     class  => $plugin_class,
144                     method => 'edifact_process_invoice',
145                     params => {
146                         invoice => $invoice,
147                     }
148                 }
149             );
150         }
151     }
152
153     process_invoice($invoice) unless $plugin_used;
154 }
155
156 my @downloaded_responses = $schema->resultset('EdifactMessage')->search(
157     {
158         message_type => 'ORDRSP',
159         status       => 'new',
160     }
161 )->all;
162
163 foreach my $response (@downloaded_responses) {
164     my $filename = $response->filename();
165     $logger->trace("Processing order response $filename");
166     process_ordrsp($response);
167 }
168
169 if ( close $pid_handle ) {
170     unlink $pidfile;
171     exit 0;
172 }
173 else {
174     $logger->error("Error on pidfile close: $!");
175     exit 1;
176 }
177
178 sub check_pidfile {
179
180     # sysopen my $fh, $pidfile, O_EXCL | O_RDWR or log_exit "$0 already running"
181     sysopen my $fh, $pidfile, O_RDWR | O_CREAT
182       or log_exit("$0: open $pidfile: $!");
183     flock $fh => LOCK_EX or log_exit("$0: flock $pidfile: $!");
184
185     sysseek $fh, 0, SEEK_SET or log_exit("$0: sysseek $pidfile: $!");
186     truncate $fh, 0 or log_exit("$0: truncate $pidfile: $!");
187     print $fh "$$\n" or log_exit("$0: print $pidfile: $!");
188
189     return $fh;
190 }
191
192 sub log_exit {
193     my $error = shift;
194     $logger->error($error);
195
196     exit 1;
197 }