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

(-)a/C4/Items.pm (-17 / +114 lines)
Lines 25-30 use Carp; Link Here
25
use C4::Context;
25
use C4::Context;
26
use C4::Koha;
26
use C4::Koha;
27
use C4::Biblio;
27
use C4::Biblio;
28
use C4::SQLHelper;
28
use C4::Dates qw/format_date format_date_in_iso/;
29
use C4::Dates qw/format_date format_date_in_iso/;
29
use MARC::Record;
30
use MARC::Record;
30
use C4::ClassSource;
31
use C4::ClassSource;
Lines 1186-1191 sub GetItemsByBiblioitemnumber { Link Here
1186
=head2 GetItemsInfo
1187
=head2 GetItemsInfo
1187
1188
1188
  @results = GetItemsInfo($biblionumber);
1189
  @results = GetItemsInfo($biblionumber);
1190
  @results = GetItemsInfo($biblionumber, $filter);
1189
1191
1190
Returns information about items with the given biblionumber.
1192
Returns information about items with the given biblionumber.
1191
1193
Lines 1223-1234 If this is set, it is set to C<One Order>. Link Here
1223
1225
1224
=back
1226
=back
1225
1227
1228
=item C<$filter>
1229
1230
A reference-to-hash. Valid filters are:
1231
$filter->{branch} = 'CPL';          #Branchcode of the library whose items should only be displayed.
1232
$filter->{volume} = '2013';         #The volume of the item from items.enumchron aka. "Numbering formula".
1233
$filter->{number} = '11';           #The number or issue of the item from items.enumchron aka. "Numbering formula".
1234
$filter->{fromDate} = '01/01/2013'; #Filters only serial issues by the serialitems.publisheddate
1235
                                          #The starting date in C4::Context->preference('dateformat') format
1236
$filter->{toDate} = '31/12/2014';   #Filters only serial issues by the serialitems.publisheddate
1237
                                          #The ending date in C4::Context->preference('dateformat') format
1238
1239
Filters are expected to be validated! If a filter is not defined, that filter is not present in the $filter-HASH
1240
1226
=cut
1241
=cut
1227
1242
1228
sub GetItemsInfo {
1243
sub GetItemsInfo {
1229
    my ( $biblionumber ) = @_;
1244
    my ( $biblionumber, $filter ) = @_;
1230
    my $dbh   = C4::Context->dbh;
1245
    my $dbh   = C4::Context->dbh;
1246
1247
    #Prepare the filter
1248
    my $filterEnumchron = 0;
1249
    my $enumchronSQLRegexp;
1250
    if (defined $filter && ref $filter eq 'HASH') {
1251
1252
        #Items enumchron can be filtered by volume or number or both.
1253
        #Because the format of enumchron
1254
        #For performance reasons regexp's need to be as simple as possible.
1255
        ## It is entirely possible to search with just volume or just number or just issue.
1256
        ##  We don't know which filters are used so it is safer and more efficient to just
1257
        ##  prepare the enumeration parsing SQL every time.
1258
        $enumchronSQLRegexp = C4::Context->preference('NumberingFormulaParsingRegexp');
1259
1260
        if (exists $filter->{volume}) {
1261
            $filterEnumchron = 1;
1262
            $enumchronSQLRegexp =~ s/volume/$filter->{volume}/;
1263
        }
1264
        else {
1265
            $enumchronSQLRegexp =~ s/volume/[0-9]*/;
1266
        }
1267
        if (exists $filter->{number}) {
1268
            $filterEnumchron = 1;
1269
            $enumchronSQLRegexp =~ s/number/$filter->{number}/;
1270
        }
1271
        else {
1272
            $enumchronSQLRegexp =~ s/number/[0-9]*/;
1273
        }
1274
        if (exists $filter->{issue}) {
1275
            $filterEnumchron = 1;
1276
            $enumchronSQLRegexp =~ s/issue/$filter->{issue}/;
1277
        }
1278
        else {
1279
            $enumchronSQLRegexp =~ s/issue/[0-9]*/;
1280
        }
1281
    }
1282
    #If we know that this item is a serial, we can better optimize our big SQL.
1283
    # This is especially useful when we want to filter based on the publication date.
1284
    # SELECTing a huge blob of serials just to remove unnecessary ones will be really sloooow.
1285
    my $search = C4::SQLHelper::SearchInTable("biblio",{biblionumber => $biblionumber}, undef, undef, ['serial'], undef, "exact");
1286
    my $serial = $search->[0]->{serial};
1287
1231
    # note biblioitems.* must be avoided to prevent large marc and marcxml fields from killing performance.
1288
    # note biblioitems.* must be avoided to prevent large marc and marcxml fields from killing performance.
1289
    #Because it is uncertain how many parameters the SQL query needs, we need to build the parameters dynamically
1290
    # This is because we cannot predict what filters our users use.
1291
    my $queryParams = [$biblionumber];
1232
    my $query = "
1292
    my $query = "
1233
    SELECT items.*,
1293
    SELECT items.*,
1234
           biblio.*,
1294
           biblio.*,
Lines 1248-1254 sub GetItemsInfo { Link Here
1248
           itemtypes.notforloan as notforloan_per_itemtype,
1308
           itemtypes.notforloan as notforloan_per_itemtype,
1249
           holding.branchurl,
1309
           holding.branchurl,
1250
           holding.branchname,
1310
           holding.branchname,
1251
           holding.opac_info as branch_opac_info
1311
           holding.opac_info as branch_opac_info ";
1312
    if ($serial) {
1313
        $query .= ",
1314
           serial.serialseq,
1315
           serial.publisheddate ";
1316
    }
1317
    $query .= "
1252
     FROM items
1318
     FROM items
1253
     LEFT JOIN branches AS holding ON items.holdingbranch = holding.branchcode
1319
     LEFT JOIN branches AS holding ON items.holdingbranch = holding.branchcode
1254
     LEFT JOIN branches AS home ON items.homebranch=home.branchcode
1320
     LEFT JOIN branches AS home ON items.homebranch=home.branchcode
Lines 1256-1274 sub GetItemsInfo { Link Here
1256
     LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber
1322
     LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber
1257
     LEFT JOIN itemtypes   ON   itemtypes.itemtype         = "
1323
     LEFT JOIN itemtypes   ON   itemtypes.itemtype         = "
1258
     . (C4::Context->preference('item-level_itypes') ? 'items.itype' : 'biblioitems.itemtype');
1324
     . (C4::Context->preference('item-level_itypes') ? 'items.itype' : 'biblioitems.itemtype');
1259
    $query .= " WHERE items.biblionumber = ? ORDER BY home.branchname, items.enumchron, LPAD( items.copynumber, 8, '0' ), items.dateaccessioned DESC" ;
1325
1326
    if ($serial) {
1327
        $query .= "
1328
           LEFT JOIN serialitems ON serialitems.itemnumber = items.itemnumber
1329
           LEFT JOIN serial ON serialitems.serialid = serial.serialid ";
1330
    }
1331
1332
    $query .= " WHERE items.biblionumber = ? ";
1333
1334
    if (exists $filter->{branch}) {
1335
        $query .= " AND items.holdingbranch = ?";
1336
        push @$queryParams, $filter->{branch};
1337
    }
1338
    if ($filterEnumchron) {
1339
        $query .= " AND items.enumchron REGEXP ?";
1340
        push @$queryParams, $enumchronSQLRegexp;
1341
    }
1342
    if (exists $filter->{fromDate}) {
1343
        if ($serial) {
1344
            $query .= " AND serial.publisheddate >= ?";
1345
        }
1346
        else {
1347
            $query .= " AND items.timestamp >= ?";
1348
        }
1349
        push @$queryParams, $filter->{fromDate};
1350
    }
1351
    if (exists $filter->{toDate}) {
1352
        if ($serial) {
1353
            $query .= " AND serial.publisheddate <= ?";
1354
        }
1355
        else {
1356
            $query .= " AND items.timestamp <= ?";
1357
        }
1358
        push @$queryParams, $filter->{toDate};
1359
    }
1360
1361
    $query .= "ORDER BY home.branchname, items.enumchron, LPAD( items.copynumber, 8, '0' ), items.dateaccessioned DESC" ;
1260
    my $sth = $dbh->prepare($query);
1362
    my $sth = $dbh->prepare($query);
1261
    $sth->execute($biblionumber);
1363
    $sth->execute(@$queryParams);
1262
    my $i = 0;
1364
    my $i = 0;
1263
    my @results;
1365
    my @results;
1264
    my $serial;
1265
1366
1266
    my $isth    = $dbh->prepare(
1367
    my $isth    = $dbh->prepare(
1267
        "SELECT issues.*,borrowers.cardnumber,borrowers.surname,borrowers.firstname,borrowers.branchcode as bcode
1368
        "SELECT issues.*,borrowers.cardnumber,borrowers.surname,borrowers.firstname,borrowers.branchcode as bcode
1268
        FROM   issues LEFT JOIN borrowers ON issues.borrowernumber=borrowers.borrowernumber
1369
        FROM   issues LEFT JOIN borrowers ON issues.borrowernumber=borrowers.borrowernumber
1269
        WHERE  itemnumber = ?"
1370
        WHERE  itemnumber = ?"
1270
       );
1371
       );
1271
	my $ssth = $dbh->prepare("SELECT serialseq,publisheddate from serialitems left join serial on serialitems.serialid=serial.serialid where serialitems.itemnumber=? "); 
1372
1373
1272
	while ( my $data = $sth->fetchrow_hashref ) {
1374
	while ( my $data = $sth->fetchrow_hashref ) {
1273
        my $datedue = '';
1375
        my $datedue = '';
1274
        $isth->execute( $data->{'itemnumber'} );
1376
        $isth->execute( $data->{'itemnumber'} );
Lines 1279-1295 sub GetItemsInfo { Link Here
1279
            $data->{firstname}     = $idata->{firstname};
1381
            $data->{firstname}     = $idata->{firstname};
1280
            $data->{lastreneweddate} = $idata->{lastreneweddate};
1382
            $data->{lastreneweddate} = $idata->{lastreneweddate};
1281
            $datedue                = $idata->{'date_due'};
1383
            $datedue                = $idata->{'date_due'};
1282
        if (C4::Context->preference("IndependentBranches")){
1384
            if (C4::Context->preference("IndependentBranches")){
1283
        my $userenv = C4::Context->userenv;
1385
                my $userenv = C4::Context->userenv;
1284
        if ( ($userenv) && ( $userenv->{flags} % 2 != 1 ) ) { 
1386
                if ( ($userenv) && ( $userenv->{flags} % 2 != 1 ) ) {
1285
            $data->{'NOTSAMEBRANCH'} = 1 if ($idata->{'bcode'} ne $userenv->{branch});
1387
                    $data->{'NOTSAMEBRANCH'} = 1 if ($idata->{'bcode'} ne $userenv->{branch});
1286
        }
1388
                }
1287
        }
1389
            }
1288
        }
1289
		if ( $data->{'serial'}) {	
1290
			$ssth->execute($data->{'itemnumber'}) ;
1291
			($data->{'serialseq'} , $data->{'publisheddate'}) = $ssth->fetchrow_array();
1292
			$serial = 1;
1293
        }
1390
        }
1294
        #get branch information.....
1391
        #get branch information.....
1295
        my $bsth = $dbh->prepare(
1392
        my $bsth = $dbh->prepare(
(-)a/installer/data/mysql/sysprefs.sql (+2 lines)
Lines 110-115 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
110
('ExtendedPatronAttributes','0',NULL,'Use extended patron IDs and attributes','YesNo'),
110
('ExtendedPatronAttributes','0',NULL,'Use extended patron IDs and attributes','YesNo'),
111
('FacetLabelTruncationLength','20',NULL,'Specify the facet max length in OPAC','Integer'),
111
('FacetLabelTruncationLength','20',NULL,'Specify the facet max length in OPAC','Integer'),
112
('FilterBeforeOverdueReport','0','','Do not run overdue report until filter selected','YesNo'),
112
('FilterBeforeOverdueReport','0','','Do not run overdue report until filter selected','YesNo'),
113
('FilterSerialsByIssue','0',NULL,'Use issue-field when filtering serial issues in addition to the volume- and number-fields? This relates to NumberingFormulaParsingRegexp system preference.','YesNo'),
113
('FineNotifyAtCheckin','0',NULL,'If ON notify librarians of overdue fines on the items they are checking in.','YesNo'),
114
('FineNotifyAtCheckin','0',NULL,'If ON notify librarians of overdue fines on the items they are checking in.','YesNo'),
114
('finesCalendar','noFinesWhenClosed','ignoreCalendar|noFinesWhenClosed','Specify whether to use the Calendar in calculating duedates and fines','Choice'),
115
('finesCalendar','noFinesWhenClosed','ignoreCalendar|noFinesWhenClosed','Specify whether to use the Calendar in calculating duedates and fines','Choice'),
115
('FinesIncludeGracePeriod','1',NULL,'If enabled, fines calculations will include the grace period.','YesNo'),
116
('FinesIncludeGracePeriod','1',NULL,'If enabled, fines calculations will include the grace period.','YesNo'),
Lines 192-197 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
192
('NovelistSelectPassword',NULL,NULL,'Enable Novelist user Profile','free'),
193
('NovelistSelectPassword',NULL,NULL,'Enable Novelist user Profile','free'),
193
('NovelistSelectProfile',NULL,NULL,'Novelist Select user Password','free'),
194
('NovelistSelectProfile',NULL,NULL,'Novelist Select user Password','free'),
194
('NovelistSelectView','tab','tab|above|below|right','Where to display Novelist Select content','Choice'),
195
('NovelistSelectView','tab','tab|above|below|right','Where to display Novelist Select content','Choice'),
196
('NumberingFormulaParsingRegexp','','','Explanation','free')
195
('numReturnedItemsToShow','20',NULL,'Number of returned items to show on the check-in page','Integer'),
197
('numReturnedItemsToShow','20',NULL,'Number of returned items to show on the check-in page','Integer'),
196
('numSearchResults','20',NULL,'Specify the maximum number of results to display on a page of results','Integer'),
198
('numSearchResults','20',NULL,'Specify the maximum number of results to display on a page of results','Integer'),
197
('numSearchRSSResults','50',NULL,'Specify the maximum number of results to display on a RSS page of results','Integer'),
199
('numSearchRSSResults','50',NULL,'Specify the maximum number of results to display on a RSS page of results','Integer'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/serials.pref (+14 lines)
Lines 50-52 Serials: Link Here
50
    -
50
    -
51
        - List of fields which must not be rewritten when a subscription is duplicated (Separated by pipe |)
51
        - List of fields which must not be rewritten when a subscription is duplicated (Separated by pipe |)
52
        - pref: SubscriptionDuplicateDroppedInput
52
        - pref: SubscriptionDuplicateDroppedInput
53
    -
54
        - pref: NumberingFormulaParsingRegexp
55
          class: long
56
        - "When dealing with potentially thousands of Serial items, there is a need to limit the display of a large number of serial issues in OPAC. This preference controls how the enumeration of a serial issue should be parsed."
57
        - "It must be a MySQL compliant regular expression, with values volume, number, issue representing those enumerants."
58
        - 'Example: ^[^0-9]*volume[^0-9]*number[^0-9]*$  would work with enumerations like "Vol 2013, No 11" or "2013 :11", but not with enumerations like "No 11, Vol 2013" or "1.a Vol 2013, No 11".'
59
        - It is recommended to not mix different enumeration schemes inside a Koha installation. It is not possible to have one branch enumerate like "issue, volume, number" and other as "volume, number" or even "volume, number, issue".
60
        - Use the recommeded value, or if you are using the FilterSerialsByIssue -system preference, use this ^[^0-9]*volume[^0-9]*number[^0-9]*issue[^0-9]*$
61
    -
62
        - pref: FilterSerialsByIssue
63
          choices:
64
              yes: "Use"
65
              no: "Don't use"
66
        - issue-field when filtering serial issues in addition to the volume- and number-fields. This relates to NumberingFormulaParsingRegexp system preference.
(-)a/koha-tmpl/opac-tmpl/prog/en/css/opac-detail.css (+14 lines)
Line 0 Link Here
1
/* Lots of stuff copied from opac.css since it shouldn't be modified. The button elements should be generalized for maintainability reasons! */
2
3
#filterIssuesButton {
4
    z-index: 1001; /* Make sure this element is always over the #filterIssuesFormContainer */
5
6
	padding : .3em .7em;
7
8
    background-image: url("../../images/desc.gif"); /* FF3.6+ */
9
    background-position:  center right;
10
	background-repeat: no-repeat;
11
12
	padding-right: 20px;
13
    margin-right: 6px;
14
}
(-)a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt (-24 / +150 lines)
Lines 19-24 Link Here
19
19
20
[% INCLUDE 'doc-head-open.inc' %][% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog &rsaquo; Details for: [% title |html %][% FOREACH subtitl IN subtitle %], [% subtitl.subfield |html %][% END %]
20
[% INCLUDE 'doc-head-open.inc' %][% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog &rsaquo; Details for: [% title |html %][% FOREACH subtitl IN subtitle %], [% subtitl.subfield |html %][% END %]
21
[% INCLUDE 'doc-head-close.inc' %]
21
[% INCLUDE 'doc-head-close.inc' %]
22
[% INCLUDE 'calendar.inc' %]
22
[% INCLUDE 'datatables.inc' %]
23
[% INCLUDE 'datatables.inc' %]
23
[% IF ( SocialNetworks ) %]
24
[% IF ( SocialNetworks ) %]
24
    <script type="text/javascript" src="https://apis.google.com/js/plusone.js">
25
    <script type="text/javascript" src="https://apis.google.com/js/plusone.js">
Lines 35-40 Link Here
35
[% IF ( bidi ) %]
36
[% IF ( bidi ) %]
36
  <link rel="stylesheet" type="text/css" href="[% themelang %]/css/right-to-left.css" />
37
  <link rel="stylesheet" type="text/css" href="[% themelang %]/css/right-to-left.css" />
37
[% END %]
38
[% END %]
39
<link rel="stylesheet" type="text/css" href="[% themelang %]/css/opac-detail.css" />
38
<script type="text/javascript">
40
<script type="text/javascript">
39
//<![CDATA[
41
//<![CDATA[
40
42
Lines 66-72 Link Here
66
            $(".highlight_toggle").toggle();
68
            $(".highlight_toggle").toggle();
67
        }
69
        }
68
    [% END %]
70
    [% END %]
69
71
// ------------------------------ //
72
//>>> Document READY starts here! //
73
// ------------------------------ //
70
     $(document).ready(function() { 
74
     $(document).ready(function() { 
71
        $('#bibliodescriptions').tabs();
75
        $('#bibliodescriptions').tabs();
72
        $(".branch-info-tooltip-trigger").tooltip({
76
        $(".branch-info-tooltip-trigger").tooltip({
Lines 109-135 Link Here
109
        });
113
        });
110
[% END %]
114
[% END %]
111
115
112
            $(".holdingst").dataTable($.extend(true, {}, dataTablesDefaults, {
116
        $(".holdingst").dataTable($.extend(true, {}, dataTablesDefaults, {
113
                "aoColumns": [
117
            "aoColumns": [
114
                    [% IF ( item_level_itypes ) %]null,[% END %]
118
                [% IF ( item_level_itypes ) %]null,[% END %]
115
                    null,
119
                null,
116
                    [% IF ( itemdata_ccode ) %]null,[% END %]
120
                [% IF ( itemdata_ccode ) %]null,[% END %]
121
                null,
122
                [% IF ( itemdata_enumchron ) %]null,[% END %]
123
                [% IF ( itemdata_uri ) %]null,[% END %]
124
                [% IF ( itemdata_copynumber ) %]null,[% END %]
125
                null,
126
                [% IF ( itemdata_itemnotes ) %]null,[% END %]
127
                { "sType": "title-string" },
128
                [% IF ( OPACShowBarcode ) %]null,[% END %]
129
                [% IF holds_count.defined %]
117
                    null,
130
                    null,
118
                    [% IF ( itemdata_enumchron ) %]null,[% END %]
131
                [% ELSIF show_priority %]
119
                    [% IF ( itemdata_uri ) %]null,[% END %]
120
                    [% IF ( itemdata_copynumber ) %]null,[% END %]
121
                    null,
132
                    null,
122
                    [% IF ( itemdata_itemnotes ) %]null,[% END %]
133
                [% END %]
123
                    { "sType": "title-string" },
134
                [% IF ( ShowCourseReservesHeader ) %]null,[% END %]
124
                    [% IF ( OPACShowBarcode ) %]null,[% END %]
135
            ]
125
                    [% IF holds_count.defined %]
136
        }));
126
                        null,
137
127
                    [% ELSIF show_priority %]
138
        //Bind the datepicker
128
                        null,
139
        $('.datepicker').datepicker();
129
                    [% END %]
130
                    [% IF ( ShowCourseReservesHeader ) %]null,[% END %]
131
                ]
132
            }));
133
140
134
        [% IF ( query_desc ) %][% IF ( OpacHighlightedWords ) %]var query_desc = "[% query_desc |replace("'", "\'") |replace('\n', '\\n') |replace('\r', '\\r') |html %]";
141
        [% IF ( query_desc ) %][% IF ( OpacHighlightedWords ) %]var query_desc = "[% query_desc |replace("'", "\'") |replace('\n', '\\n') |replace('\r', '\\r') |html %]";
135
            q_array = query_desc.split(" ");
142
            q_array = query_desc.split(" ");
Lines 248-254 $(function () { Link Here
248
    }
255
    }
249
256
250
[% END %]
257
[% END %]
251
});
258
259
        $('#filterIssuesFormContainer').hide(); /* Making this element unobtrusive for javascript consumers */
260
        $('#filterIssuesButton').click(function() {
261
            $('#filterIssuesFormContainer').toggle();
262
        });
263
    });
264
// --------------------------- //
265
//<<< Document READY ends here //
266
// --------------------------- //
252
[% IF ( IDreamBooksReviews || IDreamBooksReadometer ) %]
267
[% IF ( IDreamBooksReviews || IDreamBooksReadometer ) %]
253
function parseIDBJSON( json ) {
268
function parseIDBJSON( json ) {
254
    if(json.total_results > 0 && json.book.rating > 0){
269
    if(json.total_results > 0 && json.book.rating > 0){
Lines 1038-1046 YAHOO.util.Event.onContentReady("furtherm", function () { Link Here
1038
1053
1039
1054
1040
<div id="holdings">
1055
<div id="holdings">
1056
1057
    [% IF ( lotsofitems ) %]
1058
        [%# Display the items filtering form used to filter the shown items. See the end of this file! %]
1059
        [% INCLUDE filter_form tab="holdings" %]
1060
    [% END %]
1061
1041
[% IF ( itemloop.size ) %]
1062
[% IF ( itemloop.size ) %]
1042
    [% IF ( lotsofholdingsitems ) %]
1063
1043
        <p>This record has many physical items. <a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% biblionumber %]&amp;viewallitems=1#holdings">Click here to view them all.</a></p>
1064
    [% IF ( lotsofitems ) %]
1065
	<p>This record has many physical items. <a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% biblionumber %]&amp;viewallitems=1#holdings">Click here to view them all.</a> Or use the filter above to limit your selection</p>
1044
    [% ELSE %]
1066
    [% ELSE %]
1045
        [% INCLUDE items_table items=itemloop tab="holdings" %]
1067
        [% INCLUDE items_table items=itemloop tab="holdings" %]
1046
    [% END %]
1068
    [% END %]
Lines 1064-1070 YAHOO.util.Event.onContentReady("furtherm", function () { Link Here
1064
        <div id="alternateholdings"><span class="holdings_label">Holdings:</span> [% ALTERNATEHOLDING.holding %]</div>
1086
        <div id="alternateholdings"><span class="holdings_label">Holdings:</span> [% ALTERNATEHOLDING.holding %]</div>
1065
    [% END %]
1087
    [% END %]
1066
    [% ELSE %]
1088
    [% ELSE %]
1067
    <div id="noitems">No physical items for this record</div>
1089
    <h4 id="noitems">
1090
        No physical items for this record.
1091
        [% IF filter %]
1092
            <br/> Try clearing the filter.
1093
        [% END %]
1094
    </h4>
1068
    [% END %]
1095
    [% END %]
1069
[% END %]
1096
[% END %]
1070
1097
Lines 1604-1606 YAHOO.util.Event.onContentReady("furtherm", function () { Link Here
1604
	    [% END %]</tbody>
1631
	    [% END %]</tbody>
1605
	</table>
1632
	</table>
1606
[% END %][%# end of items_table block %]
1633
[% END %][%# end of items_table block %]
1634
1635
[% BLOCK filter_form %]
1636
    [% IF ( notDefined_NumberingFormulaParsingRegexp ) %]
1637
        <div class="dialog alert">
1638
            You must define the NumberingFormulaParsingRegexp system preference to filter items by enumeration!
1639
        </div>
1640
    [% END %]
1641
1642
    <div id="filterIssuesParentContainer">
1643
    <a id="filterIssuesButton" >Limit issues</a>
1644
    [% IF filter %]
1645
        <form id="issuesFilter" method="get" action="/cgi-bin/koha/opac-detail.pl">
1646
            <input type="hidden" name="biblionumber" id="biblionumber" value="[% biblionumber %]"/>
1647
            <input type="submit" name="clearFilter" value="Clear filter" class="submit"/>
1648
        </form>
1649
    [% END %]
1650
    <div id="filterIssuesFormContainer">
1651
    <form id="issuesFilter" method="get" action="/cgi-bin/koha/opac-detail.pl">
1652
        <input type="hidden" name="biblionumber" id="biblionumber" value="[% biblionumber %]"/>
1653
        <input type="hidden" name="viewallitems" id="viewallitems" value="1"/>
1654
1655
        <fieldset>
1656
            <table>
1657
                <tr><td>
1658
                        <label for="filterBranchLimiter">
1659
                            Library:
1660
                        </label>
1661
                    </td><td>
1662
                        <select name="filterBranchLimiter" size="1" id="filterBranchLimiter">
1663
                        [%- FOREACH branchloo IN branchloop %]
1664
                            [% IF ( branchloo.selected ) -%]
1665
                                <option value="[% branchloo.branchcode %]" selected="selected">
1666
                            [%- ELSE -%]
1667
                                <option value="[% branchloo.branchcode %]">
1668
                            [%- END -%]
1669
                            [% IF ( branchloo.branchcode ) == '_ShowAll' -%]
1670
                                Show from any library</option>
1671
                            [%- ELSE -%]
1672
                                [% branchloo.branchname %]</option>
1673
                            [%- END -%]
1674
                        [%- END %]
1675
                        </select>
1676
                    </td>
1677
                </tr>
1678
                [% IF isSerial %]
1679
                    <tr>
1680
                        <td>
1681
                            <label for="filterVolume">
1682
                                Issue volume:
1683
                            </label>
1684
                        </td><td>
1685
                            <input type="number" id="filterVolume" name="filterVolume" min="0" max="9999" maxlength="4" value="[% filter.volume %]">
1686
                        </td>
1687
                    </tr><tr>
1688
                        <td>
1689
                            <label for="filterNumber">
1690
                                Issue number:
1691
                            </label>
1692
                        </td><td>
1693
                            <input type="number" id="filterNumber" name="filterNumber" min="0" max="99" maxlength="2" value="[% filter.number %]">
1694
                        </td>
1695
                    </tr>
1696
                    [% IF useFilterIssueInput %]
1697
                    <tr>
1698
                        <td>
1699
                            <label for="filterIssue">
1700
                                Issue issue:
1701
                            </label>
1702
                        </td><td>
1703
                            <input type="number" id="filterIssue" name="filterIssue" min="0" max="99" maxlength="2" value="[% filter.issue %]">
1704
                        </td>
1705
                    </tr>
1706
                    [% END %]
1707
                [% END %][%# End of IF isSerial %]
1708
                <tr>
1709
                    <td>
1710
                        <label for="filterFrom">
1711
                            From date:
1712
                        </label>
1713
                    </td><td>
1714
                        <input type="text" size="10" id="filterFrom" name="filterFrom" value="[% filter.serialFromDate %]" class="datepicker" />
1715
                    </td>
1716
                </tr><tr>
1717
                    <td>
1718
                        <label for="filterTo">
1719
                            To date:
1720
                        </label>
1721
                    </td><td>
1722
                        <input type="text" size="10" id="filterTo" name="filterTo" value="[% filter.serialToDate %]" class="datepicker" />
1723
                    </td>
1724
                </tr>
1725
            </table>
1726
1727
            <input type="submit" name="filterIssues" value="Submit" class="submit"/>
1728
        </fieldset>
1729
    </form>
1730
    </div>
1731
    </div>
1732
[% END %][%# end of filter_form block %]
(-)a/opac/opac-detail.pl (-1 / +113 lines)
Lines 73-79 my ( $template, $borrowernumber, $cookie ) = get_template_and_user( Link Here
73
my $biblionumber = $query->param('biblionumber') || $query->param('bib') || 0;
73
my $biblionumber = $query->param('biblionumber') || $query->param('bib') || 0;
74
$biblionumber = int($biblionumber);
74
$biblionumber = int($biblionumber);
75
75
76
my @all_items = GetItemsInfo($biblionumber);
76
##
77
##>> Handling the Serial issue filter parameters from the user
78
##
79
# We can filter issues based on these five values.
80
my $filterBranchLimiter = $query->param('filterBranchLimiter') ? $query->param('filterBranchLimiter') : '_ShowAll';
81
my $filterVolume = $query->param('filterVolume') ? $query->param('filterVolume') : undef;
82
my $filterNumber = $query->param('filterNumber') ? $query->param('filterNumber') : undef;
83
my $filterIssue = $query->param('filterIssue') ? $query->param('filterIssue') : undef;
84
my $filterFromDate = $query->param('filterFrom') ? $query->param('filterFrom') : undef;
85
my $filterToDate = $query->param('filterTo') ? $query->param('filterTo') : undef;
86
87
my $filter; #a HASH! Collect the filters here, so they can be more conveniently moved around.
88
89
#We filter by the branch only if a valid branch is given.
90
if (defined $filterBranchLimiter && $filterBranchLimiter ne '_ShowAll') {
91
    $filter->{branch} = $filterBranchLimiter;
92
}
93
if (defined $filterVolume && length $filterVolume > 0) {
94
    if (!($filterVolume =~ /\d{1,4}/)) {
95
        print $query->header(); #bad data goddamnit!
96
        print "Invalid volume. Please try again. \n";
97
        exit;
98
    }
99
    else {
100
        $filter->{volume} = $filterVolume;
101
    }
102
}
103
if (defined $filterNumber && length $filterNumber > 0) {
104
    if (!($filterNumber =~ /\d{1,2}/)) {
105
        print $query->header(); #stop spamming bad data!
106
        print "Invalid number. Please try again. \n";
107
        exit;
108
    }
109
    else {
110
        $filter->{number} = $filterNumber;
111
    }
112
}
113
if (defined $filterIssue && length $filterIssue > 0) {
114
    if (!($filterIssue =~ /\d{1,2}/) ) {
115
        print $query->header(); #stop spamming bad data!
116
        print "Invalid issue. Please try again. \n";
117
        exit;
118
    }
119
    else {
120
        $filter->{issue} = $filterIssue;
121
    }
122
}
123
if (defined $filterFromDate && length $filterFromDate > 0) {
124
    if (!($filterFromDate =~ C4::Dates->regexp( C4::Context->preference('dateformat') )) ) {
125
        print $query->header(); #noo not anymore noo!
126
        print "Invalid starting date. Please try again. \n";
127
        exit;
128
    }
129
    else {
130
        $filter->{fromDate} = C4::Dates::format_date_in_iso( $filterFromDate );
131
    }
132
}
133
if (defined $filterToDate && length $filterToDate > 0) {
134
    if (!($filterToDate =~ C4::Dates->regexp( C4::Context->preference('dateformat') )) ) {
135
        print $query->header(); #take your bad data away!
136
        print "Invalid ending date. Please try again. \n";
137
        exit;
138
    }
139
    else {
140
        $filter->{toDate} = C4::Dates::format_date_in_iso( $filterToDate );
141
    }
142
}
143
144
145
##Prepare the custom branches loop containing the _ShowAll entry to show issues from all libraries.
146
my $branchloop;
147
if ( $filterBranchLimiter eq '_ShowAll' || !(defined $filterBranchLimiter) ) {
148
    $branchloop = C4::Branch::GetBranchesLoop('0'); #Using '0' to disable reverting to the users home branch
149
    unshift @$branchloop, { branchcode => '_ShowAll', branchname => 'Show from any library', selected => '1', value => '_ShowAll'};
150
}
151
else {
152
    $branchloop = C4::Branch::GetBranchesLoop($filterBranchLimiter);
153
    unshift @$branchloop, { branchcode => '_ShowAll', branchname => 'Show from any library', selected => '0', value => '_ShowAll'};
154
}
155
$template->param( branchloop => $branchloop );
156
$template->param( filter => $filter ) if defined $filter;
157
158
##
159
##<< Serial issues filter parameters handled! ##
160
##
161
162
163
my @all_items = GetItemsInfo($biblionumber, $filter);
164
165
# Now that the filter is no longer needed, we can reuse it to keep the filter modifications in the UI,
166
#  by reverting the dates to the same format as in the UI layer.
167
$filter->{fromDate} = $filterFromDate;
168
$filter->{toDate} = $filterToDate;
169
77
my @hiddenitems;
170
my @hiddenitems;
78
if (scalar @all_items >= 1) {
171
if (scalar @all_items >= 1) {
79
    push @hiddenitems, GetHiddenItemnumbers(@all_items);
172
    push @hiddenitems, GetHiddenItemnumbers(@all_items);
Lines 91-96 if ( ! $record ) { Link Here
91
}
184
}
92
$template->param( biblionumber => $biblionumber );
185
$template->param( biblionumber => $biblionumber );
93
186
187
#Figure out if we are dealing with a serial! This affects the filter fields in UI
188
if (scalar @all_items > 0) {
189
    $template->param( isSerial => $all_items[0]->{serial} );
190
}
191
else {
192
    #It could be that a serial has no items to be displayed. This could be because there are none or the filters filter all items
193
    my $search = C4::SQLHelper::SearchInTable("biblio",{biblionumber => $biblionumber}, undef, undef, ['serial'], undef, "exact");
194
    $template->param( isSerial => $search->[0]->{serial} );
195
}
196
197
198
199
94
# get biblionumbers stored in the cart
200
# get biblionumbers stored in the cart
95
my @cart_list;
201
my @cart_list;
96
202
Lines 1068-1072 if ( C4::Context->preference('UseCourseReserves') ) { Link Here
1068
        $i->{'course_reserves'} = GetItemCourseReservesInfo( itemnumber => $i->{'itemnumber'} );
1174
        $i->{'course_reserves'} = GetItemCourseReservesInfo( itemnumber => $i->{'itemnumber'} );
1069
    }
1175
    }
1070
}
1176
}
1177
## Defining general Serial issue filter related system preferences
1178
#Making sure the NumberingFormulaParsingRegexp preference is set!
1179
if ( length C4::Context->preference('NumberingFormulaParsingRegexp') < 3 ) {
1180
    $template->{VARS}->{notDefined_NumberingFormulaParsingRegexp} = 1;
1181
}
1182
$template->{VARS}->{useFilterIssueInput} = 1 if (C4::Context->preference('FilterSerialsByIssue'));
1071
1183
1072
output_html_with_http_headers $query, $cookie, $template->output;
1184
output_html_with_http_headers $query, $cookie, $template->output;
(-)a/t/db_dependent/Items.t (-1 / +34 lines)
Lines 21-27 use Modern::Perl; Link Here
21
use MARC::Record;
21
use MARC::Record;
22
use C4::Biblio;
22
use C4::Biblio;
23
23
24
use Test::More tests => 3;
24
use Test::More tests => 4;
25
25
26
BEGIN {
26
BEGIN {
27
    use_ok('C4::Items');
27
    use_ok('C4::Items');
Lines 142-147 subtest 'GetHiddenItemnumbers tests' => sub { Link Here
142
    $dbh->rollback;
142
    $dbh->rollback;
143
};
143
};
144
144
145
146
subtest 'Filter items tests' => sub {
147
148
    plan tests => 2;
149
150
    # Start transaction
151
    $dbh->{AutoCommit} = 0;
152
    $dbh->{RaiseError} = 1;
153
154
    # Create a new biblio
155
    my ($biblionumber, $biblioitemnumber) = get_biblio();
156
157
    # Add two items
158
    my ($item1_bibnum, $item1_bibitemnum, $item1_itemnumber) = AddItem(
159
            { homebranch => 'CPL',
160
              holdingbranch => 'CPL', },
161
            $biblionumber
162
    );
163
    my ($item2_bibnum, $item2_bibitemnum, $item2_itemnumber) = AddItem(
164
            { homebranch => 'MPL',
165
              holdingbranch => 'MPL', },
166
            $biblionumber
167
    );
168
169
    # Testing the branch filter
170
    my @shouldBeItem2 = C4::Items::GetItemsInfo($biblionumber, {branch => 'MPL'});
171
    is( $shouldBeItem2[0]->{itemnumber}, $item2_itemnumber, "Filtering by branch");
172
173
    # Testing the dates filter
174
    my @shouldBeEmpty = C4::Items::GetItemsInfo($biblionumber, {toDate => '01/01/1933'});
175
    is( scalar(@shouldBeEmpty), 0, "Filtering by date");
176
};
177
145
# Helper method to set up a Biblio.
178
# Helper method to set up a Biblio.
146
sub get_biblio {
179
sub get_biblio {
147
    my $bib = MARC::Record->new();
180
    my $bib = MARC::Record->new();
(-)a/t/db_dependent/Serials.t (-120 / +253 lines)
Lines 14-23 use C4::Debug; Link Here
14
use C4::Bookseller;
14
use C4::Bookseller;
15
use C4::Biblio;
15
use C4::Biblio;
16
use C4::Budgets;
16
use C4::Budgets;
17
use C4::Items;
17
use Test::More tests => 35;
18
use Test::More tests => 35;
18
19
19
BEGIN {
20
BEGIN {
20
    use_ok('C4::Serials');
21
	use_ok('C4::Serials');
21
}
22
}
22
23
23
my $dbh = C4::Context->dbh;
24
my $dbh = C4::Context->dbh;
Lines 27-75 $dbh->{AutoCommit} = 0; Link Here
27
$dbh->{RaiseError} = 1;
28
$dbh->{RaiseError} = 1;
28
29
29
my $booksellerid = C4::Bookseller::AddBookseller(
30
my $booksellerid = C4::Bookseller::AddBookseller(
30
    {
31
	{
31
        name => "my vendor",
32
		name     => "my vendor",
32
        address1 => "bookseller's address",
33
		address1 => "bookseller's address",
33
        phone => "0123456",
34
		phone    => "0123456",
34
        active => 1
35
		active   => 1
35
    }
36
	}
36
);
37
);
37
38
38
my ($biblionumber, $biblioitemnumber) = AddBiblio(MARC::Record->new, '');
39
my ( $biblionumber, $biblioitemnumber ) = AddBiblio( MARC::Record->new, '' );
39
40
40
my $budgetid;
41
my $budgetid;
41
my $bpid = AddBudgetPeriod({
42
my $bpid = AddBudgetPeriod(
42
    budget_period_startdate => '01-01-2015',
43
	{
43
    budget_period_enddate   => '12-31-2015',
44
		budget_period_startdate => '01-01-2015',
44
    budget_description      => "budget desc"
45
		budget_period_enddate   => '12-31-2015',
45
});
46
		budget_description      => "budget desc"
46
47
	}
47
my $budget_id = AddBudget({
48
);
48
    budget_code        => "ABCD",
49
49
    budget_amount      => "123.132",
50
my $budget_id = AddBudget(
50
    budget_name        => "Périodiques",
51
	{
51
    budget_notes       => "This is a note",
52
		budget_code        => "ABCD",
52
    budget_description => "Serials",
53
		budget_amount      => "123.132",
53
    budget_active      => 1,
54
		budget_name        => "Périodiques",
54
    budget_period_id   => $bpid
55
		budget_notes       => "This is a note",
55
});
56
		budget_description => "Serials",
56
57
		budget_active      => 1,
57
my $frequency_id = AddSubscriptionFrequency({ description => "Test frequency 1" });
58
		budget_period_id   => $bpid
58
my $pattern_id = AddSubscriptionNumberpattern({
59
	}
59
    label => 'Test numberpattern 1',
60
);
60
    numberingmethod => '{X}'
61
61
});
62
my $frequency_id =
63
  AddSubscriptionFrequency( { description => "Test frequency 1" } );
64
my $pattern_id = AddSubscriptionNumberpattern(
65
	{
66
		label           => 'Test numberpattern 1',
67
		numberingmethod => '{X}'
68
	}
69
);
62
70
63
my $subscriptionid = NewSubscription(
71
my $subscriptionid = NewSubscription(
64
    undef,      "",     undef, undef, $budget_id, $biblionumber,
72
	undef,        "",            undef,        undef,
65
    '2013-01-01', $frequency_id, undef, undef,  undef,
73
	$budget_id,   $biblionumber, '2013-01-01', $frequency_id,
66
    undef,      undef,  undef, undef, undef, undef,
74
	undef,        undef,         undef,        undef,
67
    1,          "notes",undef, '2013-01-01', undef, $pattern_id,
75
	undef,        undef,         undef,        undef,
68
    undef,       undef,  0,    "intnotes",  0,
76
	undef,        1,             "notes",      undef,
69
    undef, undef, 0,          undef,         '2013-12-31', 0
77
	'2013-01-01', undef,         $pattern_id,  undef,
78
	undef,        0,             "intnotes",   0,
79
	undef,        undef,         0,            undef,
80
	'2013-12-31', 0
70
);
81
);
71
82
72
my $subscriptioninformation = GetSubscription( $subscriptionid );
83
my $subscriptioninformation = GetSubscription($subscriptionid);
73
84
74
my @subscriptions = GetSubscriptions( $$subscriptioninformation{bibliotitle} );
85
my @subscriptions = GetSubscriptions( $$subscriptioninformation{bibliotitle} );
75
isa_ok( \@subscriptions, 'ARRAY' );
86
isa_ok( \@subscriptions, 'ARRAY' );
Lines 77-183 isa_ok( \@subscriptions, 'ARRAY' ); Link Here
77
@subscriptions = GetSubscriptions( undef, $$subscriptioninformation{issn} );
88
@subscriptions = GetSubscriptions( undef, $$subscriptioninformation{issn} );
78
isa_ok( \@subscriptions, 'ARRAY' );
89
isa_ok( \@subscriptions, 'ARRAY' );
79
90
80
@subscriptions = GetSubscriptions( undef, undef, $$subscriptioninformation{ean} );
91
@subscriptions =
92
  GetSubscriptions( undef, undef, $$subscriptioninformation{ean} );
81
isa_ok( \@subscriptions, 'ARRAY' );
93
isa_ok( \@subscriptions, 'ARRAY' );
82
94
83
@subscriptions = GetSubscriptions( undef, undef, undef, $$subscriptioninformation{bibnum} );
95
@subscriptions =
96
  GetSubscriptions( undef, undef, undef, $$subscriptioninformation{bibnum} );
84
isa_ok( \@subscriptions, 'ARRAY' );
97
isa_ok( \@subscriptions, 'ARRAY' );
85
98
86
my $frequency = GetSubscriptionFrequency($subscriptioninformation->{periodicity});
99
my $frequency =
100
  GetSubscriptionFrequency( $subscriptioninformation->{periodicity} );
87
my $old_frequency;
101
my $old_frequency;
88
if (not $frequency->{unit}) {
102
if ( not $frequency->{unit} ) {
89
    $old_frequency = $frequency->{id};
103
	$old_frequency              = $frequency->{id};
90
    $frequency->{unit} = "month";
104
	$frequency->{unit}          = "month";
91
    $frequency->{unitsperissue} = 1;
105
	$frequency->{unitsperissue} = 1;
92
    $frequency->{issuesperunit} = 1;
106
	$frequency->{issuesperunit} = 1;
93
    $frequency->{description} = "Frequency created by t/db_dependant/Serials.t";
107
	$frequency->{description} = "Frequency created by t/db_dependant/Serials.t";
94
    $subscriptioninformation->{periodicity} = AddSubscriptionFrequency($frequency);
108
	$subscriptioninformation->{periodicity} =
95
109
	  AddSubscriptionFrequency($frequency);
96
    ModSubscription( @$subscriptioninformation{qw(
110
97
        librarian branchcode aqbooksellerid cost aqbudgetid startdate
111
	ModSubscription(
98
        periodicity firstacquidate irregularity numberpattern locale
112
		@$subscriptioninformation{
99
        numberlength weeklength monthlength lastvalue1 innerloop1 lastvalue2
113
			qw(
100
        innerloop2 lastvalue3 innerloop3 status biblionumber callnumber notes
114
			  librarian branchcode aqbooksellerid cost aqbudgetid startdate
101
        letter manualhistory internalnotes serialsadditems staffdisplaycount
115
			  periodicity firstacquidate irregularity numberpattern locale
102
        opacdisplaycount graceperiod location enddate subscriptionid
116
			  numberlength weeklength monthlength lastvalue1 innerloop1 lastvalue2
103
        skip_serialseq
117
			  innerloop2 lastvalue3 innerloop3 status biblionumber callnumber notes
104
    )} );
118
			  letter manualhistory internalnotes serialsadditems staffdisplaycount
119
			  opacdisplaycount graceperiod location enddate subscriptionid
120
			  skip_serialseq
121
			  )
122
		}
123
	);
105
}
124
}
106
my $expirationdate = GetExpirationDate($subscriptionid) ;
125
my $expirationdate = GetExpirationDate($subscriptionid);
107
ok( $expirationdate, "expiration date is not NULL" );
126
ok( $expirationdate, "expiration date is not NULL" );
108
127
109
is(C4::Serials::GetLateIssues(), undef, 'test getting late issues');
128
is( C4::Serials::GetLateIssues(), undef, 'test getting late issues' );
110
129
111
ok(C4::Serials::GetSubscriptionHistoryFromSubscriptionId($subscriptionid), 'test getting history from sub-scription');
130
ok( C4::Serials::GetSubscriptionHistoryFromSubscriptionId($subscriptionid),
131
	'test getting history from sub-scription' );
112
132
113
my ($serials_count, @serials) = GetSerials($subscriptionid);
133
my ( $serials_count, @serials ) = GetSerials($subscriptionid);
114
ok($serials_count > 0, 'Subscription has at least one serial');
134
ok( $serials_count > 0, 'Subscription has at least one serial' );
115
my $serial = $serials[0];
135
my $serial = $serials[0];
116
136
117
ok(C4::Serials::GetSerialStatusFromSerialId($serial->{serialid}), 'test getting Serial Status From Serial Id');
137
ok( C4::Serials::GetSerialStatusFromSerialId( $serial->{serialid} ),
138
	'test getting Serial Status From Serial Id' );
118
139
119
isa_ok(C4::Serials::GetSerialInformation($serial->{serialid}), 'HASH', 'test getting Serial Information');
140
isa_ok( C4::Serials::GetSerialInformation( $serial->{serialid} ),
141
	'HASH', 'test getting Serial Information' );
120
142
121
# Delete created frequency
143
# Delete created frequency
122
if ($old_frequency) {
144
if ($old_frequency) {
123
    my $freq_to_delete = $subscriptioninformation->{periodicity};
145
	my $freq_to_delete = $subscriptioninformation->{periodicity};
124
    $subscriptioninformation->{periodicity} = $old_frequency;
146
	$subscriptioninformation->{periodicity} = $old_frequency;
125
147
126
    ModSubscription( @$subscriptioninformation{qw(
148
	ModSubscription(
127
        librarian branchcode aqbooksellerid cost aqbudgetid startdate
149
		@$subscriptioninformation{
128
        periodicity firstacquidate irregularity numberpattern locale
150
			qw(
129
        numberlength weeklength monthlength lastvalue1 innerloop1 lastvalue2
151
			  librarian branchcode aqbooksellerid cost aqbudgetid startdate
130
        innerloop2 lastvalue3 innerloop3 status biblionumber callnumber notes
152
			  periodicity firstacquidate irregularity numberpattern locale
131
        letter manualhistory internalnotes serialsadditems staffdisplaycount
153
			  numberlength weeklength monthlength lastvalue1 innerloop1 lastvalue2
132
        opacdisplaycount graceperiod location enddate subscriptionid
154
			  innerloop2 lastvalue3 innerloop3 status biblionumber callnumber notes
133
        skip_serialseq
155
			  letter manualhistory internalnotes serialsadditems staffdisplaycount
134
    )} );
156
			  opacdisplaycount graceperiod location enddate subscriptionid
135
157
			  skip_serialseq
136
    DelSubscriptionFrequency($freq_to_delete);
158
			  )
159
		}
160
	);
161
162
	DelSubscriptionFrequency($freq_to_delete);
137
}
163
}
138
164
139
140
# Test calling subs without parameters
165
# Test calling subs without parameters
141
is(C4::Serials::AddItem2Serial(), undef, 'test adding item to serial');
166
is( C4::Serials::AddItem2Serial(),        undef, 'test adding item to serial' );
142
is(C4::Serials::UpdateClaimdateIssues(), undef, 'test updating claim date');
167
is( C4::Serials::UpdateClaimdateIssues(), undef, 'test updating claim date' );
143
is(C4::Serials::GetFullSubscription(), undef, 'test getting full subscription');
168
is( C4::Serials::GetFullSubscription(),
144
is(C4::Serials::PrepareSerialsData(), undef, 'test preparing serial data');
169
	undef, 'test getting full subscription' );
145
is(C4::Serials::GetSubscriptionsFromBiblionumber(), undef, 'test getting subscriptions form biblio number');
170
is( C4::Serials::PrepareSerialsData(), undef, 'test preparing serial data' );
146
171
is( C4::Serials::GetSubscriptionsFromBiblionumber(),
147
is(C4::Serials::GetSerials(), undef, 'test getting serials when you enter nothing');
172
	undef, 'test getting subscriptions form biblio number' );
148
is(C4::Serials::GetSerials2(), undef, 'test getting serials when you enter nothing');
173
149
174
is( C4::Serials::GetSerials(), undef,
150
is(C4::Serials::GetLatestSerials(), undef, 'test getting lastest serials');
175
	'test getting serials when you enter nothing' );
151
176
is( C4::Serials::GetSerials2(),
152
is(C4::Serials::GetDistributedTo(), undef, 'test getting distributed when nothing is entered');
177
	undef, 'test getting serials when you enter nothing' );
153
178
154
is(C4::Serials::GetNextSeq(), undef, 'test getting next seq when you enter nothing');
179
is( C4::Serials::GetLatestSerials(), undef, 'test getting lastest serials' );
155
180
156
is(C4::Serials::GetSeq(), undef, 'test getting seq when you enter nothing');
181
is( C4::Serials::GetDistributedTo(),
157
182
	undef, 'test getting distributed when nothing is entered' );
158
is(C4::Serials::CountSubscriptionFromBiblionumber(), undef, 'test counting subscription when nothing is entered');
183
159
184
is( C4::Serials::GetNextSeq(), undef,
160
is(C4::Serials::ModSubscriptionHistory(), undef, 'test modding subscription history');
185
	'test getting next seq when you enter nothing' );
161
186
162
is(C4::Serials::ModSerialStatus(),undef, 'test modding serials');
187
is( C4::Serials::GetSeq(), undef, 'test getting seq when you enter nothing' );
163
188
164
is(C4::Serials::NewIssue(), undef, 'test getting 0 when nothing is entered');
189
is( C4::Serials::CountSubscriptionFromBiblionumber(),
165
190
	undef, 'test counting subscription when nothing is entered' );
166
is(C4::Serials::ItemizeSerials(),undef, 'test getting nothing when nothing is entered');
191
167
192
is( C4::Serials::ModSubscriptionHistory(),
168
is(C4::Serials::HasSubscriptionStrictlyExpired(), undef, 'test if the subscriptions has expired');
193
	undef, 'test modding subscription history' );
169
is(C4::Serials::HasSubscriptionExpired(), undef, 'test if the subscriptions has expired');
194
170
195
is( C4::Serials::ModSerialStatus(), undef, 'test modding serials' );
171
is(C4::Serials::GetLateOrMissingIssues(), undef, 'test getting last or missing issues');
196
172
197
is( C4::Serials::NewIssue(), undef, 'test getting 0 when nothing is entered' );
173
is(C4::Serials::removeMissingIssue(), undef, 'test removing a missing issue');
198
174
199
is( C4::Serials::ItemizeSerials(),
175
is(C4::Serials::updateClaim(),undef, 'test updating claim');
200
	undef, 'test getting nothing when nothing is entered' );
176
201
177
is(C4::Serials::getsupplierbyserialid(),undef, 'test getting supplier idea');
202
is( C4::Serials::HasSubscriptionStrictlyExpired(),
178
203
	undef, 'test if the subscriptions has expired' );
179
is(C4::Serials::check_routing(), undef, 'test checking route');
204
is( C4::Serials::HasSubscriptionExpired(),
180
205
	undef, 'test if the subscriptions has expired' );
181
is(C4::Serials::addroutingmember(),undef, 'test adding route member');
206
207
is( C4::Serials::GetLateOrMissingIssues(),
208
	undef, 'test getting last or missing issues' );
209
210
is( C4::Serials::removeMissingIssue(), undef, 'test removing a missing issue' );
211
212
is( C4::Serials::updateClaim(), undef, 'test updating claim' );
213
214
is( C4::Serials::getsupplierbyserialid(), undef, 'test getting supplier idea' );
215
216
is( C4::Serials::check_routing(), undef, 'test checking route' );
217
218
is( C4::Serials::addroutingmember(), undef, 'test adding route member' );
219
220
subtest 'Filter items tests' => sub {
221
222
	plan tests => 4;
223
224
	# Start transaction
225
	$dbh->{AutoCommit} = 0;
226
	$dbh->{RaiseError} = 1;
227
228
	# Create a new biblio
229
	my ( $biblionumber, $biblioitemnumber ) = get_biblio();
230
231
	# Add items
232
	my ( $item0_bibnum, $item0_bibitemnum, $item0_itemnumber ) = AddItem(
233
		{
234
			homebranch    => 'CPL',
235
			holdingbranch => 'CPL',
236
			enumchron     => 'Vol 2012 : No 1, Issuezz 1'
237
		},
238
		$biblionumber
239
	);
240
	my ( $item1_bibnum, $item1_bibitemnum, $item1_itemnumber ) = AddItem(
241
		{
242
			homebranch    => 'CPL',
243
			holdingbranch => 'CPL',
244
			enumchron     => 'Vol 2013 : No 11, Issuezz 1'
245
		},
246
		$biblionumber
247
	);
248
	my ( $item2_bibnum, $item2_bibitemnum, $item2_itemnumber ) = AddItem(
249
		{
250
			homebranch    => 'MPL',
251
			holdingbranch => 'MPL',
252
			enumchron     => 'Vol 2013 : No 11, Issuezz 2'
253
		},
254
		$biblionumber
255
	);
256
	my ( $item3_bibnum, $item3_bibitemnum, $item3_itemnumber ) = AddItem(
257
		{
258
			homebranch    => 'CPL',
259
			holdingbranch => 'CPL',
260
			enumchron     => 'Vol 2013 : No 12, Issuezz 1'
261
		},
262
		$biblionumber
263
	);
264
	my ( $item4_bibnum, $item4_bibitemnum, $item4_itemnumber ) = AddItem(
265
		{
266
			homebranch    => 'MPL',
267
			holdingbranch => 'MPL',
268
			enumchron     => 'Vol 2013 : No 12, Issuezz 2'
269
		},
270
		$biblionumber
271
	);
272
	my ( $item5_bibnum, $item5_bibitemnum, $item5_itemnumber ) = AddItem(
273
		{
274
			homebranch    => 'MPL',
275
			holdingbranch => 'MPL',
276
			enumchron     => 'Vol 2014 : No 12, Issuezz 3'
277
		},
278
		$biblionumber
279
	);
280
281
	C4::Context->set_preference( 'NumberingFormulaParsingRegexp',
282
		'^[^0-9]*volume[^0-9]*number[^0-9]*issue[^0-9]*$' );
283
284
	# Testing the volume filter
285
	my @shouldBe4Items =
286
	  C4::Items::GetItemsInfo( $biblionumber, { volume => '2013' } );
287
	is( scalar(@shouldBe4Items), 4, "Filtering by volume" );
288
289
	# Testing the number filter
290
	my @shouldBe3Items =
291
	  C4::Items::GetItemsInfo( $biblionumber, { number => '12' } );
292
	is( scalar(@shouldBe3Items), 3, "Filtering by number" );
293
294
	# Testing the issue filter
295
	my @shouldBe2Items =
296
	  C4::Items::GetItemsInfo( $biblionumber, { issue => '2' } );
297
	is( scalar(@shouldBe2Items), 2, "Filtering by issue" );
298
299
	# Testing the volume + number + issue filter
300
	my @shouldBeItem4 = C4::Items::GetItemsInfo( $biblionumber,
301
		{ volume => 2013, number => 12, issue => '2' } );
302
	is( $shouldBeItem4[0]->{itemnumber},
303
		$item4_itemnumber, "Filtering by volume + number + issue" );
304
};
305
306
# Helper method to set up a Biblio.
307
sub get_biblio {
308
	my $bib = MARC::Record->new();
309
	$bib->append_fields(
310
		MARC::Field->new( '100', ' ', ' ', a => 'Moffat, Steven' ),
311
		MARC::Field->new( '245', ' ', ' ', a => 'Silence in the library' ),
312
	);
313
	my ( $bibnum, $bibitemnum ) = C4::Biblio::AddBiblio( $bib, '' );
314
	return ( $bibnum, $bibitemnum );
315
}
182
316
183
$dbh->rollback;
317
$dbh->rollback;
184
- 

Return to bug 11129