3 # This file is part of Koha.
5 # Copyright (C) 2012-2013 ByWater Solutions
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>.
26 use C4
::SIP
::Sip
::Constants
qw(:all);
29 use constant
{ LANGUAGE
=> '001' };
40 my $patron_identifier;
47 my $fee_acknowledged = 0;
62 "a|address|host|hostaddress=s" => \
$host, # sip server ip
63 "p|port=s" => \
$port, # sip server port
64 "su|sip_user=s" => \
$login_user_id, # sip user
65 "sp|sip_pass=s" => \
$login_password, # sip password
66 "l|location|location_code=s" => \
$location_code, # sip location code
68 "patron=s" => \
$patron_identifier, # patron cardnumber or login
69 "password=s" => \
$patron_password, # patron's password
71 "i|item=s" => \
$item_identifier,
73 "fa|fee-acknowledged" => \
$fee_acknowledged,
75 "s|summary=s" => \
$summary,
77 "fee-type=s" => \
$fee_type,
78 "payment-type=s" => \
$payment_type,
79 "currency-type=s" => \
$currency_type,
80 "fee-amount=s" => \
$fee_amount,
81 "fee-identifier=s" => \
$fee_identifier,
82 "transaction-id=s" => \
$transaction_id,
83 "pickup-location=s" => \
$pickup_location,
85 "t|terminator=s" => \
$terminator,
87 "m|message=s" => \
@messages,
102 $terminator = ( $terminator eq 'CR' ) ?
$CR : $CRLF;
104 # Set perl to expect the same record terminator it is sending
107 my $transaction_date = C4
::SIP
::Sip
::timestamp
();
109 my $terminal_password = $login_password;
112 print "Attempting socket connection to $host:$port...";
114 my $socket = IO
::Socket
::INET
->new("$host:$port")
115 or die "failed! : $!\n";
121 subroutine
=> \
&build_login_command_message
,
123 login_user_id
=> $login_user_id,
124 login_password
=> $login_password,
125 location_code
=> $location_code,
128 patron_status_request
=> {
129 name
=> 'Patron Status Request',
130 subroutine
=> \
&build_patron_status_request_command_message
,
132 transaction_date
=> $transaction_date,
133 institution_id
=> $location_code,
134 patron_identifier
=> $patron_identifier,
135 terminal_password
=> $terminal_password,
136 patron_password
=> $patron_password,
138 optional
=> [ 'patron_password', ],
140 patron_information
=> {
141 name
=> 'Patron Information',
142 subroutine
=> \
&build_patron_information_command_message
,
144 transaction_date
=> $transaction_date,
145 institution_id
=> $location_code,
146 patron_identifier
=> $patron_identifier,
147 terminal_password
=> $terminal_password,
148 patron_password
=> $patron_password,
151 optional
=> [ 'patron_password', 'summary' ],
153 item_information
=> {
154 name
=> 'Item Information',
155 subroutine
=> \
&build_item_information_command_message
,
157 transaction_date
=> $transaction_date,
158 institution_id
=> $location_code,
159 item_identifier
=> $item_identifier,
160 terminal_password
=> $terminal_password,
166 subroutine
=> \
&build_checkout_command_message
,
168 SC_renewal_policy
=> 'Y',
170 transaction_date
=> $transaction_date,
171 nb_due_date
=> undef,
172 institution_id
=> $location_code,
173 patron_identifier
=> $patron_identifier,
174 item_identifier
=> $item_identifier,
175 terminal_password
=> $terminal_password,
176 item_properties
=> undef,
177 patron_password
=> $patron_password,
178 fee_acknowledged
=> $fee_acknowledged,
182 'nb_due_date', # defaults to transaction date
191 subroutine
=> \
&build_checkin_command_message
,
194 transaction_date
=> $transaction_date,
195 return_date
=> $transaction_date,
196 current_location
=> $location_code,
197 institution_id
=> $location_code,
198 item_identifier
=> $item_identifier,
199 terminal_password
=> $terminal_password,
200 item_properties
=> undef,
204 'return_date', # defaults to transaction date
212 subroutine
=> \
&build_renew_command_message
,
214 third_party_allowed
=> 'N',
216 transaction_date
=> $transaction_date,
217 nb_due_date
=> undef,
218 institution_id
=> $location_code,
219 patron_identifier
=> $patron_identifier,
220 patron_password
=> $patron_password,
221 item_identifier
=> $item_identifier,
222 title_identifier
=> undef,
223 terminal_password
=> $terminal_password,
224 item_properties
=> undef,
225 fee_acknowledged
=> $fee_acknowledged,
228 'nb_due_date', # defaults to transaction date
239 subroutine
=> \
&build_fee_paid_command_message
,
241 transaction_date
=> $transaction_date,
242 fee_type
=> $fee_type,
243 payment_type
=> $payment_type,
244 currency_type
=> $currency_type,
245 fee_amount
=> $fee_amount,
246 institution_id
=> $location_code,
247 patron_identifier
=> $patron_identifier,
248 terminal_password
=> $terminal_password,
249 patron_password
=> $patron_password,
250 fee_identifier
=> $fee_identifier,
251 transaction_id
=> $transaction_id,
254 'fee_type', # has default
255 'payment_type', # has default
256 'currency_type', #has default
265 subroutine
=> \
&build_hold_command_message
,
268 transaction_date
=> $transaction_date,
269 expiration_date
=> undef,
270 pickup_location
=> $pickup_location,
272 institution_id
=> $location_code,
273 patron_identifier
=> $patron_identifier,
274 patron_password
=> $patron_password,
275 item_identifier
=> $item_identifier,
276 title_identifier
=> undef,
277 terminal_password
=> $terminal_password,
278 fee_acknowledged
=> $fee_acknowledged,
293 my $data = run_command_message
('login');
295 if ( $data =~ '^941' ) { ## we are logged in
296 foreach my $m (@messages) {
299 my $data = run_command_message
($m);
307 sub build_command_message
{
310 ##FIXME It would be much better to use exception handling so we aren't priting from subs
311 unless ( $handlers->{$message} ) {
312 say "$message is an unsupported command!";
316 my $subroutine = $handlers->{$message}->{subroutine
};
317 my $parameters = $handlers->{$message}->{parameters
};
318 my %optional = map { $_ => 1 } @
{ $handlers->{$message}->{optional
} };
320 foreach my $key ( keys %$parameters ) {
321 unless ( $parameters->{$key} ) {
322 unless ( $optional{$key} ) {
323 say "$key is required for $message";
329 return &$subroutine($parameters);
332 sub run_command_message
{
335 my $command_message = build_command_message
($message);
337 return unless $command_message;
339 say "SEND: $command_message";
340 print $socket $command_message . $terminator;
342 my $data = <$socket>;
349 sub build_login_command_message
{
352 my $login_user_id = $params->{login_user_id
};
353 my $login_password = $params->{login_password
};
354 my $location_code = $params->{location_code
};
358 . build_field
( FID_LOGIN_UID
, $login_user_id )
359 . build_field
( FID_LOGIN_PWD
, $login_password )
360 . build_field
( FID_LOCATION_CODE
, $location_code );
363 sub build_patron_status_request_command_message
{
366 my $transaction_date = $params->{transaction_date
};
367 my $institution_id = $params->{institution_id
};
368 my $patron_identifier = $params->{patron_identifier
};
369 my $terminal_password = $params->{terminal_password
};
370 my $patron_password = $params->{patron_password
};
376 . build_field
( FID_INST_ID
, $institution_id )
377 . build_field
( FID_PATRON_ID
, $patron_identifier )
378 . build_field
( FID_TERMINAL_PWD
, $terminal_password )
379 . build_field
( FID_PATRON_PWD
, $patron_password );
382 sub build_patron_information_command_message
{
385 my $transaction_date = $params->{transaction_date
};
386 my $institution_id = $params->{institution_id
};
387 my $patron_identifier = $params->{patron_identifier
};
388 my $terminal_password = $params->{terminal_password
};
389 my $patron_password = $params->{patron_password
};
390 my $summary = $params->{summary
};
399 . build_field
( FID_INST_ID
, $institution_id )
400 . build_field
( FID_PATRON_ID
, $patron_identifier )
401 . build_field
( FID_TERMINAL_PWD
, $terminal_password )
402 . build_field
( FID_PATRON_PWD
, $patron_password, { optional
=> 1 } );
405 sub build_item_information_command_message
{
408 my $transaction_date = $params->{transaction_date
};
409 my $institution_id = $params->{institution_id
};
410 my $item_identifier = $params->{item_identifier
};
411 my $terminal_password = $params->{terminal_password
};
417 . build_field
( FID_INST_ID
, $institution_id )
418 . build_field
( FID_ITEM_ID
, $item_identifier )
419 . build_field
( FID_TERMINAL_PWD
, $terminal_password );
422 sub build_checkout_command_message
{
425 my $SC_renewal_policy = $params->{SC_renewal_policy
} || 'N';
426 my $no_block = $params->{no_block
} || 'N';
427 my $transaction_date = $params->{transaction_date
};
428 my $nb_due_date = $params->{nb_due_date
};
429 my $institution_id = $params->{institution_id
};
430 my $patron_identifier = $params->{patron_identifier
};
431 my $item_identifier = $params->{item_identifier
};
432 my $terminal_password = $params->{terminal_password
};
433 my $item_properties = $params->{item_properties
};
434 my $patron_password = $params->{patron_password
};
435 my $fee_acknowledged = $params->{fee_acknowledged
} || 'N';
436 my $cancel = $params->{cancel
} || 'N';
438 $SC_renewal_policy = $SC_renewal_policy eq 'Y' ?
'Y' : 'N';
439 $no_block = $no_block eq 'Y' ?
'Y' : 'N';
440 $fee_acknowledged = $fee_acknowledged eq 'Y' ?
'Y' : 'N';
441 $cancel = $cancel eq 'Y' ?
'Y' : 'N';
443 $nb_due_date ||= $transaction_date;
451 . build_field
( FID_INST_ID
, $institution_id )
452 . build_field
( FID_PATRON_ID
, $patron_identifier )
453 . build_field
( FID_ITEM_ID
, $item_identifier )
454 . build_field
( FID_TERMINAL_PWD
, $terminal_password )
455 . build_field
( FID_ITEM_PROPS
, $item_properties, { optional
=> 1 } )
456 . build_field
( FID_PATRON_PWD
, $patron_password, { optional
=> 1 } )
457 . build_field
( FID_FEE_ACK
, $fee_acknowledged, { optional
=> 1 } )
458 . build_field
( FID_CANCEL
, $cancel, { optional
=> 1 } );
461 sub build_checkin_command_message
{
464 my $no_block = $params->{no_block
} || 'N';
465 my $transaction_date = $params->{transaction_date
};
466 my $return_date = $params->{return_date
};
467 my $current_location = $params->{current_location
};
468 my $institution_id = $params->{institution_id
};
469 my $item_identifier = $params->{item_identifier
};
470 my $terminal_password = $params->{terminal_password
};
471 my $item_properties = $params->{item_properties
};
472 my $cancel = $params->{cancel
} || 'N';
474 $no_block = $no_block eq 'Y' ?
'Y' : 'N';
475 $cancel = $cancel eq 'Y' ?
'Y' : 'N';
477 $return_date ||= $transaction_date;
484 . build_field
( FID_CURRENT_LOCN
, $current_location )
485 . build_field
( FID_INST_ID
, $institution_id )
486 . build_field
( FID_ITEM_ID
, $item_identifier )
487 . build_field
( FID_TERMINAL_PWD
, $terminal_password )
488 . build_field
( FID_ITEM_PROPS
, $item_properties, { optional
=> 1 } )
489 . build_field
( FID_CANCEL
, $cancel, { optional
=> 1 } );
492 sub build_hold_command_message
{
495 my $hold_mode = $params->{hold_mode
} || '+';
496 my $transaction_date = $params->{transaction_date
};
497 my $expiration_date = $params->{expiration_date
};
498 my $pickup_location = $params->{pickup_location
};
499 my $hold_type = $params->{hold_type
};
500 my $institution_id = $params->{institution_id
};
501 my $patron_identifier = $params->{patron_identifier
};
502 my $patron_password = $params->{patron_password
};
503 my $item_identifier = $params->{item_identifier
};
504 my $title_identifier = $params->{title_identifier
};
505 my $terminal_password = $params->{terminal_password
};
506 my $fee_acknowledged = $params->{fee_acknowledged
} || 'N';
512 . build_field
( FID_EXPIRATION
, $expiration_date, { optional
=> 1 } )
513 . build_field
( FID_PICKUP_LOCN
, $pickup_location, { optional
=> 1 } )
514 . build_field
( FID_HOLD_TYPE
, $hold_type, { optional
=> 1 } )
515 . build_field
( FID_INST_ID
, $institution_id )
516 . build_field
( FID_PATRON_ID
, $patron_identifier )
517 . build_field
( FID_PATRON_PWD
, $patron_password, { optional
=> 1 } )
518 . build_field
( FID_ITEM_ID
, $item_identifier, { optional
=> 1 } )
519 . build_field
( FID_TITLE_ID
, $title_identifier, { optional
=> 1 } )
520 . build_field
( FID_TERMINAL_PWD
, $terminal_password, { optional
=> 1 } )
521 . build_field
( FID_FEE_ACK
, $fee_acknowledged, { optional
=> 1 } );
524 sub build_renew_command_message
{
527 my $third_party_allowed = $params->{third_party_allowed
} || 'N';
528 my $no_block = $params->{no_block
} || 'N';
529 my $transaction_date = $params->{transaction_date
};
530 my $nb_due_date = $params->{nb_due_date
};
531 my $institution_id = $params->{institution_id
};
532 my $patron_identifier = $params->{patron_identifier
};
533 my $patron_password = $params->{patron_password
};
534 my $item_identifier = $params->{item_identifier
};
535 my $title_identifier = $params->{title_identifier
};
536 my $terminal_password = $params->{terminal_password
};
537 my $item_properties = $params->{item_properties
};
538 my $fee_acknowledged = $params->{fee_acknowledged
} || 'N';
540 $third_party_allowed = $third_party_allowed eq 'Y' ?
'Y' : 'N';
541 $no_block = $no_block eq 'Y' ?
'Y' : 'N';
542 $fee_acknowledged = $fee_acknowledged eq 'Y' ?
'Y' : 'N';
544 $nb_due_date ||= $transaction_date;
548 . $third_party_allowed
552 . build_field
( FID_INST_ID
, $institution_id )
553 . build_field
( FID_PATRON_ID
, $patron_identifier )
554 . build_field
( FID_PATRON_PWD
, $patron_password, { optional
=> 1 } )
555 . build_field
( FID_ITEM_ID
, $item_identifier )
556 . build_field
( FID_TITLE_ID
, $title_identifier )
557 . build_field
( FID_TERMINAL_PWD
, $terminal_password )
558 . build_field
( FID_ITEM_PROPS
, $item_properties, { optional
=> 1 } )
559 . build_field
( FID_FEE_ACK
, $fee_acknowledged, { optional
=> 1 } );
562 sub build_fee_paid_command_message
{
565 my $transaction_date = $params->{transaction_date
};
566 my $fee_type = $params->{fee_type
} || '01';
567 my $payment_type = $params->{payment_type
} || '00';
568 my $currency_type = $params->{currency_type
} || 'USD';
569 my $fee_amount = $params->{fee_amount
};
570 my $institution_id = $params->{location_code
};
571 my $patron_identifier = $params->{patron_identifier
};
572 my $terminal_password = $params->{terminal_password
};
573 my $patron_password = $params->{patron_password
};
574 my $fee_identifier = $params->{fee_identifier
};
575 my $transaction_id = $params->{transaction_id
};
583 . build_field
( FID_FEE_AMT
, $fee_amount )
584 . build_field
( FID_INST_ID
, $institution_id )
585 . build_field
( FID_PATRON_ID
, $patron_identifier )
586 . build_field
( FID_TERMINAL_PWD
, $terminal_password, { optional
=> 1 } )
587 . build_field
( FID_PATRON_PWD
, $patron_password, { optional
=> 1 } )
588 . build_field
( FID_FEE_ID
, $fee_identifier, { optional
=> 1 } )
589 . build_field
( FID_TRANSACTION_ID
, $transaction_id, { optional
=> 1 } );
593 my ( $field_identifier, $value, $params ) = @_;
597 return q{} if ( $params->{optional
} && !$value );
599 return $field_identifier . (($value) ?
$value : '') . '|';
603 say q
/sip_cli_emulator
.pl
- SIP command line emulator
605 Test a SIP2 service by sending patron status
and patron
606 information requests
.
609 sip_cli_emulator
.pl
[OPTIONS
]
612 --help display help message
614 -a
--address SIP server ip address
or host name
615 -p
--port SIP server port
617 -su
--sip_user SIP server login username
618 -sp
--sip_pass SIP server login password
620 -l
--location SIP location code
622 --patron ILS patron cardnumber
or username
623 --password ILS patron password
625 -s
--summary Optionally define the patron information request summary field
.
626 Please refer to the SIP2 protocol specification
for details
628 --item ILS item identifier
( item barcode
)
630 -t
--terminator SIP2 message terminator
, either CR
, or CRLF
633 -fa
--fee
-acknowledged Sends a confirmation of checkout fee
635 --fee
-type Fee type
for Fee Paid message
, defaults to
'01'
636 --payment
-type Payment type
for Fee Paid message
, default to
'00'
637 --currency
-type Currency type
for Fee Paid message
, defaults to
'USD'
638 --fee
-amount Fee amount
for Fee Paid message
, required
639 --fee
-identifier Fee identifier
for Fee Paid message
, optional
640 --transaction
-id Transaction id
for Fee Paid message
, optional
641 --pickup
-location Pickup location
(branchcode
) for Hold message
, optional
643 -m
--message SIP2 message to execute
645 Implemented Messages
:
652 patron_status_request