@@ -19,9 +19,10 @@ use Modern::Perl;
1919
2020use base qw( Koha::Plugins::Base) ;
2121use utf8;
22- use JSON qw( decode_json ) ;
22+ use JSON qw( decode_json encode_json ) ;
2323use Try::Tiny;
2424use Cwd qw( abs_path) ;
25+ use Data::Dumper;
2526
2627use C4::Context;
2728use C4::Koha qw( GetAuthorisedValues ) ;
@@ -36,15 +37,16 @@ use Koha::List::Patron qw( GetPatronLists );
3637use Koha::Patron::Attribute::Types;
3738use Koha::Patron::Categories;
3839use Koha::Plugin::Com::LMSCloud::LatePaymentClaiming::LatePaymentClaimingConfiguration;
40+ use Koha::Plugin::Com::LMSCloud::LatePaymentClaiming::LatePaymentClaiming;
3941
40- our $VERSION = " 0.2 .0" ;
42+ our $VERSION = " 0.3 .0" ;
4143our $MINIMUM_VERSION = " 22.11" ;
4244
4345our $metadata = {
4446 name => ' Gebührenmahnung' ,
4547 author => ' LMSCloud GmbH' ,
4648 date_authored => ' 2026-02-15' ,
47- date_updated => " 2026-03-26 " ,
49+ date_updated => " 2026-03-30 " ,
4850 minimum_version => $MINIMUM_VERSION ,
4951 maximum_version => undef ,
5052 version => $VERSION ,
@@ -76,6 +78,9 @@ sub configure {
7678 execution_monthes => scalar $cgi -> param(' execution_monthes' ) || ' *' ,
7779 execution_weekdays => scalar $cgi -> param(' execution_weekdays' ) || ' *' ,
7880 execution_on_closing_days => scalar $cgi -> param(' execution_on_closing_days' ) || ' yes' ,
81+ account_balance_for_closing => scalar $cgi -> param(' account_balance_for_closing' ) || ' 0.0' ,
82+ unban_actions => scalar $cgi -> param(' unban_actions' ) || ' []' ,
83+ do_automatic_close_on_payment => (scalar $cgi -> param(' do_automatic_close_on_payment' )) + 0
7984 }
8085 );
8186 }
@@ -84,75 +89,81 @@ sub configure {
8489
8590 my $do = $cgi -> param(' do' ) || ' ' ;
8691
87- if ( $do eq ' edit' ) {
8892
89- # get debit types
90- my @debit_types = Koha::Account::DebitTypes-> search_with_library_limits({ can_be_invoiced => 1, archived => 0 },{})-> as_list;
91-
92- # get restriction types
93- my @restriction_types = Koha::Patron::Restriction::Types-> search()-> as_list;
93+
94+ # get debit types
95+ my @debit_types = Koha::Account::DebitTypes-> search_with_library_limits({ can_be_invoiced => 1, archived => 0 },{})-> as_list;
9496
95- # get the patron attributes list
96- my @patron_attributes_values ;
97- my @patron_attributes_codes ;
98- my $library_id = C4::Context-> userenv ? C4::Context-> userenv-> {' branch' } : undef ;
99- my $patron_attribute_types = Koha::Patron::Attribute::Types-> search_with_library_limits({}, {}, $library_id );
100- my @patron_categories = Koha::Patron::Categories-> search_with_library_limits({}, {order_by => [' description' ]})-> as_list;
101- while ( my $attr_type = $patron_attribute_types -> next ) {
102- next if $attr_type -> repeatable;
103- next if $attr_type -> unique_id; # Don't display patron attributes that must be unqiue
104- my $options = $attr_type -> authorised_value_category
105- ? GetAuthorisedValues( $attr_type -> authorised_value_category )
106- : undef ;
107- push @patron_attributes_values ,
108- {
109- attribute_code => $attr_type -> code,
110- options => $options ,
111- };
112-
113- my $category_code = $attr_type -> category_code;
114- my ( $category_lib ) = map {
115- ( defined $category_code and $attr_type -> category_code eq $category_code ) ? $attr_type -> description : ()
116- } @patron_categories ;
117- push @patron_attributes_codes ,
118- {
119- attribute_code => $attr_type -> code,
120- attribute_lib => $attr_type -> description,
121- category_lib => $category_lib ,
122- type => $attr_type -> authorised_value_category ? ' select' : ' text' ,
123- };
124- }
97+ # get restriction types
98+ my @restriction_types = Koha::Patron::Restriction::Types-> search()-> as_list;
99+
100+ # get the patron attributes list
101+ my @patron_attributes_values ;
102+ my @patron_attributes_codes ;
103+ my $library_id = C4::Context-> userenv ? C4::Context-> userenv-> {' branch' } : undef ;
104+ my $patron_attribute_types = Koha::Patron::Attribute::Types-> search_with_library_limits({}, {}, $library_id );
105+ my @patron_categories = Koha::Patron::Categories-> search_with_library_limits({}, {order_by => [' description' ]})-> as_list;
106+ while ( my $attr_type = $patron_attribute_types -> next ) {
107+ next if $attr_type -> repeatable;
108+ next if $attr_type -> unique_id; # Don't display patron attributes that must be unqiue
109+ my $options = $attr_type -> authorised_value_category
110+ ? GetAuthorisedValues( $attr_type -> authorised_value_category )
111+ : undef ;
112+ push @patron_attributes_values ,
113+ {
114+ attribute_code => $attr_type -> code,
115+ options => $options ,
116+ };
117+
118+ my $category_code = $attr_type -> category_code;
119+ my ( $category_lib ) = map {
120+ ( defined $category_code and $attr_type -> category_code eq $category_code ) ? $attr_type -> description : ()
121+ } @patron_categories ;
122+ push @patron_attributes_codes ,
123+ {
124+ attribute_code => $attr_type -> code,
125+ attribute_lib => $attr_type -> description,
126+ category_lib => $category_lib ,
127+ type => $attr_type -> authorised_value_category ? ' select' : ' text' ,
128+ };
129+ }
125130
131+ if ( $do eq ' edit' ) {
126132 my $action = $cgi -> param(' do' );
127133 if ( $action && $action eq ' edit' ) {
128134 $template -> param(
129135 action => ' edit_config'
130136 );
131137 }
132-
133- my $currency = Koha::Acquisition::Currencies-> get_active;
134-
135- my $dbh = C4::Context-> dbh;
136- my $selectLetter = q{ SELECT code, module, name, GROUP_CONCAT(DISTINCT message_transport_type SEPARATOR ',') message_transport_type
137- FROM letter
138- WHERE module IN ('members')
139- GROUP BY code, module, name
140- ORDER BY name} ;
141- my $letters = $dbh -> selectall_arrayref($selectLetter ,{ Slice => {} });
142-
143- $template -> param(
144- last_upgraded => $self -> retrieve_data(' last_upgraded' ),
145- debit_types => \@debit_types ,
146- restriction_types => \@restriction_types ,
147- patron_attributes_codes => \@patron_attributes_codes ,
148- patron_attributes_values => \@patron_attributes_values ,
149- patron_lists => [ GetPatronLists() ],
150- library_id => scalar $cgi -> param(' library_id' ),
151- category_id => scalar $cgi -> param(' category_id' ),
152- currency => ($currency ) ? $currency -> symbol : ' ' ,
153- patronLetters => $letters
154- );
155138 }
139+
140+ my $currency = Koha::Acquisition::Currencies-> get_active;
141+
142+ my $dbh = C4::Context-> dbh;
143+ my $selectLetter = q{ SELECT code, module, name, GROUP_CONCAT(DISTINCT message_transport_type SEPARATOR ',') message_transport_type
144+ FROM letter
145+ WHERE module IN ('members')
146+ GROUP BY code, module, name
147+ ORDER BY name} ;
148+ my $letters = $dbh -> selectall_arrayref($selectLetter ,{ Slice => {} });
149+
150+ $template -> param(
151+ last_upgraded => $self -> retrieve_data(' last_upgraded' ),
152+ debit_types => \@debit_types ,
153+ restriction_types => \@restriction_types ,
154+ patron_attributes_codes => \@patron_attributes_codes ,
155+ patron_attributes_values => \@patron_attributes_values ,
156+ patron_lists => [ GetPatronLists() ],
157+ library_id => scalar $cgi -> param(' library_id' ),
158+ category_id => scalar $cgi -> param(' category_id' ),
159+ currency => ($currency ) ? $currency -> symbol : ' ' ,
160+ patronLetters => $letters ,
161+ defaultStrings => {
162+ letter_charge_description => ' Benachrichtigungsgebühr für [% claim.level %]. Gebührenmahnung' ,
163+ letter_charge_note => ' [% claim.level %]. Gebührenmahnung vom [% today %]' ,
164+ fee_note => ' [% claim.level %]. Gebührenmahnung vom [% today %]' ,
165+ },
166+ );
156167
157168 my $config = Koha::Plugin::Com::LMSCloud::LatePaymentClaiming::LatePaymentClaimingConfiguration-> new();
158169
@@ -162,6 +173,9 @@ sub configure {
162173 execution_monthes => $self -> retrieve_data(' execution_monthes' ) || ' *' ,
163174 execution_weekdays => $self -> retrieve_data(' execution_weekdays' ) || ' *' ,
164175 execution_on_closing_days => $self -> retrieve_data(' execution_on_closing_days' ) || ' yes' ,
176+ account_balance_for_closing => $self -> retrieve_data(' account_balance_for_closing' ) || ' 0.0' ,
177+ unban_actions => $self -> retrieve_data(' unban_actions' ) || ' []' ,
178+ do_automatic_close_on_payment => $self -> retrieve_data(' do_automatic_close_on_payment' ) + 0,
165179 configurations => $config -> getConfigurationList()
166180 );
167181
@@ -192,6 +206,44 @@ sub tool {
192206 }
193207}
194208
209+ sub after_account_action {
210+ my ($self , $args ) = @_ ;
211+
212+ my $do_automatic_close_on_payment = ($self -> retrieve_data(' do_automatic_close_on_payment' )) + 0;
213+
214+ return if (! $do_automatic_close_on_payment );
215+
216+ my $line ;
217+ if ( exists ($args -> {payload }) && exists ($args -> {payload }-> {line }) ) {
218+ $line = $args -> {payload }-> {line };
219+ }
220+ if ( exists ($args -> {action }) && $args -> {action } eq " add_credit" ) {
221+ if ( $line && $line -> borrowernumber ) {
222+ my $dbh = C4::Context-> dbh;
223+ my $claim = $dbh -> selectrow_hashref(" SELECT * FROM lmsc_late_payment_claim WHERE borrowernumber = ?" ,undef ,$line -> borrowernumber);
224+ if ( $claim ) {
225+ my $patron = Koha::Patrons-> find( $line -> borrowernumber );
226+ if ( $patron ) {
227+ my $balance = $patron -> account-> balance;
228+ $balance = 0.0 if (!defined $balance );
229+ $balance += 0.0;
230+ my $checkAmount = $self -> retrieve_data(' account_balance_for_closing' ) + 0.0;
231+ if ( $balance <= $checkAmount ) {
232+ print STDERR " after_account_action: Patron " , $line -> borrowernumber, " reached level to close claim\n " ;
233+
234+ my $json = JSON-> new-> allow_nonref;
235+ my $unbanJSON = $self -> retrieve_data(' unban_actions' ) || ' []' ;
236+ my $unbanActions = $json -> decode( $unbanJSON );
237+
238+ my $claiming = Koha::Plugin::Com::LMSCloud::LatePaymentClaiming::LatePaymentClaiming-> new();
239+ $claiming -> closePaidLatePaymentClaim($patron ,$claim ,$unbanActions );
240+ }
241+ }
242+ }
243+ }
244+ }
245+ }
246+
195247sub claimHistory {
196248 my ($self , $args ) = @_ ;
197249
@@ -311,6 +363,13 @@ sub install {
311363 CONSTRAINT `lmsc_lpcr_ibfk_2` FOREIGN KEY (`categorycode`) REFERENCES `categories` (`categorycode`) ON DELETE CASCADE ON UPDATE CASCADE
312364 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
313365 } );
366+
367+ C4::Context-> dbh-> do(
368+ q{
369+ INSERT IGNORE INTO account_debit_types ( code, description, can_be_invoiced, can_be_sold, default_amount, is_system )
370+ VALUES ('LATE_PAYMENT_CLAIM', 'Gebührenmahnung', 1, 0, NULL, 1);
371+ }
372+ );
314373 my $dt = dt_from_string();
315374 $self -> store_data( { last_upgraded => $dt -> ymd(' -' ) . ' ' . $dt -> hms(' :' ) } );
316375
0 commit comments