View | Details | Raw Unified | Return to bug 40932
Collapse All | Expand All

(-)a/t/db_dependent/Circulation/AutoCloseInvoiceOnCheckin.t (-1 / +310 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# Koha is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with Koha; if not, see <https://www.gnu.org/licenses>.
17
18
use Modern::Perl;
19
20
use Test::More tests => 7;
21
use Test::NoWarnings;
22
23
use C4::Circulation qw( AddIssue AddReturn );
24
use Koha::Acquisition::Invoices;
25
use Koha::Acquisition::OrderItems;
26
27
use t::lib::Mocks;
28
use t::lib::TestBuilder;
29
30
my $schema  = Koha::Database->schema;
31
my $builder = t::lib::TestBuilder->new;
32
33
subtest 'check_and_close: all items received closes invoice' => sub {
34
    plan tests => 3;
35
36
    $schema->storage->txn_begin;
37
38
    my $invoice = $builder->build_object( { class => 'Koha::Acquisition::Invoices', value => { closedate => undef } } );
39
40
    my $order = $builder->build(
41
        {
42
            source => 'Aqorder',
43
            value  => { invoiceid => $invoice->invoiceid, orderstatus => 'complete' },
44
        }
45
    );
46
    my $item = $builder->build_sample_item;
47
    $builder->build(
48
        {
49
            source => 'AqordersItem',
50
            value  => {
51
                ordernumber => $order->{ordernumber},
52
                itemnumber  => $item->itemnumber,
53
                received    => '2026-01-01 10:00:00',
54
            },
55
        }
56
    );
57
58
    my $closed = $invoice->check_and_close;
59
    is( $closed, 1, 'check_and_close returns 1 when all items received' );
60
61
    $invoice->discard_changes;
62
    ok( $invoice->closedate, 'Invoice has a closedate after check_and_close' );
63
64
    my $closed_again = $invoice->check_and_close;
65
    is( $closed_again, 0, 'check_and_close returns 0 if already closed' );
66
67
    $schema->storage->txn_rollback;
68
};
69
70
subtest 'check_and_close: unreceived item keeps invoice open' => sub {
71
    plan tests => 2;
72
73
    $schema->storage->txn_begin;
74
75
    my $invoice = $builder->build_object( { class => 'Koha::Acquisition::Invoices', value => { closedate => undef } } );
76
77
    my $order = $builder->build(
78
        {
79
            source => 'Aqorder',
80
            value  => { invoiceid => $invoice->invoiceid, orderstatus => 'complete' },
81
        }
82
    );
83
84
    # One received item
85
    my $item1 = $builder->build_sample_item;
86
    $builder->build(
87
        {
88
            source => 'AqordersItem',
89
            value  => {
90
                ordernumber => $order->{ordernumber},
91
                itemnumber  => $item1->itemnumber,
92
                received    => '2026-01-01 10:00:00',
93
            },
94
        }
95
    );
96
97
    # One NOT yet received item
98
    my $item2 = $builder->build_sample_item;
99
    $builder->build(
100
        {
101
            source => 'AqordersItem',
102
            value  => {
103
                ordernumber => $order->{ordernumber},
104
                itemnumber  => $item2->itemnumber,
105
                received    => undef,
106
            },
107
        }
108
    );
109
110
    my $closed = $invoice->check_and_close;
111
    is( $closed, 0, 'check_and_close returns 0 when an item is not yet received' );
112
113
    $invoice->discard_changes;
114
    ok( !$invoice->closedate, 'Invoice remains open' );
115
116
    $schema->storage->txn_rollback;
117
};
118
119
subtest 'check_and_close: cancelled order lines excluded' => sub {
120
    plan tests => 2;
121
122
    $schema->storage->txn_begin;
123
124
    my $invoice = $builder->build_object( { class => 'Koha::Acquisition::Invoices', value => { closedate => undef } } );
125
126
    # Active order with all items received
127
    my $active_order = $builder->build(
128
        {
129
            source => 'Aqorder',
130
            value  => { invoiceid => $invoice->invoiceid, orderstatus => 'complete' },
131
        }
132
    );
133
    my $item = $builder->build_sample_item;
134
    $builder->build(
135
        {
136
            source => 'AqordersItem',
137
            value  => {
138
                ordernumber => $active_order->{ordernumber},
139
                itemnumber  => $item->itemnumber,
140
                received    => '2026-01-01 10:00:00',
141
            },
142
        }
143
    );
144
145
    # Cancelled order with unreceived item — should NOT block close
146
    my $cancelled_order = $builder->build(
147
        {
148
            source => 'Aqorder',
149
            value  => { invoiceid => $invoice->invoiceid, orderstatus => 'cancelled' },
150
        }
151
    );
152
    my $cancelled_item = $builder->build_sample_item;
153
    $builder->build(
154
        {
155
            source => 'AqordersItem',
156
            value  => {
157
                ordernumber => $cancelled_order->{ordernumber},
158
                itemnumber  => $cancelled_item->itemnumber,
159
                received    => undef,
160
            },
161
        }
162
    );
163
164
    my $closed = $invoice->check_and_close;
165
    is( $closed, 1, 'Invoice closed: cancelled order line unreceived item does not block' );
166
167
    $invoice->discard_changes;
168
    ok( $invoice->closedate, 'Invoice has a closedate' );
169
170
    $schema->storage->txn_rollback;
171
};
172
173
subtest 'check_and_close: invoice with no items stays open' => sub {
174
    plan tests => 2;
175
176
    $schema->storage->txn_begin;
177
178
    my $invoice = $builder->build_object( { class => 'Koha::Acquisition::Invoices', value => { closedate => undef } } );
179
180
    # Order on invoice but no aqorders_items rows
181
    $builder->build(
182
        {
183
            source => 'Aqorder',
184
            value  => { invoiceid => $invoice->invoiceid, orderstatus => 'complete' },
185
        }
186
    );
187
188
    my $closed = $invoice->check_and_close;
189
    is( $closed, 0, 'check_and_close returns 0 for invoice with no linked items' );
190
191
    $invoice->discard_changes;
192
    ok( !$invoice->closedate, 'Invoice remains open' );
193
194
    $schema->storage->txn_rollback;
195
};
196
197
subtest '_record_physical_receipt stamps received and auto-closes' => sub {
198
    plan tests => 4;
199
200
    $schema->storage->txn_begin;
201
202
    t::lib::Mocks::mock_preference( 'AutoCloseInvoicesOnCheckin', 1 );
203
204
    my $library = $builder->build_object( { class => 'Koha::Libraries' } );
205
    my $patron  = $builder->build_object(
206
        {
207
            class => 'Koha::Patrons',
208
            value => { branchcode => $library->branchcode },
209
        }
210
    );
211
    my $item = $builder->build_sample_item( { library => $library->branchcode } );
212
213
    # Issue the item
214
    t::lib::Mocks::mock_userenv( { branchcode => $library->branchcode } );
215
    AddIssue( $patron, $item->barcode );
216
217
    my $invoice = $builder->build_object( { class => 'Koha::Acquisition::Invoices', value => { closedate => undef } } );
218
219
    my $order = $builder->build(
220
        {
221
            source => 'Aqorder',
222
            value  => { invoiceid => $invoice->invoiceid, orderstatus => 'complete' },
223
        }
224
    );
225
    $builder->build(
226
        {
227
            source => 'AqordersItem',
228
            value  => {
229
                ordernumber => $order->{ordernumber},
230
                itemnumber  => $item->itemnumber,
231
                received    => undef,
232
            },
233
        }
234
    );
235
236
    # Check in the item
237
    my ($doreturn) = AddReturn( $item->barcode, $library->branchcode );
238
    ok( $doreturn, 'AddReturn succeeded' );
239
240
    # Verify received timestamp was set
241
    my $order_item = Koha::Acquisition::OrderItems->find( { itemnumber => $item->itemnumber } );
242
    ok( $order_item->received, 'aqorders_items.received was stamped on check-in' );
243
244
    # Second check-in should NOT overwrite the received timestamp
245
    AddIssue( $patron, $item->barcode );
246
    my $first_received = $order_item->received;
247
    AddReturn( $item->barcode, $library->branchcode );
248
    $order_item->discard_changes;
249
    is(
250
        $order_item->received, $first_received,
251
        'Second check-in does not overwrite received timestamp'
252
    );
253
254
    # Invoice should be closed (only one item, now received)
255
    $invoice->discard_changes;
256
    ok( $invoice->closedate, 'Invoice was auto-closed after last item checked in' );
257
258
    $schema->storage->txn_rollback;
259
};
260
261
subtest 'AutoCloseInvoicesOnCheckin disabled: no auto-close' => sub {
262
    plan tests => 2;
263
264
    $schema->storage->txn_begin;
265
266
    t::lib::Mocks::mock_preference( 'AutoCloseInvoicesOnCheckin', 0 );
267
268
    my $library = $builder->build_object( { class => 'Koha::Libraries' } );
269
    my $patron  = $builder->build_object(
270
        {
271
            class => 'Koha::Patrons',
272
            value => { branchcode => $library->branchcode },
273
        }
274
    );
275
    my $item = $builder->build_sample_item( { library => $library->branchcode } );
276
277
    t::lib::Mocks::mock_userenv( { branchcode => $library->branchcode } );
278
    AddIssue( $patron, $item->barcode );
279
280
    my $invoice = $builder->build_object( { class => 'Koha::Acquisition::Invoices', value => { closedate => undef } } );
281
282
    my $order = $builder->build(
283
        {
284
            source => 'Aqorder',
285
            value  => { invoiceid => $invoice->invoiceid, orderstatus => 'complete' },
286
        }
287
    );
288
    $builder->build(
289
        {
290
            source => 'AqordersItem',
291
            value  => {
292
                ordernumber => $order->{ordernumber},
293
                itemnumber  => $item->itemnumber,
294
                received    => undef,
295
            },
296
        }
297
    );
298
299
    AddReturn( $item->barcode, $library->branchcode );
300
301
    # received should still be stamped (that always happens)
302
    my $order_item = Koha::Acquisition::OrderItems->find( { itemnumber => $item->itemnumber } );
303
    ok( $order_item->received, 'received is stamped regardless of preference' );
304
305
    # Invoice should NOT be closed
306
    $invoice->discard_changes;
307
    ok( !$invoice->closedate, 'Invoice not auto-closed when AutoCloseInvoicesOnCheckin is off' );
308
309
    $schema->storage->txn_rollback;
310
};

Return to bug 40932