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

(-)a/ill/ill-requests.pl (-2 / +9 lines)
Lines 129-136 if ( $backends_available ) { Link Here
129
                value   => {}
129
                value   => {}
130
            };
130
            };
131
            $template->param(
131
            $template->param(
132
                whole   => $backend_result,
132
                whole          => $backend_result,
133
                request => $request
133
                request        => $request,
134
                status_aliases => scalar Koha::AuthorisedValues->search(
135
                    { category => 'ILLSTATUS' }
136
                )
134
            );
137
            );
135
        } else {
138
        } else {
136
            # Commit:
139
            # Commit:
Lines 141-146 if ( $backends_available ) { Link Here
141
            $request->price_paid($params->{price_paid});
144
            $request->price_paid($params->{price_paid});
142
            $request->notesopac($params->{notesopac});
145
            $request->notesopac($params->{notesopac});
143
            $request->notesstaff($params->{notesstaff});
146
            $request->notesstaff($params->{notesstaff});
147
            my $alias = ($params->{status_alias} =~ /\d/) ?
148
                $params->{status_alias} :
149
                undef;
150
            $request->status_alias($alias);
144
            $request->store;
151
            $request->store;
145
            my $backend_result = {
152
            my $backend_result = {
146
                error   => 0,
153
                error   => 0,
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/ill/ill-requests.tt (-3 / +533 lines)
Lines 445-451 Link Here
445
                                <li class="status">
445
                                <li class="status">
446
                                    <label class="status">Status:</label>
446
                                    <label class="status">Status:</label>
447
                                    [% stat = request.status %]
447
                                    [% stat = request.status %]
448
                                    [% request.capabilities.$stat.name | html %]
448
                                    [% current_alias = request.status_alias %]
449
                                    <select id="status_alias" name="status_alias">
450
                                        [% IF !current_alias %]
451
                                        <option value="" selected>
452
                                        [% ELSE %]
453
                                        <option value="">
454
                                        [% END %]
455
                                            [% request.capabilities.$stat.name | html %]
456
                                        </option>
457
                                        [% FOREACH alias IN status_aliases %]
458
                                            [% IF alias.id == current_alias %]
459
                                            <option value="[% alias.id %]" selected>
460
                                            [% ELSE %]
461
                                            <option value="[% alias.id %]">
462
                                            [% END %]
463
                                                [% alias.authorised_value | html %]
464
                                            </option>
465
                                        [% END %]
466
                                    </select>
449
                                </li>
467
                                </li>
450
                                <li class="updated">
468
                                <li class="updated">
451
                                    <label class="updated">Last updated:</label>
469
                                    <label class="updated">Last updated:</label>
Lines 555-561 Link Here
555
                                    </li>
573
                                    </li>
556
                                    <li class="status">
574
                                    <li class="status">
557
                                        <span class="label status">Status:</span>
575
                                        <span class="label status">Status:</span>
558
                                        [% request.capabilities.$req_status.name | html %]
576
                                        [% IF request.statusalias %]
577
                                            [% request.statusalias.authorised_value | html %]
578
                                        [% ELSE %]
579
                                            [% request.capabilities.$req_status.name | html%]
580
                                        [% END %]
559
                                    </li>
581
                                    </li>
560
                                    <li class="updated">
582
                                    <li class="updated">
561
                                        <span class="label updated">Last updated:</span>
583
                                        <span class="label updated">Last updated:</span>
Lines 707-710 Link Here
707
[% CATCH %]
729
[% CATCH %]
708
[% END %]
730
[% END %]
709
731
732
[% MACRO jsinclude BLOCK %]
733
    [% INCLUDE 'datatables.inc' %]
734
    [% INCLUDE 'calendar.inc' %]
735
    [% Asset.js("lib/jquery/plugins/jquery.checkboxes.min.js") | $raw %]
736
    <script>
737
        $(document).ready(function() {
738
739
            // Illview Datatable setup
740
741
            var table;
742
743
            // Filters that are active
744
            var activeFilters = {};
745
746
            // Fields we don't want to display
747
            var ignore = [
748
                'accessurl',
749
                'backend',
750
                'branchcode',
751
                'completed',
752
                'capabilities',
753
                'cost',
754
                'medium',
755
                'notesopac',
756
                'notesstaff',
757
                'replied'
758
            ];
759
760
            // Fields we need to expand (flatten)
761
            var expand = [
762
                'metadata',
763
                'patron'
764
            ];
765
766
            // Expanded fields
767
            // This is auto populated
768
            var expanded = {};
769
770
            // The core fields that should be displayed first
771
            var core = [
772
                'metadata_author',
773
                'metadata_title',
774
                'borrowername',
775
                'biblio_id',
776
                'library',
777
                'status',
778
                'placed',
779
                'placed_formatted',
780
                'updated',
781
                'updated_formatted',
782
                'illrequest_id',
783
                'comments',
784
                'patron_cardnumber',
785
                'action'
786
            ];
787
788
            // Filterable columns
789
            var filterable = {
790
                status: {
791
                    prep: function(tableData, oData) {
792
                        var uniques = {};
793
                        tableData.forEach(function(row) {
794
                            var resolvedName = getStatusName(
795
                                oData[0].capabilities[row.status].name
796
                            );
797
                            uniques[resolvedName] = 1
798
                        });
799
                        Object.keys(uniques).sort().forEach(function(unique) {
800
                            $('#illfilter_status').append(
801
                                '<option value="' + unique  +
802
                                '">' + unique +  '</option>'
803
                            );
804
                        });
805
                    },
806
                    listener: function() {
807
                        var me = 'status';
808
                        $('#illfilter_status').change(function() {
809
                            var sel = $('#illfilter_status option:selected').val();
810
                            if (sel && sel.length > 0) {
811
                                activeFilters[me] = function() {
812
                                    table.column(5).search(sel);
813
                                }
814
                            } else {
815
                                if (activeFilters.hasOwnProperty(me)) {
816
                                    delete activeFilters[me];
817
                                }
818
                            }
819
                        });
820
                    },
821
                    clear: function() {
822
                        $('#illfilter_status').val('');
823
                    }
824
                },
825
                pickupBranch: {
826
                    prep: function(tableData, oData) {
827
                        var uniques = {};
828
                        tableData.forEach(function(row) {
829
                            uniques[row.library.branchname] = 1
830
                        });
831
                        Object.keys(uniques).sort().forEach(function(unique) {
832
                            $('#illfilter_branchname').append(
833
                                '<option value="' + unique  +
834
                                '">' + unique +  '</option>'
835
                            );
836
                        });
837
                    },
838
                    listener: function() {
839
                        var me = 'pickupBranch';
840
                        $('#illfilter_branchname').change(function() {
841
                            var sel = $('#illfilter_branchname option:selected').val();
842
                            if (sel && sel.length > 0) {
843
                                activeFilters[me] = function() {
844
                                    table.column(4).search(sel);
845
                                }
846
                            } else {
847
                                if (activeFilters.hasOwnProperty(me)) {
848
                                    delete activeFilters[me];
849
                                }
850
                            }
851
                        });
852
                    },
853
                    clear: function() {
854
                        $('#illfilter_branchname').val('');
855
                    }
856
                },
857
                barcode: {
858
                    listener: function() {
859
                        var me = 'barcode';
860
                        $('#illfilter_barcode').change(function() {
861
                            var val = $('#illfilter_barcode').val();
862
                            if (val && val.length > 0) {
863
                                activeFilters[me] = function() {
864
                                    table.column(12).search(val);
865
                                }
866
                            } else {
867
                                if (activeFilters.hasOwnProperty(me)) {
868
                                    delete activeFilters[me];
869
                                }
870
                            }
871
                        });
872
                    },
873
                    clear: function() {
874
                        $('#illfilter_barcode').val('');
875
                    }
876
                },
877
                dateModified: {
878
                    clear: function() {
879
                        $('#illfilter_datemodified_start, #illfilter_datemodified_end').val('');
880
                    }
881
                },
882
                datePlaced: {
883
                    clear: function() {
884
                        $('#illfilter_dateplaced_start, #illfilter_dateplaced_end').val('');
885
                    }
886
                }
887
            };
888
889
            // Remove any fields we're ignoring
890
            var removeIgnore = function(dataObj) {
891
                dataObj.forEach(function(thisRow) {
892
                    ignore.forEach(function(thisIgnore) {
893
                        if (thisRow.hasOwnProperty(thisIgnore)) {
894
                            delete thisRow[thisIgnore];
895
                        }
896
                    });
897
                });
898
            };
899
900
            // Expand any fields we're expanding
901
            var expandExpand = function(row) {
902
                expand.forEach(function(thisExpand) {
903
                    if (row.hasOwnProperty(thisExpand)) {
904
                        if (!expanded.hasOwnProperty(thisExpand)) {
905
                            expanded[thisExpand] = [];
906
                        }
907
                        var expandObj = row[thisExpand];
908
                        Object.keys(expandObj).forEach(
909
                            function(thisExpandCol) {
910
                                var expColName = thisExpand + '_' + thisExpandCol;
911
                                // Keep a list of fields that have been expanded
912
                                // so we can create toggle links for them
913
                                if (expanded[thisExpand].indexOf(expColName) == -1) {
914
                                    expanded[thisExpand].push(expColName);
915
                                }
916
                                expandObj[expColName] =
917
                                    expandObj[thisExpandCol];
918
                                delete expandObj[thisExpandCol];
919
                            }
920
                        );
921
                        $.extend(true, row, expandObj);
922
                        delete row[thisExpand];
923
                    }
924
                });
925
            };
926
927
            // Build a de-duped list of all column names
928
            var allCols = {};
929
            core.map(function(thisCore) {
930
                allCols[thisCore] = 1;
931
            });
932
933
            // Strip the expand prefix if it exists, we do this for display
934
            var stripPrefix = function(value) {
935
                expand.forEach(function(thisExpand) {
936
                    var regex = new RegExp(thisExpand + '_', 'g');
937
                    value = value.replace(regex, '');
938
                });
939
                return value;
940
            };
941
942
            // Our 'render' function for borrowerlink
943
            var createPatronLink = function(data, type, row) {
944
                var patronLink = '<a title="' + _("View borrower details") + '" ' +
945
                    'href="/cgi-bin/koha/members/moremember.pl?' +
946
                    'borrowernumber='+row.borrowernumber+'">';
947
                if ( row.patron_firstname ) {
948
                    patronLink = patronLink + row.patron_firstname + ' ';
949
                }
950
                patronLink = patronLink + row.patron_surname + '</a>';
951
                return patronLink;
952
            };
953
954
            // Our 'render' function for the library name
955
            var createLibrary = function(data, type, row) {
956
                return row.library.branchname;
957
            };
958
959
            // Render function for request ID
960
            var createRequestId = function(data, type, row) {
961
                return row.id_prefix + row.illrequest_id;
962
            };
963
964
            // Render function for request status
965
            var createStatus = function(data, type, row, meta) {
966
                if (row.status_alias) {
967
                    return row.status_alias.authorised_value;
968
                } else {
969
                    var origData = meta.settings.oInit.originalData;
970
                    if (origData.length > 0) {
971
                        var status_name = meta.settings.oInit.originalData[0].capabilities[
972
                            row.status
973
                        ].name;
974
                        return getStatusName(status_name);
975
                    } else {
976
                        return '';
977
                    }
978
                }
979
            };
980
981
            var getStatusName = function(origName) {
982
                switch( origName ) {
983
                    case "New request":
984
                        return _("New request");
985
                    case "Requested":
986
                        return _("Requested");
987
                    case "Requested from partners":
988
                        return _("Requested from partners");
989
                    case "Request reverted":
990
                        return _("Request reverted");
991
                    case "Queued request":
992
                        return _("Queued request");
993
                    case "Cancellation requested":
994
                        return _("Cancellation requested");
995
                    case "Completed":
996
                        return _("Completed");
997
                    case "Delete request":
998
                        return _("Delete request");
999
                    default:
1000
                        return origName;
1001
                }
1002
            };
1003
1004
            // Render function for creating a row's action link
1005
            var createActionLink = function(data, type, row) {
1006
                return '<a class="btn btn-default btn-sm" ' +
1007
                    'href="/cgi-bin/koha/ill/ill-requests.pl?' +
1008
                    'method=illview&amp;illrequest_id=' +
1009
                    row.illrequest_id +
1010
                    '">' + _("Manage request") + '</a>';
1011
            };
1012
1013
            // Columns that require special treatment
1014
            var specialCols = {
1015
                action: {
1016
                    name: '',
1017
                    func: createActionLink
1018
                },
1019
                borrowername: {
1020
                    name: _("Patron"),
1021
                    func: createPatronLink
1022
                },
1023
                illrequest_id: {
1024
                    name: _("Request number"),
1025
                    func: createRequestId
1026
                },
1027
                status: {
1028
                    name: _("Status"),
1029
                    func: createStatus
1030
                },
1031
                biblio_id: {
1032
                    name: _("Biblio ID")
1033
                },
1034
                library: {
1035
                    name: _("Library"),
1036
                    func: createLibrary
1037
                },
1038
                updated: {
1039
                    name: _("Updated on"),
1040
                },
1041
                patron_cardnumber: {
1042
                    name: _("Patron barcode")
1043
                }
1044
            };
1045
1046
            // Toggle request attributes in Illview
1047
            $('#toggle_requestattributes').on('click', function(e) {
1048
                e.preventDefault();
1049
                $('#requestattributes').toggleClass('content_hidden');
1050
            });
1051
1052
            // Toggle new comment form in Illview
1053
            $('#toggle_addcomment').on('click', function(e) {
1054
                e.preventDefault();
1055
                $('#addcomment').toggleClass('content_hidden');
1056
            });
1057
1058
            // Filter partner list
1059
            $('#partner_filter').keyup(function() {
1060
                var needle = $('#partner_filter').val();
1061
                $('#partners > option').each(function() {
1062
                    var regex = new RegExp(needle, 'i');
1063
                    if (
1064
                        needle.length == 0 ||
1065
                        $(this).is(':selected') ||
1066
                        $(this).text().match(regex)
1067
                    ) {
1068
                        $(this).show();
1069
                    } else {
1070
                        $(this).hide();
1071
                    }
1072
                });
1073
            });
1074
1075
        // Display the modal containing request supplier metadata
1076
        $('#ill-request-display-metadata').on('click', function(e) {
1077
            e.preventDefault();
1078
            $('#dataPreview').modal({show:true});
1079
        });
1080
1081
            // Get our data from the API and process it prior to passing
1082
            // it to datatables
1083
            var ajax = $.ajax(
1084
                '/api/v1/illrequests?embed=metadata,patron,capabilities,library'
1085
                ).done(function() {
1086
                    var data = JSON.parse(ajax.responseText);
1087
                    // Make a copy, we'll be removing columns next and need
1088
                    // to be able to refer to data that has been removed
1089
                    var dataCopy = $.extend(true, [], data);
1090
                    // Remove all columns we're not interested in
1091
                    removeIgnore(dataCopy);
1092
                    // Expand columns that need it and create an array
1093
                    // of all column names
1094
                    $.each(dataCopy, function(k, row) {
1095
                        expandExpand(row);
1096
                    });
1097
1098
                    // Assemble an array of column definitions for passing
1099
                    // to datatables
1100
                    var colData = [];
1101
                    Object.keys(allCols).forEach(function(thisCol) {
1102
                        // Create the base column object
1103
                        var colObj = {
1104
                            name: thisCol,
1105
                            className: thisCol,
1106
                            defaultContent: ''
1107
                        };
1108
                        // We may need to process the data going in this
1109
                        // column, so do it if necessary
1110
                        if (
1111
                            specialCols.hasOwnProperty(thisCol) &&
1112
                            specialCols[thisCol].hasOwnProperty('func')
1113
                        ) {
1114
                            colObj.render = specialCols[thisCol].func;
1115
                        } else {
1116
                            colObj.data = thisCol;
1117
                        }
1118
                        colData.push(colObj);
1119
                    });
1120
1121
                    // Initialise the datatable
1122
                    table = $('#ill-requests').DataTable($.extend(true, {}, dataTablesDefaults, {
1123
                        'aoColumnDefs': [
1124
                            { // Last column shouldn't be sortable or searchable
1125
                                'aTargets': [ 'actions' ],
1126
                                'bSortable': false,
1127
                                'bSearchable': false
1128
                            },
1129
                            { // Hide the two date columns we use just for sorting
1130
                                'aTargets': [ 'placed', 'updated' ],
1131
                                'bVisible': false,
1132
                                'bSearchable': true
1133
                            },
1134
                            { // When sorting 'placed', we want to use the
1135
                              // unformatted column
1136
                              'aTargets': [ 'placed_formatted'],
1137
                              'iDataSort': 7
1138
                            },
1139
                            { // When sorting 'updated', we want to use the
1140
                              // unformatted column
1141
                              'aTargets': [ 'updated_formatted'],
1142
                              'iDataSort': 9
1143
                            },
1144
                            {
1145
                              'aTargets': [ 'patron_cardnumber' ],
1146
                              'bVisible': false,
1147
                              'bSearchable': true
1148
                            }
1149
                        ],
1150
                        'aaSorting': [[ 9, 'desc' ]], // Default sort, updated descending
1151
                        'processing': true, // Display a message when manipulating
1152
                        'sPaginationType': "full_numbers", // Pagination display
1153
                        'deferRender': true, // Improve performance on big datasets
1154
                        'data': dataCopy,
1155
                        'columns': colData,
1156
                        'originalData': data, // Enable render functions to access
1157
                                              // our original data
1158
                        'initComplete': function() {
1159
1160
                            // Prepare any filter elements that need it
1161
                            for (var el in filterable) {
1162
                                if (filterable.hasOwnProperty(el)) {
1163
                                    if (filterable[el].hasOwnProperty('prep')) {
1164
                                        filterable[el].prep(dataCopy, data);
1165
                                    }
1166
                                    if (filterable[el].hasOwnProperty('listener')) {
1167
                                        filterable[el].listener();
1168
                                    }
1169
                                }
1170
                            }
1171
1172
                        }
1173
                    }));
1174
1175
                    // Custom date range filtering
1176
                    $.fn.dataTable.ext.search.push(function(settings, data, dataIndex) {
1177
                        var placedStart = $('#illfilter_dateplaced_start').datepicker('getDate');
1178
                        var placedEnd = $('#illfilter_dateplaced_end').datepicker('getDate');
1179
                        var modifiedStart = $('#illfilter_datemodified_start').datepicker('getDate');
1180
                        var modifiedEnd = $('#illfilter_datemodified_end').datepicker('getDate');
1181
                        var rowPlaced = data[6] ? new Date(data[6]) : null;
1182
                        var rowModified = data[8] ? new Date(data[8]) : null;
1183
                        var placedPassed = true;
1184
                        var modifiedPassed = true;
1185
                        if (placedStart && rowPlaced && rowPlaced < placedStart) {
1186
                            placedPassed = false
1187
                        };
1188
                        if (placedEnd && rowPlaced && rowPlaced > placedEnd) {
1189
                            placedPassed = false;
1190
                        }
1191
                        if (modifiedStart && rowModified && rowModified < modifiedStart) {
1192
                            modifiedPassed = false
1193
                        };
1194
                        if (modifiedEnd && rowModified && rowModified > modifiedEnd) {
1195
                            modifiedPassed = false;
1196
                        }
1197
1198
                        return placedPassed && modifiedPassed;
1199
1200
                    });
1201
1202
                }
1203
            );
1204
1205
            var clearSearch = function() {
1206
                table.search('').columns().search('');
1207
                activeFilters = {};
1208
                for (var filter in filterable) {
1209
                    if (
1210
                        filterable.hasOwnProperty(filter) &&
1211
                        filterable[filter].hasOwnProperty('clear')
1212
                    ) {
1213
                        filterable[filter].clear();
1214
                    }
1215
                }
1216
                table.draw();
1217
            };
1218
1219
            // Apply any search filters, or clear any previous
1220
            // ones
1221
            $('#illfilter_form').submit(function(event) {
1222
                event.preventDefault();
1223
                table.search('').columns().search('');
1224
                for (var active in activeFilters) {
1225
                    if (activeFilters.hasOwnProperty(active)) {
1226
                        activeFilters[active]();
1227
                    }
1228
                }
1229
                table.draw();
1230
            });
1231
1232
            // Clear all filters
1233
            $('#clear_search').click(function() {
1234
                clearSearch();
1235
            });
1236
1237
        });
1238
    </script>
1239
[% END %]
1240
710
[% INCLUDE 'intranet-bottom.inc' %]
1241
[% INCLUDE 'intranet-bottom.inc' %]
711
- 

Return to bug 20581