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

(-)a/t/db_dependent/Koha/Account/Line.t (-1 / +69 lines)
Lines 20-26 Link Here
20
use Modern::Perl;
20
use Modern::Perl;
21
21
22
use Test::NoWarnings;
22
use Test::NoWarnings;
23
use Test::More tests => 16;
23
use Test::More tests => 17;
24
use Test::Exception;
24
use Test::Exception;
25
use Test::MockModule;
25
use Test::MockModule;
26
26
Lines 1470-1473 subtest "cancel() tests" => sub { Link Here
1470
    $schema->storage->txn_rollback;
1470
    $schema->storage->txn_rollback;
1471
};
1471
};
1472
1472
1473
subtest 'linking methods tests' => sub {
1474
    plan tests => 8;
1475
1476
    $schema->storage->txn_begin;
1477
1478
    # Create test data
1479
    my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
1480
    my $biblio = $builder->build_sample_biblio();
1481
    my $item   = $builder->build_sample_item( { biblionumber => $biblio->biblionumber } );
1482
1483
    # Create a hold
1484
    my $hold = Koha::Hold->new(
1485
        {
1486
            borrowernumber => $patron->borrowernumber,
1487
            biblionumber   => $biblio->biblionumber,
1488
            itemnumber     => $item->itemnumber,
1489
            branchcode     => $patron->branchcode,
1490
            reservedate    => '2023-01-01',
1491
            priority       => 1,
1492
        }
1493
    )->store;
1494
1495
    # Create a checkout
1496
    my $checkout = Koha::Checkout->new(
1497
        {
1498
            borrowernumber => $patron->borrowernumber,
1499
            itemnumber     => $item->itemnumber,
1500
            issuedate      => '2023-01-01',
1501
            date_due       => '2023-01-15',
1502
            branchcode     => $patron->branchcode,
1503
        }
1504
    )->store;
1505
1506
    # Create an account line
1507
    my $account_line = $patron->account->add_debit(
1508
        {
1509
            amount      => 5.00,
1510
            description => 'Mixed fee',
1511
            type        => 'MANUAL',
1512
            interface   => 'intranet'
1513
        }
1514
    );
1515
1516
    # Test add_link method
1517
    my $hold_link = $account_line->add_link( 'hold', $hold->id );
1518
    isa_ok( $hold_link, 'Koha::Account::Link', 'add_link returns Link object' );
1519
1520
    my $checkout_link = $account_line->add_link( 'checkout', $checkout->id );
1521
    isa_ok( $checkout_link, 'Koha::Account::Link', 'add_link returns Link object for checkout' );
1522
1523
    # Test links method
1524
    my $links = $account_line->links;
1525
    isa_ok( $links, 'Koha::Account::Links', 'links returns Links collection' );
1526
    is( $links->count, 2, 'Account line has two links' );
1527
1528
    # Test holds method
1529
    my @holds = $account_line->holds;
1530
    is( scalar @holds, 1, 'holds() returns correct number of holds' );
1531
    isa_ok( $holds[0], 'Koha::Hold', 'holds() returns Hold object' );
1532
    is( $holds[0]->id, $hold->id, 'holds() returns correct hold' );
1533
1534
    # Test checkouts method
1535
    my @checkouts = $account_line->checkouts;
1536
    is( scalar @checkouts, 1, 'checkouts() returns correct number of checkouts' );
1537
1538
    $schema->storage->txn_rollback;
1539
};
1540
1473
1;
1541
1;
(-)a/t/db_dependent/Koha/Account/Link.t (+295 lines)
Line 0 Link Here
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 <http://www.gnu.org/licenses>.
17
18
use Modern::Perl;
19
20
use Test::More tests => 6;
21
use Test::Exception;
22
use Test::Warn;
23
24
use Koha::Database;
25
use Koha::Account::Link;
26
use Koha::Account::Links;
27
28
use t::lib::TestBuilder;
29
use t::lib::Mocks;
30
31
my $schema = Koha::Database->new->schema;
32
$schema->storage->txn_begin;
33
34
my $builder = t::lib::TestBuilder->new;
35
36
subtest 'Basic object creation and validation' => sub {
37
    plan tests => 8;
38
39
    # Create test data
40
    my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
41
    my $biblio = $builder->build_sample_biblio();
42
    my $item   = $builder->build_sample_item( { biblionumber => $biblio->biblionumber } );
43
44
    # Create a hold
45
    my $hold = Koha::Hold->new(
46
        {
47
            borrowernumber => $patron->borrowernumber,
48
            biblionumber   => $biblio->biblionumber,
49
            itemnumber     => $item->itemnumber,
50
            branchcode     => $patron->branchcode,
51
            reservedate    => '2023-01-01',
52
            priority       => 1,
53
        }
54
    )->store;
55
56
    # Create an account line
57
    my $account_line = $patron->account->add_debit(
58
        {
59
            amount      => 5.00,
60
            description => 'Hold fee',
61
            type        => 'RESERVE',
62
            interface   => 'intranet'
63
        }
64
    );
65
66
    # Test link creation
67
    my $link = Koha::Account::Link->new(
68
        {
69
            accountlines_id => $account_line->id,
70
            link_type       => 'hold',
71
            linked_id       => $hold->id,
72
        }
73
    );
74
75
    is( $link->accountlines_id, $account_line->id, 'Account line ID set correctly' );
76
    is( $link->link_type,       'hold',            'Link type set correctly' );
77
    is( $link->linked_id,       $hold->id,         'Linked ID set correctly' );
78
79
    # Test validation passes
80
    ok( $link->_validate_link_integrity(), 'Link validation passes for valid data' );
81
82
    # Test store
83
    lives_ok { $link->store() } 'Link stores without error';
84
    ok( $link->id, 'Link has ID after storing' );
85
86
    # Test linked_object method
87
    my $linked_obj = $link->linked_object;
88
    isa_ok( $linked_obj, 'Koha::Schema::Result::Reserve', 'linked_object returns correct type' );
89
    is( $linked_obj->reserve_id, $hold->id, 'linked_object returns correct hold' );
90
};
91
92
subtest 'Link validation' => sub {
93
    plan tests => 4;
94
95
    my $patron       = $builder->build_object( { class => 'Koha::Patrons' } );
96
    my $account_line = $patron->account->add_debit(
97
        {
98
            amount      => 3.00,
99
            description => 'Test fee',
100
            type        => 'MANUAL',
101
            interface   => 'intranet'
102
        }
103
    );
104
105
    # Test invalid link type
106
    my $invalid_link = Koha::Account::Link->new(
107
        {
108
            accountlines_id => $account_line->id,
109
            link_type       => 'invalid_type',
110
            linked_id       => 999,
111
        }
112
    );
113
114
    ok( !$invalid_link->_validate_link_integrity(), 'Validation fails for invalid link type' );
115
116
    # Test nonexistent linked entity
117
    my $nonexistent_link = Koha::Account::Link->new(
118
        {
119
            accountlines_id => $account_line->id,
120
            link_type       => 'hold',
121
            linked_id       => 99999,               # Doesn't exist
122
        }
123
    );
124
125
    ok( !$nonexistent_link->_validate_link_integrity(), 'Validation fails for nonexistent linked entity' );
126
127
    # Test store with invalid data
128
    throws_ok {
129
        $invalid_link->store()
130
    }
131
    'Koha::Exceptions::Account::InvalidLinkType', 'Store throws InvalidLinkType exception for invalid link';
132
133
    throws_ok {
134
        $nonexistent_link->store()
135
    }
136
    'Koha::Exceptions::Account::InvalidLinkTarget', 'Store throws InvalidLinkTarget exception for nonexistent entity';
137
};
138
139
subtest 'Linked Koha object access' => sub {
140
    plan tests => 3;
141
142
    my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
143
    my $biblio = $builder->build_sample_biblio();
144
    my $hold   = Koha::Hold->new(
145
        {
146
            borrowernumber => $patron->borrowernumber,
147
            biblionumber   => $biblio->biblionumber,
148
            branchcode     => $patron->branchcode,
149
            reservedate    => '2023-01-01',
150
            priority       => 1,
151
        }
152
    )->store;
153
154
    my $account_line = $patron->account->add_debit(
155
        {
156
            amount      => 2.00,
157
            description => 'Hold fee',
158
            type        => 'RESERVE',
159
            interface   => 'intranet'
160
        }
161
    );
162
163
    my $link = Koha::Account::Link->new(
164
        {
165
            accountlines_id => $account_line->id,
166
            link_type       => 'hold',
167
            linked_id       => $hold->id,
168
        }
169
    )->store;
170
171
    # Test linked_koha_object method
172
    my $koha_hold = $link->linked_koha_object;
173
    isa_ok( $koha_hold, 'Koha::Hold', 'linked_koha_object returns Koha::Hold object' );
174
    is( $koha_hold->id,             $hold->id,               'Returned object has correct ID' );
175
    is( $koha_hold->borrowernumber, $patron->borrowernumber, 'Returned object has correct patron' );
176
};
177
178
subtest 'Account line integration' => sub {
179
    plan tests => 4;
180
181
    my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
182
    my $biblio = $builder->build_sample_biblio();
183
    my $hold   = Koha::Hold->new(
184
        {
185
            borrowernumber => $patron->borrowernumber,
186
            biblionumber   => $biblio->biblionumber,
187
            branchcode     => $patron->branchcode,
188
            reservedate    => '2023-01-01',
189
            priority       => 1,
190
        }
191
    )->store;
192
193
    my $account_line = $patron->account->add_debit(
194
        {
195
            amount      => 1.50,
196
            description => 'Hold fee',
197
            type        => 'RESERVE',
198
            interface   => 'intranet'
199
        }
200
    );
201
202
    # Test add_link method
203
    my $link = $account_line->add_link( 'hold', $hold->id );
204
    isa_ok( $link, 'Koha::Account::Link', 'add_link returns Link object' );
205
    is( $link->accountlines_id, $account_line->id, 'Link has correct account line ID' );
206
207
    # Test links method
208
    my $links = $account_line->links;
209
    isa_ok( $links, 'Koha::Account::Links', 'links returns Links collection' );
210
    is( $links->count, 1, 'Account line has one link' );
211
};
212
213
subtest 'Hold integration' => sub {
214
    plan tests => 3;
215
216
    my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
217
    my $biblio = $builder->build_sample_biblio();
218
    my $hold   = Koha::Hold->new(
219
        {
220
            borrowernumber => $patron->borrowernumber,
221
            biblionumber   => $biblio->biblionumber,
222
            branchcode     => $patron->branchcode,
223
            reservedate    => '2023-01-01',
224
            priority       => 1,
225
        }
226
    )->store;
227
228
    # Create multiple account lines for this hold
229
    my $fee1 = $patron->account->add_debit(
230
        {
231
            amount      => 2.00,
232
            description => 'Hold placement fee',
233
            type        => 'RESERVE',
234
            interface   => 'intranet'
235
        }
236
    );
237
238
    my $fee2 = $patron->account->add_debit(
239
        {
240
            amount      => 1.00,
241
            description => 'Hold collection fee',
242
            type        => 'RESERVE_EXPIRED',
243
            interface   => 'intranet'
244
        }
245
    );
246
247
    # Link both fees to the hold
248
    $fee1->add_link( 'hold', $hold->id );
249
    $fee2->add_link( 'hold', $hold->id );
250
251
    # Test hold can find its account lines
252
    my $debits = $hold->debits;
253
    isa_ok( $debits, 'Koha::Account::Debits', 'debits returns Debits collection' );
254
    is( $debits->search( {} )->count, 2, 'Hold has two linked debit lines' );
255
256
    my $total_fees = $debits->total_outstanding;
257
    is( $total_fees, 3.00, 'Total fees calculated correctly' );
258
};
259
260
subtest 'Unique constraint and duplicate prevention' => sub {
261
    plan tests => 2;
262
263
    my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
264
    my $biblio = $builder->build_sample_biblio();
265
    my $hold   = Koha::Hold->new(
266
        {
267
            borrowernumber => $patron->borrowernumber,
268
            biblionumber   => $biblio->biblionumber,
269
            branchcode     => $patron->branchcode,
270
            reservedate    => '2023-01-01',
271
            priority       => 1,
272
        }
273
    )->store;
274
275
    my $account_line = $patron->account->add_debit(
276
        {
277
            amount      => 5.00,
278
            description => 'Hold fee',
279
            type        => 'RESERVE',
280
            interface   => 'intranet'
281
        }
282
    );
283
284
    # Create first link
285
    my $link1 = $account_line->add_link( 'hold', $hold->id );
286
    ok( $link1->id, 'First link created successfully' );
287
288
    # Try to create duplicate link
289
    throws_ok {
290
        $account_line->add_link( 'hold', $hold->id )
291
    }
292
    qr/duplicate/i, 'Duplicate link creation fails with unique constraint error';
293
};
294
295
$schema->storage->txn_rollback;
(-)a/t/db_dependent/Koha/Account/Links.t (-1 / +322 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 <http://www.gnu.org/licenses>.
17
18
use Modern::Perl;
19
20
use Test::More tests => 4;
21
22
use Koha::Database;
23
use Koha::Account::Links;
24
25
use t::lib::TestBuilder;
26
27
my $schema = Koha::Database->new->schema;
28
$schema->storage->txn_begin;
29
30
my $builder = t::lib::TestBuilder->new;
31
32
subtest 'Basic collection functionality' => sub {
33
    plan tests => 3;
34
35
    $schema->storage->txn_begin;
36
37
    # Create test data
38
    my $patron1 = $builder->build_object( { class => 'Koha::Patrons' } );
39
    my $patron2 = $builder->build_object( { class => 'Koha::Patrons' } );
40
    my $biblio  = $builder->build_sample_biblio();
41
42
    my $hold1 = Koha::Hold->new(
43
        {
44
            borrowernumber => $patron1->borrowernumber,
45
            biblionumber   => $biblio->biblionumber,
46
            branchcode     => $patron1->branchcode,
47
            reservedate    => '2023-01-01',
48
            priority       => 1,
49
        }
50
    )->store;
51
52
    my $hold2 = Koha::Hold->new(
53
        {
54
            borrowernumber => $patron2->borrowernumber,
55
            biblionumber   => $biblio->biblionumber,
56
            branchcode     => $patron2->branchcode,
57
            reservedate    => '2023-01-02',
58
            priority       => 2,
59
        }
60
    )->store;
61
62
    # Create account lines and links
63
    my $fee1 = $patron1->account->add_debit(
64
        {
65
            amount      => 2.00,
66
            description => 'Hold fee 1',
67
            type        => 'RESERVE',
68
            interface   => 'intranet'
69
        }
70
    );
71
72
    my $fee2 = $patron2->account->add_debit(
73
        {
74
            amount      => 3.00,
75
            description => 'Hold fee 2',
76
            type        => 'RESERVE',
77
            interface   => 'intranet'
78
        }
79
    );
80
81
    $fee1->add_link( 'hold', $hold1->id );
82
    $fee2->add_link( 'hold', $hold2->id );
83
84
    # Test collection methods
85
    my $all_links = Koha::Account::Links->search( {} );
86
    is( $all_links->count, 2, 'Found both links in collection' );
87
88
    my $hold_links = $all_links->by_link_type('hold');
89
    is( $hold_links->count, 2, 'by_link_type filters correctly' );
90
91
    my $specific_links = $all_links->by_linked_id( $hold1->id );
92
    is( $specific_links->count, 1, 'by_linked_id filters correctly' );
93
94
    $schema->storage->txn_rollback;
95
};
96
97
subtest 'Filtering methods' => sub {
98
    plan tests => 4;
99
100
    $schema->storage->txn_begin;
101
102
    # Create diverse test data
103
    my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
104
    my $biblio = $builder->build_sample_biblio();
105
    my $item   = $builder->build_sample_item( { biblionumber => $biblio->biblionumber } );
106
107
    # Create hold
108
    my $hold = Koha::Hold->new(
109
        {
110
            borrowernumber => $patron->borrowernumber,
111
            biblionumber   => $biblio->biblionumber,
112
            itemnumber     => $item->itemnumber,
113
            branchcode     => $patron->branchcode,
114
            reservedate    => '2023-01-01',
115
            priority       => 1,
116
        }
117
    )->store;
118
119
    # Create checkout
120
    my $checkout = Koha::Checkout->new(
121
        {
122
            borrowernumber => $patron->borrowernumber,
123
            itemnumber     => $item->itemnumber,
124
            issuedate      => '2023-01-01',
125
            date_due       => '2023-01-15',
126
            branchcode     => $patron->branchcode,
127
        }
128
    )->store;
129
130
    # Create different types of fees
131
    my $hold_fee = $patron->account->add_debit(
132
        {
133
            amount      => 2.00,
134
            description => 'Hold fee',
135
            type        => 'RESERVE',
136
            interface   => 'intranet'
137
        }
138
    );
139
140
    my $overdue_fee = $patron->account->add_debit(
141
        {
142
            amount      => 5.00,
143
            description => 'Overdue fee',
144
            type        => 'OVERDUE',
145
            interface   => 'intranet'
146
        }
147
    );
148
149
    my $manual_fee = $patron->account->add_debit(
150
        {
151
            amount      => 1.00,
152
            description => 'Manual fee',
153
            type        => 'MANUAL',
154
            interface   => 'intranet'
155
        }
156
    );
157
158
    # Create links
159
    $hold_fee->add_link( 'hold', $hold->id );
160
    $overdue_fee->add_link( 'checkout', $checkout->id );
161
162
    # Manual fee has no link
163
164
    my $all_links = Koha::Account::Links->search( {} );
165
    is( $all_links->count, 2, 'Total links created correctly' );
166
167
    # Test filtering by type
168
    my $hold_links = $all_links->by_link_type('hold');
169
    is( $hold_links->count, 1, 'Hold links filtered correctly' );
170
171
    my $checkout_links = $all_links->by_link_type('checkout');
172
    is( $checkout_links->count, 1, 'Checkout links filtered correctly' );
173
174
    # Test filtering by ID
175
    my $hold_id_links = $all_links->by_linked_id( $hold->id );
176
    is( $hold_id_links->count, 1, 'Links filtered by ID correctly' );
177
178
    $schema->storage->txn_rollback;
179
};
180
181
subtest 'Collection methods for related objects' => sub {
182
    plan tests => 4;
183
184
    $schema->storage->txn_begin;
185
186
    my $patron  = $builder->build_object( { class => 'Koha::Patrons' } );
187
    my $biblio1 = $builder->build_sample_biblio();
188
    my $biblio2 = $builder->build_sample_biblio();
189
190
    # Create multiple holds
191
    my $hold1 = Koha::Hold->new(
192
        {
193
            borrowernumber => $patron->borrowernumber,
194
            biblionumber   => $biblio1->biblionumber,
195
            branchcode     => $patron->branchcode,
196
            reservedate    => '2023-01-01',
197
            priority       => 1,
198
        }
199
    )->store;
200
201
    my $hold2 = Koha::Hold->new(
202
        {
203
            borrowernumber => $patron->borrowernumber,
204
            biblionumber   => $biblio2->biblionumber,
205
            branchcode     => $patron->branchcode,
206
            reservedate    => '2023-01-02',
207
            priority       => 1,
208
        }
209
    )->store;
210
211
    # Create fees for both holds
212
    my $fee1 = $patron->account->add_debit(
213
        {
214
            amount      => 2.00,
215
            description => 'Hold fee 1',
216
            type        => 'RESERVE',
217
            interface   => 'intranet'
218
        }
219
    );
220
221
    my $fee2 = $patron->account->add_debit(
222
        {
223
            amount      => 3.00,
224
            description => 'Hold fee 2',
225
            type        => 'RESERVE',
226
            interface   => 'intranet'
227
        }
228
    );
229
230
    # Link fees to holds
231
    $fee1->add_link( 'hold', $hold1->id );
232
    $fee2->add_link( 'hold', $hold2->id );
233
234
    # Test holds collection method
235
    my $links = Koha::Account::Links->search( {} );
236
    my @holds = $links->holds();
237
238
    is( scalar @holds, 2, 'holds() method returns correct number of holds' );
239
240
    my @hold_ids     = sort map { $_->id } @holds;
241
    my @expected_ids = sort ( $hold1->id, $hold2->id );
242
243
    is_deeply( \@hold_ids, \@expected_ids, 'holds() method returns correct holds' );
244
245
    # Test checkouts collection method (should be empty in this test)
246
    my @checkouts = $links->checkouts();
247
    is( scalar @checkouts, 0, 'checkouts() method returns empty array when no checkouts linked' );
248
249
    # Test filtering and then getting related objects
250
    my $hold1_links    = $links->by_linked_id( $hold1->id );
251
    my @filtered_holds = $hold1_links->holds();
252
    is( scalar @filtered_holds, 1, 'Filtered links return correct number of holds' );
253
254
    $schema->storage->txn_rollback;
255
};
256
257
subtest 'Integration with account line methods' => sub {
258
    plan tests => 6;
259
260
    $schema->storage->txn_begin;
261
262
    my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
263
    my $biblio = $builder->build_sample_biblio();
264
    my $item   = $builder->build_sample_item( { biblionumber => $biblio->biblionumber } );
265
266
    # Create hold and checkout
267
    my $hold = Koha::Hold->new(
268
        {
269
            borrowernumber => $patron->borrowernumber,
270
            biblionumber   => $biblio->biblionumber,
271
            itemnumber     => $item->itemnumber,
272
            branchcode     => $patron->branchcode,
273
            reservedate    => '2023-01-01',
274
            priority       => 1,
275
        }
276
    )->store;
277
278
    my $checkout = Koha::Checkout->new(
279
        {
280
            borrowernumber => $patron->borrowernumber,
281
            itemnumber     => $item->itemnumber,
282
            issuedate      => '2023-01-01',
283
            date_due       => '2023-01-15',
284
            branchcode     => $patron->branchcode,
285
        }
286
    )->store;
287
288
    # Create account line
289
    my $account_line = $patron->account->add_debit(
290
        {
291
            amount      => 4.00,
292
            description => 'Mixed fee',
293
            type        => 'MANUAL',
294
            interface   => 'intranet'
295
        }
296
    );
297
298
    # Link to both hold and checkout (edge case)
299
    $account_line->add_link( 'hold',     $hold->id );
300
    $account_line->add_link( 'checkout', $checkout->id );
301
302
    # Test account line can access all its links
303
    my $links = $account_line->links;
304
    is( $links->count, 2, 'Account line has both links' );
305
306
    # Test account line can get specific types
307
    my @holds = $account_line->holds;
308
    is( scalar @holds, 1,         'Account line holds() method works' );
309
    is( $holds[0]->id, $hold->id, 'Correct hold returned' );
310
311
    my @checkouts = $account_line->checkouts;
312
    is( scalar @checkouts, 1,             'Account line checkouts() method works' );
313
    is( $checkouts[0]->id, $checkout->id, 'Correct checkout returned' );
314
315
    # Test hold can find its account lines
316
    my $hold_fees = $hold->debits;
317
    is( $hold_fees->count, 1, 'Hold can find its account lines' );
318
319
    $schema->storage->txn_rollback;
320
};
321
322
$schema->storage->txn_rollback;

Return to bug 40808