373 lines
12 KiB
Perl
Executable file
373 lines
12 KiB
Perl
Executable file
#!/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 );
|