|
Lines 498-500
$(document).ready(function() {
Link Here
|
| 498 |
}); |
498 |
}); |
| 499 |
|
499 |
|
| 500 |
}); |
500 |
}); |
|
|
501 |
|
| 502 |
function fetch_libraries() { |
| 503 |
return $.ajax({ |
| 504 |
method: "GET", |
| 505 |
url: "/api/v1/libraries", |
| 506 |
data: {_per_page: -1}, |
| 507 |
success: function(data, textStatus, request){ |
| 508 |
}, |
| 509 |
error: function( jqXHR, textStatus, errorThrown) { |
| 510 |
console.log(errorThrown); |
| 511 |
}, |
| 512 |
}); |
| 513 |
} |
| 514 |
|
| 515 |
async function load_patron_holds_table(biblio_id, split_data) { |
| 516 |
const { name: split_name, value: split_value } = split_data; |
| 517 |
const table_id = `#patron_holds_table_${biblio_id}_${split_value}`; |
| 518 |
hold_table_settings.table = `patron_holds_table_${biblio_id}_${split_data.value}`; |
| 519 |
let url = `/api/v1/holds/?q={"me.biblio_id":${biblio_id}`; |
| 520 |
|
| 521 |
if (split_name === 'branch' && split_value !== 'any') { |
| 522 |
url += `, "me.pickup_library_id":"${split_value}"`; |
| 523 |
} else if (split_name === 'itemtype' && split_value !== 'any') { |
| 524 |
url += `, "me.itemtype":"${split_value}"`; |
| 525 |
} else if (split_name === 'branch_itemtype') { |
| 526 |
const [branch, itemtype] = split_value.split('_'); |
| 527 |
url += itemtype === 'any' |
| 528 |
? `, "me.pickup_library_id":"${branch}"` |
| 529 |
: `, "me.pickup_library_id":"${branch}", "me.itemtype":"${itemtype}"`; |
| 530 |
} |
| 531 |
|
| 532 |
url += '}'; |
| 533 |
const totalHolds = $(table_id).data('total-holds'); |
| 534 |
const totalHoldsSelect = parseInt(totalHolds)+1; |
| 535 |
const multiChange = {}; |
| 536 |
let pageStart; |
| 537 |
const libraries = await fetch_libraries(); |
| 538 |
var holdsQueueTable = $(table_id).kohaTable({ |
| 539 |
ajax: { |
| 540 |
url: url, |
| 541 |
data: function (params) { |
| 542 |
pageStart = params.start; |
| 543 |
var query = { |
| 544 |
"_per_page": params.length, |
| 545 |
"_page": params.start / params.length + 1, |
| 546 |
"_order_by": "priority", |
| 547 |
"_match": "exact" |
| 548 |
}; |
| 549 |
return query; |
| 550 |
}, |
| 551 |
}, |
| 552 |
embed: ['patron'], |
| 553 |
columnDefs: [ |
| 554 |
{ |
| 555 |
targets: [2, 3], |
| 556 |
className: 'dt-body-nowrap' |
| 557 |
}, |
| 558 |
{ |
| 559 |
targets: [3, 9], |
| 560 |
visible: CAN_user_reserveforothers_modify_holds_priority ? true : false |
| 561 |
}, |
| 562 |
|
| 563 |
], |
| 564 |
columns: [ |
| 565 |
{ |
| 566 |
data: "hold_id", |
| 567 |
orderable: false, |
| 568 |
searchable: false, |
| 569 |
render: function( data, type, row, meta ) { |
| 570 |
return '<input type="checkbox" class="select_hold" data-id="'+data+'"/>'; |
| 571 |
} |
| 572 |
}, |
| 573 |
{ |
| 574 |
data: "priority", |
| 575 |
orderable: false, |
| 576 |
searchable: false, |
| 577 |
render: function(data, type, row, meta) { |
| 578 |
let select = '<select name="rank-request" class="rank-request" data-id="'+row.hold_id; |
| 579 |
if(CAN_user_reserveforothers_modify_holds_priority && split_name == 'any') { |
| 580 |
for ( var i=0; i < totalHoldsSelect; i++ ){ |
| 581 |
let selected; |
| 582 |
let value; |
| 583 |
let desc; |
| 584 |
if (data == i && row.status == 'T') { |
| 585 |
select += '" disabled="disabled">'; |
| 586 |
selected = " selected='selected' "; |
| 587 |
value = 'T'; |
| 588 |
desc = 'In transit'; |
| 589 |
} else if (data == i && row.status == 'P') { |
| 590 |
select += '" disabled="disabled">'; |
| 591 |
selected = " selected='selected' "; |
| 592 |
value = 'P'; |
| 593 |
desc = 'In processing'; |
| 594 |
} else if (data == i && row.status == 'W'){ |
| 595 |
select += '" disabled="disabled">'; |
| 596 |
selected = " selected='selected' "; |
| 597 |
value = 'W'; |
| 598 |
desc = 'Waiting'; |
| 599 |
} else if (data == i && !row.status) { |
| 600 |
select += '">'; |
| 601 |
selected = " selected='selected' "; |
| 602 |
value = data; |
| 603 |
desc = data; |
| 604 |
} else { |
| 605 |
if (i != 0) { |
| 606 |
select += '">'; |
| 607 |
value = i; |
| 608 |
desc = i; |
| 609 |
} else { |
| 610 |
select += '">'; |
| 611 |
} |
| 612 |
} |
| 613 |
if (value) { |
| 614 |
select += '<option value="'+ value +'"'+selected+'>'+desc+'</option>'; |
| 615 |
} |
| 616 |
} |
| 617 |
}else { |
| 618 |
if (row.status == 'T') { |
| 619 |
select += '" disabled="disabled"><option value="T" selected="selected">In transit</option></select>'; |
| 620 |
} else if (row.status == 'P') { |
| 621 |
select += '" disabled="disabled"><option value="P" selected="selected">In processing</option></select>'; |
| 622 |
} else if (row.status == 'W') { |
| 623 |
select += '" disabled="disabled"><option value="W" selected="selected">Waiting</option></select>'; |
| 624 |
} else { |
| 625 |
if (HoldsSplitQueue !== "nothing" && HoldsSplitQueueNumbering === 'virtual') { |
| 626 |
let virtualPriority = pageStart + meta.row + 1; |
| 627 |
select += '" disabled="disabled"><option value="'+ data +'" selected="selected">'+ virtualPriority +'</option></select>'; |
| 628 |
} else { |
| 629 |
select += '" disabled="disabled"><option value="'+ data +'" selected="selected">'+ data +'</option></select>'; |
| 630 |
} |
| 631 |
} |
| 632 |
} |
| 633 |
select += '</select>'; |
| 634 |
return select; |
| 635 |
} |
| 636 |
}, |
| 637 |
{ |
| 638 |
data: "", |
| 639 |
orderable: false, |
| 640 |
searchable: false, |
| 641 |
render: function(data, type, row, meta) { |
| 642 |
if (row.status) { |
| 643 |
return null; |
| 644 |
} |
| 645 |
let buttons = '<a class="hold-arrow move-hold" title="Move hold up" href="#" data-move-hold="up" data-priority="'+row.priority+'" reserve_id="'+row.hold_id+'"><i class="fa fa-lg icon-move-hold-up" aria-hidden="true"></i></a>'; |
| 646 |
buttons += '<a class="hold-arrow move-hold" title="Move hold to top" href="#" data-move-hold="top" data-priority="'+row.priority+'" reserve_id="'+row.hold_id+'"><i class="fa fa-lg icon-move-hold-top" aria-hidden="true"></i></a>'; |
| 647 |
buttons += '<a class="hold-arrow move-hold" title="Move hold to bottom" href="#" data-move-hold="bottom" data-priority="'+row.priority+'" reserve_id="'+row.hold_id+'"><i class="fa fa-lg icon-move-hold-bottom" aria-hidden="true"></i></a>'; |
| 648 |
buttons += '<a class="hold-arrow move-hold" title="Move hold down" href="#" data-move-hold="down" data-priority="'+row.priority+'" reserve_id="'+row.hold_id+'"><i class="fa fa-lg icon-move-hold-down" aria-hidden="true"></i></a>'; |
| 649 |
return buttons; |
| 650 |
} |
| 651 |
}, |
| 652 |
{ |
| 653 |
data: "patron.cardnumber", |
| 654 |
orderable: false, |
| 655 |
searchable: true, |
| 656 |
render: function(data, type, row, meta) { |
| 657 |
if(data == null) { |
| 658 |
let library = libraries.find(library => library.library_id == row.pickup_library_id); |
| 659 |
return __("A patron from library %s").format(library.name); |
| 660 |
} else { |
| 661 |
return '<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber='+row.patron.patron_id+'">'+data+'</a>'; |
| 662 |
} |
| 663 |
} |
| 664 |
}, |
| 665 |
{ |
| 666 |
data: "notes", |
| 667 |
orderable: false, |
| 668 |
searchable: false, |
| 669 |
render: function(data, type, row, meta) { |
| 670 |
return data; |
| 671 |
} |
| 672 |
}, |
| 673 |
{ |
| 674 |
data: "hold_date", |
| 675 |
orderable: false, |
| 676 |
searchable: false, |
| 677 |
render: function(data, type, row, meta) { |
| 678 |
if (AllowHoldDateInFuture) { |
| 679 |
return '<input type="text" class="holddate" value="'+$date(data)+'" size="10" name="hold_date" data-id="'+row.hold_id+'" data-current-date="'+data+'"/>'; |
| 680 |
} else { |
| 681 |
return $date(data); |
| 682 |
} |
| 683 |
} |
| 684 |
}, |
| 685 |
{ |
| 686 |
data: "expiration_date", |
| 687 |
orderable: false, |
| 688 |
searchable: false, |
| 689 |
render: function(data, type, row, meta) { |
| 690 |
return '<input type="text" class="expirationdate" value="'+$date(data)+'" size="10" name="expiration_date" data-id="'+row.hold_id+'" data-current-date="'+data+'"/>'; |
| 691 |
} |
| 692 |
}, |
| 693 |
{ |
| 694 |
data: "pickup_library_id", |
| 695 |
orderable: false, |
| 696 |
searchable: false, |
| 697 |
render: function(data, type, row, meta) { |
| 698 |
var branchSelect='<select priority='+row.priority+' class="hold_location_select" data-id="'+row.hold_id+'" reserve_id="'+row.hold_id+'" name="pick-location" data-pickup-location-source="hold">'; |
| 699 |
var libraryname; |
| 700 |
for ( var i=0; i < libraries.length; i++ ){ |
| 701 |
var selectedbranch; |
| 702 |
var setbranch; |
| 703 |
if( libraries[i].library_id == data ){ |
| 704 |
selectedbranch = " selected='selected' "; |
| 705 |
setbranch = __(" (current) "); |
| 706 |
libraryname = libraries[i].name; |
| 707 |
} else if ( libraries[i].pickup_location == false ) { |
| 708 |
continue; |
| 709 |
} else{ |
| 710 |
selectedbranch = ''; |
| 711 |
setbranch = ''; |
| 712 |
} |
| 713 |
branchSelect += '<option value="'+ libraries[i].library_id.escapeHtml() +'"'+selectedbranch+'>'+libraries[i].name.escapeHtml()+setbranch+'</option>'; |
| 714 |
} |
| 715 |
branchSelect +='</select>'; |
| 716 |
if ( row.status == 'T' ) { |
| 717 |
return __("Item being transferred to <strong>%s</strong>").format(libraryname); |
| 718 |
} else if (row.status == 'P') { |
| 719 |
return __("Item being processed at <strong>%s</strong>").format(libraryname); |
| 720 |
} |
| 721 |
else if (row.status == 'W') { |
| 722 |
return __("Item waiting at <strong>%s</strong> since %s").format(libraryname, $date(row.waiting_date)); |
| 723 |
} else { |
| 724 |
return branchSelect; |
| 725 |
} |
| 726 |
} |
| 727 |
}, |
| 728 |
{ |
| 729 |
data: "item_id", |
| 730 |
orderable: false, |
| 731 |
searchable: false, |
| 732 |
render: function(data, type, row, meta) { |
| 733 |
let currentCell = $(table_id).DataTable().cells({"row":meta.row, "column":meta.col}).nodes(0); |
| 734 |
if (data) { |
| 735 |
$.ajax({ |
| 736 |
method: "GET", |
| 737 |
url: "/api/v1/items/"+data, |
| 738 |
success: function(res){ |
| 739 |
$(currentCell).html('<a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber='+biblio_id+'&itemnumber='+data+'">'+res.external_id+'</a>'); |
| 740 |
} |
| 741 |
}); |
| 742 |
return '<img src="/intranet-tmpl/prog/img/spinner-small.gif" alt="" /><span class="waiting_msg"></span></div>'; |
| 743 |
} else if (row.item_group_id) { |
| 744 |
$.ajax({ |
| 745 |
method: "GET", |
| 746 |
url: "/api/v1/biblios/"+biblio_id+"/item_groups/"+row.item_group_id, |
| 747 |
success: function(res){ |
| 748 |
$(currentCell).html(__("Next available item group <strong>%s</strong> item").format( res.description )); |
| 749 |
} |
| 750 |
}); |
| 751 |
return '<img src="/intranet-tmpl/prog/img/spinner-small.gif" alt="" /><span class="waiting_msg"></span></div>'; |
| 752 |
} else { |
| 753 |
if (row.non_priority) { |
| 754 |
return '<em>'+__("Next available")+'</em><br/><i>'+__("Non priority hold")+'</i>'; |
| 755 |
} else { |
| 756 |
return '<em>'+__("Next available")+'</em>'; |
| 757 |
} |
| 758 |
} |
| 759 |
} |
| 760 |
}, |
| 761 |
{ |
| 762 |
data: "", |
| 763 |
orderable: false, |
| 764 |
searchable: false, |
| 765 |
render: function(data, type, row, meta) { |
| 766 |
if (row.item_id) { |
| 767 |
return null |
| 768 |
} else { |
| 769 |
if(row.lowest_priority){ |
| 770 |
return '<a class="hold-arrow toggle-lowest-priority" title="Remove lowest priority" data-op="cud-setLowestPriority" data-borrowernumber="'+ row.patron_id +'" data-biblionumber="'+ biblio_id +'" data-reserve_id="'+ row.hold_id +'" data-date="'+ row.hold_date +'"><i class="fa fa-lg fa-rotate-90 icon-unset-lowest" aria-hidden="true"></i></a>'; |
| 771 |
} else { |
| 772 |
return '<a class="hold-arrow toggle-lowest-priority" title="Set lowest priority" data-op="cud-setLowestPriority" data-borrowernumber="'+ row.patron_id +'" data-biblionumber="'+ biblio_id +'" data-reserve_id="'+ row.hold_id +'" data-date="'+ row.hold_date +'"><i class="fa fa-lg fa-rotate-90 icon-set-lowest" aria-hidden="true"></i></a>'; |
| 773 |
} |
| 774 |
} |
| 775 |
} |
| 776 |
}, |
| 777 |
{ |
| 778 |
data: "hold_id", |
| 779 |
orderable: false, |
| 780 |
searchable: false, |
| 781 |
render: function(data, type, row, meta) { |
| 782 |
return '<a class="cancel-hold" title="Cancel hold" reserve_id="'+data+'"><i class="fa fa-trash text-danger" aria-label="Cancel hold"></i></a>'; |
| 783 |
} |
| 784 |
}, |
| 785 |
{ |
| 786 |
data: "hold_id", |
| 787 |
orderable: false, |
| 788 |
searchable: false, |
| 789 |
render: function(data, type, row, meta) { |
| 790 |
if (row.status) { |
| 791 |
var link_value = row.status == 'T' ? __("Revert transit status") : __("Revert waiting status"); |
| 792 |
return '<a class="btn btn-default submit-form-link" href="#" id="revert_hold_'+data+'" data-op="cud-move" data-where="down" data-first_priority="1" data-last_priority="'+ totalHolds +'" data-prev_priority="0" data-next_priority="1" data-borrowernumber="'+ row.patron_id +'" data-biblionumber="'+ biblio_id +'" data-itemnumber="'+ row.item_id +'" data-reserve_id="'+ row.hold_id +'" data-date="'+ row.hold_date +'" data-action="request.pl" data-method="post">'+ link_value +'</a>'; |
| 793 |
} else { |
| 794 |
let td = ''; |
| 795 |
if (SuspendHoldsIntranet) { |
| 796 |
td += '<button class="btn btn-default btn-xs toggle-suspend" data-id="'+data+'" data-biblionumber="'+biblio_id+'" data-suspended="'+row.suspended+'">' |
| 797 |
if ( row.suspended ) { |
| 798 |
td += '<i class="fa fa-play" aria-hidden="true"></i> '+__("Resume")+'</button>'; |
| 799 |
} else { |
| 800 |
td += '<i class="fa fa-pause" aria-hidden="true"></i> '+__("Suspend")+'</button>'; |
| 801 |
} |
| 802 |
if (AutoResumeSuspendedHolds) { |
| 803 |
if (row.suspended) { |
| 804 |
td += '<label for="suspend_until_'+data+'">'+__("Suspend on")+' </label>'; |
| 805 |
} else { |
| 806 |
td += '<label for="suspend_until_'+data+'">'+__("Suspend until")+' </label>'; |
| 807 |
} |
| 808 |
td += '<input type="text" name="suspend_until_'+data+'" data-id="'+data+'" size="10" value="'+$date(row.suspended_until)+'" class="suspenddate" data-flatpickr-futuredate="true" data-current-date="'+row.suspended_until+'" />'; |
| 809 |
} |
| 810 |
return td; |
| 811 |
} else { |
| 812 |
return null; |
| 813 |
} |
| 814 |
} |
| 815 |
} |
| 816 |
}, |
| 817 |
{ |
| 818 |
data: "hold_id", |
| 819 |
orderable: false, |
| 820 |
searchable: false, |
| 821 |
render: function(data, type, row, meta) { |
| 822 |
return '<a class="btn btn-default btn-xs printholdslip" data-reserve_id="'+data+'">'+__("Print slip")+'</a>'; |
| 823 |
} |
| 824 |
}, |
| 825 |
] |
| 826 |
},hold_table_settings); |
| 827 |
$(table_id).on( 'draw.dt', function () { |
| 828 |
// Remove the search box. Don't know why it isn't working in the table settings |
| 829 |
$(this).parent().find(".dataTables_filter, .dt_button_clear_filter").remove(); |
| 830 |
let multiselect = false; |
| 831 |
var MSG_CANCEL_SELECTED = _("Cancel selected (%s)"); |
| 832 |
$('.cancel_selected_holds').html(MSG_CANCEL_SELECTED.format($('.holds_table .select_hold:checked').length)); |
| 833 |
$('.holds_table .select_hold').each(function() { |
| 834 |
if(localStorage.selectedHolds && localStorage.selectedHolds.includes($(this).data('id'))) { |
| 835 |
$(this).prop('checked', true); |
| 836 |
} |
| 837 |
}); |
| 838 |
$('.holds_table .select_hold_all').on("click",function() { |
| 839 |
var table = $(this).parents('.holds_table'); |
| 840 |
var count = $('.select_hold:checked', table).length; |
| 841 |
$('.select_hold', table).prop('checked', !count); |
| 842 |
$(this).prop('checked', !count); |
| 843 |
$(this).parent().parent().toggleClass('selected'); |
| 844 |
$('.cancel_selected_holds').html(MSG_CANCEL_SELECTED.format($('.holds_table .select_hold:checked').length)); |
| 845 |
localStorage.selectedHolds = $('.holds_table .select_hold:checked').toArray().map(el => $(el).data('id')); |
| 846 |
multiselect = true; |
| 847 |
|
| 848 |
}); |
| 849 |
$('.holds_table .select_hold').on("click", function() { |
| 850 |
var table = $(this).parents('.holds_table'); |
| 851 |
var count = $('.select_hold:not(:checked)', table).length; |
| 852 |
$('.select_hold_all', table).prop('checked', !count); |
| 853 |
$(this).parent().parent().toggleClass('selected'); |
| 854 |
$('.cancel_selected_holds').html(MSG_CANCEL_SELECTED.format($('.holds_table .select_hold:checked').length)); |
| 855 |
localStorage.selectedHolds = $('.holds_table .select_hold:checked').toArray().map(el => $(el).data('id')); |
| 856 |
multiselect = true; |
| 857 |
}); |
| 858 |
$(".cancel-hold").on("click",function(e) { |
| 859 |
e.preventDefault; |
| 860 |
var res_id = $(this).attr('reserve_id'); |
| 861 |
$('.select_hold').prop('checked', false); |
| 862 |
$('.select_hold_all').prop('checked', false); |
| 863 |
$('.cancel_selected_holds').html(MSG_CANCEL_SELECTED.format(0)); |
| 864 |
$('#cancelModal').modal('show').find('#cancelModalConfirmBtn').attr("data-id", res_id); |
| 865 |
delete localStorage.selectedHolds; |
| 866 |
}); |
| 867 |
$('.cancel_selected_holds').on("click", function(e) { |
| 868 |
e.preventDefault(); |
| 869 |
if($('.holds_table .select_hold:checked').length) { |
| 870 |
delete localStorage.selectedHolds; |
| 871 |
$('#cancelModal').modal('show'); |
| 872 |
} |
| 873 |
return false; |
| 874 |
}); |
| 875 |
$("#cancelModalConfirmBtn").one("click",function(e) { |
| 876 |
e.preventDefault(); |
| 877 |
let hold_ids; |
| 878 |
const hold_id = $('#cancelModal').modal('show').find('#cancelModalConfirmBtn').attr("data-id"); |
| 879 |
let reason = $("#modal-cancellation-reason").val(); |
| 880 |
if (hold_id) { |
| 881 |
hold_ids = [hold_id]; |
| 882 |
} else { |
| 883 |
hold_ids = $('.holds_table .select_hold:checked').toArray().map(el => $(el).data('id')); |
| 884 |
} |
| 885 |
$('#cancelModal').find('.modal-footer #cancelModalConfirmBtn').before('<img src="/intranet-tmpl/prog/img/spinner-small.gif" alt="" style="padding-right: 10px;"/>'); |
| 886 |
deleteHolds(hold_ids, reason); |
| 887 |
$('#cancelModal').modal('show').find('#cancelModalConfirmBtn').attr("data-id", ""); |
| 888 |
|
| 889 |
}); |
| 890 |
async function deleteHolds (hold_ids, reason) { |
| 891 |
for (const hold_id of hold_ids) { |
| 892 |
await deleteHold(hold_id, reason); |
| 893 |
$('#cancelModal').find('.modal-body').append('<p class="hold-cancelled">'+__("Hold")+' '+hold_id+' '+__("cancelled")+'</p>'); |
| 894 |
await new Promise(resolve => setTimeout(resolve, 1000)); |
| 895 |
} |
| 896 |
holdsQueueTable.api().ajax.reload(null, false); |
| 897 |
setTimeout(() => { |
| 898 |
$('#cancelModal').modal('hide'); |
| 899 |
$('#cancelModal').find('.modal-footer #cancelModalConfirmBtn').prev('img').remove(); |
| 900 |
$('#cancelModal').find('.modal-body').find('.hold-cancelled').remove(); |
| 901 |
}); |
| 902 |
} |
| 903 |
async function deleteHold(hold_id, reason) { |
| 904 |
try { |
| 905 |
await $.ajax({ |
| 906 |
method: "DELETE", |
| 907 |
url: '/api/v1/holds/' + encodeURIComponent(hold_id), |
| 908 |
data: JSON.stringify(reason), |
| 909 |
}); |
| 910 |
} catch (error) { |
| 911 |
console.error("Error when deleting hold: " + hold_id); |
| 912 |
} |
| 913 |
} |
| 914 |
$(".holddate, .expirationdate").flatpickr({ |
| 915 |
dateFormat: flatpickr_dateformat_string, |
| 916 |
onChange: function (selectedDates, dateStr, instance){ |
| 917 |
let hold_id = $(instance.input).attr('data-id'); |
| 918 |
let fieldname = $(instance.input).attr('name'); |
| 919 |
let current_date = $(instance.input).attr('data-current-date'); |
| 920 |
const date = new Date(selectedDates); |
| 921 |
const year = date.getFullYear(); |
| 922 |
const month = String(date.getMonth() + 1).padStart(2, '0'); |
| 923 |
const day = String(date.getDate()).padStart(2, '0'); |
| 924 |
let newdate; |
| 925 |
if (year && month && day) { |
| 926 |
newdate = [year, month, day].join('-'); |
| 927 |
} |
| 928 |
multiChange[hold_id] = fieldname == "hold_date" ? {"hold_date": newdate} : { "expiration_date": dateStr }; |
| 929 |
let req = fieldname == "hold_date" ? { "hold_date": newdate } : { "expiration_date": newdate }; |
| 930 |
if (current_date != newdate && !multiselect) { |
| 931 |
$.ajax({ |
| 932 |
method: "PATCH", |
| 933 |
url: '/api/v1/holds/' + encodeURIComponent(hold_id), |
| 934 |
contentType: 'application/json', |
| 935 |
data: JSON.stringify(req), |
| 936 |
success: function( data ){ holdsQueueTable.api().ajax.reload(null, false); }, |
| 937 |
error: function( jqXHR, textStatus, errorThrown) { |
| 938 |
holdsQueueTable.api().ajax.reload(null, false); |
| 939 |
}, |
| 940 |
}); |
| 941 |
} |
| 942 |
} |
| 943 |
}); |
| 944 |
$(".suspenddate").flatpickr({ |
| 945 |
dateFormat: flatpickr_dateformat_string, |
| 946 |
onChange: function (selectedDates, dateStr, instance){ |
| 947 |
let hold_id = $(instance.input).data('id'); |
| 948 |
let current_date = $(instance.input).attr('data-current-date'); |
| 949 |
const date = new Date(selectedDates); |
| 950 |
const year = date.getFullYear(); |
| 951 |
const month = String(date.getMonth() + 1).padStart(2, '0'); |
| 952 |
const day = String(date.getDate()).padStart(2, '0'); |
| 953 |
const newdate = [year, month, day].join('-'); |
| 954 |
const method = dateStr ? 'POST' : 'DELETE'; |
| 955 |
multiChange[hold_id] = {suspended_until: dateStr}; |
| 956 |
if (current_date != newdate && !multiselect) { |
| 957 |
$.ajax({ |
| 958 |
method: method, |
| 959 |
url: '/api/v1/holds/' + encodeURIComponent(hold_id) +'/suspension', |
| 960 |
contentType: 'application/json', |
| 961 |
data: JSON.stringify({ "end_date": newdate }), |
| 962 |
success: function( data ){ holdsQueueTable.api().ajax.reload(null, false); }, |
| 963 |
error: function( jqXHR, textStatus, errorThrown) { |
| 964 |
holdsQueueTable.api().ajax.reload(null, false); |
| 965 |
}, |
| 966 |
}); |
| 967 |
} |
| 968 |
} |
| 969 |
}); |
| 970 |
$(".toggle-suspend").one("click",function(e) { |
| 971 |
e.preventDefault(); |
| 972 |
const hold_id = $(this).data('id'); |
| 973 |
const suspended = $(this).attr('data-suspended'); |
| 974 |
const method = suspended == 'true' ? 'DELETE' : 'POST'; |
| 975 |
if (!multiselect) { |
| 976 |
$.ajax({ |
| 977 |
method: method, |
| 978 |
url: '/api/v1/holds/' + encodeURIComponent(hold_id) +'/suspension', |
| 979 |
success: function( data ){ holdsQueueTable.api().ajax.reload(null, false); }, |
| 980 |
error: function( jqXHR, textStatus, errorThrown) { |
| 981 |
holdsQueueTable.api().ajax.reload(null, false); |
| 982 |
alert('There was an error:'+textStatus+" "+errorThrown); |
| 983 |
}, |
| 984 |
}); |
| 985 |
} |
| 986 |
}); |
| 987 |
$(".rank-request").on("change", function(e){ |
| 988 |
e.preventDefault(); |
| 989 |
const hold_id = $(this).data('id'); |
| 990 |
let priority = e.target.value; |
| 991 |
multiChange[hold_id] = {priority: priority}; |
| 992 |
if (!multiselect) { |
| 993 |
$.ajax({ |
| 994 |
method: "PUT", |
| 995 |
url: '/api/v1/holds/' + encodeURIComponent(hold_id) +'/priority', |
| 996 |
data: JSON.stringify(priority), |
| 997 |
success: function( data ){ holdsQueueTable.api().ajax.reload(null, false); }, |
| 998 |
error: function( jqXHR, textStatus, errorThrown) { |
| 999 |
alert('There was an error:'+textStatus+" "+errorThrown); |
| 1000 |
}, |
| 1001 |
}); |
| 1002 |
} |
| 1003 |
}); |
| 1004 |
$(".move-hold").one("click", function(e){ |
| 1005 |
e.preventDefault(); |
| 1006 |
let toPosition = $(this).attr('data-move-hold'); |
| 1007 |
let priority = $(this).attr('data-priority'); |
| 1008 |
var res_id = $(this).attr('reserve_id'); |
| 1009 |
var moveTo; |
| 1010 |
if (toPosition == 'up'){ |
| 1011 |
moveTo = parseInt(priority)-1; |
| 1012 |
} |
| 1013 |
if (toPosition == 'down'){ |
| 1014 |
moveTo = parseInt(priority)+1; |
| 1015 |
} |
| 1016 |
if (toPosition == 'top'){ |
| 1017 |
moveTo = 1; |
| 1018 |
} |
| 1019 |
if (toPosition == 'bottom'){ |
| 1020 |
moveTo = totalHolds; |
| 1021 |
} |
| 1022 |
if (!multiselect) { |
| 1023 |
$.ajax({ |
| 1024 |
method: "PUT", |
| 1025 |
url: '/api/v1/holds/' + encodeURIComponent(res_id) +'/priority', |
| 1026 |
data: JSON.stringify(moveTo), |
| 1027 |
success: function( data ){ |
| 1028 |
holdsQueueTable.api().ajax.reload(null, false); |
| 1029 |
}, |
| 1030 |
error: function( jqXHR, textStatus, errorThrown) { |
| 1031 |
alert('There was an error:'+textStatus+" "+errorThrown); |
| 1032 |
}, |
| 1033 |
}); |
| 1034 |
} |
| 1035 |
}); |
| 1036 |
$(".toggle-lowest-priority").one("click", function(e){ |
| 1037 |
e.preventDefault(); |
| 1038 |
var res_id = $(this).attr('data-reserve_id'); |
| 1039 |
$.ajax({ |
| 1040 |
method: "PUT", |
| 1041 |
url: '/api/v1/holds/' + encodeURIComponent(res_id) +'/lowest_priority', |
| 1042 |
success: function( data ){ holdsQueueTable.api().ajax.reload(null, false); }, |
| 1043 |
error: function( jqXHR, textStatus, errorThrown) { |
| 1044 |
alert('There was an error:'+textStatus+" "+errorThrown); |
| 1045 |
}, |
| 1046 |
}); |
| 1047 |
}); |
| 1048 |
$(".hold_location_select").on("change", function(){ |
| 1049 |
$(this).prop("disabled",true); |
| 1050 |
var cur_select = $(this); |
| 1051 |
var res_id = $(this).attr('reserve_id'); |
| 1052 |
multiChange[res_id] = {pickup_library_id: $(this).val()}; |
| 1053 |
if (!multiselect) { |
| 1054 |
$(this).after('<div id="updating_reserveno'+res_id+'" class="waiting"><img src="/intranet-tmpl/prog/img/spinner-small.gif" alt="" /><span class="waiting_msg"></span></div>'); |
| 1055 |
let api_url = '/api/v1/holds/' + encodeURIComponent(res_id) + '/pickup_location'; |
| 1056 |
$.ajax({ |
| 1057 |
method: "PUT", |
| 1058 |
url: api_url, |
| 1059 |
data: JSON.stringify({ "pickup_library_id": $(this).val() }), |
| 1060 |
headers: { "x-koha-override": "any" }, |
| 1061 |
success: function( data ){ holdsQueueTable.api().ajax.reload(null, false); }, |
| 1062 |
error: function( jqXHR, textStatus, errorThrown) { |
| 1063 |
alert('There was an error:'+textStatus+" "+errorThrown); |
| 1064 |
cur_select.prop("disabled",false); |
| 1065 |
$("#updating_reserveno"+res_id).remove(); |
| 1066 |
cur_select.val( cur_select.children('option[selected="selected"]').val() ); |
| 1067 |
}, |
| 1068 |
}); |
| 1069 |
} |
| 1070 |
}); |
| 1071 |
$('.printholdslip').one('click', function(){ |
| 1072 |
var reserve_id = $(this).attr('data-reserve_id'); |
| 1073 |
window.open("/cgi-bin/koha/circ/hold-transfer-slip.pl?reserve_id=" + reserve_id); |
| 1074 |
return false; |
| 1075 |
}); |
| 1076 |
}); |
| 1077 |
|
| 1078 |
$('.update_selected_holds').on('click', function (e) { |
| 1079 |
const data = [] |
| 1080 |
holdsQueueTable.api().rows('.selected').every(function (index, element) { |
| 1081 |
data.push(this.data()); |
| 1082 |
}); |
| 1083 |
fieldNames = { |
| 1084 |
hold_id: 'reserve_id', |
| 1085 |
hold_date: 'reservedate', |
| 1086 |
pickup_library_id: 'pickup', |
| 1087 |
item_id: 'itemnumber', |
| 1088 |
expiration_date: 'expirationdate', |
| 1089 |
suspended_until: 'suspend_until', |
| 1090 |
priority: 'rank-request', |
| 1091 |
}; |
| 1092 |
let biblionumberInput = $("<input>").attr({ |
| 1093 |
type: "hidden", |
| 1094 |
name: "biblionumber", |
| 1095 |
value: biblio_id |
| 1096 |
}); |
| 1097 |
$("#existing_holds").append(biblionumberInput); |
| 1098 |
data.forEach((row) => { |
| 1099 |
Object.keys(row).forEach((key) => { |
| 1100 |
let update = multiChange[row.hold_id]; |
| 1101 |
if (update && update[key]) { |
| 1102 |
row[key] = update[key]; |
| 1103 |
} |
| 1104 |
if (fieldNames[key] && row[key] != null) { |
| 1105 |
let input = $("<input>").attr({ |
| 1106 |
type: "hidden", |
| 1107 |
name: fieldNames[key], |
| 1108 |
value: row[key] |
| 1109 |
}); |
| 1110 |
$("#existing_holds").append(input); |
| 1111 |
} |
| 1112 |
}); |
| 1113 |
}); |
| 1114 |
}); |
| 1115 |
} |