bug_7001: Issue and Reserve slips are notices.

Branches can have their own version of notices - added branchcode to
letter table.
Support html notices - added is_html to letter table.
Support for borrower attributes in templates.
GetPreparedletter() is the interface for compiling letters (notices).
Sysprefs for notice and slips stylesheets
Added TRANSFERSLIP to the letters

Signed-off-by: Paul Poulain <paul.poulain@biblibre.com>
This commit is contained in:
Srdjan Jankovic 2012-03-09 13:22:17 +13:00 committed by Paul Poulain
parent e32e3ba662
commit a9ded4fa00
44 changed files with 1376 additions and 703 deletions

View File

@ -99,6 +99,7 @@ BEGIN {
&IsBranchTransferAllowed
&CreateBranchTransferLimit
&DeleteBranchTransferLimits
&TransferSlip
);
# subs to deal with offline circulation
@ -2676,11 +2677,18 @@ sub SendCirculationAlert {
borrowernumber => $borrower->{borrowernumber},
message_name => $message_name{$type},
});
my $letter = C4::Letters::getletter('circulation', $type);
C4::Letters::parseletter($letter, 'biblio', $item->{biblionumber});
C4::Letters::parseletter($letter, 'biblioitems', $item->{biblionumber});
C4::Letters::parseletter($letter, 'borrowers', $borrower->{borrowernumber});
C4::Letters::parseletter($letter, 'branches', $branch);
my $letter = C4::Letters::GetPreparedLetter (
module => 'circulation',
letter_code => $type,
branchcode => $branch,
tables => {
'biblio' => $item->{biblionumber},
'biblioitems' => $item->{biblionumber},
'borrowers' => $borrower,
'branches' => $branch,
}
) or return;
my @transports = @{ $borrower_preferences->{transports} };
# warn "no transports" unless @transports;
for (@transports) {
@ -2695,7 +2703,8 @@ sub SendCirculationAlert {
$message->update;
}
}
$letter;
return $letter;
}
=head2 updateWrongTransfer
@ -3147,6 +3156,35 @@ sub ProcessOfflineIssue {
=head2 TransferSlip
TransferSlip($user_branch, $itemnumber, $to_branch)
Returns letter hash ( see C4::Letters::GetPreparedLetter ) or undef
=cut
sub TransferSlip {
my ($branch, $itemnumber, $to_branch) = @_;
my $item = GetItem( $itemnumber )
or return;
my $pulldate = C4::Dates->new();
return C4::Letters::GetPreparedLetter (
module => 'circulation',
letter_code => 'TRANSFERSLIP',
branchcode => $branch,
tables => {
'branches' => $to_branch,
'biblio' => $item->{biblionumber},
'items' => $item,
},
);
}
1;
__END__

View File

@ -24,6 +24,7 @@ use MIME::Lite;
use Mail::Sendmail;
use C4::Members;
use C4::Members::Attributes qw(GetBorrowerAttributes);
use C4::Branch;
use C4::Log;
use C4::SMS;
@ -40,7 +41,7 @@ BEGIN {
$VERSION = 3.01;
@ISA = qw(Exporter);
@EXPORT = qw(
&GetLetters &getletter &addalert &getalert &delalert &findrelatedto &SendAlerts GetPrintMessages
&GetLetters &GetPreparedLetter &GetWrappedLetter &addalert &getalert &delalert &findrelatedto &SendAlerts &GetPrintMessages
);
}
@ -115,13 +116,26 @@ sub GetLetters (;$) {
return \%letters;
}
sub getletter ($$) {
my ( $module, $code ) = @_;
my %letter;
sub getletter ($$$) {
my ( $module, $code, $branchcode ) = @_;
if (C4::Context->preference('IndependantBranches') && $branchcode){
$branchcode = C4::Context->userenv->{'branch'};
}
if ( my $l = $letter{$module}{$code}{$branchcode} ) {
return { %$l }; # deep copy
}
my $dbh = C4::Context->dbh;
my $sth = $dbh->prepare("select * from letter where module=? and code=?");
$sth->execute( $module, $code );
my $line = $sth->fetchrow_hashref;
return $line;
my $sth = $dbh->prepare("select * from letter where module=? and code=? and (branchcode = ? or branchcode = '') order by branchcode desc limit 1");
$sth->execute( $module, $code, $branchcode );
my $line = $sth->fetchrow_hashref
or return;
$line->{'content-type'} = 'text/html; charset="UTF-8"' if $line->{is_html};
$letter{$module}{$code}{$branchcode} = $line;
return { %$line };
}
=head2 addalert ($borrowernumber, $type, $externalid)
@ -176,7 +190,7 @@ sub delalert ($) {
sub getalert (;$$$) {
my ( $borrowernumber, $type, $externalid ) = @_;
my $dbh = C4::Context->dbh;
my $query = "SELECT * FROM alert WHERE";
my $query = "SELECT a.*, b.branchcode FROM alert a JOIN borrowers b USING(borrowernumber) WHERE";
my @bind;
if ($borrowernumber and $borrowernumber =~ /^\d+$/) {
$query .= " borrowernumber=? AND ";
@ -232,73 +246,68 @@ sub findrelatedto ($$) {
parameters :
- $type : the type of alert
- $externalid : the id of the "object" to query
- $letter : the letter to send.
- $letter_code : the letter to send.
send an alert to all borrowers having put an alert on a given subject.
=cut
sub SendAlerts {
my ( $type, $externalid, $letter ) = @_;
my ( $type, $externalid, $letter_code ) = @_;
my $dbh = C4::Context->dbh;
my $strsth;
if ( $type eq 'issue' ) {
# warn "sending issues...";
my $letter = getletter( 'serial', $letter );
# prepare the letter...
# search the biblionumber
my $sth =
$dbh->prepare(
"SELECT biblionumber FROM subscription WHERE subscriptionid=?");
$sth->execute($externalid);
my ($biblionumber) = $sth->fetchrow;
# parsing branch info
my $userenv = C4::Context->userenv;
parseletter( $letter, 'branches', $userenv->{branch} );
# parsing librarian name
$letter->{content} =~ s/<<LibrarianFirstname>>/$userenv->{firstname}/g;
$letter->{content} =~ s/<<LibrarianSurname>>/$userenv->{surname}/g;
$letter->{content} =~
s/<<LibrarianEmailaddress>>/$userenv->{emailaddress}/g;
# parsing biblio information
parseletter( $letter, 'biblio', $biblionumber );
parseletter( $letter, 'biblioitems', $biblionumber );
my ($biblionumber) = $sth->fetchrow
or warn( "No subscription for '$externalid'" ),
return;
my %letter;
# find the list of borrowers to alert
my $alerts = getalert( '', 'issue', $externalid );
foreach (@$alerts) {
# and parse borrower ...
my $innerletter = $letter;
my $borinfo = C4::Members::GetMember('borrowernumber' => $_->{'borrowernumber'});
parseletter( $innerletter, 'borrowers', $_->{'borrowernumber'} );
my $email = $borinfo->{email} or next;
# warn "sending issues...";
my $userenv = C4::Context->userenv;
my $letter = GetPreparedLetter (
module => 'serial',
letter_code => $letter_code,
branchcode => $userenv->{branch},
tables => {
'branches' => $_->{branchcode},
'biblio' => $biblionumber,
'biblioitems' => $biblionumber,
'borrowers' => $borinfo,
},
want_librarian => 1,
) or return;
# ... then send mail
if ( $borinfo->{email} ) {
my %mail = (
To => $borinfo->{email},
From => $borinfo->{email},
Subject => "" . $innerletter->{title},
Message => "" . $innerletter->{content},
'Content-Type' => 'text/plain; charset="utf8"',
);
sendmail(%mail) or carp $Mail::Sendmail::error;
}
my %mail = (
To => $email,
From => $email,
Subject => "" . $letter->{title},
Message => "" . $letter->{content},
'Content-Type' => 'text/plain; charset="utf8"',
);
sendmail(%mail) or carp $Mail::Sendmail::error;
}
}
elsif ( $type eq 'claimacquisition' ) {
$letter = getletter( 'claimacquisition', $letter );
elsif ( $type eq 'claimacquisition' or $type eq 'claimissues' ) {
# prepare the letter...
# search the biblionumber
$strsth = qq{
$strsth = $type eq 'claimacquisition'
? qq{
SELECT aqorders.*,aqbasket.*,biblio.*,biblioitems.*,aqbooksellers.*
FROM aqorders
LEFT JOIN aqbasket ON aqbasket.basketno=aqorders.basketno
@ -306,114 +315,83 @@ sub SendAlerts {
LEFT JOIN biblioitems ON aqorders.biblioitemnumber=biblioitems.biblioitemnumber
LEFT JOIN aqbooksellers ON aqbasket.booksellerid=aqbooksellers.id
WHERE aqorders.ordernumber IN (
}
. join( ",", @$externalid ) . ")";
}
elsif ( $type eq 'claimissues' ) {
$letter = getletter( 'claimissues', $letter );
# prepare the letter...
# search the biblionumber
$strsth = qq{
}
: qq{
SELECT serial.*,subscription.*, biblio.*, aqbooksellers.*
FROM serial
LEFT JOIN subscription ON serial.subscriptionid=subscription.subscriptionid
LEFT JOIN biblio ON serial.biblionumber=biblio.biblionumber
LEFT JOIN aqbooksellers ON subscription.aqbooksellerid=aqbooksellers.id
WHERE serial.serialid IN (
}
}
. join( ",", @$externalid ) . ")";
}
if ( $type eq 'claimacquisition' or $type eq 'claimissues' ) {
my $sthorders = $dbh->prepare($strsth);
$sthorders->execute;
my @fields = map {
$sthorders->{mysql_table}[$_] . "." . $sthorders->{NAME}[$_] }
(0 .. $#{$sthorders->{NAME}} ) ;
my $dataorders = $sthorders->fetchall_arrayref( {} );
my @orders_infos;
while ( my $row = $sthorders->fetchrow_arrayref() ) {
my %rec = ();
@rec{@fields} = @$row;
push @orders_infos, \%rec;
my $sthbookseller =
$dbh->prepare("select * from aqbooksellers where id=?");
$sthbookseller->execute( $dataorders->[0]->{booksellerid} );
my $databookseller = $sthbookseller->fetchrow_hashref;
my @email;
push @email, $databookseller->{bookselleremail} if $databookseller->{bookselleremail};
push @email, $databookseller->{contemail} if $databookseller->{contemail};
unless (@email) {
warn "Bookseller $dataorders->[0]->{booksellerid} without emails";
return;
}
# parsing branch info
my $userenv = C4::Context->userenv;
parseletter( $letter, 'branches', $userenv->{branch} );
# parsing librarian name
$letter->{content} =~ s/<<LibrarianFirstname>>/$userenv->{firstname}/g;
$letter->{content} =~ s/<<LibrarianSurname>>/$userenv->{surname}/g;
$letter->{content} =~ s/<<LibrarianEmailaddress>>/$userenv->{emailaddress}/g;
# Get Fields remplacement
my $order_format = $1 if ( $letter->{content} =~ m/(<order>.*<\/order>)/xms );
# Foreach field to remplace
while ( $letter->{content} =~ m/<<([^>]*)>>/g ) {
my $field = $1;
my $value = $orders_infos[0]->{$field} || "";
$value = sprintf("%.2f", $value) if $field =~ /price/;
$letter->{content} =~ s/<<$field>>/$value/g;
}
if ( $order_format ) {
# For each order
foreach my $infos ( @orders_infos ) {
my $order_content = $order_format;
# We replace by value
while ( $order_content =~ m/<<([^>]*)>>/g ) {
my $field = $1;
my $value = $infos->{$field} || "";
$value = sprintf("%.2f", $value) if $field =~ /price/;
$order_content =~ s/(<<$field>>)/$value/g;
}
$order_content =~ s/<\/{0,1}?order>//g;
$letter->{content} =~ s/<order>.*<\/order>/$order_content\n$order_format/xms;
}
$letter->{content} =~ s/<order>.*<\/order>//xms;
}
my $innerletter = $letter;
my $letter = GetPreparedLetter (
module => $type,
letter_code => $letter_code,
branchcode => $userenv->{branch},
tables => {
'branches' => $userenv->{branch},
'aqbooksellers' => $databookseller,
},
repeat => $dataorders,
want_librarian => 1,
) or return;
# ... then send mail
if ( $orders_infos[0]->{'aqbooksellers.bookselleremail'}
|| $orders_infos[0]->{'aqbooksellers.contemail'} ) {
my $to = $orders_infos[0]->{'aqbooksellers.bookselleremail'};
$to .= ", " if $to;
$to .= $orders_infos[0]->{'aqbooksellers.contemail'} || "";
my %mail = (
To => $to,
From => $userenv->{emailaddress},
Subject => Encode::encode( "utf8", "" . $innerletter->{title} ),
Message => Encode::encode( "utf8", "" . $innerletter->{content} ),
'Content-Type' => 'text/plain; charset="utf8"',
);
sendmail(%mail) or carp $Mail::Sendmail::error;
warn "sending to $mail{To} From $mail{From} subj $mail{Subject} Mess $mail{Message}" if $debug;
if ( C4::Context->preference("LetterLog") ) {
logaction( "ACQUISITION", "Send Acquisition claim letter", "", "order list : " . join( ",", @$externalid ) . "\n$innerletter->{title}\n$innerletter->{content}" ) if $type eq 'claimacquisition';
logaction( "ACQUISITION", "CLAIM ISSUE", undef, "To=" . $mail{To} . " Title=" . $innerletter->{title} . " Content=" . $innerletter->{content} ) if $type eq 'claimissues';
}
} else {
return {error => "no_email" };
}
my %mail = (
To => join( ','. @email),
From => $userenv->{emailaddress},
Subject => "" . $letter->{title},
Message => "" . $letter->{content},
'Content-Type' => 'text/plain; charset="utf8"',
);
sendmail(%mail) or carp $Mail::Sendmail::error;
warn "sending to From $userenv->{emailaddress} subj $innerletter->{title} Mess $innerletter->{content}" if $debug;
logaction(
"ACQUISITION",
$type eq 'claimissues' ? "CLAIM ISSUE" : "ACQUISITION CLAIM",
undef,
"To="
. $databookseller->{contemail}
. " Title="
. $letter->{title}
. " Content="
. $letter->{content}
) if C4::Context->preference("LetterLog");
}
# send an "account details" notice to a newly created user
# send an "account details" notice to a newly created user
elsif ( $type eq 'members' ) {
# must parse the password special, before it's hashed.
$letter->{content} =~ s/<<borrowers.password>>/$externalid->{'password'}/g;
parseletter( $letter, 'borrowers', $externalid->{'borrowernumber'});
parseletter( $letter, 'branches', $externalid->{'branchcode'} );
my $branchdetails = GetBranchDetail($externalid->{'branchcode'});
my $letter = GetPreparedLetter (
module => 'members',
letter_code => $letter_code,
branchcode => $externalid->{'branchcode'},
tables => {
'branches' => $branchdetails,
'borrowers' => $externalid->{'borrowernumber'},
},
substitute => { 'borrowers.password' => $externalid->{'password'} },
want_librarian => 1,
) or return;
my %mail = (
To => $externalid->{'emailaddr'},
From => $branchdetails->{'branchemail'} || C4::Context->preference("KohaAdminEmailAddress"),
@ -425,24 +403,148 @@ sub SendAlerts {
}
}
=head2 parseletter($letter, $table, $pk)
=head2 GetPreparedLetter( %params )
parameters :
- $letter : a hash to letter fields (title & content useful)
- $table : the Koha table to parse.
- $pk : the primary key to query on the $table table
parse all fields from a table, and replace values in title & content with the appropriate value
(not exported sub, used only internally)
%params hash:
module => letter module, mandatory
letter_code => letter code, mandatory
branchcode => for letter selection, if missing default system letter taken
tables => a hashref with table names as keys. Values are either:
- a scalar - primary key value
- an arrayref - primary key values
- a hashref - full record
substitute => custom substitution key/value pairs
repeat => records to be substituted on consecutive lines:
- an arrayref - tries to guess what needs substituting by
taking remaining << >> tokensr; not recommended
- a hashref token => @tables - replaces <token> << >> << >> </token>
subtemplate for each @tables row; table is a hashref as above
want_librarian => boolean, if set to true triggers librarian details
substitution from the userenv
Return value:
letter fields hashref (title & content useful)
=cut
our %handles = ();
our %columns = ();
sub GetPreparedLetter {
my %params = @_;
sub parseletter_sth {
my $module = $params{module} or croak "No module";
my $letter_code = $params{letter_code} or croak "No letter_code";
my $branchcode = $params{branchcode} || '';
my $letter = getletter( $module, $letter_code, $branchcode )
or warn( "No $module $letter_code letter"),
return;
my $tables = $params{tables};
my $substitute = $params{substitute};
my $repeat = $params{repeat};
$tables || $substitute || $repeat
or carp( "ERROR: nothing to substitute - both 'tables' and 'substitute' are empty" ),
return;
my $want_librarian = $params{want_librarian};
if ($substitute) {
while ( my ($token, $val) = each %$substitute ) {
$letter->{title} =~ s/<<$token>>/$val/g;
$letter->{content} =~ s/<<$token>>/$val/g;
}
}
if ($want_librarian) {
# parsing librarian name
my $userenv = C4::Context->userenv;
$letter->{content} =~ s/<<LibrarianFirstname>>/$userenv->{firstname}/go;
$letter->{content} =~ s/<<LibrarianSurname>>/$userenv->{surname}/go;
$letter->{content} =~ s/<<LibrarianEmailaddress>>/$userenv->{emailaddress}/go;
}
my ($repeat_no_enclosing_tags, $repeat_enclosing_tags);
if ($repeat) {
if (ref ($repeat) eq 'ARRAY' ) {
$repeat_no_enclosing_tags = $repeat;
} else {
$repeat_enclosing_tags = $repeat;
}
}
if ($repeat_enclosing_tags) {
while ( my ($tag, $tag_tables) = each %$repeat_enclosing_tags ) {
if ( $letter->{content} =~ m!<$tag>(.*)</$tag>!s ) {
my $subcontent = $1;
my @lines = map {
my %subletter = ( title => '', content => $subcontent );
_substitute_tables( \%subletter, $_ );
$subletter{content};
} @$tag_tables;
$letter->{content} =~ s!<$tag>.*</$tag>!join( "\n", @lines )!se;
}
}
}
if ($tables) {
_substitute_tables( $letter, $tables );
}
if ($repeat_no_enclosing_tags) {
if ( $letter->{content} =~ m/[^\n]*<<.*>>[^\n]*/so ) {
my $line = $&;
my $i = 1;
my @lines = map {
my $c = $line;
$c =~ s/<<count>>/$i/go;
foreach my $field ( keys %{$_} ) {
$c =~ s/(<<[^\.]+.$field>>)/$_->{$field}/;
}
$i++;
$c;
} @$repeat_no_enclosing_tags;
my $replaceby = join( "\n", @lines );
$letter->{content} =~ s/\Q$line\E/$replaceby/s;
}
}
$letter->{content} =~ s/<<\S*>>//go; #remove any stragglers
# $letter->{content} =~ s/<<[^>]*>>//go;
return $letter;
}
sub _substitute_tables {
my ( $letter, $tables ) = @_;
while ( my ($table, $param) = each %$tables ) {
next unless $param;
my $ref = ref $param;
my $values;
if ($ref && $ref eq 'HASH') {
$values = $param;
}
else {
my @pk;
my $sth = _parseletter_sth($table);
unless ($sth) {
warn "_parseletter_sth('$table') failed to return a valid sth. No substitution will be done for that table.";
return;
}
$sth->execute( $ref ? @$param : $param );
$values = $sth->fetchrow_hashref;
}
_parseletter ( $letter, $table, $values );
}
}
my %handles = ();
sub _parseletter_sth {
my $table = shift;
unless ($table) {
carp "ERROR: parseletter_sth() called without argument (table)";
carp "ERROR: _parseletter_sth() called without argument (table)";
return;
}
# check cache first
@ -456,9 +558,12 @@ sub parseletter_sth {
($table eq 'borrowers' ) ? "SELECT * FROM $table WHERE borrowernumber = ?" :
($table eq 'branches' ) ? "SELECT * FROM $table WHERE branchcode = ?" :
($table eq 'suggestions' ) ? "SELECT * FROM $table WHERE suggestionid = ?" :
($table eq 'aqbooksellers') ? "SELECT * FROM $table WHERE id = ?" : undef ;
($table eq 'aqbooksellers') ? "SELECT * FROM $table WHERE id = ?" :
($table eq 'aqorders' ) ? "SELECT * FROM $table WHERE ordernumber = ?" :
($table eq 'opac_news' ) ? "SELECT * FROM $table WHERE idnew = ?" :
undef ;
unless ($query) {
warn "ERROR: No parseletter_sth query for table '$table'";
warn "ERROR: No _parseletter_sth query for table '$table'";
return; # nothing to get
}
unless ($handles{$table} = C4::Context->dbh->prepare($query)) {
@ -468,25 +573,21 @@ sub parseletter_sth {
return $handles{$table}; # now cache is populated for that $table
}
sub parseletter {
my ( $letter, $table, $pk, $pk2 ) = @_;
unless ($letter) {
carp "ERROR: parseletter() 1st argument 'letter' empty";
return;
}
my $sth = parseletter_sth($table);
unless ($sth) {
warn "parseletter_sth('$table') failed to return a valid sth. No substitution will be done for that table.";
return;
}
if ( $pk2 ) {
$sth->execute($pk, $pk2);
} else {
$sth->execute($pk);
}
=head2 _parseletter($letter, $table, $values)
parameters :
- $letter : a hash to letter fields (title & content useful)
- $table : the Koha table to parse.
- $values : table record hashref
parse all fields from a table, and replace values in title & content with the appropriate value
(not exported sub, used only internally)
=cut
my %columns = ();
sub _parseletter {
my ( $letter, $table, $values ) = @_;
my $values = $sth->fetchrow_hashref;
# TEMPORARY hack until the expirationdate column is added to reserves
if ( $table eq 'reserves' && $values->{'waitingdate'} ) {
my @waitingdate = split /-/, $values->{'waitingdate'};
@ -500,16 +601,51 @@ sub parseletter {
)->output();
}
if ($letter->{content} && $letter->{content} =~ /<<today>>/) {
my @da = localtime();
my $todaysdate = "$da[2]:$da[1] " . C4::Dates->today();
$letter->{content} =~ s/<<today>>/$todaysdate/go;
}
# and get all fields from the table
my $columns = C4::Context->dbh->prepare("SHOW COLUMNS FROM $table");
$columns->execute;
while ( ( my $field ) = $columns->fetchrow_array ) {
my $replacefield = "<<$table.$field>>";
$values->{$field} =~ s/\p{P}(?=$)//g if $values->{$field};
my $replacedby = $values->{$field} || '';
($letter->{title} ) and $letter->{title} =~ s/$replacefield/$replacedby/g;
($letter->{content}) and $letter->{content} =~ s/$replacefield/$replacedby/g;
# my $columns = $columns{$table};
# unless ($columns) {
# $columns = $columns{$table} = C4::Context->dbh->selectcol_arrayref("SHOW COLUMNS FROM $table");
# }
# foreach my $field (@$columns) {
while ( my ($field, $val) = each %$values ) {
my $replacetablefield = "<<$table.$field>>";
my $replacefield = "<<$field>>";
$val =~ s/\p{P}(?=$)//g if $val;
my $replacedby = defined ($val) ? $val : '';
($letter->{title} ) and do {
$letter->{title} =~ s/$replacetablefield/$replacedby/g;
$letter->{title} =~ s/$replacefield/$replacedby/g;
};
($letter->{content}) and do {
$letter->{content} =~ s/$replacetablefield/$replacedby/g;
$letter->{content} =~ s/$replacefield/$replacedby/g;
};
}
if ($table eq 'borrowers' && $letter->{content}) {
if ( my $attributes = GetBorrowerAttributes($values->{borrowernumber}) ) {
my %attr;
foreach (@$attributes) {
my $code = $_->{code};
my $val = $_->{value_description} || $_->{value};
$val =~ s/\p{P}(?=$)//g if $val;
next unless $val gt '';
$attr{$code} ||= [];
push @{ $attr{$code} }, $val;
}
while ( my ($code, $val_ar) = each %attr ) {
my $replacefield = "<<borrower-attribute:$code>>";
my $replacedby = join ',', @$val_ar;
$letter->{content} =~ s/$replacefield/$replacedby/g;
}
}
}
return $letter;
}
@ -694,31 +830,32 @@ returns your letter object, with the content updated.
sub _add_attachments {
my $params = shift;
return unless 'HASH' eq ref $params;
foreach my $required_parameter (qw( letter attachments message )) {
return unless exists $params->{$required_parameter};
}
return $params->{'letter'} unless @{ $params->{'attachments'} };
my $letter = $params->{'letter'};
my $attachments = $params->{'attachments'};
return $letter unless @$attachments;
my $message = $params->{'message'};
# First, we have to put the body in as the first attachment
$params->{'message'}->attach(
Type => 'TEXT',
Data => $params->{'letter'}->{'content'},
$message->attach(
Type => $letter->{'content-type'} || 'TEXT',
Data => $letter->{'is_html'}
? _wrap_html($letter->{'content'}, $letter->{'title'})
: $letter->{'content'},
);
foreach my $attachment ( @{ $params->{'attachments'} } ) {
$params->{'message'}->attach(
foreach my $attachment ( @$attachments ) {
$message->attach(
Type => $attachment->{'type'},
Data => $attachment->{'content'},
Filename => $attachment->{'filename'},
);
}
# we're forcing list context here to get the header, not the count back from grep.
( $params->{'letter'}->{'content-type'} ) = grep( /^Content-Type:/, split( /\n/, $params->{'message'}->header_as_string ) );
$params->{'letter'}->{'content-type'} =~ s/^Content-Type:\s+//;
$params->{'letter'}->{'content'} = $params->{'message'}->body_as_string;
( $letter->{'content-type'} ) = grep( /^Content-Type:/, split( /\n/, $params->{'message'}->header_as_string ) );
$letter->{'content-type'} =~ s/^Content-Type:\s+//;
$letter->{'content'} = $message->body_as_string;
return $params->{'letter'};
return $letter;
}
@ -785,14 +922,17 @@ sub _send_message_by_email ($;$$$) {
my $utf8 = decode('MIME-Header', $message->{'subject'} );
$message->{subject}= encode('MIME-Header', $utf8);
my $subject = encode('utf8', $message->{'subject'});
my $content = encode('utf8', $message->{'content'});
my $content_type = $message->{'content_type'} || 'text/plain; charset="UTF-8"';
my $is_html = $content_type =~ m/html/io;
my %sendmail_params = (
To => $to_address,
From => $message->{'from_address'} || C4::Context->preference('KohaAdminEmailAddress'),
Subject => encode('utf8', $message->{'subject'}),
Subject => $subject,
charset => 'utf8',
Message => $content,
'content-type' => $message->{'content_type'} || 'text/plain; charset="UTF-8"',
Message => $is_html ? _wrap_html($content, $subject) : $content,
'content-type' => $content_type,
);
$sendmail_params{'Auth'} = {user => $username, pass => $password, method => $method} if $username;
if ( my $bcc = C4::Context->preference('OverdueNoticeBcc') ) {
@ -812,6 +952,27 @@ sub _send_message_by_email ($;$$$) {
}
}
sub _wrap_html {
my ($content, $title) = @_;
my $css = C4::Context->preference("NoticeCSS") || '';
$css = qq{<link rel="stylesheet" type="text/css" href="$css">} if $css;
return <<EOS;
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>$title</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
$css
</head>
<body>
$content
</body>
</html>
EOS
}
sub _send_message_by_sms ($) {
my $message = shift or return undef;
my $member = C4::Members::GetMember( 'borrowernumber' => $message->{'borrowernumber'} );

View File

@ -23,7 +23,7 @@ package C4::Members;
use strict;
#use warnings; FIXME - Bug 2505
use C4::Context;
use C4::Dates qw(format_date_in_iso);
use C4::Dates qw(format_date_in_iso format_date);
use Digest::MD5 qw(md5_base64);
use Date::Calc qw/Today Add_Delta_YM check_date Date_to_Days/;
use C4::Log; # logaction
@ -31,8 +31,10 @@ use C4::Overdues;
use C4::Reserves;
use C4::Accounts;
use C4::Biblio;
use C4::Letters;
use C4::SQLHelper qw(InsertInTable UpdateInTable SearchInTable);
use C4::Members::Attributes qw(SearchIdMatchingAttribute);
use C4::NewsChannels; #get slip news
our ($VERSION,@ISA,@EXPORT,@EXPORT_OK,$debug);
@ -91,6 +93,8 @@ BEGIN {
&DeleteMessage
&GetMessages
&GetMessagesCount
&IssueSlip
);
#Modify data
@ -2229,7 +2233,80 @@ sub DeleteMessage {
logaction("MEMBERS", "DELCIRCMESSAGE", $message->{'borrowernumber'}, $message->{'message'}) if C4::Context->preference("BorrowersLog");
}
END { } # module clean-up code here (global destructor)
=head2 IssueSlip
IssueSlip($branchcode, $borrowernumber, $quickslip)
Returns letter hash ( see C4::Letters::GetPreparedLetter )
$quickslip is boolean, to indicate whether we want a quick slip
=cut
sub IssueSlip {
my ($branch, $borrowernumber, $quickslip) = @_;
# return unless ( C4::Context->boolean_preference('printcirculationslips') );
my $today = POSIX::strftime("%Y-%m-%d", localtime);
my $issueslist = GetPendingIssues($borrowernumber);
foreach my $it (@$issueslist){
if ($it->{'issuedate'} eq $today) {
$it->{'today'} = 1;
}
elsif ($it->{'date_due'} le $today) {
$it->{'overdue'} = 1;
}
$it->{'date_due'}=format_date($it->{'date_due'});
}
my @issues = sort { $b->{'timestamp'} <=> $a->{'timestamp'} } @$issueslist;
my ($letter_code, %repeat);
if ( $quickslip ) {
$letter_code = 'ISSUEQSLIP';
%repeat = (
'checkedout' => [ map {
'biblio' => $_,
'items' => $_,
'issues' => $_,
}, grep { $_->{'today'} } @issues ],
);
}
else {
$letter_code = 'ISSUESLIP';
%repeat = (
'checkedout' => [ map {
'biblio' => $_,
'items' => $_,
'issues' => $_,
}, grep { !$_->{'overdue'} } @issues ],
'overdue' => [ map {
'biblio' => $_,
'items' => $_,
'issues' => $_,
}, grep { $_->{'overdue'} } @issues ],
'news' => [ map {
$_->{'timestamp'} = $_->{'newdate'};
{ opac_news => $_ }
} @{ GetNewsToDisplay("slip") } ],
);
}
return C4::Letters::GetPreparedLetter (
module => 'circulation',
letter_code => $letter_code,
branchcode => $branch,
tables => {
'branches' => $branch,
'borrowers' => $borrowernumber,
},
repeat => \%repeat,
);
}
1;

View File

@ -95,6 +95,24 @@ sub GetBorrowerAttributes {
return \@results;
}
=head2 GetAttributes
my $attributes = C4::Members::Attributes::GetAttributes([$opac_only]);
Retrieve an arrayref of extended attribute codes
=cut
sub GetAttributes {
my ($opac_only) = @_;
my $dbh = C4::Context->dbh();
my $query = "SELECT code FROM borrower_attribute_types";
$query .= "\nWHERE opac_display = 1" if $opac_only;
$query .= "\nORDER BY code";
return $dbh->selectcol_arrayref($query);
}
=head2 GetBorrowerAttributeValue
my $value = C4::Members::Attributes::GetBorrowerAttributeValue($borrowernumber, $attribute_code);

View File

@ -18,9 +18,15 @@ How to add a new message to the queue:
use C4::Items;
my $borrower = { borrowernumber => 1 };
my $item = C4::Items::GetItem(1);
my $letter = C4::Letters::getletter('circulation', 'CHECKOUT');
C4::Letters::parseletter($letter, 'biblio', $item->{biblionumber});
C4::Letters::parseletter($letter, 'biblioitems', $item->{biblionumber});
my $letter = C4::Letters::GetPreparedLetter (
module => 'circulation',
letter_code => 'CHECKOUT',
branchcode => $branch,
tables => {
'biblio', $item->{biblionumber},
'biblioitems', $item->{biblionumber},
},
);
C4::Message->enqueue($letter, $borrower->{borrowernumber}, 'email');
How to update a borrower's last checkout message:

View File

@ -20,8 +20,6 @@ package C4::Print;
use strict;
#use warnings; FIXME - Bug 2505
use C4::Context;
use C4::Members;
use C4::Dates qw(format_date);
use vars qw($VERSION @ISA @EXPORT);
@ -30,7 +28,7 @@ BEGIN {
$VERSION = 3.01;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(&remoteprint &printreserve &printslip);
@EXPORT = qw(&printslip);
}
=head1 NAME
@ -47,28 +45,48 @@ The functions in this module handle sending text to a printer.
=head1 FUNCTIONS
=head2 remoteprint
=cut
&remoteprint($items, $borrower);
=comment
my $slip = <<"EOF";
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Date: $todaysdate;
Prints the list of items in C<$items> to a printer.
ITEM RESERVED:
$itemdata->{'title'} ($itemdata->{'author'})
barcode: $itemdata->{'barcode'}
C<$borrower> is a reference-to-hash giving information about a patron.
This may be gotten from C<&GetMemberDetails>. The patron's name
will be printed in the output.
COLLECT AT: $branchname
C<$items> is a reference-to-list, where each element is a
reference-to-hash describing a borrowed item. C<$items> may be gotten
from C<&GetBorrowerIssues>.
BORROWER:
$bordata->{'surname'}, $bordata->{'firstname'}
card number: $bordata->{'cardnumber'}
Phone: $bordata->{'phone'}
$bordata->{'streetaddress'}
$bordata->{'suburb'}
$bordata->{'town'}
$bordata->{'emailaddress'}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
EOF
=cut
=head2 printslip
&printslip($slip)
print a slip for the given $borrowernumber and $branchcode
=cut
# FIXME - It'd be nifty if this could generate pretty PostScript.
sub remoteprint ($$) {
my ($items, $borrower) = @_;
sub printslip ($) {
my ($slip) = @_;
return unless ( C4::Context->boolean_preference('printcirculationslips') );
# FIXME - It'd be nifty if this could generate pretty PostScript.
(return)
unless ( C4::Context->boolean_preference('printcirculationslips') );
my $queue = '';
# FIXME - If 'queue' is undefined or empty, then presumably it should
@ -94,107 +112,13 @@ sub remoteprint ($$) {
# print $queue;
#open (FILE,">/tmp/$file");
my $i = 0;
# FIXME - This is HLT-specific. Put this stuff in a customizable
# site-specific file somewhere.
print PRINTER "Horowhenua Library Trust\r\n";
print PRINTER "Phone: 368-1953\r\n";
print PRINTER "Fax: 367-9218\r\n";
print PRINTER "Email: renewals\@library.org.nz\r\n\r\n\r\n";
print PRINTER "$borrower->{'cardnumber'}\r\n";
print PRINTER
"$borrower->{'title'} $borrower->{'initials'} $borrower->{'surname'}\r\n";
# FIXME - Use for ($i = 0; $items->[$i]; $i++)
# Or better yet, foreach $item (@{$items})
while ( $items->[$i] ) {
# print $i;
my $itemdata = $items->[$i];
# FIXME - This is just begging for a Perl format.
print PRINTER "$i $itemdata->{'title'}\r\n";
print PRINTER "$itemdata->{'barcode'}";
print PRINTER " " x 15;
print PRINTER "$itemdata->{'date_due'}\r\n";
$i++;
}
print PRINTER $slip;
print PRINTER "\r\n" x 7 ;
close PRINTER;
#system("lpr /tmp/$file");
}
sub printreserve {
# FIXME - make useful
return;
my ( $branchname, $bordata, $itemdata ) = @_;
my $printer = '';
(return) unless ( C4::Context->boolean_preference('printreserveslips') );
if ( $printer eq "" || $printer eq 'nulllp' ) {
open( PRINTER, ">>/tmp/kohares" )
or die "Could not write to /tmp/kohares";
}
else {
open( PRINTER, "| lpr -P $printer >/dev/null" )
or die "Couldn't write to queue:$!\n";
}
my @da = localtime();
my $todaysdate = "$da[2]:$da[1] " . C4::Dates->today();
my $slip = <<"EOF";
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Date: $todaysdate;
ITEM RESERVED:
$itemdata->{'title'} ($itemdata->{'author'})
barcode: $itemdata->{'barcode'}
COLLECT AT: $branchname
BORROWER:
$bordata->{'surname'}, $bordata->{'firstname'}
card number: $bordata->{'cardnumber'}
Phone: $bordata->{'phone'}
$bordata->{'streetaddress'}
$bordata->{'suburb'}
$bordata->{'town'}
$bordata->{'emailaddress'}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
EOF
print PRINTER $slip;
close PRINTER;
return $slip;
}
=head2 printslip
&printslip($borrowernumber)
print a slip for the given $borrowernumber
=cut
#'
sub printslip ($) {
#FIXME - make useful
my $borrowernumber = shift;
my $borrower = GetMemberDetails($borrowernumber);
my $issueslist = GetPendingIssues($borrowernumber);
foreach my $it (@$issueslist){
$it->{'date_due'}=format_date($it->{'date_due'});
}
my @issues = sort { $b->{'timestamp'} <=> $a->{'timestamp'} } @$issueslist;
remoteprint(\@issues, $borrower );
}
END { } # module clean-up code here (global destructor)
1;
__END__

View File

@ -121,6 +121,8 @@ BEGIN {
&AlterPriority
&ToggleLowestPriority
&ReserveSlip
);
@EXPORT_OK = qw( MergeHolds );
}
@ -194,32 +196,31 @@ sub AddReserve {
# Send e-mail to librarian if syspref is active
if(C4::Context->preference("emailLibrarianWhenHoldIsPlaced")){
my $borrower = C4::Members::GetMember(borrowernumber => $borrowernumber);
my $biblio = GetBiblioData($biblionumber);
my $letter = C4::Letters::getletter( 'reserves', 'HOLDPLACED');
my $branchcode = $borrower->{branchcode};
my $branch_details = C4::Branch::GetBranchDetail($branchcode);
my $admin_email_address =$branch_details->{'branchemail'} || C4::Context->preference('KohaAdminEmailAddress');
my $branch_details = C4::Branch::GetBranchDetail($borrower->{branchcode});
if ( my $letter = C4::Letters::GetPreparedLetter (
module => 'reserves',
letter_code => 'HOLDPLACED',
branchcode => $branch,
tables => {
'branches' => $branch_details,
'borrowers' => $borrower,
'biblio' => $biblionumber,
},
) ) {
my %keys = (%$borrower, %$biblio);
foreach my $key (keys %keys) {
my $replacefield = "<<$key>>";
$letter->{content} =~ s/$replacefield/$keys{$key}/g;
$letter->{title} =~ s/$replacefield/$keys{$key}/g;
my $admin_email_address =$branch_details->{'branchemail'} || C4::Context->preference('KohaAdminEmailAddress');
C4::Letters::EnqueueLetter(
{ letter => $letter,
borrowernumber => $borrowernumber,
message_transport_type => 'email',
from_address => $admin_email_address,
to_address => $admin_email_address,
}
);
}
C4::Letters::EnqueueLetter(
{ letter => $letter,
borrowernumber => $borrowernumber,
message_transport_type => 'email',
from_address => $admin_email_address,
to_address => $admin_email_address,
}
);
}
#}
($const eq "o" || $const eq "e") or return; # FIXME: why not have a useful return value?
$query = qq/
@ -1720,21 +1721,21 @@ sub _koha_notify_reserve {
my $admin_email_address = $branch_details->{'branchemail'} || C4::Context->preference('KohaAdminEmailAddress');
my $letter = getletter( 'reserves', $letter_code );
die "Could not find a letter called '$letter_code' in the 'reserves' module" unless( $letter );
my $letter = C4::Letters::GetPreparedLetter (
module => 'reserves',
letter_code => $letter_code,
branchcode => $reserve->{branchcode},
tables => {
'branches' => $branch_details,
'borrowers' => $borrower,
'biblio' => $biblionumber,
'reserves' => $reserve,
'items', $reserve->{'itemnumber'},
},
substitute => { today => C4::Dates->new()->output() },
) or die "Could not find a letter called '$letter_code' in the 'reserves' module";
C4::Letters::parseletter( $letter, 'branches', $reserve->{'branchcode'} );
C4::Letters::parseletter( $letter, 'borrowers', $borrowernumber );
C4::Letters::parseletter( $letter, 'biblio', $biblionumber );
C4::Letters::parseletter( $letter, 'reserves', $borrowernumber, $biblionumber );
if ( $reserve->{'itemnumber'} ) {
C4::Letters::parseletter( $letter, 'items', $reserve->{'itemnumber'} );
}
my $today = C4::Dates->new()->output();
$letter->{'title'} =~ s/<<today>>/$today/g;
$letter->{'content'} =~ s/<<today>>/$today/g;
$letter->{'content'} =~ s/<<[a-z0-9_]+\.[a-z0-9]+>>//g; #remove any stragglers
if ( $print_mode ) {
C4::Letters::EnqueueLetter( {
@ -1908,6 +1909,36 @@ sub MergeHolds {
}
=head2 ReserveSlip
ReserveSlip($branchcode, $borrowernumber, $biblionumber)
Returns letter hash ( see C4::Letters::GetPreparedLetter ) or undef
=cut
sub ReserveSlip {
my ($branch, $borrowernumber, $biblionumber) = @_;
# return unless ( C4::Context->boolean_preference('printreserveslips') );
my $reserve = GetReserveInfo($borrowernumber,$biblionumber )
or return;
return C4::Letters::GetPreparedLetter (
module => 'circulation',
letter_code => 'RESERVESLIP',
branchcode => $branch,
tables => {
'reserves' => $reserve,
'branches' => $reserve->{branchcode},
'borrowers' => $reserve,
'biblio' => $reserve,
'items' => $reserve,
},
);
}
=head1 AUTHOR
Koha Development Team <http://koha-community.org/>

View File

@ -425,20 +425,24 @@ sub ModSuggestion {
if ($suggestion->{STATUS}) {
# fetch the entire updated suggestion so that we can populate the letter
my $full_suggestion = GetSuggestion($suggestion->{suggestionid});
my $letter = C4::Letters::getletter('suggestions', $full_suggestion->{STATUS});
if ($letter) {
C4::Letters::parseletter($letter, 'branches', $full_suggestion->{branchcode});
C4::Letters::parseletter($letter, 'borrowers', $full_suggestion->{suggestedby});
C4::Letters::parseletter($letter, 'suggestions', $full_suggestion->{suggestionid});
C4::Letters::parseletter($letter, 'biblio', $full_suggestion->{biblionumber});
my $enqueued = C4::Letters::EnqueueLetter({
if ( my $letter = C4::Letters::GetPreparedLetter (
module => 'suggestions',
letter_code => $full_suggestion->{STATUS},
branchcode => $full_suggestion->{branchcode},
tables => {
'branches' => $full_suggestion->{branchcode},
'borrowers' => $full_suggestion->{suggestedby},
'suggestions' => $full_suggestion,
'biblio' => $full_suggestion->{biblionumber},
},
) ) {
C4::Letters::EnqueueLetter({
letter => $letter,
borrowernumber => $full_suggestion->{suggestedby},
suggestionid => $full_suggestion->{suggestionid},
LibraryName => C4::Context->preference("LibraryName"),
message_transport_type => 'email',
});
if (!$enqueued){warn "can't enqueue letter $letter";}
}) or warn "can't enqueue letter $letter";
}
}
return $status_update_table;

View File

@ -111,16 +111,11 @@ for my $vendor (@suppliers) {
for my $basket ( @{$baskets} ) {
my $authorisedby = $basket->{authorisedby};
my $basketbranch = ''; # set a blank branch to start with
if ( GetMember( borrowernumber => $authorisedby ) ) {
# authorisedby may not be a valid borrowernumber; it's not foreign-key constrained!
$basketbranch = GetMember( borrowernumber => $authorisedby )->{branchcode};
}
if ($userenv->{'flags'} & 1 || #user is superlibrarian
(haspermission( $uid, { acquisition => q{*} } ) && #user has acq permissions and
($viewbaskets eq 'all' || #user is allowed to see all baskets
($viewbaskets eq 'branch' && $authorisedby && $userbranch eq $basketbranch) || #basket belongs to user's branch
($viewbaskets eq 'branch' && $authorisedby && $userbranch eq GetMember( borrowernumber => $authorisedby )->{branchcode}) || #basket belongs to user's branch
($basket->{authorisedby} && $viewbaskets == 'user' && $authorisedby == $loggedinuser) #user created this basket
)
)

View File

@ -24,7 +24,6 @@ use strict;
#use warnings; FIXME - Bug 2505
use CGI;
use C4::Output;
use C4::Print;
use C4::Auth qw/:DEFAULT get_session/;
use C4::Dates qw/format_date/;
use C4::Branch; # GetBranches
@ -176,7 +175,7 @@ if ( $barcode eq '' && $query->param('charges') eq 'yes' ) {
}
if ( $print eq 'yes' && $borrowernumber ne '' ) {
printslip( $borrowernumber );
PrintIssueSlip($session->param('branch') || $branch, $borrowernumber);
$query->param( 'borrowernumber', '' );
$borrowernumber = '';
}

View File

@ -23,10 +23,8 @@ use strict;
use C4::Context;
use C4::Output;
use CGI;
use C4::Auth;
use C4::Auth qw/:DEFAULT get_session/;
use C4::Reserves;
use C4::Branch;
use C4::Dates qw/format_date format_date_in_iso/;
use vars qw($debug);
@ -35,13 +33,16 @@ BEGIN {
}
my $input = new CGI;
my $sessionID = $input->cookie("CGISESSID");
my $session = get_session($sessionID);
my $biblionumber = $input->param('biblionumber');
my $borrowernumber = $input->param('borrowernumber');
my $transfer = $input->param('transfer');
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
{
template_name => "circ/hold-transfer-slip.tmpl",
template_name => "circ/printslip.tmpl",
query => $input,
type => "intranet",
authnotrequired => 0,
@ -50,14 +51,21 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
}
);
my $reserveinfo = GetReserveInfo($borrowernumber,$biblionumber );
my $pulldate = C4::Dates->new();
$reserveinfo->{'pulldate'} = $pulldate->output();
$reserveinfo->{'branchname'} = GetBranchName($reserveinfo->{'branchcode'});
$reserveinfo->{'transferrequired'} = $transfer;
$template->param( reservedata => [ $reserveinfo ] ,
);
my $userenv = C4::Context->userenv;
my ($slip, $is_html);
if ( my $letter = ReserveSlip ($session->param('branch') || $userenv->{branch}, $borrowernumber, $biblionumber) ) {
$slip = $letter->{content};
$is_html = $letter->{is_html};
}
else {
$slip = "Reserve not found";
}
$template->param(
slip => $slip,
plain => !$is_html,
title => "Koha -- Circulation: Transfers",
stylesheet => C4::Context->preference("SlipCSS"),
);
output_html_with_http_headers $input, $cookie, $template->output;

View File

@ -24,11 +24,8 @@ use warnings;
use C4::Context;
use C4::Output;
use CGI;
use C4::Auth;
use C4::Biblio;
use C4::Items;
use C4::Branch;
use C4::Dates qw/format_date format_date_in_iso/;
use C4::Auth qw/:DEFAULT get_session/;
use C4::Circulation;
use vars qw($debug);
@ -37,12 +34,15 @@ BEGIN {
}
my $input = new CGI;
my $sessionID = $input->cookie("CGISESSID");
my $session = get_session($sessionID);
my $itemnumber = $input->param('transferitem');
my $branchcode = $input->param('branchcode');
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
{
template_name => "circ/transfer-slip.tmpl",
template_name => "circ/printslip.tmpl",
query => $input,
type => "intranet",
authnotrequired => 0,
@ -51,15 +51,21 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
}
);
my $pulldate = C4::Dates->new();
my $item = GetItem( $itemnumber );
my ( undef, $biblio ) = GetBiblio($item->{biblionumber});
my $userenv = C4::Context->userenv;
my ($slip, $is_html);
if ( my $letter = TransferSlip ($session->param('branch') || $userenv->{branch}, $itemnumber, $branchcode) ) {
$slip = $letter->{content};
$is_html = $letter->{is_html};
}
else {
$slip = "Item not found";
}
$template->param(
pulldate => $pulldate->output(),
branchname => GetBranchName($branchcode),
biblio => $biblio,
item => $item,
slip => $slip,
plain => !$is_html,
title => "Koha -- Circulation: Transfers",
stylesheet => C4::Context->preference("SlipCSS"),
);
output_html_with_http_headers $input, $cookie, $template->output;

View File

@ -11,7 +11,7 @@ VALUES ('circulation','ODUE','Mahnung','Mahnung','Liebe/r <<borrowers.firstname>
('reserves', 'HOLD_PRINT', 'Vormerkbenachrichtigung (Print)', 'Vormerkbenachrichtigung (Print)', '<<branches.branchname>>\r\n<<branches.branchaddress1>>\r\n<<branches.branchaddress2>>\r\n<<branches.branchaddress2>>\r\n<<branches.branchzip>> <<branches.branchcity>>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<<borrowers.firstname>> <<borrowers.surname>>\r\n<<borrowers.address>>\r\n<<borrowers.address2>>\r\n<<borrowers.zipcode>> <<borrowers.city>>\r\n<<borrowers.country>>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nLiebe(r) <<borrowers.firstname>> <<borrowers.surname>>,\r\n\r\nFür Sie liegt seit dem <<reserves.waitingdate>> eine Vormerkung zur Abholung bereit:\r\n\r\nTitel: <<biblio.title>>\r\nVerfasser: <<biblio.author>>\r\nSignatur: <<items.itemcallnumber>>\r\n'),
('circulation','CHECKIN','Rückgabequittung (Zusammenfassung)','Rückgabequittung','Die folgenden Medien wurden zurückgegeben:\r\n----\r\n<<biblio.title>>\r\n----\r\nVielen Dank.'),
('circulation','CHECKOUT','Ausleihquittung (Zusammenfassung)','Ausleihquittung','Die folgenden Medien wurden entliehen:\r\n----\r\n<<biblio.title>>\r\n----\r\nVielen Dank für Ihren Besuch in <<branches.branchname>>.'),
('reserves', 'HOLDPLACED', 'Neue Vormerkung', 'Neue Vormerkung','Folgender Titel wurde vorgemerkt: <<title>> (<<biblionumber>>) durch den Benutzer <<firstname>> <<surname>> (<<cardnumber>>).'),
('reserves', 'HOLDPLACED', 'Neue Vormerkung', 'Neue Vormerkung','Folgender Titel wurde vorgemerkt: <<biblio.title>> (<<biblio.biblionumber>>) durch den Benutzer <<borrowers.firstname>> <<borrowers.surname>> (<<borrowers.cardnumber>>).'),
('suggestions','ACCEPTED','Anschaffungsvorschlag wurde angenommen', 'Ihr Anschaffungsvorschlag wurde angenommen','Liebe(r) <<borrowers.firstname>> <<borrowers.surname>>,\n\nSie haben der Bibliothek folgendes Medium zur Anschaffung vorgeschlagen: <<suggestions.title>> by <<suggestions.author>>.\n\nDie Bibliothek hat diesen Titel heute recherchiert und wird Ihn sobald wie möglich im Buchhandel bestellen. Sie erhalten Nachricht, sobald die Bestellung abgeschlossen ist und sobald der Titel in der Bibliotek verfügbar ist.\n\nWenn Sie Fragen haben, richten Sie Ihre Mail bitte an: <<branches.branchemail>>.\n\nVielen Dank,\n\n<<branches.branchname>>'),
('suggestions','AVAILABLE','Vorgeschlagenes Medium verfügbar', 'Das vorgeschlagene Medium ist jetzt verfügbar','Liebe(r) <<borrowers.firstname>> <<borrowers.surname>>,\n\nSie haben der Bibliothek folgendes Medium zur Anschaffung vorgeschlagen: <<suggestions.title>> von <<suggestions.author>>.\n\nWir freuen uns Ihnen mitteilen zu können, dass dieser Titel jetzt im Bestand der Bibliothek verfügbar ist.\n\nWenn Sie Fragen haben, richten Sie Ihre Mail bitte an: <<branches.branchemail>>.\n\nVielen Dank,\n\n<<branches.branchname>>'),
('suggestions','ORDERED','Vorgeschlagenes Medium bestellt', 'Das vorgeschlagene Medium wurde im Buchhandel bestellt','Liebe(r) <<borrowers.firstname>> <<borrowers.surname>>,\n\nSie haben der Bibliothek folgendes Medium zur Anschaffung vorgeschlaten: <<suggestions.title>> von <<suggestions.author>>.\n\nWir freuen uns Ihnen mitteilen zu können, dass dieser Titel jetzt im Buchhandel bestellt wurde. Nach Eintreffen wird er in unseren Bestand eingearbeitet.\n\nSie erhalten Nachricht, sobald das Medium verfügbar ist.\n\nBei Nachfragen erreichen Sie uns unter der Emailadresse <<branches.branchemail>>.\n\nVielen Dank,\n\n<<branches.branchname>>'),

View File

@ -11,8 +11,97 @@ VALUES ('circulation','ODUE','Overdue Notice','Item Overdue','Dear <<borrowers.f
('reserves', 'HOLD_PRINT', 'Hold Available for Pickup (print notice)', 'Hold Available for Pickup (print notice)', '<<branches.branchname>>\r\n<<branches.branchaddress1>>\r\n<<branches.branchaddress2>>\r\n\r\n\r\nChange Service Requested\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<<borrowers.firstname>> <<borrowers.surname>>\r\n<<borrowers.address>>\r\n<<borrowers.city>> <<borrowers.zipcode>>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<<borrowers.firstname>> <<borrowers.surname>> <<borrowers.cardnumber>>\r\n\r\nYou have a hold available for pickup as of <<reserves.waitingdate>>:\r\n\r\nTitle: <<biblio.title>>\r\nAuthor: <<biblio.author>>\r\nCopy: <<items.copynumber>>\r\n'),
('circulation','CHECKIN','Item Check-in (Digest)','Check-ins','The following items have been checked in:\r\n----\r\n<<biblio.title>>\r\n----\r\nThank you.'),
('circulation','CHECKOUT','Item Check-out (Digest)','Checkouts','The following items have been checked out:\r\n----\r\n<<biblio.title>>\r\n----\r\nThank you for visiting <<branches.branchname>>.'),
('reserves', 'HOLDPLACED', 'Hold Placed on Item', 'Hold Placed on Item','A hold has been placed on the following item : <<title>> (<<biblionumber>>) by the user <<firstname>> <<surname>> (<<cardnumber>>).'),
('reserves', 'HOLDPLACED', 'Hold Placed on Item', 'Hold Placed on Item','A hold has been placed on the following item : <<biblio.title>> (<<biblio.biblionumber>>) by the user <<borrowers.firstname>> <<borrowers.surname>> (<<borrowers.cardnumber>>).'),
('suggestions','ACCEPTED','Suggestion accepted', 'Purchase suggestion accepted','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nThe library has reviewed your suggestion today. The item will be ordered as soon as possible. You will be notified by mail when the order is completed, and again when the item arrives at the library.\n\nIf you have any questions, please email us at <<branches.branchemail>>.\n\nThank you,\n\n<<branches.branchname>>'),
('suggestions','AVAILABLE','Suggestion available', 'Suggested purchase available','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nWe are pleased to inform you that the item you requested is now part of the collection.\n\nIf you have any questions, please email us at <<branches.branchemail>>.\n\nThank you,\n\n<<branches.branchname>>'),
('suggestions','ORDERED','Suggestion ordered', 'Suggested item ordered','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nWe are pleased to inform you that the item you requested has now been ordered. It should arrive soon, at which time it will be processed for addition into the collection.\n\nYou will be notified again when the book is available.\n\nIf you have any questions, please email us at <<branches.branchemail>>\n\nThank you,\n\n<<branches.branchname>>'),
('suggestions','REJECTED','Suggestion rejected', 'Purchase suggestion declined','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nThe library has reviewed your request today, and has decided not to accept the suggestion at this time.\n\nThe reason given is: <<suggestions.reason>>\n\nIf you have any questions, please email us at <<branches.branchemail>>.\n\nThank you,\n\n<<branches.branchname>>');
INSERT INTO `letter` (module, code, name, title, content, is_html)
VALUES ('circulation','ISSUESLIP','Issue Slip','Issue Slip', '<h3><<branches.branchname>></h3>
Checked out to <<borrowers.title>> <<borrowers.firstname>> <<borrowers.initials>> <<borrowers.surname>> <br />
(<<borrowers.cardnumber>>) <br />
<<today>><br />
<h4>Checked Out</h4>
<checkedout>
<p>
<<biblio.title>> <br />
Barcode: <<items.barcode>><br />
Date due: <<issues.date_due>><br />
</p>
</checkedout>
<h4>Overdues</h4>
<overdue>
<p>
<<biblio.title>> <br />
Barcode: <<items.barcode>><br />
Date due: <<issues.date_due>><br />
</p>
</overdue>
<hr>
<h4 style="text-align: center; font-style:italic;">News</h4>
<news>
<div class="newsitem">
<h5 style="margin-bottom: 1px; margin-top: 1px"><b><<opac_news.title>></b></h5>
<p style="margin-bottom: 1px; margin-top: 1px"><<opac_news.new>></p>
<p class="newsfooter" style="font-size: 8pt; font-style:italic; margin-bottom: 1px; margin-top: 1px">Posted on <<opac_news.timestamp>></p>
<hr />
</div>
</news>', 1),
('circulation','ISSUEQSLIP','Issue Quick Slip','Issue Quick Slip', '<h3><<branches.branchname>></h3>
Checked out to <<borrowers.title>> <<borrowers.firstname>> <<borrowers.initials>> <<borrowers.surname>> <br />
(<<borrowers.cardnumber>>) <br />
<<today>><br />
<h4>Checked Out Today</h4>
<checkedout>
<p>
<<biblio.title>> <br />
Barcode: <<items.barcode>><br />
Date due: <<issues.date_due>><br />
</p>
</checkedout>', 1),
('circulation','RESERVESLIP','Reserve Slip','Reserve Slip', '<h5>Date: <<today>></h5>
<h3> Transfer to/Hold in <<branches.branchname>></h3>
<h3><<borrowers.surname>>, <<borrowers.firstname>></h3>
<ul>
<li><<borrowers.cardnumber>></li>
<li><<borrowers.phone>></li>
<li> <<borrowers.address>><br />
<<borrowers.address2>><br />
<<borrowers.city >> <<borrowers.zipcode>>
</li>
<li><<borrowers.email>></li>
</ul>
<br />
<h3>ITEM ON HOLD</h3>
<h4><<biblio.title>></h4>
<h5><<biblio.author>></h5>
<ul>
<li><<items.barcode>></li>
<li><<items.itemcallnumber>></li>
<li><<reserves.waitingdate>></li>
</ul>
<p>Notes:
<pre><<reserves.reservenotes>></pre>
</p>
', 1),
('circulation','TRANSFERSLIP','Transfer Slip','Transfer Slip', '<h5>Date: <<today>></h5>
<h3>Transfer to <<branches.branchname>></h3>
<h3>ITEM</h3>
<h4><<biblio.title>></h4>
<h5><<biblio.author>></h5>
<ul>
<li><<items.barcode>></li>
<li><<items.itemcallnumber>></li>
</ul>', 1);

View File

@ -11,7 +11,7 @@ VALUES ('circulation','ODUE','Overdue Notice','Item Overdue','Dear <<borrowers.f
('reserves', 'HOLD_PRINT', 'Hold Available for Pickup (print notice)', 'Hold Available for Pickup (print notice)', '<<branches.branchname>>\r\n<<branches.branchaddress1>>\r\n<<branches.branchaddress2>>\r\n\r\n\r\nChange Service Requested\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<<borrowers.firstname>> <<borrowers.surname>>\r\n<<borrowers.address>>\r\n<<borrowers.city>> <<borrowers.zipcode>>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<<borrowers.firstname>> <<borrowers.surname>> <<borrowers.cardnumber>>\r\n\r\nYou have a hold available for pickup as of <<reserves.waitingdate>>:\r\n\r\nTitle: <<biblio.title>>\r\nAuthor: <<biblio.author>>\r\nCopy: <<items.copynumber>>\r\n'),
('circulation','CHECKIN','Item Check-in (Digest)','Check-ins','The following items have been checked in:\r\n----\r\n<<biblio.title>>\r\n----\r\nThank you.'),
('circulation','CHECKOUT','Item Check-out (Digest)','Checkouts','The following items have been checked out:\r\n----\r\n<<biblio.title>>\r\n----\r\nThank you for visiting <<branches.branchname>>.'),
('reserves', 'HOLDPLACED', 'Hold Placed on Item', 'Hold Placed on Item','A hold has been placed on the following item : <<title>> (<<biblionumber>>) by the user <<firstname>> <<surname>> (<<cardnumber>>).'),
('reserves', 'HOLDPLACED', 'Hold Placed on Item', 'Hold Placed on Item','A hold has been placed on the following item : <<biblio.title>> (<<biblio.biblionumber>>) by the user <<borrowers.firstname>> <<borrowers.surname>> (<<borrowers.cardnumber>>).'),
('suggestions','ACCEPTED','Suggestion accepted', 'Purchase suggestion accepted','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nThe library has reviewed your suggestion today. The item will be ordered as soon as possible. You will be notified by mail when the order is completed, and again when the item arrives at the library.\n\nIf you have any questions, please email us at <<branches.branchemail>>.\n\nThank you,\n\n<<branches.branchname>>'),
('suggestions','AVAILABLE','Suggestion available', 'Suggested purchase available','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nWe are pleased to inform you that the item you requested is now part of the collection.\n\nIf you have any questions, please email us at <<branches.branchemail>>.\n\nThank you,\n\n<<branches.branchname>>'),
('suggestions','ORDERED','Suggestion ordered', 'Suggested item ordered','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nWe are pleased to inform you that the item you requested has now been ordered. It should arrive soon, at which time it will be processed for addition into the collection.\n\nYou will be notified again when the book is available.\n\nIf you have any questions, please email us at <<branches.branchemail>>\n\nThank you,\n\n<<branches.branchname>>'),

View File

@ -13,7 +13,7 @@ VALUES
('reserves', 'HOLD_PRINT', 'Hold Available for Pickup (print notice)', 'Hold Available for Pickup at <<branches.branchname>>', '<<branches.branchname>>\n<<branches.branchaddress1>>\n<<branches.branchaddress2>>\n\n\nChange Service Requested\n\n\n\n\n\n\n\n<<borrowers.firstname>> <<borrowers.surname>>\n<<borrowers.address>>\n<<borrowers.city>> <<borrowers.zipcode>>\n\n\n\n\n\n\n\n\n\n\n<<borrowers.firstname>> <<borrowers.surname>> <<borrowers.cardnumber>>\n\nYou have a hold available for pickup as of <<reserves.waitingdate>>:\r\n\r\nTitle: <<biblio.title>>\r\nAuthor: <<biblio.author>>\r\nCopy: <<items.copynumber>>\r\n'),
('circulation','CHECKIN','Item Check-in (Digest)','Check-ins','The following items have been checked in:\r\n----\r\n<<biblio.title>>\r\n----\r\nThank you.'),
('circulation','CHECKOUT','Item Check-out (Digest)','Checkouts','The following items have been checked out:\r\n----\r\n<<biblio.title>>\r\n----\r\nThank you for visiting <<branches.branchname>>.'),
('reserves', 'HOLDPLACED', 'Hold Placed on Item', 'Hold Placed on Item','A hold has been placed on the following item : <<title>> (<<biblionumber>>) by the user <<firstname>> <<surname>> (<<cardnumber>>).'),
('reserves', 'HOLDPLACED', 'Hold Placed on Item', 'Hold Placed on Item','A hold has been placed on the following item : <<biblio.title>> (<<biblio.biblionumber>>) by the user <<borrowers.firstname>> <<borrowers.surname>> (<<borrowers.cardnumber>>).'),
('suggestions','ACCEPTED','Suggestion accepted', 'Purchase suggestion accepted','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nThe library has reviewed your suggestion today. The item will be ordered as soon as possible. You will be notified by mail when the order is completed, and again when the item arrives at the library.\n\nIf you have any questions, please email us at <<branches.branchemail>>.\n\nThank you,\n\n<<branches.branchname>>'),
('suggestions','AVAILABLE','Suggestion available', 'Suggested purchase available','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nWe are pleased to inform you that the item you requested is now part of the collection.\n\nIf you have any questions, please email us at <<branches.branchemail>>.\n\nThank you,\n\n<<branches.branchname>>'),
('suggestions','ORDERED','Suggestion ordered', 'Suggested item ordered','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nWe are pleased to inform you that the item you requested has now been ordered. It should arrive soon, at which time it will be processed for addition into the collection.\n\nYou will be notified again when the book is available.\n\nIf you have any questions, please email us at <<branches.branchemail>>\n\nThank you,\n\n<<branches.branchname>>'),

View File

@ -11,7 +11,7 @@ VALUES ('circulation','ODUE','Overdue Notice','Item Overdue','Dear <<borrowers.f
('reserves', 'HOLD_PRINT', 'Hold Available for Pickup (print notice)', 'Hold Available for Pickup (print notice)', '<<branches.branchname>>\r\n<<branches.branchaddress1>>\r\n<<branches.branchaddress2>>\r\n\r\n\r\nChange Service Requested\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<<borrowers.firstname>> <<borrowers.surname>>\r\n<<borrowers.address>>\r\n<<borrowers.city>> <<borrowers.zipcode>>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<<borrowers.firstname>> <<borrowers.surname>> <<borrowers.cardnumber>>\r\n\r\nYou have a hold available for pickup as of <<reserves.waitingdate>>:\r\n\r\nTitle: <<biblio.title>>\r\nAuthor: <<biblio.author>>\r\nCopy: <<items.copynumber>>\r\n'),
('circulation','CHECKIN','Item Check-in (Digest)','Check-ins','The following items have been checked in:\r\n----\r\n<<biblio.title>>\r\n----\r\nThank you.'),
('circulation','CHECKOUT','Item Check-out (Digest)','Checkouts','The following items have been checked out:\r\n----\r\n<<biblio.title>>\r\n----\r\nThank you for visiting <<branches.branchname>>.'),
('reserves', 'HOLDPLACED', 'Hold Placed on Item', 'Hold Placed on Item','A hold has been placed on the following item : <<title>> (<<biblionumber>>) by the user <<firstname>> <<surname>> (<<cardnumber>>).'),
('reserves', 'HOLDPLACED', 'Hold Placed on Item', 'Hold Placed on Item','A hold has been placed on the following item : <<biblio.title>> (<<biblio.biblionumber>>) by the user <<borrowers.firstname>> <<borrowers.surname>> (<<borrowers.cardnumber>>).'),
('suggestions','ACCEPTED','Suggestion accepted', 'Purchase suggestion accepted','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nThe library has reviewed your suggestion today. The item will be ordered as soon as possible. You will be notified by mail when the order is completed, and again when the item arrives at the library.\n\nIf you have any questions, please email us at <<branches.branchemail>>.\n\nThank you,\n\n<<branches.branchname>>'),
('suggestions','AVAILABLE','Suggestion available', 'Suggested purchase available','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nWe are pleased to inform you that the item you requested is now part of the collection.\n\nIf you have any questions, please email us at <<branches.branchemail>>.\n\nThank you,\n\n<<branches.branchname>>'),
('suggestions','ORDERED','Suggestion ordered', 'Suggested item ordered','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nWe are pleased to inform you that the item you requested has now been ordered. It should arrive soon, at which time it will be processed for addition into the collection.\n\nYou will be notified again when the book is available.\n\nIf you have any questions, please email us at <<branches.branchemail>>\n\nThank you,\n\n<<branches.branchname>>'),

View File

@ -1169,10 +1169,12 @@ DROP TABLE IF EXISTS `letter`;
CREATE TABLE `letter` ( -- table for all notice templates in Koha
`module` varchar(20) NOT NULL default '', -- Koha module that triggers this notice
`code` varchar(20) NOT NULL default '', -- unique identifier for this notice
`branchcode` varchar(10) default NULL, -- foreign key, linking to the branches table for the location the item was checked out
`name` varchar(100) NOT NULL default '', -- plain text name for this notice
`is_html` tinyint(1) default 0,
`title` varchar(200) NOT NULL default '', -- subject line of the notice
`content` text, -- body text for the notice
PRIMARY KEY (`module`,`code`)
PRIMARY KEY (`module`,`code`, `branchcode`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
@ -2273,12 +2275,13 @@ CREATE TABLE `message_transports` (
`is_digest` tinyint(1) NOT NULL default '0',
`letter_module` varchar(20) NOT NULL default '',
`letter_code` varchar(20) NOT NULL default '',
`branchcode` varchar(10) NOT NULL default '',
PRIMARY KEY (`message_attribute_id`,`message_transport_type`,`is_digest`),
KEY `message_transport_type` (`message_transport_type`),
KEY `letter_module` (`letter_module`,`letter_code`),
CONSTRAINT `message_transports_ibfk_1` FOREIGN KEY (`message_attribute_id`) REFERENCES `message_attributes` (`message_attribute_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `message_transports_ibfk_2` FOREIGN KEY (`message_transport_type`) REFERENCES `message_transport_types` (`message_transport_type`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `message_transports_ibfk_3` FOREIGN KEY (`letter_module`, `letter_code`) REFERENCES `letter` (`module`, `code`) ON DELETE CASCADE ON UPDATE CASCADE
CONSTRAINT `message_transports_ibfk_3` FOREIGN KEY (`letter_module`, `letter_code`, `branchcode`) REFERENCES `letter` (`module`, `code`, `branchcode`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--

View File

@ -32,7 +32,7 @@ VALUES ('circulation','ODUE','Purring','Purring på dokument','<<borrowers.first
('reserves', 'HOLD_PRINT', 'Hentemelding (på papir)', 'Hentemelding', '<<branches.branchname>>\r\n<<branches.branchaddress1>>\r\n<<branches.branchaddress2>>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<<borrowers.firstname>> <<borrowers.surname>>\r\n<<borrowers.address>>\r\n<<borrowers.city>> <<borrowers.zipcode>>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<<borrowers.firstname>> <<borrowers.surname>> <<borrowers.cardnumber>>\r\n\r\nDu har et reservert dokument som kan hentes fra <<reserves.waitingdate>>:\r\n\r\nTittel: <<biblio.title>>\r\nForfatter: <<biblio.author>>\r\nEksemplar: <<items.copynumber>>\r\n'),
('circulation','CHECKIN','Innlevering','Melding om innlevering','Følgende dokument har blitt innlevert:\r\n----\r\n<<biblio.title>>\r\n----\r\nVennlig hilsen\r\nBiblioteket'),
('circulation','CHECKOUT','Utlån','Melding om utlån','Følgende dokument har blitt lånt ut:\r\n----\r\n<<biblio.title>>\r\n----\r\nVennlig hilsen\r\nBiblioteket'),
('reserves', 'HOLDPLACED', 'Melding om reservasjon', 'Melding om reservasjon','Følgende dokument har blitt reservert : <<title>> (<<biblionumber>>) av <<firstname>> <<surname>> (<<cardnumber>>).'),
('reserves', 'HOLDPLACED', 'Melding om reservasjon', 'Melding om reservasjon','Følgende dokument har blitt reservert : <<biblio.title>> (<<biblio.biblionumber>>) av <<borrowers.firstname>> <<borrowers.surname>> (<<borrowers.cardnumber>>).'),
('suggestions','ACCEPTED','Forslag godtatt', 'Innkjøpsforslag godtatt','<<borrowers.firstname>> <<borrowers.surname>>,\n\nDu har foreslått at biblioteket kjøper inn <<suggestions.title>> av <<suggestions.author>>.\n\nBiblioteket har vurdert forslaget i dag. Dokumentet vil bli bestilt så fort det lar seg gjøre. Du vil få en ny melding når bestillingen er gjort, og når dokumentet ankommer biblioteket.\n\nEr det noe du lurer på, vennligst kontakt oss på <<branches.branchemail>>.\n\nVennlig hilsen,\n\n<<branches.branchname>>'),
('suggestions','AVAILABLE','Foreslått dokument tilgjengelig', 'Foreslått dokument tilgjengelig','<<borrowers.firstname>> <<borrowers.surname>>,\n\nDu har foreslått at biblioteket kjøper inn <<suggestions.title>> av <<suggestions.author>>.\n\nVi har gleden av å informere deg om at dokumentet nå er innlemmet i samlingen.\n\nEr det noe du lurer på, vennligst kontakt oss på <<branches.branchemail>>.\n\nVennlig hilsen,\n\n<<branches.branchname>>'),
('suggestions','ORDERED','Innkjøpsforslag i bestilling', 'Innkjøpsforslag i bestilling','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nDu har foreslått at biblioteket kjøper inn <<suggestions.title>> av <<suggestions.author>>.\n\nVi har gleden av å informere deg om at dokumentet du foreslo nå er i bestilling.\n\nDu vil få en ny melding når dokumentet er tilgjengelig.\n\nEr det noe du lurer på, vennligst kontakt oss på <<branches.branchemail>>.\n\nVennlig hilsen,\n\n<<branches.branchname>>'),

View File

@ -13,7 +13,7 @@ VALUES
('reserves', 'HOLD_PRINT', 'Hold Available for Pickup (print notice)', 'Hold Available for Pickup (print notice)', '<<branches.branchname>>\r\n<<branches.branchaddress1>>\r\n<<branches.branchaddress2>>\r\n\r\n\r\nChange Service Requested\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<<borrowers.firstname>> <<borrowers.surname>>\r\n<<borrowers.address>>\r\n<<borrowers.city>> <<borrowers.zipcode>>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<<borrowers.firstname>> <<borrowers.surname>> <<borrowers.cardnumber>>\r\n\r\nYou have a hold available for pickup as of <<reserves.waitingdate>>:\r\n\r\nTitle: <<biblio.title>>\r\nAuthor: <<biblio.author>>\r\nCopy: <<items.copynumber>>\r\n'),
('circulation','CHECKIN','Item Check-in (Digest)','Check-ins','The following items have been checked in:\r\n----\r\n<<biblio.title>>\r\n----\r\nThank you.'),
('circulation','CHECKOUT','Item Check-out (Digest)','Checkouts','The following items have been checked out:\r\n----\r\n<<biblio.title>>\r\n----\r\nThank you for visiting <<branches.branchname>>.'),
('reserves', 'HOLDPLACED', 'Hold Placed on Item', 'Hold Placed on Item','A hold has been placed on the following item : <<title>> (<<biblionumber>>) by the user <<firstname>> <<surname>> (<<cardnumber>>).'),
('reserves', 'HOLDPLACED', 'Hold Placed on Item', 'Hold Placed on Item','A hold has been placed on the following item : <<biblio.title>> (<<biblio.biblionumber>>) by the user <<borrowers.firstname>> <<borrowers.surname>> (<<borrowers.cardnumber>>).'),
('suggestions','ACCEPTED','Suggestion accepted', 'Purchase suggestion accepted','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nThe library has reviewed your suggestion today. The item will be ordered as soon as possible. You will be notified by mail when the order is completed, and again when the item arrives at the library.\n\nIf you have any questions, please email us at <<branches.branchemail>>.\n\nThank you,\n\n<<branches.branchname>>'),
('suggestions','AVAILABLE','Suggestion available', 'Suggested purchase available','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nWe are pleased to inform you that the item you requested is now part of the collection.\n\nIf you have any questions, please email us at <<branches.branchemail>>.\n\nThank you,\n\n<<branches.branchname>>'),
('suggestions','ORDERED','Suggestion ordered', 'Suggested item ordered','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nWe are pleased to inform you that the item you requested has now been ordered. It should arrive soon, at which time it will be processed for addition into the collection.\n\nYou will be notified again when the book is available.\n\nIf you have any questions, please email us at <<branches.branchemail>>\n\nThank you,\n\n<<branches.branchname>>'),

View File

@ -11,7 +11,7 @@ VALUES ('circulation','ODUE','Overdue Notice','Item Overdue','Dear <<borrowers.f
('reserves', 'HOLD_PRINT', 'Hold Available for Pickup (print notice)', 'Hold Available for Pickup (print notice)', '<<branches.branchname>>\r\n<<branches.branchaddress1>>\r\n<<branches.branchaddress2>>\r\n\r\n\r\nChange Service Requested\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<<borrowers.firstname>> <<borrowers.surname>>\r\n<<borrowers.address>>\r\n<<borrowers.city>> <<borrowers.zipcode>>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<<borrowers.firstname>> <<borrowers.surname>> <<borrowers.cardnumber>>\r\n\r\nYou have a hold available for pickup as of <<reserves.waitingdate>>:\r\n\r\nTitle: <<biblio.title>>\r\nAuthor: <<biblio.author>>\r\nCopy: <<items.copynumber>>\r\n'),
('circulation','CHECKIN','Item Check-in (Digest)','Check-ins','The following items have been checked in:\r\n----\r\n<<biblio.title>>\r\n----\r\nThank you.'),
('circulation','CHECKOUT','Item Check-out (Digest)','Checkouts','The following items have been checked out:\r\n----\r\n<<biblio.title>>\r\n----\r\nThank you for visiting <<branches.branchname>>.'),
('reserves', 'HOLDPLACED', 'Hold Placed on Item', 'Hold Placed on Item','A hold has been placed on the following item : <<title>> (<<biblionumber>>) by the user <<firstname>> <<surname>> (<<cardnumber>>).'),
('reserves', 'HOLDPLACED', 'Hold Placed on Item', 'Hold Placed on Item','A hold has been placed on the following item : <<biblio.title>> (<<biblio.biblionumber>>) by the user <<borrowers.firstname>> <<borrowers.surname>> (<<borrowers.cardnumber>>).'),
('suggestions','ACCEPTED','Suggestion accepted', 'Purchase suggestion accepted','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nThe library has reviewed your suggestion today. The item will be ordered as soon as possible. You will be notified by mail when the order is completed, and again when the item arrives at the library.\n\nIf you have any questions, please email us at <<branches.branchemail>>.\n\nThank you,\n\n<<branches.branchname>>'),
('suggestions','AVAILABLE','Suggestion available', 'Suggested purchase available','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nWe are pleased to inform you that the item you requested is now part of the collection.\n\nIf you have any questions, please email us at <<branches.branchemail>>.\n\nThank you,\n\n<<branches.branchname>>'),
('suggestions','ORDERED','Suggestion ordered', 'Suggested item ordered','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nWe are pleased to inform you that the item you requested has now been ordered. It should arrive soon, at which time it will be processed for addition into the collection.\n\nYou will be notified again when the book is available.\n\nIf you have any questions, please email us at <<branches.branchemail>>\n\nThank you,\n\n<<branches.branchname>>'),

View File

@ -331,7 +331,10 @@ INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('EasyAnalyticalRecords','0','If on, display in the catalogue screens tools to easily setup analytical record relationships','','YesNo');
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacShowRecentComments',0,'If ON a link to recent comments will appear in the OPAC masthead',NULL,'YesNo');
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('CircAutoPrintQuickSlip', '1', 'Choose what should happen when an empty barcode field is submitted in circulation: Display a print quick slip window or Clear the screen.',NULL,'YesNo');
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('NoticeCSS','','Notices CSS url.',NULL,'free');
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('SlipCSS','','Slips CSS url.',NULL,'free');
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('TransferWhenCancelAllWaitingHolds','0','Transfer items when cancelling all waiting holds',NULL,'YesNo');
>>>>>>> kc/master
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('OPACLocalCoverImages','0','Display local cover images on OPAC search and details pages.','1','YesNo');
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('LocalCoverImages','0','Display local cover images on intranet details pages.','1','YesNo');
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('AllowMultipleCovers','0','Allow multiple cover images to be attached to each bibliographic record.','1','YesNo');

View File

@ -10,7 +10,7 @@ VALUES ('circulation','ODUE','Overdue Notice','Item Overdue','Dear <<borrowers.f
('reserves', 'HOLD', 'Hold Available for Pickup', 'Hold Available for Pickup at <<branches.branchname>>', 'Dear <<borrowers.firstname>> <<borrowers.surname>>,\r\n\r\nYou have a hold available for pickup as of <<reserves.waitingdate>>:\r\n\r\nTitle: <<biblio.title>>\r\nAuthor: <<biblio.author>>\r\nCopy: <<items.copynumber>>\r\nLocation: <<branches.branchname>>\r\n<<branches.branchaddress1>>\r\n<<branches.branchaddress2>>\r\n<<branches.branchaddress3>>\r\n<<branches.branchcity>> <<branches.branchzip>>'),
('circulation','CHECKIN','Item Check-in (Digest)','Check-ins','The following items have been checked in:\r\n----\r\n<<biblio.title>>\r\n----\r\nThank you.'),
('circulation','CHECKOUT','Item Check-out (Digest)','Checkouts','The following items have been checked out:\r\n----\r\n<<biblio.title>>\r\n----\r\nThank you for visiting <<branches.branchname>>.'),
('reserves', 'HOLDPLACED', 'Hold Placed on Item', 'Hold Placed on Item','A hold has been placed on the following item : <<title>> (<<biblionumber>>) by the user <<firstname>> <<surname>> (<<cardnumber>>).'),
('reserves', 'HOLDPLACED', 'Hold Placed on Item', 'Hold Placed on Item','A hold has been placed on the following item : <<biblio.title>> (<<biblio.biblionumber>>) by the user <<borrowers.firstname>> <<borrowers.surname>> (<<borrowers.cardnumber>>).'),
('suggestions','ACCEPTED','Suggestion accepted', 'Purchase suggestion accepted','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nThe library has reviewed your suggestion today. The item will be ordered as soon as possible. You will be notified by mail when the order is completed, and again when the item arrives at the library.\n\nIf you have any questions, please email us at <<branches.branchemail>>.\n\nThank you,\n\n<<branches.branchname>>'),
('suggestions','AVAILABLE','Suggestion available', 'Suggested purchase available','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nWe are pleased to inform you that the item you requested is now part of the collection.\n\nIf you have any questions, please email us at <<branches.branchemail>>.\n\nThank you,\n\n<<branches.branchname>>'),
('suggestions','ORDERED','Suggestion ordered', 'Suggested item ordered','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nWe are pleased to inform you that the item you requested has now been ordered. It should arrive soon, at which time it will be processed for addition into the collection.\n\nYou will be notified again when the book is available.\n\nIf you have any questions, please email us at <<branches.branchemail>>\n\nThank you,\n\n<<branches.branchname>>'),

111
installer/data/mysql/updatedatabase.pl Executable file → Normal file
View File

@ -4497,7 +4497,6 @@ if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
print "Upgrade to $DBversion done (Add 461 subfield 9 to default framework)\n";
SetVersion ($DBversion);
}
}
$DBversion = "3.05.00.018";
@ -4775,6 +4774,116 @@ if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
SetVersion($DBversion);
}
$DBversion = "3.07.00.XXX";
if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
$dbh->do("ALTER TABLE `message_transports` DROP FOREIGN KEY `message_transports_ibfk_3`");
$dbh->do("ALTER TABLE `letter` DROP PRIMARY KEY");
$dbh->do("ALTER TABLE `letter` ADD `branchcode` varchar(10) default NULL AFTER `code`");
$dbh->do("ALTER TABLE `letter` ADD PRIMARY KEY (`module`,`code`, `branchcode`)");
$dbh->do("ALTER TABLE `message_transports` ADD `branchcode` varchar(10) NOT NULL default ''");
$dbh->do("ALTER TABLE `message_transports` ADD CONSTRAINT `message_transports_ibfk_3` FOREIGN KEY (`letter_module`, `letter_code`, `branchcode`) REFERENCES `letter` (`module`, `code`, `branchcode`) ON DELETE CASCADE ON UPDATE CASCADE");
$dbh->do("ALTER TABLE `letter` ADD `is_html` tinyint(1) default 0 AFTER `name`");
$dbh->do("INSERT INTO `letter` (module, code, name, title, content, is_html)
VALUES ('circulation','ISSUESLIP','Issue Slip','Issue Slip', '<h3><<branches.branchname>></h3>
Checked out to <<borrowers.title>> <<borrowers.firstname>> <<borrowers.initials>> <<borrowers.surname>> <br />
(<<borrowers.cardnumber>>) <br />
<<today>><br />
<h4>Checked Out</h4>
<checkedout>
<p>
<<biblio.title>> <br />
Barcode: <<items.barcode>><br />
Date due: <<issues.date_due>><br />
</p>
</checkedout>
<h4>Overdues</h4>
<overdue>
<p>
<<biblio.title>> <br />
Barcode: <<items.barcode>><br />
Date due: <<issues.date_due>><br />
</p>
</overdue>
<hr>
<h4 style=\"text-align: center; font-style:italic;\">News</h4>
<news>
<div class=\"newsitem\">
<h5 style=\"margin-bottom: 1px; margin-top: 1px\"><b><<opac_news.title>></b></h5>
<p style=\"margin-bottom: 1px; margin-top: 1px\"><<opac_news.new>></p>
<p class=\"newsfooter\" style=\"font-size: 8pt; font-style:italic; margin-bottom: 1px; margin-top: 1px\">Posted on <<opac_news.timestamp>></p>
<hr />
</div>
</news>', 1)");
$dbh->do("INSERT INTO `letter` (module, code, name, title, content, is_html)
VALUES ('circulation','ISSUEQSLIP','Issue Quick Slip','Issue Quick Slip', '<h3><<branches.branchname>></h3>
Checked out to <<borrowers.title>> <<borrowers.firstname>> <<borrowers.initials>> <<borrowers.surname>> <br />
(<<borrowers.cardnumber>>) <br />
<<today>><br />
<h4>Checked Out Today</h4>
<checkedout>
<p>
<<biblio.title>> <br />
Barcode: <<items.barcode>><br />
Date due: <<issues.date_due>><br />
</p>
</checkedout>', 1)");
$dbh->do("INSERT INTO `letter` (module, code, name, title, content, is_html)
VALUES ('circulation','RESERVESLIP','Reserve Slip','Reserve Slip', '<h5>Date: <<today>></h5>
<h3> Transfer to/Hold in <<branches.branchname>></h3>
<h3><<borrowers.surname>>, <<borrowers.firstname>></h3>
<ul>
<li><<borrowers.cardnumber>></li>
<li><<borrowers.phone>></li>
<li> <<borrowers.address>><br />
<<borrowers.address2>><br />
<<borrowers.city >> <<borrowers.zipcode>>
</li>
<li><<borrowers.email>></li>
</ul>
<br />
<h3>ITEM ON HOLD</h3>
<h4><<biblio.title>></h4>
<h5><<biblio.author>></h5>
<ul>
<li><<items.barcode>></li>
<li><<items.itemcallnumber>></li>
<li><<reserves.waitingdate>></li>
</ul>
<p>Notes:
<pre><<reserves.reservenotes>></pre>
</p>', 1)");
$dbh->do("INSERT INTO `letter` (module, code, name, title, content, is_html)
VALUES ('circulation','TRANSFERSLIP','Transfer Slip','Transfer Slip', '<h5>Date: <<today>></h5>
<h3>Transfer to <<branches.branchname>></h3>
<h3>ITEM</h3>
<h4><<biblio.title>></h4>
<h5><<biblio.author>></h5>
<ul>
<li><<items.barcode>></li>
<li><<items.itemcallnumber>></li>
</ul>', 1)");
$dbh->do("INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('NoticeCSS','','Notices CSS url.',NULL,'free')");
$dbh->do("INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('SlipCSS','','Slips CSS url.',NULL,'free')");
$dbh->do("UPDATE `letter` SET content = replace(content, '<<title>>', '<<biblio.title>>') WHERE code = 'HOLDPLACED'");
print "Upgrade to $DBversion done (Add branchcode and is_html to letter table; Default ISSUESLIP, RESERVESLIP and TRANSFERSLIP letters; Add NoticeCSS and SlipCSS sysprefs)\n";
SetVersion($DBversion);
}
=head1 FUNCTIONS
=head2 DropAllForeignKeys($table)

View File

@ -42,8 +42,10 @@ function update_child() {
});
// YUI Toolbar Functions
var slip_re = /slip/;
function printx_window(print_type) {
window.open("/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]&amp;print=" + print_type, "printwindow");
var handler = print_type.match(slip_re) ? "printslip" : "moremember";
window.open("/cgi-bin/koha/members/" + handler + ".pl?borrowernumber=[% borrowernumber %]&amp;print=" + print_type, "printwindow");
return false;
}
function searchToHold(){

View File

@ -98,6 +98,11 @@ Circulation:
yes: "open a print quick slip window"
no: "clear the screen"
- .
-
- Include the stylesheet at
- pref: NoticeCSS
class: url
- on Notices. (This should be a complete URL, starting with <code>http://</code>)
Checkout Policy:
-
- pref: AllowNotForLoanOverride

View File

@ -83,6 +83,11 @@ Staff Client:
Results: "Results page (for future use, Results XSLT not functional at this time)."
Both: "Both Results and Details pages (for future use, Results XSLT not functional at this time)."
- 'Note: The corresponding XSLT option must be turned on.'
-
- Include the stylesheet at
- pref: SlipCSS
class: url
- on Issue and Reserve Slips. (This should be a complete URL, starting with <code>http://</code>.)
Options:
-
- pref: viewMARC

View File

@ -8,11 +8,7 @@
-->
</style>
[% IF ( stylesheet ) %]
<style type="text/css">
<!--
[% stylesheet %]
-->
</style>
<link rel="stylesheet" type="text/css" href="[% stylesheet %]">
[% END %]
</head>
<body>

View File

@ -1,54 +0,0 @@
[% INCLUDE 'doc-head-open.inc' %]
<title>Koha -- Circulation: Transfers</title>
[% INCLUDE 'doc-head-close-receipt.inc' %]
<script language="javascript">
function printandclose()
{
window.print();
window.close();
}
</script>
</head>
<body onload="printandclose();"><div id="main">
[% FOREACH reservedat IN reservedata %]
<h5>Date: [% reservedat.pulldate %]</h5>
<h3> [% IF ( reservedat.transferrequired ) %]Transfer to [% reservedat.branchname %] [% ELSE %]Hold in [% reservedat.branchname %][% END %]</h3>
<div id="reserve_display">
<h3>[% reservedat.surname %], [% reservedat.firstname %]</h3>
<ul>
<li>[% reservedat.cardnumber %]</li>
[% IF ( reservedat.phone ) %]
<li>[% reservedat.phone %]</li>
[% END %]
<li>
[% reservedat.address %]<br />
[% IF ( reservedat.address2 ) %][% reservedat.address2 %]<br />[% END %]
[% reservedat.city %] [% reservedat.zip %]
</li>
[% IF ( reservedat.email ) %]
<li>[% reservedat.email %]</li>
[% END %]
</ul>
<br />
<h3>ITEM ON HOLD</h3>
<h4>[% reservedat.title |html %]</h4>
<h5>[% reservedat.author %] </h5>
<ul>
[% IF ( reservedat.barcode ) %]<li>[% reservedat.barcode %]</li>[% END %]
[% IF ( reservedat.itemcallnumber ) %]<li>[% reservedat.itemcallnumber %]</li>[% END %]
[% IF ( reservedat.waitingdate ) %]<li>[% reservedat.waitingdate %]</li>[% END %]
</ul>
[% IF ( reservedat.reservenotes ) %]
<p>Notes: [% reservedat.reservenotes %]</p>
[% END %]
[% END %]
</div>
[% INCLUDE 'intranet-bottom.inc' %]

View File

@ -0,0 +1,28 @@
[% INCLUDE 'doc-head-open.inc' %]
<title>[% title %]</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="shortcut icon" href="[% IF ( IntranetFavicon ) %][% IntranetFavicon %][% ELSE %][% themelang %]/includes/favicon.ico[% END %]" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="[% themelang %]/css/print.css" />
[% IF stylesheet %]
<link rel="stylesheet" type="text/css" href="[% stylesheet %]" />
[% END %]
<script language="javascript">
function printThenClose() {
window.print();
window.close();
}
</script>
</head>
<body onload="printThenClose();">
<div id="receipt">
[% IF plain %]
<pre>
[% slip %]
</pre>
[% ELSE %]
[% slip %]
[% END %]
[% INCLUDE 'intranet-bottom.inc' %]

View File

@ -5,14 +5,29 @@
<script type="text/javascript">
//<![CDATA[
$(document).ready(function() {
$("#lettert").tablesorter({
$("#lettert:has(tbody tr)").tablesorter({
widgets : ['zebra'],
sortList: [[0,0]],
headers: { 3: {sorter:false},4: { sorter: false }}
});
$('#branch').change(function() {
$('#op').val("");
$('#selectlibrary').submit();
});
$('#newnotice').click(function() {
$('#op').val("add_form");
return true;
});
});
[% IF ( add_form ) %]
function cancel(f) {
$('#op').val("");
f.method = "get";
f.submit();
}
function isNotNull(f,noalert) {
if (f.value.length ==0) {
return false;
@ -106,7 +121,7 @@ $(document).ready(function() {
[% INCLUDE 'header.inc' %]
[% INCLUDE 'letters-search.inc' %]
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> &rsaquo; [% IF ( add_form ) %][% IF ( modify ) %]<a href="/cgi-bin/koha/tools/letter.pl">Notices</a> &rsaquo; Modify notice[% ELSE %] <a href="/cgi-bin/koha/tools/letter.pl">Notices</a> &rsaquo; Add notice[% END %][% ELSE %][% IF ( add_validate ) %] <a href="/cgi-bin/koha/tools/letter.pl">Notices</a> &rsaquo; Notice added[% ELSE %][% IF ( delete_confirm ) %] <a href="/cgi-bin/koha/tools/letter.pl">Notices</a> &rsaquo; Confirm Deletion[% ELSE %]Notices[% END %][% END %][% END %]</div>
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> &rsaquo; [% IF ( add_form ) %][% IF ( modify ) %]<a href="/cgi-bin/koha/tools/letter.pl">Notices &amp; Slips</a> &rsaquo; Modify notice[% ELSE %] <a href="/cgi-bin/koha/tools/letter.pl">Notices &amp; Slips</a> &rsaquo; Add notice[% END %][% ELSE %][% IF ( add_validate ) %] <a href="/cgi-bin/koha/tools/letter.pl">Notices &amp; Slips</a> &rsaquo; Notice added[% ELSE %][% IF ( delete_confirm ) %] <a href="/cgi-bin/koha/tools/letter.pl">Notices &amp; Slips</a> &rsaquo; Confirm Deletion[% ELSE %]Notices &amp; Slips[% END %][% END %][% END %]</div>
[% IF ( add_form ) %]<div id="doc" class="yui-t7">[% ELSE %]<div id="doc3" class="yui-t2">[% END %]
@ -114,65 +129,97 @@ $(document).ready(function() {
<div id="yui-main">
<div class="yui-b">
[% IF ( no_op_set ) %]
<div id="toolbar">
<script type="text/javascript">
//<![CDATA[
// prepare DOM for YUI Toolbar
$(document).ready(function() {
yuiToolbar();
});
// YUI Toolbar Functions
function yuiToolbar() {
new YAHOO.widget.Button("newnotice");
}
//]]>
</script>
<ul class="toolbar">
<li><a id="newnotice" href="/cgi-bin/koha/tools/letter.pl?op=add_form">New Notice</a></li>
</ul></div>
[% IF ( no_op_set ) %]
<form method="get" action="?" id="selectlibrary">
<input type="hidden" name="searchfield" value="[% searchfield %]" />
[% UNLESS independant_branch %]
<p>
Select a library :
<select name="branchcode" id="branch" style="width:20em;">
<option value="">All libraries</option>
[% FOREACH branchloo IN branchloop %]
[% IF ( branchloo.selected ) %]<option value="[% branchloo.value %]" selected="selected">[% branchloo.branchname %]</option>[% ELSE %]<option value="[% branchloo.value %]">[% branchloo.branchname %]</option>[% END %]
[% END %]
</select>
</p>
[% END %]
<p>
<input type="submit" id="newnotice" value="New Notice" />
<input type="hidden" id="op" name="op" />
</p>
</form>
[% IF ( search ) %]
<p>You Searched for <b>[% searchfield %]</b></p>
[% END %]
[% IF ( letter ) %]<table id="lettert">
[% IF ( letter && !independant_branch) %]
[% select_for_copy = BLOCK %]
<select name="branchcode">
[% FOREACH branchloo IN branchloop %]
<option value="[% branchloo.value %]">[% branchloo.branchname %]</option>
[% END %]
</select>
[% END %]
[% END %]
<table id="lettert">
<thead><tr>
<th>Branch</th>
<th>Module</th>
<th>Code</th>
<th>Name</th>
<th>&nbsp;</th>
<th>&nbsp;</th>
<th>&nbsp;</th>
</tr></thead>
<tbody>[% FOREACH lette IN letter %]
[% UNLESS ( loop.odd ) %]
<tbody>
[% FOREACH lette IN letter %]
[% can_edit = lette.branchcode || !independant_branch %]
[% UNLESS ( loop.odd ) %]
<tr class="highlight">
[% ELSE %]
[% ELSE %]
<tr>
[% END %]
[% END %]
<td>[% lette.branchname || "(All libraries)" %]</td>
<td>[% lette.module %]</td>
<td>[% lette.code %]</td>
<td>[% lette.name %]</td>
<td>
<a href="/cgi-bin/koha/tools/letter.pl?op=add_form&amp;module=[% lette.module %]&amp;code=[% lette.code %]">Edit</a>
[% IF can_edit %]
<a href="/cgi-bin/koha/tools/letter.pl?op=add_form&branchcode=[% lette.branchcode %]&module=[% lette.module %]&code=[% lette.code %]">Edit</a>
[% END %]
</td>
<td>
[% IF ( lette.protected ) %]
-
[% ELSE %]
<a href="/cgi-bin/koha/tools/letter.pl?op=delete_confirm&amp;module=[% lette.module %]&amp;code=[% lette.code %]">Delete</a>
[% END %]
[% IF !independant_branch || !lette.branchcode %]
<form method="post" action="?">
<input type="hidden" name="op" value="copy" />
<input type="hidden" name="oldbranchcode" value="[% lette.branchcode %]" />
<input type="hidden" name="module" value="[% lette.module %]" />
<input type="hidden" name="code" value="[% lette.code %]" />
[% IF independant_branch %]
<input type="hidden" name="branchcode" value="[% independant_branch %]" />
[% ELSE %]
[% select_for_copy %]
[% END %]
<input type="submit" value="Copy" />
</form>
[% END %]
</td>
<td>
[% IF !lette.protected && can_edit %]
<a href="/cgi-bin/koha/tools/letter.pl?op=delete_confirm&branchcode=[%lette.branchcode %]&module=[% lette.module %]&code=[% lette.code %]">Delete</a>
[% END %]
</td>
</tr>
[% END %]</tbody>
[% END %]
</tbody>
</table>
[% END %]
[% END %]
[% END %]
[% IF ( add_form ) %]
[% IF ( add_form ) %]
<form action="/cgi-bin/koha/tools/letter.pl" name="Aform" method="post">
<input type="hidden" name="op" value="add_validate" />
<form action="?" name="Aform" method="post">
<input type="hidden" name="op" id="op" value="add_validate" />
<input type="hidden" name="checked" value="0" />
[% IF ( modify ) %]
<input type="hidden" name="add" value="0" />
@ -182,6 +229,20 @@ $(document).ready(function() {
<fieldset class="rows">
<legend>[% IF ( modify ) %]Modify notice[% ELSE %]Add notice[% END %]</legend>
<ol>
<input type="hidden" name="oldbranchcode" value="[% branchcode %]" />
[% IF independant_branch %]
<input type="hidden" name="branchcode" value="[% independant_branch %]" />
[% ELSE %]
<li>
<label for="branchcode">Library:</label>
<select name="branchcode" id="branch" style="width:20em;">
<option value="">All libraries</option>
[% FOREACH branchloo IN branchloop %]
[% IF ( branchloo.selected ) %]<option value="[% branchloo.value %]" selected="selected">[% branchloo.branchname %]</option>[% ELSE %]<option value="[% branchloo.value %]">[% branchloo.branchname %]</option>[% END %]
[% END %]
</select>
</li>
[% END %]
<li>
<label for="module">Koha module:</label>
<input type="hidden" name="oldmodule" value="[% module %]" />
@ -234,6 +295,14 @@ $(document).ready(function() {
<li>
<label for="name">Name:</label><input type="text" id="name" name="name" size="60" value="[% name %]" />
</li>
<li>
<label for="is_html">HTML Message:</label>
[% IF is_html %]
<input type="checkbox" id="is_html" name="is_html" value="1" checked />
[% ELSE %]
<input type="checkbox" id="is_html" name="is_html" value="1" />
[% END %]
</li>
<li>
<label for="title">Message Subject:</label><input type="text" id="title" name="title" size="60" value="[% title %]" />
</li>
@ -252,27 +321,31 @@ $(document).ready(function() {
</ol>
</fieldset>
<fieldset class="action"><input type="button" value="Submit" onclick="Check(this.form)" class="button" /></fieldset>
<fieldset class="action"><input type="button" value="Cancel" onclick="cancel(this.form)" class="button" /></fieldset>
<input type="hidden" name="searchfield" value="[% searchfield %]" />
</form>
[% END %]
[% END %]
[% IF ( add_validate ) %]
[% IF ( add_validate ) %]
Data recorded
<form action="[% action %]" method="post">
<input type="submit" value="OK" />
</form>
[% END %]
[% END %]
[% IF ( delete_confirm ) %]
[% IF ( delete_confirm ) %]
<div class="dialog alert"><h3>Delete Notice?</h3>
<table>
<thead>
<tr>
<th>Branch</th>
<th>Module</th>
<th>Code</th>
<th>Name</th>
</tr>
</thead>
<tr>
<td>[% branchname %]</td>
<td>[% module %]</td>
<td>[% code %]</td>
<td>[% name %]</td>
@ -280,6 +353,7 @@ $(document).ready(function() {
</table>
<form action="[% action %]" method="post">
<input type="hidden" name="op" value="delete_confirmed">
<input type="hidden" name="branchcode" value="[% branchcode %]" />
<input type="hidden" name="code" value="[% code %]" />
<input type="hidden" name="module" value="[% module %]" />
<input type="submit" value="Yes, Delete" class="approve" />
@ -290,14 +364,14 @@ $(document).ready(function() {
</form>
</div>
[% END %]
[% END %]
[% IF ( delete_confirmed ) %]
[% IF ( delete_confirmed ) %]
Data deleted
<form action="[% action %]" method="post">
<input type="submit" value="OK" />
</form>
[% END %]
[% END %]
</div>
</div>

View File

@ -26,7 +26,7 @@
[% END %]
[% IF ( CAN_user_tools_edit_notices ) %]
<dt><a href="/cgi-bin/koha/tools/letter.pl">Notices</a></dt>
<dt><a href="/cgi-bin/koha/tools/letter.pl">Notices &amp; Slips</a></dt>
<dd>Define notices (print and email notification messages for overdues, etc.)</dd>
[% END %]

View File

@ -347,10 +347,7 @@ if ((!$nok) and $nodouble and ($op eq 'insert' or $op eq 'save')){
# if we manage to find a valid email address, send notice
if ($emailaddr) {
$newdata{emailaddr} = $emailaddr;
my $letter = getletter ('members', "ACCTDETAILS:$newdata{'branchcode'}") ;
# if $branch notice fails, then email a default notice instead.
$letter = getletter ('members', "ACCTDETAILS") if !$letter;
SendAlerts ( 'members' , \%newdata , $letter ) if $letter
SendAlerts ( 'members', \%newdata, "ACCTDETAILS" );
}
}

View File

@ -51,7 +51,6 @@ use C4::Reserves;
use C4::Branch; # GetBranchName
use C4::Overdues qw/CheckBorrowerDebarred/;
use C4::Form::MessagingPreferences;
use C4::NewsChannels; #get slip news
use List::MoreUtils qw/uniq/;
use C4::Members::Attributes qw(GetBorrowerAttributes);
@ -484,13 +483,4 @@ $template->param(
activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
);
#Get the slip news items
my $all_koha_news = &GetNewsToDisplay("slip");
my $koha_news_count = scalar @$all_koha_news;
$template->param(
koha_news => $all_koha_news,
koha_news_count => $koha_news_count
);
output_html_with_http_headers $input, $cookie, $template->output;

92
members/printslip.pl Executable file
View File

@ -0,0 +1,92 @@
#!/usr/bin/perl
# Copyright 2000-2002 Katipo Communications
# Copyright 2010 BibLibre
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
=head1 moremember.pl
script to do a borrower enquiry/bring up borrower details etc
Displays all the details about a borrower
written 20/12/99 by chris@katipo.co.nz
last modified 21/1/2000 by chris@katipo.co.nz
modified 31/1/2001 by chris@katipo.co.nz
to not allow items on request to be renewed
needs html removed and to use the C4::Output more, but its tricky
=cut
use strict;
#use warnings; FIXME - Bug 2505
use CGI;
use C4::Context;
use C4::Auth qw/:DEFAULT get_session/;
use C4::Output;
use C4::Members;
use C4::Koha;
#use Smart::Comments;
#use Data::Dumper;
use vars qw($debug);
BEGIN {
$debug = $ENV{DEBUG} || 0;
}
my $input = new CGI;
my $sessionID = $input->cookie("CGISESSID");
my $session = get_session($sessionID);
$debug or $debug = $input->param('debug') || 0;
my $print = $input->param('print');
my $error = $input->param('error');
# circ staff who process checkouts but can't edit
# patrons still need to be able to print receipts
my $flagsrequired = { circulate => "circulate_remaining_permissions" };
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
{
template_name => "circ/printslip.tmpl",
query => $input,
type => "intranet",
authnotrequired => 0,
flagsrequired => $flagsrequired,
debug => 1,
}
);
my $borrowernumber = $input->param('borrowernumber');
my $branch=C4::Context->userenv->{'branch'};
my ($slip, $is_html);
if (my $letter = IssueSlip ($session->param('branch') || $branch, $borrowernumber, $print eq "qslip")) {
$slip = $letter->{content};
$is_html = $letter->{is_html};
}
$template->param(
slip => $slip,
plain => !$is_html,
title => "Print Receipt for $borrowernumber",
stylesheet => C4::Context->preference("SlipCSS"),
error => $error,
);
output_html_with_http_headers $input, $cookie, $template->output;

View File

@ -79,13 +79,10 @@ patrons. It queues them in the message queue, which is processed by
the process_message_queue.pl cronjob.
See the comments in the script for directions on changing the script.
This script has the following parameters :
-c Confirm and remove this help & warning
-m maximum number of days in advance to send advance notices.
-n send No mail. Instead, all mail messages are printed on screen. Usefull for testing purposes.
-v verbose
-i csv list of fields that get substituted into templates in places
of the E<lt>E<lt>items.contentE<gt>E<gt> placeholder. Defaults to
issuedate,title,barcode,author
-c Confirm and remove this help & warning
-m maximum number of days in advance to send advance notices.
-n send No mail. Instead, all mail messages are printed on screen. Usefull for testing purposes.
-v verbose
ENDUSAGE
# Since advance notice options are not visible in the web-interface
@ -157,8 +154,6 @@ UPCOMINGITEM: foreach my $upcoming ( @$upcoming_dues ) {
} else {
my $biblio = C4::Biblio::GetBiblioFromItemNumber( $upcoming->{'itemnumber'} );
my $letter_type = 'DUE';
$letter = C4::Letters::getletter( 'circulation', $letter_type );
die "no letter of type '$letter_type' found. Please see sample_notices.sql" unless $letter;
$sth->execute($upcoming->{'borrowernumber'},$upcoming->{'itemnumber'},'0');
my $titles = "";
while ( my $item_info = $sth->fetchrow_hashref()) {
@ -166,13 +161,14 @@ UPCOMINGITEM: foreach my $upcoming ( @$upcoming_dues ) {
$titles .= join("\t",@item_info) . "\n";
}
$letter = parse_letter( { letter => $letter,
$letter = parse_letter( { letter_code => $letter_type,
borrowernumber => $upcoming->{'borrowernumber'},
branchcode => $upcoming->{'branchcode'},
biblionumber => $biblio->{'biblionumber'},
itemnumber => $upcoming->{'itemnumber'},
substitute => { 'items.content' => $titles }
} );
} )
or die "no letter of type '$letter_type' found. Please see sample_notices.sql";
}
} else {
$borrower_preferences = C4::Members::Messaging::GetMessagingPreferences( { borrowernumber => $upcoming->{'borrowernumber'},
@ -189,8 +185,6 @@ UPCOMINGITEM: foreach my $upcoming ( @$upcoming_dues ) {
} else {
my $biblio = C4::Biblio::GetBiblioFromItemNumber( $upcoming->{'itemnumber'} );
my $letter_type = 'PREDUE';
$letter = C4::Letters::getletter( 'circulation', $letter_type );
die "no letter of type '$letter_type' found. Please see sample_notices.sql" unless $letter;
$sth->execute($upcoming->{'borrowernumber'},$upcoming->{'itemnumber'},$borrower_preferences->{'days_in_advance'});
my $titles = "";
while ( my $item_info = $sth->fetchrow_hashref()) {
@ -198,13 +192,14 @@ UPCOMINGITEM: foreach my $upcoming ( @$upcoming_dues ) {
$titles .= join("\t",@item_info) . "\n";
}
$letter = parse_letter( { letter => $letter,
$letter = parse_letter( { letter_code => $letter_type,
borrowernumber => $upcoming->{'borrowernumber'},
branchcode => $upcoming->{'branchcode'},
biblionumber => $biblio->{'biblionumber'},
itemnumber => $upcoming->{'itemnumber'},
substitute => { 'items.content' => $titles }
} );
} )
or die "no letter of type '$letter_type' found. Please see sample_notices.sql";
}
}
@ -250,8 +245,6 @@ PATRON: while ( my ( $borrowernumber, $digest ) = each %$upcoming_digest ) {
my $letter_type = 'PREDUEDGST';
my $letter = C4::Letters::getletter( 'circulation', $letter_type );
die "no letter of type '$letter_type' found. Please see sample_notices.sql" unless $letter;
$sth->execute($borrowernumber,$borrower_preferences->{'days_in_advance'});
my $titles = "";
@ -259,12 +252,13 @@ PATRON: while ( my ( $borrowernumber, $digest ) = each %$upcoming_digest ) {
my @item_info = map { $_ =~ /^date|date$/ ? format_date($item_info->{$_}) : $item_info->{$_} || '' } @item_content_fields;
$titles .= join("\t",@item_info) . "\n";
}
$letter = parse_letter( { letter => $letter,
my $letter = parse_letter( { letter_code => $letter_type,
borrowernumber => $borrowernumber,
substitute => { count => $count,
'items.content' => $titles
}
} );
} )
or die "no letter of type '$letter_type' found. Please see sample_notices.sql";
if ($nomail) {
local $, = "\f";
print $letter->{'content'};
@ -290,20 +284,19 @@ PATRON: while ( my ( $borrowernumber, $digest ) = each %$due_digest ) {
next PATRON unless $borrower_preferences; # how could this happen?
my $letter_type = 'DUEDGST';
my $letter = C4::Letters::getletter( 'circulation', $letter_type );
die "no letter of type '$letter_type' found. Please see sample_notices.sql" unless $letter;
$sth->execute($borrowernumber,'0');
my $titles = "";
while ( my $item_info = $sth->fetchrow_hashref()) {
my @item_info = map { $_ =~ /^date|date$/ ? format_date($item_info->{$_}) : $item_info->{$_} || '' } @item_content_fields;
$titles .= join("\t",@item_info) . "\n";
}
$letter = parse_letter( { letter => $letter,
my $letter = parse_letter( { letter_code => $letter_type,
borrowernumber => $borrowernumber,
substitute => { count => $count,
'items.content' => $titles
}
} );
} )
or die "no letter of type '$letter_type' found. Please see sample_notices.sql";
if ($nomail) {
local $, = "\f";
@ -323,40 +316,35 @@ PATRON: while ( my ( $borrowernumber, $digest ) = each %$due_digest ) {
=head2 parse_letter
=cut
sub parse_letter {
my $params = shift;
foreach my $required ( qw( letter borrowernumber ) ) {
foreach my $required ( qw( letter_code borrowernumber ) ) {
return unless exists $params->{$required};
}
if ( $params->{'substitute'} ) {
while ( my ($key, $replacedby) = each %{$params->{'substitute'}} ) {
my $replacefield = "<<$key>>";
$params->{'letter'}->{title} =~ s/$replacefield/$replacedby/g;
$params->{'letter'}->{content} =~ s/$replacefield/$replacedby/g;
}
my %table_params = ( 'borrowers' => $params->{'borrowernumber'} );
if ( my $p = $params->{'branchcode'} ) {
$table_params{'branches'} = $p;
}
if ( my $p = $params->{'itemnumber'} ) {
$table_params{'issues'} = $p;
$table_params{'items'} = $p;
}
if ( my $p = $params->{'biblionumber'} ) {
$table_params{'biblio'} = $p;
$table_params{'biblioitems'} = $p;
}
C4::Letters::parseletter( $params->{'letter'}, 'borrowers', $params->{'borrowernumber'} );
if ( $params->{'branchcode'} ) {
C4::Letters::parseletter( $params->{'letter'}, 'branches', $params->{'branchcode'} );
}
if ( $params->{'itemnumber'} ) {
C4::Letters::parseletter( $params->{'letter'}, 'issues', $params->{'itemnumber'} );
C4::Letters::parseletter( $params->{'letter'}, 'items', $params->{'itemnumber'} );
}
if ( $params->{'biblionumber'} ) {
C4::Letters::parseletter( $params->{'letter'}, 'biblio', $params->{'biblionumber'} );
C4::Letters::parseletter( $params->{'letter'}, 'biblioitems', $params->{'biblionumber'} );
}
return $params->{'letter'};
return C4::Letters::GetPreparedLetter (
module => 'circulation',
letter_code => $params->{'letter_code'},
branchcode => $table_params{'branches'},
substitute => $params->{'substitute'},
tables => \%table_params,
);
}
1;

View File

@ -39,11 +39,9 @@ use Getopt::Long;
sub usage {
print STDERR <<USAGE;
Usage: $0 [ -s STYLESHEET ] OUTPUT_DIRECTORY
Usage: $0 OUTPUT_DIRECTORY
Will print all waiting print notices to
OUTPUT_DIRECTORY/notices-CURRENT_DATE.html .
If the filename of a CSS stylesheet is specified with -s, the contents of that
file will be included in the HTML.
USAGE
exit $_[0];
}
@ -51,7 +49,6 @@ USAGE
my ( $stylesheet, $help );
GetOptions(
's:s' => \$stylesheet,
'h|help' => \$help,
) || usage( 1 );
@ -71,16 +68,9 @@ exit unless( @messages );
open OUTPUT, '>', File::Spec->catdir( $output_directory, "holdnotices-" . $today->output( 'iso' ) . ".html" );
my $template = C4::Templates::gettemplate( 'batch/print-notices.tmpl', 'intranet', new CGI );
my $stylesheet_contents = '';
if ($stylesheet) {
open STYLESHEET, '<', $stylesheet;
while ( <STYLESHEET> ) { $stylesheet_contents .= $_ }
close STYLESHEET;
}
$template->param(
stylesheet => $stylesheet_contents,
stylesheet => C4::Context->preference("NoticeCSS"),
today => $today->output(),
messages => \@messages,
);

View File

@ -460,16 +460,6 @@ END_SQL
{
$verbose and warn "borrower $firstname, $lastname ($borrowernumber) has items triggering level $i.";
my $letter = C4::Letters::getletter( 'circulation', $overdue_rules->{"letter$i"} );
unless ($letter) {
$verbose and warn "Message '$overdue_rules->{letter$i}' content not found";
# might as well skip while PERIOD, no other borrowers are going to work.
# FIXME : Does this mean a letter must be defined in order to trigger a debar ?
next PERIOD;
}
if ( $overdue_rules->{"debarred$i"} ) {
#action taken is debarring
@ -494,11 +484,12 @@ END_SQL
my @item_info = map { $_ =~ /^date|date$/ ? format_date( $item_info->{$_} ) : $item_info->{$_} || '' } @item_content_fields;
$titles .= join("\t", @item_info) . "\n";
$itemcount++;
push @items, { itemnumber => $item_info->{'itemnumber'}, biblionumber => $item_info->{'biblionumber'} };
push @items, $item_info;
}
$sth2->finish;
$letter = parse_letter(
{ letter => $letter,
my $letter = parse_letter(
{ letter_code => $overdue_rules->{"letter$i"},
borrowernumber => $borrowernumber,
branchcode => $branchcode,
items => \@items,
@ -509,6 +500,13 @@ END_SQL
}
}
);
unless ($letter) {
$verbose and warn "Message '$overdue_rules->{letter$i}' content not found";
# might as well skip while PERIOD, no other borrowers are going to work.
# FIXME : Does this mean a letter must be defined in order to trigger a debar ?
next PERIOD;
}
if ( $exceededPrintNoticesMaxLines ) {
$letter->{'content'} .= "List too long for form; please check your account online for a complete list of your overdue items.";
@ -643,54 +641,56 @@ substituted keys and values.
=cut
sub parse_letter { # FIXME: this code should probably be moved to C4::Letters:parseletter
sub parse_letter {
my $params = shift;
foreach my $required (qw( letter borrowernumber )) {
foreach my $required (qw( letter_code borrowernumber )) {
return unless exists $params->{$required};
}
my $todaysdate = C4::Dates->new()->output("syspref");
$params->{'letter'}->{title} =~ s/<<today>>/$todaysdate/g;
$params->{'letter'}->{content} =~ s/<<today>>/$todaysdate/g;
my $substitute = $params->{'substitute'} || {};
$substitute->{today} ||= C4::Dates->new()->output("syspref");
if ( $params->{'substitute'} ) {
while ( my ( $key, $replacedby ) = each %{ $params->{'substitute'} } ) {
my $replacefield = "<<$key>>";
$params->{'letter'}->{title} =~ s/$replacefield/$replacedby/g;
$params->{'letter'}->{content} =~ s/$replacefield/$replacedby/g;
}
my %tables = ( 'borrowers' => $params->{'borrowernumber'} );
if ( my $p = $params->{'branchcode'} ) {
$tables{'branches'} = $p;
}
$params->{'letter'} = C4::Letters::parseletter( $params->{'letter'}, 'borrowers', $params->{'borrowernumber'} );
if ( $params->{'branchcode'} ) {
$params->{'letter'} = C4::Letters::parseletter( $params->{'letter'}, 'branches', $params->{'branchcode'} );
my $currency_format;
if ($params->{'letter'}->{'content'} =~ m/<fine>(.*)<\/fine>/o) { # process any fine tags...
$currency_format = $1;
$params->{'letter'}->{'content'} =~ s/<fine>.*<\/fine>/<<item.fine>>/o;
}
if ( $params->{'items'} ) {
my @item_tables;
if ( my $i = $params->{'items'} ) {
my $item_format = '';
PROCESS_ITEMS:
while (scalar(@{$params->{'items'}}) > 0) {
my $item = shift @{$params->{'items'}};
foreach my $item (@$i) {
my $fine = GetFine($item->{'itemnumber'}, $params->{'borrowernumber'});
if (!$item_format) {
$params->{'letter'}->{'content'} =~ m/(<item>.*<\/item>)/;
$item_format = $1;
}
if ($params->{'letter'}->{'content'} =~ m/<fine>(.*)<\/fine>/) { # process any fine tags...
my $formatted_fine = currency_format("$1", "$fine", FMT_SYMBOL);
$params->{'letter'}->{'content'} =~ s/<fine>.*<\/fine>/$formatted_fine/;
}
$params->{'letter'} = C4::Letters::parseletter( $params->{'letter'}, 'biblio', $item->{'biblionumber'} );
$params->{'letter'} = C4::Letters::parseletter( $params->{'letter'}, 'biblioitems', $item->{'biblionumber'} );
$params->{'letter'} = C4::Letters::parseletter( $params->{'letter'}, 'items', $item->{'itemnumber'} );
$params->{'letter'} = C4::Letters::parseletter( $params->{'letter'}, 'issues', $item->{'itemnumber'} );
$params->{'letter'}->{'content'} =~ s/(<item>.*<\/item>)/$1\n$item_format/ if scalar(@{$params->{'items'}} > 0);
$item->{'fine'} = currency_format($currency_format, "$fine", FMT_SYMBOL)
if $currency_format;
push @item_tables, {
'biblio' => $item->{'biblionumber'},
'biblioitems' => $item->{'biblionumber'},
'items' => $item,
'issues' => $item->{'itemnumber'},
};
}
}
$params->{'letter'}->{'content'} =~ s/<\/{0,1}?item>//g; # strip all remaining item tags...
return $params->{'letter'};
return C4::Letters::GetPreparedLetter (
module => 'circulation',
letter_code => $params->{'letter_code'},
branchcode => $params->{'branchcode'},
tables => \%tables,
substitute => $substitute,
repeat => { item => \@item_tables },
);
}
=head2 prepare_letter_for_printing

View File

@ -12,13 +12,12 @@ sub testing_class { 'C4::Letters' };
sub methods : Test( 1 ) {
my $self = shift;
my @methods = qw( getletter
addalert
my @methods = qw( addalert
delalert
getalert
findrelatedto
SendAlerts
parseletter
GetPreparedLetter
);
can_ok( $self->testing_class, @methods );

View File

@ -10,7 +10,7 @@ use Test::More;
sub GetLetter : Test( 6 ) {
my $self = shift;
my $letter = getletter( 'circulation', 'ODUE' );
my $letter = getletter( 'circulation', 'ODUE', '' );
isa_ok( $letter, 'HASH' )
or diag( Data::Dumper->Dump( [ $letter ], [ 'letter' ] ) );
@ -21,7 +21,6 @@ sub GetLetter : Test( 6 ) {
ok( exists $letter->{'name'}, 'name' );
ok( exists $letter->{'title'}, 'title' );
}
1;

View File

@ -52,6 +52,7 @@ sub methods : Test( 1 ) {
GetBorrowersWhoHaveNeverBorrowed
GetBorrowersWithIssuesHistoryOlderThan
GetBorrowersNamesAndLatestIssue
IssueSlip
);
can_ok( $self->testing_class, @methods );

View File

@ -12,10 +12,7 @@ sub testing_class { 'C4::Print' };
sub methods : Test( 1 ) {
my $self = shift;
my @methods = qw( remoteprint
printreserve
printslip
);
my @methods = qw( printslip );
can_ok( $self->testing_class, @methods );
}

View File

@ -33,6 +33,7 @@ sub methods : Test( 1 ) {
GetReserveInfo
_FixPriority
_Findgroupreserve
ReserveSlip
);
can_ok( $self->testing_class, @methods );

View File

@ -46,14 +46,35 @@ use CGI;
use C4::Auth;
use C4::Context;
use C4::Output;
use C4::Branch; # GetBranches
use C4::Members::Attributes;
# letter_exists($module, $code)
# - return true if a letter with the given $module and $code exists
# _letter_from_where($branchcode,$module, $code)
# - return FROM WHERE clause and bind args for a letter
sub _letter_from_where {
my ($branchcode, $module, $code) = @_;
my $sql = q{FROM letter WHERE branchcode = ? AND module = ? AND code = ?};
my @args = ($branchcode || '', $module, $code);
# Mysql is retarded. cause branchcode is part of the primary key it cannot be null. How does that
# work with foreign key constraint I wonder...
# if ($branchcode) {
# $sql .= " AND branchcode = ?";
# push @args, $branchcode;
# } else {
# $sql .= " AND branchcode IS NULL";
# }
return ($sql, \@args);
}
# letter_exists($branchcode,$module, $code)
# - return true if a letter with the given $branchcode, $module and $code exists
sub letter_exists {
my ($module, $code) = @_;
my ($sql, $args) = _letter_from_where(@_);
my $dbh = C4::Context->dbh;
my $letters = $dbh->selectall_arrayref(q{SELECT name FROM letter WHERE module = ? AND code = ?}, undef, $module, $code);
return @{$letters};
my $letter = $dbh->selectrow_hashref("SELECT * $sql", undef, @$args);
return $letter;
}
# $protected_letters = protected_letters()
@ -67,16 +88,14 @@ sub protected_letters {
my $input = new CGI;
my $searchfield = $input->param('searchfield');
my $script_name = '/cgi-bin/koha/tools/letter.pl';
my $branchcode = $input->param('branchcode');
my $code = $input->param('code');
my $module = $input->param('module');
my $content = $input->param('content');
my $op = $input->param('op');
my $op = $input->param('op') || '';
my $dbh = C4::Context->dbh;
if (!defined $module ) {
$module = q{};
}
my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
my ( $template, $borrowernumber, $cookie, $staffflags ) = get_template_and_user(
{
template_name => 'tools/letter.tmpl',
query => $input,
@ -87,32 +106,39 @@ my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
}
);
if (!defined $op) {
$op = q{}; # silence errors from eq
}
my $my_branch = C4::Context->preference("IndependantBranches") && !$staffflags->{'superlibrarian'}
? C4::Context->userenv()->{'branch'}
: undef;
# we show only the TMPL_VAR names $op
$template->param(
independant_branch => $my_branch,
script_name => $script_name,
searchfield => $searchfield,
action => $script_name
);
if ($op eq 'copy') {
add_copy();
$op = 'add_form';
}
if ($op eq 'add_form') {
add_form($module, $code);
add_form($branchcode, $module, $code);
}
elsif ( $op eq 'add_validate' ) {
add_validate();
$op = q{}; # next operation is to return to default screen
}
elsif ( $op eq 'delete_confirm' ) {
delete_confirm($module, $code);
delete_confirm($branchcode, $module, $code);
}
elsif ( $op eq 'delete_confirmed' ) {
delete_confirmed($module, $code);
delete_confirmed($branchcode, $module, $code);
$op = q{}; # next operation is to return to default screen
}
else {
default_display($searchfield);
default_display($branchcode,$searchfield);
}
# Do this last as delete_confirmed resets
@ -125,23 +151,21 @@ if ($op) {
output_html_with_http_headers $input, $cookie, $template->output;
sub add_form {
my ($module, $code ) = @_;
my ($branchcode,$module, $code ) = @_;
my $letter;
# if code has been passed we can identify letter and its an update action
if ($code) {
$letter = $dbh->selectrow_hashref(q{SELECT module, code, name, title, content FROM letter WHERE module=? AND code=?},
undef, $module, $code);
$letter = letter_exists($branchcode,$module, $code);
}
if ($letter) {
$template->param( modify => 1 );
$template->param( code => $letter->{code} );
}
else { # initialize the new fields
$letter = {
module => $module,
code => q{},
name => q{},
title => q{},
content => q{},
branchcode => $branchcode,
module => $module,
};
$template->param( adding => 1 );
}
@ -173,14 +197,20 @@ sub add_form {
{value => q{}, text => '---ITEMS---' },
{value => 'items.content', text => 'items.content'},
add_fields('issues','borrowers');
if ($module eq 'circulation') {
push @{$field_selection}, add_fields('opac_news');
}
}
$template->param(
name => $letter->{name},
title => $letter->{title},
content => $letter->{content},
module => $module,
$module => 1,
branchcode => $letter->{branchcode},
name => $letter->{name},
is_html => $letter->{is_html},
title => $letter->{title},
content => $letter->{content},
module => $module,
$module => 1,
branchloop => _branchloop($branchcode),
SQLfieldname => $field_selection,
);
return;
@ -188,37 +218,56 @@ sub add_form {
sub add_validate {
my $dbh = C4::Context->dbh;
my $module = $input->param('module');
my $oldmodule = $input->param('oldmodule');
my $code = $input->param('code');
my $name = $input->param('name');
my $title = $input->param('title');
my $content = $input->param('content');
if (letter_exists($oldmodule, $code)) {
my $oldbranchcode = $input->param('oldbranchcode');
my $branchcode = $input->param('branchcode') || '';
my $module = $input->param('module');
my $oldmodule = $input->param('oldmodule');
my $code = $input->param('code');
my $name = $input->param('name');
my $is_html = $input->param('is_html');
my $title = $input->param('title');
my $content = $input->param('content');
if (letter_exists($oldbranchcode,$oldmodule, $code)) {
$dbh->do(
q{UPDATE letter SET module = ?, code = ?, name = ?, title = ?, content = ? WHERE module = ? AND code = ?},
q{UPDATE letter SET branchcode = ?, module = ?, name = ?, is_html = ?, title = ?, content = ? WHERE branchcode = ? AND module = ? AND code = ?},
undef,
$module, $code, $name, $title, $content,
$oldmodule, $code
$branchcode, $module, $name, $is_html || 0, $title, $content,
$oldbranchcode, $oldmodule, $code
);
} else {
$dbh->do(
q{INSERT INTO letter (module,code,name,title,content) VALUES (?,?,?,?,?)},
q{INSERT INTO letter (branchcode,module,code,name,is_html,title,content) VALUES (?,?,?,?,?,?,?)},
undef,
$module, $code, $name, $title, $content
$branchcode, $module, $code, $name, $is_html || 0, $title, $content
);
}
# set up default display
default_display();
return;
default_display($branchcode);
}
sub add_copy {
my $dbh = C4::Context->dbh;
my $oldbranchcode = $input->param('oldbranchcode');
my $branchcode = $input->param('branchcode');
my $module = $input->param('module');
my $code = $input->param('code');
return if letter_exists($branchcode,$module, $code);
my $old_letter = letter_exists($oldbranchcode,$module, $code);
$dbh->do(
q{INSERT INTO letter (branchcode,module,code,name,is_html,title,content) VALUES (?,?,?,?,?,?,?)},
undef,
$branchcode, $module, $code, $old_letter->{name}, $old_letter->{is_html}, $old_letter->{title}, $old_letter->{content}
);
}
sub delete_confirm {
my ($module, $code) = @_;
my ($branchcode, $module, $code) = @_;
my $dbh = C4::Context->dbh;
my $letter = $dbh->selectrow_hashref(q|SELECT name FROM letter WHERE module = ? AND code = ?|,
{ Slice => {} },
$module, $code);
my $letter = letter_exists($branchcode, $module, $code);
$template->param( branchcode => $branchcode, branchname => GetBranchName($branchcode) );
$template->param( code => $code );
$template->param( module => $module);
$template->param( name => $letter->{name});
@ -226,40 +275,53 @@ sub delete_confirm {
}
sub delete_confirmed {
my ($module, $code) = @_;
my ($branchcode, $module, $code) = @_;
my ($sql, $args) = _letter_from_where($branchcode, $module, $code);
my $dbh = C4::Context->dbh;
$dbh->do('DELETE FROM letter WHERE module=? AND code=?',{},$module,$code);
$dbh->do("DELETE $sql", undef, @$args);
# setup default display for screen
default_display();
default_display($branchcode);
return;
}
sub retrieve_letters {
my $searchstring = shift;
my ($branchcode, $searchstring) = @_;
$branchcode = $my_branch if $branchcode && $my_branch;
my $dbh = C4::Context->dbh;
if ($searchstring) {
if ($searchstring=~m/(\S+)/) {
$searchstring = $1 . q{%};
return $dbh->selectall_arrayref('SELECT module, code, name FROM letter WHERE code LIKE ? ORDER BY module, code',
{ Slice => {} }, $searchstring);
}
my ($sql, @where, @args);
$sql = "SELECT branchcode, module, code, name, branchname
FROM letter
LEFT OUTER JOIN branches USING (branchcode)";
if ($searchstring && $searchstring=~m/(\S+)/) {
$searchstring = $1 . q{%};
push @where, 'code LIKE ?';
push @args, $searchstring;
}
else {
return $dbh->selectall_arrayref('SELECT module, code, name FROM letter ORDER BY module, code', { Slice => {} });
elsif ($branchcode) {
push @where, 'branchcode = ?';
push @args, $branchcode || '';
}
return;
elsif ($my_branch) {
push @where, "(branchcode = ? OR branchcode = '')";
push @args, $my_branch;
}
$sql .= " WHERE ".join(" AND ", @where) if @where;
$sql .= " ORDER BY module, code, branchcode";
# use Data::Dumper; die Dumper($sql, \@args);
return $dbh->selectall_arrayref($sql, { Slice => {} }, @args);
}
sub default_display {
my $searchfield = shift;
my $results;
my ($branchcode, $searchfield) = @_;
if ( $searchfield ) {
$template->param( search => 1 );
$template->param( searchfield => $searchfield );
$results = retrieve_letters($searchfield);
} else {
$results = retrieve_letters();
}
my $results = retrieve_letters($branchcode,$searchfield);
my $loop_data = [];
my $protected_letters = protected_letters();
foreach my $row (@{$results}) {
@ -267,8 +329,27 @@ sub default_display {
push @{$loop_data}, $row;
}
$template->param( letter => $loop_data );
return;
$template->param(
letter => $loop_data,
branchloop => _branchloop($branchcode),
);
}
sub _branchloop {
my ($branchcode) = @_;
my $branches = GetBranches();
my @branchloop;
for my $thisbranch (sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} } keys %$branches) {
push @branchloop, {
value => $thisbranch,
selected => $branchcode && $thisbranch eq $branchcode,
branchname => $branches->{$thisbranch}->{'branchname'},
};
}
return \@branchloop;
}
sub add_fields {
@ -307,6 +388,7 @@ sub get_columns_for {
text => $tlabel,
};
}
my $sql = "SHOW COLUMNS FROM $table";# TODO not db agnostic
my $table_prefix = $table . q|.|;
my $rows = C4::Context->dbh->selectall_arrayref($sql, { Slice => {} });
@ -317,5 +399,15 @@ sub get_columns_for {
text => $table_prefix . $row->{Field},
}
}
if ($table eq 'borrowers') {
if ( my $attributes = C4::Members::Attributes::GetAttributes() ) {
foreach (@$attributes) {
push @fields, {
value => "borrower-attribute:$_",
text => "attribute:$_",
}
}
}
}
return @fields;
}