]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/offline/offline-execute.pl
more work done
[working/Evergreen.git] / Open-ILS / src / offline / offline-execute.pl
1 #!/usr/bin/perl
2 use strict; use warnings;
3
4 # --------------------------------------------------------------------
5 # Loads the offline script files for a given org, sorts and runs the 
6 # scripts, and returns the exception list
7 # --------------------------------------------------------------------
8
9 our ($REQUESTOR, $META_FILE, $LOCK_FILE, $AUTHTOKEN, $U, %config, $cgi, $base_dir, $logger, $ORG);
10 my @data;
11 require 'offline-lib.pl';
12
13 my $evt = $U->check_perms($REQUESTOR->id, $ORG, 'OFFLINE_EXECUTE');
14 handle_event($evt) if $evt;
15
16 my $resp = &process_data( &sort_data( &collect_data() ) );
17 &archive_files();
18 handle_event(OpenILS::Event->new('SUCCESS', payload => $resp));
19
20
21
22 # --------------------------------------------------------------------
23 # Collects all of the script logs into an in-memory structure that
24 # can be sorted, etc.
25 # Returns a blob like -> { $ws1 => [ commands... ], $ws2 => [ commands... ] }
26 # --------------------------------------------------------------------
27 sub collect_data {
28
29         handle_event(OpenILS::Event->new('OFFLINE_PARAM_ERROR')) unless $ORG;
30         my $dir = get_pending_dir();
31         handle_event(OpenILS::Event->new('OFFLINE_SESSION_ACTIVE')) if (-e "$dir/$LOCK_FILE");
32
33         # Lock the pending directory
34         system(("touch",  "$dir/$LOCK_FILE")) == 0 
35                 or handle_event(OpenILS::Event->new('OFFLINE_FILE_ERROR'));
36
37         my $file;
38         my %data;
39
40         # Load the data from the list of files
41         while( ($file = <$dir/*.log>) ) {
42                 $logger->debug("offline: Loading script file $file");
43                 open(F, $file) or handle_event(
44                         OpenILS::Event->new('OFFLINE_FILE_ERROR'));
45                 my $ws = log_to_wsname($file);
46                 $data{$ws} = [];
47                 push(@{$data{$ws}}, , <F>);
48         }
49
50         return \%data;
51 }
52
53
54 # --------------------------------------------------------------------
55 # Sorts the commands
56 # --------------------------------------------------------------------
57 sub sort_data {
58         my $data = shift;
59         my @parsed;
60
61         $logger->debug("offline: Sorting data");
62         my $meta = read_meta();
63         
64         # cycle through the workstations
65         for my $ws (keys %$data) {
66
67                 # find the meta line for this ws.
68                 my ($m) = grep { $_->{workstation} eq $ws } @$meta;
69                 
70                 $logger->debug("offline: Sorting workstations $ws with a time delta of ".$m->{delta});
71
72                 my @scripts = @{$$data{$ws}};
73
74                 # cycle through the scripts for the current workstation
75                 for my $s (@scripts) {
76                         my $command = JSON->JSON2perl($s);
77                         $command->{_workstation} = $ws;
78                         $command->{_realtime} = $command->{timestamp} + $m->{delta};
79                         $logger->debug("offline: setting realtime to ".
80                                 $command->{_realtime} . " from timestamp " . $command->{timestamp});
81                         push( @parsed, $command );
82
83                 }
84         }
85
86         @parsed = sort { $a->{_realtime} <=> $b->{_realtime} } @parsed;
87         return \@parsed;
88 }
89
90
91 # --------------------------------------------------------------------
92 # Runs the commands and returns the list of errors
93 # --------------------------------------------------------------------
94 sub process_data {
95         my $data = shift;
96         my @resp;
97
98         for my $d (@$data) {
99                 my $t = $d->{type};
100
101                 push( @resp, {command => $d, event => handle_checkin($d)})      if( $t eq 'checkin' );
102                 push( @resp, {command => $d, event => handle_inhouse($d)})      if( $t eq 'in_house_use' );
103                 push( @resp, {command => $d, event => handle_checkout($d)})     if( $t eq 'checkout' );
104                 push( @resp, {command => $d, event => handle_renew($d)})                if( $t eq 'renew' );
105                 push( @resp, {command => $d, event => handle_register($d)})     if( $t eq 'register' );
106         }
107         return \@resp;
108 }
109
110
111 # --------------------------------------------------------------------
112 # Runs a checkin action
113 # --------------------------------------------------------------------
114 sub handle_checkin {
115
116         my $command             = shift;
117         my $realtime    = $command->{_realtime};
118         my $ws                  = $command->{_workstation};
119         my $barcode             = $command->{barcode};
120         my $backdate    = $command->{backdate} || "";
121
122         $logger->activity("offline: checkin : requestor=". $REQUESTOR->id.
123                 ", realtime=$realtime, ".  "workstation=$ws, barcode=$barcode, backdate=$backdate");
124
125         return $U->simplereq(
126                 'open-ils.circ', 
127                 'open-ils.circ.checkin', $AUTHTOKEN,
128                 { barcode => $barcode, backdate => $backdate } );
129 }
130
131
132 # --------------------------------------------------------------------
133 # Runs an in_house_use action
134 # --------------------------------------------------------------------
135 sub handle_inhouse {
136
137         my $command             = shift;
138         my $realtime    = $command->{_realtime};
139         my $ws                  = $command->{_workstation};
140         my $barcode             = $command->{barcode};
141         my $count               = $command->{count} || 1;
142
143         $logger->activity("offline: in_house_use : requestor=". $REQUESTOR->id.
144                 ", realtime=$realtime, ".  "workstation=$ws, barcode=$barcode, count=$count");
145
146         my( $copy, $evt ) = $U->fetch_copy_by_barcode($barcode);
147         return $evt if $evt;
148
149         my $ids = $U->simplereq(
150                 'open-ils.circ', 
151                 'open-ils.circ.in_house_use.create', $AUTHTOKEN,
152                 { copyid => $copy->id, count => $count, location =>  $ORG} );
153         
154         return OpenILS::Event->new('SUCCESS', payload => $ids) if( ref($ids) eq 'ARRAY' );
155         return $ids;
156 }
157
158
159
160 sub handle_checkout {
161         my $command = shift;
162         return OpenILS::Event->new('SUCCESS', payload => $command);
163 }
164
165
166 sub handle_renew {
167         my $command = shift;
168         return OpenILS::Event->new('SUCCESS', payload => $command);
169 }
170
171
172 sub handle_register {
173         my $command = shift;
174         return OpenILS::Event->new('SUCCESS', payload => $command);
175 }
176
177
178
179 # --------------------------------------------------------------------
180 # Removes the log file and Moves the script files from the pending 
181 # directory to the archive dir
182 # --------------------------------------------------------------------
183 sub archive_files {
184         my $archivedir = create_archive_dir();
185         my $pendingdir = get_pending_dir();
186         my @files = <$pendingdir/*.log>;
187         push(@files, <$pendingdir/$META_FILE>);
188
189         $logger->debug("offline: Archiving files to $archivedir...");
190         system( ("rm", "$pendingdir/$LOCK_FILE") ) == 0 
191                 or handle_event(OpenILS::Event->new('OFFLINE_FILE_ERROR'));
192
193         return unless (<$pendingdir/*>);
194
195         for my $f (@files) {
196                 system( ("mv", "$f", "$archivedir") ) == 0 
197                         or handle_event(OpenILS::Event->new('OFFLINE_FILE_ERROR'));
198         }
199
200         system( ("rmdir", "$pendingdir") ) == 0 
201                 or handle_event(OpenILS::Event->new('OFFLINE_FILE_ERROR'));
202 }
203
204