QUICK Slip
<head>
<link href="https://fonts.googleapis.com/css2?family=Libre+Barcode+39&display=swap" rel="stylesheet" />
<style>
@page {
size: 5in auto; /* Increased page width */
margin: 0.5in 0.3in 0.3in 0.3in;
}
body {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
}
.right-side {
width: 100%;
max-width: 420px;
margin-left: auto;
font-weight: bold; /* All text bold by default */
font-size: 22px; /* Larger text */
}
table {
width: 100%;
border-collapse: collapse;
table-layout: fixed;
min-width: 400px;
}
td:first-child {
width: 55%;
text-align: left;
white-space: normal;
overflow: visible;
padding: 4px 8px 4px 32px; /* Shift left text 4 spaces (approx) */
}
td:last-child {
width: 45%;
text-align: right;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 4px 8px;
}
tr.fax-row td:last-child {
white-space: normal;
overflow-wrap: break-word;
max-width: 100%;
padding-top: 8px;
padding-bottom: 8px;
font-size: 20px;
}
tr.firstname-row td:last-child {
padding: 0;
width: 45%;
white-space: nowrap;
}
.barcode-container {
width: 100%;
text-align: center;
margin-top: 15px;
}
.barcode {
font-family: 'Libre Barcode 39', monospace;
font-size: 40px;
letter-spacing: 3px;
white-space: nowrap;
display: inline-block;
max-width: 100%;
overflow: visible;
}
/* Sort2 outside the table, normal weight */
.sort2-container {
width: 100%;
font-size: 20px;
text-align: left;
padding: 5px 0 0 8px;
font-weight: normal; /* not bold */
}
</style>
</head>
<body>
<div class="right-side">
<table>
<tr>
<td></td>
<td>[% borrower.phone %]</td>
</tr>
<tr>
<td><span style="font-weight: bold;">[% borrower.cardnumber %]</span></td>
<td>[% borrower.mobile %]</td>
</tr>
<tr>
<td>[% borrower.categorycode %]</td>
<td><span id="formatted_date">[% borrower.dateexpiry %]</span></td>
</tr>
<!-- Firstname row -->
<tr class="firstname-row">
<td>[% borrower.firstname %]</td>
<td>[% borrower.fax %]</td>
</tr>
</table>
<!-- Sort2 below table -->
<div class="sort2-container">[% borrower.sort2 %]</div>
<!-- Barcode -->
<div class="barcode-container">
<span class="barcode">*[% borrower.cardnumber %]*</span>
</div>
</div>
<script>
const dateCell = document.getElementById("formatted_date");
const rawDate = dateCell.innerText.trim();
const dateObj = new Date(rawDate);
if (!isNaN(dateObj)) {
const day = String(dateObj.getDate()).padStart(2, '0');
const month = String(dateObj.getMonth() + 1).padStart(2, '0');
const year = dateObj.getFullYear();
dateCell.innerText = `${day}/${month}/${year}`;
}
</script>
</body>
Issue Slip
<h3 style="text-align:center;">Punjab University Library</h3>
<p><strong>Patron ID:</strong> [% borrower.cardnumber %]</p>
<h4>📚 Books Issued Today</h4>
<div id="issuedToday"></div>
<p><strong>Total Book(s) Issued Today:</strong> <span id="issuedCount">0</span></p>
<p><strong>Staff Username:</strong> [% loggedinusername %]</p>
<!-- Hidden raw data -->
<div id="allBooks" style="display:none;">
[% FOREACH checkout IN checkouts %]
<div class="book"
data-issuedate="[% checkout.issuedate %]"
data-barcode="[% checkout.item.barcode %]"
data-duedate="[% checkout.date_due %]">
</div>
[% END %]
</div>
<script>
window.onload = function () {
const allBooks = document.querySelectorAll("#allBooks .book");
const issuedTodayContainer = document.getElementById("issuedToday");
// Today's date in Koha format (YYYY-MM-DD)
const today = new Date();
const yyyy = today.getFullYear();
const mm = String(today.getMonth() + 1).padStart(2, '0');
const dd = String(today.getDate()).padStart(2, '0');
const todayStr = `${yyyy}-${mm}-${dd}`;
let todayCount = 0;
allBooks.forEach(book => {
const issuedDate = (book.getAttribute("data-issuedate") || "").trim().split(" ")[0];
const barcode = book.getAttribute("data-barcode");
const dueDate = book.getAttribute("data-duedate");
if (issuedDate === todayStr) {
todayCount++;
const entry = document.createElement("div");
entry.textContent = `${todayCount}) Barcode: ${barcode}, Issued: ${issuedDate}, Due: ${dueDate}`;
issuedTodayContainer.appendChild(entry);
}
});
document.getElementById("issuedCount").textContent = todayCount;
};
</script>
IntranetUserJS
$(document).ready(function () {
// Only run this code on the returns page
if (window.location.pathname.includes("/cgi-bin/koha/circ/returns.pl")) {
let returnedBooks = [];
let previousRows = 0;
// Monitor the table of returned books every second
setInterval(function () {
let rows = $(".checkedin");
if (rows.length > previousRows) {
rows.slice(previousRows).each(function () {
let barcode = $(this).find(".barcode").text().trim();
let issued = $(this).find(".issuedate").text().trim();
if (barcode && issued) {
returnedBooks.push(`${barcode} – ${issued}`);
}
});
previousRows = rows.length;
}
}, 1000);
// Detect double Enter key press in #barcode field
let enterCount = 0;
let enterTimer = null;
$("#barcode").on("keydown", function (e) {
if (e.key === "Enter") {
enterCount++;
if (enterCount === 2) {
if (returnedBooks.length > 0) {
alert("📚 Returned Books:\n\n" + returnedBooks.join("\n"));
returnedBooks = [];
previousRows = $(".checkedin").length;
} else {
alert("⚠️ No returned books found.");
}
clearTimeout(enterTimer);
enterCount = 0;
} else {
enterTimer = setTimeout(function () {
enterCount = 0;
}, 2000); // Reset after 2 seconds
}
}
});
return; // Don't load any other code
}
// Your existing circulation (issuance) script
if (!window.location.pathname.includes("/cgi-bin/koha/circ/circulation.pl")) return;
$("a[href$='frameworkcode=']").hide();
$("#Frameworks option[value=Default]").hide();
$('li.z3950searchFw:first').hide();
function blockIssuance() {
$("#checkout_form").hide();
$(".checkout").hide();
$("#circ_submit").prop("disabled", true);
}
let categoryCodeMatch = $("li:contains('Category')").text().match(/\(([^)]+)\)/);
if (categoryCodeMatch) {
let categoryCode = categoryCodeMatch[1];
if (categoryCode === "W") {
alert("⚠️ Office Copy Required! Book issuance is blocked until the category is changed.");
blockIssuance();
} else if (categoryCode === "V") {
alert("🚫 Clearance Taken! This patron cannot be issued any books.");
blockIssuance();
}
if (categoryCode === "B" || categoryCode === "C") {
let blocked = false;
const today = new Date();
$("table#issues-table tbody tr").each(function () {
let dueDateText = $(this).find("td").eq(3).text().trim();
let dueDateParts = dueDateText.split("/");
if (dueDateParts.length === 3) {
let dueDate = new Date(`${dueDateParts[2]}-${dueDateParts[1]}-${dueDateParts[0]}`);
let diffDays = Math.floor((today - dueDate) / (1000 * 60 * 60 * 24));
if (diffDays > 30) {
blocked = true;
return false;
}
}
});
if (blocked) {
alert("⛔ This patron has book(s) overdue by more than 30 days. Further issuance is not allowed.");
blockIssuance();
}
}
}
});
No comments:
Post a Comment