Bug 7736: Support Ordering via Edifact EDI messages
[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 C4::Context;
33 use Log::Log4perl qw(:easy);
34 use Koha::Database;
35 use Koha::EDI qw( process_quote process_invoice process_ordrsp);
36 use Koha::Edifact::Transport;
37 use Fcntl qw( :DEFAULT :flock :seek );
38
39 my $logdir = C4::Context->logdir;
40
41 # logging set to trace as this may be what you
42 # want on implementation
43 Log::Log4perl->easy_init(
44     {
45         level => $TRACE,
46         file  => ">>$logdir/editrace.log",
47     }
48 );
49
50 # we dont have a lock dir in context so use the logdir
51 my $pidfile = "$logdir/edicron.pid";
52
53 my $pid_handle = check_pidfile();
54
55 my $schema = Koha::Database->new()->schema();
56
57 my @edi_accts = $schema->resultset('VendorEdiAccount')->all();
58
59 my $logger = Log::Log4perl->get_logger();
60
61 for my $acct (@edi_accts) {
62     if ( $acct->quotes_enabled ) {
63         my $downloader = Koha::Edifact::Transport->new( $acct->id );
64         $downloader->download_messages('QUOTE');
65
66     }
67
68     if ( $acct->invoices_enabled ) {
69         my $downloader = Koha::Edifact::Transport->new( $acct->id );
70         $downloader->download_messages('INVOICE');
71
72     }
73     if ( $acct->orders_enabled ) {
74
75         # select pending messages
76         my @pending_orders = $schema->resultset('EdifactMessage')->search(
77             {
78                 message_type => 'ORDERS',
79                 vendor_id    => $acct->vendor_id,
80                 status       => 'Pending',
81             }
82         );
83         my $uploader = Koha::Edifact::Transport->new( $acct->id );
84         $uploader->upload_messages(@pending_orders);
85     }
86     if ( $acct->responses_enabled ) {
87         my $downloader = Koha::Edifact::Transport->new( $acct->id );
88         $downloader->download_messages('ORDRSP');
89     }
90 }
91
92 # process any downloaded quotes
93
94 my @downloaded_quotes = $schema->resultset('EdifactMessage')->search(
95     {
96         message_type => 'QUOTE',
97         status       => 'new',
98     }
99 )->all;
100
101 foreach my $quote_file (@downloaded_quotes) {
102     my $filename = $quote_file->filename;
103     $logger->trace("Processing quote $filename");
104     process_quote($quote_file);
105 }
106
107 # process any downloaded invoices
108
109 my @downloaded_invoices = $schema->resultset('EdifactMessage')->search(
110     {
111         message_type => 'INVOICE',
112         status       => 'new',
113     }
114 )->all;
115
116 foreach my $invoice (@downloaded_invoices) {
117     my $filename = $invoice->filename();
118     $logger->trace("Processing invoice $filename");
119     process_invoice($invoice);
120 }
121
122 my @downloaded_responses = $schema->resultset('EdifactMessage')->search(
123     {
124         message_type => 'ORDRSP',
125         status       => 'new',
126     }
127 )->all;
128
129 foreach my $response (@downloaded_responses) {
130     my $filename = $response->filename();
131     $logger->trace("Processing order response $filename");
132     process_ordrsp($response);
133 }
134
135 if ( close $pid_handle ) {
136     unlink $pidfile;
137     exit 0;
138 }
139 else {
140     $logger->error("Error on pidfile close: $!");
141     exit 1;
142 }
143
144 sub check_pidfile {
145
146     # sysopen my $fh, $pidfile, O_EXCL | O_RDWR or log_exit "$0 already running"
147     sysopen my $fh, $pidfile, O_RDWR | O_CREAT
148       or log_exit("$0: open $pidfile: $!");
149     flock $fh => LOCK_EX or log_exit("$0: flock $pidfile: $!");
150
151     sysseek $fh, 0, SEEK_SET or log_exit("$0: sysseek $pidfile: $!");
152     truncate $fh, 0 or log_exit("$0: truncate $pidfile: $!");
153     print $fh "$$\n" or log_exit("$0: print $pidfile: $!");
154
155     return $fh;
156 }
157
158 sub log_exit {
159     my $error = shift;
160     $logger->error($error);
161
162     exit 1;
163 }