| Lines 23-29
          use Test::More tests => 12;
      
      
        Link Here | 
        
          | 23 | use Test::Warn; | 23 | use Test::Warn; | 
        
          | 24 |  | 24 |  | 
        
          | 25 | use C4::Circulation qw( AddIssue ); | 25 | use C4::Circulation qw( AddIssue ); | 
          
            
              | 26 | use C4::Reserves qw( AddReserve ModReserve ModReserveCancelAll ); | 26 | use C4::Reserves qw( AddReserve CheckReserves ModReserve ModReserveCancelAll ); | 
        
          | 27 | use Koha::AuthorisedValueCategory; | 27 | use Koha::AuthorisedValueCategory; | 
        
          | 28 | use Koha::Biblio::ItemGroups; | 28 | use Koha::Biblio::ItemGroups; | 
        
          | 29 | use Koha::Database; | 29 | use Koha::Database; | 
  
    | Lines 134-171
          subtest 'cancel' => sub {
      
      
        Link Here | 
        
          | 134 |     is( $third_hold->discard_changes->priority, 2, 'Third hold should now be second' ); | 134 |     is( $third_hold->discard_changes->priority, 2, 'Third hold should now be second' ); | 
        
          | 135 |  | 135 |  | 
        
          | 136 |     subtest 'charge_cancel_fee parameter' => sub { | 136 |     subtest 'charge_cancel_fee parameter' => sub { | 
          
            
              | 137 |         plan tests => 4; | 137 |         plan tests => 15; | 
            
              | 138 |         my $patron_category = $builder->build_object({ class => 'Koha::Patron::Categories', value => { reservefee => 0 } } ); | 138 |         my $library1 = $builder->build({ | 
            
              | 139 |         my $patron = $builder->build_object({ class => 'Koha::Patrons', value => { categorycode => $patron_category->categorycode } }); | 139 |             source => 'Branch', | 
            
              | 140 |         is( $patron->account->balance, 0, 'A new patron does not have any charges' ); | 140 |         }); | 
            
              |  |  | 141 |         my $library2 = $builder->build({ | 
            
              | 142 |             source => 'Branch', | 
            
              | 143 |         }); | 
            
              | 144 |  | 
            
              | 145 |         my $bib_title = "Test Title"; | 
            
              | 146 |  | 
            
              | 147 |         my $borrower = $builder->build({ | 
            
              | 148 |             source => 'Borrower', | 
            
              | 149 |             value => { | 
            
              | 150 |                 branchcode => $library1->{branchcode}, | 
            
              | 151 |             } | 
            
              | 152 |         }); | 
            
              | 153 |  | 
            
              | 154 |         my $itemtype1 = $builder->build({ | 
            
              | 155 |             source => 'Itemtype', | 
            
              | 156 |             value => {} | 
            
              | 157 |         }); | 
            
              | 158 |         my $itemtype2 = $builder->build({ | 
            
              | 159 |             source => 'Itemtype', | 
            
              | 160 |             value => {} | 
            
              | 161 |         }); | 
            
              | 162 |         my $itemtype3 = $builder->build({ | 
            
              | 163 |             source => 'Itemtype', | 
            
              | 164 |             value => {} | 
            
              | 165 |         }); | 
            
              | 166 |         my $itemtype4 = $builder->build({ | 
            
              | 167 |             source => 'Itemtype', | 
            
              | 168 |             value => {} | 
            
              | 169 |         }); | 
            
              | 170 |  | 
            
              | 171 |         my $borrowernumber = $borrower->{borrowernumber}; | 
            
              | 172 |  | 
            
              | 173 |         my $library_A_code = $library1->{branchcode}; | 
            
              | 174 |  | 
            
              | 175 |         my $biblio = $builder->build_sample_biblio({itemtype => $itemtype1->{itemtype}}); | 
            
              | 176 |         my $biblionumber = $biblio->biblionumber; | 
            
              | 177 |         my $item1 = $builder->build_sample_item({ | 
            
              | 178 |             biblionumber => $biblionumber, | 
            
              | 179 |             itype => $itemtype1->{itemtype}, | 
            
              | 180 |             homebranch => $library_A_code, | 
            
              | 181 |             holdingbranch => $library_A_code | 
            
              | 182 |         }); | 
            
              | 183 |         my $item2 = $builder->build_sample_item({ | 
            
              | 184 |             biblionumber => $biblionumber, | 
            
              | 185 |             itype => $itemtype2->{itemtype}, | 
            
              | 186 |             homebranch => $library_A_code, | 
            
              | 187 |             holdingbranch => $library_A_code | 
            
              | 188 |         }); | 
            
              | 189 |         my $item3 = $builder->build_sample_item({ | 
            
              | 190 |             biblionumber => $biblionumber, | 
            
              | 191 |             itype => $itemtype3->{itemtype}, | 
            
              | 192 |             homebranch => $library_A_code, | 
            
              | 193 |             holdingbranch => $library_A_code | 
            
              | 194 |         }); | 
            
              | 195 |  | 
            
              | 196 |         my $library_B_code = $library2->{branchcode}; | 
            
              | 197 |  | 
            
              | 198 |         my $biblio2 = $builder->build_sample_biblio({itemtype => $itemtype4->{itemtype}}); | 
            
              | 199 |         my $biblionumber2 = $biblio2->biblionumber; | 
            
              | 200 |         my $item4 = $builder->build_sample_item({ | 
            
              | 201 |             biblionumber => $biblionumber2, | 
            
              | 202 |             itype => $itemtype4->{itemtype}, | 
            
              | 203 |             homebranch => $library_B_code, | 
            
              | 204 |             holdingbranch => $library_B_code | 
            
              | 205 |         }); | 
            
              | 206 |  | 
            
              | 207 |         Koha::CirculationRules->set_rules( | 
            
              | 208 |             { | 
            
              | 209 |                 itemtype     => undef, | 
            
              | 210 |                 categorycode => undef, | 
            
              | 211 |                 branchcode   => undef, | 
            
              | 212 |                 rules        => { | 
            
              | 213 |                     expire_reserves_charge => undef | 
            
              | 214 |                 } | 
            
              | 215 |             } | 
            
              | 216 |         ); | 
            
              | 217 |         Koha::CirculationRules->set_rules( | 
            
              | 218 |             { | 
            
              | 219 |                 itemtype     => $itemtype1->{itemtype}, | 
            
              | 220 |                 categorycode => undef, | 
            
              | 221 |                 branchcode   => undef, | 
            
              | 222 |                 rules        => { | 
            
              | 223 |                     expire_reserves_charge => '111' | 
            
              | 224 |                 } | 
            
              | 225 |             } | 
            
              | 226 |         ); | 
            
              | 227 |         Koha::CirculationRules->set_rules( | 
            
              | 228 |             { | 
            
              | 229 |                 itemtype     => $itemtype2->{itemtype}, | 
            
              | 230 |                 categorycode => undef, | 
            
              | 231 |                 branchcode   => undef, | 
            
              | 232 |                 rules        => { | 
            
              | 233 |                     expire_reserves_charge => undef | 
            
              | 234 |                 } | 
            
              | 235 |             } | 
            
              | 236 |         ); | 
            
              | 237 |         Koha::CirculationRules->set_rules( | 
            
              | 238 |             { | 
            
              | 239 |                 itemtype     => undef, | 
            
              | 240 |                 categorycode => undef, | 
            
              | 241 |                 branchcode   => $library_B_code, | 
            
              | 242 |                 rules        => { | 
            
              | 243 |                     expire_reserves_charge => '444' | 
            
              | 244 |                 } | 
            
              | 245 |             } | 
            
              | 246 |         ); | 
        
          | 141 |  | 247 |  | 
          
            
              | 142 |         my $hold_info = { | 248 |         t::lib::Mocks::mock_preference('ReservesControlBranch', 'ItemHomeLibrary'); | 
            
              | 143 |             branchcode     => $library->branchcode, | 249 |  | 
            
              | 144 |             borrowernumber => $patron->borrowernumber, | 250 |         my $reserve_id; | 
            
              | 145 |             biblionumber   => $item->biblionumber, | 251 |         my $account; | 
            
              | 146 |             priority       => 1, | 252 |         my $status; | 
            
              | 147 |             title          => "title for fee", | 253 |         my $start_balance; | 
            
              | 148 |             itemnumber     => $item->itemnumber, | 254 |  | 
            
              | 149 |         }; | 255 | # TEST: Hold itemtype1 item | 
            
              |  |  | 256 |         $reserve_id = AddReserve( | 
            
              | 257 |             { | 
            
              | 258 |                 branchcode       => $library_A_code, | 
            
              | 259 |                 borrowernumber   => $borrowernumber, | 
            
              | 260 |                 biblionumber     => $biblionumber, | 
            
              | 261 |                 priority         => 1, | 
            
              | 262 |                 itemnumber       => $item1->itemnumber, | 
            
              | 263 |             } | 
            
              | 264 |         ); | 
            
              | 265 |  | 
            
              | 266 |         $account = Koha::Account->new({ patron_id => $borrowernumber }); | 
            
              | 267 |  | 
            
              | 268 |         ( $status ) = CheckReserves($item1->id); | 
            
              | 269 |         is( $status, 'Reserved', "Hold for the itemtype1 created" ); | 
            
              | 270 |  | 
            
              | 271 |         $start_balance = $account->balance(); | 
            
              | 272 |  | 
            
              | 273 |         Koha::Holds->find( $reserve_id )->cancel({ charge_cancel_fee => 1 }); | 
            
              | 274 |  | 
            
              | 275 |         ( $status ) = CheckReserves($item1->id); | 
            
              | 276 |         is( $status, '', "Hold for the itemtype1 cancelled" ); | 
            
              | 277 |  | 
            
              | 278 |         is( $account->balance() - $start_balance, 111, "Used circulation rule for itemtype1" ); | 
            
              | 279 |  | 
            
              | 280 | # TEST: circulation rule for itemtype2 has 'expire_reserves_charge' set undef, so it should use ExpireReservesMaxPickUpDelayCharge preference | 
            
              | 281 |         t::lib::Mocks::mock_preference('ExpireReservesMaxPickUpDelayCharge', 222); | 
            
              | 282 |  | 
            
              | 283 |         $reserve_id = AddReserve( | 
            
              | 284 |             { | 
            
              | 285 |                 branchcode       => $library_A_code, | 
            
              | 286 |                 borrowernumber   => $borrowernumber, | 
            
              | 287 |                 biblionumber     => $biblionumber, | 
            
              | 288 |                 priority         => 1, | 
            
              | 289 |                 itemnumber       => $item2->itemnumber, | 
            
              | 290 |             } | 
            
              | 291 |         ); | 
            
              | 292 |  | 
            
              | 293 |         $account = Koha::Account->new({ patron_id => $borrowernumber }); | 
            
              | 294 |  | 
            
              | 295 |         ( $status ) = CheckReserves($item2->id); | 
            
              | 296 |         is( $status, 'Reserved', "Hold for the itemtype2 created" ); | 
            
              | 297 |  | 
            
              | 298 |         $start_balance = $account->balance(); | 
            
              | 299 |  | 
            
              | 300 |         Koha::Holds->find( $reserve_id )->cancel({ charge_cancel_fee => 1 }); | 
            
              | 301 |  | 
            
              | 302 |         ( $status ) = CheckReserves($item2->id); | 
            
              | 303 |         is( $status, '', "Hold for the itemtype2 cancelled" ); | 
            
              | 304 |  | 
            
              | 305 |         is( $account->balance() - $start_balance, 222, "Used ExpireReservesMaxPickUpDelayCharge preference as expire_reserves_charge set to undef" ); | 
            
              | 306 |  | 
            
              | 307 | # TEST: no circulation rules for itemtype3, it should use ExpireReservesMaxPickUpDelayCharge preference | 
            
              | 308 |         t::lib::Mocks::mock_preference('ExpireReservesMaxPickUpDelayCharge', 333); | 
            
              | 309 |  | 
            
              | 310 |         $reserve_id = AddReserve( | 
            
              | 311 |             { | 
            
              | 312 |                 branchcode       => $library_A_code, | 
            
              | 313 |                 borrowernumber   => $borrowernumber, | 
            
              | 314 |                 biblionumber     => $biblionumber, | 
            
              | 315 |                 priority         => 1, | 
            
              | 316 |                 itemnumber       => $item3->itemnumber, | 
            
              | 317 |             } | 
            
              | 318 |         ); | 
            
              | 319 |  | 
            
              | 320 |         $account = Koha::Account->new({ patron_id => $borrowernumber }); | 
            
              | 321 |  | 
            
              | 322 |         ( $status ) = CheckReserves($item3->id); | 
            
              | 323 |         is( $status, 'Reserved', "Hold for the itemtype3 created" ); | 
            
              | 324 |  | 
            
              | 325 |         $start_balance = $account->balance(); | 
            
              | 326 |  | 
            
              | 327 |         Koha::Holds->find( $reserve_id )->cancel({ charge_cancel_fee => 1 }); | 
            
              | 328 |  | 
            
              | 329 |         ( $status ) = CheckReserves($item3->id); | 
            
              | 330 |         is( $status, '', "Hold for the itemtype3 cancelled" ); | 
            
              | 331 |  | 
            
              | 332 |         is( $account->balance() - $start_balance, 333, "Used ExpireReservesMaxPickUpDelayCharge preference as there's no circulation rules for itemtype3" ); | 
            
              | 333 |  | 
            
              | 334 | # TEST: circulation rule for itemtype4 with library_B_code | 
            
              | 335 |         t::lib::Mocks::mock_preference('ExpireReservesMaxPickUpDelayCharge', 555); | 
            
              | 336 |  | 
            
              | 337 |         $reserve_id = AddReserve( | 
            
              | 338 |             { | 
            
              | 339 |                 branchcode       => $library_B_code, | 
            
              | 340 |                 borrowernumber   => $borrowernumber, | 
            
              | 341 |                 biblionumber     => $biblionumber2, | 
            
              | 342 |                 priority         => 1, | 
            
              | 343 |                 itemnumber       => $item4->itemnumber, | 
            
              | 344 |             } | 
            
              | 345 |         ); | 
            
              | 346 |  | 
            
              | 347 |         $account = Koha::Account->new({ patron_id => $borrowernumber }); | 
            
              | 348 |  | 
            
              | 349 |         ( $status ) = CheckReserves($item4->id); | 
            
              | 350 |         is( $status, 'Reserved', "Hold for the itemtype4 created" ); | 
            
              | 351 |  | 
            
              | 352 |         $start_balance = $account->balance(); | 
            
              | 353 |  | 
            
              | 354 |         Koha::Holds->find( $reserve_id )->cancel({ charge_cancel_fee => 1 }); | 
            
              | 355 |  | 
            
              | 356 |         ( $status ) = CheckReserves($item4->id); | 
            
              | 357 |         is( $status, '', "Hold for the itemtype4 cancelled" ); | 
            
              | 358 |  | 
            
              | 359 |         is( $account->balance() - $start_balance, 444, "Used circulation rule for itemtype4 with library_B_code" ); | 
            
              | 360 |  | 
            
              | 361 |         $reserve_id = AddReserve( | 
            
              | 362 |             { | 
            
              | 363 |                 branchcode       => $library_B_code, | 
            
              | 364 |                 borrowernumber   => $borrowernumber, | 
            
              | 365 |                 biblionumber     => $biblionumber2, | 
            
              | 366 |                 priority         => 1, | 
            
              | 367 |                 itemnumber       => $item4->itemnumber, | 
            
              | 368 |             } | 
            
              | 369 |         ); | 
            
              | 370 |  | 
            
              | 371 |         $account = Koha::Account->new({ patron_id => $borrowernumber }); | 
            
              | 372 |  | 
            
              | 373 |         ( $status ) = CheckReserves($item4->id); | 
            
              | 374 |         is( $status, 'Reserved', "Hold for the itemtype4 created" ); | 
        
          | 150 |  | 375 |  | 
          
            
              | 151 |         # First, test cancelling a reserve when there's no charge configured. | 376 |         $start_balance = $account->balance(); | 
            
              | 152 |         t::lib::Mocks::mock_preference('ExpireReservesMaxPickUpDelayCharge', 0); |  |  | 
            
              | 153 |         my $reserve_id = C4::Reserves::AddReserve( $hold_info ); | 
            
              | 154 |         Koha::Holds->find( $reserve_id )->cancel( { charge_cancel_fee => 1 } ); | 
            
              | 155 |         is( $patron->account->balance, 0, 'ExpireReservesMaxPickUpDelayCharge=0 - The patron should not have been charged' ); | 
        
          | 156 |  | 377 |  | 
          
            
              | 157 |         # Then, test cancelling a reserve when there's no charge desired. | 378 |         Koha::Holds->find( $reserve_id )->cancel({ charge_cancel_fee => 0 }); | 
            
              | 158 |         t::lib::Mocks::mock_preference('ExpireReservesMaxPickUpDelayCharge', 42); |  |  | 
            
              | 159 |         $reserve_id = C4::Reserves::AddReserve( $hold_info ); | 
            
              | 160 |         Koha::Holds->find( $reserve_id )->cancel(); # charge_cancel_fee => 0 | 
            
              | 161 |         is( $patron->account->balance, 0, 'ExpireReservesMaxPickUpDelayCharge=42, but charge_cancel_fee => 0, The patron should not have been charged' ); | 
        
          | 162 |  | 379 |  | 
            
              |  |  | 380 |         ( $status ) = CheckReserves($item4->id); | 
            
              | 381 |         is( $status, '', "Hold for the itemtype4 cancelled" ); | 
        
          | 163 |  | 382 |  | 
          
            
              | 164 |         # Finally, test cancelling a reserve when there's a charge desired and configured. | 383 |         is( $account->balance() - $start_balance, 0, "Patron not charged when charge_cancel_fee is 0" ); | 
            
              | 165 |         t::lib::Mocks::mock_preference('ExpireReservesMaxPickUpDelayCharge', 42); |  |  | 
            
              | 166 |         $reserve_id = C4::Reserves::AddReserve( $hold_info ); | 
            
              | 167 |         Koha::Holds->find( $reserve_id )->cancel( { charge_cancel_fee => 1 } ); | 
            
              | 168 |         is( int($patron->account->balance), 42, 'ExpireReservesMaxPickUpDelayCharge=42 and charge_cancel_fee => 1, The patron should have been charged!' ); | 
        
          | 169 |     }; | 384 |     }; | 
        
          | 170 |  | 385 |  | 
        
          | 171 |     subtest 'waiting hold' => sub { | 386 |     subtest 'waiting hold' => sub { | 
            
              | 172 | -  |  |  |