Koha with no barcodes

Traditionally, Koha 3 depends on the items (we call them existencias in spanish) having a barcode in order to uniquely identify each item. Circulation, for example, requires the librarian to scan the barcode of an item in order to circulate it.

At times, this proves inconvenient since lots of biblios (titles, or títulos in spanish) have the same barcode printed on each item (usually the ISBN number) forcing the library to print new unique barcodes (Koha has a nice barcode generator) for each one of the items in existence.

However, it’s usually not feasible to relabel all items with new barcodes, especially if you have millions of items nationwide. So, I thought of an easy patch to Koha that allows to circulate items based on the item number, and not the barcode.

First of all, you should set the barcode number for each item equal to the item number for those items where you don’t have any barcode recorded. These is best accomplished after loading MARC records on the database using the MySQL console:

  UPDATE items SET barcode = itemnumber; -- optionally using something like WHERE barcode = ''

On my case, for over 1.1 million items, it took some 3 minutes 6 seconds to complete. There’s a drawback, however, because you need to run this periodically as you add more items, but it’s not something your DBA can’t automate. At this point you can circulate items using items number, and you can print barcodes with that number, but it’s still not easy for the librarian to either remember the item number or look it up before circulating.

You can apply an easy patch on line 44 of the modules/catalogue/moredetail.tmpl file of the Intranet, providing a new link on the Items tab of a biblio to start the borrowing workflow for a specific item:

<!-- TMPL_UNLESS NAME="issue" --><a href="/cgi-bin/koha/circ/circulation.pl?barcode=<!-- TMPL_VAR NAME="itemnumber" -->">[Circulate item <!-- TMPL_VAR NAME="itemnumber" -->]</a><!-- /TMPL_UNLESS -->

Of course, circ/circulation.pl on the Intranet also needs a small patch to store the barcode number on the session and then reusing it when the borrower is selected, near line 111:

my $barcode;
if ( $session->param('barcode') ) {
  $barcode = $session->param('barcode');
  $session->clear('barcode');
} elsif ( $query->param('barcode') ) {
  $barcode = $query->param('barcode') || '';
  $session->param('barcode', $barcode);
}

$barcode =~  s/^\s*|\s*$//g; # remove leading/trailing whitespace
...

Restart your Web server and that’s it. You can now search for a biblio, go to the Items tab, select an item to be circulated, select a borrower, and the item is circulated. For returns, search for the user and go to the end of the page, you can see all items on circulation, fines and return options. The workflow changes a little bit, but it’s the easiest way I’ve devised to operate a Koha ILS when barcodes are absent or outside your control.

Complex multi-PBX setups with Asterisk

The greatest feature of the Asterisk IPBX is the dialplan. Basically, sources (extensions, incoming calls, internal applications) and destinations (outgoing calls, extensions at other PBXs, internal applications) are mapped as contexts on this dialplan thingy. The dialplan lives on the extensions.conf file, or those that are included, such as extensions_custom.conf on FreePBX setups.

If you already write your own dialplan, consider yourself an Asterisk hacker and you’ll probably want to stop reading. However, if you wonder how to interconnect multiple Asterisk PBXs, especially when using a Web-based administration interface such as the ones found on Elastix, Trixbox and home-brewed FreePBX-based solutions, then keep reading, I hope it’s edifying and entertaining.

Assume you have three locations which need PBX service. In my case, those are Quito, Cuenca and Guayaquil. They are interconnected using a telco E1 connection, full-data. They’re on separate private /24 blocks, but they see each other just fine.

First of all, ask yourself if you really need to provide PBX service to each location. I mean, do you need to offer point-to-point communications even when the third party is down? But then, isn’t your E1 connection a single point of failure? You need to decide this before deciding to offer local PBX services, since it’s obviously cheaper to maintain just one PBX. And if you only need one PBX, then you might also stop reading.

That said, the advantages of providing a local PBX are:

  • Faster response for applications such as voicemail, directory, IVRs et al.
  • Ability to take profit of local PSTN connections, for example, an existing FXO
  • In case of failure of one site, you can communicate the others, provided the communication channel is stil there
  • Administration becomes delegable if your setup is big enough to justify local admins

If you want to take advantage of having a local PBX, then you’ll create the local extensions in the local PBX. Let’s assume that Alice and Bob work on Cuenca, so they have their extensions 100 and 101 created there. Mallory works on Guayaquil, so he’s 200 in the local PBX and Charlie is 300 on Quito. So, go ahead and use FreePBX to create the SIP extensions on each PBX!

Next step is to create IAX2 trunks. IAX exists to interconnect Asterisk PBXs. To our eyes, using IAX instead of SIP or whatever means we get full semantics on signalling among the PBXs, no headaches with caller IDs, channel usage et al. So, the process is a bit creepy on FreePBX, we need to go to Basic -> Trunks, Add IAX2 Trunk and define PEER and USER details. So basically we should interchange the information from PEER on one side to USER on the other side, fill the blanks so you get something like:

On PBX A 10.10.1.1 On PBX B 10.10.2.1
PEER details:

host=10.10.2.1
username=PBXA
secret=FOOBARBAZ
type=peer
USER details:

secret=FOOBARBAZ
type=user
context=from-trunk
USER details:

secret=BAZBARFOO
type=user
context=from-trunk
PEER details:

host=10.10.1.1
username=PBXB
secret=BAZBARFOO
type=peer

Set meaningful names for Trunk name and USER context, since those would be useful later. Right now you have local PBX services, and IAX trunks among the PBXs, but they’re not aware neither of the existence of more extensions on the other side, nor the dial rules to get there. Here we go with Outbound routes.

You should create n-1 trunks and n-1 routes for any n-PBX Asterisk setup. Go ahead and create two outbound routes on each of your PBXs, using the prefix for each location, for example 1xx for Cuenca, 2xx for Guayaquil and 3xx for Quito. The ‘xx’ thingy has a special meaning on Asterisk’s dialplan, check FreePBX’s online help for details, but using ‘Nxx’ where N is the prefix for each location should do just fine. For each outbound route select the matching trunk.

Great, you can now dial 2xx from Cuenca or Quito and you should get to Guayaquil via the IAX trunks. The only issue is that, when you have a respectable amount of extensions, you need to centralize your extensions directory. If you don’t use an LDAP directory, which you should do, you’ll run into problems when provisioning the personal directory to your users.

So, finally, FreePBX has this thingy called “Custom Extensions” which you can create as a regular extension and after you do that you can assign a dial rule for that. So, instead of CUSTOM/XXX as the dial rule, use IAX2/foo-peer/XXX. Be advised that by setting this up this way, your whole work with outbound routes is useless, and you have to create the extension in all PBXes, but this is easily solved using LDAP.

Alright, so that’s it. You now have multiple Asterisk PBXes, local service on each site, IAX2 trunks among them, calling routes active for all your extensions and some scenarios for ‘centralized’ extension management. Check my other posts under the Asterisk tag for more Asterisk awesomeness.

Este blog refleja única y exclusivamente mis opiniones, y no las de mis empleadores, las de las organizaciones de las que formo parte ni las de ninguna otra persona natural o jurídica, pública o privada, nacional o extranjera.