Kyle M Hall
5788a0f262
The SIP circulation status specifies that a 12 means an item is lost, and 13 means an item is missing. In Koha, missing items are simply a type of lost item so we never send a 13. This is an important distinction for some SIP based inventory tools. It would be good to be able to specify when lost status means "missing" at the SIP login level. Test Plan: 1) Apply this patch 2) prove t/db_dependent/SIP/Transaction.t Signed-off-by: David Nind <david@davidnind.com> Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de> Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
1317 lines
46 KiB
Perl
Executable file
1317 lines
46 KiB
Perl
Executable file
#!/usr/bin/perl
|
|
|
|
# Tests for SIP::ILS::Transaction
|
|
# Current state is very rudimentary. Please help to extend it!
|
|
|
|
use Modern::Perl;
|
|
use Test::More tests => 18;
|
|
use Test::Warn;
|
|
|
|
use Koha::Database;
|
|
use t::lib::TestBuilder;
|
|
use t::lib::Mocks;
|
|
use C4::SIP::ILS;
|
|
use C4::SIP::ILS::Patron;
|
|
use C4::SIP::ILS::Transaction::RenewAll;
|
|
use C4::SIP::ILS::Transaction::Checkout;
|
|
use C4::SIP::ILS::Transaction::FeePayment;
|
|
use C4::SIP::ILS::Transaction::Hold;
|
|
use C4::SIP::ILS::Transaction::Checkout;
|
|
use C4::SIP::ILS::Transaction::Checkin;
|
|
|
|
use C4::Reserves qw( AddReserve ModReserve ModReserveAffect RevertWaitingStatus );
|
|
use Koha::CirculationRules;
|
|
use Koha::Item::Transfer;
|
|
use Koha::DateUtils qw( dt_from_string output_pref );
|
|
use Koha::Recalls;
|
|
|
|
my $schema = Koha::Database->new->schema;
|
|
$schema->storage->txn_begin;
|
|
|
|
my $builder = t::lib::TestBuilder->new();
|
|
my $borr1 = $builder->build( { source => 'Borrower' } );
|
|
my $card = $borr1->{cardnumber};
|
|
my $sip_patron = C4::SIP::ILS::Patron->new($card);
|
|
|
|
# Create transaction RenewAll, assign patron, and run (no items)
|
|
my $transaction = C4::SIP::ILS::Transaction::RenewAll->new();
|
|
is( ref $transaction, "C4::SIP::ILS::Transaction::RenewAll", "New transaction created" );
|
|
is( $transaction->patron($sip_patron), $sip_patron, "Patron assigned to transaction" );
|
|
isnt( $transaction->do_renew_all, undef, "RenewAll on zero items" );
|
|
|
|
subtest fill_holds_at_checkout => sub {
|
|
plan tests => 6;
|
|
|
|
my $category = $builder->build( { source => 'Category', value => { category_type => 'A' } } );
|
|
my $branch = $builder->build( { source => 'Branch' } );
|
|
my $borrower = $builder->build(
|
|
{
|
|
source => 'Borrower',
|
|
value => {
|
|
branchcode => $branch->{branchcode},
|
|
categorycode => $category->{categorycode}
|
|
}
|
|
}
|
|
);
|
|
t::lib::Mocks::mock_userenv( { branchcode => $branch->{branchcode}, flags => 1 } );
|
|
|
|
my $itype = $builder->build( { source => 'Itemtype', value => { notforloan => 0 } } );
|
|
my $item1 = $builder->build_sample_item(
|
|
{
|
|
barcode => 'barcode4test',
|
|
homebranch => $branch->{branchcode},
|
|
holdingbranch => $branch->{branchcode},
|
|
itype => $itype->{itemtype},
|
|
notforloan => 0,
|
|
}
|
|
)->unblessed;
|
|
my $item2 = $builder->build_sample_item(
|
|
{
|
|
homebranch => $branch->{branchcode},
|
|
holdingbranch => $branch->{branchcode},
|
|
biblionumber => $item1->{biblionumber},
|
|
itype => $itype->{itemtype},
|
|
notforloan => 0,
|
|
}
|
|
)->unblessed;
|
|
|
|
Koha::CirculationRules->set_rules(
|
|
{
|
|
categorycode => $borrower->{categorycode},
|
|
branchcode => $branch->{branchcode},
|
|
itemtype => $itype->{itemtype},
|
|
rules => {
|
|
onshelfholds => 1,
|
|
reservesallowed => 3,
|
|
holds_per_record => 3,
|
|
issuelength => 5,
|
|
lengthunit => 'days',
|
|
}
|
|
}
|
|
);
|
|
|
|
my $reserve1 = AddReserve(
|
|
{
|
|
branchcode => $branch->{branchcode},
|
|
borrowernumber => $borrower->{borrowernumber},
|
|
biblionumber => $item1->{biblionumber}
|
|
}
|
|
);
|
|
my $reserve2 = AddReserve(
|
|
{
|
|
branchcode => $branch->{branchcode},
|
|
borrowernumber => $borrower->{borrowernumber},
|
|
biblionumber => $item1->{biblionumber}
|
|
}
|
|
);
|
|
|
|
my $bib = Koha::Biblios->find( $item1->{biblionumber} );
|
|
is( $bib->holds->count(), 2, "Bib has 2 holds" );
|
|
|
|
my $sip_patron = C4::SIP::ILS::Patron->new( $borrower->{cardnumber} );
|
|
my $sip_item = C4::SIP::ILS::Item->new( $item1->{barcode} );
|
|
my $transaction = C4::SIP::ILS::Transaction::Checkout->new();
|
|
is( ref $transaction, "C4::SIP::ILS::Transaction::Checkout", "New transaction created" );
|
|
is( $transaction->patron($sip_patron), $sip_patron, "Patron assigned to transaction" );
|
|
is( $transaction->item($sip_item), $sip_item, "Item assigned to transaction" );
|
|
my $checkout = $transaction->do_checkout();
|
|
use Data::Dumper; # Temporary debug statement
|
|
is( $bib->holds->count(), 1, "Bib has 1 holds remaining" ) or diag Dumper $checkout;
|
|
|
|
t::lib::Mocks::mock_preference( 'itemBarcodeInputFilter', 'whitespace' );
|
|
$sip_item = C4::SIP::ILS::Item->new(' barcode 4 test ');
|
|
$transaction = C4::SIP::ILS::Transaction::Checkout->new();
|
|
is( $sip_item->{barcode}, $item1->{barcode}, "Item assigned to transaction" );
|
|
};
|
|
|
|
subtest "FeePayment->pay tests" => sub {
|
|
|
|
plan tests => 5;
|
|
|
|
# Create a borrower and add some outstanding debts to their account
|
|
my $patron = $builder->build( { source => 'Borrower' } );
|
|
my $account =
|
|
Koha::Account->new( { patron_id => $patron->{borrowernumber} } );
|
|
my $debt1 = $account->add_debit( { type => 'ACCOUNT', amount => 100, interface => 'commandline' } );
|
|
my $debt2 = $account->add_debit( { type => 'ACCOUNT', amount => 200, interface => 'commandline' } );
|
|
|
|
# Instantiate a new FeePayment transaction object
|
|
my $trans = C4::SIP::ILS::Transaction::FeePayment->new();
|
|
is(
|
|
ref $trans,
|
|
"C4::SIP::ILS::Transaction::FeePayment",
|
|
"New fee transaction created"
|
|
);
|
|
|
|
# Test the 'pay' method
|
|
# FIXME: pay should not require a borrowernumber
|
|
# (we should reach out to the transaction which should contain a patron object)
|
|
my $pay_type = '00'; # 00 - Cash, 01 - VISA, 02 - Creditcard
|
|
my $ok = $trans->pay(
|
|
$patron->{borrowernumber}, 100, $pay_type, $debt1->id, 0,
|
|
0
|
|
);
|
|
ok( $ok, "FeePayment transaction succeeded" );
|
|
$debt1->discard_changes;
|
|
is(
|
|
$debt1->amountoutstanding + 0, 0,
|
|
"Debt1 was reduced to 0 as expected"
|
|
);
|
|
my $offsets = Koha::Account::Offsets->search( { debit_id => $debt1->id, credit_id => { '!=' => undef } } );
|
|
is( $offsets->count, 1, "FeePayment produced an offset line correctly" );
|
|
my $credit = $offsets->next->credit;
|
|
is( $credit->payment_type, 'SIP00', "Payment type was set correctly" );
|
|
};
|
|
|
|
subtest cancel_hold => sub {
|
|
plan tests => 7;
|
|
|
|
my $library = $builder->build_object( { class => 'Koha::Libraries' } );
|
|
my $patron = $builder->build_object(
|
|
{
|
|
class => 'Koha::Patrons',
|
|
value => {
|
|
branchcode => $library->branchcode,
|
|
}
|
|
}
|
|
);
|
|
t::lib::Mocks::mock_userenv( { branchcode => $library->branchcode, flags => 1 } );
|
|
|
|
my $item = $builder->build_sample_item(
|
|
{
|
|
library => $library->branchcode,
|
|
}
|
|
);
|
|
|
|
Koha::CirculationRules->set_rules(
|
|
{
|
|
categorycode => $patron->categorycode,
|
|
branchcode => $library->branchcode,
|
|
itemtype => $item->effective_itemtype,
|
|
rules => {
|
|
onshelfholds => 1,
|
|
reservesallowed => 3,
|
|
holds_per_record => 3,
|
|
issuelength => 5,
|
|
lengthunit => 'days',
|
|
}
|
|
}
|
|
);
|
|
|
|
my $reserve1 = AddReserve(
|
|
{
|
|
branchcode => $library->branchcode,
|
|
borrowernumber => $patron->borrowernumber,
|
|
biblionumber => $item->biblio->biblionumber,
|
|
itemnumber => $item->itemnumber,
|
|
}
|
|
);
|
|
is( $item->biblio->holds->count(), 1, "Hold was placed on bib" );
|
|
is( $item->holds->count(), 1, "Hold was placed on specific item" );
|
|
|
|
my $sip_patron = C4::SIP::ILS::Patron->new( $patron->cardnumber );
|
|
my $sip_item = C4::SIP::ILS::Item->new( $item->barcode );
|
|
my $transaction = C4::SIP::ILS::Transaction::Hold->new();
|
|
is( ref $transaction, "C4::SIP::ILS::Transaction::Hold", "New transaction created" );
|
|
is( $transaction->patron($sip_patron), $sip_patron, "Patron assigned to transaction" );
|
|
is( $transaction->item($sip_item), $sip_item, "Item assigned to transaction" );
|
|
my $hold = $transaction->drop_hold();
|
|
is( $item->biblio->holds->count(), 0, "Bib has 0 holds remaining" );
|
|
is( $item->holds->count(), 0, "Item has 0 holds remaining" );
|
|
};
|
|
|
|
subtest do_hold => sub {
|
|
plan tests => 8;
|
|
|
|
my $library = $builder->build_object(
|
|
{
|
|
class => 'Koha::Libraries',
|
|
value => { pickup_location => 1 }
|
|
}
|
|
);
|
|
my $patron_1 = $builder->build_object(
|
|
{
|
|
class => 'Koha::Patrons',
|
|
value => {
|
|
branchcode => $library->branchcode,
|
|
}
|
|
}
|
|
);
|
|
my $patron_2 = $builder->build_object(
|
|
{
|
|
class => 'Koha::Patrons',
|
|
value => {
|
|
branchcode => $library->branchcode,
|
|
categorycode => $patron_1->categorycode,
|
|
}
|
|
}
|
|
);
|
|
|
|
t::lib::Mocks::mock_userenv( { branchcode => $library->branchcode, flags => 1 } );
|
|
|
|
my $item = $builder->build_sample_item(
|
|
{
|
|
library => $library->branchcode,
|
|
}
|
|
);
|
|
|
|
my $reserve1 = AddReserve(
|
|
{
|
|
branchcode => $library->branchcode,
|
|
borrowernumber => $patron_1->borrowernumber,
|
|
biblionumber => $item->biblio->biblionumber,
|
|
itemnumber => $item->itemnumber,
|
|
}
|
|
);
|
|
is( $item->biblio->holds->count(), 1, "Hold was placed on bib" );
|
|
is( $item->holds->count(), 1, "Hold was placed on specific item" );
|
|
|
|
my $sip_patron = C4::SIP::ILS::Patron->new( $patron_2->cardnumber );
|
|
my $sip_item = C4::SIP::ILS::Item->new( $item->barcode );
|
|
my $transaction = C4::SIP::ILS::Transaction::Hold->new();
|
|
is(
|
|
ref $transaction,
|
|
"C4::SIP::ILS::Transaction::Hold",
|
|
"New transaction created"
|
|
);
|
|
is(
|
|
$transaction->patron($sip_patron),
|
|
$sip_patron, "Patron assigned to transaction"
|
|
);
|
|
is(
|
|
$transaction->item($sip_item),
|
|
$sip_item, "Item assigned to transaction"
|
|
);
|
|
my $hold = $transaction->do_hold();
|
|
is( $item->biblio->holds->count(), 2, "Bib has 2 holds" );
|
|
|
|
my $THE_hold = $patron_2->holds->next;
|
|
is( $THE_hold->priority, 2, 'Hold placed from SIP should have a correct priority of 2' );
|
|
is( $THE_hold->branchcode, $patron_2->branchcode, 'Hold placed from SIP should have the branchcode set' );
|
|
};
|
|
|
|
subtest "Placing holds via SIP check CanItemBeReserved" => sub {
|
|
plan tests => 4;
|
|
|
|
my $library = $builder->build_object(
|
|
{
|
|
class => 'Koha::Libraries',
|
|
value => { pickup_location => 0 }
|
|
}
|
|
);
|
|
my $patron_1 = $builder->build_object(
|
|
{
|
|
class => 'Koha::Patrons',
|
|
value => {
|
|
branchcode => $library->branchcode,
|
|
}
|
|
}
|
|
);
|
|
my $patron_2 = $builder->build_object(
|
|
{
|
|
class => 'Koha::Patrons',
|
|
value => {
|
|
branchcode => $library->branchcode,
|
|
categorycode => $patron_1->categorycode,
|
|
}
|
|
}
|
|
);
|
|
|
|
t::lib::Mocks::mock_userenv( { branchcode => $library->branchcode, flags => 1 } );
|
|
|
|
my $item = $builder->build_sample_item(
|
|
{
|
|
library => $library->branchcode,
|
|
}
|
|
);
|
|
|
|
my $sip_patron = C4::SIP::ILS::Patron->new( $patron_2->cardnumber );
|
|
my $sip_item = C4::SIP::ILS::Item->new( $item->barcode );
|
|
my $transaction = C4::SIP::ILS::Transaction::Hold->new();
|
|
is(
|
|
ref $transaction,
|
|
"C4::SIP::ILS::Transaction::Hold",
|
|
"New transaction created"
|
|
);
|
|
is(
|
|
$transaction->patron($sip_patron),
|
|
$sip_patron, "Patron assigned to transaction"
|
|
);
|
|
is(
|
|
$transaction->item($sip_item),
|
|
$sip_item, "Item assigned to transaction"
|
|
);
|
|
my $hold = $transaction->do_hold();
|
|
|
|
is( $transaction->ok, 0, "Hold was not allowed" );
|
|
};
|
|
|
|
subtest do_checkin => sub {
|
|
plan tests => 14;
|
|
|
|
my $mockILS = Test::MockObject->new;
|
|
my $server = { ils => $mockILS };
|
|
my $library = $builder->build_object( { class => 'Koha::Libraries' } );
|
|
my $library2 = $builder->build_object( { class => 'Koha::Libraries' } );
|
|
my $patron = $builder->build_object(
|
|
{
|
|
class => 'Koha::Patrons',
|
|
value => {
|
|
branchcode => $library->branchcode,
|
|
}
|
|
}
|
|
);
|
|
|
|
t::lib::Mocks::mock_userenv( { branchcode => $library->branchcode, flags => 1 } );
|
|
|
|
my $item = $builder->build_sample_item(
|
|
{
|
|
library => $library->branchcode,
|
|
}
|
|
);
|
|
|
|
# Checkout
|
|
my $sip_patron = C4::SIP::ILS::Patron->new( $patron->cardnumber );
|
|
my $sip_item = C4::SIP::ILS::Item->new( $item->barcode );
|
|
my $co_transaction = C4::SIP::ILS::Transaction::Checkout->new();
|
|
is(
|
|
$co_transaction->patron($sip_patron),
|
|
$sip_patron, "Patron assigned to transaction"
|
|
);
|
|
is(
|
|
$co_transaction->item($sip_item),
|
|
$sip_item, "Item assigned to transaction"
|
|
);
|
|
my $checkout = $co_transaction->do_checkout();
|
|
is( $patron->checkouts->count, 1, 'Checkout should have been done successfully' );
|
|
|
|
# Checkin
|
|
my $ci_transaction = C4::SIP::ILS::Transaction::Checkin->new();
|
|
is(
|
|
$ci_transaction->patron($sip_patron),
|
|
$sip_patron, "Patron assigned to transaction"
|
|
);
|
|
is(
|
|
$ci_transaction->item($sip_item),
|
|
$sip_item, "Item assigned to transaction"
|
|
);
|
|
|
|
my $checkin = $ci_transaction->do_checkin( $library->branchcode, C4::SIP::Sip::timestamp );
|
|
is( $patron->checkouts->count, 0, 'Checkin should have been done successfully' );
|
|
|
|
# Test checkin without return date
|
|
$co_transaction->do_checkout;
|
|
is( $patron->checkouts->count, 1, 'Checkout should have been done successfully' );
|
|
$ci_transaction->do_checkin( $library->branchcode, undef );
|
|
is( $patron->checkouts->count, 0, 'Checkin should have been done successfully' );
|
|
|
|
my $result = $ci_transaction->do_checkin( $library2->branchcode, undef );
|
|
is( $ci_transaction->alert_type, '04', "Checkin of item no issued at another branch succeeds" );
|
|
is_deeply(
|
|
$result,
|
|
{
|
|
messages => {
|
|
'NotIssued' => $item->barcode,
|
|
'WasTransfered' => $library->branchcode,
|
|
'TransferTrigger' => 'ReturnToHome'
|
|
}
|
|
},
|
|
"Messages show not issued and transferred"
|
|
);
|
|
is( $ci_transaction->item->destination_loc, $library->branchcode, "Item destination correctly set" );
|
|
|
|
subtest 'Checkin an in transit item' => sub {
|
|
|
|
plan tests => 5;
|
|
|
|
my $library_1 = $builder->build_object( { class => 'Koha::Libraries' } );
|
|
my $library_2 = $builder->build_object( { class => 'Koha::Libraries' } );
|
|
|
|
my $patron =
|
|
$builder->build_object( { class => 'Koha::Patrons', value => { branchcode => $library_1->branchcode, } } );
|
|
my $sip_patron = C4::SIP::ILS::Patron->new( $patron->cardnumber );
|
|
my $item = $builder->build_sample_item( { library => $library_1->branchcode } );
|
|
my $sip_item = C4::SIP::ILS::Item->new( $item->barcode );
|
|
|
|
t::lib::Mocks::mock_userenv( { branchcode => $library_1->branchcode, flags => 1 } );
|
|
|
|
my $reserve = AddReserve(
|
|
{
|
|
branchcode => $library_1->branchcode,
|
|
borrowernumber => $patron->borrowernumber,
|
|
biblionumber => $item->biblionumber,
|
|
}
|
|
);
|
|
|
|
ModReserveAffect( $item->itemnumber, $patron->borrowernumber ); # Mark waiting
|
|
|
|
my $ci_transaction = C4::SIP::ILS::Transaction::Checkin->new();
|
|
is(
|
|
$ci_transaction->patron($sip_patron),
|
|
$sip_patron, "Patron assigned to transaction"
|
|
);
|
|
is(
|
|
$ci_transaction->item($sip_item),
|
|
$sip_item, "Item assigned to transaction"
|
|
);
|
|
|
|
my $checkin = $ci_transaction->do_checkin( $library_2->branchcode, C4::SIP::Sip::timestamp );
|
|
|
|
my $hold = Koha::Holds->find($reserve);
|
|
is( $hold->found, 'T', );
|
|
is( $hold->itemnumber, $item->itemnumber, );
|
|
is( Koha::Checkouts->search( { itemnumber => $item->itemnumber } )->count, 0, );
|
|
};
|
|
|
|
subtest 'Checkin message' => sub {
|
|
plan tests => 3;
|
|
my $mockILS = Test::MockObject->new;
|
|
my $server = { ils => $mockILS };
|
|
my $library = $builder->build_object( { class => 'Koha::Libraries' } );
|
|
my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
|
|
my $homebranch = $builder->build(
|
|
{
|
|
source => 'Branch',
|
|
value => {
|
|
branchcode => 'HMBR',
|
|
branchname => 'Homebranch'
|
|
}
|
|
}
|
|
);
|
|
|
|
my $institution = {
|
|
id => $library->id,
|
|
implementation => "ILS",
|
|
policy => {
|
|
checkin => "true",
|
|
renewal => "true",
|
|
checkout => "true",
|
|
timeout => 100,
|
|
retries => 5,
|
|
}
|
|
};
|
|
my $ils = C4::SIP::ILS->new($institution);
|
|
my $item = $builder->build_sample_item(
|
|
{
|
|
library => $library->branchcode,
|
|
homebranch => $homebranch->{'branchcode'},
|
|
location => 'My Location',
|
|
permanent_location => 'My Permanent Location',
|
|
}
|
|
);
|
|
my $circ = $ils->checkout( $patron->cardnumber, $item->barcode, undef, undef, $server->{account} );
|
|
$circ = $ils->checkin(
|
|
$item->barcode, C4::SIP::Sip::timestamp, undef, $library->branchcode, undef, undef,
|
|
$server->{account}
|
|
);
|
|
is( $circ->{screen_msg}, '', "Checkin message is not displayed when show_checkin_message is disabled" );
|
|
|
|
$server->{account}->{show_checkin_message} = 1;
|
|
|
|
$circ = $ils->checkout( $patron->cardnumber, $item->barcode, undef, undef, $server->{account} );
|
|
$circ = $ils->checkin(
|
|
$item->barcode, C4::SIP::Sip::timestamp, undef, $library->branchcode, undef, undef,
|
|
$server->{account}
|
|
);
|
|
is(
|
|
$circ->{screen_msg}, 'Item checked-in: Homebranch - My Location.',
|
|
"Checkin message when show_checkin_message is enabled and UseLocationAsAQInSIP is disabled"
|
|
);
|
|
|
|
t::lib::Mocks::mock_preference( 'UseLocationAsAQInSIP', '1' );
|
|
|
|
$circ = $ils->checkout( $patron->cardnumber, $item->barcode, undef, undef, $server->{account} );
|
|
$circ = $ils->checkin(
|
|
$item->barcode, C4::SIP::Sip::timestamp, undef, $library->branchcode, undef, undef,
|
|
$server->{account}
|
|
);
|
|
is(
|
|
$circ->{screen_msg}, 'Item checked-in: My Permanent Location - My Location.',
|
|
"Checkin message when both show_checkin_message and UseLocationAsAQInSIP are enabled"
|
|
);
|
|
|
|
};
|
|
|
|
subtest 'Checkin with fines' => sub {
|
|
plan tests => 2;
|
|
|
|
my $mockILS = Test::MockObject->new;
|
|
my $server = { ils => $mockILS };
|
|
my $library = $builder->build_object( { class => 'Koha::Libraries' } );
|
|
my $institution = {
|
|
id => $library->id,
|
|
implementation => "ILS",
|
|
policy => {
|
|
checkin => "true",
|
|
renewal => "true",
|
|
checkout => "true",
|
|
timeout => 100,
|
|
retries => 5,
|
|
}
|
|
};
|
|
my $ils = C4::SIP::ILS->new($institution);
|
|
my $item = $builder->build_sample_item(
|
|
{
|
|
library => $library->branchcode,
|
|
}
|
|
);
|
|
|
|
# show_outstanding_amount disabled
|
|
my $patron = $builder->build_object(
|
|
{
|
|
class => 'Koha::Patrons',
|
|
value => {
|
|
branchcode => $library->branchcode,
|
|
}
|
|
}
|
|
);
|
|
my $circ = $ils->checkout( $patron->cardnumber, $item->barcode, undef, undef, $server->{account} );
|
|
my $fee1 = $builder->build(
|
|
{
|
|
source => 'Accountline',
|
|
value => {
|
|
borrowernumber => $patron->borrowernumber,
|
|
amountoutstanding => 12,
|
|
debit_type_code => 'OVERDUE',
|
|
itemnumber => $item->itemnumber
|
|
}
|
|
}
|
|
);
|
|
$circ = $ils->checkin(
|
|
$item->barcode, C4::SIP::Sip::timestamp, undef, $library->branchcode, undef, undef,
|
|
$server->{account}
|
|
);
|
|
is( $circ->{screen_msg}, '', "The fine is not displayed on checkin when show_outstanding_amount is disabled" );
|
|
|
|
# show_outstanding_amount enabled
|
|
$patron = $builder->build_object(
|
|
{
|
|
class => 'Koha::Patrons',
|
|
value => {
|
|
branchcode => $library->branchcode,
|
|
}
|
|
}
|
|
);
|
|
$circ = $ils->checkout( $patron->cardnumber, $item->barcode, undef, undef, $server->{account} );
|
|
|
|
$fee1 = $builder->build(
|
|
{
|
|
source => 'Accountline',
|
|
value => {
|
|
borrowernumber => $patron->borrowernumber,
|
|
amountoutstanding => 12,
|
|
debit_type_code => 'OVERDUE',
|
|
itemnumber => $item->itemnumber
|
|
}
|
|
}
|
|
);
|
|
|
|
$server->{account}->{show_outstanding_amount} = 1;
|
|
$circ = $ils->checkout( $patron->cardnumber, $item->barcode, undef, undef, $server->{account} );
|
|
|
|
$circ = $ils->checkin(
|
|
$item->barcode, C4::SIP::Sip::timestamp, undef, $library->branchcode, undef, undef,
|
|
$server->{account}
|
|
);
|
|
is(
|
|
$circ->{screen_msg}, 'You owe $12.00 for this item.',
|
|
"The fine is displayed on checkin when show_outstanding_amount is enabled"
|
|
);
|
|
|
|
};
|
|
};
|
|
|
|
subtest do_checkout_with_sysprefs_override => sub {
|
|
plan tests => 8;
|
|
|
|
my $mockILS = Test::MockObject->new;
|
|
my $server = { ils => $mockILS };
|
|
my $library = $builder->build_object( { class => 'Koha::Libraries' } );
|
|
my $institution = {
|
|
id => $library->id,
|
|
implementation => "ILS",
|
|
policy => {
|
|
checkin => "true",
|
|
renewal => "true",
|
|
checkout => "true",
|
|
timeout => 100,
|
|
retries => 5,
|
|
}
|
|
};
|
|
my $ils = C4::SIP::ILS->new($institution);
|
|
my $item = $builder->build_sample_item(
|
|
{
|
|
library => $library->branchcode,
|
|
}
|
|
);
|
|
|
|
my $patron_under_noissuescharge = $builder->build_object(
|
|
{
|
|
class => 'Koha::Patrons',
|
|
value => {
|
|
branchcode => $library->branchcode,
|
|
}
|
|
}
|
|
);
|
|
|
|
my $fee_under_noissuescharge = $builder->build(
|
|
{
|
|
source => 'Accountline',
|
|
value => {
|
|
borrowernumber => $patron_under_noissuescharge->borrowernumber,
|
|
amountoutstanding => 4,
|
|
debit_type_code => 'OVERDUE',
|
|
}
|
|
}
|
|
);
|
|
|
|
my $patron_over_noissuescharge = $builder->build_object(
|
|
|
|
{
|
|
class => 'Koha::Patrons',
|
|
value => {
|
|
branchcode => $library->branchcode,
|
|
}
|
|
}
|
|
);
|
|
|
|
my $fee_over_noissuescharge = $builder->build(
|
|
{
|
|
source => 'Accountline',
|
|
value => {
|
|
borrowernumber => $patron_over_noissuescharge->borrowernumber,
|
|
amountoutstanding => 6,
|
|
debit_type_code => 'OVERDUE',
|
|
}
|
|
}
|
|
);
|
|
|
|
$server->{account}->{override_fine_on_checkout} = 0;
|
|
|
|
t::lib::Mocks::mock_preference( 'AllFinesNeedOverride', '0' );
|
|
t::lib::Mocks::mock_preference( 'AllowFineOverride', '0' );
|
|
my $circ =
|
|
$ils->checkout( $patron_under_noissuescharge->cardnumber, $item->barcode, undef, undef, $server->{account} );
|
|
is(
|
|
$patron_under_noissuescharge->checkouts->count, 1,
|
|
'Checkout is allowed when the amount is under noissuecharge, AllFinesNeedOverride and AllowFineOverride disabled'
|
|
);
|
|
|
|
$circ = $ils->checkin( $item->barcode, C4::SIP::Sip::timestamp, undef, $library->branchcode );
|
|
|
|
$circ = $ils->checkout( $patron_over_noissuescharge->cardnumber, $item->barcode, undef, undef, $server->{account} );
|
|
is(
|
|
$patron_over_noissuescharge->checkouts->count, 0,
|
|
'Checkout is blocked when the amount is over noissuecharge, AllFinesNeedOverride and AllowFineOverride disabled'
|
|
);
|
|
|
|
t::lib::Mocks::mock_preference( 'AllFinesNeedOverride', '0' );
|
|
t::lib::Mocks::mock_preference( 'AllowFineOverride', '1' );
|
|
|
|
$circ =
|
|
$ils->checkout( $patron_under_noissuescharge->cardnumber, $item->barcode, undef, undef, $server->{account} );
|
|
is(
|
|
$patron_under_noissuescharge->checkouts->count, 1,
|
|
'Checkout is allowed when the amount is under noissuecharge, AllFinesNeedOverride disabled and AllowFineOverride enabled'
|
|
);
|
|
|
|
$circ = $ils->checkin( $item->barcode, C4::SIP::Sip::timestamp, undef, $library->branchcode );
|
|
|
|
$circ = $ils->checkout( $patron_over_noissuescharge->cardnumber, $item->barcode, undef, undef, $server->{account} );
|
|
is(
|
|
$patron_over_noissuescharge->checkouts->count, 0,
|
|
'Checkout is blocked when the amount is over noissuecharge, AllFinesNeedOverride disabled and AllowFineOverride enabled'
|
|
);
|
|
|
|
t::lib::Mocks::mock_preference( 'AllFinesNeedOverride', '1' );
|
|
t::lib::Mocks::mock_preference( 'AllowFineOverride', '0' );
|
|
|
|
$circ =
|
|
$ils->checkout( $patron_under_noissuescharge->cardnumber, $item->barcode, undef, undef, $server->{account} );
|
|
is(
|
|
$patron_under_noissuescharge->checkouts->count, 0,
|
|
'Checkout is blocked when the amount is under noissuecharge, AllFinesNeedOverride enabled and AllowFineOverride disabled'
|
|
);
|
|
|
|
$circ = $ils->checkout( $patron_over_noissuescharge->cardnumber, $item->barcode, undef, undef, $server->{account} );
|
|
is(
|
|
$patron_over_noissuescharge->checkouts->count, 0,
|
|
'Checkout is blocked when the amount is over noissuecharge, AllFinesNeedOverride enabled and AllowFineOverride disabled'
|
|
);
|
|
|
|
t::lib::Mocks::mock_preference( 'AllFinesNeedOverride', '1' );
|
|
t::lib::Mocks::mock_preference( 'AllowFineOverride', '1' );
|
|
|
|
$circ =
|
|
$ils->checkout( $patron_under_noissuescharge->cardnumber, $item->barcode, undef, undef, $server->{account} );
|
|
is(
|
|
$patron_under_noissuescharge->checkouts->count, 0,
|
|
'Checkout is blocked when the amount is under noissuecharge, AllFinesNeedOverride and AllowFineOverride enabled'
|
|
);
|
|
|
|
$circ = $ils->checkout( $patron_over_noissuescharge->cardnumber, $item->barcode, undef, undef, $server->{account} );
|
|
is(
|
|
$patron_over_noissuescharge->checkouts->count, 0,
|
|
'Checkout is blocked when the amount is over noissuecharge, AllFinesNeedOverride and AllowFineOverride enabled'
|
|
);
|
|
};
|
|
|
|
subtest do_checkout_with_patron_blocked => sub {
|
|
plan tests => 5;
|
|
|
|
my $mockILS = Test::MockObject->new;
|
|
my $server = { ils => $mockILS };
|
|
my $library = $builder->build_object( { class => 'Koha::Libraries' } );
|
|
my $institution = {
|
|
id => $library->id,
|
|
implementation => "ILS",
|
|
policy => {
|
|
checkin => "true",
|
|
renewal => "true",
|
|
checkout => "true",
|
|
timeout => 100,
|
|
retries => 5,
|
|
}
|
|
};
|
|
my $ils = C4::SIP::ILS->new($institution);
|
|
my $item = $builder->build_sample_item(
|
|
{
|
|
library => $library->branchcode,
|
|
}
|
|
);
|
|
|
|
my $expired_patron = $builder->build_object(
|
|
{
|
|
class => 'Koha::Patrons',
|
|
value => {
|
|
branchcode => $library->branchcode,
|
|
dateexpiry => '2020/01/03',
|
|
}
|
|
}
|
|
);
|
|
my $circ = $ils->checkout( $expired_patron->cardnumber, $item->barcode );
|
|
is( $circ->{screen_msg}, 'Patron expired on 01/03/2020', "Got correct expired screen message" );
|
|
|
|
my $fines_patron = $builder->build_object(
|
|
{
|
|
class => 'Koha::Patrons',
|
|
value => {
|
|
branchcode => $library->branchcode,
|
|
}
|
|
}
|
|
);
|
|
my $fee1 = $builder->build(
|
|
{
|
|
source => 'Accountline',
|
|
value => {
|
|
borrowernumber => $fines_patron->borrowernumber,
|
|
amountoutstanding => 10,
|
|
debit_type_code => 'OVERDUE',
|
|
}
|
|
}
|
|
);
|
|
|
|
my $fines_sip_patron = C4::SIP::ILS::Patron->new( $fines_patron->cardnumber );
|
|
|
|
$circ = $ils->checkout( $fines_patron->cardnumber, $item->barcode, undef, undef, $server->{account} );
|
|
is( $circ->{screen_msg}, 'Patron has fines', "Got correct fines screen message" );
|
|
|
|
$server->{account}->{show_outstanding_amount} = 1;
|
|
$circ = $ils->checkout( $fines_patron->cardnumber, $item->barcode, undef, undef, $server->{account} );
|
|
is( $circ->{screen_msg}, 'Patron has fines - You owe $10.00.', "Got correct fines with amount screen message" );
|
|
my $debarred_patron = $builder->build_object(
|
|
{
|
|
class => 'Koha::Patrons',
|
|
value => {
|
|
branchcode => $library->branchcode,
|
|
debarred => '9999/01/01',
|
|
}
|
|
}
|
|
);
|
|
my $debarred_sip_patron = C4::SIP::ILS::Patron->new( $debarred_patron->cardnumber );
|
|
$circ = $ils->checkout( $debarred_patron->cardnumber, $item->barcode );
|
|
is( $circ->{screen_msg}, 'Patron debarred', "Got correct debarred screen message" );
|
|
|
|
my $overdue_patron = $builder->build_object(
|
|
{
|
|
class => 'Koha::Patrons',
|
|
value => {
|
|
branchcode => $library->branchcode,
|
|
}
|
|
}
|
|
);
|
|
|
|
my $odue = $builder->build(
|
|
{
|
|
source => 'Issue',
|
|
value => {
|
|
borrowernumber => $overdue_patron->borrowernumber,
|
|
date_due => '2017-01-01',
|
|
}
|
|
}
|
|
);
|
|
t::lib::Mocks::mock_preference( 'OverduesBlockCirc', 'block' );
|
|
my $overdue_sip_patron = C4::SIP::ILS::Patron->new( $overdue_patron->cardnumber );
|
|
$circ = $ils->checkout( $overdue_patron->cardnumber, $item->barcode );
|
|
is( $circ->{screen_msg}, 'Patron blocked', "Got correct blocked screen message" );
|
|
|
|
};
|
|
|
|
subtest do_checkout_with_noblock => sub {
|
|
plan tests => 3;
|
|
|
|
my $library = $builder->build_object( { class => 'Koha::Libraries' } );
|
|
my $patron = $builder->build_object(
|
|
{
|
|
class => 'Koha::Patrons',
|
|
value => {
|
|
branchcode => $library->branchcode,
|
|
debarred => '9999/01/01',
|
|
},
|
|
}
|
|
);
|
|
|
|
t::lib::Mocks::mock_userenv( { branchcode => $library->branchcode, flags => 1 } );
|
|
|
|
my $item = $builder->build_sample_item(
|
|
{
|
|
library => $library->branchcode,
|
|
}
|
|
);
|
|
|
|
my $sip_patron = C4::SIP::ILS::Patron->new( $patron->cardnumber );
|
|
my $sip_item = C4::SIP::ILS::Item->new( $item->barcode );
|
|
my $co_transaction = C4::SIP::ILS::Transaction::Checkout->new();
|
|
is(
|
|
$co_transaction->patron($sip_patron),
|
|
$sip_patron, "Patron assigned to transaction"
|
|
);
|
|
is(
|
|
$co_transaction->item($sip_item),
|
|
$sip_item, "Item assigned to transaction"
|
|
);
|
|
|
|
$co_transaction->do_checkout( undef, '19990102 030405' );
|
|
|
|
is( $patron->checkouts->count, 1, 'No Block checkout was performed for debarred patron' );
|
|
};
|
|
|
|
subtest do_checkout_with_holds => sub {
|
|
plan tests => 7;
|
|
|
|
my $library = $builder->build_object( { class => 'Koha::Libraries' } );
|
|
my $patron = $builder->build_object(
|
|
{
|
|
class => 'Koha::Patrons',
|
|
value => {
|
|
branchcode => $library->branchcode,
|
|
}
|
|
}
|
|
);
|
|
my $patron2 = $builder->build_object(
|
|
{
|
|
class => 'Koha::Patrons',
|
|
value => {
|
|
branchcode => $library->branchcode,
|
|
}
|
|
}
|
|
);
|
|
|
|
t::lib::Mocks::mock_userenv( { branchcode => $library->branchcode, flags => 1 } );
|
|
|
|
my $item = $builder->build_sample_item(
|
|
{
|
|
library => $library->branchcode,
|
|
}
|
|
);
|
|
|
|
my $reserve = AddReserve(
|
|
{
|
|
branchcode => $library->branchcode,
|
|
borrowernumber => $patron2->borrowernumber,
|
|
biblionumber => $item->biblionumber,
|
|
}
|
|
);
|
|
|
|
my $sip_patron = C4::SIP::ILS::Patron->new( $patron->cardnumber );
|
|
my $sip_item = C4::SIP::ILS::Item->new( $item->barcode );
|
|
my $co_transaction = C4::SIP::ILS::Transaction::Checkout->new();
|
|
is(
|
|
$co_transaction->patron($sip_patron),
|
|
$sip_patron, "Patron assigned to transaction"
|
|
);
|
|
is(
|
|
$co_transaction->item($sip_item),
|
|
$sip_item, "Item assigned to transaction"
|
|
);
|
|
|
|
# Test attached holds
|
|
ModReserveAffect( $item->itemnumber, $patron->borrowernumber, 0, $reserve ); # Mark waiting (W)
|
|
my $hold = Koha::Holds->find($reserve);
|
|
$co_transaction->do_checkout();
|
|
is( $patron->checkouts->count, 0, 'Checkout was not done due to attached hold (W)' );
|
|
|
|
$hold->set_transfer;
|
|
$co_transaction->do_checkout();
|
|
is( $patron->checkouts->count, 0, 'Checkout was not done due to attached hold (T)' );
|
|
|
|
$hold->set_processing;
|
|
$co_transaction->do_checkout();
|
|
is( $patron->checkouts->count, 0, 'Checkout was not done due to attached hold (P)' );
|
|
|
|
# Test non-attached holds
|
|
C4::Reserves::RevertWaitingStatus( { itemnumber => $hold->itemnumber } );
|
|
t::lib::Mocks::mock_preference( 'AllowItemsOnHoldCheckoutSIP', '0' );
|
|
$co_transaction->do_checkout();
|
|
is( $patron->checkouts->count, 0, 'Checkout refused due to hold and AllowItemsOnHoldCheckoutSIP' );
|
|
|
|
t::lib::Mocks::mock_preference( 'AllowItemsOnHoldCheckoutSIP', '1' );
|
|
$co_transaction->do_checkout();
|
|
is( $patron->checkouts->count, 1, 'Checkout allowed due to hold and AllowItemsOnHoldCheckoutSIP' );
|
|
};
|
|
|
|
subtest checkin_lost => sub {
|
|
plan tests => 2;
|
|
|
|
my $library = $builder->build_object( { class => 'Koha::Libraries' } );
|
|
|
|
t::lib::Mocks::mock_userenv( { branchcode => $library->branchcode, flags => 1 } );
|
|
|
|
my $item = $builder->build_sample_item(
|
|
{
|
|
library => $library->branchcode,
|
|
}
|
|
);
|
|
|
|
$item->itemlost(1)->itemlost_on(dt_from_string)->store();
|
|
|
|
my $instituation = {
|
|
id => $library->id,
|
|
implementation => "ILS",
|
|
policy => {
|
|
checkin => "true",
|
|
renewal => "true",
|
|
checkout => "true",
|
|
timeout => 100,
|
|
retries => 5,
|
|
}
|
|
};
|
|
my $ils = C4::SIP::ILS->new($instituation);
|
|
|
|
t::lib::Mocks::mock_preference( 'BlockReturnOfLostItems', '1' );
|
|
my $circ = $ils->checkin( $item->barcode, C4::SIP::Sip::timestamp, undef, $library->branchcode );
|
|
is( $circ->{screen_msg}, 'Item lost, return not allowed', "Got correct screen message" );
|
|
|
|
t::lib::Mocks::mock_preference( 'BlockReturnOfLostItems', '0' );
|
|
$circ = $ils->checkin( $item->barcode, C4::SIP::Sip::timestamp, undef, $library->branchcode );
|
|
is( $circ->{screen_msg}, 'Item not checked out', "Got 'Item not checked out' screen message" );
|
|
};
|
|
|
|
subtest checkin_withdrawn => sub {
|
|
plan tests => 2;
|
|
|
|
my $library = $builder->build_object( { class => 'Koha::Libraries' } );
|
|
|
|
t::lib::Mocks::mock_userenv( { branchcode => $library->branchcode, flags => 1 } );
|
|
|
|
my $item = $builder->build_sample_item(
|
|
{
|
|
library => $library->branchcode,
|
|
}
|
|
);
|
|
|
|
$item->withdrawn(1)->withdrawn_on(dt_from_string)->store();
|
|
|
|
my $instituation = {
|
|
id => $library->id,
|
|
implementation => "ILS",
|
|
policy => {
|
|
checkin => "true",
|
|
renewal => "true",
|
|
checkout => "true",
|
|
timeout => 100,
|
|
retries => 5,
|
|
}
|
|
};
|
|
my $ils = C4::SIP::ILS->new($instituation);
|
|
|
|
t::lib::Mocks::mock_preference( 'BlockReturnOfWithdrawnItems', '1' );
|
|
my $circ = $ils->checkin( $item->barcode, C4::SIP::Sip::timestamp, undef, $library->branchcode );
|
|
is( $circ->{screen_msg}, 'Item withdrawn, return not allowed', "Got correct screen message" );
|
|
|
|
t::lib::Mocks::mock_preference( 'BlockReturnOfWithdrawnItems', '0' );
|
|
$circ = $ils->checkin( $item->barcode, C4::SIP::Sip::timestamp, undef, $library->branchcode );
|
|
is( $circ->{screen_msg}, 'Item not checked out', "Got 'Item not checked out' screen message" );
|
|
};
|
|
|
|
subtest _get_sort_bin => sub {
|
|
plan tests => 6;
|
|
|
|
my $library = $builder->build_object( { class => 'Koha::Libraries' } );
|
|
my $branch = $library->branchcode;
|
|
my $library2 = $builder->build_object( { class => 'Koha::Libraries' } );
|
|
my $branch2 = $library2->branchcode;
|
|
|
|
# Rules starts with malformed line, empty line and a comment to prove they are skipped
|
|
my $rules = <<"RULES";
|
|
$branch:homebranch:ne:\$holdingbranch:X\r
|
|
$branch:effective_itemtype:eq:CD:0\r
|
|
$branch:itemcallnumber:<:340:1\r
|
|
$branch:itemcallnumber:<:370:2\r
|
|
$branch:itemcallnumber:<:600:3\r
|
|
$branch2:homebranch:ne:\$holdingbranch:X\r
|
|
$branch2:effective_itemtype:eq:CD:4\r
|
|
$branch2:itemcallnumber:>:600:5\r
|
|
$branch2:effective_itemtype:eq:BOOK:ccode:eq:TEEN:6\r
|
|
# Comment line to skip\r
|
|
\r
|
|
$branch:homebranch:Z\r
|
|
RULES
|
|
|
|
t::lib::Mocks::mock_preference( 'SIP2SortBinMapping', $rules );
|
|
|
|
my $item_cd = $builder->build_sample_item(
|
|
{
|
|
library => $library->branchcode,
|
|
itype => 'CD'
|
|
}
|
|
);
|
|
|
|
my $item_book = $builder->build_sample_item(
|
|
{
|
|
library => $library->branchcode,
|
|
itype => 'BOOK',
|
|
itemcallnumber => '200.01'
|
|
}
|
|
);
|
|
|
|
my $item_book2 = $builder->build_sample_item(
|
|
{
|
|
library => $library2->branchcode,
|
|
itype => 'BOOK',
|
|
ccode => 'TEEN'
|
|
}
|
|
);
|
|
|
|
my $item_dvd = $builder->build_sample_item(
|
|
{
|
|
library => $library2->branchcode,
|
|
itype => 'DVD'
|
|
}
|
|
);
|
|
|
|
my $bin;
|
|
|
|
# Set holdingbranch as though item returned to library other than homebranch (As AddReturn would)
|
|
$item_cd->holdingbranch( $library2->branchcode )->store();
|
|
$bin = C4::SIP::ILS::Transaction::Checkin::_get_sort_bin( $item_cd, $library2->branchcode );
|
|
is( $bin, 'X', "Item parameter on RHS of comparison works (ne comparator)" );
|
|
|
|
# Reset holdingbranch as though item returned to home library
|
|
$item_cd->holdingbranch( $library->branchcode )->store();
|
|
$bin = C4::SIP::ILS::Transaction::Checkin::_get_sort_bin( $item_cd, $library->branchcode );
|
|
is( $bin, '0', "Fixed value on RHS of comparison works (eq comparator)" );
|
|
$bin = C4::SIP::ILS::Transaction::Checkin::_get_sort_bin( $item_book, $library->branchcode );
|
|
is( $bin, '1', "Rules applied in order (< comparator)" );
|
|
$item_book->itemcallnumber('350.20')->store();
|
|
$bin = C4::SIP::ILS::Transaction::Checkin::_get_sort_bin( $item_book, $library->branchcode );
|
|
is( $bin, '2', "Rules applied in order (< comparator)" );
|
|
|
|
$bin = C4::SIP::ILS::Transaction::Checkin::_get_sort_bin( $item_book2, $library2->branchcode );
|
|
is( $bin, '6', "Rules with multiple field matches" );
|
|
|
|
warnings_are { $bin = C4::SIP::ILS::Transaction::Checkin::_get_sort_bin( $item_dvd, $library2->branchcode ); }
|
|
["Malformed preference line found: '$branch:homebranch:Z'"],
|
|
"Comments and blank lines are skipped, Malformed lines are warned and skipped";
|
|
};
|
|
|
|
subtest item_circulation_status => sub {
|
|
plan tests => 8;
|
|
|
|
my $library = $builder->build_object( { class => 'Koha::Libraries' } );
|
|
my $library2 = $builder->build_object( { class => 'Koha::Libraries' } );
|
|
|
|
my $patron = $builder->build_object(
|
|
{
|
|
class => 'Koha::Patrons',
|
|
value => {
|
|
branchcode => $library->branchcode,
|
|
}
|
|
}
|
|
);
|
|
|
|
t::lib::Mocks::mock_userenv( { branchcode => $library->branchcode, flags => 1 } );
|
|
|
|
my $item = $builder->build_sample_item(
|
|
{
|
|
library => $library->branchcode,
|
|
}
|
|
);
|
|
|
|
my $sip_item = C4::SIP::ILS::Item->new( $item->barcode );
|
|
my $status = $sip_item->sip_circulation_status;
|
|
is( $status, '03', "Item circulation status is available" );
|
|
|
|
my $transfer = Koha::Item::Transfer->new(
|
|
{
|
|
itemnumber => $item->id,
|
|
datesent => '2020-01-01',
|
|
frombranch => $library->branchcode,
|
|
tobranch => $library2->branchcode,
|
|
}
|
|
)->store();
|
|
|
|
$sip_item = C4::SIP::ILS::Item->new( $item->barcode );
|
|
$status = $sip_item->sip_circulation_status;
|
|
is( $status, '10', "Item circulation status is in transit" );
|
|
|
|
$transfer->delete;
|
|
|
|
my $claim = Koha::Checkouts::ReturnClaim->new(
|
|
{
|
|
itemnumber => $item->id,
|
|
borrowernumber => $patron->id,
|
|
created_by => $patron->id,
|
|
}
|
|
)->store();
|
|
|
|
$sip_item = C4::SIP::ILS::Item->new( $item->barcode );
|
|
$status = $sip_item->sip_circulation_status;
|
|
is( $status, '11', "Item circulation status is claimed returned" );
|
|
|
|
$claim->delete;
|
|
|
|
$item->itemlost(1)->store();
|
|
$sip_item = C4::SIP::ILS::Item->new( $item->barcode );
|
|
$status = $sip_item->sip_circulation_status;
|
|
is( $status, '12', "Item circulation status is lost" );
|
|
$status = $sip_item->sip_circulation_status( { account => { missing_lost_status => "1" } } );
|
|
is( $status, '13', "Item circulation status is missing" );
|
|
$item->itemlost(0)->store();
|
|
|
|
my $location = $item->location;
|
|
$item->location("CART")->store();
|
|
$sip_item = C4::SIP::ILS::Item->new( $item->barcode );
|
|
$status = $sip_item->sip_circulation_status;
|
|
is( $status, '09', "Item circulation status is waiting to be re-shelved" );
|
|
$item->location($location)->store();
|
|
|
|
my $nfl = $item->notforloan;
|
|
$item->notforloan(-1)->store();
|
|
$sip_item = C4::SIP::ILS::Item->new( $item->barcode );
|
|
$status = $sip_item->sip_circulation_status;
|
|
is( $status, '02', "Item circulation status is on order" );
|
|
$item->notforloan($nfl)->store();
|
|
|
|
my $damaged = $item->damaged;
|
|
$item->damaged(1)->store();
|
|
$sip_item = C4::SIP::ILS::Item->new( $item->barcode );
|
|
$status = $sip_item->sip_circulation_status;
|
|
is( $status, '01', "Item circulation status is damaged" );
|
|
$item->damaged(0)->store();
|
|
};
|
|
|
|
subtest do_checkout_with_recalls => sub {
|
|
plan tests => 7;
|
|
|
|
my $library = $builder->build_object( { class => 'Koha::Libraries' } );
|
|
my $patron = $builder->build_object(
|
|
{
|
|
class => 'Koha::Patrons',
|
|
value => {
|
|
branchcode => $library->branchcode,
|
|
}
|
|
}
|
|
);
|
|
my $patron2 = $builder->build_object(
|
|
{
|
|
class => 'Koha::Patrons',
|
|
value => {
|
|
branchcode => $library->branchcode,
|
|
}
|
|
}
|
|
);
|
|
|
|
t::lib::Mocks::mock_userenv( { branchcode => $library->branchcode, flags => 1 } );
|
|
|
|
my $item = $builder->build_sample_item(
|
|
{
|
|
library => $library->branchcode,
|
|
}
|
|
);
|
|
|
|
t::lib::Mocks::mock_preference( 'UseRecalls', 1 );
|
|
Koha::CirculationRules->set_rule(
|
|
{
|
|
branchcode => undef,
|
|
categorycode => undef,
|
|
itemtype => undef,
|
|
rule_name => 'recalls_allowed',
|
|
rule_value => '10',
|
|
}
|
|
);
|
|
|
|
my $recall1 = Koha::Recall->new(
|
|
{
|
|
patron_id => $patron2->borrowernumber,
|
|
created_date => \'NOW()',
|
|
biblio_id => $item->biblio->biblionumber,
|
|
pickup_library_id => $library->branchcode,
|
|
item_id => $item->itemnumber,
|
|
expiration_date => undef,
|
|
item_level => 1
|
|
}
|
|
)->store;
|
|
|
|
my $sip_patron = C4::SIP::ILS::Patron->new( $patron->cardnumber );
|
|
my $sip_item = C4::SIP::ILS::Item->new( $item->barcode );
|
|
my $co_transaction = C4::SIP::ILS::Transaction::Checkout->new();
|
|
is(
|
|
$co_transaction->patron($sip_patron),
|
|
$sip_patron, "Patron assigned to transaction"
|
|
);
|
|
is(
|
|
$co_transaction->item($sip_item),
|
|
$sip_item, "Item assigned to transaction"
|
|
);
|
|
|
|
# Test recalls made by another patron
|
|
|
|
$recall1->set_waiting( { item => $item } );
|
|
$co_transaction->do_checkout();
|
|
is( $patron->checkouts->count, 0, 'Checkout was not done due to waiting recall' );
|
|
|
|
$recall1->revert_waiting;
|
|
$recall1->start_transfer( { item => $item } );
|
|
$co_transaction->do_checkout();
|
|
is( $patron->checkouts->count, 0, 'Checkout was not done due to recall in transit' );
|
|
|
|
$recall1->revert_transfer;
|
|
$recall1->update( { item_id => undef, item_level => 0 } );
|
|
$co_transaction->do_checkout();
|
|
is( $patron->checkouts->count, 0, 'Checkout was not done due to a biblio-level recall that this item could fill' );
|
|
|
|
$recall1->set_cancelled;
|
|
|
|
my $recall2 = Koha::Recall->new(
|
|
{
|
|
patron_id => $patron->borrowernumber,
|
|
created_date => \'NOW()',
|
|
biblio_id => $item->biblio->biblionumber,
|
|
pickup_library_id => $library->branchcode,
|
|
item_id => $item->itemnumber,
|
|
expiration_date => undef,
|
|
item_level => 1
|
|
}
|
|
)->store;
|
|
|
|
# Test recalls made by SIP patron
|
|
|
|
$recall2->set_waiting( { item => $item } );
|
|
$co_transaction->do_checkout();
|
|
is( $patron->checkouts->count, 1, 'Checkout was done because recalled item was allocated to them' );
|
|
$recall2 = Koha::Recalls->find( $recall2->id );
|
|
is( $recall2->status, 'fulfilled', 'Recall is fulfilled by checked out item' );
|
|
};
|
|
|
|
$schema->storage->txn_rollback;
|