3 # Tests for SIP::ILS::Transaction
4 # Current state is very rudimentary. Please help to extend it!
7 use Test::More tests => 8;
10 use t::lib::TestBuilder;
12 use C4::SIP::ILS::Patron;
13 use C4::SIP::ILS::Transaction::RenewAll;
14 use C4::SIP::ILS::Transaction::Checkout;
15 use C4::SIP::ILS::Transaction::FeePayment;
16 use C4::SIP::ILS::Transaction::Hold;
17 use C4::SIP::ILS::Transaction::Checkout;
18 use C4::SIP::ILS::Transaction::Checkin;
21 use Koha::CirculationRules;
22 use Koha::DateUtils qw( dt_from_string output_pref );
24 my $schema = Koha::Database->new->schema;
25 $schema->storage->txn_begin;
27 my $builder = t::lib::TestBuilder->new();
28 my $borr1 = $builder->build({ source => 'Borrower' });
29 my $card = $borr1->{cardnumber};
30 my $sip_patron = C4::SIP::ILS::Patron->new( $card );
32 # Create transaction RenewAll, assign patron, and run (no items)
33 my $transaction = C4::SIP::ILS::Transaction::RenewAll->new();
34 is( ref $transaction, "C4::SIP::ILS::Transaction::RenewAll", "New transaction created" );
35 is( $transaction->patron( $sip_patron ), $sip_patron, "Patron assigned to transaction" );
36 isnt( $transaction->do_renew_all, undef, "RenewAll on zero items" );
38 subtest fill_holds_at_checkout => sub {
42 my $category = $builder->build({ source => 'Category', value => { category_type => 'A' }});
43 my $branch = $builder->build({ source => 'Branch' });
44 my $borrower = $builder->build({ source => 'Borrower', value =>{
45 branchcode => $branch->{branchcode},
46 categorycode=>$category->{categorycode}
49 t::lib::Mocks::mock_userenv({ branchcode => $branch->{branchcode}, flags => 1 });
51 my $itype = $builder->build({ source => 'Itemtype', value =>{notforloan=>0} });
52 my $item1 = $builder->build_sample_item({
53 barcode => 'barcode4test',
54 homebranch => $branch->{branchcode},
55 holdingbranch => $branch->{branchcode},
56 itype => $itype->{itemtype},
59 my $item2 = $builder->build_sample_item({
60 homebranch => $branch->{branchcode},
61 holdingbranch => $branch->{branchcode},
62 biblionumber => $item1->{biblionumber},
63 itype => $itype->{itemtype},
67 Koha::CirculationRules->set_rules(
69 categorycode => $borrower->{categorycode},
70 branchcode => $branch->{branchcode},
71 itemtype => $itype->{itemtype},
75 holds_per_record => 3,
82 my $reserve1 = AddReserve(
84 branchcode => $branch->{branchcode},
85 borrowernumber => $borrower->{borrowernumber},
86 biblionumber => $item1->{biblionumber}
89 my $reserve2 = AddReserve(
91 branchcode => $branch->{branchcode},
92 borrowernumber => $borrower->{borrowernumber},
93 biblionumber => $item1->{biblionumber}
97 my $bib = Koha::Biblios->find( $item1->{biblionumber} );
98 is( $bib->holds->count(), 2, "Bib has 2 holds");
100 my $sip_patron = C4::SIP::ILS::Patron->new( $borrower->{cardnumber} );
101 my $sip_item = C4::SIP::ILS::Item->new( $item1->{barcode} );
102 my $transaction = C4::SIP::ILS::Transaction::Checkout->new();
103 is( ref $transaction, "C4::SIP::ILS::Transaction::Checkout", "New transaction created" );
104 is( $transaction->patron( $sip_patron ), $sip_patron, "Patron assigned to transaction" );
105 is( $transaction->item( $sip_item ), $sip_item, "Item assigned to transaction" );
106 my $checkout = $transaction->do_checkout();
107 use Data::Dumper; # Temporary debug statement
108 is( $bib->holds->count(), 1, "Bib has 1 holds remaining") or diag Dumper $checkout;
110 t::lib::Mocks::mock_preference('itemBarcodeInputFilter', 'whitespace');
111 $sip_item = C4::SIP::ILS::Item->new( ' barcode 4 test ');
112 $transaction = C4::SIP::ILS::Transaction::Checkout->new();
113 is( $sip_item->{barcode}, $item1->{barcode}, "Item assigned to transaction" );
116 subtest "FeePayment->pay tests" => sub {
120 # Create a borrower and add some outstanding debts to their account
121 my $patron = $builder->build( { source => 'Borrower' } );
123 Koha::Account->new( { patron_id => $patron->{borrowernumber} } );
124 my $debt1 = $account->add_debit(
125 { type => 'ACCOUNT', amount => 100, interface => 'commandline' } );
126 my $debt2 = $account->add_debit(
127 { type => 'ACCOUNT', amount => 200, interface => 'commandline' } );
129 # Instantiate a new FeePayment transaction object
130 my $trans = C4::SIP::ILS::Transaction::FeePayment->new();
133 "C4::SIP::ILS::Transaction::FeePayment",
134 "New fee transaction created"
137 # Test the 'pay' method
138 # FIXME: pay should not require a borrowernumber
139 # (we should reach out to the transaction which should contain a patron object)
140 my $pay_type = '00'; # 00 - Cash, 01 - VISA, 02 - Creditcard
142 $trans->pay( $patron->{borrowernumber}, 100, $pay_type, $debt1->id, 0,
144 ok( $ok, "FeePayment transaction succeeded" );
145 $debt1->discard_changes;
146 is( $debt1->amountoutstanding + 0, 0,
147 "Debt1 was reduced to 0 as expected" );
148 my $offsets = Koha::Account::Offsets->search(
149 { debit_id => $debt1->id, credit_id => { '!=' => undef } } );
150 is( $offsets->count, 1, "FeePayment produced an offset line correctly" );
151 my $credit = $offsets->next->credit;
152 is( $credit->payment_type, 'SIP00', "Payment type was set correctly" );
155 subtest cancel_hold => sub {
158 my $library = $builder->build_object ({ class => 'Koha::Libraries' });
159 my $patron = $builder->build_object(
161 class => 'Koha::Patrons',
163 branchcode => $library->branchcode,
167 t::lib::Mocks::mock_userenv({ branchcode => $library->branchcode, flags => 1 });
169 my $item = $builder->build_sample_item({
170 library => $library->branchcode,
173 Koha::CirculationRules->set_rules(
175 categorycode => $patron->categorycode,
176 branchcode => $library->branchcode,
177 itemtype => $item->effective_itemtype,
180 reservesallowed => 3,
181 holds_per_record => 3,
183 lengthunit => 'days',
188 my $reserve1 = AddReserve(
190 branchcode => $library->branchcode,
191 borrowernumber => $patron->borrowernumber,
192 biblionumber => $item->biblio->biblionumber,
193 itemnumber => $item->itemnumber,
196 is( $item->biblio->holds->count(), 1, "Hold was placed on bib");
197 is( $item->holds->count(),1,"Hold was placed on specific item");
199 my $sip_patron = C4::SIP::ILS::Patron->new( $patron->cardnumber );
200 my $sip_item = C4::SIP::ILS::Item->new( $item->barcode );
201 my $transaction = C4::SIP::ILS::Transaction::Hold->new();
202 is( ref $transaction, "C4::SIP::ILS::Transaction::Hold", "New transaction created" );
203 is( $transaction->patron( $sip_patron ), $sip_patron, "Patron assigned to transaction" );
204 is( $transaction->item( $sip_item ), $sip_item, "Item assigned to transaction" );
205 my $hold = $transaction->drop_hold();
206 is( $item->biblio->holds->count(), 0, "Bib has 0 holds remaining");
207 is( $item->holds->count(), 0, "Item has 0 holds remaining");
210 subtest do_hold => sub {
213 my $library = $builder->build_object( { class => 'Koha::Libraries' } );
214 my $patron_1 = $builder->build_object(
216 class => 'Koha::Patrons',
218 branchcode => $library->branchcode,
222 my $patron_2 = $builder->build_object(
224 class => 'Koha::Patrons',
226 branchcode => $library->branchcode,
227 categorycode => $patron_1->categorycode,
232 t::lib::Mocks::mock_userenv(
233 { branchcode => $library->branchcode, flags => 1 } );
235 my $item = $builder->build_sample_item(
237 library => $library->branchcode,
241 my $reserve1 = AddReserve(
243 branchcode => $library->branchcode,
244 borrowernumber => $patron_1->borrowernumber,
245 biblionumber => $item->biblio->biblionumber,
246 itemnumber => $item->itemnumber,
249 is( $item->biblio->holds->count(), 1, "Hold was placed on bib" );
250 is( $item->holds->count(), 1, "Hold was placed on specific item" );
252 my $sip_patron = C4::SIP::ILS::Patron->new( $patron_2->cardnumber );
253 my $sip_item = C4::SIP::ILS::Item->new( $item->barcode );
254 my $transaction = C4::SIP::ILS::Transaction::Hold->new();
257 "C4::SIP::ILS::Transaction::Hold",
258 "New transaction created"
260 is( $transaction->patron($sip_patron),
261 $sip_patron, "Patron assigned to transaction" );
262 is( $transaction->item($sip_item),
263 $sip_item, "Item assigned to transaction" );
264 my $hold = $transaction->do_hold();
265 is( $item->biblio->holds->count(), 2, "Bib has 2 holds" );
267 is( $patron_2->holds->next->priority, 2, 'Hold placed from SIP should have a correct priority of 2');
270 subtest do_checkin => sub {
273 my $library = $builder->build_object( { class => 'Koha::Libraries' } );
274 my $patron = $builder->build_object(
276 class => 'Koha::Patrons',
278 branchcode => $library->branchcode,
283 t::lib::Mocks::mock_userenv(
284 { branchcode => $library->branchcode, flags => 1 } );
286 my $item = $builder->build_sample_item(
288 library => $library->branchcode,
294 my $sip_patron = C4::SIP::ILS::Patron->new( $patron->cardnumber );
295 my $sip_item = C4::SIP::ILS::Item->new( $item->barcode );
296 my $co_transaction = C4::SIP::ILS::Transaction::Checkout->new();
297 is( $co_transaction->patron($sip_patron),
298 $sip_patron, "Patron assigned to transaction" );
299 is( $co_transaction->item($sip_item),
300 $sip_item, "Item assigned to transaction" );
301 my $checkout = $co_transaction->do_checkout();
302 is( $patron->checkouts->count, 1, 'Checkout should have been done successfully');
305 my $ci_transaction = C4::SIP::ILS::Transaction::Checkin->new();
306 is( $ci_transaction->patron($sip_patron),
307 $sip_patron, "Patron assigned to transaction" );
308 is( $ci_transaction->item($sip_item),
309 $sip_item, "Item assigned to transaction" );
311 my $checkin = $ci_transaction->do_checkin($library->branchcode, C4::SIP::Sip::timestamp);
312 is( $patron->checkouts->count, 0, 'Checkin should have been done successfully');
314 # Test checkin without return date
315 $co_transaction->do_checkout;
316 is( $patron->checkouts->count, 1, 'Checkout should have been done successfully');
317 $ci_transaction->do_checkin($library->branchcode, undef);
318 is( $patron->checkouts->count, 0, 'Checkin should have been done successfully');
321 $schema->storage->txn_rollback;