Koha/barcodes/barcodesGenerator.pl
2007-03-09 14:28:54 +00:00

373 lines
12 KiB
Perl
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/perl
# script to generate items barcodes
# written 07/04
# by Veleda Matias - matias_veleda@hotmail.com - Physics Library UNLP Argentina and
# Castañeda Sebastian - seba3c@yahoo.com.ar - Physics Library UNLP Argentina and
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
# Suite 330, Boston, MA 02111-1307 USA
require Exporter;
use strict;
use CGI;
use C4::Context;
use C4::Output;
#FIXME : module deprecated ?
use PDF::API2;
use PDF::API2::Page;
use PDF::API2::Util;
use C4::Barcodes::PrinterConfig;
use Time::localtime;
# This function returns the path to deal with the correct files, considering
# templates set and language.
sub getPath {
my $type = shift @_;
my $templatesSet = C4::Context->preference('template');
my $lang = C4::Context->preference('opaclanguages');
if ( $type eq "intranet" ) {
return "$ENV{'DOCUMENT_ROOT'}/intranet-tmpl/$templatesSet/$lang";
}
else {
return "$ENV{'DOCUMENT_ROOT'}/opac-tmpl/$templatesSet/$lang";
}
}
# Load a configuration file. Before use this function, check if that file exists.
sub loadConfFromFile {
my $fileName = shift @_;
my %keyValues;
open FILE, "<$fileName";
while (<FILE>) {
chomp;
if (/\s*([\w_]*)\s*=\s*([\[\]\<\>\w_\s:@,\.-]*)\s*/) {
$keyValues{$1} = $2;
}
}
close FILE;
return %keyValues;
}
# Save settings to a configuration file. It delete previous configuration settings.
sub saveConfToFile {
my $fileName = shift @_;
my %keyValues = %{ shift @_ };
my $i;
open FILE, ">$fileName";
foreach $i ( keys(%keyValues) ) {
print FILE $i . " = " . $keyValues{$i} . "\n";
}
close FILE;
}
# Load the config file.
my $filenameConf =
&getPath("intranet") . "/includes/labelConfig/itemsLabelConfig.conf";
my %labelConfig = &loadConfFromFile($filenameConf);
# Creates a CGI object and take its parameters
my $cgi = new CGI;
my $from = $cgi->param('from');
my $to = $cgi->param('to');
my $individualCodes = $cgi->param('individualCodes');
my $rangeType = $cgi->param('rangeType');
my $pageType = $cgi->param('pages');
my $label = $cgi->param('label');
my $numbersystem = $cgi->param('numbersystem');
my $text_under_label = $cgi->param('text_under_label');
# Generate the checksum from an inventary code
sub checksum {
sub calculateDigit {
my $code = shift @_;
my $sum = 0;
my $odd_parity = 1;
my $i;
for ( $i = length($code) - 1 ; $i >= 0 ; $i-- ) {
if ($odd_parity) {
$sum = $sum + ( 3 * substr( $code, $i, 1 ) );
}
else {
$sum = $sum + substr( $code, $i, 1 );
}
$odd_parity = !$odd_parity;
}
my $check_digit = 10 - ( $sum % 10 );
if ( $check_digit == 10 ) {
$check_digit = 0;
}
return $code . $check_digit;
}
my $currentCode = shift @_;
$currentCode = &calculateDigit($currentCode);
return $currentCode;
}
# Assigns a temporary name to the PDF file
sub assingFilename {
my ( $from, $to ) = @_;
my $ip = $cgi->remote_addr();
my $random = int( rand(1000000) );
my $timeObj = localtime();
my ( $day, $month, $year, $hour, $min, $sec ) = (
$timeObj->mday,
$timeObj->mon + 1,
$timeObj->year + 1900,
$timeObj->hour, $timeObj->min, $timeObj->sec
);
my $tmpFileName =
$random . '-' . $ip
. '-(From '
. $from . ' to '
. $to . ')-['
. $day . '.'
. $month . '.'
. $year . ']-['
. $hour . ':'
. $min . ':'
. $sec . '].pdf';
return $tmpFileName;
}
sub getCallnum {
#grabs a callnumber for the specified barcode
my ($barcode) = @_;
my $query =
"select dewey from items,biblioitems where items.biblionumber=biblioitems.biblionumber and items.barcode=?";
my $dbh = C4::Context->dbh;
my $sth = $dbh->prepare($query);
$sth->execute($barcode);
my ($callnum) = $sth->fetchrow_array();
warn "Call number is:" . $barcode;
return $callnum;
}
# Takes inventary codes from database and if they are between
# the interval specify by parameters, it generates the correspond barcodes
sub barcodesGenerator {
my ( $from, $to, $rangeType, $individualCodes, $text_under_label ) = @_;
# Returns a database handler
my $dbh = C4::Context->dbh;
# Create the query to database
# Assigns a temporary filename for the pdf file
my $tmpFileName = &assingFilename( $from, $to );
# warn "range type: ".$rangeType;
if ( $rangeType eq 'continuous' ) {
# Set the temp directory for pdf´s files
if ( !defined( $ENV{'TEMP'} ) ) {
$ENV{'TEMP'} = '/tmp/';
}
$tmpFileName = $ENV{'TEMP'} . $tmpFileName;
# Creates a PDF object
my $pdf = PDF::API2->new( -file => $tmpFileName );
# Set the positions where barcodes are going to be placed
C4::Barcodes::PrinterConfig::setPositionsForX(
$labelConfig{'marginLeft'}, $labelConfig{'labelWidth'},
$labelConfig{'columns'}, $labelConfig{'pageType'}
);
C4::Barcodes::PrinterConfig::setPositionsForY(
$labelConfig{'marginBottom'}, $labelConfig{'labelHeigth'},
$labelConfig{'rows'}, $labelConfig{'pageType'}
);
# Creates a font object
my $tr = $pdf->corefont('Helvetica-Bold');
# Barcode position
my ( $page, $gfx, $text );
for ( my $code = $from ; $code <= $to ; $code++ ) {
# Generetase checksum
my $codeC = &checksum($code);
# Generate the corresponde barcode to $code
# warn "Code is :-->".$codeC."<--";
my $barcode = $pdf->barcode(
-font => $tr, # The font object to use
-type => 'ean128', # Standard of codification
-code => $codeC, # Text to codify
-extn => '012345', # Barcode extension (if it is aplicable)
-umzn => 10, # Top limit of the finished bar
-lmzn => 10, # Bottom limit of the finished bar
-zone => 15, # Bars size
-quzn => 0, # Space destinated for legend
-ofwt => 0.01, # Bars width
-fnsz => 8, # Font size
-text => ''
);
( my $x, my $y, $pdf, $page, $gfx, $text, $tr, $label ) =
C4::Barcodes::PrinterConfig::getLabelPosition( $label, $pdf,
$page, $gfx, $text, $tr, $pageType );
# Assigns a barcodes to $gfx
$gfx->barcode( $barcode, $x, $y,
( 72 / $labelConfig{'systemDpi'} ) );
# Assigns the additional information to the barcode (Legend)
$text->translate( $x - 48, $y - 22 );
#warn "code is ".$codeC;
if ($text_under_label) {
$text->text($text_under_label);
}
else {
$text->text( getCallnum($code) );
}
}
# Writes the objects added in $gfx to $page
$pdf->finishobjects( $page, $gfx, $text );
# Save changes to the PDF
$pdf->saveas;
# Close the conection with the PDF file
$pdf->end;
# Show the PDF file
print $cgi->redirect(
"/cgi-bin/koha/barcodes/pdfViewer.pl?tmpFileName=$tmpFileName");
}
else {
my $rangeCondition;
if ( $individualCodes ne "" ) {
$rangeCondition = "AND (I.barcode IN " . $individualCodes . ")";
}
else {
$rangeCondition =
"AND (I.barcode >= " . $from . " AND I.barcode <=" . $to . " )";
}
my $query =
"SELECT CONCAT('$numbersystem',REPEAT('0',((12 - LENGTH('$numbersystem')) - LENGTH(I.barcode))), I.barcode) AS Codigo, B.title, B.author FROM biblio B, items I WHERE (I.biblionumber = B.biblioNumber ) "
. $rangeCondition
. " AND (I.barcode <> 'FALTA') ORDER BY Codigo";
# Prepare the query
my $sth = $dbh->prepare($query);
# Executes the query
$sth->execute;
if ( $sth->rows ) { # There are inventary codes
# Set the temp directory for pdf´s files
if ( !defined( $ENV{'TEMP'} ) ) {
$ENV{'TEMP'} = '/tmp/';
}
# Assigns a temporary filename for the pdf file
my $tmpFileName = &assingFilename( $from, $to );
$tmpFileName = $ENV{'TEMP'} . $tmpFileName;
# Creates a PDF object
my $pdf = PDF::API2->new( -file => $tmpFileName );
# Set the positions where barcodes are going to be placed
C4::Barcodes::PrinterConfig::setPositionsForX(
$labelConfig{'marginLeft'}, $labelConfig{'labelWidth'},
$labelConfig{'columns'}, $labelConfig{'pageType'}
);
C4::Barcodes::PrinterConfig::setPositionsForY(
$labelConfig{'marginBottom'}, $labelConfig{'labelHeigth'},
$labelConfig{'rows'}, $labelConfig{'pageType'}
);
# Creates a font object
my $tr = $pdf->corefont('Helvetica-Bold');
# Barcode position
my ( $page, $gfx, $text );
while ( my ( $code, $dewey, $title, $author ) =
$sth->fetchrow_array )
{
# Generetase checksum
$code = &checksum($code);
# Generate the corresponde barcode to $code
my $barcode = $pdf->barcode(
-font => $tr, # The font object to use
-type => 'ean13', # Standard of codification
-code => $code, # Text to codify
-extn => '012345', # Barcode extension (if it is aplicable)
-umzn => 10, # Top limit of the finished bar
-lmzn => 10, # Bottom limit of the finished bar
-zone => 15, # Bars size
-quzn => 0, # Space destinated for legend
-ofwt => 0.01, # Bars width
-fnsz => 8, # Font size
-text => ''
);
( my $x, my $y, $pdf, $page, $gfx, $text, $tr, $label ) =
C4::Barcodes::PrinterConfig::getLabelPosition( $label, $pdf,
$page, $gfx, $text, $tr, $pageType );
# Assigns a barcodes to $gfx
$gfx->barcode( $barcode, $x, $y,
( 72 / $labelConfig{'systemDpi'} ) );
# Assigns the additional information to the barcode (Legend)
$text->translate( $x - 48, $y - 22 );
if ($text_under_label) {
$text->text($text_under_label);
}
else {
$text->text( substr $title, 0, 30 );
$text->translate( $x - 48, $y - 29 );
#$text->text(substr $author, 0, 30);
$text->text( substr $author, 0, 30 );
}
}
# Writes the objects added in $gfx to $page
$pdf->finishobjects( $page, $gfx, $text );
# Save changes to the PDF
$pdf->saveas;
# Close the conection with the PDF file
$pdf->end;
# Show the PDF file
print $cgi->redirect(
"/cgi-bin/koha/barcodes/pdfViewer.pl?tmpFileName=$tmpFileName");
}
else {
# Rollback and shows the error legend
print $cgi->redirect("/cgi-bin/koha/barcodes/barcodes.pl?error=1");
}
$sth->finish;
}
}
barcodesGenerator( $from, $to, $rangeType, $individualCodes,
$text_under_label );