04 August 2025

Customizing Overdue Fine Calculations in Koha: A Detailed Guide

Customizing Overdue Fine Calculations in Koha: A Detailed Guide

Customizing Overdue Fine Calculations in Koha: A Detailed Guide

Here’s a more detailed guide on how to modify the overdue.pm file in Koha step by step, including navigating the filesystem, editing the code, and testing the changes.

Step-by-Step Detailed Guide

Step 1: Access the Koha Server

To make changes to the Koha installation, you first need to access the server where Koha is hosted. You can use SSH to log in to the server.

ssh skysivan@koha_server_ip (10.21.1.10)
    
  • Replace username with your actual username (often sky or koha or root).
  • Replace koha_server_ip 10.21.1.10 with the IP address or hostname of the Koha server.

Once logged in, you’ll be in the server's home directory or wherever the default shell points.

Step 2: Navigate to the Koha Directory

Koha is installed under /usr/share/koha, but the overdue.pm file is in a subdirectory. To navigate to this directory, run the following command:

cd /usr/share/koha/lib/C4/
    

Here’s what’s happening:

  • /usr/share/koha/: Main directory for Koha installation.
  • lib/: Contains all the Perl library files for Koha.
  • C4/: Contains C4 modules, which handle core functionalities, including overdue and fines.

If you want to list the contents of this directory to check if overdue.pm exists, run:

sudo ls /usr/share/koha/lib/C4/
    

You should see something like this (the output will vary based on your Koha version and installed modules):

C4.pm              Overdue.pm          ...
    

If overdue.pm is listed here, you're in the right place.

Step 3: Open the overdue.pm File for Editing

Next, open the overdue.pm file in a text editor. You can use nano for simplicity or vim if you're more comfortable with it.

sudo nano /usr/share/koha/lib/C4/Overdue.pm
    
  • sudo: Runs the command as the root user (if required).
  • nano: The text editor.
  • /usr/share/koha/lib/C4/Overdue.pm: Full path to the file.

Once opened, you can start navigating through the code.

Step 4: Locate Line 350 in the File

You need to find the line in the code where the fine amount is calculated. According to your original question, the target line is:

$amount = $charge_periods * $issuing_rule->{fine};
    

To quickly find line 350, press Ctrl + _ in nano (this opens the "go to line" prompt), and type 350, then press Enter.

If you can’t locate line 350 directly, you can also scroll through the file and look for the section that calculates fines.

Step 5: Replace the Fine Calculation Logic

Once you’ve located the line, replace it with the new fine calculation logic as per your requirements. Here's the code to replace:

if ($charge_periods <= 15) {
    $amount = $charge_periods * 1;
} elsif ($charge_periods > 15 && $charge_periods <= 30) {
    $amount = 15 + ($charge_periods - 15) * 2;
} else {
    $amount = 45 + ($charge_periods - 30) * 5;
}
    

Explanation:

  • First condition ($charge_periods <= 15): If the charge_periods is less than or equal to 15, the fine is simply $charge_periods * 1 (i.e., 1 unit per day overdue).
  • Second condition ($charge_periods > 15 && $charge_periods <= 30): If the charge_periods is greater than 15 but less than or equal to 30, the fine is calculated as \$15 for the first 15 days, plus \$2 for each additional day over 15 days.
  • Third condition ($charge_periods > 30): If the charge_periods exceeds 30 days, the fine is calculated as \$45 for the first 30 days, plus \$5 for each additional day over 30.

Step 6: Save and Exit the File

After making the changes, save and close the file.

In nano:

  • Press Ctrl + X to exit.
  • When asked to save the changes, press Y for "Yes".
  • Press Enter to confirm the filename and save the file.

If you're using vim, press Esc, then type :wq and press Enter to save and quit.

Step 7: Test the Changes

Now, it’s time to test your modifications. You’ll need to test whether the fine calculation is working as expected after the code change.

Test Methods:

  1. Direct Test in Koha: If you have access to Koha’s web interface, simulate overdue loans of various periods (e.g., 10, 20, 40 days) and check that the fine amounts appear as expected based on the rules you defined.
  2. Use Koha's Testing Functionality: You can create custom test cases that simulate overdue books and calculate fines.

Example test:

my $charge_periods = 10;
my $issuing_rule = { fine => 1 };
my $amount = 0;

if ($charge_periods <= 15) {
    $amount = $charge_periods * 1;
} elsif ($charge_periods > 15 && $charge_periods <= 30) {
    $amount = 15 + ($charge_periods - 15) * 2;
} else {
    $amount = 45 + ($charge_periods - 30) * 5;
}

print "Fine: $amount\n";
    

Step 8: Check for Errors

If something went wrong, Koha should log the errors. To view them in real-time, run the following command:

sudo tail -f /var/log/koha/koha-error_log
    

Step 9: Verify the Changes in Production

Once you have confirmed everything works in the test environment, you can move forward with the changes on the production server. If you're using version control (e.g., Git), commit your changes:

git add /usr/share/koha/lib/C4/Overdue.pm
git commit -m "Modified fine calculation logic based on charge periods"
git push
    

Step 10: Optional – Restart Koha Services

Sometimes, after making code changes, you may need to restart Koha services to apply the changes. To do this, use the following command:

sudo systemctl restart koha-common
    

Conclusion

You’ve now modified the fine calculation logic in Koha. To summarize:

  1. You located the overdue.pm file.
  2. You replaced the fine calculation code with the new rules.
  3. You tested the changes in a test environment.
  4. Finally, you verified the code and restarted the services.

Let me know if you need any further details or assistance with testing!

29 June 2025

Acquisitions module in Koha, designed for new users

Acquisitions module in Koha, designed for new users 


๐Ÿ›’ Koha Acquisitions Module – Step-by-Step Guide

The Acquisitions module in Koha helps you manage vendors, budgets, ordering, receiving, and invoicing of library materials efficiently.

๐Ÿ”น Step 1: Set Up Budgets and Funds

Before placing any order, define your financial structure.

➤ Go to: Acquisitions → Budgets

  1. Click "New Budget".

  2. Enter a budget name (e.g., 2024-2025), start and end date.

  3. Click "Save".

  4. Inside the budget, click "New Fund".

    • Name it (e.g., Books, Journals).

    • Assign a percentage or amount.

    • Link to a branch if needed.

๐Ÿ”น Step 2: Add a Vendor (Bookseller/Distributor)

You must add vendors to create purchase orders.

➤ Go to: Acquisitions → Vendors → New Vendor

  1. Enter:

    • Vendor name (e.g., "ABC Books Ltd")

    • Contact info, addresses, account number.

  2. Click "Save".

๐Ÿ”น Step 3: Create a Basket (Purchase Order)

Baskets are containers for orders under a vendor.

➤ Go to: Acquisitions → Vendor Name → New Basket

  1. Add a basket name (e.g., June Order).

  2. Add a billing/shipping place.

  3. Assign a contract (optional).

  4. Click "Save".

๐Ÿ”น Step 4: Add Items to the Basket

You can order from existing catalog records or create new ones.

➤ Inside the basket:

  1. Click "Add to basket" → From existing record or "From new (brief) record".

  2. Fill in:

    • Title, Author, ISBN.

    • Quantity ordered, budget code, price, GST (if applicable).

  3. Click "Save".

  4. Repeat for multiple titles if needed.

๐Ÿ”น Step 5: Close the Basket

Once your order is complete:

  1. Click "Close this basket".

  2. Optionally, print the order (PDF) or email to the vendor.

๐Ÿ”น Step 6: Receive Ordered Items

When the items arrive:

➤ Go to: Acquisitions → Vendor → Basket → Receive shipment

  1. Enter invoice number, shipment date.

  2. Click "Receive" next to each title.

  3. Add barcode, item location, call number, etc.

  4. Click "Save".

๐Ÿ”น Step 7: Invoice and Finalize

After receiving:

  1. Go to the invoice attached to the basket.

  2. Confirm unit prices, shipping charges, and GST.

  3. Save the invoice to complete the order cycle.

๐Ÿ“ Optional Features:

  • EDIFACT support for vendor communication.

  • Late order tracking and cancellation.

  • Reports: Order status, budget usage, invoice summaries.

✅ Summary Workflow

  1. Create Budget → 2. Add Vendor → 3. Open Basket
    → 4. Add Titles to Basket → 5. Close Basket
    → 6. Receive Items → 7. Add Invoice

Enable Amazon Cover Images in Koha

Enable Amazon Cover Images in Koha

๐Ÿ› ️ 1. Enable Amazon Cover Image in Koha System Preferences

Path:
Koha Administration → System Preferences → Enhanced content

  1. Go to your Koha staff interface.

  2. Navigate to:

    Administration > Global system preferences > Enhanced Content
    
  3. Set the following preferences:

Preference Value
AmazonCoverImages Enable
AmazonAssocTag Your Amazon associate tag (optional)
AmazonDevKey (deprecated - leave blank)

๐Ÿ“Œ Note: As of 2020, Amazon discontinued support for public API access to Product Advertising unless you are approved. So cover images from Amazon may no longer work unless you're using an Amazon Product Advertising API v5 account. Otherwise, use alternative sources like OpenLibrary or Google Books.

๐Ÿ–ผ️ 2. Confirm Cover Images are Enabled Globally

Still in Enhanced Content system preferences:

  • Ensure OPACXSLTResultsDisplay and OPACXSLTDetailsDisplay are configured to show images.

  • If you use XSLT views, make sure they’re not customized to exclude images.

๐Ÿ“‚ 3. Display Priority: Amazon, OpenLibrary, or Google?

Koha checks multiple sources in order. If Amazon is enabled, it may try that first. You can prioritize other sources (like OpenLibrary) in:

Administration → Global System Preferences → Enhanced content

Check these:

  • OpenLibraryCovers: Enable

  • GoogleJackets: Enable


๐Ÿงช 4. Test Display

  1. Go to the OPAC or staff catalog.

  2. Search for a book by ISBN.

  3. If the cover image is available from Amazon (or others), it will show next to the record.

⚠️ Notes & Tips

  • Amazon Dev Key (API access) is now restricted. You need an approved affiliate account and actual usage/sales.

  • If you don’t have Amazon access, use:

    • OpenLibraryCovers

    • GoogleJackets

  • ISBN is critical for cover retrieval – ensure your records have valid ISBNs.

๐Ÿ› ️ Bonus: Customize Display via XSLT

If you're using XSLT-based templates for results/details display:

  1. Go to:

    /usr/share/koha/intranet/htdocs/intranet-tmpl/prog/en/xslt/
    
  2. Edit files:

    • MARC21slim2OPACResults.xsl

    • MARC21slim2OPACDetail.xsl

Ensure these have the logic to include:

<xsl:if test="isbn">
  <img src="https://images-na.ssl-images-amazon.com/images/P/{$isbn}.01.MZZZZZZZ.jpg" alt="Cover image" />
</xsl:if>

๐Ÿ“Œ But Koha usually injects these automatically unless you've overwritten XSLTs.

✅ Conclusion

To display Amazon cover images in Koha:

  • Enable AmazonCoverImages in system preferences

  • (Optionally) provide your AmazonAssocTag

  • Make sure you use ISBN in your records

  • Consider enabling OpenLibrary/Google covers as fallback

  • Confirm via OPAC or staff catalog

Display Discharge Warnings in Koha Based on Patron Fines and Checkouts

<!DOCTYPE html>

<html lang="en">

<head>

  <meta charset="UTF-8" />

  <title>Patron Discharge</title>

  <style>

    /* Basic styling similar to Koha intranet */

    body {

      font-family: Arial, sans-serif;

      margin: 20px;

    }

    .dialog.alert {

      border: 1px solid #f0ad4e;

      background-color: #fcf8e3;

      color: #8a6d3b;

      padding: 10px 15px;

      margin-bottom: 20px;

      border-radius: 4px;

    }

    .btn {

      padding: 8px 15px;

      font-size: 14px;

      cursor: pointer;

      border-radius: 4px;

      border: none;

    }

    .btn-primary {

      background-color: #337ab7;

      color: white;

    }

    .btn-primary:hover {

      background-color: #286090;

    }

    .btn-secondary {

      background-color: #ddd;

      color: #777;

      cursor: not-allowed;

    }

    h2 {

      margin-bottom: 10px;

    }

  </style>

</head>

<body>


  <h2>Discharge Information for [% patron.firstname %] [% patron.surname %]</h2>


  <!-- Warning Messages -->

  [% IF messages && messages.size > 0 %]

    <div class="dialog alert">

      [% FOREACH msg IN messages %]

        [% IF msg.code == 'fine_available' %]

          <p><strong>This patron has Fine Amount Available.</strong></p>

        [% ELSIF msg.code == 'active_checkouts' %]

          <p><strong>This patron has active checkouts.</strong></p>

        [% ELSIF msg.code == 'unable_to_generate_pdf' %]

          <p><strong>An error occurred while generating the discharge PDF.</strong></p>

        [% END %]

      [% END %]

    </div>

  [% END %]


  <!-- Discharge Button -->

  [% IF can_be_discharged %]

    <form method="post">

      <input type="hidden" name="op" value="cud-discharge" />

      <input type="hidden" name="borrowernumber" value="[% patron.borrowernumber %]" />

      <input type="submit" name="discharge" value="Generate Discharge PDF" class="btn btn-primary" />

    </form>

  [% ELSE %]

    <button class="btn btn-secondary" disabled>Discharge Not Available</button>

  [% END %]


  <!-- Additional patron details or discharge history can be added here -->


</body>

</html>


21 June 2025

Custom Incremental Fine Structures in Koha Library System

Step-by-step breakdown of how Koha calculates incremental fines for overdue items, especially with a tiered/incremental fine logic like the one used in your custom CalcFine function:


✅ Step-by-Step Custom Incremental Fine Structures in Koha Library System


1. Check if the Item is Overdue

return (0, 0, 0) unless (DateTime->compare($due_dt, $end_date) == -1);
  • If the item is not overdue, no fine is charged.

  • DateTime->compare() checks if the return date is later than the due date.


2. Determine the Item Type and Fetch Circulation Rules

$itemtype = $item->{itemtype} || $item->{itype};
$issuing_rule = Koha::CirculationRules->get_effective_rules(...);
  • This pulls the rules like:

    • fine

    • chargeperiod

    • firstremind (grace period)

    • overduefinescap

    • recall_overdue_fine

    • cap_fine_to_replacement_price


3. Calculate Overdue Time (in units: days/hours)

my $chargeable_units = get_chargeable_units($fine_unit, $start_date, $end_date, $branchcode);
my $units_minus_grace = $chargeable_units - ($issuing_rule->{firstremind} || 0);
  • get_chargeable_units() calculates total overdue time.

  • firstremind is subtracted if FinesIncludeGracePeriod is disabled.

  • If units_minus_grace is zero or negative → No fine.


4. Determine How Many Fine Periods Apply

my $charge_periods = $units / $issuing_rule->{chargeperiod};
$charge_periods = ceil(...) or floor(...) based on `chargeperiod_charge_at`
  • Example: 20 days overdue, chargeperiod = 1 → 20 charge periods.


5. Check for Recalls (Optional Path)

if (recall exists and issuing_rule->{recall_overdue_fine}) {
    $amount = $charge_periods * recall_overdue_fine;
}
  • If the item or biblio is recalled and recall_overdue_fine is set, use this amount per unit.


6. Apply Custom Incremental Fine Formula

If no recall, calculate based on custom tiered rate:

if ($charge_periods <= 15) {
    $amount = $charge_periods * 1;
} elsif ($charge_periods > 15 && $charge_periods <= 30) {
    $amount = 15 + ($charge_periods - 15) * 2;
} else {
    $amount = 45 + ($charge_periods - 30) * 5;
}

๐Ÿ”ข Breakdown of Formula:

  • Day 1–15 → ₹1/day → 15

  • Day 16–30 → ₹2/day → 15 * 1 + 15 * 2 = ₹45

  • Day 31+ → ₹5/day → 45 + (extra days * 5)

Example:

  • 40 overdue days →
    15*1 + 15*2 + 10*5 = ₹15 + ₹30 + ₹50 = ₹95


7. Apply Overdue Cap (if any)

if ($amount > $issuing_rule->{overduefinescap}) {
    $amount = $issuing_rule->{overduefinescap};
}
  • Maximum fine allowed per rule.


8. Apply Replacement Price Cap (if allowed)

if ($issuing_rule->{cap_fine_to_replacement_price} && $amount > $item->{replacementprice}) {
    $amount = $item->{replacementprice};
}
  • This prevents fine from exceeding the item's value.


✅ Return Values

return ($amount, $units_minus_grace, $chargeable_units);
  • Final fine amount

  • Effective overdue units (after grace)

  • Total overdue time (raw)


๐Ÿ’ก Summary Table (Incremental Fine Logic)

Days Overdue Rate per Day Cumulative Fine
1–15 ₹1 15 * 1 = ₹15
16–30 ₹2 ₹15 + 15 * 2 = ₹45
31+ ₹5 ₹45 + (days - 30) * 5

Would you like this logic formatted for configuration as a policy document or admin guide for library staff?

Koha Fine Calculation Formula

Koha Incremental Fine Calculation Formula

Step-by-Step Overview

  1. Check if the item is overdue:
    If the return date is after the due date, continue.
  2. Determine overdue days:
    Overdue Days = Return Date - Due Date
  3. Apply Grace Period:
    Chargeable Days = Overdue Days - First Reminder (grace days)
  4. Calculate Fine Based on Tiers:
    • Days 1–15: ₹1 per day
    • Days 16–30: ₹2 per day
    • Days 31+: ₹5 per day
  5. Apply Fine Caps:
    • If fine > overduefinescap, cap to overduefinescap
    • If enabled, also cap fine to item's replacementprice

Fine Tier Breakdown

Days Overdue Rate per Day Cumulative Fine
1–15 ₹1 Up to ₹15
16–30 ₹2 ₹15 + (days - 15) × ₹2
31+ ₹5 ₹45 + (days - 30) × ₹5

* This stepped fine model is a custom enhancement and may differ from Koha's default flat-rate fines.

13 June 2025

Koha Encryption Key Setup Guide

Koha Encryption Key Setup Guide

Koha: Encryption Key Setup and Management

This guide walks you through configuring and securing the <encryption_key> used in Koha’s koha-conf.xml file.

Step 1: Locate the Configuration File

Open the configuration file using a terminal:

sudo nano /etc/koha/sites/[your_instance]/koha-conf.xml

Replace [your_instance] with your actual Koha site name (e.g., library).

Step 2: Check or Add the Encryption Key

Look for this section inside the file:

<!-- Encryption key for crypted password or sensitive data -->
<encryption_key>TN58bw9750</encryption_key>

Step 3: Generate a Secure Key

Generate a random 32-character Base64 key:

openssl rand -base64 32

Use the generated string to replace the existing key in the XML file.

Step 4: Set Secure Permissions

sudo chmod 640 /etc/koha/sites/library/koha-conf.xml
sudo chown koha-koha:koha-koha /etc/koha/sites/library/koha-conf.xml

Step 5: Restart Koha Services

sudo systemctl restart koha-common
Warning: If you change the encryption key on an existing system, previously encrypted data (like SIP passwords) may become unreadable. Only change the key if you're setting up a new system or know how to re-encrypt existing data.
Best Practice: Backup the koha-conf.xml file and keep the encryption key secure. Never share this key publicly.

01 June 2025

Step-by-Step guide to install DSpace-CRIS 7

Step-by-step guide for installing DSpace-CRIS 7 on Ubuntu 20.04/22.04. This includes full backend (Spring Boot), front end (Angular), PostgreSQL setup, Tomcat deployment, admin user creation, and optional services.

What is DSpace-CRIS 7?

DSpace-CRIS 7 is an extended version of DSpace 7 that includes a Current Research Information System (CRIS). It enables tracking not just publications but also people, projects, grants, patents, and more.


Prerequisites

Hardware Recommendations

  • 4 CPU cores or more

  • 8 GB RAM minimum

  • At least 20 GB of disk space

Software Requirements

ComponentVersion
Ubuntu20.04 / 22.04 LTS
JavaOpenJDK 11
PostgreSQL12+
Apache Maven3.6+
Node.js16.x LTS
Yarn1.22+
GitLatest
Tomcat9.x

Step 1: System Update & Dependencies

bash
sudo apt update && sudo apt upgrade -y sudo apt install openjdk-11-jdk maven git curl unzip postgresql postgresql-contrib \ tomcat9 tomcat9-admin tomcat9-common -y

Install Node.js (16.x) and Yarn:

bash
curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash - sudo apt install nodejs -y npm install -g yarn

Verify tools:

bash
java -version mvn -version psql --version node -v yarn -v

Step 2: PostgreSQL Setup

Create a database and user

bash
sudo -u postgres psql

Inside the shell:

sql
CREATE USER dspace WITH PASSWORD 'dspace'; CREATE DATABASE dspace WITH OWNER dspace ENCODING 'UTF8'; \q

Step 3: Download DSpace-CRIS 7

bash
cd /opt sudo git clone https://github.com/4Science/DSpace-CRIS.git sudo chown -R $USER:$USER DSpace-CRIS cd DSpace-CRIS

Optional: Checkout stable release branch

bash
git checkout dspace-cris-7.5

Step 4: Build the Backend (Spring Boot)

Navigate to root folder:

bash
cd dspace mvn clean install -DskipTests

This will build the WAR file for deployment and create the target folder with installation artifacts.


Step 5: Install DSpace Backend

bash
cd dspace/target/dspace-installer sudo mkdir -p /dspace sudo chown $USER:$USER /dspace ant fresh_install

Initialize database:

bash
/dspace/bin/dspace database migrate

Step 6: Build the Angular UI (Frontend)

bash
cd ../dspace-angular yarn install yarn run build:ssr

To run the frontend with SSR (server-side rendering):

bash
yarn run serve:ssr

This will serve the frontend at:
http://localhost:4000


Step 7: Deploy Backend to Tomcat

Copy the generated WAR to Tomcat:

bash
cp /opt/DSpace-CRIS/dspace/target/dspace-server.war /var/lib/tomcat9/webapps/server.war

Restart Tomcat:

bash
sudo systemctl restart tomcat9

Check the REST backend:
http://localhost:8080/server/
(should return a JSON API root)


Step 8: Create Admin User

bash
/dspace/bin/dspace create-administrator

Enter:

  • Email

  • First Name, Last Name

  • Password


Step 9: Configure DSpace-CRIS Features

Open /dspace/config/local.cfg and configure:

  • Email server

  • Handle server

  • UI base URLs

  • LDAP (if needed)

CRIS-specific configuration:

bash
/dspace/config/cris/

Files like cris-entities.xml, cris-layout.xml help define your entity types, layout, and metadata.


Step 10: Reverse Proxy with NGINX (Optional)

Install NGINX:

bash
sudo apt install nginx -y

Basic reverse proxy config:

nginx
server { listen 80; server_name yourdomain.com; location / { proxy_pass http://localhost:4000; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location /server/ { proxy_pass http://localhost:8080/server/; } }

Restart NGINX:

bash
sudo systemctl restart nginx

Optional: Run as Systemd Services

Create a service for Angular SSR frontend:

bash
sudo nano /etc/systemd/system/dspace-frontend.service

Paste:

ini
[Unit] Description=DSpace Angular Frontend After=network.target [Service] User=ubuntu WorkingDirectory=/opt/DSpace-CRIS/dspace-angular ExecStart=/usr/bin/yarn serve:ssr Restart=always [Install] WantedBy=multi-user.target
bash
sudo systemctl daemon-reexec sudo systemctl enable dspace-frontend sudo systemctl start dspace-frontend

Troubleshooting

IssueFix
Tomcat shows error on WARCheck logs: sudo journalctl -u tomcat9
Angular fails to startTry: yarn cache clean && yarn install
PostgreSQL errorsCheck: sudo -u postgres psql and test DB
REST API not reachableCheck Tomcat deployment, port 8080

Useful URLs

  • REST API: http://localhost:8080/server/

  • Angular UI: http://localhost:4000

  • Admin creation: /dspace/bin/dspace create-administrator

  • CRIS Config: /dspace/config/cris/

Customizing Overdue Fine Calculations in Koha: A Detailed Guide

Customizing Overdue Fine Calculations in Koha: A Detailed Guide Customizing Overdue Fine Calculations in Koha: A De...