3 # Copyright 2014,2015 PTFS-Europe Ltd
5 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
24 use Encode
qw( from_to );
25 use Koha
::Edifact
::Segment
;
26 use Koha
::Edifact
::Message
;
38 my ( $class, $param_hashref ) = @_;
42 if ( $param_hashref->{filename} ) {
43 if ( $param_hashref->{transmission} ) {
45 "Cannot instantiate $class : both filename and transmission passed";
48 $transmission = read_file( $param_hashref->{filename} );
51 $transmission = $param_hashref->{transmission};
53 $self->{transmission} = _init($transmission);
59 sub interchange_header {
60 my ( $self, $field ) = @_;
66 interchange_control_reference => 4,
67 application_reference => 6,
69 if ( !exists $element{$field} ) {
70 carp "No interchange header field $field available";
73 my $data = $self->{transmission}->[0]->elem( $element{$field} );
77 sub interchange_trailer {
78 my ( $self, $field ) = @_;
79 my $trailer = $self->{transmission}->[-1];
80 if ( $field eq 'interchange_control_count' ) {
81 return $trailer->elem(0);
83 elsif ( $field eq 'interchange_control_reference' ) {
84 return $trailer->elem(1);
86 carp "Trailer field $field not recognized";
90 sub new_data_iterator {
93 while ( $self->{transmission}->[$offset]->tag() ne 'UNH' ) {
95 if ( $offset == @{ $self->{transmission} } ) {
96 carp 'Cannot find message start';
100 $self->{data_iterator} = $offset;
106 if ( defined $self->{data_iterator} ) {
107 my $seg = $self->{transmission}->[ $self->{data_iterator} ];
108 if ( $seg->tag eq 'UNH' ) {
110 $self->{msg_type} = $seg->elem( 1, 0 );
112 elsif ( $seg->tag eq 'LIN' ) {
113 $self->{msg_type} = 'detail';
116 if ( $seg->tag ne 'UNZ' ) {
117 $self->{data_iterator}++;
120 $self->{data_iterator} = undef;
127 # for debugging return whole transmission
128 sub get_transmission {
131 return $self->{transmission};
136 return $self->{msg_type};
144 if ( $msg =~ s/^UNA(.{6})// ) {
145 if ( service_string_advice($1) ) {
146 return segmentize($msg);
152 my $s = substr $msg, 10;
153 croak "File does not start with a Service string advice :$s";
157 # return an array of Message objects
161 # return an array of array_refs 1 ref to a message
165 foreach my $seg ( @{ $self->{transmission} } ) {
166 if ( $seg->tag eq 'UNH' ) {
170 elsif ( $seg->tag eq 'UNT' ) {
173 push @{$msg_arr}, Koha::Edifact::Message->new($msg);
185 # internal parsing routines used in _init
187 sub service_string_advice {
190 # At present this just validates that the ssa
191 # is standard Edifact
192 # TBD reset the seps if non standard
193 if ( $ssa ne q{:+.? '} ) {
194 carp
" Non standard Service String Advice [$ssa]";
198 # else use default separators
205 # In practice edifact uses latin-1 but check
206 # Transport now converts to utf-8 on ingest
207 # Do not convert here
208 #my $char_set = 'iso-8859-1';
209 #if ( $raw =~ m/^UNB[+]UNO(.)/ ) {
210 # $char_set = msgcharset($1);
212 #from_to( $raw, $char_set, 'utf8' );
215 (?
> # dont backtrack into this group
216 [?
]. # either the escape character
217 # followed by any other character
219 [^'?] # a character that is neither escape
224 while ( $raw =~ /($re)/g ) {
225 push @segmented, Koha::Edifact::Segment->new( { seg_string => $1 } );
232 if ( $code =~ m/^[^ABCDEF]$/ ) {
242 default => 'iso
-8859-1',
244 return $encoding_map{$code};
252 Edifact - Edifact message handler
256 Koha module for parsing Edifact messages
262 my $e = Koha::Edifact->new( { filename => 'myfilename
' } );
264 my $e = Koha::Edifact->new( { transmission => $msg_variable } );
266 instantiate the Edifact parser, requires either to be passed an in-memory
267 edifact message as transmission or a filename which it will read on creation
269 =head2 interchange_header
271 will return the data in the header field designated by the parameter
272 specified. Valid parameters are: 'sender
', 'recipient
', 'datetime
',
273 'interchange_control_reference
', and 'application_reference
'
275 =head2 interchange_trailer
277 called either with the string 'interchange_control_count
' or
278 'interchange_control_reference
' will return the corresponding field from
279 the interchange trailer
281 =head2 new_data_iterator
283 Sets the object's data_iterator to point to the UNH segment
287 Returns the next segment pointed to by the data_iterator. Increments the
288 data_iterator member or destroys it if segment UNZ has been reached
290 =head2 get_transmission
292 This method is useful in debugg:ing. Call on an Edifact object
293 it returns the object's transmission member
297 return the object's message type
301 return an array of Message objects contained in the Edifact transmission
303 =head1 Internal Methods
307 Called by the constructor to do the parsing of the transmission
309 =head2 service_string_advice
311 Examines the Service String Advice returns 1 if the default separartors are in use
316 takes a raw Edifact message and returns a reference to an array of
321 Return the character set the message was encoded in. The default is iso-8859-1
323 We preserve this info but will have converted to utf-8 on ingest
327 Colin Campbell <colin.campbell@ptfs-europe.com>
332 Copyright 2014,2015, PTFS-Europe Ltd
333 This program is free software, You may redistribute it under
334 under the terms of the GNU General Public License