a153fab638a5e995ae5887761b68d307e94406ac
[koha-equinox.git] / t / db_dependent / SIP / Transaction.t
1 #!/usr/bin/perl
2
3 # Tests for SIP::ILS::Transaction
4 # Current state is very rudimentary. Please help to extend it!
5
6 use Modern::Perl;
7 use Test::More tests => 8;
8
9 use Koha::Database;
10 use t::lib::TestBuilder;
11 use t::lib::Mocks;
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;
19
20 use C4::Reserves;
21 use Koha::CirculationRules;
22 use Koha::DateUtils qw( dt_from_string output_pref );
23
24 my $schema = Koha::Database->new->schema;
25 $schema->storage->txn_begin;
26
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 );
31
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" );
37
38 subtest fill_holds_at_checkout => sub {
39     plan tests => 6;
40
41
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}
47         }
48     });
49     t::lib::Mocks::mock_userenv({ branchcode => $branch->{branchcode}, flags => 1 });
50
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},
57         notforloan       => 0,
58     })->unblessed;
59     my $item2 = $builder->build_sample_item({
60         homebranch    => $branch->{branchcode},
61         holdingbranch => $branch->{branchcode},
62         biblionumber  => $item1->{biblionumber},
63         itype         => $itype->{itemtype},
64         notforloan       => 0,
65     })->unblessed;
66
67     Koha::CirculationRules->set_rules(
68         {
69             categorycode => $borrower->{categorycode},
70             branchcode   => $branch->{branchcode},
71             itemtype     => $itype->{itemtype},
72             rules        => {
73                 onshelfholds     => 1,
74                 reservesallowed  => 3,
75                 holds_per_record => 3,
76                 issuelength      => 5,
77                 lengthunit       => 'days',
78             }
79         }
80     );
81
82     my $reserve1 = AddReserve(
83         {
84             branchcode     => $branch->{branchcode},
85             borrowernumber => $borrower->{borrowernumber},
86             biblionumber   => $item1->{biblionumber}
87         }
88     );
89     my $reserve2 = AddReserve(
90         {
91             branchcode     => $branch->{branchcode},
92             borrowernumber => $borrower->{borrowernumber},
93             biblionumber   => $item1->{biblionumber}
94         }
95     );
96
97     my $bib = Koha::Biblios->find( $item1->{biblionumber} );
98     is( $bib->holds->count(), 2, "Bib has 2 holds");
99
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;
109
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" );
114 };
115
116 subtest "FeePayment->pay tests" => sub {
117
118     plan tests => 5;
119
120     # Create a borrower and add some outstanding debts to their account
121     my $patron = $builder->build( { source => 'Borrower' } );
122     my $account =
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' } );
128
129     # Instantiate a new FeePayment transaction object
130     my $trans = C4::SIP::ILS::Transaction::FeePayment->new();
131     is(
132         ref $trans,
133         "C4::SIP::ILS::Transaction::FeePayment",
134         "New fee transaction created"
135     );
136
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
141     my $ok =
142       $trans->pay( $patron->{borrowernumber}, 100, $pay_type, $debt1->id, 0,
143         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" );
153 };
154
155 subtest cancel_hold => sub {
156     plan tests => 7;
157
158     my $library = $builder->build_object ({ class => 'Koha::Libraries' });
159     my $patron = $builder->build_object(
160         {
161             class => 'Koha::Patrons',
162             value => {
163                 branchcode => $library->branchcode,
164             }
165         }
166     );
167     t::lib::Mocks::mock_userenv({ branchcode => $library->branchcode, flags => 1 });
168
169     my $item = $builder->build_sample_item({
170         library       => $library->branchcode,
171     });
172
173     Koha::CirculationRules->set_rules(
174         {
175             categorycode => $patron->categorycode,
176             branchcode   => $library->branchcode,
177             itemtype     => $item->effective_itemtype,
178             rules        => {
179                 onshelfholds     => 1,
180                 reservesallowed  => 3,
181                 holds_per_record => 3,
182                 issuelength      => 5,
183                 lengthunit       => 'days',
184             }
185         }
186     );
187
188     my $reserve1 = AddReserve(
189         {
190             branchcode     => $library->branchcode,
191             borrowernumber => $patron->borrowernumber,
192             biblionumber   => $item->biblio->biblionumber,
193             itemnumber     => $item->itemnumber,
194         }
195     );
196     is( $item->biblio->holds->count(), 1, "Hold was placed on bib");
197     is( $item->holds->count(),1,"Hold was placed on specific item");
198
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");
208 };
209
210 subtest do_hold => sub {
211     plan tests => 7;
212
213     my $library = $builder->build_object( { class => 'Koha::Libraries' } );
214     my $patron_1 = $builder->build_object(
215         {
216             class => 'Koha::Patrons',
217             value => {
218                 branchcode => $library->branchcode,
219             }
220         }
221     );
222     my $patron_2 = $builder->build_object(
223         {
224             class => 'Koha::Patrons',
225             value => {
226                 branchcode   => $library->branchcode,
227                 categorycode => $patron_1->categorycode,
228             }
229         }
230     );
231
232     t::lib::Mocks::mock_userenv(
233         { branchcode => $library->branchcode, flags => 1 } );
234
235     my $item = $builder->build_sample_item(
236         {
237             library => $library->branchcode,
238         }
239     );
240
241     my $reserve1 = AddReserve(
242         {
243             branchcode     => $library->branchcode,
244             borrowernumber => $patron_1->borrowernumber,
245             biblionumber   => $item->biblio->biblionumber,
246             itemnumber     => $item->itemnumber,
247         }
248     );
249     is( $item->biblio->holds->count(), 1, "Hold was placed on bib" );
250     is( $item->holds->count(),         1, "Hold was placed on specific item" );
251
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();
255     is(
256         ref $transaction,
257         "C4::SIP::ILS::Transaction::Hold",
258         "New transaction created"
259     );
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" );
266
267     is( $patron_2->holds->next->priority, 2, 'Hold placed from SIP should have a correct priority of 2');
268 };
269
270 subtest do_checkin => sub {
271     plan tests => 8;
272
273     my $library = $builder->build_object( { class => 'Koha::Libraries' } );
274     my $patron = $builder->build_object(
275         {
276             class => 'Koha::Patrons',
277             value => {
278                 branchcode => $library->branchcode,
279             }
280         }
281     );
282
283     t::lib::Mocks::mock_userenv(
284         { branchcode => $library->branchcode, flags => 1 } );
285
286     my $item = $builder->build_sample_item(
287         {
288             library => $library->branchcode,
289         }
290     );
291
292
293     # Checkout
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');
303
304     # Checkin
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" );
310
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');
313
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');
319 };
320
321 $schema->storage->txn_rollback;