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

(-)a/Koha/Account/Line.pm (+62 lines)
Lines 23-28 use C4::Log qw( logaction ); Link Here
23
23
24
use Koha::Account::CreditType;
24
use Koha::Account::CreditType;
25
use Koha::Account::DebitType;
25
use Koha::Account::DebitType;
26
use Koha::Account::Link;
27
use Koha::Account::Links;
26
use Koha::Account::Offsets;
28
use Koha::Account::Offsets;
27
use Koha::Database;
29
use Koha::Database;
28
use Koha::DateUtils qw( dt_from_string );
30
use Koha::DateUtils qw( dt_from_string );
Lines 1100-1105 sub store { Link Here
1100
    return $self->SUPER::store();
1102
    return $self->SUPER::store();
1101
}
1103
}
1102
1104
1105
=head3 add_link
1106
1107
Add a link to another entity (hold, checkout, article request, etc.)
1108
1109
    $account_line->add_link('hold', $hold_id);
1110
1111
=cut
1112
1113
sub add_link {
1114
    my ( $self, $link_type, $linked_id ) = @_;
1115
1116
    return Koha::Account::Link->new(
1117
        {
1118
            accountlines_id => $self->id,
1119
            link_type       => $link_type,
1120
            linked_id       => $linked_id,
1121
        }
1122
    )->store;
1123
}
1124
1125
=head3 links
1126
1127
Get all links for this account line
1128
1129
    my $links = $account_line->links;
1130
1131
=cut
1132
1133
sub links {
1134
    my ($self) = @_;
1135
1136
    my $links_rs = $self->_result->search_related('accountline_links');
1137
    return Koha::Account::Links->_new_from_dbic($links_rs);
1138
}
1139
1140
=head3 holds
1141
1142
Get all holds linked to this account line
1143
1144
    my @holds = $account_line->holds;
1145
1146
=cut
1147
1148
sub holds {
1149
    my ($self) = @_;
1150
1151
    # Get all hold IDs - we only use 'hold' link_type for both current and old holds
1152
    my @hold_ids = $self->links->search( { link_type => 'hold' } )->get_column('linked_id');
1153
1154
    return () unless @hold_ids;
1155
1156
    # Search both current holds and old holds with the same IDs
1157
    # The reserve_id is the same in both tables
1158
    my @holds = Koha::Holds->search( { reserve_id => { -in => \@hold_ids } } )->as_list;
1159
1160
    my @old_holds = Koha::Old::Holds->search( { reserve_id => { -in => \@hold_ids } } )->as_list;
1161
1162
    return ( @holds, @old_holds );
1163
}
1164
1103
=head2 Internal methods
1165
=head2 Internal methods
1104
1166
1105
=cut
1167
=cut
(-)a/Koha/Account/Link.pm (+183 lines)
Line 0 Link Here
1
package Koha::Account::Link;
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 Carp qw( croak );
21
use Koha::Exceptions::Account;
22
23
use base qw(Koha::Object);
24
25
=head1 NAME
26
27
Koha::Account::Link - Koha Account Link Object class
28
29
=head1 API
30
31
=head2 Class methods
32
33
=head3 store
34
35
Validates the link before storing
36
37
=cut
38
39
sub store {
40
    my ($self) = @_;
41
42
    my $link_type = $self->link_type;
43
    my $linked_id = $self->linked_id;
44
45
    # Check for valid link type first
46
    my $validators = {
47
        'hold' => sub { Koha::Holds->find( $_[0] ) || Koha::Old::Holds->find( $_[0] ) },
48
    };
49
50
    unless ( exists $validators->{$link_type} ) {
51
        Koha::Exceptions::Account::InvalidLinkType->throw("Unknown link_type: $link_type");
52
    }
53
54
    # Validate the linked entity exists
55
    unless ( $self->_validate_link_integrity() ) {
56
        Koha::Exceptions::Account::InvalidLinkTarget->throw(
57
            "Invalid link target: " . $link_type . " with ID " . $linked_id . " does not exist" );
58
    }
59
60
    return $self->SUPER::store();
61
}
62
63
=head3 linked_object
64
65
Returns the linked object based on link_type and linked_id
66
67
=cut
68
69
sub linked_object {
70
    my ($self) = @_;
71
72
    return $self->_result->linked_object;
73
}
74
75
=head3 linked_koha_object
76
77
Returns the Koha::Object representation of the linked object
78
79
=cut
80
81
sub linked_koha_object {
82
    my ($self) = @_;
83
84
    # Special handling for holds - they can return either Koha::Hold or Koha::Old::Hold
85
    if ( $self->link_type eq 'hold' ) {
86
        my $dbic_object = $self->linked_object;
87
        return unless $dbic_object;
88
89
        # Check which table the result came from by examining the result source
90
        my $source_name = $dbic_object->result_source->source_name;
91
92
        if ( $source_name eq 'Reserve' ) {
93
            require Koha::Hold;
94
            return Koha::Hold->_new_from_dbic($dbic_object);
95
        } elsif ( $source_name eq 'OldReserve' ) {
96
            require Koha::Old::Hold;
97
            return Koha::Old::Hold->_new_from_dbic($dbic_object);
98
        }
99
100
        return;    # Unknown source
101
    }
102
103
    # Handle other link types normally
104
    my $class_map = {
105
        'checkout'        => 'Koha::Checkout',
106
        'old_checkout'    => 'Koha::Old::Checkout',
107
        'article_request' => 'Koha::ArticleRequest',
108
    };
109
110
    my $class = $class_map->{ $self->link_type };
111
    return unless $class;
112
113
    # Load the class if needed
114
    eval "require $class";
115
    if ($@) {
116
        Koha::Exceptions::Account::InvalidLinkType->throw(
117
            "Could not load class $class for link_type '" . $self->link_type . "': $@" );
118
    }
119
120
    return $class->_new_from_dbic( $self->linked_object );
121
}
122
123
=head3 _validate_link_integrity
124
125
Internal method to validate that the linked entity exists
126
127
=cut
128
129
sub _validate_link_integrity {
130
    my ($self) = @_;
131
132
    my $link_type = $self->link_type;
133
    my $linked_id = $self->linked_id;
134
135
    # Define valid link types and their validation methods
136
    my $validators = {
137
        'hold' => sub { Koha::Holds->find( $_[0] ) || Koha::Old::Holds->find( $_[0] ) },
138
    };
139
140
    my $validator = $validators->{$link_type};
141
    return 0 unless $validator;    # Invalid link type
142
143
    return $validator->($linked_id) ? 1 : 0;
144
}
145
146
=head2 Class Methods
147
148
=head3 _type
149
150
=cut
151
152
sub _type {
153
    return 'AccountlineLink';
154
}
155
156
=head1 AUTHOR
157
158
Koha Development Team <http://koha-community.org/>
159
160
=head1 COPYRIGHT
161
162
Copyright 2025 Koha Development Team
163
164
=head1 LICENSE
165
166
This file is part of Koha.
167
168
Koha is free software; you can redistribute it and/or modify it
169
under the terms of the GNU General Public License as published by
170
the Free Software Foundation; either version 3 of the License, or
171
(at your option) any later version.
172
173
Koha is distributed in the hope that it will be useful, but
174
WITHOUT ANY WARRANTY; without even the implied warranty of
175
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
176
GNU General Public License for more details.
177
178
You should have received a copy of the GNU General Public License
179
along with Koha; if not, see <http://www.gnu.org/licenses>.
180
181
=cut
182
183
1;
(-)a/Koha/Account/Links.pm (+125 lines)
Line 0 Link Here
1
package Koha::Account::Links;
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 base qw(Koha::Objects);
21
22
=head1 NAME
23
24
Koha::Account::Links - Koha Account Links Object set class
25
26
=head1 API
27
28
=head2 Class methods
29
30
=head3 by_link_type
31
32
Filter links by link_type
33
34
    my $reserve_links = $links->by_link_type('reserve');
35
36
=cut
37
38
sub by_link_type {
39
    my ( $self, $link_type ) = @_;
40
41
    return $self->search( { link_type => $link_type } );
42
}
43
44
=head3 by_linked_id
45
46
Filter links by linked_id
47
48
    my $links = $links->by_linked_id(12345);
49
50
=cut
51
52
sub by_linked_id {
53
    my ( $self, $linked_id ) = @_;
54
55
    return $self->search( { linked_id => $linked_id } );
56
}
57
58
=head3 holds
59
60
Get all holds linked to these account lines
61
62
=cut
63
64
sub holds {
65
    my ($self) = @_;
66
67
    # Get all hold IDs - we only use 'hold' link_type for both current and old holds
68
    my @hold_ids = $self->search( { link_type => 'hold' } )->get_column('linked_id');
69
70
    return () unless @hold_ids;
71
72
    # Search both current holds and old holds with the same IDs
73
    # The reserve_id is the same in both tables
74
    my @holds     = Koha::Holds->search( { reserve_id => { -in => \@hold_ids } } )->as_list;
75
    my @old_holds = Koha::Old::Holds->search( { reserve_id => { -in => \@hold_ids } } )->as_list;
76
77
    return ( @holds, @old_holds );
78
}
79
80
=head2 Class Methods
81
82
=head3 _type
83
84
=cut
85
86
sub _type {
87
    return 'AccountlineLink';
88
}
89
90
=head3 object_class
91
92
=cut
93
94
sub object_class {
95
    return 'Koha::Account::Link';
96
}
97
98
=head1 AUTHOR
99
100
Koha Development Team <http://koha-community.org/>
101
102
=head1 COPYRIGHT
103
104
Copyright 2025 Koha Development Team
105
106
=head1 LICENSE
107
108
This file is part of Koha.
109
110
Koha is free software; you can redistribute it and/or modify it
111
under the terms of the GNU General Public License as published by
112
the Free Software Foundation; either version 3 of the License, or
113
(at your option) any later version.
114
115
Koha is distributed in the hope that it will be useful, but
116
WITHOUT ANY WARRANTY; without even the implied warranty of
117
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
118
GNU General Public License for more details.
119
120
You should have received a copy of the GNU General Public License
121
along with Koha; if not, see <http://www.gnu.org/licenses>.
122
123
=cut
124
125
1;
(-)a/Koha/Exceptions/Account.pm (+16 lines)
Lines 55-60 use Exception::Class ( Link Here
55
    'Koha::Exceptions::Account::InvalidPaymentType' => {
55
    'Koha::Exceptions::Account::InvalidPaymentType' => {
56
        isa         => 'Koha::Exceptions::Account',
56
        isa         => 'Koha::Exceptions::Account',
57
        description => 'Invalid payment type'
57
        description => 'Invalid payment type'
58
    },
59
    'Koha::Exceptions::Account::InvalidLinkType' => {
60
        isa         => 'Koha::Exceptions::Account',
61
        description => 'Invalid account line link type'
62
    },
63
    'Koha::Exceptions::Account::InvalidLinkTarget' => {
64
        isa         => 'Koha::Exceptions::Account',
65
        description => 'Invalid account line link target'
58
    }
66
    }
59
);
67
);
60
68
Lines 98-103 Exception to be used when a passed credit or debit is not of a recognised type. Link Here
98
106
99
Exception to be used when UseCashRegisters is enabled and one is not passed for a transaction.
107
Exception to be used when UseCashRegisters is enabled and one is not passed for a transaction.
100
108
109
=head2 Koha::Exceptions::Account::InvalidLinkType
110
111
Exception to be used when an invalid link type is provided to account line linking.
112
113
=head2 Koha::Exceptions::Account::InvalidLinkTarget
114
115
Exception to be used when an account line link target does not exist or is invalid.
116
101
=cut
117
=cut
102
118
103
1;
119
1;
(-)a/Koha/Hold.pm (-1 / +18 lines)
Lines 1227-1232 sub charge_hold_fee { Link Here
1227
        }
1227
        }
1228
    );
1228
    );
1229
1229
1230
    # Link the account line to this hold
1231
    $line->add_link( 'hold', $self->id );
1232
1230
    return $line;
1233
    return $line;
1231
}
1234
}
1232
1235
Lines 1450-1455 sub strings_map { Link Here
1450
    return $strings;
1453
    return $strings;
1451
}
1454
}
1452
1455
1456
=head3 debits
1457
1458
    my $fees = $hold->debits;
1459
1460
Get all debit account lines (charges) associated with this hold
1461
1462
=cut
1463
1464
sub debits {
1465
    my ($self) = @_;
1466
1467
    my $accountlines_rs = $self->_result->search_related('accountline_links')->search_related('accountline');
1468
    return Koha::Account::Debits->_new_from_dbic($accountlines_rs);
1469
}
1470
1453
=head2 Internal methods
1471
=head2 Internal methods
1454
1472
1455
=head3 _type
1473
=head3 _type
1456
- 

Return to bug 40808