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

(-)a/Koha/Schema/Result/Issue.pm (-4 / +28 lines)
Lines 184-193 __PACKAGE__->belongs_to( Link Here
184
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ZEh31EKBmURMKxDxI+H3EA
184
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ZEh31EKBmURMKxDxI+H3EA
185
185
186
__PACKAGE__->belongs_to(
186
__PACKAGE__->belongs_to(
187
  "borrower",
187
    "borrower",
188
  "Koha::Schema::Result::Borrower",
188
    "Koha::Schema::Result::Borrower",
189
  { borrowernumber => "borrowernumber" },
189
    { borrowernumber => "borrowernumber" },
190
  { join_type => "LEFT", on_delete => "CASCADE", on_update => "CASCADE" },
190
    { join_type => "LEFT", on_delete => "CASCADE", on_update => "CASCADE" },
191
);
192
193
__PACKAGE__->belongs_to(
194
  "item",
195
  "Koha::Schema::Result::Item",
196
  { itemnumber => "itemnumber" },
197
  {
198
    is_deferrable => 1,
199
    join_type     => "LEFT",
200
    on_delete     => "CASCADE",
201
    on_update     => "CASCADE",
202
  },
203
);
204
205
__PACKAGE__->belongs_to(
206
  "branch",
207
  "Koha::Schema::Result::Branch",
208
  { branchcode => "branchcode" },
209
  {
210
    is_deferrable => 1,
211
    join_type     => "LEFT",
212
    on_delete     => "CASCADE",
213
    on_update     => "CASCADE",
214
  },
191
);
215
);
192
216
193
1;
217
1;
(-)a/Koha/Schema/Result/Reserve.pm (-1 / +23 lines)
Lines 288-293 __PACKAGE__->belongs_to( Link Here
288
# Created by DBIx::Class::Schema::Loader v0.07025 @ 2013-10-14 20:56:21
288
# Created by DBIx::Class::Schema::Loader v0.07025 @ 2013-10-14 20:56:21
289
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ig/fobzvZf1OgAHZFtkyyQ
289
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ig/fobzvZf1OgAHZFtkyyQ
290
290
291
__PACKAGE__->belongs_to(
292
  "item",
293
  "Koha::Schema::Result::Item",
294
  { itemnumber => "itemnumber" },
295
  {
296
    is_deferrable => 1,
297
    join_type     => "LEFT",
298
    on_delete     => "CASCADE",
299
    on_update     => "CASCADE",
300
  },
301
);
302
303
__PACKAGE__->belongs_to(
304
  "biblio",
305
  "Koha::Schema::Result::Biblio",
306
  { biblionumber => "biblionumber" },
307
  {
308
    is_deferrable => 1,
309
    join_type     => "LEFT",
310
    on_delete     => "CASCADE",
311
    on_update     => "CASCADE",
312
  },
313
);
291
314
292
# You can replace this text with custom content, and it will be preserved on regeneration
293
1;
315
1;
(-)a/circ/circulation.pl (-205 / +13 lines)
Lines 42-47 use CGI::Session; Link Here
42
use C4::Members::Attributes qw(GetBorrowerAttributes);
42
use C4::Members::Attributes qw(GetBorrowerAttributes);
43
use Koha::Borrower::Debarments qw(GetDebarments);
43
use Koha::Borrower::Debarments qw(GetDebarments);
44
use Koha::DateUtils;
44
use Koha::DateUtils;
45
use Koha::Database;
45
46
46
use Date::Calc qw(
47
use Date::Calc qw(
47
  Today
48
  Today
Lines 96-109 my ( $template, $loggedinuser, $cookie ) = get_template_and_user ( Link Here
96
97
97
my $branches = GetBranches();
98
my $branches = GetBranches();
98
99
99
my @failedrenews = $query->param('failedrenew');    # expected to be itemnumbers 
100
our %renew_failed = ();
101
for (@failedrenews) { $renew_failed{$_} = 1; }
102
103
my @failedreturns = $query->param('failedreturn');
104
our %return_failed = ();
105
for (@failedreturns) { $return_failed{$_} = 1; }
106
107
my $findborrower = $query->param('findborrower') || q{};
100
my $findborrower = $query->param('findborrower') || q{};
108
$findborrower =~ s|,| |g;
101
$findborrower =~ s|,| |g;
109
my $borrowernumber = $query->param('borrowernumber');
102
my $borrowernumber = $query->param('borrowernumber');
Lines 121-130 if (C4::Context->preference("DisplayClearScreenButton")) { Link Here
121
    $template->param(DisplayClearScreenButton => 1);
114
    $template->param(DisplayClearScreenButton => 1);
122
}
115
}
123
116
124
if (C4::Context->preference("UseTablesortForCirc")) {
125
    $template->param(UseTablesortForCirc => 1);
126
}
127
128
my $barcode        = $query->param('barcode') || q{};
117
my $barcode        = $query->param('barcode') || q{};
129
$barcode =~  s/^\s*|\s*$//g; # remove leading/trailing whitespace
118
$barcode =~  s/^\s*|\s*$//g; # remove leading/trailing whitespace
130
119
Lines 354-362 if ($barcode) { Link Here
354
        }
343
        }
355
    }
344
    }
356
    
345
    
357
    # FIXME If the issue is confirmed, we launch another time GetMemberIssuesAndFines, now display the issue count after issue 
346
    my ( $od, $issue, $fines ) = GetMemberIssuesAndFines($borrowernumber);
358
    my ( $od, $issue, $fines ) = GetMemberIssuesAndFines( $borrowernumber );
347
    $template->param( issuecount => $issue );
359
    $template->param( issuecount   => $issue );
360
}
348
}
361
349
362
# reload the borrower info for the sake of reseting the flags.....
350
# reload the borrower info for the sake of reseting the flags.....
Lines 368-561 if ($borrowernumber) { Link Here
368
# BUILD HTML
356
# BUILD HTML
369
# show all reserves of this borrower, and the position of the reservation ....
357
# show all reserves of this borrower, and the position of the reservation ....
370
if ($borrowernumber) {
358
if ($borrowernumber) {
359
    $template->param(
360
        holds_count => Koha::Database->new()->schema()->resultset('Reserve')
361
          ->count( { borrowernumber => $borrowernumber } ) );
371
362
372
    # new op dev
373
    # now we show the status of the borrower's reservations
374
    my @borrowerreserv = GetReservesFromBorrowernumber($borrowernumber );
375
    my @reservloop;
376
    my @WaitingReserveLoop;
377
    
378
    foreach my $num_res (@borrowerreserv) {
379
        my %getreserv;
380
        my %getWaitingReserveInfo;
381
        my $getiteminfo  = GetBiblioFromItemNumber( $num_res->{'itemnumber'} );
382
        my $itemtypeinfo = getitemtypeinfo( (C4::Context->preference('item-level_itypes')) ? $getiteminfo->{'itype'} : $getiteminfo->{'itemtype'} );
383
        my ( $transfertwhen, $transfertfrom, $transfertto ) =
384
          GetTransfers( $num_res->{'itemnumber'} );
385
386
        $getreserv{waiting}       = 0;
387
        $getreserv{transfered}    = 0;
388
        $getreserv{nottransfered} = 0;
389
390
        $getreserv{reservedate}    = format_date( $num_res->{'reservedate'} );
391
        $getreserv{reserve_id}  = $num_res->{'reserve_id'};
392
        $getreserv{title}          = $getiteminfo->{'title'};
393
        $getreserv{subtitle}       = GetRecordValue('subtitle', GetMarcBiblio($getiteminfo->{biblionumber}), GetFrameworkCode($getiteminfo->{biblionumber}));
394
        $getreserv{itemtype}       = $itemtypeinfo->{'description'};
395
        $getreserv{author}         = $getiteminfo->{'author'};
396
        $getreserv{barcodereserv}  = $getiteminfo->{'barcode'};
397
        $getreserv{itemcallnumber} = $getiteminfo->{'itemcallnumber'};
398
        $getreserv{biblionumber}   = $getiteminfo->{'biblionumber'};
399
        $getreserv{waitingat}      = GetBranchName( $num_res->{'branchcode'} );
400
        $getreserv{suspend}        = $num_res->{'suspend'};
401
        $getreserv{suspend_until}  = $num_res->{'suspend_until'};
402
        #         check if we have a waiting status for reservations
403
        if ( $num_res->{'found'} && $num_res->{'found'} eq 'W' ) {
404
            $getreserv{color}   = 'reserved';
405
            $getreserv{waiting} = 1;
406
#     genarate information displaying only waiting reserves
407
        $getWaitingReserveInfo{title}        = $getiteminfo->{'title'};
408
        $getWaitingReserveInfo{biblionumber} = $getiteminfo->{'biblionumber'};
409
        $getWaitingReserveInfo{itemtype}     = $itemtypeinfo->{'description'};
410
        $getWaitingReserveInfo{author}       = $getiteminfo->{'author'};
411
        $getWaitingReserveInfo{itemcallnumber} = $getiteminfo->{'itemcallnumber'};
412
        $getWaitingReserveInfo{reservedate}  = format_date( $num_res->{'reservedate'} );
413
        $getWaitingReserveInfo{waitingat}    = GetBranchName( $num_res->{'branchcode'} );
414
        $getWaitingReserveInfo{waitinghere}  = 1 if $num_res->{'branchcode'} eq $branch;
415
        }
416
        #         check transfers with the itemnumber foud in th reservation loop
417
        if ($transfertwhen) {
418
            $getreserv{color}      = 'transfered';
419
            $getreserv{transfered} = 1;
420
            $getreserv{datesent}   = format_date($transfertwhen);
421
            $getreserv{frombranch} = GetBranchName($transfertfrom);
422
        } elsif ($getiteminfo->{'holdingbranch'} ne $num_res->{'branchcode'}) {
423
            $getreserv{nottransfered}   = 1;
424
            $getreserv{nottransferedby} = GetBranchName( $getiteminfo->{'holdingbranch'} );
425
        }
426
427
#         if we don't have a reserv on item, we put the biblio infos and the waiting position
428
        if ( $getiteminfo->{'title'} eq '' ) {
429
            my $getbibinfo = GetBiblioData( $num_res->{'biblionumber'} );
430
431
            $getreserv{color}           = 'inwait';
432
            $getreserv{title}           = $getbibinfo->{'title'};
433
            $getreserv{subtitle}        = GetRecordValue('subtitle', GetMarcBiblio($num_res->{biblionumber}), GetFrameworkCode($num_res->{biblionumber}));
434
            $getreserv{nottransfered}   = 0;
435
            $getreserv{itemtype}        = $itemtypeinfo->{'description'};
436
            $getreserv{author}          = $getbibinfo->{'author'};
437
            $getreserv{biblionumber}    = $num_res->{'biblionumber'};
438
        }
439
        $getreserv{waitingposition} = $num_res->{'priority'};
440
        $getreserv{expirationdate} = $num_res->{'expirationdate'};
441
        push( @reservloop, \%getreserv );
442
443
#         if we have a reserve waiting, initiate waitingreserveloop
444
        if ($getreserv{waiting} == 1) {
445
        push (@WaitingReserveLoop, \%getWaitingReserveInfo)
446
        }
447
      
448
    }
449
450
    # return result to the template
451
    $template->param( 
452
        countreserv => scalar @reservloop,
453
        reservloop  => \@reservloop ,
454
        WaitingReserveLoop  => \@WaitingReserveLoop,
455
    );
456
    $template->param( adultborrower => 1 ) if ( $borrower->{'category_type'} eq 'A' );
363
    $template->param( adultborrower => 1 ) if ( $borrower->{'category_type'} eq 'A' );
457
}
364
}
458
365
459
# make the issued books table.
460
my $todaysissues = '';
461
my $previssues   = '';
462
our @todaysissues   = ();
463
our @previousissues = ();
464
our @relissues      = ();
465
our @relprevissues  = ();
466
my $displayrelissues;
467
468
our $totalprice = 0;
469
470
sub build_issue_data {
471
    my $issueslist = shift;
472
    my $relatives = shift;
473
474
    # split in 2 arrays for today & previous
475
    foreach my $it ( @$issueslist ) {
476
        my $itemtypeinfo = getitemtypeinfo( (C4::Context->preference('item-level_itypes')) ? $it->{'itype'} : $it->{'itemtype'} );
477
478
        # set itemtype per item-level_itype syspref - FIXME this is an ugly hack
479
        $it->{'itemtype'} = ( C4::Context->preference( 'item-level_itypes' ) ) ? $it->{'itype'} : $it->{'itemtype'};
480
481
        ($it->{'charge'}, $it->{'itemtype_charge'}) = GetIssuingCharges(
482
            $it->{'itemnumber'}, $it->{'borrowernumber'}
483
        );
484
        $it->{'charge'} = sprintf("%.2f", $it->{'charge'});
485
        my ($can_renew, $can_renew_error) = CanBookBeRenewed( 
486
            $it->{'borrowernumber'},$it->{'itemnumber'}
487
        );
488
        $it->{"renew_error_${can_renew_error}"} = 1 if defined $can_renew_error;
489
        my $restype = C4::Reserves::GetReserveStatus( $it->{'itemnumber'} );
490
        $it->{'can_renew'} = $can_renew;
491
        $it->{'can_confirm'} = !$can_renew && !$restype;
492
        $it->{'renew_error'} = ( $restype eq "Waiting" or $restype eq "Reserved" ) ? 1 : 0;
493
        $it->{'checkoutdate'} = C4::Dates->new($it->{'issuedate'},'iso')->output('syspref');
494
        $it->{'issuingbranchname'} = GetBranchName($it->{'branchcode'});
495
496
        $totalprice += $it->{'replacementprice'} || 0;
497
        $it->{'itemtype'} = $itemtypeinfo->{'description'};
498
        $it->{'itemtype_image'} = $itemtypeinfo->{'imageurl'};
499
        $it->{'dd_sort'} = $it->{'date_due'};
500
        $it->{'dd'} = output_pref($it->{'date_due'});
501
        $it->{'displaydate_sort'} = $it->{'issuedate'};
502
        $it->{'displaydate'} = output_pref($it->{'issuedate'});
503
        #$it->{'od'} = ( $it->{'date_due'} lt $todaysdate ) ? 1 : 0 ;
504
        $it->{'od'} = $it->{'overdue'};
505
        $it->{'subtitle'} = GetRecordValue('subtitle', GetMarcBiblio($it->{biblionumber}), GetFrameworkCode($it->{biblionumber}));
506
        $it->{'renew_failed'} = $renew_failed{$it->{'itemnumber'}};
507
        $it->{'return_failed'} = $return_failed{$it->{'barcode'}};
508
509
        if ( ( $it->{'issuedate'} && $it->{'issuedate'} gt $todaysdate )
510
          || ( $it->{'lastreneweddate'} && $it->{'lastreneweddate'} gt $todaysdate ) ) {
511
            (!$relatives) ? push @todaysissues, $it : push @relissues, $it;
512
        } else {
513
            (!$relatives) ? push @previousissues, $it : push @relprevissues, $it;
514
        }
515
        ($it->{'renewcount'},$it->{'renewsallowed'},$it->{'renewsleft'}) = C4::Circulation::GetRenewCount($it->{'borrowernumber'},$it->{'itemnumber'}); #Add renewal count to item data display
516
517
        $it->{'soonestrenewdate'} = output_pref(
518
            C4::Circulation::GetSoonestRenewDate(
519
                $it->{borrowernumber}, $it->{itemnumber}
520
            )
521
        );
522
    }
523
}
524
525
if ($borrower) {
526
527
    # Getting borrower relatives
528
    my @relborrowernumbers = GetMemberRelatives($borrower->{'borrowernumber'});
529
    #push @borrowernumbers, $borrower->{'borrowernumber'};
530
531
    # get each issue of the borrower & separate them in todayissues & previous issues
532
    my $issueslist = GetPendingIssues($borrower->{'borrowernumber'});
533
    my $relissueslist = [];
534
    if ( @relborrowernumbers ) {
535
        $relissueslist = GetPendingIssues(@relborrowernumbers);
536
    }
537
538
    build_issue_data($issueslist, 0);
539
    build_issue_data($relissueslist, 1);
540
  
541
    $displayrelissues = scalar($relissueslist);
542
543
    if ( C4::Context->preference( "todaysIssuesDefaultSortOrder" ) eq 'asc' ) {
544
        @todaysissues   = sort { $a->{'timestamp'} cmp $b->{'timestamp'} } @todaysissues;
545
    }
546
    else {
547
        @todaysissues   = sort { $b->{'timestamp'} cmp $a->{'timestamp'} } @todaysissues;
548
    }
549
550
    if ( C4::Context->preference( "previousIssuesDefaultSortOrder" ) eq 'asc' ){
551
        @previousissues = sort { $a->{'date_due'} cmp $b->{'date_due'} } @previousissues;
552
    }
553
    else {
554
        @previousissues = sort { $b->{'date_due'} cmp $a->{'date_due'} } @previousissues;
555
    }
556
}
557
558
559
my @values;
366
my @values;
560
my %labels;
367
my %labels;
561
my $CGIselectborrower;
368
my $CGIselectborrower;
Lines 688-693 if (C4::Context->preference('ExtendedPatronAttributes')) { Link Here
688
    );
495
    );
689
}
496
}
690
497
498
my @relatives = GetMemberRelatives( $borrower->{'borrowernumber'} );
499
my $relatives_issues_count =
500
  Koha::Database->new()->schema()->resultset('Issue')
501
  ->count( { borrowernumber => \@relatives } );
502
691
$template->param(
503
$template->param(
692
    lib_messages_loop => $lib_messages_loop,
504
    lib_messages_loop => $lib_messages_loop,
693
    bor_messages_loop => $bor_messages_loop,
505
    bor_messages_loop => $bor_messages_loop,
Lines 725-737 $template->param( Link Here
725
    duedatespec       => $duedatespec,
537
    duedatespec       => $duedatespec,
726
    message           => $message,
538
    message           => $message,
727
    CGIselectborrower => $CGIselectborrower,
539
    CGIselectborrower => $CGIselectborrower,
728
    totalprice        => sprintf('%.2f', $totalprice),
729
    totaldue          => sprintf('%.2f', $total),
540
    totaldue          => sprintf('%.2f', $total),
730
    todayissues       => \@todaysissues,
731
    previssues        => \@previousissues,
732
    relissues			=> \@relissues,
733
    relprevissues		=> \@relprevissues,
734
    displayrelissues		=> $displayrelissues,
735
    inprocess         => $inprocess,
541
    inprocess         => $inprocess,
736
    is_child          => ($borrower->{'category_type'} eq 'C'),
542
    is_child          => ($borrower->{'category_type'} eq 'C'),
737
    circview => 1,
543
    circview => 1,
Lines 742-747 $template->param( Link Here
742
    SuspendHoldsIntranet => C4::Context->preference('SuspendHoldsIntranet'),
548
    SuspendHoldsIntranet => C4::Context->preference('SuspendHoldsIntranet'),
743
    AutoResumeSuspendedHolds => C4::Context->preference('AutoResumeSuspendedHolds'),
549
    AutoResumeSuspendedHolds => C4::Context->preference('AutoResumeSuspendedHolds'),
744
    RoutingSerials => C4::Context->preference('RoutingSerials'),
550
    RoutingSerials => C4::Context->preference('RoutingSerials'),
551
    relatives_issues_count => $relatives_issues_count,
552
    relatives_borrowernumbers => \@relatives,
745
);
553
);
746
554
747
# save stickyduedate to session
555
# save stickyduedate to session
(-)a/installer/data/mysql/sysprefs.sql (-1 lines)
Lines 415-421 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
415
('UseICU','0','1','Tell Koha if ICU indexing is in use for Zebra or not.','YesNo'),
415
('UseICU','0','1','Tell Koha if ICU indexing is in use for Zebra or not.','YesNo'),
416
('UseKohaPlugins','0','','Enable or disable the ability to use Koha Plugins.','YesNo'),
416
('UseKohaPlugins','0','','Enable or disable the ability to use Koha Plugins.','YesNo'),
417
('UseQueryParser','0',NULL,'If enabled, try to use QueryParser for queries.','YesNo'),
417
('UseQueryParser','0',NULL,'If enabled, try to use QueryParser for queries.','YesNo'),
418
('UseTablesortForCirc','0','','If on, use the JQuery tablesort function on the list of current borrower checkouts on the circulation page.  Note that the use of this function may slow down circ for patrons with may checkouts.','YesNo'),
419
('UseTransportCostMatrix','0','','Use Transport Cost Matrix when filling holds','YesNo'),
418
('UseTransportCostMatrix','0','','Use Transport Cost Matrix when filling holds','YesNo'),
420
('viewISBD','1','','Allow display of ISBD view of bibiographic records','YesNo'),
419
('viewISBD','1','','Allow display of ISBD view of bibiographic records','YesNo'),
421
('viewLabeledMARC','0','','Allow display of labeled MARC view of bibiographic records','YesNo'),
420
('viewLabeledMARC','0','','Allow display of labeled MARC view of bibiographic records','YesNo'),
(-)a/koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.dataTables.rowGrouping.js (+690 lines)
Line 0 Link Here
1
/*
2
* File:        jquery.dataTables.grouping.js
3
* Version:     1.2.9.
4
* Author:      Jovan Popovic
5
*
6
* Copyright 2013 Jovan Popovic, all rights reserved.
7
*
8
* This source file is free software, under either the GPL v2 license or a
9
* BSD style license, as supplied with this software.
10
*
11
* This source file is distributed in the hope that it will be useful, but
12
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
* or FITNESS FOR A PARTICULAR PURPOSE.
14
* Parameters:
15
* @iGroupingColumnIndex                                 Integer             Index of the column that will be used for grouping - default 0
16
* @sGroupingColumnSortDirection                         Enumeration         Sort direction of the group
17
* @iGroupingOrderByColumnIndex                          Integer             Index of the column that will be used for ordering groups
18
* @sGroupingClass                                       String              Class that will be associated to the group row. Default - "group"
19
* @sGroupItemClass                                      String              Class that will be associated to the group row of group items. Default - "group-item"
20
* @bSetGroupingClassOnTR                                Boolean             If set class will be set to the TR instead of the TD withing the grouping TR
21
* @bHideGroupingColumn                                  Boolean             Hide column used for grouping once results are grouped. Default - true
22
* @bHideGroupingOrderByColumn                           Boolean             Hide column used for ordering groups once results are grouped. Default - true
23
* @sGroupBy                                             Enumeration         Type of grouping that should be applied. Values "name"(default), "letter", "year"
24
* @sGroupLabelPrefix                                    String              Prefix that will be added to each group cell
25
* @bExpandableGrouping                                  Boolean             Attach expand/collapse handlers to the grouping rows
26
* @bExpandSingleGroup                                   Boolean             Use accordon grouping
27
* @iExpandGroupOffset                                   Integer             Number of pixels to set scroll position above the currently selected group. If -1 scroll will be alligned to the table
28
* General settings
29
* @sDateFormat: "dd/MM/yyyy"                            String              Date format used for grouping
30
* @sEmptyGroupLabel                                     String              Lable that will be placed as group if grouping cells are empty. Default "-"
31
32
* Parameters used in the second level grouping
33
* @iGroupingColumnIndex2                                Integer             Index of the secondary column that will be used for grouping - default 0
34
* @sGroupingColumnSortDirection2                        Enumeration         Sort direction of the secondary group
35
* @iGroupingOrderByColumnIndex2                         Integer             Index of the column that will be used for ordering secondary groups
36
* @sGroupingClass2                                      String              Class that will be associated to the secondary group row. Default "subgroup"
37
* @sGroupItemClass2                                     String              Class that will be associated to the secondary group row of group items. Default "subgroup-item"
38
* @bHideGroupingColumn2                                 Boolean             Hide column used for secondary grouping once results are grouped. Default - true,
39
* @bHideGroupingOrderByColumn2                          Boolean             Hide column used for ordering secondary groups once results are grouped. Default - true,
40
* @sGroupBy2                                            Enumeration         Type of grouping that should be applied to secondary column. Values "name"(default), "letter", "year",
41
* @sGroupLabelPrefix2                                   String              Prefix that will be added to each secondary group cell
42
* @fnOnGrouped                                          Function            Function that is called when grouping is finished. Function has no parameters.
43
*/
44
(function ($) {
45
46
 "use strict";
47
48
    $.fn.rowGrouping = function (options) {
49
50
        function _fnOnGrouped() {
51
52
        }
53
54
        function _fnOnGroupCreated(oGroup, sGroup, iLevel) {
55
            ///<summary>
56
            ///Function called when a new grouping row is created(it should be overriden in properties)
57
            ///</summary>
58
        }
59
60
           function _fnOnGroupCompleted(oGroup, sGroup, iLevel) {
61
            ///<summary>
62
            ///Function called when a new grouping row is created(it should be overriden in properties)
63
            ///</summary>
64
        }
65
66
        function _getMonthName(iMonth) {
67
            var asMonths = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
68
            return asMonths[iMonth - 1];
69
        }
70
71
        var defaults = {
72
73
            iGroupingColumnIndex: 0,
74
            sGroupingColumnSortDirection: "",
75
            iGroupingOrderByColumnIndex: -1,
76
            sGroupingClass: "group",
77
                        sGroupItemClass: "group-item",
78
            bHideGroupingColumn: true,
79
            bHideGroupingOrderByColumn: true,
80
            sGroupBy: "name",
81
            sGroupLabelPrefix: "",
82
            fnGroupLabelFormat: function (label) { return label; },
83
            bExpandableGrouping: false,
84
            bExpandSingleGroup: false,
85
            iExpandGroupOffset: 100,
86
            asExpandedGroups: null,
87
88
            sDateFormat: "dd/MM/yyyy",
89
            sEmptyGroupLabel: "-",
90
            bSetGroupingClassOnTR: false,
91
92
            iGroupingColumnIndex2: -1,
93
            sGroupingColumnSortDirection2: "",
94
            iGroupingOrderByColumnIndex2: -1,
95
            sGroupingClass2: "subgroup",
96
            sGroupItemClass2: "subgroup-item",
97
            bHideGroupingColumn2: true,
98
            bHideGroupingOrderByColumn2: true,
99
            sGroupBy2: "name",
100
            sGroupLabelPrefix2: "",
101
            fnGroupLabelFormat2: function (label) { return label; },
102
            bExpandableGrouping2: false,
103
104
            fnOnGrouped: _fnOnGrouped,
105
106
            fnOnGroupCreated: _fnOnGroupCreated,
107
            fnOnGroupCompleted: _fnOnGroupCompleted,
108
109
            oHideEffect: null, // { method: "hide", duration: "fast", easing: "linear" },
110
            oShowEffect: null,//{ method: "show", duration: "slow", easing: "linear" }
111
112
                   bUseFilteringForGrouping: false // This is still work in progress option
113
        };
114
        return this.each(function (index, elem) {
115
116
            var oTable = $(elem).dataTable();
117
118
            var aoGroups = new Array();
119
            $(this).dataTableExt.aoGroups = aoGroups;
120
121
            function fnCreateGroupRow(sGroupCleaned, sGroup, iColspan) {
122
                var nGroup = document.createElement('tr');
123
                var nCell = document.createElement('td');
124
                nGroup.id = "group-id-" + oTable.attr("id") + "_" + sGroupCleaned;
125
126
                var oGroup = { id: nGroup.id, key: sGroupCleaned, text: sGroup, level: 0, groupItemClass: ".group-item-" + sGroupCleaned, dataGroup: sGroupCleaned, aoSubgroups: new Array() };
127
128
129
130
                if (properties.bSetGroupingClassOnTR) {
131
                    nGroup.className = properties.sGroupingClass + " " + sGroupCleaned;
132
                } else {
133
                    nCell.className = properties.sGroupingClass + " " + sGroupCleaned;
134
                }
135
136
                nCell.colSpan = iColspan;
137
                nCell.innerHTML = properties.sGroupLabelPrefix + properties.fnGroupLabelFormat(sGroup == "" ? properties.sEmptyGroupLabel : sGroup, oGroup );
138
                if (properties.bExpandableGrouping) {
139
140
                    if (!_fnIsGroupCollapsed(sGroupCleaned)) {
141
                        nCell.className += " expanded-group";
142
                        oGroup.state = "expanded";
143
                    } else {
144
                        nCell.className += " collapsed-group";
145
                        oGroup.state = "collapsed";
146
                    }
147
                    nCell.className += " group-item-expander";
148
                    $(nCell).attr('data-group', oGroup.dataGroup); //Fix provided by mssskhalsa (Issue 5)
149
                    $(nCell).attr("data-group-level", oGroup.level);
150
                    $(nCell).click(_fnOnGroupClick);
151
                }
152
                nGroup.appendChild(nCell);
153
                aoGroups[sGroupCleaned] = oGroup;
154
                oGroup.nGroup = nGroup;
155
                properties.fnOnGroupCreated(oGroup, sGroupCleaned, 1);
156
                return oGroup;
157
            }
158
159
            function _fnCreateGroup2Row(sGroup2, sGroupLabel, iColspan, oParentGroup) {
160
161
                var nGroup2 = document.createElement('tr');
162
                nGroup2.id = oParentGroup.id + "_" + sGroup2;
163
                var nCell2 = document.createElement('td');
164
                var dataGroup = oParentGroup.dataGroup + '_' + sGroup2;
165
166
                var oGroup = { id: nGroup2.id, key: sGroup2, text: sGroupLabel, level: oParentGroup.level + 1, groupItemClass: ".group-item-" + dataGroup,
167
                    dataGroup: dataGroup, aoSubgroups: new Array()
168
                };
169
170
                if (properties.bSetGroupingClassOnTR) {
171
                    nGroup2.className = properties.sGroupingClass2 + " " + sGroup2;
172
                } else {
173
                    nCell2.className = properties.sGroupingClass2 + " " + sGroup2;
174
                }
175
176
                nCell2.colSpan = iColspan;
177
                nCell2.innerHTML = properties.sGroupLabelPrefix2 + properties.fnGroupLabelFormat2(sGroupLabel == "" ? properties.sEmptyGroupLabel : sGroupLabel, oGroup);
178
179
                if (properties.bExpandableGrouping) {
180
181
                    nGroup2.className += " group-item-" + oParentGroup.dataGroup;
182
                }
183
184
185
                if (properties.bExpandableGrouping && properties.bExpandableGrouping2) {
186
187
                    if (!_fnIsGroupCollapsed(oGroup.dataGroup)) {
188
                        nCell2.className += " expanded-group";
189
                        oGroup.state = "expanded";
190
                    } else {
191
                        nCell2.className += " collapsed-group";
192
                        oGroup.state = "collapsed";
193
                    }
194
                    nCell2.className += " group-item-expander";
195
                    $(nCell2).attr('data-group', oGroup.dataGroup);
196
                    $(nCell2).attr("data-group-level", oGroup.level);
197
                    $(nCell2).click(_fnOnGroupClick);
198
                }
199
200
                nGroup2.appendChild(nCell2);
201
202
                oParentGroup.aoSubgroups[oGroup.dataGroup] = oGroup;
203
                aoGroups[oGroup.dataGroup] = oGroup;
204
                oGroup.nGroup = nGroup2;
205
                properties.fnOnGroupCreated(oGroup, sGroup2, 2);
206
                return oGroup;
207
            }
208
209
            function _fnIsGroupCollapsed(sGroup) {
210
                if (aoGroups[sGroup] != null)
211
                    return (aoGroups[sGroup].state == "collapsed");
212
                else
213
                    if (sGroup.indexOf("_") > -1)
214
                        true;
215
                    else
216
                                             if(bInitialGrouping && (asExpandedGroups==null || asExpandedGroups.length == 0))
217
                                                       return false;// initially if asExpandedGroups is empty - no one is collapsed
218
                                           else
219
                                                   return ($.inArray(sGroup, asExpandedGroups) == -1); //the last chance check asExpandedGroups
220
            }
221
222
            function _fnGetYear(x) {
223
                               if(x.length< (iYearIndex+iYearLength) )
224
                                        return x;
225
                              else
226
                                   return x.substr(iYearIndex, iYearLength);
227
            }
228
            function _fnGetGroupByName(x) {
229
                return x;
230
            }
231
232
            function _fnGetGroupByLetter(x) {
233
                return x.substr(0, 1);
234
            }
235
236
            function _fnGetGroupByYear(x) {
237
                return _fnGetYear(x);
238
                //return Date.parseExact(x, properties.sDateFormat).getFullYear();//slooooow
239
            }
240
241
            function _fnGetGroupByYearMonth(x) {
242
                //var date = Date.parseExact(x, "dd/MM/yyyy");
243
                //return date.getFullYear() + " / " + date.getMonthName();
244
                //return x.substr(iYearIndex, iYearLength) + '/' + x.substr(iMonthIndex, iMonthLength);
245
                return x.substr(iYearIndex, iYearLength) + ' ' + _getMonthName(x.substr(iMonthIndex, iMonthLength));
246
            }
247
248
            function _fnGetCleanedGroup(sGroup) {
249
250
                if (sGroup === "") return "-";
251
                return sGroup.toLowerCase().replace(/[^a-zA-Z0-9\u0080-\uFFFF]+/g, "-"); //fix for unicode characters (Issue 23)
252
                //return sGroup.toLowerCase().replace(/\W+/g, "-"); //Fix provided by bmathews (Issue 7)
253
            }
254
255
                       function _rowGroupingRowFilter(oSettings, aData, iDataIndex) {
256
                     ///<summary>Used to expand/collapse groups with DataTables filtering</summary>
257
                if (oSettings.nTable.id !== oTable[0].id) return true;
258
                var sColData = aData[properties.iGroupingColumnIndex];
259
                if (typeof sColData === "undefined")
260
                    sColData = aData[oSettings.aoColumns[properties.iGroupingColumnIndex].mDataProp];
261
                if (_fnIsGroupCollapsed(_fnGetCleanedGroup(sColData))) {
262
                    if (oTable.fnIsOpen(oTable.fnGetNodes(iDataIndex)))
263
                                   {
264
                                              if (properties.fnOnRowClosed != null) {
265
                            properties.fnOnRowClosed(this); //    $(this.cells[0].children[0]).attr('src', '../../Images/details.png');
266
                        }
267
                        oTable.fnClose(oTable.fnGetNodes(iDataIndex));
268
                    }
269
                    return false;
270
                };
271
                            return true;
272
            } //end of function _rowGroupingRowFilter
273
274
275
            function fnExpandGroup(sGroup) {
276
                ///<summary>Expand group if expanadable grouping is used</summary>
277
278
                      aoGroups[sGroup].state = "expanded";
279
280
                              $("td[data-group^='" + sGroup + "']").removeClass("collapsed-group");
281
                $("td[data-group^='" + sGroup + "']").addClass("expanded-group");
282
283
284
                              if(properties.bUseFilteringForGrouping)
285
                                {
286
                                      oTable.fnDraw();
287
                                       return;//Because rows are expanded with _rowGroupingRowFilter function
288
                         }
289
290
                             if (jQuery.inArray(sGroup, asExpandedGroups)==-1)
291
                    asExpandedGroups.push(sGroup);
292
293
                if (properties.oHideEffect != null)
294
                    $(".group-item-" + sGroup, oTable)
295
                                       [properties.oShowEffect.method](properties.oShowEffect.duration,
296
                                                                       properties.oShowEffect.easing,
297
                                                                 function () { });
298
                else
299
                    $(".group-item-" + sGroup, oTable).show();
300
301
302
            } //end of function fnExpandGroup
303
304
            function fnCollapseGroup(sGroup) {
305
                ///<summary>Collapse group if expanadable grouping is used</summary>
306
307
                            aoGroups[sGroup].state = "collapsed";
308
                          $("td[data-group^='" + sGroup + "']").removeClass("expanded-group");
309
                $("td[data-group^='" + sGroup + "']").addClass("collapsed-group");
310
311
                               if(properties.bUseFilteringForGrouping)
312
                                {
313
                                      oTable.fnDraw();
314
                                       return;//Because rows are expanded with _rowGroupingRowFilter function
315
                         }
316
                              //var index = $.inArray(sGroup, asExpandedGroups);
317
                //asExpandedGroups.splice(index, 1);
318
319
                $('.group-item-' + sGroup).each(function () {
320
                    //Issue 24 - Patch provided by Bob Graham
321
                    if (oTable.fnIsOpen(this)) {
322
                        if (properties.fnOnRowClosed != null) {
323
                            properties.fnOnRowClosed(this); //    $(this.cells[0].children[0]).attr('src', '../../Images/details.png');
324
                        }
325
                        oTable.fnClose(this);
326
                    }
327
                });
328
329
                if (properties.oHideEffect != null)
330
                    $(".group-item-" + sGroup, oTable)
331
                                    [properties.oHideEffect.method](properties.oHideEffect.duration,
332
                                                                       properties.oHideEffect.easing,
333
                                                                 function () { });
334
                else
335
                    $(".group-item-" + sGroup, oTable).hide();
336
337
            } //end of function fnCollapseGroup
338
339
            function _fnOnGroupClick(e) {
340
                ///<summary>
341
                ///Function that is called when user click on the group cell in order to
342
                ///expand of collapse group
343
                ///</summary>
344
345
                //var sGroup = $(this).attr("rel");
346
                var sGroup = $(this).attr("data-group");
347
                var iGroupLevel = $(this).attr("data-group-level");
348
349
                var bIsExpanded = !_fnIsGroupCollapsed(sGroup);
350
                if (properties.bExpandSingleGroup) {
351
                    if (!bIsExpanded) {
352
                        var sCurrentGroup = $("td.expanded-group").attr("data-group");
353
                        fnCollapseGroup(sCurrentGroup);
354
                        fnExpandGroup(sGroup);
355
356
                        if (properties.iExpandGroupOffset != -1) {
357
                            var position = $("#group-id-" + oTable.attr("id") + "_" + sGroup).offset().top - properties.iExpandGroupOffset;
358
                            window.scroll(0, position);
359
                        } else {
360
                            var position = oTable.offset().top;
361
                            window.scroll(0, position);
362
                        }
363
                    }
364
                } else {
365
                    if (bIsExpanded) {
366
                        fnCollapseGroup(sGroup);
367
                    } else {
368
                        fnExpandGroup(sGroup);
369
                    }
370
                }
371
                e.preventDefault();
372
373
            }; //end function _fnOnGroupClick
374
375
376
                     function _fnDrawCallBackWithGrouping (oSettings) {
377
378
                if (oTable.fnSettings().oFeatures.bServerSide)
379
                    bInitialGrouping = true;
380
                var bUseSecondaryGrouping = false;
381
382
                if (properties.iGroupingColumnIndex2 != -1)
383
                    bUseSecondaryGrouping = true;
384
385
                //-----Start grouping
386
387
                if (oSettings.aiDisplayMaster.length == 0) { //aiDisplay
388
                    return;
389
                }
390
391
                var nTrs = $('tbody tr', oTable);
392
                var iColspan = 0; //nTrs[0].getElementsByTagName('td').length;
393
                for (var iColIndex = 0; iColIndex < oSettings.aoColumns.length; iColIndex++) {
394
                    if (oSettings.aoColumns[iColIndex].bVisible)
395
                        iColspan += 1;
396
                }
397
                var sLastGroup = null;
398
                var sLastGroup2 = null;
399
                if (oSettings.aiDisplay.length > 0) {
400
                    for (var i = 0; i < nTrs.length; i++) {
401
402
403
                        var iDisplayIndex = oSettings._iDisplayStart + i;
404
                        if (oTable.fnSettings().oFeatures.bServerSide)
405
                            iDisplayIndex = i;
406
                        var sGroupData = "";
407
                        var sGroup = null;
408
                        var sGroupData2 = "";
409
                        var sGroup2 = null;
410
411
                        //Issue 31 - Start fix provided by Fabien Taysse
412
//                      sGroupData = oSettings.aoData[oSettings.aiDisplay[iDisplayIndex]]._aData[properties.iGroupingColumnIndex];
413
//                      if (sGroupData == undefined)
414
//                          sGroupData = oSettings.aoData[oSettings.aiDisplay[iDisplayIndex]]._aData[oSettings.aoColumns[properties.iGroupingColumnIndex].mDataProp];
415
                        sGroupData = this.fnGetData(nTrs[i], properties.iGroupingColumnIndex);
416
                        //Issue 31 - End fix provided by Fabien Taysse
417
418
                        var sGroup = sGroupData;
419
                        if (properties.sGroupBy != "year")
420
                            sGroup = fnGetGroup(sGroupData);
421
422
                        if (bUseSecondaryGrouping) {
423
                            sGroupData2 = oSettings.aoData[oSettings.aiDisplay[iDisplayIndex]]._aData[properties.iGroupingColumnIndex2];
424
                            if (sGroupData2 == undefined)
425
                                sGroupData2 = oSettings.aoData[oSettings.aiDisplay[iDisplayIndex]]._aData[oSettings.aoColumns[properties.iGroupingColumnIndex2].mDataProp];
426
                            if (properties.sGroupBy2 != "year")
427
                                sGroup2 = fnGetGroup(sGroupData2);
428
                        }
429
430
431
                        if (sLastGroup == null || _fnGetCleanedGroup(sGroup) != _fnGetCleanedGroup(sLastGroup)) { // new group encountered (or first of group)
432
                            var sGroupCleaned = _fnGetCleanedGroup(sGroup);
433
434
                            if(sLastGroup != null)
435
                            {
436
                              properties.fnOnGroupCompleted(aoGroups[_fnGetCleanedGroup(sLastGroup)]);
437
                            }
438
                                                   /*
439
                            if (properties.bExpandableGrouping && bInitialGrouping) {
440
                                if (properties.bExpandSingleGroup) {
441
                                    if (asExpandedGroups.length == 0)
442
                                        asExpandedGroups.push(sGroupCleaned);
443
                                } else {
444
                                    asExpandedGroups.push(sGroupCleaned);
445
                                }
446
                            }
447
                                                   */
448
                                                     if(properties.bAddAllGroupsAsExpanded && jQuery.inArray(sGroupCleaned,asExpandedGroups) == -1)
449
                                                         asExpandedGroups.push(sGroupCleaned);
450
451
                            var oGroup = fnCreateGroupRow(sGroupCleaned, sGroup, iColspan);
452
                            var nGroup = oGroup.nGroup;
453
454
                                                    if(nTrs[i].parentNode!=null)
455
                                                           nTrs[i].parentNode.insertBefore(nGroup, nTrs[i]);
456
                                                      else
457
                                                           $(nTrs[i]).before(nGroup);
458
459
                            sLastGroup = sGroup;
460
                            sLastGroup2 = null; //to reset second level grouping
461
462
463
464
465
466
                        } // end if (sLastGroup == null || sGroup != sLastGroup)
467
468
                                           $(nTrs[i]).attr("data-group", aoGroups[sGroupCleaned].dataGroup);
469
470
                        $(nTrs[i]).addClass(properties.sGroupItemClass);
471
                        $(nTrs[i]).addClass("group-item-" + sGroupCleaned);
472
                        if (properties.bExpandableGrouping) {
473
                            if (_fnIsGroupCollapsed(sGroupCleaned) && !properties.bUseFilteringForGrouping) {
474
                                $(nTrs[i]).hide();
475
                            }
476
                        }
477
478
479
                        if (bUseSecondaryGrouping) {
480
481
                            if (sLastGroup2 == null || _fnGetCleanedGroup(sGroup2) != _fnGetCleanedGroup(sLastGroup2)) {
482
                                var sGroup2Id = _fnGetCleanedGroup(sGroup) + '-' + _fnGetCleanedGroup(sGroup2);
483
                                var oGroup2 = _fnCreateGroup2Row(sGroup2Id, sGroup2, iColspan, aoGroups[sGroupCleaned])
484
                                var nGroup2 = oGroup2.nGroup;
485
                                nTrs[i].parentNode.insertBefore(nGroup2, nTrs[i]);
486
487
                                sLastGroup2 = sGroup2;
488
                            }
489
490
                            $(nTrs[i]).attr("data-group", oGroup2.dataGroup)
491
                                                                           .addClass(properties.sGroupItemClass2)
492
                                        .addClass("group-item-" + oGroup2.dataGroup);
493
                        } //end if (bUseSecondaryGrouping)
494
495
496
497
                    } // end for (var i = 0; i < nTrs.length; i++)
498
                }; // if (oSettings.aiDisplay.length > 0)
499
500
                               if(sLastGroup != null)
501
                     {
502
                                properties.fnOnGroupCompleted(aoGroups[_fnGetCleanedGroup(sLastGroup)]);
503
                         }
504
505
506
                //-----End grouping
507
                properties.fnOnGrouped(aoGroups);
508
509
                bInitialGrouping = false;
510
511
            }; // end of _fnDrawCallBackWithGrouping = function (oSettings)
512
513
514
            //var oTable = this;
515
            var iYearIndex = 6;
516
            var iYearLength = 4;
517
            var asExpandedGroups = new Array();
518
            var bInitialGrouping = true;
519
520
            var properties = $.extend(defaults, options);
521
522
            if (properties.iGroupingOrderByColumnIndex == -1) {
523
                properties.bCustomColumnOrdering = false;
524
                properties.iGroupingOrderByColumnIndex = properties.iGroupingColumnIndex;
525
            } else {
526
                properties.bCustomColumnOrdering = true;
527
            }
528
529
            if (properties.sGroupingColumnSortDirection == "") {
530
                if (properties.sGroupBy == "year")
531
                    properties.sGroupingColumnSortDirection = "desc";
532
                else
533
                    properties.sGroupingColumnSortDirection = "asc";
534
            }
535
536
537
            if (properties.iGroupingOrderByColumnIndex2 == -1) {
538
                properties.bCustomColumnOrdering2 = false;
539
                properties.iGroupingOrderByColumnIndex2 = properties.iGroupingColumnIndex2;
540
            } else {
541
                properties.bCustomColumnOrdering2 = true;
542
            }
543
544
            if (properties.sGroupingColumnSortDirection2 == "") {
545
                if (properties.sGroupBy2 == "year")
546
                    properties.sGroupingColumnSortDirection2 = "desc";
547
                else
548
                    properties.sGroupingColumnSortDirection2 = "asc";
549
            }
550
551
552
553
            iYearIndex = properties.sDateFormat.toLowerCase().indexOf('yy');
554
            iYearLength = properties.sDateFormat.toLowerCase().lastIndexOf('y') - properties.sDateFormat.toLowerCase().indexOf('y') + 1;
555
556
            var iMonthIndex = properties.sDateFormat.toLowerCase().indexOf('mm');
557
            var iMonthLength = properties.sDateFormat.toLowerCase().lastIndexOf('m') - properties.sDateFormat.toLowerCase().indexOf('m') + 1;
558
559
            var fnGetGroup = _fnGetGroupByName;
560
            switch (properties.sGroupBy) {
561
                case "letter": fnGetGroup = _fnGetGroupByLetter;
562
                    break;
563
                case "year": fnGetGroup = _fnGetGroupByYear;
564
                    break;
565
                case "month": fnGetGroup = _fnGetGroupByYearMonth;
566
                    break;
567
                default: fnGetGroup = _fnGetGroupByName;
568
                    break;
569
            }
570
571
572
            if (properties.asExpandedGroups != null) {
573
                if (properties.asExpandedGroups == "NONE") {
574
                    properties.asExpandedGroups = [];
575
                    asExpandedGroups = properties.asExpandedGroups;
576
                    bInitialGrouping = false;
577
                } else if (properties.asExpandedGroups == "ALL") {
578
                                     properties.bAddAllGroupsAsExpanded = true;
579
                } else if (properties.asExpandedGroups.constructor == String) {
580
                    var currentGroup = properties.asExpandedGroups;
581
                    properties.asExpandedGroups = new Array();
582
                    properties.asExpandedGroups.push(_fnGetCleanedGroup(currentGroup));
583
                    asExpandedGroups = properties.asExpandedGroups;
584
                    bInitialGrouping = false;
585
                } else if (properties.asExpandedGroups.constructor == Array) {
586
                    for (var i = 0; i < properties.asExpandedGroups.length; i++) {
587
                        asExpandedGroups.push(_fnGetCleanedGroup(properties.asExpandedGroups[i]));
588
                        if (properties.bExpandSingleGroup)
589
                            break;
590
                    }
591
                    bInitialGrouping = false;
592
                }
593
            }else{
594
                            properties.asExpandedGroups = new Array();
595
                             properties.bAddAllGroupsAsExpanded = true;
596
                     }
597
                      if(properties.bExpandSingleGroup){
598
                         var nTrs = $('tbody tr', oTable);
599
                          var sGroupData = oTable.fnGetData(nTrs[0], properties.iGroupingColumnIndex);
600
601
                          var sGroup = sGroupData;
602
                if (properties.sGroupBy != "year")
603
                    sGroup = fnGetGroup(sGroupData);
604
605
                              var sGroupCleaned = _fnGetCleanedGroup(sGroup);
606
                                properties.asExpandedGroups = new Array();
607
                             properties.asExpandedGroups.push(sGroupCleaned);
608
609
                      }
610
611
            oTable.fnSetColumnVis(properties.iGroupingColumnIndex, !properties.bHideGroupingColumn);
612
            if (properties.bCustomColumnOrdering) {
613
                oTable.fnSetColumnVis(properties.iGroupingOrderByColumnIndex, !properties.bHideGroupingOrderByColumn);
614
            }
615
            if (properties.iGroupingColumnIndex2 != -1) {
616
                oTable.fnSetColumnVis(properties.iGroupingColumnIndex2, !properties.bHideGroupingColumn2);
617
            }
618
            if (properties.bCustomColumnOrdering2) {
619
                oTable.fnSetColumnVis(properties.iGroupingOrderByColumnIndex2, !properties.bHideGroupingOrderByColumn2);
620
            }
621
            oTable.fnSettings().aoDrawCallback.push({
622
                "fn": _fnDrawCallBackWithGrouping,
623
                "sName": "fnRowGrouping"
624
            });
625
626
            var aaSortingFixed = new Array();
627
            aaSortingFixed.push([properties.iGroupingOrderByColumnIndex, properties.sGroupingColumnSortDirection]);
628
            if (properties.iGroupingColumnIndex2 != -1) {
629
                aaSortingFixed.push([properties.iGroupingOrderByColumnIndex2, properties.sGroupingColumnSortDirection2]);
630
            } // end of if (properties.iGroupingColumnIndex2 != -1)
631
632
            oTable.fnSettings().aaSortingFixed = aaSortingFixed;
633
            //Old way
634
            //oTable.fnSettings().aaSortingFixed = [[properties.iGroupingOrderByColumnIndex, properties.sGroupingColumnSortDirection]];
635
636
            switch (properties.sGroupBy) {
637
                case "name":
638
                    break;
639
640
641
                case "letter":
642
643
                    /* Create an array with the values of all the input boxes in a column */
644
                    oTable.fnSettings().aoColumns[properties.iGroupingOrderByColumnIndex].sSortDataType = "rg-letter";
645
                    $.fn.dataTableExt.afnSortData['rg-letter'] = function (oSettings, iColumn) {
646
                        var aData = [];
647
                        $('td:eq(' + iColumn + ')', oSettings.oApi._fnGetTrNodes(oSettings)).each(function () {
648
                            aData.push(_fnGetGroupByLetter(this.innerHTML));
649
                        });
650
                        return aData;
651
                    }
652
653
654
                    break;
655
656
657
                case "year":
658
                    /* Create an array with the values of all the input boxes in a column */
659
                    oTable.fnSettings().aoColumns[properties.iGroupingOrderByColumnIndex].sSortDataType = "rg-date";
660
                    $.fn.dataTableExt.afnSortData['rg-date'] = function (oSettings, iColumn) {
661
                        var aData = [];
662
                                              var nTrs = oSettings.oApi._fnGetTrNodes(oSettings);
663
                                            for(i = 0; i< nTrs.length; i++)
664
                                                {
665
                                                      aData.push(_fnGetYear( oTable.fnGetData( nTrs[i], iColumn) ));
666
                                         }
667
668
/*
669
                        $('td:eq(' + iColumn + ')', oSettings.oApi._fnGetTrNodes(oSettings)).each(function () {
670
                            aData.push(_fnGetYear(this.innerHTML));
671
                        });
672
*/
673
                        return aData;
674
                    }
675
                    break;
676
                default:
677
                    break;
678
679
            } // end of switch (properties.sGroupBy)
680
681
                     if(properties.bUseFilteringForGrouping)
682
                                        $.fn.dataTableExt.afnFiltering.push(_rowGroupingRowFilter);
683
684
            oTable.fnDraw();
685
686
687
688
        });
689
    };
690
})(jQuery);
(-)a/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css (-1 / +1 lines)
Lines 274-280 tr.even td, tr.even.highlight td { Link Here
274
    border-right : 1px solid #BCBCBC;
274
    border-right : 1px solid #BCBCBC;
275
}
275
}
276
276
277
td.od {
277
.overdue td.od {
278
	color : #cc0000;
278
	color : #cc0000;
279
	font-weight : bold;
279
	font-weight : bold;
280
}
280
}
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table-footer.inc (-1 / +1 lines)
Lines 1-6 Link Here
1
<tfoot>
1
<tfoot>
2
	<tr>
2
	<tr>
3
        <td colspan="6" style="text-align: right; font-weight:bold;">Totals:</td>
3
        <td colspan="8" style="text-align: right; font-weight:bold;">Totals:</td>
4
		<td>[% totaldue %]</td>
4
		<td>[% totaldue %]</td>
5
		<td>[% totalprice %]</td>
5
		<td>[% totalprice %]</td>
6
                <td colspan="3"><div class="date-select">
6
                <td colspan="3"><div class="date-select">
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/strings.inc (+30 lines)
Line 0 Link Here
1
<script type="text/javascript">
2
//<![CDATA[
3
    var CIRCULATION_RETURNED = _("Returned");
4
    var CIRCULATION_NOT_RETURNED = _("Unable to return");
5
    var CIRCULATION_RENEWED_DUE = _("Renewed, due:");
6
    var CIRCULATION_RENEW_FAILED = _("Renew failed:")
7
    var NOT_CHECKED_OUT = _("not checked out");
8
    var TOO_MANY_RENEWALS = _("too many renewals");
9
    var ON_RESERVE = _("on reserve");
10
    var REASON_UNKNOWN = _("reason unkown");
11
    var TODAYS_CHECKOUTS = _("Today's checkouts");
12
    var PREVIOUS_CHECKOUTS = _("Previous checkouts");
13
    var BY = _("by");
14
    var ON_HOLD = _("On hold");
15
    var NOT_RENEWABLE = _("Not renewable");
16
    var OF = _("of");
17
    var RENEWALS_REMAINING = _("renewals remaining");
18
    var HOLD_IS = _("Hold is");
19
    var SUSPENDED = _("suspended");
20
    var UNTIL = _("until");
21
    var ITEM_IS = _("Item is");
22
    var WAITING = _("waiting");
23
    var AT = _("at");
24
    var IN_TRANSIT = _("in transit");
25
    var FROM = _("from");
26
    var NOT_TRANSFERRED_YET = _("Item hasn't been transferred yet from");
27
    var NO = _("No");
28
    var YES = _("Yes");
29
//]]>
30
</script>
(-)a/koha-tmpl/intranet-tmpl/prog/en/js/checkouts.js (+435 lines)
Line 0 Link Here
1
$(document).ready(function() {
2
    // Handle the select all/none links for checkouts table columns
3
    $("#CheckAllRenewals").on("click",function(){
4
        $("#UncheckAllCheckins").click();
5
        $(".renew:visible").attr("checked", "checked" );
6
        return false;
7
    });
8
    $("#UncheckAllRenewals").on("click",function(){
9
        $(".renew:visible").removeAttr("checked");
10
        return false;
11
    });
12
13
    $("#CheckAllCheckins").on("click",function(){
14
        $("#UncheckAllRenewals").click();
15
        $(".checkin:visible").attr("checked", "checked" );
16
        return false;
17
    });
18
    $("#UncheckAllCheckins").on("click",function(){
19
        $(".checkin:visible").removeAttr("checked");
20
        return false;
21
    });
22
23
    // Don't allow both return and renew checkboxes to be checked
24
    $(document).on("change", '.renew', function(){
25
        if ( $(this).is(":checked") ) {
26
            $( "#checkin_" + $(this).val() ).removeAttr("checked");
27
        }
28
    });
29
    $(document).on("change", '.checkin', function(){
30
        if ( $(this).is(":checked") ) {
31
            $( "#renew_" + $(this).val() ).removeAttr("checked");
32
        }
33
    });
34
35
    // Clicking the table cell checks the checkbox inside it
36
    $(document).on("click", 'td', function(e){
37
        if(e.target.tagName.toLowerCase() == 'td'){
38
          $(this).find("input:checkbox:visible").each( function() {
39
            $(this).click();
40
          });
41
        }
42
    });
43
44
    // Handle renewals and returns
45
    $("#RenewCheckinChecked").on("click",function(){
46
        $(".checkin:checked:visible").each(function() {
47
            itemnumber = $(this).val();
48
49
            $(this).replaceWith("<img id='checkin_" + itemnumber + "' src='" + interface + "/" + theme + "/img/loading-small.gif' />");
50
51
            params = {
52
                itemnumber:     itemnumber,
53
                borrowernumber: borrowernumber,
54
                branchcode:     branchcode,
55
                exempt_fine:    $("#exemptfine").is(':checked')
56
            };
57
58
            $.post( "/cgi-bin/koha/svc/checkin.pl", params, function( data ) {
59
                id = "#checkin_" + data.itemnumber;
60
61
                content = "";
62
                if ( data.returned ) {
63
                    content = CIRCULATION_RETURNED;
64
                } else {
65
                    content = CIRCULATION_NOT_RETURNED;
66
                }
67
68
                $(id).replaceWith( content );
69
            }, "json")
70
        });
71
72
        $(".renew:checked:visible").each(function() {
73
            var override_limit = $("#override_limit").is(':checked') ? 1 : 0;
74
75
            var itemnumber = $(this).val();
76
77
            $(this).parent().parent().replaceWith("<img id='renew_" + itemnumber + "' src='" + interface + "/" + theme + "/img/loading-small.gif' />");
78
79
            var params = {
80
                itemnumber:     itemnumber,
81
                borrowernumber: borrowernumber,
82
                branchcode:     branchcode,
83
                override_limit: override_limit,
84
                date_due:       $("#newduedate").val()
85
            };
86
87
            $.post( "/cgi-bin/koha/svc/renew.pl", params, function( data ) {
88
                var id = "#renew_" + data.itemnumber;
89
90
                var content = "";
91
                if ( data.renew_okay ) {
92
                    content = CIRCULATION_RENEWED_DUE + " " + data.date_due;
93
                } else {
94
                    content = CIRCULATION_RENEW_FAILED + " ";
95
                    if ( data.error == "no_checkout" ) {
96
                        content += NOT_CHECKED_OUT;
97
                    } else if ( data.error == "too_many" ) {
98
                        content += TOO_MANY_RENEWALS;
99
                    } else if ( data.error == "on_reserve" ) {
100
                        content += ON_RESERVE;
101
                    } else if ( data.error ) {
102
                        content += data.error;
103
                    } else {
104
                        content += REASON_UNKNOWN;
105
                    }
106
                }
107
108
                $(id).replaceWith( content );
109
            }, "json")
110
        });
111
112
        // Prevent form submit
113
        return false;
114
    });
115
116
    $("#RenewAll").on("click",function(){
117
        $("#CheckAllRenewals").click();
118
        $("#UncheckAllCheckins").click();
119
        $("#RenewCheckinChecked").click();
120
121
        // Prevent form submit
122
        return false;
123
    });
124
125
    var ymd = $.datepicker.formatDate('yy-mm-dd', new Date());
126
127
    var issuesTable;
128
    var drawn = 0;
129
    issuesTable = $("#issues-table").dataTable({
130
        "sDom": "<'row-fluid'<'span6'><'span6'>r>t<'row-fluid'>t",
131
        "aaSorting": [[ 0, "desc" ]],
132
        "aoColumns": [
133
            {
134
                "mDataProp": function( oObj ) {
135
                    if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
136
                        return "<strong>" + TODAYS_CHECKOUTS + "</strong>";
137
                    } else {
138
                        return "<strong>" + PREVIOUS_CHECKOUTS + "</strong>";
139
                    }
140
                }
141
            },
142
            {
143
                "mDataProp": "date_due",
144
                "bVisible": false,
145
            },
146
            {
147
                "iDataSort": 1, // Sort on hidden unformatted date due column
148
                "mDataProp": function( oObj ) {
149
                    var today = new Date();
150
                    var due = new Date( oObj.date_due );
151
                    if ( today > due ) {
152
                        return "<span class='overdue'>" + oObj.date_due_formatted + "</span>";
153
                    } else {
154
                        return oObj.date_due_formatted;
155
                    }
156
                }
157
            },
158
            {
159
                "mDataProp": function ( oObj ) {
160
                    title = "<a href='/cgi-bin/koha/catalogue/detail.pl?biblionumber="
161
                          + oObj.biblionumber
162
                          + "'>"
163
                          + oObj.title;
164
165
                    $.each(oObj.subtitle, function( index, value ) {
166
                              title += " " + value.subfield;
167
                    });
168
169
                    title += "</a>";
170
171
                    if ( oObj.author ) {
172
                        title += " " + BY + " " + oObj.author;
173
                    }
174
175
                    if ( oObj.itemnotes ) {
176
                        var span_class = "";
177
                        if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
178
                            span_class = "circ-hlt";
179
                        }
180
                        title += " - <span class='" + span_class + "'>" + oObj.itemnotes + "</span>"
181
                    }
182
183
                    title += " "
184
                          + "<a href='/cgi-bin/koha/catalogue/moredetail.pl?biblionumber="
185
                          + oObj.biblionumber
186
                          + "&itemnumber="
187
                          + oObj.itemnumber
188
                          + "#"
189
                          + oObj.itemnumber
190
                          + "'>"
191
                          + oObj.barcode
192
                          + "</a>";
193
194
                    return title;
195
                }
196
            },
197
            { "mDataProp": "itemtype" },
198
            { "mDataProp": "issuedate" },
199
            { "mDataProp": "branchname" },
200
            { "mDataProp": "itemcallnumber" },
201
            {
202
                "bSortable": false,
203
                "mDataProp": function ( oObj ) {
204
                    return parseFloat(oObj.charge).toFixed(2);
205
                }
206
            },
207
            {
208
                "bSortable": false,
209
                "mDataProp": "price" },
210
            {
211
                "bSortable": false,
212
                "mDataProp": function ( oObj ) {
213
                    var content = "";
214
                    var span_style = "";
215
                    var span_class = "";
216
217
                    content += "<span>";
218
                    content += "<span style='padding: 0 1em;'>" + oObj.renewals_count + "</span>";
219
220
                    if ( oObj.can_renew ) {
221
                        // Do nothing
222
                    } else if ( oObj.can_renew_error == "on_reserve" ) {
223
                        content += "<span class='renewals-disabled'>"
224
                                + "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber=" + oObj.biblionumber + "'>" + ON_HOLD + "</a>"
225
                                + "</span>";
226
227
                        span_style = "display: none";
228
                        span_class = "renewals-allowed";
229
                    } else if ( oObj.can_renew_error == "too_many" ) {
230
                        content += "<span class='renewals-disabled'>"
231
                                + NOT_RENEWABLE
232
                                + "</span>";
233
234
                        span_style = "display: none";
235
                        span_class = "renewals-allowed";
236
                    } else {
237
                        content += "<span class='renewals-disabled'>"
238
                                + oObj.can_renew_error
239
                                + "</span>";
240
241
                        span_style = "display: none";
242
                        span_class = "renewals-allowed";
243
                    }
244
245
                    content += "<span class='" + span_class + "' style='" + span_style + "'>"
246
                            +  "<input type='checkbox' class='renew' id='renew_" + oObj.itemnumber + "' name='renew' value='" + oObj.itemnumber +"'/>"
247
                            +  "</span>";
248
249
                    if ( oObj.renewals_remaining ) {
250
                        content += "<span class='renewals'>("
251
                                + oObj.renewals_remaining
252
                                + " " + OF + " "
253
                                + oObj.renewals_allowed + " "
254
                                + RENEWALS_REMAINING + ")</span>";
255
                    }
256
257
                    content += "</span>";
258
259
260
                    return content;
261
                }
262
            },
263
            {
264
                "bSortable": false,
265
                "mDataProp": function ( oObj ) {
266
                    if ( oObj.can_renew_error == "on_reserve" ) {
267
                        return "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber=" + oObj.biblionumber + "'>" + ON_HOLD + "</a>";
268
                    } else {
269
                        return "<input type='checkbox' class='checkin' id='checkin_" + oObj.itemnumber + "' name='checkin' value='" + oObj.itemnumber +"'></input>";
270
                    }
271
                }
272
            },
273
            {
274
                "bVisible": exports_enabled ? true : false,
275
                "bSortable": false,
276
                "mDataProp": function ( oObj ) {
277
                    return "<input type='checkbox' class='export' id='export_" + oObj.biblionumber + "' name='biblionumbers' value='" + oObj.biblionumber + "' />";
278
                }
279
            }
280
        ],
281
        "fnFooterCallback": function ( nRow, aaData, iStart, iEnd, aiDisplay ) {
282
            var total_charge = 0;
283
            var total_price = 0;
284
            for ( var i=0; i < aaData.length; i++ ) {
285
                total_charge += aaData[i]['charge'] * 1;
286
                total_price  += aaData[i]['price'] * 1;
287
            }
288
            var nCells = nRow.getElementsByTagName('td');
289
            nCells[1].innerHTML = total_charge.toFixed(2);
290
            nCells[2].innerHTML = total_price.toFixed(2);
291
        },
292
        "bPaginate": false,
293
        "bProcessing": true,
294
        "bServerSide": false,
295
        "sAjaxSource": '/cgi-bin/koha/svc/checkouts.pl',
296
        "fnServerData": function ( sSource, aoData, fnCallback ) {
297
            aoData.push( { "name": "borrowernumber", "value": borrowernumber } );
298
299
            $.getJSON( sSource, aoData, function (json) {
300
                fnCallback(json)
301
            } );
302
        },
303
        "fnInitComplete": function(oSettings) {
304
            // Disable rowGrouping plugin after first use
305
            // so any sorting on the table doesn't use it
306
            var oSettings = issuesTable.fnSettings();
307
308
            for (f = 0; f < oSettings.aoDrawCallback.length; f++) {
309
                if (oSettings.aoDrawCallback[f].sName == 'fnRowGrouping') {
310
                    oSettings.aoDrawCallback.splice(f, 1);
311
                    break;
312
                }
313
            }
314
315
            oSettings.aaSortingFixed = null;
316
        },
317
    }).rowGrouping(
318
        {
319
            iGroupingOrderByColumnIndex: 0,
320
            sGroupingColumnSortDirection: "desc"
321
        }
322
    );
323
324
    if ( $("#issues-table").length ) {
325
        $("#issues-table_processing").position({
326
            of: $( "#issues-table" ),
327
            collision: "none"
328
        });
329
    }
330
331
    // Don't load relatives' issues table unless it is clicked on
332
    var relativesIssuesTable;
333
    $("#relatives-issues-tab").click( function() {
334
        if ( ! relativesIssuesTable ) {
335
            relativesIssuesTable = $("#relatives-issues-table").dataTable({
336
                "sDom": "<'row-fluid'<'span6'><'span6'>r>t<'row-fluid'>t",
337
                "aaSorting": [],
338
                "aoColumns": [
339
                    {
340
                        "mDataProp": function( oObj ) {
341
                            var today = new Date();
342
                            var due = new Date( oObj.date_due );
343
                            if ( today > due ) {
344
                                return "<span class='overdue'>" + oObj.date_due_formatted + "</span>";
345
                            } else {
346
                                return oObj.date_due_formatted;
347
                            }
348
                        }
349
                    },
350
                    {
351
                        "mDataProp": function ( oObj ) {
352
                            title = "<a href='/cgi-bin/koha/catalogue/detail.pl?biblionumber="
353
                                  + oObj.biblionumber
354
                                  + "'>"
355
                                  + oObj.title;
356
357
                            $.each(oObj.subtitle, function( index, value ) {
358
                                      title += " " + value.subfield;
359
                            });
360
361
                            title += "</a>";
362
363
                            if ( oObj.author ) {
364
                                title += " " + BY + " " + oObj.author;
365
                            }
366
367
                            if ( oObj.itemnotes ) {
368
                                var span_class = "";
369
                                if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
370
                                    span_class = "circ-hlt";
371
                                }
372
                                title += " - <span class='" + span_class + "'>" + oObj.itemnotes + "</span>"
373
                            }
374
375
                            title += " "
376
                                  + "<a href='/cgi-bin/koha/catalogue/moredetail.pl?biblionumber="
377
                                  + oObj.biblionumber
378
                                  + "&itemnumber="
379
                                  + oObj.itemnumber
380
                                  + "#"
381
                                  + oObj.itemnumber
382
                                  + "'>"
383
                                  + oObj.barcode
384
                                  + "</a>";
385
386
                            return title;
387
                        }
388
                    },
389
                    { "mDataProp": "itemtype" },
390
                    { "mDataProp": "issuedate" },
391
                    { "mDataProp": "branchname" },
392
                    { "mDataProp": "itemcallnumber" },
393
                    { "mDataProp": "charge" },
394
                    { "mDataProp": "price" },
395
                    {
396
                        "mDataProp": function( oObj ) {
397
                            return "<a href='/cgi-bin/koha/members/moremember.pl?borrowernumber=" + oObj.borrowernumber + "'>"
398
                                 + oObj.borrower.firstname + " " + oObj.borrower.surname + " (" + oObj.borrower.cardnumber + ")</a>"
399
                        }
400
                    },
401
                ],
402
                "bPaginate": false,
403
                "bProcessing": true,
404
                "bServerSide": true,
405
                "sAjaxSource": '/cgi-bin/koha/svc/checkouts.pl',
406
                "fnServerData": function ( sSource, aoData, fnCallback ) {
407
                    $.each(relatives_borrowernumbers, function( index, value ) {
408
                        aoData.push( { "name": "borrowernumber", "value": value } );
409
                    });
410
411
                    $.getJSON( sSource, aoData, function (json) {
412
                        fnCallback(json)
413
                    } );
414
                },
415
            });
416
        }
417
    });
418
419
    if ( $("#relatives-issues-table").length ) {
420
        $("#relatives-issues-table_processing").position({
421
            of: $( "#relatives-issues-table" ),
422
            collision: "none"
423
        });
424
    }
425
426
    if ( AllowRenewalLimitOverride ) {
427
        $( '#override_limit' ).click( function () {
428
            if ( this.checked ) {
429
                $( '.renewals-allowed' ).show(); $( '.renewals-disabled' ).hide();
430
            } else {
431
                $( '.renewals-allowed' ).hide(); $( '.renewals-disabled' ).show();
432
            }
433
        } ).attr( 'checked', false );
434
    }
435
 });
(-)a/koha-tmpl/intranet-tmpl/prog/en/js/holds.js (+133 lines)
Line 0 Link Here
1
$(document).ready(function() {
2
    // Don't load holds table unless it is clicked on
3
    var holdsTable;
4
    $("#holds-tab").click( function() {
5
        if ( ! holdsTable ) {
6
            holdsTable = $("#holds-table").dataTable({
7
                "sDom": "<'row-fluid'<'span6'><'span6'>r>t<'row-fluid'>t",
8
                "aoColumns": [
9
                    {
10
                        "mDataProp": "reservedate_formatted"
11
                    },
12
                    {
13
                        "mDataProp": function ( oObj ) {
14
                            title = "<a href='/cgi-bin/koha/catalogue/detail.pl?biblionumber="
15
                                  + oObj.biblionumber
16
                                  + "'>"
17
                                  + oObj.title;
18
19
                            $.each(oObj.subtitle, function( index, value ) {
20
                                      title += " " + value.subfield;
21
                            });
22
23
                            title += "</a>";
24
25
                            if ( oObj.author ) {
26
                                title += " " + BY + " " + oObj.author;
27
                            }
28
29
                            if ( oObj.itemnotes ) {
30
                                var span_class = "";
31
                                if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
32
                                    span_class = "circ-hlt";
33
                                }
34
                                title += " - <span class='" + span_class + "'>" + oObj.itemnotes + "</span>"
35
                            }
36
37
                            title += " "
38
                                  + "<a href='/cgi-bin/koha/catalogue/moredetail.pl?biblionumber="
39
                                  + oObj.biblionumber
40
                                  + "&itemnumber="
41
                                  + oObj.itemnumber
42
                                  + "#"
43
                                  + oObj.itemnumber
44
                                  + "'>"
45
                                  + oObj.barcode
46
                                  + "</a>";
47
48
                            return title;
49
                        }
50
                    },
51
                    {
52
                        "mDataProp": function( oObj ) {
53
                            return oObj.itemcallnumber || "";
54
                        }
55
                    },
56
                    {
57
                        "mDataProp": function( oObj ) {
58
                            var data = "";
59
60
                            if ( oObj.suspend == 1 ) {
61
                                data += "<p>" + HOLD_IS + " <strong> " + SUSPENDED + " </strong>";
62
                                if ( oObj.suspend_until ) {
63
                                    data += " " + UNTIL + " " + oObj.suspend_until_formatted;
64
                                }
65
                                data += "</p>";
66
                            }
67
68
                            if ( oObj.barcode ) {
69
                                data += "<em>";
70
                                if ( oObj.found == "W" ) {
71
                                    data += ITEM_IS + " <strong> " + WAITING + " </strong>";
72
73
                                    if ( ! oObj.waiting_here ) {
74
                                        data += " " + AT + " " + oObj.waiting_at;
75
                                    }
76
                                } else if ( oObj.transferred ) {
77
                                    data += ITEM_IS + " <strong> " + IN_TRANSIT + " </strong> " + FROM + oObj.from_branch;
78
                                } else if ( oObj.not_transferred ) {
79
                                    data += NOT_TRANSFERRED_YET + " " + oObj.not_transferred_by;
80
                                }                                 data += "</em>";
81
82
                                data += " <a href='/cgi-bin/koha/catalogue/detail.pl?biblionumber="
83
                                     + oObj.biblionumber + "'>" + oObj.barcode + "</a>";
84
                            }
85
86
                            return data;
87
                        }
88
                    },
89
                    { "mDataProp": "expirationdate_formatted" },
90
                    {
91
                        "mDataProp": function( oObj ) {
92
                            if ( oObj.priority && parseInt( oObj.priority ) && parseInt( oObj.priority ) > 0 ) {
93
                                return oObj.priority;
94
                            } else {
95
                                return "";
96
                            }
97
                        }
98
                    },
99
                    {
100
                        "mDataProp": function( oObj ) {
101
                            return "<select name='rank-request'>"
102
                                 + "<option value='n'>" + NO + "</option>"
103
                                 + "<option value='del'>" + YES  + "</option>"
104
                                 + "</select>"
105
                                 + "<input type='hidden' name='biblionumber' value='" + oObj.biblionumber + "'>"
106
                                 + "<input type='hidden' name='borrowernumber' value='" + borrowernumber + "'>"
107
                                 + "<input type='hidden' name='reserve_id' value='" + oObj.reserve_id + "'>";
108
                        }
109
                    }
110
                ],
111
                "bPaginate": false,
112
                "bProcessing": true,
113
                "bServerSide": true,
114
                "sAjaxSource": '/cgi-bin/koha/svc/holds.pl',
115
                "fnServerData": function ( sSource, aoData, fnCallback ) {
116
                    aoData.push( { "name": "borrowernumber", "value": borrowernumber } );
117
118
                    $.getJSON( sSource, aoData, function (json) {
119
                        fnCallback(json)
120
                    } );
121
                },
122
            });
123
124
            if ( $("#holds-table").length ) {
125
                $("#holds-table_processing").position({
126
                    of: $( "#holds-table" ),
127
                    collision: "none"
128
                });
129
            }
130
        }
131
    });
132
133
});
(-)a/koha-tmpl/intranet-tmpl/prog/en/js/pages/circulation.js (-63 / +10 lines)
Lines 1-57 Link Here
1
$(document).ready(function() {
1
$(document).ready(function() {
2
    $('#patronlists').tabs();
2
    $("#CheckAllExports").on("click",function(){
3
    var allcheckboxes = $(".checkboxed");
3
        $(".export:visible").attr("checked", "checked" );
4
    $("#renew_all").on("click",function(){
5
        allcheckboxes.checkCheckboxes(":input[name*=items]");
6
        allcheckboxes.unCheckCheckboxes(":input[name*=barcodes]");
7
    });
8
    $("#CheckAllitems").on("click",function(){
9
        allcheckboxes.checkCheckboxes(":input[name*=items]");
10
        allcheckboxes.unCheckCheckboxes(":input[name*=barcodes]"); return false;
11
    });
12
    $("#CheckNoitems").on("click",function(){
13
        allcheckboxes.unCheckCheckboxes(":input[name*=items]"); return false;
14
    });
15
    $("#CheckAllreturns").on("click",function(){
16
        allcheckboxes.checkCheckboxes(":input[name*=barcodes]");
17
        allcheckboxes.unCheckCheckboxes(":input[name*=items]"); return false;
18
    });
19
    $("#CheckNoreturns" ).on("click",function(){
20
        allcheckboxes.unCheckCheckboxes(":input[name*=barcodes]"); return false;
21
    });
22
23
    $("#CheckAllexports").on("click",function(){
24
        allcheckboxes.checkCheckboxes(":input[name*=biblionumbers]");
25
        return false;
4
        return false;
26
    });
5
    });
27
    $("#CheckNoexports").on("click",function(){
6
    $("#UncheckAllExports").on("click",function(){
28
        allcheckboxes.unCheckCheckboxes(":input[name*=biblionumbers]");
7
        $(".export:visible").removeAttr("checked");
29
        return false;
8
        return false;
30
    });
9
    });
31
10
32
    $("#relrenew_all").on("click",function(){
11
    $('#patronlists').tabs();
33
        allcheckboxes.checkCheckboxes(":input[name*=items]");
12
34
        allcheckboxes.unCheckCheckboxes(":input[name*=barcodes]");
35
    });
36
    $("#relCheckAllitems").on("click",function(){
37
        allcheckboxes.checkCheckboxes(":input[name*=items]");
38
        allcheckboxes.unCheckCheckboxes(":input[name*=barcodes]"); return false;
39
    });
40
    $("#relCheckNoitems").on("click",function(){
41
        allcheckboxes.unCheckCheckboxes(":input[name*=items]"); return false;
42
    });
43
    $("#relCheckAllreturns").on("click",function(){
44
        allcheckboxes.checkCheckboxes(":input[name*=barcodes]");
45
        allcheckboxes.unCheckCheckboxes(":input[name*=items]"); return false;
46
    });
47
    $("#relCheckNoreturns").on("click",function(){
48
        allcheckboxes.unCheckCheckboxes(":input[name*=barcodes]"); return false;
49
    });
50
    $("#messages ul").after("<a href=\"#\" id=\"addmessage\">"+MSG_ADD_MESSAGE+"</a>");
13
    $("#messages ul").after("<a href=\"#\" id=\"addmessage\">"+MSG_ADD_MESSAGE+"</a>");
14
51
    $("#borrower_messages .cancel").on("click",function(){
15
    $("#borrower_messages .cancel").on("click",function(){
52
        $("#add_message_form").hide();
16
        $("#add_message_form").hide();
53
        $("#addmessage").show();
17
        $("#addmessage").show();
54
    });
18
    });
19
55
    $("#addmessage").on("click",function(){
20
    $("#addmessage").on("click",function(){
56
        $(this).hide();
21
        $(this).hide();
57
        $("#add_message_form").show();
22
        $("#add_message_form").show();
Lines 76-89 $(document).ready(function() { Link Here
76
        export_checkouts(export_format);
41
        export_checkouts(export_format);
77
        return false;
42
        return false;
78
    });
43
    });
79
    // Clicking the table cell checks the checkbox inside it
44
80
    $("td").on("click",function(e){
81
        if(e.target.tagName.toLowerCase() == 'td'){
82
          $(this).find("input:checkbox:visible").each( function() {
83
            $(this).click();
84
          });
85
        }
86
    });
87
});
45
});
88
46
89
function export_checkouts(format) {
47
function export_checkouts(format) {
Lines 107-119 function export_checkouts(format) { Link Here
107
    } else if (format == 'iso2709') {
65
    } else if (format == 'iso2709') {
108
        $("#dont_export_item").val(1);
66
        $("#dont_export_item").val(1);
109
    }
67
    }
110
    document.issues.action="/cgi-bin/koha/tools/export.pl";
68
111
    document.getElementById("export_format").value = format;
69
    document.getElementById("export_format").value = format;
112
    document.issues.submit();
70
    document.issues.submit();
113
114
    /* Reset form action to its initial value */
115
    document.issues.action="/cgi-bin/koha/reserve/renewscript.pl";
116
117
}
71
}
118
72
119
function validate1(date) {
73
function validate1(date) {
Lines 124-133 function validate1(date) { Link Here
124
        return false;
78
        return false;
125
     }
79
     }
126
}
80
}
127
128
// prevent adjacent checkboxes from being checked simultaneously
129
function radioCheckBox(box){
130
    box.parents("td").siblings().find("input:checkbox.radio").each(function(){
131
        $(this).removeAttr("checked");
132
    });
133
 }
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref (-6 lines)
Lines 40-51 Circulation: Link Here
40
                  desc: latest to earliest
40
                  desc: latest to earliest
41
            - due date.
41
            - due date.
42
        -
42
        -
43
            - pref: UseTablesortForCirc
44
              choices:
45
                  yes: "Enable"
46
                  no: "Don't enable"
47
            - "the sorting of current patron checkouts on the circulation screen. <br/>NOTE: Enabling this function may slow down circulation time for patrons with many checkouts."
48
        -
49
            - pref: soundon
43
            - pref: soundon
50
              choices: 
44
              choices: 
51
                 yes: "Enable"
45
                 yes: "Enable"
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt (-445 / +114 lines)
Lines 13-101 Link Here
13
</title>
13
</title>
14
[% INCLUDE 'doc-head-close.inc' %]
14
[% INCLUDE 'doc-head-close.inc' %]
15
[% INCLUDE 'calendar.inc' %]
15
[% INCLUDE 'calendar.inc' %]
16
[% IF ( UseTablesortForCirc ) %]<link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" />
16
17
<link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" />
17
[% INCLUDE 'datatables.inc' %][% END %]
18
[% INCLUDE 'datatables.inc' %][% END %]
18
<script type="text/javascript" src="[% interface %]/lib/jquery/plugins/jquery.checkboxes.min.js"></script>
19
<script type="text/javascript" src="[% interface %]/lib/jquery/plugins/jquery.checkboxes.min.js"></script>
20
[% INCLUDE 'strings.inc' %]
19
<script type="text/javascript" src="[% interface %]/lib/jquery/plugins/jquery-ui-timepicker-addon.min.js"></script>
21
<script type="text/javascript" src="[% interface %]/lib/jquery/plugins/jquery-ui-timepicker-addon.min.js"></script>
20
[% INCLUDE 'timepicker.inc' %]
22
[% INCLUDE 'timepicker.inc' %]
23
<script type="text/javascript" src="[% interface %]/lib/jquery/plugins/jquery.dataTables.rowGrouping.js"></script>
21
<script type="text/javascript" src="[% themelang %]/js/pages/circulation.js"></script>
24
<script type="text/javascript" src="[% themelang %]/js/pages/circulation.js"></script>
25
<script type="text/javascript" src="[% themelang %]/js/checkouts.js"></script>
26
<script type="text/javascript" src="[% themelang %]/js/holds.js"></script>
22
<script type="text/javascript">
27
<script type="text/javascript">
23
//<![CDATA[
28
//<![CDATA[
29
/* Set some variable needed in circulation.js */
30
var interface = "[% interface %]";
31
var theme = "[% theme %]";
32
var borrowernumber = "[% borrowernumber %]";
33
var branchcode = "[% branch %]";
34
var exports_enabled = "[% exports_enabled %]";
35
var AllowRenewalLimitOverride = [% CAN_user_circulate_override_renewals && AllowRenewalLimitOverride %];
36
var relatives_borrowernumbers = new Array();
37
[% FOREACH b IN relatives_borrowernumbers %]
38
    relatives_borrowernumbers.push("[% b %]");
39
[% END %]
40
24
var MSG_ADD_MESSAGE = _("Add a new message");
41
var MSG_ADD_MESSAGE = _("Add a new message");
25
var MSG_EXPORT_SELECT_CHECKOUTS = _("You must select checkout(s) to export");
42
var MSG_EXPORT_SELECT_CHECKOUTS = _("You must select checkout(s) to export");
26
[% IF ( UseTablesortForCirc && dateformat == 'metric' ) %]dt_add_type_uk_date();[% END %]
27
[% IF ( borrowernumber ) %]if($.cookie("holdfor") != [% borrowernumber %]){ $.cookie("holdfor",null, { path: "/", expires: 0 }); }[% ELSE %]$.cookie("holdfor",null, { path: "/", expires: 0 });[% END %]
43
[% IF ( borrowernumber ) %]if($.cookie("holdfor") != [% borrowernumber %]){ $.cookie("holdfor",null, { path: "/", expires: 0 }); }[% ELSE %]$.cookie("holdfor",null, { path: "/", expires: 0 });[% END %]
28
[% UNLESS ( borrowernumber ) %][% UNLESS ( CGIselectborrower ) %]window.onload=function(){ $('#findborrower').focus(); };[% END %][% END %]
44
[% UNLESS ( borrowernumber ) %][% UNLESS ( CGIselectborrower ) %]window.onload=function(){ $('#findborrower').focus(); };[% END %][% END %]
29
	 $(document).ready(function() {
45
30
        $('#patronlists').tabs([% IF ( UseTablesortForCirc ) %]{
46
$(document).ready(function() {
31
            // Correct table sizing for tables hidden in tabs
47
    [% IF !( CircAutoPrintQuickSlip == 'clear' ) %]
32
            // http://www.datatables.net/examples/api/tabs_and_scrolling.html
33
            "show": function(event, ui) {
34
                var oTable = $('div.dataTables_wrapper>table', ui.panel).dataTable();
35
                if ( oTable.length > 0 ) {
36
                    oTable.fnAdjustColumnSizing();
37
                }
38
            }
39
        }[% END %]);
40
        [% IF ( UseTablesortForCirc ) %]
41
        $("#issuest").dataTable($.extend(true, {}, dataTablesDefaults, {
42
            "sDom": 't',
43
            "aaSorting": [],
44
            "aoColumnDefs": [
45
                { "aTargets": [ -1, -2[% IF ( exports_enabled ) %], -3[% END %] ], "bSortable": false, "bSearchable": false }
46
            ],
47
            "aoColumns": [
48
                { "sType": "title-string" },{ "sType": "anti-the" },null,{ "sType": "title-string" },null,null,null,null,null,null[% IF ( exports_enabled ) %],null[% END %]
49
            ],
50
            "bPaginate": false
51
        }));
52
53
        $("#relissuest").dataTable($.extend(true, {}, dataTablesDefaults, {
54
            "sDom": 't',
55
            "aaSorting": [],
56
            "aoColumns": [
57
                { "sType": "title-string" },{ "sType": "anti-the" },null,{ "sType": "title-string" },null,null,null,null,{ "sType": "html" }
58
            ],
59
            "bPaginate": false
60
        }));
61
62
        $("#issuest").on("sort",function() {
63
            $("#previous").hide();  // Don't want to see "previous checkouts" header sorted with other rows
64
        });
65
        $("#relissuest").on("sort",function() {
66
            $("#relprevious").hide();  // Don't want to see "previous checkouts" header sorted with other rows
67
        });
68
        [% END %]
69
        [% IF ( AllowRenewalLimitOverride ) %]
70
        $( '#override_limit' ).click( function () {
71
            if ( this.checked ) {
72
                $( '.renewals-allowed' ).show(); $( '.renewals-disabled' ).hide();
73
            } else {
74
                $( '.renewals-allowed' ).hide(); $( '.renewals-disabled' ).show();
75
            }
76
        } ).attr( 'checked', false );
77
        [% END %][% IF !( CircAutoPrintQuickSlip == 'clear' ) %]
78
        // listen submit to trigger qslip on empty checkout
48
        // listen submit to trigger qslip on empty checkout
79
        $('#mainform').bind('submit',function() {
49
        $('#mainform').bind('submit',function() {
80
          if ($('#barcode').val() == '') {
50
            if ($('#barcode').val() == '') {
81
            return printx_window( '[% CircAutoPrintQuickSlip %]' ); }
51
                return printx_window( '[% CircAutoPrintQuickSlip %]' );
82
        });[% END %]
52
            }
83
53
        });
84
    [% IF ( CAN_user_circulate_override_renewals ) %]
85
    [% IF ( AllowRenewalLimitOverride ) %]
86
    $( '#override_limit' ).click( function () {
87
        if ( this.checked ) {
88
           $( '.renewals-allowed' ).show(); $( '.renewals-disabled' ).hide();
89
        } else {
90
           $( '.renewals-allowed' ).hide(); $( '.renewals-disabled' ).show();
91
        }
92
    } ).attr( 'checked', false );
93
    [% END %]
94
    [% END %]
95
    [% IF AutoResumeSuspendedHolds %]
96
        $("#suspend_until").datepicker("option", "minDate", 1); // require that hold suspended until date is after today
97
    [% END %]
54
    [% END %]
98
 });
55
});
99
//]]>
56
//]]>
100
</script>
57
</script>
101
</head>
58
</head>
Lines 526-532 No patron matched <span class="ex">[% message %]</span> Link Here
526
    [% ELSE %]
483
    [% ELSE %]
527
	    <input type="text" name="barcode" id="barcode" class="barcode focus" size="14" />
484
	    <input type="text" name="barcode" id="barcode" class="barcode focus" size="14" />
528
    [% END %]
485
    [% END %]
529
    <input type="submit" value="Check Out" />
486
    <button type="submit" class="btn">Check out</button>
530
487
531
    [% IF ( SpecifyDueDate ) %]<div class="date-select">
488
    [% IF ( SpecifyDueDate ) %]<div class="date-select">
532
        <div class="hint">Specify due date [% INCLUDE 'date-format.inc' %]: </div>
489
        <div class="hint">Specify due date [% INCLUDE 'date-format.inc' %]: </div>
Lines 538-544 No patron matched <span class="ex">[% message %]</span> Link Here
538
[% ELSE %]
495
[% ELSE %]
539
<input type="checkbox" id="stickyduedate" onclick="this.form.barcode.focus();" name="stickyduedate" />
496
<input type="checkbox" id="stickyduedate" onclick="this.form.barcode.focus();" name="stickyduedate" />
540
[% END %]
497
[% END %]
541
          <input type="button" class="action" id="cleardate" value="Clear" name="cleardate" onclick="this.checked = false; this.form.duedatespec.value = ''; this.form.stickyduedate.checked = false; this.form.barcode.focus(); return false;" />
498
          <button class="btn btn-small action" id="cleardate" name="cleardate" onclick="this.checked = false; this.form.duedatespec.value = ''; this.form.stickyduedate.checked = false; this.form.barcode.focus(); return false;" >Clear</button>
542
</div>[% END %]
499
</div>[% END %]
543
          <input type="hidden" name="borrowernumber" id="borrowernumber" value="[% borrowernumber %]" />
500
          <input type="hidden" name="borrowernumber" id="borrowernumber" value="[% borrowernumber %]" />
544
          <input type="hidden" name="branch" value="[% branch %]" />
501
          <input type="hidden" name="branch" value="[% branch %]" />
Lines 697-1095 No patron matched <span class="ex">[% message %]</span> Link Here
697
<div class="yui-g"><div id="patronlists" class="toptabs">
654
<div class="yui-g"><div id="patronlists" class="toptabs">
698
655
699
<ul>
656
<ul>
700
<li>    [% IF ( issuecount ) %]
657
    <li>
658
        [% IF ( issuecount ) %]
701
            <a href="#checkouts">[% issuecount %] Checkout(s)</a>
659
            <a href="#checkouts">[% issuecount %] Checkout(s)</a>
702
    [% ELSE %]
660
        [% ELSE %]
703
            <a href="#checkouts">0 Checkouts</a>
661
            <a href="#checkouts">0 Checkouts</a>
704
    [% END %]</li>
705
[% IF ( displayrelissues ) %]
706
<li><a href="#relissues">Relatives' checkouts</a></li>
707
[% END %]
708
<li>[% IF ( countreserv ) %]
709
            <a href="#reserves">[% countreserv %] Hold(s)</a>
710
    [% ELSE %]
711
            <a href="#reserves">0 Holds</a>
712
    [% END %]</li>
713
    <li><a id="debarments-tab-link" href="#reldebarments">[% debarments.size %] Restrictions</a></li>
714
715
</ul>
716
717
<!-- SUMMARY : TODAY & PREVIOUS ISSUES -->
718
<div id="checkouts">
719
[% IF ( issuecount ) %]
720
    <form name="issues" action="/cgi-bin/koha/reserve/renewscript.pl" method="post" class="checkboxed">
721
    <input type="hidden" value="circ" name="destination" />
722
    <input type="hidden" name="cardnumber" value="[% cardnumber %]" />
723
    <input type="hidden" name="borrowernumber" value="[% borrowernumber %]" />
724
    <input type="hidden" name="branch" value="[% branch %]" />
725
        <table id="issuest">
726
    <thead><tr>
727
        <th scope="col">Due date</th>
728
        <th scope="col">Title</th>
729
        <th scope="col">Item type</th>
730
        <th scope="col">Checked out on</th>
731
        <th scope="col">Checked out from</th>
732
        <th scope="col">Call no</th>
733
        <th scope="col">Charge</th>
734
        <th scope="col">Price</th>
735
        <th scope="col">Renew <p class="column-tool"><a href="#" id="CheckAllitems">select all</a> | <a href="#" id="CheckNoitems">none</a></p></th>
736
        <th scope="col">Check in <p class="column-tool"><a href="#" id="CheckAllreturns">select all</a> | <a href="#" id="CheckNoreturns">none</a></p></th>
737
        [% IF ( exports_enabled ) %]
738
          <th scope="col">Export <p class="column-tool"><a href="#" id="CheckAllexports">select all</a> | <a href="#" id="CheckNoexports">none</a></p></th>
739
        [% END %]
662
        [% END %]
740
    </tr></thead>
663
    </li>
741
[% IF ( todayissues ) %]
742
[% INCLUDE 'checkouts-table-footer.inc' %]
743
	<tbody>
744
745
    [% FOREACH todayissue IN todayissues %]
746
    [% IF ( loop.odd ) %]
747
    <tr>
748
    [% ELSE %]
749
    <tr class="highlight">
750
    [% END %]
751
        [% IF ( todayissue.od ) %]<td class="od">[% ELSE %]<td>[% END %]
752
        <span title="[% todayissue.dd_sort %]">[% todayissue.dd %]</span>
753
664
754
            [% IF ( todayissue.itemlost ) %]
665
    [% IF relatives_issues_count %]
755
                <span class="lost">[% AuthorisedValues.GetByCode( 'LOST', todayissue.itemlost ) %]</span>
666
        <li><a id="relatives-issues-tab" href="#relatives-issues">Relatives' checkouts</a></li>
756
            [% END %]
757
            [% IF ( todayissue.damaged ) %]
758
                <span class="dmg">[% AuthorisedValues.GetByCode( 'DAMAGED', todayissue.damaged ) %]</span>
759
            [% END %]
760
        </td>
761
        <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% todayissue.biblionumber %]&amp;type=intra"><strong>[% todayissue.title |html %][% FOREACH subtitl IN todayissue.subtitle %] [% subtitl.subfield %][% END %]</strong></a>[% IF ( todayissue.author ) %], by [% todayissue.author %][% END %][% IF ( todayissue.itemnotes ) %]- <span class="circ-hlt">[% todayissue.itemnotes %]</span>[% END %] <a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=[% todayissue.biblionumber %]&amp;itemnumber=[% todayissue.itemnumber %]#item[% todayissue.itemnumber %]">[% todayissue.barcode %]</a></td>
762
        <td>[% UNLESS ( noItemTypeImages ) %] [% IF ( todayissue.itemtype_image ) %]<img src="[% todayissue.itemtype_image %]" alt="" />[% END %][% END %][% todayissue.itemtype %]</td>
763
        <td><span title="[% todayissue.displaydate_sort %]">[% todayissue.checkoutdate %]</span></td>
764
        [% IF ( todayissue.multiple_borrowers ) %]<td>[% todayissue.firstname %] [% todayissue.surname %]</td>[% END %]
765
        <td>[% todayissue.issuingbranchname %]</td>
766
        <td>[% todayissue.itemcallnumber %]</td>
767
            <td>[% todayissue.charge %]</td>
768
            <td>[% todayissue.replacementprice %]</td>
769
      [% IF ( todayissue.renew_failed ) %]
770
            <td class="problem">Renewal failed</td>
771
      [% ELSE %]
772
        <td><span style="padding: 0 1em;">[% IF ( todayissue.renewals ) %][% todayissue.renewals %][% ELSE %]0[% END %]</span>
773
        [% IF ( todayissue.can_renew ) %]
774
        <input type="checkbox" name="all_items[]" value="[% todayissue.itemnumber %]" checked="checked" style="display: none;" />
775
        [% IF ( todayissue.od ) %]
776
            <input type="checkbox" class="radio" name="items[]" value="[% todayissue.itemnumber %]" checked="checked" />
777
        [% ELSE %]
778
            <input type="checkbox" class="radio" name="items[]" value="[% todayissue.itemnumber %]" />
779
        [% END %]
780
            [% IF todayissue.renewsallowed && todayissue.renewsleft %]
781
                <span class="renewals">([% todayissue.renewsleft %] of [% todayissue.renewsallowed %] renewals remaining)</span>
782
            [% END %]
783
        [% ELSE %]
784
            [% IF ( todayissue.can_confirm ) %]<span class="renewals-allowed" style="display: none">
785
                <input type="checkbox" name="all_items[]" value="[% todayissue.itemnumber %]" checked="checked" style="display: none;" />
786
                [% IF ( todayissue.od ) %]
787
                    <input type="checkbox" class="radio" name="items[]" value="[% todayissue.itemnumber %]" checked="checked" />
788
                [% ELSE %]
789
                    <input type="checkbox" class="radio" name="items[]" value="[% todayissue.itemnumber %]" />
790
                [% END %]
791
                </span>
792
                [% IF todayissue.renewsallowed && todayissue.renewsleft && !todayissue.renew_error_too_soon %]
793
                    <span class="renewals">([% todayissue.renewsleft %] of [% todayissue.renewsallowed %] renewals remaining)</span>
794
                [% END %]
795
                <span class="renewals-disabled">
796
            [% END %]
797
            [% IF ( todayissue.renew_error_on_reserve ) %]
798
                <a href="/cgi-bin/koha/reserve/request.pl?biblionumber=[% todayissue.biblionumber %]">On hold</a>
799
            [% ELSIF ( todayissue.renew_error_too_many ) %]
800
                Not renewable
801
            [% ELSIF ( todayissue.renew_error_too_soon ) %]
802
                No renewal before [% todayissue.soonestrenewdate %]
803
                <span class="renewals">([% todayissue.renewsleft %] of [% todayissue.renewsallowed %] renewals remaining)</span>
804
            [% END %]
805
            [% IF ( todayissue.can_confirm ) %]
806
                </span>
807
            [% END %]
808
        [% END %]
809
        </td>
810
        [% END %]
811
        [% IF ( todayissue.return_failed ) %]
812
            <td class="problem">Checkin failed</td>
813
        [% ELSE %]
814
            [% IF ( todayissue.renew_error_on_reserve ) %]
815
               <td><a href="/cgi-bin/koha/reserve/request.pl?biblionumber=[% todayissue.biblionumber %]">On hold</a>
816
                <input type="checkbox" name="all_barcodes[]" value="[% todayissue.barcode %]" checked="checked" style="display: none;" />
817
                </td>
818
            [% ELSE %]
819
            <td><input type="checkbox" class="radio" name="barcodes[]"  value="[% todayissue.barcode %]" />
820
                <input type="checkbox" name="all_barcodes[]" value="[% todayissue.barcode %]" checked="checked" style="display: none;" />
821
            </td>
822
            [% END %]
823
        [% END %]
824
        [% IF ( exports_enabled ) %]
825
          <td style="text-align:center;">
826
            <input type="checkbox" id="export_[% todayissue.biblionumber %]" name="biblionumbers" value="[% todayissue.biblionumber %]" />
827
            <input type="checkbox" name="itemnumbers" value="[% todayissue.itemnumber %]" style="visibility:hidden;" />
828
          </td>
829
        [% END %]
830
    </tr>
831
    [% END %] <!-- /loop todayissues -->
832
    <!-- /if todayissues -->[% END %]
833
834
[% IF ( previssues ) %]
835
    [% UNLESS ( todayissues ) %]
836
    [% INCLUDE 'checkouts-table-footer.inc' %]
837
        <tbody>
838
    [% END %]
839
    [% IF ( UseTablesortForCirc ) %]<tr id="previous"><th><span title="">Previous checkouts</span></th><th></th><th></th><th><span title=""></span></th><th></th><th></th><th></th><th></th><th></th><th></th>[% IF ( exports_enabled ) %]<th></th>[% END %]</tr>[% ELSE %]<tr id="previous">[% IF ( exports_enabled ) %]<th colspan="11">[% ELSE %]<th colspan="10">[% END %]Previous checkouts</th></tr>[% END %]
840
    [% FOREACH previssue IN previssues %]
841
    [% IF ( loop.odd ) %]
842
        <tr>
843
    [% ELSE %]
844
        <tr class="highlight">
845
    [% END %]
667
    [% END %]
846
        [% IF ( previssue.od ) %]<td class="od">[% ELSE %]<td>[% END %]
847
        <span title="[% previssue.dd_sort %]">[% previssue.dd %]</span>
848
668
849
            [% IF ( previssue.itemlost ) %]
669
    <li>
850
                <span class="lost">[% AuthorisedValues.GetByCode( 'LOST', previssue.itemlost ) %]</span>
670
        [% IF ( holds_count ) %]
851
            [% END %]
671
            <a href="#reserves" id="holds-tab">[% holds_count %] Hold(s)</a>
852
            [% IF ( previssue.damaged ) %]
853
                <span class="dmg">[% AuthorisedValues.GetByCode( 'DAMAGED', previssue.damaged ) %]</span>
854
            [% END %]
855
        </td>
856
        <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% previssue.biblionumber %]&amp;type=intra"><strong>[% previssue.title |html %][% FOREACH subtitl IN previssue.subtitle %] [% subtitl.subfield %][% END %]</strong></a>[% IF ( previssue.author ) %], by [% previssue.author %][% END %] [% IF ( previssue.itemnotes ) %]- [% previssue.itemnotes %][% END %] <a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=[% previssue.biblionumber %]&amp;itemnumber=[% previssue.itemnumber %]#item[% previssue.itemnumber %]">[% previssue.barcode %]</a></td>
857
        <td>
858
            [% previssue.itemtype %]
859
        </td>
860
        <td><span title="[% previssue.displaydate_sort %]">[% previssue.displaydate %]</span></td>
861
        [% IF ( previssue.multiple_borrowers ) %]<td>[% previssue.firstname %] [% previssue.surname %]</td>[% END %]
862
        <td>[% previssue.issuingbranchname %]</td>
863
        <td>[% previssue.itemcallnumber %]</td>
864
        <td>[% previssue.charge %]</td>
865
        <td>[% previssue.replacementprice %]</td>
866
      [% IF ( previssue.renew_failed ) %]
867
            <td class="problem">Renewal failed</td>
868
      [% ELSE %]
869
        <td><span style="padding: 0 1em;">[% IF ( previssue.renewals ) %][% previssue.renewals %][% ELSE %]0[% END %]</span>
870
        [% IF ( previssue.can_renew ) %]
871
        <input type="checkbox" name="all_items[]" value="[% previssue.itemnumber %]" checked="checked" style="display: none;" />
872
        [% IF ( previssue.od ) %]
873
            <input type="checkbox" class="radio" name="items[]" value="[% previssue.itemnumber %]" checked="checked" />
874
        [% ELSE %]
875
            <input type="checkbox" class="radio" name="items[]" value="[% previssue.itemnumber %]" />
876
        [% END %]
877
            [% IF previssue.renewsallowed && previssue.renewsleft %]
878
                <span class="renewals">([% previssue.renewsleft %] of [% previssue.renewsallowed %] renewals remaining)</span>
879
            [% END %]
880
        [% ELSE %]
881
            [% IF ( previssue.can_confirm ) %]<span class="renewals-allowed" style="display: none">
882
                <input type="checkbox" name="all_items[]" value="[% previssue.itemnumber %]" checked="checked" style="display: none;" />
883
                [% IF ( previssue.od ) %]
884
                    <input type="checkbox" class="radio" name="items[]" value="[% previssue.itemnumber %]" checked="checked" />
885
                [% ELSE %]
886
                    <input type="checkbox" class="radio" name="items[]" value="[% previssue.itemnumber %]" />
887
                [% END %]
888
                </span>
889
                [% IF previssue.renewsallowed && previssue.renewsleft && !previssue.renew_error_too_soon %]
890
                    <span class="renewals">([% previssue.renewsleft %] of [% previssue.renewsallowed %] renewals remaining)</span>
891
                [% END %]
892
                <span class="renewals-disabled">
893
            [% END %]
894
            [% IF ( previssue.renew_error_on_reserve ) %]
895
                <a href="/cgi-bin/koha/reserve/request.pl?biblionumber=[% previssue.biblionumber %]">On Hold</a>
896
            [% ELSIF ( previssue.renew_error_too_many ) %]
897
                Not renewable
898
            [% ELSIF ( previssue.renew_error_too_soon ) %]
899
                No renewal before [% previssue.soonestrenewdate %]
900
                <span class="renewals">([% previssue.renewsleft %] of [% previssue.renewsallowed %] renewals remaining)</span>
901
            [% END %]
902
            [% IF ( previssue.can_confirm ) %]
903
                </span>
904
            [% END %]
905
        [% END %]
906
        </td>
907
        [% END %]
908
		  [% IF ( previssue.return_failed ) %]
909
            <td class="problem">Check-in failed</td>
910
        [% ELSE %]
672
        [% ELSE %]
911
            [% IF ( previssue.renew_error_on_reserve ) %]
673
            <a href="#reserves" id="holds-tab">0 Holds</a>
912
               <td><a href="/cgi-bin/koha/reserve/request.pl?biblionumber=[% previssue.biblionumber %]">On hold</a>
913
                <input type="checkbox" name="all_barcodes[]" value="[% previssue.barcode %]" checked="checked" style="display: none;" />
914
                </td>
915
            [% ELSE %]
916
            <td><input type="checkbox" class="radio" name="barcodes[]"  value="[% previssue.barcode %]" />
917
                <input type="checkbox" name="all_barcodes[]" value="[% previssue.barcode %]" checked="checked" style="display: none;" />
918
            </td>
919
            [% END %]
920
        [% END %]
921
        [% IF ( exports_enabled ) %]
922
          <td style="text-align:center;">
923
            <input type="checkbox" id="export_[% previssue.biblionumber %]" name="biblionumbers" value="[% previssue.biblionumber %]" />
924
            <input type="checkbox" name="itemnumbers" value="[% previssue.itemnumber %]" style="visibility:hidden;" />
925
          </td>
926
        [% END %]
927
    </tr>
928
    <!-- /loop previssues -->[% END %]
929
<!--/if previssues -->[% END %]
930
      </tbody>
931
    </table>
932
    [% IF ( issuecount ) %]
933
    <fieldset class="action">
934
        [% IF ( CAN_user_circulate_override_renewals ) %]
935
        [% IF ( AllowRenewalLimitOverride ) %]
936
        <label for="override_limit">Override renewal limit:</label>
937
        <input type="checkbox" name="override_limit" id="override_limit" value="1" />
938
        [% END %]
939
        [% END %]
940
        <input type="submit" name="renew_checked" value="Renew or Return checked items" />
941
        <input type="submit" id="renew_all" name="renew_all" value="Renew all" />
942
    </fieldset>
943
        [% IF ( exports_enabled ) %]
944
            <fieldset>
945
            <label for="export_formats"><b>Export checkouts using format:</b></label>
946
            <select name="export_formats" id="export_formats">
947
                <option value="iso2709_995">ISO2709 with items</option>
948
                <option value="iso2709">ISO2709 without items</option>
949
                [% IF ( export_with_csv_profile ) %]
950
                    <option value="csv">CSV</option>
951
                [% END %]
952
953
            </select>
954
           <label for="export_remove_fields">Don't export fields:</label> <input type="text" id="export_remove_fields" name="export_remove_fields" value="[% export_remove_fields %]" title="Use for iso2709 exports" />
955
            <input type="hidden" name="op" value="export" />
956
            <input type="hidden" id="export_format" name="format" value="iso2709" />
957
            <input type="hidden" id="dont_export_item" name="dont_export_item" value="0" />
958
            <input type="hidden" id="record_type" name="record_type" value="bibs" />
959
            <input type="button" id="export_submit" value="Export" />
960
            </fieldset>
961
        [% END %]
674
        [% END %]
962
    [% END %]
675
    </li>
963
    </form>
964
[% ELSE %]
965
<p>Patron has nothing checked out.</p>
966
[% END %]
967
968
</div>
969
970
676
971
[% IF ( displayrelissues ) %]
677
    <li><a id="debarments-tab-link" href="#reldebarments">[% debarments.size %] Restrictions</a></li>
972
<div id="relissues">
678
</ul>
973
    <table id="relissuest">
974
    <thead>
975
    <tr>
976
        <th scope="col">Due date</th>
977
        <th scope="col">Title</th>
978
        <th scope="col">Item type</th>
979
        <th scope="col">Checked out on</th>
980
        <th scope="col">Checked out from</th>
981
        <th scope="col">Call no</th>
982
        <th scope="col">Charge</th>
983
        <th scope="col">Price</th>
984
        <th scope="col">Patron</th>
985
    </tr>
986
    </thead>
987
[% IF ( relissues ) %]	<tbody>
988
989
    [% FOREACH relissue IN relissues %]
990
    [% IF ( loop.odd ) %]
991
    <tr>
992
    [% ELSE %]
993
    <tr class="highlight">
994
    [% END %]
995
        [% IF ( relissue.overdue ) %]<td class="od">[% ELSE %]<td>[% END %]
996
            <span title="[% relissue.dd_sort %]">[% relissue.dd %]</span></td>
997
679
998
            [% IF ( relissue.itemlost ) %]
680
<!-- SUMMARY : TODAY & PREVIOUS ISSUES -->
999
                <span class="lost">[% AuthorisedValues.GetByCode( 'LOST', relissue.itemlost ) %]</span>
681
<div id="checkouts">
1000
            [% END %]
682
    [% IF ( issuecount ) %]
1001
            [% IF ( relissue.damaged ) %]
683
        <table id="issues-table">
1002
                <span class="dmg">[% AuthorisedValues.GetByCode( 'DAMAGED', relissue.damaged ) %]</span>
684
            <thead>
685
                <tr>
686
                    <th scope="col">&nbsp;</th>
687
                    <th scope="col">Due date</th>
688
                    <th scope="col">Due date</th>
689
                    <th scope="col">Title</th>
690
                    <th scope="col">Item type</th>
691
                    <th scope="col">Checked out on</th>
692
                    <th scope="col">Checked out from</th>
693
                    <th scope="col">Call no</th>
694
                    <th scope="col">Charge</th>
695
                    <th scope="col">Price</th>
696
                    <th scope="col">Renew <p class="column-tool"><a href="#" id="CheckAllRenewals">select all</a> | <a href="#" id="UncheckAllRenewals">none</a></p></th>
697
                    <th scope="col">Check in <p class="column-tool"><a href="#" id="CheckAllCheckins">select all</a> | <a href="#" id="UncheckAllCheckins">none</a></p></th>
698
                    <th scope="col">Export <p class="column-tool"><a href="#" id="CheckAllExports">select all</a> | <a href="#" id="UncheckAllExports">none</a></p></th>
699
                </tr>
700
            </thead>
701
            [% INCLUDE 'checkouts-table-footer.inc' %]
702
        </table>
703
704
        <fieldset class="action">
705
            [% IF ( CAN_user_circulate_override_renewals ) %]
706
                [% IF ( AllowRenewalLimitOverride ) %]
707
                    <label for="override_limit">Override renewal limit:</label>
708
                    <input type="checkbox" name="override_limit" id="override_limit" value="1" />
709
                [% END %]
1003
            [% END %]
710
            [% END %]
1004
        </td>
711
            <button class="btn" id="RenewCheckinChecked"><i class="icon-check"></i> Renew or return checked items</button>
1005
        <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% relissue.biblionumber %]&amp;type=intra"><strong>[% relissue.title |html %][% FOREACH subtitl IN relissue.subtitle %] [% subtitl.subfield %][% END %]</strong></a>[% IF ( relissue.author ) %], by [% relissue.author %][% END %][% IF ( relissue.itemnotes ) %]- <span class="circ-hlt">[% relissue.itemnotes %]</span>[% END %] <a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=[% relissue.biblionumber %]&amp;itemnumber=[% relissue.itemnumber %]#item[% relissue.itemnumber %]">[% relissue.barcode %]</a></td>
712
            <button class="btn" id="RenewAll"><i class="icon-book"></i> Renew all</button>
1006
        <td>[% UNLESS ( noItemTypeImages ) %] [% IF ( relissue.itemtype_image ) %]<img src="[% relissue.itemtype_image %]" alt="" />[% END %][% END %][% relissue.itemtype %]</td>
713
        </fieldset>
1007
        <td><span title="[% relissue.displaydate_sort %]">[% relissue.displaydate %]</span></td>
1008
        <td>[% relissue.issuingbranchname %]</td>
1009
        <td>[% relissue.itemcallnumber %]</td>
1010
        <td>[% relissue.charge %]</td>
1011
        <td>[% relissue.replacementprice %]</td><td><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% relissue.borrowernumber %]">[% relissue.firstname %] [% relissue.surname %] ([% relissue.cardnumber %])</a></td>
1012
     </tr>
1013
    [% END %] <!-- /loop relissues -->
1014
    <!-- /if relissues -->[% END %]
1015
[% IF ( relprevissues ) %]
1016
    [% IF ( UseTablesortForCirc ) %]<tr id="relprevious"><th><span title="">Previous checkouts</span></th><th></th><th></th><th><span title=""></span></th><th></th><th></th><th></th><th></th><th></th></tr>[% ELSE %]<tr id="relprevious"><th colspan="9">Previous checkouts</th></tr>[% END %]
1017
    [% FOREACH relprevissue IN relprevissues %]
1018
    [% IF ( loop.odd ) %]
1019
        <tr>
1020
    [% ELSE %]
714
    [% ELSE %]
1021
        <tr class="highlight">
715
        <p>Patron has nothing checked out.</p>
1022
    [% END %]
716
    [% END %]
1023
        [% IF ( relprevissue.overdue ) %]<td class="od">[% ELSE %]<td>[% END %]
1024
        <span title="[% relprevissue.dd_sort %]">[% relprevissue.dd %]</span>
1025
        </td>
1026
        <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% relprevissue.biblionumber %]&amp;type=intra"><strong>[% relprevissue.title |html %][% FOREACH subtitl IN relprevissue.subtitle %] [% subtitl.subfield %][% END %]</strong></a>[% IF ( relprevissue.author ) %], by [% relprevissue.author %][% END %] [% IF ( relprevissue.itemnotes ) %]- [% relprevissue.itemnotes %][% END %] <a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=[% relprevissue.biblionumber %]&amp;itemnumber=[% relprevissue.itemnumber %]#item[% relprevissue.itemnumber %]">[% relprevissue.barcode %]</a></td>
1027
        <td>[% UNLESS noItemTypeImages %][% IF relprevissue.itemtype_image %]<img src="[% relprevissue.itemtype_image %]" alt="" />[% END %][% END %][% relprevissue.itemtype %]</td>
1028
        <td><span title="[% relprevissue.displaydate_sort %]">[% relprevissue.displaydate %]</span></td>
1029
        <td>[% relprevissue.issuingbranchname %]</td>
1030
        <td>[% relprevissue.itemcallnumber %]</td>
1031
	[% IF ( relprevissue.multiple_borrowers ) %]<td>[% relprevissue.firstname %] [% relprevissue.surname %]</td>[% END %]
1032
        <td>[% relprevissue.charge %]</td>
1033
        <td>[% relprevissue.replacementprice %]</td>
1034
        <td><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% relprevissue.borrowernumber %]">[% relprevissue.firstname %] [% relprevissue.surname %] ([% relprevissue.cardnumber %])</a></td>
1035
1036
    </tr>
1037
    <!-- /loop relprevissue -->[% END %]
1038
<!--/if relprevissues -->[% END %]
1039
      </tbody>
1040
    </table>
1041
1042
</div>
717
</div>
1043
[% END %]<!-- end displayrelissues -->
718
719
[% IF ( relatives_issues_count ) %]
720
    <div id="relatives-issues">
721
        <table id="relatives-issues-table">
722
            <thead>
723
                <tr>
724
                    <th scope="col">Due date</th>
725
                    <th scope="col">Title</th>
726
                    <th scope="col">Item type</th>
727
                    <th scope="col">Checked out on</th>
728
                    <th scope="col">Checked out from</th>
729
                    <th scope="col">Call no</th>
730
                    <th scope="col">Charge</th>
731
                    <th scope="col">Price</th>
732
                    <th scope="col">Patron</th>
733
                </tr>
734
            </thead>
735
        </table>
736
    </div>
737
[% END %]
1044
738
1045
[% INCLUDE borrower_debarments.inc %]
739
[% INCLUDE borrower_debarments.inc %]
1046
740
1047
<div id="reserves">
741
<div id="reserves">
1048
[% IF ( reservloop ) %]
742
[% IF ( holds_count ) %]
1049
    <form action="/cgi-bin/koha/reserve/modrequest.pl" method="post">
743
    <form action="/cgi-bin/koha/reserve/modrequest.pl" method="post">
1050
	<input type="hidden" name="from" value="circ" />
744
        <input type="hidden" name="from" value="circ" />
1051
    <table id="holdst">
745
        <table id="holds-table" style="width: 100% !Important;">
1052
        <thead><tr>
746
            <thead>
1053
            <th>Hold date</th>
747
                <tr>
1054
            <th>Title</th>
748
                    <th>Hold date</th>
1055
            <th>Call number</th>
749
                    <th>Title</th>
1056
            <th>Barcode</th>
750
                    <th>Call number</th>
1057
            <th>Expiration</th>
751
                    <th>Barcode</th>
1058
            <th>Priority</th>
752
                    <th>Expiration</th>
1059
            <th>Delete?</th>
753
                    <th>Priority</th>
1060
            <th>&nbsp;</th>
754
                    <th>Delete?</th>
1061
        </tr></thead>
755
                </tr>
1062
		<tbody>
756
            </thead>
1063
        [% FOREACH reservloo IN reservloop %]
757
        </table>
1064
        <tr class="[% reservloo.color %]">
758
1065
                    <td>[% reservloo.reservedate %]</td>
759
        <fieldset class="action">
1066
                    <td><a href="/cgi-bin/koha/reserve/request.pl?biblionumber=[% reservloo.biblionumber %]"><strong>[% reservloo.title |html %][% FOREACH subtitl IN reservloo.subtitle %] [% subtitl.subfield %][% END %]</strong></a>[% IF ( reservloo.author ) %], by [% reservloo.author %][% END %]</td>
760
            <input type="submit" class="cancel" name="submit" value="Cancel marked holds" />
1067
                    <td>[% reservloo.itemcallnumber %]</td>
761
        </fieldset>
1068
					<td><em>[% IF ( reservloo.barcodereserv ) %]Item [% reservloo.barcodereserv %]
1069
                        [% END %][% IF ( reservloo.waiting ) %] <strong>waiting at [% reservloo.waitingat %]</strong>
1070
                        [% END %]
1071
                        [% IF ( reservloo.transfered ) %] <strong>in transit</strong> from
1072
                        [% reservloo.frombranch %] since [% reservloo.datesent %]
1073
                        [% END %]
1074
                        [% IF ( reservloo.nottransfered ) %] hasn't been transferred yet from [% reservloo.nottransferedby %]</i>
1075
                        [% END %]</em></td>
1076
                    <td>[% reservloo.expirationdate | $KohaDates %]</td>
1077
                    <td>
1078
                        [% IF ( reservloo.waitingposition ) %]<b> [% reservloo.waitingposition %] </b>[% END %]
1079
                    </td>
1080
				<td><select name="rank-request">
1081
                    <option value="n">No</option>
1082
                    <option value="del">Yes</option>
1083
                </select>
1084
                <input type="hidden" name="biblionumber" value="[% reservloo.biblionumber %]" />
1085
                <input type="hidden" name="borrowernumber" value="[% borrowernumber %]" />
1086
                <input type="hidden" name="reserve_id" value="[% reservloo.reserve_id %]" />
1087
            </td>
1088
            <td>[% IF ( reservloo.suspend ) %]Suspended [% IF ( reservloo.suspend_until ) %] until [% reservloo.suspend_until | $KohaDates %][% END %][% END %]</td>
1089
            </tr>
1090
        [% END %]</tbody>
1091
    </table>
1092
            <fieldset class="action"><input type="submit" class="cancel" name="submit" value="Cancel marked holds" /></fieldset>
1093
    </form>
762
    </form>
1094
763
1095
    [% IF SuspendHoldsIntranet %]
764
    [% IF SuspendHoldsIntranet %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt (-280 / +124 lines)
Lines 9-21 Link Here
9
</title>
9
</title>
10
[% INCLUDE 'doc-head-close.inc' %]
10
[% INCLUDE 'doc-head-close.inc' %]
11
[% INCLUDE 'calendar.inc' %]
11
[% INCLUDE 'calendar.inc' %]
12
<link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" />
12
<link rel="stylesheet" type="text/css" href="[% interface %]/[% theme %]/en/css/datatables.css" />
13
[% INCLUDE 'datatables.inc' %]
13
[% INCLUDE 'datatables.inc' %]
14
<script type="text/javascript" src="[% interface %]/lib/jquery/plugins/jquery.checkboxes.min.js"></script>
14
[% INCLUDE 'strings.inc' %]
15
<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.checkboxes.min.js"></script>
15
<script type="text/javascript" src="[% interface %]/lib/jquery/plugins/jquery-ui-timepicker-addon.min.js"></script>
16
<script type="text/javascript" src="[% interface %]/lib/jquery/plugins/jquery-ui-timepicker-addon.min.js"></script>
16
[% INCLUDE 'timepicker.inc' %]
17
[% INCLUDE 'timepicker.inc' %]
18
<script type="text/javascript" src="[% interface %]/lib/jquery/plugins/jquery.dataTables.rowGrouping.js"></script>
19
<script type="text/javascript" src="[% themelang %]/js/checkouts.js"></script>
20
<script type="text/javascript" src="[% themelang %]/js/holds.js"></script>
17
<script type="text/JavaScript">
21
<script type="text/JavaScript">
18
//<![CDATA[
22
//<![CDATA[
23
/* Set some variable needed in circulation.js */
24
var interface = "[% interface %]";
25
var theme = "[% theme %]";
26
var borrowernumber = "[% borrowernumber %]";
27
var branchcode = "[% branch %]";
28
var exports_enabled = "[% exports_enabled %]";
29
var AllowRenewalLimitOverride = [% CAN_user_circulate_override_renewals && AllowRenewalLimitOverride %];
30
var relatives_borrowernumbers = new Array();
31
[% FOREACH b IN relatives_borrowernumbers %]
32
    relatives_borrowernumbers.push("[% b %]");
33
[% END %]
34
19
$(document).ready(function() {
35
$(document).ready(function() {
20
    $('#finesholdsissues').tabs({
36
    $('#finesholdsissues').tabs({
21
        // Correct table sizing for tables hidden in tabs
37
        // Correct table sizing for tables hidden in tabs
Lines 27-49 $(document).ready(function() { Link Here
27
            }
43
            }
28
        }
44
        }
29
    } );
45
    } );
30
    $("#issuest").dataTable($.extend(true, {}, dataTablesDefaults, {
31
        "sDom": 't',
32
        "aoColumnDefs": [
33
            { "aTargets": [ -1,-2 ], "bSortable": false, "bSearchable": false }
34
        ],
35
        "aoColumns": [
36
            { "sType": "title-string" },{ "sType": "anti-the" },null,{ "sType": "title-string" },null,null,null,null,null,null
37
        ],
38
        "bPaginate": false
39
    }));
40
    $("#relissuest").dataTable($.extend(true, {}, dataTablesDefaults, {
41
        "sDom": 't',
42
        "aoColumns": [
43
            { "sType": "title-string" },{ "sType": "anti-the" },null,{ "sType": "title-string" },null,null,null,null,null
44
        ],
45
        "bPaginate": false
46
    }));
47
    $("#holdst").dataTable($.extend(true, {}, dataTablesDefaults, {
46
    $("#holdst").dataTable($.extend(true, {}, dataTablesDefaults, {
48
        "sDom": 't',
47
        "sDom": 't',
49
        "aoColumnDefs": [
48
        "aoColumnDefs": [
Lines 66-107 $(document).ready(function() { Link Here
66
        }
65
        }
67
        return confirm(_("Are you sure you want to replace the current patron image? This cannot be undone."));
66
        return confirm(_("Are you sure you want to replace the current patron image? This cannot be undone."));
68
	});[% END %]
67
	});[% END %]
69
	$("#renew_all"      ).click(function(){ $(".checkboxed").checkCheckboxes(":input[name*=items]"   ); $(".checkboxed").unCheckCheckboxes(":input[name*=barcodes]"); });
68
70
	$("#CheckAllitems"  ).click(function(){ $(".checkboxed").checkCheckboxes(":input[name*=items]"   ); $(".checkboxed").unCheckCheckboxes(":input[name*=barcodes]"); return false; });
71
    $("#CheckNoitems"   ).click(function(){ $(".checkboxed").unCheckCheckboxes(":input[name*=items]"); return false; });
72
	$("#CheckAllreturns").click(function(){ $(".checkboxed").checkCheckboxes(":input[name*=barcodes]"); $(".checkboxed").unCheckCheckboxes(":input[name*=items]"); return false; });
73
    $("#CheckNoreturns" ).click(function(){ $(".checkboxed").unCheckCheckboxes(":input[name*=barcodes]"); return false; });
74
75
    $("#relrenew_all"      ).click(function(){ $(".checkboxed").checkCheckboxes(":input[name*=items]"   ); $(".checkboxed").unCheckCheckboxes(":input[name*=barcodes]"); });
76
    $("#relCheckAllitems"  ).click(function(){ $(".checkboxed").checkCheckboxes(":input[name*=items]"   ); $(".checkboxed").unCheckCheckboxes(":input[name*=barcodes]"); return false; });
77
    $("#relCheckNoitems"   ).click(function(){ $(".checkboxed").unCheckCheckboxes(":input[name*=items]"); return false; });
78
    $("#relCheckAllreturns").click(function(){ $(".checkboxed").checkCheckboxes(":input[name*=barcodes]"); $(".checkboxed").unCheckCheckboxes(":input[name*=items]"); return false; });
79
    $("#relCheckNoreturns" ).click(function(){ $(".checkboxed").unCheckCheckboxes(":input[name*=barcodes]"); return false; });
80
81
82
    [% IF ( CAN_user_circulate_override_renewals ) %]
83
    [% IF ( AllowRenewalLimitOverride ) %]
84
    $( '#override_limit' ).click( function () {
85
        if ( this.checked ) {
86
           $( '.renewals-allowed' ).show(); $( '.renewals-disabled' ).hide();
87
        } else {
88
           $( '.renewals-allowed' ).hide(); $( '.renewals-disabled' ).show();
89
        }
90
    } ).attr( 'checked', false );
91
    [% END %]
92
    [% END %]
93
	$("td").click(function(e){
94
		if(e.target.tagName.toLowerCase() == 'td'){
95
           $(this).find("input:checkbox").each( function() {
96
               $(this).attr('checked', !$(this).attr('checked'));
97
			   if($(this).attr('checked')){
98
                    $(this).parent().siblings().find("input:checkbox").each(function(){
99
                       if($(this).attr('checked')){ $(this).removeAttr('checked'); }
100
                   });
101
			   }
102
           });
103
		}
104
	});
105
    $("#suspend_until").datepicker({ minDate: 1 }); // require that hold suspended until date is after today
69
    $("#suspend_until").datepicker({ minDate: 1 }); // require that hold suspended until date is after today
106
    $("#newduedate").datetimepicker({
70
    $("#newduedate").datetimepicker({
107
        minDate: 1, // require that renewal date is after today
71
        minDate: 1, // require that renewal date is after today
Lines 424-613 function validate1(date) { Link Here
424
388
425
<div id="finesholdsissues" class="toptabs">
389
<div id="finesholdsissues" class="toptabs">
426
    <ul>
390
    <ul>
427
        <li><a href="#checkedout">[% issueloop.size %] Checkout(s)</a></li>
391
        <li><a href="#checkouts">[% issueloop.size %] Checkout(s)</a></li>
428
    [% IF relissueloop.size %]
392
        [% IF relatives_issues_count %]
429
        <li><a href="#relissues">Relatives' Checkouts</a></li>
393
            <li><a href="#relatives-issues" id="relatives-issues-tab">Relatives' checkouts</a></li>
430
    [% END %]
394
        [% END %]
431
        <li><a href="#finesandcharges">Fines &amp; Charges</a></li>
395
        <li><a href="#finesandcharges">Fines &amp; Charges</a></li>
432
        <li>[% IF ( countreserv ) %]
396
        <li>
433
            <a href="#onhold">[% countreserv %] Hold(s)</a>    [% ELSE %]
397
            [% IF ( holds_count ) %]
434
            <a href="#onhold">0 Holds</a>
398
                <a href="#reserves" id="holds-tab">[% holds_count %] Hold(s)</a>
435
    [% END %]</li>
399
            [% ELSE %]
400
                <a href="#reserves" id="holds-tab">0 Holds</a>
401
            [% END %]
402
        </li>
436
        <li><a id="debarments-tab-link" href="#reldebarments">[% debarments.size %] Restrictions</a></li>
403
        <li><a id="debarments-tab-link" href="#reldebarments">[% debarments.size %] Restrictions</a></li>
437
    </ul>
404
    </ul>
438
405
439
    <form action="/cgi-bin/koha/reserve/renewscript.pl" method="post" class="checkboxed">
406
    <div id="checkouts">
440
    <input type="hidden" name="borrowernumber" value="[% borrowernumber %]" />
407
        [% IF ( issuecount ) %]
441
    <input type="hidden" name="branch" value="[% branch %]" />
408
            <form name="issues" action="/cgi-bin/koha/tools/export.pl" method="post" class="checkboxed">
442
<div id="checkedout">
409
                <table id="issues-table" style="width: 100% !Important;">
443
    [% IF ( issueloop ) %]
410
                    <thead>
444
    <table id="issuest">
411
                        <tr>
445
    <thead>
412
                            <th scope="col">&nbsp;</th>
446
        <tr>
413
                            <th scope="col">Due date</th>
447
            <th scope="col">Due date</th>
414
                            <th scope="col">Due date</th>
448
            <th scope="col">Title</th>
415
                            <th scope="col">Title</th>
449
            <th scope="col">Item type</th>
416
                            <th scope="col">Item type</th>
450
            <th scope="col">Checked out on</th> 
417
                            <th scope="col">Checked out on</th>
451
            <th scope="col">Checked out from</th> 
418
                            <th scope="col">Checked out from</th>
452
            <th scope="col">Call no.</th>
419
                            <th scope="col">Call no</th>
453
            <th scope="col">Charge</th>
420
                            <th scope="col">Charge</th>
454
            <th scope="col">Price</th>
421
                            <th scope="col">Price</th>
455
            <th scope="col">Renew <p class="column-tool"><a href="#" id="CheckAllitems">select all</a> | <a href="#" id="CheckNoitems">none</a></p></th>
422
                            <th scope="col">Renew <p class="column-tool"><a href="#" id="CheckAllRenewals">select all</a> | <a href="#" id="UncheckAllRenewals">none</a></p></th>
456
            <th scope="col">Check in <p class="column-tool"><a href="#" id="CheckAllreturns">select all</a> | <a href="#" id="CheckNoreturns">none</a></p></th>
423
                            <th scope="col">Check in <p class="column-tool"><a href="#" id="CheckAllCheckins">select all</a> | <a href="#" id="UncheckAllCheckins">none</a></p></th>
457
        </tr></thead>
424
                            <th scope="col">Export <p class="column-tool"><a href="#" id="CheckAllExports">select all</a> | <a href="#" id="UncheckAllExports">none</a></p></th>
458
        [% INCLUDE 'checkouts-table-footer.inc' %]
425
                        </tr>
459
       <tbody>
426
                    </thead>
460
       [% FOREACH issueloo IN issueloop %]
427
                    [% INCLUDE 'checkouts-table-footer.inc' %]
461
428
                </table>
462
          [% IF ( issueloo.overdue ) %]
429
463
          <tr class="problem">
430
                [% IF ( issuecount ) %]
464
          [% ELSE %]
431
                    <fieldset class="action">
465
          <tr>
432
                        [% IF ( CAN_user_circulate_override_renewals ) %]
466
          [% END %]
433
                            [% IF ( AllowRenewalLimitOverride ) %]
467
          [% IF ( issueloo.red ) %]
434
                                <label for="override_limit">Override renewal limit:</label>
468
              <td class="od">
435
                                <input type="checkbox" name="override_limit" id="override_limit" value="1" />
469
          [% ELSE %]
436
                            [% END %]
470
            <td>
437
                        [% END %]
471
          [% END %]
438
                        <button class="btn" id="RenewCheckinChecked"><i class="icon-check"></i> Renew or return checked items</button>
472
                <span title="[% issueloo.date_due %]">[% issueloo.date_due | $KohaDates %]</span>
439
                        <button class="btn" id="RenewAll"><i class="icon-book"></i> Renew all</button>
473
                [% IF ( issueloo.itemlost ) %]
440
                    </fieldset>
474
                                        <span class="lost">[% issueloo.itemlost %]</span>
441
442
                    [% IF ( exports_enabled ) %]
443
                        <fieldset>
444
                            <label for="export_formats"><b>Export checkouts using format:</b></label>
445
                            <select name="export_formats" id="export_formats">
446
                                <option value="iso2709_995">ISO2709 with items</option>
447
                                <option value="iso2709">ISO2709 without items</option>
448
                                [% IF ( export_with_csv_profile ) %]
449
                                    <option value="csv">CSV</option>
450
                                [% END %]
451
                            </select>
452
453
                           <label for="export_remove_fields">Don't export fields:</label> <input type="text" id="export_remove_fields" name="export_remove_fields" value="[% export_remove_fields %]" title="Use for iso2709 exports" />
454
                            <input type="hidden" name="op" value="export" />
455
                            <input type="hidden" id="export_format" name="format" value="iso2709" />
456
                            <input type="hidden" id="dont_export_item" name="dont_export_item" value="0" />
457
                            <input type="hidden" id="record_type" name="record_type" value="bibs" />
458
                            <button class="btn btn-small" id="export_submit"><i class="icon-download-alt"></i> Export</button>
459
                        </fieldset>
475
                    [% END %]
460
                    [% END %]
476
                [% IF ( issueloo.damaged ) %]
477
                                        <span class="dmg">[% issueloo.itemdamaged %]</span>
478
                [% END %]
479
</td>
480
            <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% issueloo.biblionumber %]"><strong>[% issueloo.title |html %][% FOREACH subtitl IN issueloo.subtitle %] [% subtitl.subfield %][% END %]</strong></a>[% IF ( issueloo.author ) %], by [% issueloo.author %][% END %] [% IF ( issueloo.publishercode ) %]; [% issueloo.publishercode %] [% END %] [% IF ( issueloo.publicationyear ) %], [% issueloo.publicationyear %][% END %] <a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=[% issueloo.biblionumber %]&amp;itemnumber=[% issueloo.itemnumber %]#item[% issueloo.itemnumber %]">[% issueloo.barcode %]</a></td>
481
<td>[% UNLESS ( noItemTypeImages ) %] [% IF ( issueloo.itemtype_image ) %]<img src="[% issueloo.itemtype_image %]" alt="" />[% END %][% END %][% issueloo.itemtype_description %]</td>
482
            <td><span title="[% issueloo.issuedate %]">[% issueloo.issuedate | $KohaDates%]</span></td>
483
            <td>[% issueloo.issuingbranchname %]</td>
484
            <td>[% issueloo.itemcallnumber %]</td>
485
            <td>[% issueloo.charge %]</td>
486
            <td>[% issueloo.replacementprice %]</td>
487
      [% IF ( issueloo.renew_failed ) %]
488
            <td class="problem">Renewal Failed</td>
489
      [% ELSE %]
490
            <td><span style="padding: 0 1em;">[% IF ( issueloo.renewals ) %][% issueloo.renewals %][% ELSE %]0[% END %]</span>
491
            [% IF ( issueloo.norenew ) %]
492
                [% IF ( issueloo.can_confirm ) %]<span class="renewals-allowed" style="display: none">
493
                    <input type="checkbox" name="all_items[]" value="[% issueloo.itemnumber %]" checked="checked" style="display: none;" />
494
                    [% IF ( issueloo.od ) %]
495
                        <input type="checkbox" name="items[]" value="[% issueloo.itemnumber %]" checked="checked" />
496
                    [% ELSE %]
497
                        <input type="checkbox" name="items[]" value="[% issueloo.itemnumber %]" />
498
                    [% END %]
499
                    </span>
500
                    [% IF issueloo.renewsallowed && issueloo.renewsleft && !issueloo.norenew_reason_too_soon %]
501
                        <span class="renewals">([% issueloo.renewsleft %] of [% issueloo.renewsallowed %] renewals remaining)</span>
502
                    [% END %]
503
                    <span class="renewals-disabled">
504
                [% END %]
505
                [% IF ( issueloo.norenew_reason_on_reserve ) %]
506
                    <a href="/cgi-bin/koha/reserve/request.pl?biblionumber=[% issueloo.biblionumber %]">On Hold</a>
507
                [% ELSIF ( issueloo.norenew_reason_too_many ) %]
508
                    Not renewable
509
                [% ELSIF ( issueloo.norenew_reason_too_soon ) %]
510
                    No renewal before [% issueloo.soonestrenewdate %]
511
                    <span class="renewals">([% issueloo.renewsleft %] of [% issueloo.renewsallowed %] renewals remaining)</span>
512
                [% END %]
461
                [% END %]
513
                [% IF ( issueloo.can_confirm ) %]
462
            </form>
514
                    </span>
515
                [% END %]
516
            [% ELSE %]
517
            <input type="checkbox" name="all_items[]" value="[% issueloo.itemnumber %]" checked="checked" style="display: none;" />
518
            [% IF ( issueloo.red ) %]
519
            <input type="checkbox" name="items[]" value="[% issueloo.itemnumber %]" checked="checked" onclick="uncheck_sibling(this);" />
520
            [% ELSE %]
521
            <input type="checkbox" name="items[]" value="[% issueloo.itemnumber %]" onclick="uncheck_sibling(this);" />
522
            [% END %]
523
                [% IF issueloo.renewsallowed && issueloo.renewsleft %]
524
                    <span class="renewals">([% issueloo.renewsleft %] of [% issueloo.renewsallowed %] renewals remaining)</span>
525
                [% END %]
526
            [% END %]
527
            </td>
528
      [% END %]
529
      [% IF ( issueloo.return_failed ) %]
530
            <td class="problem">Check-in failed</td>
531
      [% ELSE %]
532
        [% IF ( issueloo.norenew_reason_on_reserve ) %]
533
            <td><a href="/cgi-bin/koha/reserve/request.pl?biblionumber=[% issueloo.biblionumber %]">On hold</a></td>
534
        [% ELSE %]
463
        [% ELSE %]
535
            <td><input type="checkbox" name="barcodes[]"  value="[% issueloo.barcode %]" onclick="uncheck_sibling(this);" />
464
            <p>Patron has nothing checked out.</p>
536
                <input type="checkbox" name="all_barcodes[]" value="[% issueloo.barcode %]" checked="checked" style="display: none;" />
537
            </td>
538
        [% END %]
539
      [% END %]
540
        </tr>
541
  [% END %]
542
        </tbody>
543
        </table>
544
        <fieldset class="action">
545
        [% IF ( CAN_user_circulate_override_renewals ) %]
546
        [% IF ( AllowRenewalLimitOverride ) %]
547
        <label for="override_limit">Override renewal limit:</label>
548
        <input type="checkbox" name="override_limit" id="override_limit" value="1" />
549
        [% END %]
465
        [% END %]
550
        [% END %]
466
    </div>
551
        <input type="submit" name="renew_checked" value="Renew or return checked items" />
552
        <input type="submit" id="renew_all" name="renew_all" value="Renew all" />
553
        </fieldset>
554
    [% ELSE %]<p>Patron has nothing checked out.</p>
555
[% END %]
556
</div>
557
558
467
559
[% IF relissueloop %]
468
[% IF ( relatives_issues_count ) %]
560
<div id="relissues">
469
    <div id="relatives-issues">
561
 <table id="relissuest">
470
        <table id="relatives-issues-table" style="width: 100% !Important;">
562
    <thead>
471
            <thead>
563
    <tr>
472
                <tr>
564
            <th scope="col">Due date</th>
473
                    <th scope="col">Due date</th>
565
            <th scope="col">Title</th>
474
                    <th scope="col">Title</th>
566
            <th scope="col">Item type</th>
475
                    <th scope="col">Item type</th>
567
            <th scope="col">Checked out on</th> 
476
                    <th scope="col">Checked out on</th>
568
            <th scope="col">Checked out from</th>
477
                    <th scope="col">Checked out from</th>
569
            <th scope="col">Call no.</th>
478
                    <th scope="col">Call no</th>
570
            <th scope="col">Charge</th>
479
                    <th scope="col">Charge</th>
571
            <th scope="col">Price</th>
480
                    <th scope="col">Price</th>
572
            <th scope="col">Patron</th>
481
                    <th scope="col">Patron</th>
573
        </tr>
482
                </tr>
574
    </thead>
483
            </thead>
575
       <tbody>
484
        </table>
576
       [% FOREACH relissueloo IN relissueloop %]
577
578
          [% IF ( relissueloo.overdue ) %]
579
          <tr class="problem">
580
          [% ELSE %]
581
          <tr>
582
          [% END %]
583
          [% IF ( relissueloo.red ) %]
584
            <td class="od">
585
          [% ELSE %]
586
            <td>
587
          [% END %]
588
                <span title="[% relissueloo.date_due %]">[% relissueloo.date_due | $KohaDates %]</span>
589
                [% IF ( relissueloo.itemlost ) %]
590
                                        <span class="lost">[% relissueloo.itemlost %]</span>
591
                    [% END %]
592
                [% IF ( relissueloo.damaged ) %]
593
                                        <span class="dmg">[% relissueloo.itemdamaged %]</span>
594
                [% END %]
595
</td>
596
            <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% relissueloo.biblionumber %]"><strong>[% relissueloo.title |html %][% FOREACH subtitl IN relissueloo.subtitle %] [% subtitl.subfield %][% END %]</strong></a>[% IF relissueloo.author %], by [% relissueloo.author %][% END %] [% IF relissueloo.publishercode %]; [% relissueloo.publishercode %] [% END %] [% IF relissueloo.publicationyear %], [% relissueloo.publicationyear %][% END %] <a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=[% relissueloo.biblionumber %]&amp;itemnumber=[% relissueloo.itemnumber %]#item[% relissueloo.itemnumber %]">[% relissueloo.barcode %]</a></td>
597
<td>[% UNLESS ( noItemTypeImages ) %] [% IF ( relissueloo.itemtype_image ) %]<img src="[% relissueloo.itemtype_image %]" alt="" />[% END %][% END %][% relissueloo.itemtype_description %]</td>
598
            <td><span title="[% relissueloo.issuedate %]">[% relissueloo.issuedate | $KohaDates %]</span></td>
599
            <td>[% relissueloo.issuingbranchname %]</td>
600
        <td>[% relissueloo.itemcallnumber %]</td>
601
        <td>[% relissueloo.charge %]</td>
602
        <td>[% relissueloo.replacementprice %]</td>
603
        <td><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% relissueloo.borrowernumber %]">[% relissueloo.firstname %] [% relissueloo.surname %] ([% relissueloo.cardnumber %])</a></td>
604
        </tr>
605
  [% END %]
606
        </tbody>
607
       </table>
608
    </div>
485
    </div>
609
[% END %]
486
[% END %]
610
    </form>
611
487
612
<div id="finesandcharges">
488
<div id="finesandcharges">
613
    [% IF ( totaldue_raw ) %]
489
    [% IF ( totaldue_raw ) %]
Lines 619-677 function validate1(date) { Link Here
619
495
620
[% INCLUDE borrower_debarments.inc %]
496
[% INCLUDE borrower_debarments.inc %]
621
497
622
<div id="onhold">
498
<div id="reserves">
623
[% IF ( reservloop ) %]
499
[% IF ( holds_count ) %]
624
<form action="/cgi-bin/koha/reserve/modrequest.pl" method="post">
500
    <form action="/cgi-bin/koha/reserve/modrequest.pl" method="post">
625
	<input type="hidden" name="from" value="borrower" />
501
        <input type="hidden" name="from" value="circ" />
626
	<table id="holdst">
502
        <table id="holds-table" style="width: 100% !Important;">
627
		<thead><tr>
503
            <thead>
628
			<th>Hold date</th>
504
                <tr>
629
			<th>Title</th>
505
                    <th>Hold date</th>
630
            <th>Call number</th>
506
                    <th>Title</th>
631
			<th>Barcode</th>
507
                    <th>Call number</th>
632
            <th>Expiration</th>
508
                    <th>Barcode</th>
633
			<th>Priority</th>
509
                    <th>Expiration</th>
634
			<th>Delete?</th>
510
                    <th>Priority</th>
635
			<th>&nbsp;</th>
511
                    <th>Delete?</th>
636
		</tr></thead>
512
                </tr>
637
		<tbody>[% FOREACH reservloo IN reservloop %]
513
            </thead>
638
		<tr class="[% reservloo.color %]">
514
        </table>
639
            <td><span title="[% reservloo.reservedate %]">[% reservloo.reservedate | $KohaDates %]</span></td>
640
            <td>
641
                <a href="/cgi-bin/koha/reserve/request.pl?biblionumber=[% reservloo.biblionumber %]">[% reservloo.title |html %][% FOREACH subtitl IN reservloo.subtitle %] [% subtitl.subfield %][% END %]</a>[% IF ( reservloo.author ) %], by [% reservloo.author %][% END %]
642
            </td>
643
            <td>[% reservloo.itemcallnumber %]</td>
644
            <td>[% IF ( reservloo.waiting ) %]
645
                <em>Item is <strong>waiting</strong></em>
646
                [% END %]
647
                [% IF ( reservloo.transfered ) %]
648
                <em>Item <strong>in transit</strong> from
649
                [% reservloo.frombranch %] since [% reservloo.datesent %] </em>
650
                [% END %]
651
515
652
                [% IF ( reservloo.nottransfered ) %]
516
        <fieldset class="action">
653
                <em>Item hasn't been transferred yet from [% reservloo.nottransferedby %]</em>
517
            <input type="submit" class="cancel" name="submit" value="Cancel marked holds" />
654
                [% END %]
518
        </fieldset>
655
                [% IF ( reservloo.barcodereserv ) %]
656
                <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% reservloo.biblionumber %]">[% reservloo.barcodereserv %]</a>
657
                [% END %]
658
            </td>
659
            <td>[% reservloo.expirationdate | $KohaDates %]</td>
660
            <td>[% IF ( reservloo.waitingposition ) %]<strong>[% reservloo.waitingposition %]</strong>[% END %]</td>
661
            <td><select name="rank-request">
662
                    <option value="n">No</option>
663
                    <option value="del">Yes</option>
664
                </select>
665
                <input type="hidden" name="biblionumber" value="[% reservloo.biblionumber %]" />
666
                <input type="hidden" name="borrowernumber" value="[% borrowernumber %]" />
667
                <input type="hidden" name="reserve_id" value="[% reservloo.reserve_id %]" />
668
            </td>
669
            <td>[% IF ( reservloo.suspend ) %]Suspended [% IF ( reservloo.suspend_until ) %] until [% reservloo.suspend_until | $KohaDates %][% END %][% END %]</td>
670
        </tr>
671
		[% END %]</tbody>
672
    </table>
673
674
        <fieldset class="action"><input type="submit" class="cancel" name="submit" value="Cancel marked holds" /></fieldset>
675
    </form>
519
    </form>
676
520
677
    [% IF SuspendHoldsIntranet %]
521
    [% IF SuspendHoldsIntranet %]
(-)a/members/moremember.pl (-195 / +16 lines)
Lines 2-7 Link Here
2
2
3
# Copyright 2000-2002 Katipo Communications
3
# Copyright 2000-2002 Katipo Communications
4
# Copyright 2010 BibLibre
4
# Copyright 2010 BibLibre
5
# Copyright 2014 ByWater Solutions
5
#
6
#
6
# This file is part of Koha.
7
# This file is part of Koha.
7
#
8
#
Lines 52-61 use C4::Form::MessagingPreferences; Link Here
52
use List::MoreUtils qw/uniq/;
53
use List::MoreUtils qw/uniq/;
53
use C4::Members::Attributes qw(GetBorrowerAttributes);
54
use C4::Members::Attributes qw(GetBorrowerAttributes);
54
use Koha::Borrower::Debarments qw(GetDebarments);
55
use Koha::Borrower::Debarments qw(GetDebarments);
55
#use Smart::Comments;
56
#use Data::Dumper;
57
use DateTime;
56
use DateTime;
58
use Koha::DateUtils;
57
use Koha::DateUtils;
58
use Koha::Database;
59
59
60
use vars qw($debug);
60
use vars qw($debug);
61
61
Lines 68-81 my $dbh = C4::Context->dbh; Link Here
68
my $input = CGI->new;
68
my $input = CGI->new;
69
$debug or $debug = $input->param('debug') || 0;
69
$debug or $debug = $input->param('debug') || 0;
70
my $print = $input->param('print');
70
my $print = $input->param('print');
71
my $override_limit = $input->param("override_limit") || 0;
72
my @failedrenews = $input->param('failedrenew');
73
my @failedreturns = $input->param('failedreturn');
74
my $error = $input->param('error');
75
my %renew_failed;
76
for my $renew (@failedrenews) { $renew_failed{$renew} = 1; }
77
my %return_failed;
78
for my $failedret (@failedreturns) { $return_failed{$failedret} = 1; }
79
71
80
my $template_name;
72
my $template_name;
81
my $quickslip = 0;
73
my $quickslip = 0;
Lines 115-122 my ( $template, $loggedinuser, $cookie ) = get_template_and_user( Link Here
115
);
107
);
116
my $borrowernumber = $input->param('borrowernumber');
108
my $borrowernumber = $input->param('borrowernumber');
117
109
118
#start the page and read in includes
110
my ( $od, $issue, $fines ) = GetMemberIssuesAndFines($borrowernumber);
119
my $data           = GetMember( 'borrowernumber' => $borrowernumber );
111
$template->param( issuecount => $issue );
112
113
my $data = GetMember( 'borrowernumber' => $borrowernumber );
120
114
121
if ( not defined $data ) {
115
if ( not defined $data ) {
122
    $template->param (unknowuser => 1);
116
    $template->param (unknowuser => 1);
Lines 126-133 if ( not defined $data ) { Link Here
126
120
127
my $category_type = $data->{'category_type'};
121
my $category_type = $data->{'category_type'};
128
122
129
### $category_type
130
131
$debug and printf STDERR "dates (enrolled,expiry,birthdate) raw: (%s, %s, %s)\n", map {$data->{$_}} qw(dateenrolled dateexpiry dateofbirth);
123
$debug and printf STDERR "dates (enrolled,expiry,birthdate) raw: (%s, %s, %s)\n", map {$data->{$_}} qw(dateenrolled dateexpiry dateofbirth);
132
foreach (qw(dateenrolled dateexpiry dateofbirth)) {
124
foreach (qw(dateenrolled dateexpiry dateofbirth)) {
133
		my $userdate = $data->{$_};
125
		my $userdate = $data->{$_};
Lines 251-264 if ( C4::Context->preference('OPACPrivacy') ) { Link Here
251
    $template->param( "privacy".$data->{'privacy'} => 1);
243
    $template->param( "privacy".$data->{'privacy'} => 1);
252
}
244
}
253
245
254
# current issues
246
my @relatives = GetMemberRelatives($borrowernumber);
255
#
247
my $relatives_issues_count =
256
my @borrowernumbers = GetMemberRelatives($borrowernumber);
248
  Koha::Database->new()->schema()->resultset('Issue')
257
my $issue       = GetPendingIssues($borrowernumber);
249
  ->count( { borrowernumber => \@relatives } );
258
my $relissue    = [];
250
259
if ( @borrowernumbers ) {
260
    $relissue    = GetPendingIssues(@borrowernumbers);
261
}
262
my $roadtype = C4::Koha::GetAuthorisedValueByCode( 'ROADTYPE', $data->{streettype} );
251
my $roadtype = C4::Koha::GetAuthorisedValueByCode( 'ROADTYPE', $data->{streettype} );
263
my $today       = DateTime->now( time_zone => C4::Context->tz);
252
my $today       = DateTime->now( time_zone => C4::Context->tz);
264
$today->truncate(to => 'day');
253
$today->truncate(to => 'day');
Lines 266-350 my @borrowers_with_issues; Link Here
266
my $overdues_exist = 0;
255
my $overdues_exist = 0;
267
my $totalprice = 0;
256
my $totalprice = 0;
268
257
269
my @issuedata = build_issue_data($issue);
270
my @relissuedata = build_issue_data($relissue);
271
272
273
### ###############################################################################
258
### ###############################################################################
274
# BUILD HTML
259
# BUILD HTML
275
# show all reserves of this borrower, and the position of the reservation ....
260
# show all reserves of this borrower, and the position of the reservation ....
276
if ($borrowernumber) {
261
if ($borrowernumber) {
277
262
    $template->param(
278
    # new op dev
263
        holds_count => Koha::Database->new()->schema()->resultset('Reserve')
279
    # now we show the status of the borrower's reservations
264
          ->count( { borrowernumber => $borrowernumber } ) );
280
    my @borrowerreserv = GetReservesFromBorrowernumber($borrowernumber );
281
    my @reservloop;
282
    foreach my $num_res (@borrowerreserv) {
283
        my %getreserv;
284
        my $getiteminfo  = GetBiblioFromItemNumber( $num_res->{'itemnumber'} );
285
        my $itemtypeinfo = getitemtypeinfo( $getiteminfo->{'itemtype'} );
286
        my ( $transfertwhen, $transfertfrom, $transfertto ) =
287
            GetTransfers( $num_res->{'itemnumber'} );
288
289
        foreach (qw(waiting transfered nottransfered)) {
290
            $getreserv{$_} = 0;
291
        }
292
        $getreserv{reservedate}  = $num_res->{'reservedate'};
293
        foreach (qw(biblionumber title author itemcallnumber )) {
294
            $getreserv{$_} = $getiteminfo->{$_};
295
        }
296
        $getreserv{barcodereserv}  = $getiteminfo->{'barcode'};
297
        $getreserv{itemtype}  = $itemtypeinfo->{'description'};
298
299
        # 		check if we have a waitin status for reservations
300
        if ( $num_res->{'found'} eq 'W' ) {
301
            $getreserv{color}   = 'reserved';
302
            $getreserv{waiting} = 1;
303
        }
304
305
        # 		check transfers with the itemnumber foud in th reservation loop
306
        if ($transfertwhen) {
307
            $getreserv{color}      = 'transfered';
308
            $getreserv{transfered} = 1;
309
            $getreserv{datesent}   = C4::Dates->new($transfertwhen, 'iso')->output('syspref') or die "Cannot get new($transfertwhen, 'iso') from C4::Dates";
310
            $getreserv{frombranch} = GetBranchName($transfertfrom);
311
        }
312
313
        if ( ( $getiteminfo->{'holdingbranch'} ne $num_res->{'branchcode'} )
314
            and not $transfertwhen )
315
        {
316
            $getreserv{nottransfered}   = 1;
317
            $getreserv{nottransferedby} =
318
                GetBranchName( $getiteminfo->{'holdingbranch'} );
319
        }
320
        $getreserv{title}          = $getiteminfo->{'title'};
321
        $getreserv{subtitle}       = GetRecordValue('subtitle', GetMarcBiblio($getiteminfo->{biblionumber}), GetFrameworkCode($getiteminfo->{biblionumber}));
322
323
# 		if we don't have a reserv on item, we put the biblio infos and the waiting position
324
        if ( $getiteminfo->{'title'} eq '' ) {
325
            my $getbibinfo = GetBiblioData( $num_res->{'biblionumber'} );
326
            my $getbibtype = getitemtypeinfo( $getbibinfo->{'itemtype'} );
327
            $getreserv{color}           = 'inwait';
328
            $getreserv{title}           = $getbibinfo->{'title'};
329
            $getreserv{subtitle}        = GetRecordValue('subtitle', GetMarcBiblio($num_res->{biblionumber}), GetFrameworkCode($num_res->{biblionumber}));
330
            $getreserv{nottransfered}   = 0;
331
            $getreserv{itemtype}        = $getbibtype->{'description'};
332
            $getreserv{author}          = $getbibinfo->{'author'};
333
            $getreserv{biblionumber}  = $num_res->{'biblionumber'};	
334
        }
335
        $getreserv{waitingposition} = $num_res->{'priority'};
336
        $getreserv{suspend} = $num_res->{'suspend'};
337
        $getreserv{suspend_until} = $num_res->{'suspend_until'};
338
        $getreserv{expirationdate} = $num_res->{'expirationdate'};
339
        $getreserv{reserve_id} = $num_res->{'reserve_id'};
340
341
        push( @reservloop, \%getreserv );
342
    }
343
344
    # return result to the template
345
    $template->param( reservloop => \@reservloop,
346
        countreserv => scalar @reservloop,
347
	 );
348
}
265
}
349
266
350
# current alert subscriptions
267
# current alert subscriptions
Lines 435-447 $template->param( Link Here
435
    totalprice      => sprintf("%.2f", $totalprice),
352
    totalprice      => sprintf("%.2f", $totalprice),
436
    totaldue        => sprintf("%.2f", $total),
353
    totaldue        => sprintf("%.2f", $total),
437
    totaldue_raw    => $total,
354
    totaldue_raw    => $total,
438
    issueloop       => @issuedata,
439
    relissueloop    => @relissuedata,
440
    overdues_exist  => $overdues_exist,
355
    overdues_exist  => $overdues_exist,
441
    error           => $error,
442
    StaffMember     => ($category_type eq 'S'),
356
    StaffMember     => ($category_type eq 'S'),
443
    is_child        => ($category_type eq 'C'),
357
    is_child        => ($category_type eq 'C'),
444
#   reserveloop     => \@reservedata,
445
    samebranch     => $samebranch,
358
    samebranch     => $samebranch,
446
    quickslip		  => $quickslip,
359
    quickslip		  => $quickslip,
447
    activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
360
    activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
Lines 449-548 $template->param( Link Here
449
    SuspendHoldsIntranet => C4::Context->preference('SuspendHoldsIntranet'),
362
    SuspendHoldsIntranet => C4::Context->preference('SuspendHoldsIntranet'),
450
    RoutingSerials => C4::Context->preference('RoutingSerials'),
363
    RoutingSerials => C4::Context->preference('RoutingSerials'),
451
    debarments => GetDebarments({ borrowernumber => $borrowernumber }),
364
    debarments => GetDebarments({ borrowernumber => $borrowernumber }),
365
    relatives_issues_count => $relatives_issues_count,
366
    relatives_borrowernumbers => \@relatives,
452
);
367
);
453
$template->param( $error => 1 ) if $error;
454
368
455
output_html_with_http_headers $input, $cookie, $template->output;
369
output_html_with_http_headers $input, $cookie, $template->output;
456
457
sub build_issue_data {
458
    my $issues = shift;
459
460
    my $localissue;
461
462
    foreach my $issue ( @{$issues} ) {
463
464
        # Getting borrower details
465
        my $memberdetails = GetMemberDetails( $issue->{borrowernumber} );
466
        $issue->{borrowername} =
467
          $memberdetails->{firstname} . ' ' . $memberdetails->{surname};
468
        $issue->{cardnumber} = $memberdetails->{cardnumber};
469
        my $issuedate;
470
        if ($issue->{issuedate} ) {
471
           $issuedate = $issue->{issuedate}->clone();
472
        }
473
        $issue->{subtitle} = GetRecordValue('subtitle', GetMarcBiblio($issue->{biblionumber}), GetFrameworkCode($issue->{biblionumber}));
474
        $issue->{issuingbranchname} = GetBranchName($issue->{branchcode});
475
        my %row          = %{$issue};
476
        $totalprice += $issue->{replacementprice};
477
478
        # item lost, damaged loops
479
        if ( $row{'itemlost'} ) {
480
            my $fw       = GetFrameworkCode( $issue->{biblionumber} );
481
            my $category = GetAuthValCode( 'items.itemlost', $fw );
482
            my $lostdbh  = C4::Context->dbh;
483
            my $sth      = $lostdbh->prepare(
484
"select lib from authorised_values where category=? and authorised_value =? "
485
            );
486
            $sth->execute( $category, $row{'itemlost'} );
487
            my $loststat = $sth->fetchrow;
488
            if ($loststat) {
489
                $row{'itemlost'} = $loststat;
490
            }
491
        }
492
        if ( $row{'damaged'} ) {
493
            my $fw         = GetFrameworkCode( $issue->{biblionumber} );
494
            my $category   = GetAuthValCode( 'items.damaged', $fw );
495
            my $damageddbh = C4::Context->dbh;
496
            my $sth        = $damageddbh->prepare(
497
"select lib from authorised_values where category=? and authorised_value =? "
498
            );
499
            $sth->execute( $category, $row{'damaged'} );
500
            my $damagedstat = $sth->fetchrow;
501
            if ($damagedstat) {
502
                $row{'itemdamaged'} = $damagedstat;
503
            }
504
        }
505
506
        # end lost, damaged
507
        if ( $issue->{overdue} ) {
508
            $overdues_exist = 1;
509
            $row{red} = 1;
510
        }
511
        if ($issuedate) {
512
            $issuedate->truncate( to => 'day' );
513
            if ( DateTime->compare( $issuedate, $today ) == 0 ) {
514
                $row{today} = 1;
515
            }
516
        }
517
518
        #find the charge for an item
519
        my ( $charge, $itemtype ) =
520
          GetIssuingCharges( $issue->{itemnumber}, $borrowernumber );
521
522
        my $itemtypeinfo = getitemtypeinfo($itemtype);
523
        $row{'itemtype_description'} = $itemtypeinfo->{description};
524
        $row{'itemtype_image'}       = $itemtypeinfo->{imageurl};
525
526
        $row{'charge'} = sprintf( "%.2f", $charge );
527
528
        my ( $renewokay, $renewerror ) =
529
          CanBookBeRenewed( $borrowernumber, $issue->{itemnumber},
530
            $override_limit );
531
        $row{'norenew'} = !$renewokay;
532
        $row{'can_confirm'} = ( !$renewokay && $renewerror ne 'on_reserve' );
533
        $row{"norenew_reason_$renewerror"} = 1 if $renewerror;
534
        $row{renew_failed}  = $renew_failed{ $issue->{itemnumber} };
535
        $row{return_failed} = $return_failed{ $issue->{barcode} };
536
        ($row{'renewcount'},$row{'renewsallowed'},$row{'renewsleft'}) = C4::Circulation::GetRenewCount($issue->{'borrowernumber'},$issue->{'itemnumber'}); #Add renewal count to item data display
537
538
        $row{'soonestrenewdate'} = output_pref(
539
            C4::Circulation::GetSoonestRenewDate(
540
                $issue->{borrowernumber},
541
                $issue->{itemnumber}
542
            )
543
        );
544
545
        push( @{$localissue}, \%row );
546
    }
547
    return $localissue;
548
}
(-)a/svc/checkin.pl (+75 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright 2014 ByWater Solutions
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 3 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use Modern::Perl;
21
22
use CGI;
23
use JSON qw(to_json);
24
25
use C4::Circulation;
26
use C4::Items qw(GetBarcodeFromItemnumber);
27
use C4::Context;
28
use C4::Auth qw(check_cookie_auth);
29
30
use Koha::DateUtils qw(output_pref_due);
31
32
my $input = new CGI;
33
34
my ( $auth_status, $sessionID ) =
35
  check_cookie_auth( $input->cookie('CGISESSID'),
36
    { circulate => 'circulate_remaining_permissions' } );
37
38
if ( $auth_status ne "ok" ) {
39
    exit 0;
40
}
41
42
binmode STDOUT, ":encoding(UTF-8)";
43
print $input->header( -type => 'text/plain', -charset => 'UTF-8' );
44
45
my $itemnumber     = $input->param('itemnumber');
46
my $borrowernumber = $input->param('borrowernumber');
47
my $override_limit = $input->param('override_limit');
48
my $exempt_fine    = $input->param('exempt_fine');
49
my $branchcode     = $input->param('branchcode')
50
  || C4::Context->userenv->{'branch'};
51
52
my $barcode = GetBarcodeFromItemnumber($itemnumber);
53
54
my $data;
55
$data->{itemnumber}     = $itemnumber;
56
$data->{borrowernumber} = $borrowernumber;
57
$data->{branchcode}     = $branchcode;
58
59
if ( C4::Context->preference("InProcessingToShelvingCart") ) {
60
    my $item = GetItem($itemnumber);
61
    if ( $item->{'location'} eq 'PROC' ) {
62
        $item->{'location'} = 'CART';
63
        ModItem( $item, $item->{'biblionumber'}, $item->{'itemnumber'} );
64
    }
65
}
66
67
if ( C4::Context->preference("ReturnToShelvingCart") ) {
68
    my $item = GetItem($itemnumber);
69
    $item->{'location'} = 'CART';
70
    ModItem( $item, $item->{'biblionumber'}, $item->{'itemnumber'} );
71
}
72
73
( $data->{returned} ) = AddReturn( $barcode, $branchcode, $exempt_fine );
74
75
print to_json($data);
(-)a/svc/checkouts.pl (+167 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# This software is placed under the gnu General Public License, v2 (http://www.gnu.org/licenses/gpl.html)
4
5
# Copyright 2014 ByWater Solutions
6
#
7
# This file is part of Koha.
8
#
9
# Koha is free software; you can redistribute it and/or modify it under the
10
# terms of the GNU General Public License as published by the Free Software
11
# Foundation; either version 3 of the License, or (at your option) any later
12
# version.
13
#
14
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
15
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
17
#
18
# You should have received a copy of the GNU General Public License along
19
# with Koha; if not, write to the Free Software Foundation, Inc.,
20
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
22
use strict;
23
use warnings;
24
25
use CGI;
26
use JSON qw(to_json);
27
28
use C4::Auth qw(check_cookie_auth);
29
use C4::Biblio qw(GetMarcBiblio GetFrameworkCode GetRecordValue );
30
use C4::Circulation qw(GetIssuingCharges CanBookBeRenewed GetRenewCount);
31
use C4::Context;
32
33
use Koha::DateUtils;
34
35
my $input = new CGI;
36
37
my ( $auth_status, $sessionID ) =
38
  check_cookie_auth( $input->cookie('CGISESSID'),
39
    { circulate => 'circulate_remaining_permissions' } );
40
41
if ( $auth_status ne "ok" ) {
42
    exit 0;
43
}
44
45
my @sort_columns = qw/date_due title itype issuedate branchcode itemcallnumber/;
46
47
my @borrowernumber   = $input->param('borrowernumber');
48
my $offset           = $input->param('iDisplayStart');
49
my $results_per_page = $input->param('iDisplayLength') || -1;
50
my $sorting_column   = $sort_columns[ $input->param('iSortCol_0') ]
51
  || 'issuedate';
52
my $sorting_direction = $input->param('sSortDir_0') eq 'asc' ? 'asc' : 'desc';
53
54
$results_per_page = undef if ( $results_per_page == -1 );
55
56
binmode STDOUT, ":encoding(UTF-8)";
57
print $input->header( -type => 'text/plain', -charset => 'UTF-8' );
58
59
my @parameters;
60
my $sql = '
61
    SELECT
62
        issuedate,
63
        date_due,
64
65
        biblionumber,
66
        biblio.title,
67
        author,
68
69
        itemnumber,
70
        barcode,
71
        itemnotes,
72
        itemcallnumber,
73
        replacementprice,
74
75
        issues.branchcode,
76
        branchname,
77
78
        itype,
79
        itemtype,
80
81
        borrowernumber,
82
        surname,
83
        firstname,
84
        cardnumber
85
    FROM issues
86
        LEFT JOIN items USING ( itemnumber )
87
        LEFT JOIN biblio USING ( biblionumber )
88
        LEFT JOIN biblioitems USING ( biblionumber )
89
        LEFT JOIN borrowers USING ( borrowernumber )
90
        LEFT JOIN branches ON ( issues.branchcode = branches.branchcode )
91
    WHERE borrowernumber
92
';
93
94
if ( @borrowernumber == 1 ) {
95
    $sql .= '= ?';
96
}
97
else {
98
    $sql = ' IN (' . join( ',', ('?') x @borrowernumber ) . ') ';
99
}
100
push( @parameters, @borrowernumber );
101
102
$sql .= " ORDER BY $sorting_column $sorting_direction ";
103
104
my $dbh = C4::Context->dbh();
105
my $sth = $dbh->prepare($sql);
106
$sth->execute( @parameters );
107
108
my $item_level_itypes = C4::Context->preference('item-level_itypes');
109
110
my @checkouts;
111
while ( my $c = $sth->fetchrow_hashref() ) {
112
    my ($charge) = GetIssuingCharges( $c->{itemnumber}, $c->{borrowernumber} );
113
114
    my ( $can_renew, $can_renew_error ) =
115
      CanBookBeRenewed( $c->{borrowernumber}, $c->{itemnumber} );
116
117
    my ( $renewals_count, $renewals_allowed, $renewals_remaining ) =
118
      GetRenewCount( $c->{borrowernumber}, $c->{itemnumber} );
119
    push(
120
        @checkouts,
121
        {
122
            DT_RowId   => $c->{itemnumber} . '-' . $c->{borrowernumber},
123
            title      => $c->{title},
124
            author     => $c->{author},
125
            barcode    => $c->{barcode},
126
            itemtype   => $item_level_itypes ? $c->{itype} : $c->{itemtype},
127
            itemnotes  => $c->{itemnotes},
128
            branchcode => $c->{branchcode},
129
            branchname => $c->{branchname},
130
            itemcallnumber => $c->{itemcallnumber}   || q{},
131
            charge         => $charge,
132
            price          => $c->{replacementprice} || q{},
133
            can_renew      => $can_renew,
134
            can_renew_error    => $can_renew_error,
135
            itemnumber         => $c->{itemnumber},
136
            borrowernumber     => $c->{borrowernumber},
137
            biblionumber       => $c->{biblionumber},
138
            issuedate          => $c->{issuedate},
139
            date_due           => $c->{date_due},
140
            renewals_count     => $renewals_count,
141
            renewals_allowed   => $renewals_allowed,
142
            renewals_remaining => $renewals_remaining,
143
            issuedate_formatted =>
144
              output_pref( dt_from_string( $c->{issuedate} ) ),
145
            date_due_formatted =>
146
              output_pref_due( dt_from_string( $c->{date_due} ) ),
147
            subtitle => GetRecordValue(
148
                'subtitle',
149
                GetMarcBiblio( $c->{biblionumber} ),
150
                GetFrameworkCode( $c->{biblionumber} )
151
            ),
152
            borrower => {
153
                surname    => $c->{surname},
154
                firstname  => $c->{firstname},
155
                cardnumber => $c->{cardnumber},
156
            }
157
        }
158
    );
159
}
160
161
my $data;
162
$data->{'iTotalRecords'}        = scalar @checkouts;                 #FIXME
163
$data->{'iTotalDisplayRecords'} = scalar @checkouts;
164
$data->{'sEcho'}                = $input->param('sEcho') || undef;
165
$data->{'aaData'}               = \@checkouts;
166
167
print to_json($data);
(-)a/svc/holds.pl (+143 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# This software is placed under the gnu General Public License, v2 (http://www.gnu.org/licenses/gpl.html)
4
5
# Copyright 2014 ByWater Solutions
6
#
7
# This file is part of Koha.
8
#
9
# Koha is free software; you can redistribute it and/or modify it under the
10
# terms of the GNU General Public License as published by the Free Software
11
# Foundation; either version 3 of the License, or (at your option) any later
12
# version.
13
#
14
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
15
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
17
#
18
# You should have received a copy of the GNU General Public License along
19
# with Koha; if not, write to the Free Software Foundation, Inc.,
20
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
22
use Modern::Perl;
23
24
use CGI;
25
use JSON qw(to_json);
26
27
use C4::Auth qw(check_cookie_auth);
28
use C4::Biblio qw(GetMarcBiblio GetFrameworkCode GetRecordValue );
29
use C4::Branch qw(GetBranchName);
30
use C4::Charset;
31
use C4::Circulation qw(GetTransfers);
32
use C4::Context;
33
34
use Koha::Database;
35
use Koha::DateUtils;
36
37
my $input = new CGI;
38
39
my ( $auth_status, $sessionID ) =
40
  check_cookie_auth( $input->cookie('CGISESSID'),
41
    { circulate => 'circulate_remaining_permissions' } );
42
43
if ( $auth_status ne "ok" ) {
44
    exit 0;
45
}
46
47
my $branch = C4::Context->userenv->{'branch'};
48
49
my $schema = Koha::Database->new()->schema();
50
51
my @sort_columns =
52
  qw/reservedate title itemcallnumber barcode expirationdate priority/;
53
54
my $borrowernumber    = $input->param('borrowernumber');
55
my $offset            = $input->param('iDisplayStart');
56
my $results_per_page  = $input->param('iDisplayLength');
57
my $sorting_direction = $input->param('sSortDir_0') || 'desc';
58
my $sorting_column    = $sort_columns[ $input->param('iSortCol_0') ]
59
  || 'reservedate';
60
61
binmode STDOUT, ":encoding(UTF-8)";
62
print $input->header( -type => 'text/plain', -charset => 'UTF-8' );
63
64
my $holds_rs = $schema->resultset('Reserve')->search(
65
    { borrowernumber => $borrowernumber },
66
    {
67
        prefetch => { 'item'                => 'biblio' },
68
        order_by => { "-$sorting_direction" => $sorting_column }
69
    }
70
);
71
72
my $borrower;
73
my @holds;
74
while ( my $h = $holds_rs->next() ) {
75
    my $item = $h->item();
76
77
    my $biblionumber = $h->biblio()->biblionumber();
78
79
    my $hold = {
80
        DT_RowId       => $h->reserve_id(),
81
        biblionumber   => $biblionumber,
82
        title          => $h->biblio()->title(),
83
        author         => $h->biblio()->author(),
84
        reserve_id     => $h->reserve_id(),
85
        reservedate    => $h->reservedate(),
86
        expirationdate => $h->expirationdate(),
87
        suspend        => $h->suspend(),
88
        suspend_until  => $h->suspend_until(),
89
        found          => $h->found(),
90
        waiting        => $h->found() eq 'W',
91
        waiting_at     => $h->branchcode()->branchname(),
92
        waiting_here   => $h->branchcode()->branchcode() eq $branch,
93
        priority       => $h->priority(),
94
        subtitle       => GetRecordValue(
95
            'subtitle', GetMarcBiblio($biblionumber),
96
            GetFrameworkCode($biblionumber)
97
        ),
98
        reservedate_formatted => $h->reservedate()
99
        ? output_pref_due( dt_from_string( $h->reservedate() ) )
100
        : q{},
101
        suspend_until_formatted => $h->suspend_until()
102
        ? output_pref_due( dt_from_string( $h->suspend_until() ) )
103
        : q{},
104
        expirationdate_formatted => $h->expirationdate()
105
        ? output_pref_due( dt_from_string( $h->expirationdate() ) )
106
        : q{},
107
    };
108
109
    $hold->{transfered}     = 0;
110
    $hold->{not_transfered} = 0;
111
112
    if ($item) {
113
        $hold->{itemnumber}     = $item->itemnumber();
114
        $hold->{barcode}        = $item->barcode();
115
        $hold->{itemtype}       = $item->effective_itemtype();
116
        $hold->{itemcallnumber} = $item->itemcallnumber() || q{};
117
118
        my ( $transferred_when, $transferred_from, $transferred_to ) =
119
          GetTransfers( $item->itemnumber() );
120
        if ($transferred_when) {
121
            $hold->{color}       = 'transferred';
122
            $hold->{transferred} = 1;
123
            $hold->{date_sent}   = format_date($transferred_when);
124
            $hold->{from_branch} = GetBranchName($transferred_from);
125
        }
126
        elsif ( $item->holdingbranch()->branchcode() ne
127
            $h->branchcode()->branchcode() )
128
        {
129
            $hold->{not_transferred}    = 1;
130
            $hold->{not_transferred_by} = $h->branchcode()->branchname();
131
        }
132
    }
133
134
    push( @holds, $hold );
135
}
136
137
my $data;
138
$data->{'iTotalRecords'}        = scalar @holds;
139
$data->{'iTotalDisplayRecords'} = scalar @holds;
140
$data->{'sEcho'}                = $input->param('sEcho') || undef;
141
$data->{'aaData'}               = \@holds;
142
143
print to_json($data);
(-)a/svc/renew.pl (-1 / +69 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# Copyright 2014 ByWater Solutions
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 3 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use Modern::Perl;
21
22
use CGI;
23
use JSON qw(to_json);
24
25
use C4::Circulation;
26
use C4::Context;
27
use C4::Auth qw(check_cookie_auth);
28
29
use Koha::DateUtils qw(output_pref_due dt_from_string);
30
31
my $input = new CGI;
32
33
my ( $auth_status, $sessionID ) =
34
  check_cookie_auth( $input->cookie('CGISESSID'),
35
    { circulate => 'circulate_remaining_permissions' } );
36
37
if ( $auth_status ne "ok" ) {
38
    exit 0;
39
}
40
41
binmode STDOUT, ":encoding(UTF-8)";
42
print $input->header( -type => 'text/plain', -charset => 'UTF-8' );
43
44
my $itemnumber     = $input->param('itemnumber');
45
my $borrowernumber = $input->param('borrowernumber');
46
my $override_limit = $input->param('override_limit');
47
my $branchcode     = $input->param('branchcode')
48
  || C4::Context->userenv->{'branch'};
49
my $date_due;
50
if ( $input->param('date_due') ) {
51
    $date_due = dt_from_string( $input->param('date_due') );
52
    $date_due->set_hour(23);
53
    $date_due->set_minute(59);
54
}
55
56
my $data;
57
$data->{itemnumber} = $itemnumber;
58
$data->{borrowernumber} = $borrowernumber;
59
$data->{branchcode} = $branchcode;
60
61
( $data->{renew_okay}, $data->{error} ) =
62
  CanBookBeRenewed( $borrowernumber, $itemnumber, $override_limit );
63
64
if ( $data->{renew_okay} ) {
65
    $date_due = AddRenewal( $borrowernumber, $itemnumber, $branchcode, $date_due );
66
    $data->{date_due} = output_pref_due( $date_due );
67
}
68
69
print to_json($data);

Return to bug 11703