From Katrin.Fischer.83 at web.de Sun Jan 1 14:23:07 2012 From: Katrin.Fischer.83 at web.de (Katrin Fischer) Date: Sun, 1 Jan 2012 14:23:07 +0100 Subject: [Koha-patches] [PATCH] Bug 7392: Add system preference to define export options in OPAC Message-ID: <1325424187-15179-1-git-send-email-Katrin.Fischer.83@web.de> NOTE: Patch depends on changes made for Bug 7245 for the "marcstd" option. It adds a new system preference 'OpacExportOptions': The new system preference allows to give a list of | separated values to define, which download options are offered in OPAC. Possible options are listed in the system preference editor and include the new export option 'marcstd' from bug 7245. The sequence of the download options in the system preference will be the sequence in the OPAC pull down. If left empty, the export option will be hidden from OPAC. This patch creates a new include file for the OPAC with all the code that is common to the three detail views (regular, MARC, and ISBD). As a side effect of creating this include file, some inconsistencies in OpacSearchForTitleIn were fixed. {BIBLIONUMBER} and {CONTROLNUMBER} were broken for ISBD and MARC view before and should now be replaced with the correct values in all tabs. --- installer/data/mysql/sysprefs.sql | 2 +- installer/data/mysql/updatedatabase.pl | 9 +++ .../prog/en/modules/admin/preferences/opac.pref | 9 +++- .../prog/en/includes/opac-detail-sidebar.inc | 63 ++++++++++++++++++++ .../opac-tmpl/prog/en/modules/opac-ISBDdetail.tt | 56 +----------------- .../opac-tmpl/prog/en/modules/opac-MARCdetail.tt | 55 +----------------- koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt | 55 +----------------- opac/opac-ISBDdetail.pl | 9 +++ opac/opac-MARCdetail.pl | 22 +++++-- opac/opac-detail.pl | 5 ++ 10 files changed, 115 insertions(+), 170 deletions(-) create mode 100644 koha-tmpl/opac-tmpl/prog/en/includes/opac-detail-sidebar.inc diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 128c9b2..6ed5d0f 100755 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -328,4 +328,4 @@ INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES(' INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('OpacKohaUrl','1',"Show 'Powered by Koha' text on OPAC footer.",NULL,NULL); 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('OpacExportOptions','bibtex|dc|marcxml|marc8|utf8|marcstd|mods|ris','Define export options available on OPAC detail page.','','free'); diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index 67708fa..32bc210 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -4585,6 +4585,15 @@ if (C4::Context->preference("Version") < TransformToNum($DBversion)) { SetVersion($DBversion); } +$DBversion = "3.06.03.XXX"; +if (C4::Context->preference("Version") < TransformToNum($DBversion)) { + $dbh->do("INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacExportOptions','bibtex|dc|marcxml|marc8|utf8|marcstd|mods|ris','Define available export options on OPAC detail page.','','free');"); + print "Upgrade to $DBversion done (Bug 7345: Add system preference OpacExportOptions.)\n"; + SetVersion($DBversion); +} + + + =head1 FUNCTIONS =head2 DropAllForeignKeys($table) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref index d6ae2b2..40cdf78 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref @@ -132,7 +132,7 @@ OPAC: class: file - to override specified settings from the default stylesheet. Enter the filename (if the file is in the server's css directory) or a complete URL beginning with http:// (if the file lives on a remote server). Leave blank to disable. - - - Use the CSS stylesheet /css/ + - Use the CSS stylesheet [% opacthemelang %]/css/ - pref: opaclayoutstylesheet class: file - on all pages in the OPAC, instead of the default (leave blank to disable). @@ -208,6 +208,13 @@ OPAC: Results: "Results page only" Both: "Both Details and Results pages" - 'Note: The corresponding OPACXSLT option must be turned on.' + - + - 'List export options that should be available from OPAC detail page separated by |:' + - pref: OpacExportOptions + class: multi + - '
Note: Available options are: BIBTEX (bibtex), Dublin Core (dc),' + - 'MARCXML (marcxml), MARC-8 encoded MARC (marc8), Unicode/UTF-8 encoded MARC (utf8),' + - 'Unicode/UTF-8 encoded MARC without local use (9xx, x9x, xx9) fields and subfields (marcstd), MODS (mods), RIS (ris)' Features: - - pref: opacuserlogin diff --git a/koha-tmpl/opac-tmpl/prog/en/includes/opac-detail-sidebar.inc b/koha-tmpl/opac-tmpl/prog/en/includes/opac-detail-sidebar.inc new file mode 100644 index 0000000..12772aa --- /dev/null +++ b/koha-tmpl/opac-tmpl/prog/en/includes/opac-detail-sidebar.inc @@ -0,0 +1,63 @@ + + +[% IF ( OPACSearchForTitleIn ) %] +
+
+

Search for this title in:

+ +
+
+[% END %] + +[% IF ( export_options.size ) %] +
+
+ + + + +
+
+[% END %] \ No newline at end of file diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-ISBDdetail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-ISBDdetail.tt index f9984a7..97b64ad 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-ISBDdetail.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-ISBDdetail.tt @@ -46,63 +46,9 @@
- - -[% IF ( OPACSearchForTitleIn ) %] -
-
-

Search for this title in:

-
    - -[% OPACSearchForTitleIn %] - -
-
-
-[% END %] - -
-
- - -
diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-MARCdetail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-MARCdetail.tt index 284154e..f3d2c91 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-MARCdetail.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-MARCdetail.tt @@ -201,62 +201,9 @@ $(document).ready(function(){
- - -[% IF ( OPACSearchForTitleIn ) %] -
-
-

Search for this title in:

-
    - -[% OPACSearchForTitleIn %] - -
-
-
-[% END %] +[% INCLUDE 'opac-detail-sidebar.inc' %] -
-
- - -
diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt index d1b6570..aa411ca 100755 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt @@ -1013,61 +1013,8 @@ YAHOO.util.Event.onContentReady("furtherm", function () { [% END %] [% END %] - - -[% IF ( OPACSearchForTitleIn ) %] -
-
-

Search for this title in:

- -
-
-[% END %] - -
-
- - -
-
+[% INCLUDE 'opac-detail-sidebar.inc' %] [% IF ( NovelistSelectProfile ) %] [% IF ( NovelistSelectView == 'right') %]
diff --git a/opac/opac-ISBDdetail.pl b/opac/opac-ISBDdetail.pl index c80d41c..3373787 100755 --- a/opac/opac-ISBDdetail.pl +++ b/opac/opac-ISBDdetail.pl @@ -159,13 +159,22 @@ $template->param( reviews => $reviews, ); +#Export options +my $OpacExportOptions=C4::Context->preference("OpacExportOptions"); +my @export_options = split(/\|/,$OpacExportOptions); +$template->{VARS}->{'export_options'} = \@export_options; + #Search for title in links +my $marccontrolnumber = GetMarcControlnumber ($record, $marcflavour); + if (my $search_for_title = C4::Context->preference('OPACSearchForTitleIn')){ $dat->{author} ? $search_for_title =~ s/{AUTHOR}/$dat->{author}/g : $search_for_title =~ s/{AUTHOR}//g; $dat->{title} =~ s/\/+$//; # remove trailing slash $dat->{title} =~ s/\s+$//; # remove trailing space $dat->{title} ? $search_for_title =~ s/{TITLE}/$dat->{title}/g : $search_for_title =~ s/{TITLE}//g; $isbn ? $search_for_title =~ s/{ISBN}/$isbn/g : $search_for_title =~ s/{ISBN}//g; + $marccontrolnumber ? $search_for_title =~ s/{CONTROLNUMBER}/$marccontrolnumber/g : $search_for_title =~ s/{CONTROLNUMBER}//g; + $search_for_title =~ s/{BIBLIONUMBER}/$biblionumber/g; $template->param('OPACSearchForTitleIn' => $search_for_title); } diff --git a/opac/opac-MARCdetail.pl b/opac/opac-MARCdetail.pl index ffa0a6d..9f552b8 100755 --- a/opac/opac-MARCdetail.pl +++ b/opac/opac-MARCdetail.pl @@ -270,13 +270,25 @@ if(C4::Context->preference("ISBD")) { $template->param(ISBD => 1); } +#Export options +my $OpacExportOptions=C4::Context->preference("OpacExportOptions"); +my @export_options = split(/\|/,$OpacExportOptions); +$template->{VARS}->{'export_options'} = \@export_options; + #Search for title in links +my $marcflavour = C4::Context->preference("marcflavour"); +my $dat = TransformMarcToKoha( $dbh, $record ); +my $isbn = GetNormalizedISBN(undef,$record,$marcflavour); +my $marccontrolnumber = GetMarcControlnumber ($record, $marcflavour); + if (my $search_for_title = C4::Context->preference('OPACSearchForTitleIn')){ - $biblio->{author} ? $search_for_title =~ s/{AUTHOR}/$biblio->{author}/g : $search_for_title =~ s/{AUTHOR}//g; - $biblio->{title} =~ s/\/+$//; # remove trailing slash - $biblio->{title} =~ s/\s+$//; # remove trailing space - $biblio->{title} ? $search_for_title =~ s/{TITLE}/$biblio->{title}/g : $search_for_title =~ s/{TITLE}//g; - $biblio->{isbn} ? $search_for_title =~ s/{ISBN}/$biblio->{isbn}/g : $search_for_title =~ s/{ISBN}//g; + $dat->{author} ? $search_for_title =~ s/{AUTHOR}/$dat->{author}/g : $search_for_title =~ s/{AUTHOR}//g; + $dat->{title} =~ s/\/+$//; # remove trailing slash + $dat->{title} =~ s/\s+$//; # remove trailing space + $dat->{title} ? $search_for_title =~ s/{TITLE}/$dat->{title}/g : $search_for_title =~ s/{TITLE}//g; + $isbn ? $search_for_title =~ s/{ISBN}/$isbn/g : $search_for_title =~ s/{ISBN}//g; + $marccontrolnumber ? $search_for_title =~ s/{CONTROLNUMBER}/$marccontrolnumber/g : $search_for_title =~ s/{CONTROLNUMBER}//g; + $search_for_title =~ s/{BIBLIONUMBER}/$biblionumber/g; $template->param('OPACSearchForTitleIn' => $search_for_title); } diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl index f82dde2..59f243e 100755 --- a/opac/opac-detail.pl +++ b/opac/opac-detail.pl @@ -881,6 +881,11 @@ if (C4::Context->preference("OPACURLOpenInNewWindow")) { $template->param(covernewwindow => 'false'); } +#Export options +my $OpacExportOptions=C4::Context->preference("OpacExportOptions"); +my @export_options = split(/\|/,$OpacExportOptions); +$template->{VARS}->{'export_options'} = \@export_options; + #Search for title in links my $marccontrolnumber = GetMarcControlnumber ($record, $marcflavour); -- 1.7.5.4 From Katrin.Fischer.83 at web.de Sun Jan 1 20:37:06 2012 From: Katrin.Fischer.83 at web.de (Katrin Fischer) Date: Sun, 1 Jan 2012 20:37:06 +0100 Subject: [Koha-patches] [PATCH] Bug 7345: Follow up: Adding the new export option to staff interface Message-ID: <1325446626-19779-1-git-send-email-Katrin.Fischer.83@web.de> This patch adds the new export option 'marcstd' for exporting MARC records without 9xx, x9x and xx9 fields and subfields to the staff detail page. Patch applies on top of first patch for this bug. --- catalogue/export.pl | 3 ++- .../intranet-tmpl/prog/en/includes/cat-toolbar.inc | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/catalogue/export.pl b/catalogue/export.pl index db69af9..d832fbb 100755 --- a/catalogue/export.pl +++ b/catalogue/export.pl @@ -27,6 +27,7 @@ if ($op eq "export") { if ($biblionumber){ my $marc = GetMarcBiblio($biblionumber, 1); + my $error = ''; if ($format =~ /endnote/) { $marc = marc2endnote($marc); @@ -53,7 +54,7 @@ if ($op eq "export") { } elsif ($format =~ /marcstd/) { C4::Charset::SetUTF8Flag($marc,1); - ($error,$marc) = marc2marc($marc, 'marcstd', C4::Context->preference('marcflavour')); + ($error, $marc) = marc2marc($marc, 'marcstd', C4::Context->preference('marcflavour')); } print $query->header( -type => 'application/octet-stream', diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc index 413d7f4..114f345 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc @@ -122,7 +122,8 @@ function confirm_items_deletion() { { text: _("Dublin Core (XML)"), url: "/cgi-bin/koha/catalogue/export.pl?format=dc&op=export&bib=[% biblionumber %]" }, { text: _("MARCXML"), url: "/cgi-bin/koha/catalogue/export.pl?format=marcxml&op=export&bib=[% biblionumber %]" }, { text: _("MARC (non-Unicode/MARC-8)"), url: "/cgi-bin/koha/catalogue/export.pl?format=marc8&op=export&bib=[% biblionumber %]" }, - { text: _("MARC (Unicode/UTF-8)"), url: "/cgi-bin/koha/catalogue/export.pl?format=utf8&op=export&bib=[% biblionumber %]" } + { text: _("MARC (Unicode/UTF-8)"), url: "/cgi-bin/koha/catalogue/export.pl?format=utf8&op=export&bib=[% biblionumber %]" }, + { text: _("MARC (Unicode/UTF-8, Standard)"), url: "/cgi-bin/koha/catalogue/export.pl?format=marcstd&op=export&bib=[% biblionumber %]" } ]; new YAHOO.widget.Button({ -- 1.7.5.4 From jonathan.druart at biblibre.com Mon Jan 2 09:46:28 2012 From: jonathan.druart at biblibre.com (Jonathan Druart) Date: Mon, 2 Jan 2012 09:46:28 +0100 Subject: [Koha-patches] [PATCH 1/1] [SIGNED-OFF] Bug 5347: Follow up - Fix warnings, check/uncheck all and makes error message translatable Message-ID: <1325493988-6861-1-git-send-email-jonathan.druart@biblibre.com> From: Katrin Fischer This patch fixes some minor problems found in late order management: 1) Silences 2 warns in Letters.p After patch is applied no more warns should show up in the logs. 2) Fixes check/uncheck al When limiting on one vendor the checkbox in the last header column was doing nothing. I changed the checkbox to 2 links 'check all' and 'uncheck all' as it's done in other templates. 3) Email has been sent The message was hardcoded into the lateorders.pl file and not translatable. I moved it to the template and changed the wording slightly. Note: The error message 'The bookseller has no email' comes from Letters.pm. I didn't change that, because I was not sure where it is used. The error message as is can not be translated and should be moved into the templates too. --- C4/Letters.pm | 4 ++-- acqui/lateorders.pl | 2 +- .../prog/en/modules/acqui/lateorders.tt | 11 +++++++---- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/C4/Letters.pm b/C4/Letters.pm index 5cde41d..5e3089b 100644 --- a/C4/Letters.pm +++ b/C4/Letters.pm @@ -393,7 +393,7 @@ sub SendAlerts { '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}"; + 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'; @@ -402,7 +402,7 @@ sub SendAlerts { die "This bookseller has no email\n"; } - warn "sending to From $userenv->{emailaddress} subj $innerletter->{title} Mess $innerletter->{content}"; + warn "sending to From $userenv->{emailaddress} subj $innerletter->{title} Mess $innerletter->{content}" if $debug; } # send an "account details" notice to a newly created user diff --git a/acqui/lateorders.pl b/acqui/lateorders.pl index 2482ffb..998899e 100755 --- a/acqui/lateorders.pl +++ b/acqui/lateorders.pl @@ -85,7 +85,7 @@ if ($op and $op eq "send_alert"){ if ( $@ ) { $template->param(error_claim => $@); } else { - $template->param(info_claim => "Emails have been sent"); + $template->{VARS}->{'info_claim'} = 1; } } diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/lateorders.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/lateorders.tt index 8227722..5ce1fae 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/lateorders.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/lateorders.tt @@ -1,6 +1,7 @@ [% INCLUDE 'doc-head-open.inc' %] Koha › Acquisitions › Late orders [% INCLUDE 'doc-head-close.inc' %] + @@ -35,7 +38,7 @@ $(document).ready(function() {
[% error_claim %]
[% END %] [% IF info_claim %] -
[% info_claim %]
+
Email has been sent.
[% END %] [% IF ( lateorders ) %]
@@ -50,7 +53,7 @@ $(document).ready(function() {

[% END %] - +
@@ -61,7 +64,7 @@ $(document).ready(function() { [% IF Supplier %] - + [% ELSE %] [% END %] @@ -103,7 +106,7 @@ $(document).ready(function() { -- 1.7.7.3 From jonathan.druart at biblibre.com Mon Jan 2 13:30:04 2012 From: jonathan.druart at biblibre.com (Jonathan Druart) Date: Mon, 2 Jan 2012 13:30:04 +0100 Subject: [Koha-patches] [PATCH 1/1] Bug 6751: Adds a link "Export checkin barcodes" in readingrec Message-ID: <1325507404-18913-1-git-send-email-jonathan.druart@biblibre.com> to export a file containing a list of checkin barcode for the current day. --- .../prog/en/modules/members/readingrec.tt | 1 + members/readingrec.pl | 23 +++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletions(-) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/readingrec.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/readingrec.tt index f1554f0..be62076 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/readingrec.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/readingrec.tt @@ -34,6 +34,7 @@ [% IF ( loop_reading ) %] +

Export checkin barcodes

[% INCLUDE 'table-pager.inc' perpage='20' %]
diff --git a/members/readingrec.pl b/members/readingrec.pl index b4fb8a7..dc0807f 100755 --- a/members/readingrec.pl +++ b/members/readingrec.pl @@ -29,7 +29,7 @@ use C4::Auth; use C4::Output; use C4::Members; use C4::Branch; -use List::MoreUtils qw/any/; +use List::MoreUtils qw/any uniq/; use C4::Dates qw/format_date/; use C4::Members::Attributes qw(GetBorrowerAttributes); @@ -64,6 +64,9 @@ my $limit = 0; my ( $issues ) = GetAllIssues($borrowernumber,$order,$limit); my @loop_reading; +my @barcodes; +my $today = C4::Dates->new(); +$today = $today->output("iso"); foreach my $issue (@{$issues}){ my %line; @@ -80,6 +83,24 @@ foreach my $issue (@{$issues}){ $line{barcode} = $issue->{'barcode'}; $line{volumeddesc} = $issue->{'volumeddesc'}; push(@loop_reading,\%line); + if (($input->param('op') eq 'export_barcodes') and ($today eq $issue->{'returndate'})) { + push( @barcodes, $issue->{'barcode'} ); + } +} + +if ($input->param('op') eq 'export_barcodes') { + my $borrowercardnumber = GetMember( borrowernumber => $borrowernumber )->{'cardnumber'} ; + my $delimiter = ":"; + $delimiter = "\n"; + binmode( STDOUT, ":utf8" ); + print $input->header( + -type => 'application/octet-stream', + -charset => 'utf-8', + -attachment => "$today-$borrowercardnumber-checkinexport.txt" + ); + my $content = join($delimiter, uniq(@barcodes)); + print $content; + exit; } if ( $data->{'category_type'} eq 'C') { -- 1.7.7.3 From srdjan at catalyst.net.nz Tue Jan 3 00:20:23 2012 From: srdjan at catalyst.net.nz (Srdjan Jankovic) Date: Tue, 3 Jan 2012 12:20:23 +1300 Subject: [Koha-patches] [PATCH] bug_5786: moved AllowOnShelfHolds to circ matrix (issuingrules) In-Reply-To: References: Message-ID: <1325546423-20624-1-git-send-email-srdjan@catalyst.net.nz> --- C4/Circulation.pm | 3 +- C4/Items.pm | 2 + C4/Reserves.pm | 72 ++++++++++++++++--- C4/VirtualShelves/Page.pm | 1 - admin/smart-rules.pl | 9 ++- admin/systempreferences.pl | 1 - .../mysql/it-IT/necessari/system_preferences.sql | 1 - installer/data/mysql/kohastructure.sql | 3 +- installer/data/mysql/sysprefs.sql | 1 - installer/data/mysql/updatedatabase.pl | 20 ++++++ installer/html-template-to-template-toolkit.pl | 2 +- .../en/modules/admin/preferences/circulation.pref | 6 -- .../prog/en/modules/admin/preferences/opac.pref | 6 -- .../prog/en/modules/admin/smart-rules.tt | 25 +++++-- .../prog/en/modules/help/reserve/request.tt | 2 +- .../opac-tmpl/prog/en/modules/opac-ISBDdetail.tt | 6 -- .../opac-tmpl/prog/en/modules/opac-MARCdetail.tt | 6 -- koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt | 12 +--- .../prog/en/modules/opac-results-grouped.tt | 6 -- .../opac-tmpl/prog/en/modules/opac-results.tt | 8 +-- .../opac-tmpl/prog/en/modules/opac-shelves.tt | 6 -- opac/opac-ISBDdetail.pl | 2 - opac/opac-MARCdetail.pl | 1 - opac/opac-detail.pl | 2 - opac/opac-reserve.pl | 2 +- opac/opac-search.pl | 2 +- 26 files changed, 116 insertions(+), 91 deletions(-) diff --git a/C4/Circulation.pm b/C4/Circulation.pm index 9a6f4f2..df202e1 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -2200,7 +2200,8 @@ sub CanBookBeRenewed { LEFT JOIN biblioitems USING (biblioitemnumber) WHERE - (issuingrules.categorycode = borrowers.categorycode OR issuingrules.categorycode = '*') + (issuingrules.categorycode = borrowers.categorycode + OR issuingrules.categorycode = '*') AND (issuingrules.itemtype = $itype OR issuingrules.itemtype = '*') AND diff --git a/C4/Items.pm b/C4/Items.pm index 8802a4c..7c3a26f 100644 --- a/C4/Items.pm +++ b/C4/Items.pm @@ -160,6 +160,8 @@ sub GetItem { ($data->{'serialseq'} , $data->{'publisheddate'}) = $ssth->fetchrow_array(); } #if we don't have an items.itype, use biblioitems.itemtype. + # FIXME this should respect the itypes systempreference + # if (C4::Context->preference('item-level_itypes')) { if( ! $data->{'itype'} ) { my $sth = $dbh->prepare("SELECT itemtype FROM biblioitems WHERE biblionumber = ?"); $sth->execute($data->{'biblionumber'}); diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 359bbad..5a2d819 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -479,7 +479,6 @@ sub CanItemBeReserved{ if(my $rowcount = $sthcount->fetchrow_hashref()){ $reservecount = $rowcount->{count}; } - # we check if it's ok or not if( $reservecount < $allowedreserves ){ return 1; @@ -1321,7 +1320,7 @@ sub GetReserveInfo { =head2 IsAvailableForItemLevelRequest - my $is_available = IsAvailableForItemLevelRequest($itemnumber); + my $is_available = IsAvailableForItemLevelRequest($itemnumber,$borrowernumber,$branchcode); Checks whether a given item record is available for an item-level hold request. An item is available if @@ -1331,12 +1330,8 @@ item-level hold request. An item is available if * it is not withdrawn AND * does not have a not for loan value > 0 -Whether or not the item is currently on loan is -also checked - if the AllowOnShelfHolds system preference -is ON, an item can be requested even if it is currently -on loan to somebody else. If the system preference -is OFF, an item that is currently checked out cannot -be the target of an item-level hold request. +Need to check the issuingrules onshelfholds column, +if this is set items on the shelf can be placed on hold Note that IsAvailableForItemLevelRequest() does not check if the staff operator is authorized to place @@ -1348,9 +1343,9 @@ and canreservefromotherbranches. sub IsAvailableForItemLevelRequest { my $itemnumber = shift; - + my $borrowernumber = shift; + my $branchcode = shift; my $item = GetItem($itemnumber); - # must check the notforloan setting of the itemtype # FIXME - a lot of places in the code do this # or something similar - need to be @@ -1383,14 +1378,67 @@ sub IsAvailableForItemLevelRequest { $item->{wthdrawn} or $notforloan_per_itemtype; - - if (C4::Context->preference('AllowOnShelfHolds')) { + # check issuingrules + + if (OnShelfHoldsAllowed($itemnumber,$borrowernumber,$branchcode)) { return $available_per_item; } else { return ($available_per_item and ($item->{onloan} or GetReserveStatus($itemnumber) eq "W")); } } +=head2 OnShelfHoldsAllowed + + OnShelfHoldsAllowed($itemnumber,$borrowernumber,$branchcode); + +Checks issuingrules, using the borrowers categorycode, the itemtype, and branchcode to see if onshelf +holds are allowed, returns true if so. + +=cut + +sub OnShelfHoldsAllowed { + my ($itemnumber,$borrowernumber,$branchcode) = @_; + my $item = GetItem($itemnumber); + my $borrower = C4::Members::GetMember(borrowernumber => $borrowernumber); + my $itype; + my $dbh = C4::Context->dbh; + if (C4::Context->preference('item-level_itypes')) { + # We cant trust GetItem to honour the syspref, so safest to do it ourselves + # When GetItem is fixed, we can remove this + $itype = $item->{itype}; + } + else { + my $query = "SELECT itemtype FROM biblioitems WHERE biblioitemnumber = ? "; + my $sth = $dbh->prepare($query); + $sth->execute($item->{biblioitemnumber}); + if (my $data = $sth->fetchrow_hashref()){ + $itype = $data->{itemtype}; + } + } + + my $query = "SELECT onshelfholds,categorycode,itemtype,branchcode FROM issuingrules WHERE + (issuingrules.categorycode = ? OR issuingrules.categorycode = '*') + AND + (issuingrules.itemtype = ? OR issuingrules.itemtype = '*') + AND + (issuingrules.branchcode = ? OR issuingrules.branchcode = '*') + ORDER BY + issuingrules.categorycode desc, + issuingrules.itemtype desc, + issuingrules.branchcode desc + LIMIT 1"; + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare($query); + $sth->execute($borrower->{categorycode},$itype,$branchcode); + my $data = $sth->fetchrow_hashref; + if ($data->{onshelfholds}){ + return 1; + } + else { + return 0; + } +} + =head2 AlterPriority AlterPriority( $where, $borrowernumber, $biblionumber, $reservedate ); diff --git a/C4/VirtualShelves/Page.pm b/C4/VirtualShelves/Page.pm index 523527e..ff55dc0 100644 --- a/C4/VirtualShelves/Page.pm +++ b/C4/VirtualShelves/Page.pm @@ -183,7 +183,6 @@ sub shelfpage ($$$$$) { # explicitly fetch this shelf my ($shelfnumber2,$shelfname,$owner,$category,$sorton) = GetShelf($shelfnumber); - $template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') ); if (C4::Context->preference('TagsEnabled')) { $template->param(TagsEnabled => 1); foreach (qw(TagsShowOnList TagsInputOnList)) { diff --git a/admin/smart-rules.pl b/admin/smart-rules.pl index f290934..5bfdc7d 100755 --- a/admin/smart-rules.pl +++ b/admin/smart-rules.pl @@ -101,8 +101,8 @@ elsif ($op eq 'delete-branch-item') { # save the values entered elsif ($op eq 'add') { my $sth_search = $dbh->prepare("SELECT COUNT(*) AS total FROM issuingrules WHERE branchcode=? AND categorycode=? AND itemtype=?"); - my $sth_insert = $dbh->prepare("INSERT INTO issuingrules (branchcode, categorycode, itemtype, maxissueqty, renewalsallowed, reservesallowed, issuelength, hardduedate, hardduedatecompare, fine, finedays, firstremind, chargeperiod,rentaldiscount) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); - my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, reservesallowed=?, issuelength=?, hardduedate=?, hardduedatecompare=?, rentaldiscount=? WHERE branchcode=? AND categorycode=? AND itemtype=?"); + my $sth_insert = $dbh->prepare("INSERT INTO issuingrules (branchcode, categorycode, itemtype, maxissueqty, renewalsallowed, reservesallowed, issuelength, hardduedate, hardduedatecompare, fine, finedays, firstremind, chargeperiod, rentaldiscount, onshelfholds) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); + my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, reservesallowed=?, issuelength=?, hardduedate=?, hardduedatecompare=?, rentaldiscount=?, onshelfholds=? WHERE branchcode=? AND categorycode=? AND itemtype=?"); my $br = $branch; # branch my $bor = $input->param('categorycode'); # borrower category @@ -114,6 +114,7 @@ elsif ($op eq 'add') { my $maxissueqty = $input->param('maxissueqty'); my $renewalsallowed = $input->param('renewalsallowed'); my $reservesallowed = $input->param('reservesallowed'); + my $onshelfholds = $input->param('onshelfholds'); $maxissueqty =~ s/\s//g; $maxissueqty = undef if $maxissueqty !~ /^\d+/; my $issuelength = $input->param('issuelength'); @@ -126,9 +127,9 @@ elsif ($op eq 'add') { $sth_search->execute($br,$bor,$cat); my $res = $sth_search->fetchrow_hashref(); if ($res->{total}) { - $sth_update->execute($fine, $finedays,$firstremind, $chargeperiod, $maxissueqty, $renewalsallowed,$reservesallowed, $issuelength,$hardduedate,$hardduedatecompare,$rentaldiscount, $br,$bor,$cat); + $sth_update->execute($fine, $finedays,$firstremind, $chargeperiod, $maxissueqty, $renewalsallowed,$reservesallowed, $issuelength,$hardduedate,$hardduedatecompare,$rentaldiscount, $onshelfholds, $br,$bor,$cat); } else { - $sth_insert->execute($br,$bor,$cat,$maxissueqty,$renewalsallowed,$reservesallowed,$issuelength,$hardduedate,$hardduedatecompare,$fine,$finedays,$firstremind,$chargeperiod,$rentaldiscount); + $sth_insert->execute($br,$bor,$cat,$maxissueqty,$renewalsallowed,$reservesallowed,$issuelength,$hardduedate,$hardduedatecompare,$fine,$finedays,$firstremind,$chargeperiod,$rentaldiscount,$onshelfholds); } } elsif ($op eq "set-branch-defaults") { diff --git a/admin/systempreferences.pl b/admin/systempreferences.pl index 78d0768..6bd68ee 100755 --- a/admin/systempreferences.pl +++ b/admin/systempreferences.pl @@ -186,7 +186,6 @@ $tabsysprefs{HomeOrHoldingBranch} = "Circulation"; $tabsysprefs{HomeOrHoldingBranchReturn} = "Circulation"; $tabsysprefs{RandomizeHoldsQueueWeight} = "Circulation"; $tabsysprefs{StaticHoldsQueueWeight} = "Circulation"; -$tabsysprefs{AllowOnShelfHolds} = "Circulation"; $tabsysprefs{AllowHoldsOnDamagedItems} = "Circulation"; $tabsysprefs{UseBranchTransferLimits} = "Circulation"; $tabsysprefs{AllowHoldPolicyOverride} = "Circulation"; diff --git a/installer/data/mysql/it-IT/necessari/system_preferences.sql b/installer/data/mysql/it-IT/necessari/system_preferences.sql index b4ddfa0..7aaa066 100644 --- a/installer/data/mysql/it-IT/necessari/system_preferences.sql +++ b/installer/data/mysql/it-IT/necessari/system_preferences.sql @@ -17,7 +17,6 @@ -- 51 Franklin Street' WHERE variable = ' Fifth Floor' WHERE variable = ' Boston' WHERE variable = ' MA 02110-1301 USA. UPDATE systempreferences SET value = 'cataloguing' WHERE variable = 'AcqCreateItem'; -UPDATE systempreferences SET value = '1' WHERE variable = 'AllowOnShelfHolds'; UPDATE systempreferences SET value = '1' WHERE variable = 'AllowRenewalLimitOverride'; UPDATE systempreferences SET value = 'annual' WHERE variable = 'autoBarcode'; UPDATE systempreferences SET value = 'email' WHERE variable = 'AutoEmailPrimaryAddress'; diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 5287d9f..d7cdc2e 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -970,6 +970,7 @@ CREATE TABLE `issues` ( -- information related to check outs or issues DROP TABLE IF EXISTS `issuingrules`; CREATE TABLE `issuingrules` ( + `branchcode` varchar(10) NOT NULL default '', `categorycode` varchar(10) NOT NULL default '', `itemtype` varchar(10) NOT NULL default '', `restrictedtype` tinyint(1) default NULL, @@ -987,7 +988,7 @@ CREATE TABLE `issuingrules` ( `hardduedatecompare` tinyint NOT NULL default "0", `renewalsallowed` smallint(6) NOT NULL default "0", `reservesallowed` smallint(6) NOT NULL default "0", - `branchcode` varchar(10) NOT NULL default '', + `onshelfholds` tinyint(1) NOT NULL default 0, PRIMARY KEY (`branchcode`,`categorycode`,`itemtype`), KEY `categorycode` (`categorycode`), KEY `itemtype` (`itemtype`) diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 128c9b2..a1a913a 100755 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -223,7 +223,6 @@ INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES ('XSLTDetailsDisplay','0','','Enable XSL stylesheet control over details page display on intranet','YesNo'), ('XSLTResultsDisplay','0','','Enable XSL stylesheet control over results page display on intranet','YesNo'); INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('AdvancedSearchTypes','itemtypes','itemtypes|ccode','Select which set of fields comprise the Type limit in the advanced search','Choice'); -INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('AllowOnShelfHolds', '0', '', 'Allow hold requests to be placed on items that are not on loan', 'YesNo'); INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('AllowHoldsOnDamagedItems', '1', '', 'Allow hold requests to be placed on damaged items', 'YesNo'); INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('OpacSuppression', '0', '', 'Turn ON the OPAC Suppression feature, requires further setup, ask your system administrator for details', 'YesNo'); -- FIXME: add FrameworksLoaded, noOPACUserLogin? diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index 67708fa..84b11d4 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -4585,6 +4585,26 @@ if (C4::Context->preference("Version") < TransformToNum($DBversion)) { SetVersion($DBversion); } +$DBversion = '3.06.03.XXX'; +if (C4::Context->preference("Version") < TransformToNum($DBversion)) { + # First create the column + $dbh->do("ALTER TABLE issuingrules ADD onshelfholds tinyint(1) default 0"); + # Now update the column + if (C4::Context->preference("AllowOnShelfHolds")){ + # Pref is on, set allow for all rules + $dbh->do("UPDATE issuingrules SET onshelfholds=1"); + } else { + # If the preference is not set, leave off + $dbh->do("UPDATE issuingrules SET onshelfholds=0"); + } + $dbh->do("ALTER TABLE issuingrules MODIFY onshelfholds tinyint(1) default 0 NOT NULL"); + # Remove from the systempreferences table + $dbh->do("DELETE FROM systempreferences WHERE variable = 'AllowOnShelfHolds'"); + + print "Upgrade to $DBversion done (Bug 5786 move AllowOnShelfHolds to circulation matrix)\n"; + SetVersion ($DBversion); +} + =head1 FUNCTIONS =head2 DropAllForeignKeys($table) diff --git a/installer/html-template-to-template-toolkit.pl b/installer/html-template-to-template-toolkit.pl index e99b195..5f0e0ac 100755 --- a/installer/html-template-to-template-toolkit.pl +++ b/installer/html-template-to-template-toolkit.pl @@ -32,7 +32,7 @@ my @globals = ("themelang","JacketImages","OPACAmazonCoverImages","GoogleJackets "SyndeticsEnabled", "OpacRenewalAllowed", "item_level_itypes","noItemTypeImages", "virtualshelves", "RequestOnOpac", "COinSinOPACResults", "OPACXSLTResultsDisplay", "OPACItemsResultsDisplay", "LibraryThingForLibrariesID", "opacuserlogin", "TagsEnabled", -"TagsShowOnList", "TagsInputOnList","loggedinusername","AllowOnShelfHolds","opacbookbag", +"TagsShowOnList", "TagsInputOnList","loggedinusername","opacbookbag", "OPACAmazonEnabled", "SyndeticsCoverImages","using_https"); # Arguments: diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref index f4946b5..4cb60ae 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -236,12 +236,6 @@ Circulation: no: "Don't allow" - hold requests to be placed on damaged items. - - - pref: AllowOnShelfHolds - choices: - yes: Allow - no: "Don't allow" - - hold requests to be placed on items that are not checked out. - - - pref: AllowHoldDateInFuture choices: yes: Allow diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref index d6ae2b2..0b076ca 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref @@ -319,12 +319,6 @@ OPAC: # choices: # - If ON, enables subject cloud on OPAC - - - pref: OPACItemHolds - choices: - yes: Allow - no: "Don't allow" - - patrons to place holds on specific items in the OPAC. If this is disabled, users can only put a hold on the next available item. - - - pref: OpacRenewalAllowed choices: yes: Allow diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt index d2f314f..e38e446 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt @@ -80,7 +80,8 @@ for="tobranch">Clone these rules to: Clone these rules to: Delete @@ -175,6 +183,7 @@ for="tobranch">Clone these rules to: + diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/help/reserve/request.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/help/reserve/request.tt index 3d7381b..a5a5cd0 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/help/reserve/request.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/help/reserve/request.tt @@ -72,4 +72,4 @@

See the full documentation for Holds in the manual (online).

-[% INCLUDE 'help-bottom.inc' %] \ No newline at end of file +[% INCLUDE 'help-bottom.inc' %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-ISBDdetail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-ISBDdetail.tt index f9984a7..d04e7b1 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-ISBDdetail.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-ISBDdetail.tt @@ -51,13 +51,7 @@ [% UNLESS ( norequests ) %] [% IF ( opacuserlogin ) %] [% IF ( RequestOnOpac ) %] - [% IF ( AllowOnShelfHolds ) %]
  • Place Hold
  • - [% ELSE %] - [% IF ( ItemsIssued ) %] -
  • Place Hold
  • - [% END %] - [% END %] [% END %] [% END %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-MARCdetail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-MARCdetail.tt index 284154e..200c0ed 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-MARCdetail.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-MARCdetail.tt @@ -206,13 +206,7 @@ $(document).ready(function(){ [% UNLESS ( norequests ) %] [% IF ( opacuserlogin ) %] [% IF ( RequestOnOpac ) %] - [% IF ( AllowOnShelfHolds ) %]
  • Place Hold
  • - [% ELSE %] - [% IF ( ItemsIssued ) %] -
  • Place Hold
  • - [% END %] - [% END %] [% END %] [% END %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt index d1b6570..fb367ca 100755 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt @@ -1016,16 +1016,10 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
      [% UNLESS ( norequests ) %] - [% IF ( opacuserlogin ) %] + [% IF ( opacuserlogin ) %] [% IF ( RequestOnOpac ) %] - [% IF ( AllowOnShelfHolds ) %] -
    • Place Hold
    • - [% ELSE %] - [% IF ( ItemsIssued ) %] -
    • Place Hold
    • - [% END %] - [% END %] - [% END %] +
    • Place Hold
    • + [% END %] [% END %] [% END %]
    • Print
    • diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results-grouped.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results-grouped.tt index 9e1b855..e08f7f9 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results-grouped.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results-grouped.tt @@ -260,13 +260,7 @@ function highlightOn() { [% IF ( RequestOnOpac ) %] [% UNLESS ( GROUP_RESULT.norequests ) %] [% IF ( opacuserlogin ) %] - [% IF ( AllowOnShelfHolds ) %] Place Hold - [% ELSE %] - [% IF ( GROUP_RESULT.itemsissued ) %] - Place Hold - [% END %] - [% END %] [% END %] [% END %] [% END %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt index 798e0d8..2256b3e 100755 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt @@ -510,13 +510,7 @@ $(document).ready(function(){ [% IF ( RequestOnOpac ) %] [% UNLESS ( SEARCH_RESULT.norequests ) %] [% IF ( opacuserlogin ) %] - [% IF ( AllowOnShelfHolds ) %] - Place Hold - [% ELSE %] - [% IF ( SEARCH_RESULT.itemsissued ) %] - Place Hold - [% END %] - [% END %] + Place Hold [% END %] [% END %] [% END %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-shelves.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-shelves.tt index 391037f..b9e2ed4 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-shelves.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-shelves.tt @@ -308,13 +308,7 @@ $(function() { [% IF ( RequestOnOpac ) %] [% UNLESS ( itemsloo.norequests ) %] [% IF ( opacuserlogin ) %] - [% IF ( AllowOnShelfHolds ) %] Place Hold - [% ELSE %] - [% IF ( itemsloo.itemsissued ) %] - Place Hold - [% END %] - [% END %] [% END %] [% END %] [% END %] diff --git a/opac/opac-ISBDdetail.pl b/opac/opac-ISBDdetail.pl index c80d41c..d978357 100755 --- a/opac/opac-ISBDdetail.pl +++ b/opac/opac-ISBDdetail.pl @@ -69,7 +69,6 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user( my $biblionumber = $query->param('biblionumber'); -$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') ); $template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) ); my $marcflavour = C4::Context->preference("marcflavour"); @@ -152,7 +151,6 @@ foreach ( @$reviews ) { $template->param( RequestOnOpac => C4::Context->preference("RequestOnOpac"), - AllowOnShelfHolds => C4::Context->preference('AllowOnShelfHolds'), norequests => $norequests, ISBD => $res, biblionumber => $biblionumber, diff --git a/opac/opac-MARCdetail.pl b/opac/opac-MARCdetail.pl index ffa0a6d..476fe50 100755 --- a/opac/opac-MARCdetail.pl +++ b/opac/opac-MARCdetail.pl @@ -81,7 +81,6 @@ $template->param( bibliotitle => $biblio->{title}, ); -$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') ); $template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) ); # adding the $RequestOnOpac param diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl index f82dde2..8111e9d 100755 --- a/opac/opac-detail.pl +++ b/opac/opac-detail.pl @@ -347,8 +347,6 @@ if ($session->param('busc')) { } - -$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') ); $template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) ); my $record = GetMarcBiblio($biblionumber); diff --git a/opac/opac-reserve.pl b/opac/opac-reserve.pl index b2144a9..3e573fc 100755 --- a/opac/opac-reserve.pl +++ b/opac/opac-reserve.pl @@ -471,7 +471,7 @@ foreach my $biblioNum (@biblionumbers) { $policy_holdallowed = 0; } - if (IsAvailableForItemLevelRequest($itemNum) and $policy_holdallowed and CanItemBeReserved($borrowernumber,$itemNum) and ($itemLoopIter->{already_reserved} ne 1)) { + if (IsAvailableForItemLevelRequest($itemNum,$borr->{'borrowernumber'},$itemInfo->{'homebranch'}) and $policy_holdallowed and CanItemBeReserved($borrowernumber,$itemNum) and !$itemLoopIter->{already_reserved}) { $itemLoopIter->{available} = 1; $numCopiesAvailable++; } diff --git a/opac/opac-search.pl b/opac/opac-search.pl index aba23a8..081bc81 100755 --- a/opac/opac-search.pl +++ b/opac/opac-search.pl @@ -100,7 +100,7 @@ if (C4::Context->preference("marcflavour") eq "UNIMARC" ) { elsif (C4::Context->preference("marcflavour") eq "MARC21" ) { $template->param('usmarc' => 1); } -$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') ); + $template->param( 'OPACNoResultsFound' => C4::Context->preference('OPACNoResultsFound') ); if (C4::Context->preference('BakerTaylorEnabled')) { -- 1.6.5 From adrien.saurat at biblibre.com Tue Jan 3 11:29:52 2012 From: adrien.saurat at biblibre.com (Adrien Saurat) Date: Tue, 3 Jan 2012 11:29:52 +0100 Subject: [Koha-patches] [PATCH] Bug 7379: displays copynumber description if defined AV Message-ID: <1325586592-6028-1-git-send-email-adrien.saurat@biblibre.com> If an authorized value is defined for copynumber, its description will be displayed in biblio detail page (staff and OPAC). --- catalogue/detail.pl | 97 ++++++++++++----------- opac/opac-detail.pl | 214 ++++++++++++++++++++++++++------------------------- 2 files changed, 160 insertions(+), 151 deletions(-) diff --git a/catalogue/detail.pl b/catalogue/detail.pl index a1e5cc9..abe44e0 100755 --- a/catalogue/detail.pl +++ b/catalogue/detail.pl @@ -128,8 +128,8 @@ my $hostrecords; # adding items linked via host biblios my @hostitems = GetHostItemsInfo($record); if (@hostitems){ - $hostrecords =1; - push (@items, at hostitems); + $hostrecords =1; + push (@items, at hostitems); } my $dat = &GetBiblioData($biblionumber); @@ -144,16 +144,16 @@ my @subs; foreach my $subscription (@subscriptions) { my %cell; - my $serials_to_display; + my $serials_to_display; $cell{subscriptionid} = $subscription->{subscriptionid}; $cell{subscriptionnotes} = $subscription->{notes}; $cell{branchcode} = $subscription->{branchcode}; $cell{branchname} = GetBranchName($subscription->{branchcode}); $cell{hasalert} = $subscription->{hasalert}; #get the three latest serials. - $serials_to_display = $subscription->{staffdisplaycount}; - $serials_to_display = C4::Context->preference('StaffSerialIssueDisplayCount') unless $serials_to_display; - $cell{staffdisplaycount} = $serials_to_display; + $serials_to_display = $subscription->{staffdisplaycount}; + $serials_to_display = C4::Context->preference('StaffSerialIssueDisplayCount') unless $serials_to_display; + $cell{staffdisplaycount} = $serials_to_display; $cell{latestserials} = GetLatestSerials( $subscription->{subscriptionid}, $serials_to_display ); push @subs, \%cell; @@ -167,8 +167,9 @@ $dat->{'count'} = scalar @all_items + @hostitems; $dat->{'showncount'} = scalar @items + @hostitems; $dat->{'hiddencount'} = scalar @all_items + @hostitems - scalar @items; -my $shelflocations = GetKohaAuthorisedValues('items.location', $fw); -my $collections = GetKohaAuthorisedValues('items.ccode' , $fw); +my $shelflocations = GetKohaAuthorisedValues('items.location' , $fw); +my $collections = GetKohaAuthorisedValues('items.ccode' , $fw); +my $copynumbers = GetKohaAuthorisedValues('items.copynumber', $fw); my (@itemloop, %itemfields); my $norequests = 1; my $authvalcode_items_itemlost = GetAuthValCode('items.itemlost',$fw); @@ -189,19 +190,22 @@ foreach my $item (@items) { $item->{imageurl} = defined $item->{itype} ? getitemtypeimagelocation('intranet', $itemtypes->{ $item->{itype} }{imageurl}) : ''; - foreach (qw(datedue datelastseen onloan)) { - $item->{$_} = format_date($item->{$_}); - } + foreach (qw(datedue datelastseen onloan)) { + $item->{$_} = format_date($item->{$_}); + } # item damaged, lost, withdrawn loops $item->{itemlostloop} = GetAuthorisedValues($authvalcode_items_itemlost, $item->{itemlost}) if $authvalcode_items_itemlost; if ($item->{damaged}) { $item->{itemdamagedloop} = GetAuthorisedValues($authvalcode_items_damaged, $item->{damaged}) if $authvalcode_items_damaged; } - #get shelf location and collection code description if they are authorised value. + # get shelf location and collection code description if they are authorised value + # same thing for copy number my $shelfcode = $item->{'location'}; $item->{'location'} = $shelflocations->{$shelfcode} if ( defined( $shelfcode ) && defined($shelflocations) && exists( $shelflocations->{$shelfcode} ) ); my $ccode = $item->{'ccode'}; $item->{'ccode'} = $collections->{$ccode} if ( defined( $ccode ) && defined($collections) && exists( $collections->{$ccode} ) ); + my $copynumber = $item->{'copynumber'}; + $item->{'copynumber'} = $copynumbers->{$copynumber} if ( defined( $copynumber ) && defined($copynumber) && exists( $copynumbers->{$copynumber} ) ); foreach (qw(ccode enumchron copynumber itemnotes uri)) { $itemfields{$_} = 1 if ( $item->{$_} ); } @@ -211,20 +215,20 @@ foreach my $item (@items) { my $ItemBorrowerReserveInfo = GetMemberDetails( $reservedfor, 0); if (C4::Context->preference('HidePatronName')){ - $item->{'hidepatronname'} = 1; + $item->{'hidepatronname'} = 1; } if ( defined $reservedate ) { - $item->{backgroundcolor} = 'reserved'; - $item->{reservedate} = format_date($reservedate); - $item->{ReservedForBorrowernumber} = $reservedfor; - $item->{ReservedForSurname} = $ItemBorrowerReserveInfo->{'surname'}; - $item->{ReservedForFirstname} = $ItemBorrowerReserveInfo->{'firstname'}; - $item->{ExpectedAtLibrary} = $branches->{$expectedAt}{branchname}; - $item->{Reservedcardnumber} = $ItemBorrowerReserveInfo->{'cardnumber'}; + $item->{backgroundcolor} = 'reserved'; + $item->{reservedate} = format_date($reservedate); + $item->{ReservedForBorrowernumber} = $reservedfor; + $item->{ReservedForSurname} = $ItemBorrowerReserveInfo->{'surname'}; + $item->{ReservedForFirstname} = $ItemBorrowerReserveInfo->{'firstname'}; + $item->{ExpectedAtLibrary} = $branches->{$expectedAt}{branchname}; + $item->{Reservedcardnumber} = $ItemBorrowerReserveInfo->{'cardnumber'}; } - # Check the transit status + # Check the transit status my ( $transfertwhen, $transfertfrom, $transfertto ) = GetTransfers($item->{itemnumber}); if ( defined( $transfertwhen ) && ( $transfertwhen ne '' ) ) { $item->{transfertwhen} = format_date($transfertwhen); @@ -243,40 +247,41 @@ foreach my $item (@items) { # item has a host number if its biblio number does not match the current bib if ($item->{biblionumber} ne $biblionumber){ $item->{hostbiblionumber} = $item->{biblionumber}; - $item->{hosttitle} = GetBiblioData($item->{biblionumber})->{title}; + $item->{hosttitle} = GetBiblioData($item->{biblionumber})->{title}; } - - #count if item is used in analytical bibliorecords - my $countanalytics= GetAnalyticsCount($item->{itemnumber}); - if ($countanalytics > 0){ - $analytics_flag=1; - $item->{countanalytics} = $countanalytics; - } + #count if item is used in analytical bibliorecords + my $countanalytics= GetAnalyticsCount($item->{itemnumber}); + if ( defined $countanalytics) { + if ($countanalytics > 0){ + $analytics_flag=1; + $item->{countanalytics} = $countanalytics; + } + } push @itemloop, $item; } $template->param( norequests => $norequests ); $template->param( - MARCNOTES => $marcnotesarray, - MARCSUBJCTS => $marcsubjctsarray, - MARCAUTHORS => $marcauthorsarray, - MARCSERIES => $marcseriesarray, - MARCURLS => $marcurlsarray, - MARCISBNS => $marcisbnsarray, - MARCHOSTS => $marchostsarray, - subtitle => $subtitle, - itemdata_ccode => $itemfields{ccode}, - itemdata_enumchron => $itemfields{enumchron}, - itemdata_uri => $itemfields{uri}, - itemdata_copynumber => $itemfields{copynumber}, - volinfo => $itemfields{enumchron}, + MARCNOTES => $marcnotesarray, + MARCSUBJCTS => $marcsubjctsarray, + MARCAUTHORS => $marcauthorsarray, + MARCSERIES => $marcseriesarray, + MARCURLS => $marcurlsarray, + MARCISBNS => $marcisbnsarray, + MARCHOSTS => $marchostsarray, + subtitle => $subtitle, + itemdata_ccode => $itemfields{ccode}, + itemdata_enumchron => $itemfields{enumchron}, + itemdata_uri => $itemfields{uri}, + itemdata_copynumber => $itemfields{copynumber}, + volinfo => $itemfields{enumchron}, itemdata_itemnotes => $itemfields{itemnotes}, - z3950_search_params => C4::Search::z3950_search_args($dat), + z3950_search_params => C4::Search::z3950_search_args($dat), holdcount => $holdcount, - hostrecords => $hostrecords, - analytics_flag => $analytics_flag, - C4::Search::enabled_staff_search_views, + hostrecords => $hostrecords, + analytics_flag => $analytics_flag, + C4::Search::enabled_staff_search_views, ); if (C4::Context->preference("AlternateHoldingsField") && scalar @items == 0) { diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl index f82dde2..9828a44 100755 --- a/opac/opac-detail.pl +++ b/opac/opac-detail.pl @@ -400,12 +400,12 @@ my $hideitems = 1 if C4::Context->preference('hidelostitems') or scalar(@hiddeni # Hide items if ($hideitems) { for my $itm (@all_items) { - if ( C4::Context->preference('hidelostitems') ) { - push @items, $itm unless $itm->{itemlost} or any { $itm->{'itemnumber'} eq $_ } @hiddenitems; - } else { - push @items, $itm unless any { $itm->{'itemnumber'} eq $_ } @hiddenitems; + if ( C4::Context->preference('hidelostitems') ) { + push @items, $itm unless $itm->{itemlost} or any { $itm->{'itemnumber'} eq $_ } @hiddenitems; + } else { + push @items, $itm unless any { $itm->{'itemnumber'} eq $_ } @hiddenitems; + } } -} } else { # Or not @items = @all_items; @@ -422,6 +422,7 @@ if ( $itemtype ) { } my $shelflocations =GetKohaAuthorisedValues('items.location',$dat->{'frameworkcode'}, 'opac'); my $collections = GetKohaAuthorisedValues('items.ccode',$dat->{'frameworkcode'}, 'opac'); +my $copynumbers = GetKohaAuthorisedValues('items.copynumber',$dat->{'frameworkcode'}, 'opac'); #coping with subscriptions my $subscriptionsnumber = CountSubscriptionFromBiblionumber($biblionumber); @@ -444,7 +445,7 @@ foreach my $subscription (@subscriptions) { #get the three latest serials. $serials_to_display = $subscription->{opacdisplaycount}; $serials_to_display = C4::Context->preference('OPACSerialIssueDisplayCount') unless $serials_to_display; - $cell{opacdisplaycount} = $serials_to_display; + $cell{opacdisplaycount} = $serials_to_display; $cell{latestserials} = GetLatestSerials( $subscription->{subscriptionid}, $serials_to_display ); push @subs, \%cell; @@ -467,11 +468,11 @@ my $branches = GetBranches(); my %itemfields; for my $itm (@items) { $norequests = 0 - if ( (not $itm->{'wthdrawn'} ) - && (not $itm->{'itemlost'} ) - && ($itm->{'itemnotforloan'}<0 || not $itm->{'itemnotforloan'} ) - && (not $itemtypes->{$itm->{'itype'}}->{notforloan} ) - && ($itm->{'itemnumber'} ) ); + if ( (not $itm->{'wthdrawn'} ) + && (not $itm->{'itemlost'} ) + && ($itm->{'itemnotforloan'}<0 || not $itm->{'itemnotforloan'} ) + && (not $itemtypes->{$itm->{'itype'}}->{notforloan} ) + && ($itm->{'itemnumber'} ) ); if ( defined $itm->{'publictype'} ) { # I can't actually find any case in which this is defined. --amoore 2008-12-09 @@ -480,10 +481,13 @@ for my $itm (@items) { $itm->{datedue} = format_date($itm->{datedue}); $itm->{datelastseen} = format_date($itm->{datelastseen}); - # get collection code description, too + # get collection code and copynumber description, too if ( my $ccode = $itm->{'ccode'} ) { $itm->{'ccode'} = $collections->{$ccode} if ( defined($collections) && exists( $collections->{$ccode} ) ); } + if ( my $copynumber = $itm->{'copynumber'} ) { + $itm->{'copynumber'} = $copynumbers->{$copynumber} if ( defined($copynumbers) && exists( $copynumbers->{$copynumber} ) ); + } if ( defined $itm->{'location'} ) { $itm->{'location_description'} = $shelflocations->{ $itm->{'location'} }; } @@ -499,52 +503,52 @@ for my $itm (@items) { my $item_authorised_value_images = C4::Items::get_authorised_value_images( C4::Items::get_item_authorised_values( $itm->{'itemnumber'} ) ); # warn( Data::Dumper->Dump( [ $item_authorised_value_images ], [ 'item_authorised_value_images' ] ) ); - if ( $itm->{'itemlost'} ) { - my $lostimageinfo = List::Util::first { $_->{'category'} eq 'LOST' } @$item_authorised_value_images; - $itm->{'lostimageurl'} = $lostimageinfo->{ 'imageurl' }; - $itm->{'lostimagelabel'} = $lostimageinfo->{ 'label' }; - } - - if( $itm->{'count_reserves'}){ - if( $itm->{'count_reserves'} eq "Waiting"){ $itm->{'waiting'} = 1; } - if( $itm->{'count_reserves'} eq "Reserved"){ $itm->{'onhold'} = 1; } - } - - my ( $transfertwhen, $transfertfrom, $transfertto ) = GetTransfers($itm->{itemnumber}); - if ( defined( $transfertwhen ) && $transfertwhen ne '' ) { + if ( $itm->{'itemlost'} ) { + my $lostimageinfo = List::Util::first { $_->{'category'} eq 'LOST' } @$item_authorised_value_images; + $itm->{'lostimageurl'} = $lostimageinfo->{ 'imageurl' }; + $itm->{'lostimagelabel'} = $lostimageinfo->{ 'label' }; + } + + if( $itm->{'count_reserves'}){ + if( $itm->{'count_reserves'} eq "Waiting"){ $itm->{'waiting'} = 1; } + if( $itm->{'count_reserves'} eq "Reserved"){ $itm->{'onhold'} = 1; } + } + + my ( $transfertwhen, $transfertfrom, $transfertto ) = GetTransfers($itm->{itemnumber}); + if ( defined( $transfertwhen ) && $transfertwhen ne '' ) { $itm->{transfertwhen} = format_date($transfertwhen); $itm->{transfertfrom} = $branches->{$transfertfrom}{branchname}; $itm->{transfertto} = $branches->{$transfertto}{branchname}; - } + } } ## get notes and subjects from MARC record -my $dbh = C4::Context->dbh; -my $marcnotesarray = GetMarcNotes ($record,$marcflavour); -my $marcisbnsarray = GetMarcISBN ($record,$marcflavour); -my $marcauthorsarray = GetMarcAuthors ($record,$marcflavour); -my $marcsubjctsarray = GetMarcSubjects($record,$marcflavour); -my $marcseriesarray = GetMarcSeries ($record,$marcflavour); -my $marcurlsarray = GetMarcUrls ($record,$marcflavour); -my $marchostsarray = GetMarcHosts($record,$marcflavour); -my $subtitle = GetRecordValue('subtitle', $record, GetFrameworkCode($biblionumber)); +my $dbh = C4::Context->dbh; +my $marcnotesarray = GetMarcNotes ($record,$marcflavour); +my $marcisbnsarray = GetMarcISBN ($record,$marcflavour); +my $marcauthorsarray = GetMarcAuthors ($record,$marcflavour); +my $marcsubjctsarray = GetMarcSubjects($record,$marcflavour); +my $marcseriesarray = GetMarcSeries ($record,$marcflavour); +my $marcurlsarray = GetMarcUrls ($record,$marcflavour); +my $marchostsarray = GetMarcHosts($record,$marcflavour); +my $subtitle = GetRecordValue('subtitle', $record, GetFrameworkCode($biblionumber)); $template->param( - MARCNOTES => $marcnotesarray, - MARCSUBJCTS => $marcsubjctsarray, - MARCAUTHORS => $marcauthorsarray, - MARCSERIES => $marcseriesarray, - MARCURLS => $marcurlsarray, - MARCHOSTS => $marchostsarray, - norequests => $norequests, - RequestOnOpac => C4::Context->preference("RequestOnOpac"), - itemdata_ccode => $itemfields{ccode}, - itemdata_enumchron => $itemfields{enumchron}, - itemdata_uri => $itemfields{uri}, - itemdata_copynumber => $itemfields{copynumber}, - itemdata_itemnotes => $itemfields{itemnotes}, - authorised_value_images => $biblio_authorised_value_images, - subtitle => $subtitle, + MARCNOTES => $marcnotesarray, + MARCSUBJCTS => $marcsubjctsarray, + MARCAUTHORS => $marcauthorsarray, + MARCSERIES => $marcseriesarray, + MARCURLS => $marcurlsarray, + MARCHOSTS => $marchostsarray, + norequests => $norequests, + RequestOnOpac => C4::Context->preference("RequestOnOpac"), + itemdata_ccode => $itemfields{ccode}, + itemdata_enumchron => $itemfields{enumchron}, + itemdata_uri => $itemfields{uri}, + itemdata_copynumber => $itemfields{copynumber}, + itemdata_itemnotes => $itemfields{itemnotes}, + authorised_value_images => $biblio_authorised_value_images, + subtitle => $subtitle, ); if (C4::Context->preference("AlternateHoldingsField") && scalar @items == 0) { @@ -590,11 +594,11 @@ if ( $isbn or $ean or $oclc or $upc ) { $content_identifier_exists = 1; } $template->param( - normalized_upc => $upc, - normalized_ean => $ean, - normalized_oclc => $oclc, - normalized_isbn => $isbn, - content_identifier_exists => $content_identifier_exists, + normalized_upc => $upc, + normalized_ean => $ean, + normalized_oclc => $oclc, + normalized_isbn => $isbn, + content_identifier_exists => $content_identifier_exists, ); # COinS format FIXME: for books Only @@ -628,14 +632,14 @@ foreach ( @$reviews ) { $_->{cardnumber} = $borrowerData->{'cardnumber'}; $_->{datereviewed} = format_date($_->{datereviewed}); if ($borrowerData->{'borrowernumber'} eq $borrowernumber) { - $_->{your_comment} = 1; - $loggedincommenter = 1; - } + $_->{your_comment} = 1; + $loggedincommenter = 1; + } } if(C4::Context->preference("ISBD")) { - $template->param(ISBD => 1); + $template->param(ISBD => 1); } $template->param( @@ -676,14 +680,14 @@ foreach my $sc_field (@sc_fields) { $row_data{branch} = $sc_field->subfield('9'); if ($row_data{text} && $row_data{branch}) { - push (@serialcollections, \%row_data); + push (@serialcollections, \%row_data); } } if (scalar(@serialcollections) > 0) { $template->param( - serialcollection => 1, - serialcollections => \@serialcollections); + serialcollection => 1, + serialcollections => \@serialcollections); } # Amazon.com Stuff @@ -734,12 +738,12 @@ my $syndetics_elements; if ( C4::Context->preference("SyndeticsEnabled") ) { $template->param("SyndeticsEnabled" => 1); $template->param("SyndeticsClientCode" => C4::Context->preference("SyndeticsClientCode")); - eval { - $syndetics_elements = &get_syndetics_index($isbn,$upc,$oclc); - for my $element (values %$syndetics_elements) { - $template->param("Syndetics$element"."Exists" => 1 ); - #warn "Exists: "."Syndetics$element"."Exists"; - } + eval { + $syndetics_elements = &get_syndetics_index($isbn,$upc,$oclc); + for my $element (values %$syndetics_elements) { + $template->param("Syndetics$element"."Exists" => 1 ); + #warn "Exists: "."Syndetics$element"."Exists"; + } }; warn $@ if $@; } @@ -747,22 +751,22 @@ if ( C4::Context->preference("SyndeticsEnabled") ) { if ( C4::Context->preference("SyndeticsEnabled") && C4::Context->preference("SyndeticsSummary") && ( exists($syndetics_elements->{'SUMMARY'}) || exists($syndetics_elements->{'AVSUMMARY'}) ) ) { - eval { - my $syndetics_summary = &get_syndetics_summary($isbn,$upc,$oclc, $syndetics_elements); - $template->param( SYNDETICS_SUMMARY => $syndetics_summary ); - }; - warn $@ if $@; + eval { + my $syndetics_summary = &get_syndetics_summary($isbn,$upc,$oclc, $syndetics_elements); + $template->param( SYNDETICS_SUMMARY => $syndetics_summary ); + }; + warn $@ if $@; } if ( C4::Context->preference("SyndeticsEnabled") && C4::Context->preference("SyndeticsTOC") && exists($syndetics_elements->{'TOC'}) ) { - eval { - my $syndetics_toc = &get_syndetics_toc($isbn,$upc,$oclc); - $template->param( SYNDETICS_TOC => $syndetics_toc ); - }; - warn $@ if $@; + eval { + my $syndetics_toc = &get_syndetics_toc($isbn,$upc,$oclc); + $template->param( SYNDETICS_TOC => $syndetics_toc ); + }; + warn $@ if $@; } if ( C4::Context->preference("SyndeticsEnabled") @@ -772,7 +776,7 @@ if ( C4::Context->preference("SyndeticsEnabled") my $syndetics_excerpt = &get_syndetics_excerpt($isbn,$upc,$oclc); $template->param( SYNDETICS_EXCERPT => $syndetics_excerpt ); }; - warn $@ if $@; + warn $@ if $@; } if ( C4::Context->preference("SyndeticsEnabled") @@ -781,12 +785,12 @@ if ( C4::Context->preference("SyndeticsEnabled") my $syndetics_reviews = &get_syndetics_reviews($isbn,$upc,$oclc,$syndetics_elements); $template->param( SYNDETICS_REVIEWS => $syndetics_reviews ); }; - warn $@ if $@; + warn $@ if $@; } if ( C4::Context->preference("SyndeticsEnabled") && C4::Context->preference("SyndeticsAuthorNotes") - && exists($syndetics_elements->{'ANOTES'}) ) { + && exists($syndetics_elements->{'ANOTES'}) ) { eval { my $syndetics_anotes = &get_syndetics_anotes($isbn,$upc,$oclc); $template->param( SYNDETICS_ANOTES => $syndetics_anotes ); @@ -843,34 +847,34 @@ if (C4::Context->preference("OPACShelfBrowser")) { } if (C4::Context->preference("BakerTaylorEnabled")) { - $template->param( - BakerTaylorEnabled => 1, - BakerTaylorImageURL => &image_url(), - BakerTaylorLinkURL => &link_url(), - BakerTaylorBookstoreURL => C4::Context->preference('BakerTaylorBookstoreURL'), - ); - my ($bt_user, $bt_pass); - if ($isbn and - $bt_user = C4::Context->preference('BakerTaylorUsername') and - $bt_pass = C4::Context->preference('BakerTaylorPassword') ) - { - $template->param( - BakerTaylorContentURL => - sprintf("http://contentcafe2.btol.com/ContentCafeClient/ContentCafe.aspx?UserID=%s&Password=%s&ItemKey=%s&Options=Y", - $bt_user,$bt_pass,$isbn) - ); - } + $template->param( + BakerTaylorEnabled => 1, + BakerTaylorImageURL => &image_url(), + BakerTaylorLinkURL => &link_url(), + BakerTaylorBookstoreURL => C4::Context->preference('BakerTaylorBookstoreURL'), + ); + my ($bt_user, $bt_pass); + if ($isbn and + $bt_user = C4::Context->preference('BakerTaylorUsername') and + $bt_pass = C4::Context->preference('BakerTaylorPassword') ) + { + $template->param( + BakerTaylorContentURL => + sprintf("http://contentcafe2.btol.com/ContentCafeClient/ContentCafe.aspx?UserID=%s&Password=%s&ItemKey=%s&Options=Y", + $bt_user,$bt_pass,$isbn) + ); + } } my $tag_quantity; if (C4::Context->preference('TagsEnabled') and $tag_quantity = C4::Context->preference('TagsShowOnDetail')) { - $template->param( - TagsEnabled => 1, - TagsShowOnDetail => $tag_quantity, - TagsInputOnDetail => C4::Context->preference('TagsInputOnDetail') - ); - $template->param(TagLoop => get_tags({biblionumber=>$biblionumber, approved=>1, - 'sort'=>'-weight', limit=>$tag_quantity})); + $template->param( + TagsEnabled => 1, + TagsShowOnDetail => $tag_quantity, + TagsInputOnDetail => C4::Context->preference('TagsInputOnDetail') + ); + $template->param(TagLoop => get_tags({biblionumber=>$biblionumber, approved=>1, + 'sort'=>'-weight', limit=>$tag_quantity})); } if (C4::Context->preference("OPACURLOpenInNewWindow")) { -- 1.7.4.1 From gaetan.boisson at biblibre.com Tue Jan 3 15:44:26 2012 From: gaetan.boisson at biblibre.com (Gaetan Boisson) Date: Tue, 3 Jan 2012 15:44:26 +0100 Subject: [Koha-patches] [PATCH] [SIGNED-OFF] Message-ID: <1325601866-12489-1-git-send-email-gaetan.boisson@biblibre.com> From: Adrien Saurat Works beautifully! Bug 6374: default value for Size in result pages When no size info is available, an empty string is sent to the TT (if nothing is sent, the TT engine will display another information, irrelevant for Koha). Signed-off-by: Gaetan Boisson --- catalogue/search.pl | 40 ++++--- cataloguing/addbooks.pl | 3 + opac/opac-search.pl | 262 ++++++++++++++++++++++++----------------------- 3 files changed, 158 insertions(+), 147 deletions(-) diff --git a/catalogue/search.pl b/catalogue/search.pl index 3013320..86ad2b7 100755 --- a/catalogue/search.pl +++ b/catalogue/search.pl @@ -440,18 +440,18 @@ if ($params->{'limit-yr'}) { # $ %z3950p will be a hash ref if the indexes are present (advacned search), otherwise undef my $z3950par; my $indexes2z3950 = { - kw=>'title', au=>'author', 'au,phr'=>'author', nb=>'isbn', ns=>'issn', - 'lcn,phr'=>'dewey', su=>'subject', 'su,phr'=>'subject', - ti=>'title', 'ti,phr'=>'title', se=>'title' + kw=>'title', au=>'author', 'au,phr'=>'author', nb=>'isbn', ns=>'issn', + 'lcn,phr'=>'dewey', su=>'subject', 'su,phr'=>'subject', + ti=>'title', 'ti,phr'=>'title', se=>'title' }; for (my $ii = 0; $ii < @operands; ++$ii) { - my $name = $indexes2z3950->{$indexes[$ii]}; - if (defined $name && defined $operands[$ii]) - { - $z3950par ||= {}; - $z3950par->{$name} = $operands[$ii] if !exists $z3950par->{$name}; - } + my $name = $indexes2z3950->{$indexes[$ii]}; + if (defined $name && defined $operands[$ii]) + { + $z3950par ||= {}; + $z3950par->{$name} = $operands[$ii] if !exists $z3950par->{$name}; + } } @@ -484,9 +484,9 @@ for my $this_cgi ( split('&',$query_cgi) ) { my $input_name = $1; my $input_value = $2; push @query_inputs, { input_name => $input_name, input_value => $input_value }; - if ($input_name eq 'idx') { - $scan_index_to_use = $input_value; # unless $scan_index_to_use; - } + if ($input_name eq 'idx') { + $scan_index_to_use = $input_value; # unless $scan_index_to_use; + } } $template->param ( QUERY_INPUTS => \@query_inputs, scan_index_to_use => $scan_index_to_use ); @@ -552,8 +552,8 @@ for (my $i=0;$i<@servers;$i++) { ## If there's just one result, redirect to the detail page if ($total == 1) { my $biblionumber = $newresults[0]->{biblionumber}; - my $defaultview = C4::Context->preference('IntranetBiblioDefaultView'); - my $views = { C4::Search::enabled_staff_search_views }; + my $defaultview = C4::Context->preference('IntranetBiblioDefaultView'); + my $views = { C4::Search::enabled_staff_search_views }; if ($defaultview eq 'isbd' && $views->{can_view_ISBD}) { print $cgi->redirect("/cgi-bin/koha/catalogue/ISBDdetail.pl?biblionumber=$biblionumber"); } elsif ($defaultview eq 'marc' && $views->{can_view_MARC}) { @@ -578,14 +578,18 @@ for (my $i=0;$i<@servers;$i++) { $template->param(limit_desc => $limit_desc); $template->param(offset => $offset); $template->param(DisplayMultiPlaceHold => $DisplayMultiPlaceHold); - $template->param (z3950_search_params => C4::Search::z3950_search_args($query_desc)); + $template->param (z3950_search_params => C4::Search::z3950_search_args($query_desc)); if ($query_desc || $limit_desc) { $template->param(searchdesc => 1); } $template->param(stopwords_removed => "@$stopwords_removed") if $stopwords_removed; $template->param(results_per_page => $results_per_page); + # must define a value for size if not present in DB + # in order to avoid problems generated by the default size value in TT + foreach my $line (@newresults) { + if ( not exists $line->{'size'} ) { $line->{'size'} = "" } + } $template->param(SEARCH_RESULTS => \@newresults); - ## FIXME: add a global function for this, it's better than the current global one ## Build the page numbers on the bottom of the page my @page_numbers; @@ -649,7 +653,7 @@ for (my $i=0;$i<@servers;$i++) { # no hits else { $template->param(searchdesc => 1,query_desc => $query_desc,limit_desc => $limit_desc); - $template->param (z3950_search_params => C4::Search::z3950_search_args($z3950par || $query_desc)); + $template->param (z3950_search_params => C4::Search::z3950_search_args($z3950par || $query_desc)); } } # end of the if local @@ -679,7 +683,7 @@ $template->param( total => $total, opacfacets => 1, facets_loop => $facets, - displayFacetCount=> C4::Context->preference('displayFacetCount')||0, + displayFacetCount=> C4::Context->preference('displayFacetCount')||0, scan => $scan, search_error => $error, ); diff --git a/cataloguing/addbooks.pl b/cataloguing/addbooks.pl index 5e89ef8..270b16d 100755 --- a/cataloguing/addbooks.pl +++ b/cataloguing/addbooks.pl @@ -87,6 +87,9 @@ if ($query) { # SimpleSearch() give the results per page we want, so 0 offet here my $total = @{$marcresults}; my @newresults = searchResults( 'intranet', $query, $total, $results_per_page, 0, 0, @{$marcresults} ); + foreach my $line (@newresults) { + if ( not exists $line->{'size'} ) { $line->{'size'} = "" } + } $template->param( total => $total_hits, query => $query, diff --git a/opac/opac-search.pl b/opac/opac-search.pl index aba23a8..4a2a493 100755 --- a/opac/opac-search.pl +++ b/opac/opac-search.pl @@ -48,10 +48,10 @@ use CGI qw('-no_undef_params'); my $cgi = new CGI; BEGIN { - if (C4::Context->preference('BakerTaylorEnabled')) { - require C4::External::BakerTaylor; - import C4::External::BakerTaylor qw(&image_url &link_url); - } + if (C4::Context->preference('BakerTaylorEnabled')) { + require C4::External::BakerTaylor; + import C4::External::BakerTaylor qw(&image_url &link_url); + } } my ($template,$borrowernumber,$cookie); @@ -64,13 +64,13 @@ my @params = $cgi->param("limit"); my $format = $cgi->param("format") || ''; my $build_grouped_results = C4::Context->preference('OPACGroupResults'); if ($format =~ /(rss|atom|opensearchdescription)/) { - $template_name = 'opac-opensearch.tmpl'; + $template_name = 'opac-opensearch.tmpl'; } elsif (@params && $build_grouped_results) { $template_name = 'opac-results-grouped.tmpl'; } elsif ((@params>=1) || ($cgi->param("q")) || ($cgi->param('multibranchlimit')) || ($cgi->param('limit-yr')) ) { - $template_name = 'opac-results.tmpl'; + $template_name = 'opac-results.tmpl'; } else { $template_name = 'opac-advsearch.tmpl'; @@ -89,7 +89,7 @@ if ($template_name eq 'opac-results.tmpl') { } if ($format eq 'rss2' or $format eq 'opensearchdescription' or $format eq 'atom') { - $template->param($format => 1); + $template->param($format => 1); $template->param(timestamp => strftime("%Y-%m-%dT%H:%M:%S-00:00", gmtime)) if ($format eq 'atom'); # FIXME - the timestamp is a hack - the biblio update timestamp should be used for each # entry, but not sure if that's worth an extra database query for each bib @@ -104,18 +104,18 @@ $template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHo $template->param( 'OPACNoResultsFound' => C4::Context->preference('OPACNoResultsFound') ); if (C4::Context->preference('BakerTaylorEnabled')) { - $template->param( - BakerTaylorEnabled => 1, - BakerTaylorImageURL => &image_url(), - BakerTaylorLinkURL => &link_url(), - BakerTaylorBookstoreURL => C4::Context->preference('BakerTaylorBookstoreURL'), - ); + $template->param( + BakerTaylorEnabled => 1, + BakerTaylorImageURL => &image_url(), + BakerTaylorLinkURL => &link_url(), + BakerTaylorBookstoreURL => C4::Context->preference('BakerTaylorBookstoreURL'), + ); } if (C4::Context->preference('TagsEnabled')) { - $template->param(TagsEnabled => 1); - foreach (qw(TagsShowOnList TagsInputOnList)) { - C4::Context->preference($_) and $template->param($_ => 1); - } + $template->param(TagsEnabled => 1); + foreach (qw(TagsShowOnList TagsInputOnList)) { + C4::Context->preference($_) and $template->param($_ => 1); + } } ## URI Re-Writing @@ -163,32 +163,32 @@ my $cnt; my $advanced_search_types = C4::Context->preference("AdvancedSearchTypes"); if (!$advanced_search_types or $advanced_search_types eq 'itemtypes') { - foreach my $thisitemtype ( sort {$itemtypes->{$a}->{'description'} cmp $itemtypes->{$b}->{'description'} } keys %$itemtypes ) { - my %row =( number=>$cnt++, - ccl => "$itype_or_itemtype,phr", + foreach my $thisitemtype ( sort {$itemtypes->{$a}->{'description'} cmp $itemtypes->{$b}->{'description'} } keys %$itemtypes ) { + my %row =( number=>$cnt++, + ccl => "$itype_or_itemtype,phr", code => $thisitemtype, selected => $selected, description => $itemtypes->{$thisitemtype}->{'description'}, count5 => $cnt % 4, imageurl=> getitemtypeimagelocation( 'opac', $itemtypes->{$thisitemtype}->{'imageurl'} ), ); - $selected = 0; # set to zero after first pass through - push @itemtypesloop, \%row; - } + $selected = 0; # set to zero after first pass through + push @itemtypesloop, \%row; + } } else { my $advsearchtypes = GetAuthorisedValues($advanced_search_types, '', 'opac'); - for my $thisitemtype (@$advsearchtypes) { - my %row =( - number=>$cnt++, - ccl => $advanced_search_types, + for my $thisitemtype (@$advsearchtypes) { + my %row =( + number=>$cnt++, + ccl => $advanced_search_types, code => $thisitemtype->{authorised_value}, selected => $selected, description => $thisitemtype->{'lib'}, count5 => $cnt % 4, imageurl=> getitemtypeimagelocation( 'opac', $thisitemtype->{'imageurl'} ), ); - push @itemtypesloop, \%row; - } + push @itemtypesloop, \%row; + } } $template->param(itemtypeloop => \@itemtypesloop); @@ -244,20 +244,20 @@ if ( $template_type && $template_type eq 'advsearch' ) { } } - $template->param(uc(C4::Context->preference("marcflavour")) => 1, # we already did this for UNIMARC - advsearch => 1, - search_boxes_loop => \@search_boxes_array); - -# use the global setting by default - if ( C4::Context->preference("expandedSearchOption") == 1 ) { - $template->param( expanded_options => C4::Context->preference("expandedSearchOption") ); - } - # but let the user override it - if (defined $cgi->param('expanded_options')) { - if ( ($cgi->param('expanded_options') == 0) || ($cgi->param('expanded_options') == 1 ) ) { - $template->param( expanded_options => $cgi->param('expanded_options')); - } + $template->param(uc( C4::Context->preference("marcflavour")) => 1, # we already did this for UNIMARC + advsearch => 1, + search_boxes_loop => \@search_boxes_array); + + # use the global setting by default + if ( C4::Context->preference("expandedSearchOption") == 1 ) { + $template->param( expanded_options => C4::Context->preference("expandedSearchOption") ); + } + # but let the user override it + if (defined $cgi->param('expanded_options')) { + if ( ($cgi->param('expanded_options') == 0) || ($cgi->param('expanded_options') == 1 ) ) { + $template->param( expanded_options => $cgi->param('expanded_options')); } + } output_html_with_http_headers $cgi, $cookie, $template->output; exit; } @@ -284,8 +284,6 @@ for (keys %$params) { $j++; } } -# - # Params that can have more than one value # sort by is used to sort the query @@ -430,15 +428,15 @@ my $results_hashref; my @coins; if ($tag) { - $query_cgi = "tag=" .$tag . "&" . $query_cgi; - my $taglist = get_tags({term=>$tag, approved=>1}); - $results_hashref->{biblioserver}->{hits} = scalar (@$taglist); - my @biblist = (map {GetBiblioData($_->{biblionumber})} @$taglist); - my @marclist = (map {$_->{marc}} @biblist ); - $DEBUG and printf STDERR "taglist (%s biblionumber)\nmarclist (%s records)\n", scalar(@$taglist), scalar(@marclist); - $results_hashref->{biblioserver}->{RECORDS} = \@marclist; - # FIXME: tag search and standard search should work together, not exclusively - # FIXME: No facets for tags search. + $query_cgi = "tag=" .$tag . "&" . $query_cgi; + my $taglist = get_tags({term=>$tag, approved=>1}); + $results_hashref->{biblioserver}->{hits} = scalar (@$taglist); + my @biblist = (map {GetBiblioData($_->{biblionumber})} @$taglist); + my @marclist = (map {$_->{marc}} @biblist ); + $DEBUG and printf STDERR "taglist (%s biblionumber)\nmarclist (%s records)\n", scalar(@$taglist), scalar(@marclist); + $results_hashref->{biblioserver}->{RECORDS} = \@marclist; + # FIXME: tag search and standard search should work together, not exclusively + # FIXME: No facets for tags search. } elsif (C4::Context->preference('NoZebra')) { eval { @@ -494,76 +492,82 @@ for (my $i=0;$i<@servers;$i++) { @newresults = searchResults('opac', $query_desc, $hits, $results_per_page, $offset, $scan, @{$results_hashref->{$server}->{"RECORDS"}},, C4::Context->preference('hidelostitems')); } - my $tag_quantity; - if (C4::Context->preference('TagsEnabled') and - $tag_quantity = C4::Context->preference('TagsShowOnList')) { - foreach (@newresults) { - my $bibnum = $_->{biblionumber} or next; - $_->{itemsissued} = CountItemsIssued( $bibnum ); - $_ ->{'TagLoop'} = get_tags({biblionumber=>$bibnum, approved=>1, 'sort'=>'-weight', - limit=>$tag_quantity }); - } - } - if (C4::Context->preference('COinSinOPACResults')) { - foreach (@newresults) { - my $record = GetMarcBiblio($_->{'biblionumber'}); - $_->{coins} = GetCOinSBiblio($record); - } - } + + # must define a value for size if not present in DB + # in order to avoid problems generated by the default size value in TT + foreach my $line (@newresults) { + if ( not exists $line->{'size'} ) { $line->{'size'} = "" } + } + + my $tag_quantity; + if (C4::Context->preference('TagsEnabled') and + $tag_quantity = C4::Context->preference('TagsShowOnList')) { + foreach (@newresults) { + my $bibnum = $_->{biblionumber} or next; + $_->{itemsissued} = CountItemsIssued( $bibnum ); + $_ ->{'TagLoop'} = get_tags({biblionumber=>$bibnum, approved=>1, 'sort'=>'-weight', + limit=>$tag_quantity }); + } + } + if (C4::Context->preference('COinSinOPACResults')) { + foreach (@newresults) { + my $record = GetMarcBiblio($_->{'biblionumber'}); + $_->{coins} = GetCOinSBiblio($record); + } + } - if ($results_hashref->{$server}->{"hits"}){ - $total = $total + $results_hashref->{$server}->{"hits"}; - } - # Opac search history - my $newsearchcookie; - if (C4::Context->preference('EnableOpacSearchHistory')) { - my @recentSearches; - - # Getting the (maybe) already sent cookie - my $searchcookie = $cgi->cookie('KohaOpacRecentSearches'); - if ($searchcookie){ - $searchcookie = uri_unescape($searchcookie); - if (thaw($searchcookie)) { - @recentSearches = @{thaw($searchcookie)}; - } - } - - # Adding the new search if needed - if (!$borrowernumber || $borrowernumber eq '') { - # To a cookie (the user is not logged in) - - if (($params->{'offset'}||'') eq '') { - - push @recentSearches, { - "query_desc" => $query_desc || "unknown", - "query_cgi" => $query_cgi || "unknown", - "time" => time(), - "total" => $total - }; - $template->param(ShowOpacRecentSearchLink => 1); - } - - shift @recentSearches if (@recentSearches > 15); - # Pushing the cookie back - $newsearchcookie = $cgi->cookie( - -name => 'KohaOpacRecentSearches', - # We uri_escape the whole freezed structure so we're sure we won't have any encoding problems - -value => uri_escape(freeze(\@recentSearches)), - -expires => '' - ); - $cookie = [$cookie, $newsearchcookie]; - } - else { - # To the session (the user is logged in) - if (($params->{'offset'}||'') eq '') { - AddSearchHistory($borrowernumber, $cgi->cookie("CGISESSID"), $query_desc, $query_cgi, $total); - $template->param(ShowOpacRecentSearchLink => 1); - } - } - } - ## If there's just one result, redirect to the detail page + if ($results_hashref->{$server}->{"hits"}){ + $total = $total + $results_hashref->{$server}->{"hits"}; + } + + # Opac search history + my $newsearchcookie; + if (C4::Context->preference('EnableOpacSearchHistory')) { + my @recentSearches; + + # Getting the (maybe) already sent cookie + my $searchcookie = $cgi->cookie('KohaOpacRecentSearches'); + if ($searchcookie){ + $searchcookie = uri_unescape($searchcookie); + if (thaw($searchcookie)) { + @recentSearches = @{thaw($searchcookie)}; + } + } + + # Adding the new search if needed + if (!$borrowernumber || $borrowernumber eq '') { + # To a cookie (the user is not logged in) + if (($params->{'offset'}||'') eq '') { + push @recentSearches, { + "query_desc" => $query_desc || "unknown", + "query_cgi" => $query_cgi || "unknown", + "time" => time(), + "total" => $total + }; + $template->param(ShowOpacRecentSearchLink => 1); + } + + shift @recentSearches if (@recentSearches > 15); + # Pushing the cookie back + $newsearchcookie = $cgi->cookie( + -name => 'KohaOpacRecentSearches', + # We uri_escape the whole freezed structure so we're sure we won't have any encoding problems + -value => uri_escape(freeze(\@recentSearches)), + -expires => '' + ); + $cookie = [$cookie, $newsearchcookie]; + } + else { + # To the session (the user is logged in) + if (($params->{'offset'}||'') eq '') { + AddSearchHistory($borrowernumber, $cgi->cookie("CGISESSID"), $query_desc, $query_cgi, $total); + $template->param(ShowOpacRecentSearchLink => 1); + } + } + } + ## If there's just one result, redirect to the detail page if ($total == 1 && $format ne 'rss2' - && $format ne 'opensearchdescription' && $format ne 'atom') { + && $format ne 'opensearchdescription' && $format ne 'atom') { my $biblionumber=$newresults[0]->{biblionumber}; if (C4::Context->preference('BiblioDefaultView') eq 'isbd') { print $cgi->redirect("/cgi-bin/koha/opac-ISBDdetail.pl?biblionumber=$biblionumber"); @@ -668,7 +672,7 @@ for (my $i=0;$i<@servers;$i++) { $template->param( PAGE_NUMBERS => \@page_numbers, previous_page_offset => $previous_page_offset) unless $pages < 2; $template->param(next_page_offset => $next_page_offset) unless $pages eq $current_page_number; - } + } # no hits else { $template->param(searchdesc => 1,query_desc => $query_desc,limit_desc => $limit_desc); @@ -699,7 +703,7 @@ $template->param( total => $total, opacfacets => 1, facets_loop => $facets, - displayFacetCount=> C4::Context->preference('displayFacetCount')||0, + displayFacetCount=> C4::Context->preference('displayFacetCount')||0, scan => $scan, search_error => $error, ); @@ -715,18 +719,18 @@ my @addpubshelves; my $pubshelves = $session->param('pubshelves'); my $barshelves = $session->param('barshelves'); foreach my $shelf (@$pubshelves) { - next if ( ($shelf->{'owner'} != ($borrowernumber ? $borrowernumber : -1)) && ($shelf->{'category'} < 3) ); - push (@addpubshelves, $shelf); + next if ( ($shelf->{'owner'} != ($borrowernumber ? $borrowernumber : -1)) && ($shelf->{'category'} < 3) ); + push (@addpubshelves, $shelf); } if (@addpubshelves) { - $template->param( addpubshelves => scalar (@addpubshelves)); - $template->param( addpubshelvesloop => \@addpubshelves); + $template->param( addpubshelves => scalar (@addpubshelves)); + $template->param( addpubshelvesloop => \@addpubshelves); } if (defined $barshelves) { - $template->param( addbarshelves => scalar (@$barshelves)); - $template->param( addbarshelvesloop => $barshelves); + $template->param( addbarshelves => scalar (@$barshelves)); + $template->param( addbarshelvesloop => $barshelves); } my $content_type = ($format eq 'rss' or $format eq 'atom') ? $format : 'html'; -- 1.7.5.4 From gaetan.boisson at biblibre.com Tue Jan 3 17:07:58 2012 From: gaetan.boisson at biblibre.com (Gaetan Boisson) Date: Tue, 3 Jan 2012 17:07:58 +0100 Subject: [Koha-patches] [PATCH] [SIGNED-OFF] Message-ID: <1325606878-14681-1-git-send-email-gaetan.boisson@biblibre.com> From: Adrien Saurat Works on the OPAC and in the admin, both in normal and item view. Bug 7379: display of copynumber description The biblio/items detail pages display the copynumber description if an authorized value is configured accordingly. Signed-off-by: Gaetan Boisson --- catalogue/detail.pl | 99 +++++---- catalogue/moredetail.pl | 26 ++- .../prog/en/modules/catalogue/moredetail.tt | 2 +- opac/opac-detail.pl | 221 ++++++++++---------- 4 files changed, 182 insertions(+), 166 deletions(-) diff --git a/catalogue/detail.pl b/catalogue/detail.pl index a1e5cc9..2c6de81 100755 --- a/catalogue/detail.pl +++ b/catalogue/detail.pl @@ -128,8 +128,8 @@ my $hostrecords; # adding items linked via host biblios my @hostitems = GetHostItemsInfo($record); if (@hostitems){ - $hostrecords =1; - push (@items, at hostitems); + $hostrecords =1; + push (@items, at hostitems); } my $dat = &GetBiblioData($biblionumber); @@ -144,16 +144,16 @@ my @subs; foreach my $subscription (@subscriptions) { my %cell; - my $serials_to_display; + my $serials_to_display; $cell{subscriptionid} = $subscription->{subscriptionid}; $cell{subscriptionnotes} = $subscription->{notes}; $cell{branchcode} = $subscription->{branchcode}; $cell{branchname} = GetBranchName($subscription->{branchcode}); $cell{hasalert} = $subscription->{hasalert}; #get the three latest serials. - $serials_to_display = $subscription->{staffdisplaycount}; - $serials_to_display = C4::Context->preference('StaffSerialIssueDisplayCount') unless $serials_to_display; - $cell{staffdisplaycount} = $serials_to_display; + $serials_to_display = $subscription->{staffdisplaycount}; + $serials_to_display = C4::Context->preference('StaffSerialIssueDisplayCount') unless $serials_to_display; + $cell{staffdisplaycount} = $serials_to_display; $cell{latestserials} = GetLatestSerials( $subscription->{subscriptionid}, $serials_to_display ); push @subs, \%cell; @@ -167,8 +167,9 @@ $dat->{'count'} = scalar @all_items + @hostitems; $dat->{'showncount'} = scalar @items + @hostitems; $dat->{'hiddencount'} = scalar @all_items + @hostitems - scalar @items; -my $shelflocations = GetKohaAuthorisedValues('items.location', $fw); -my $collections = GetKohaAuthorisedValues('items.ccode' , $fw); +my $shelflocations = GetKohaAuthorisedValues('items.location' , $fw); +my $collections = GetKohaAuthorisedValues('items.ccode' , $fw); +my $copynumbers = GetKohaAuthorisedValues('items.copynumber', $fw); my (@itemloop, %itemfields); my $norequests = 1; my $authvalcode_items_itemlost = GetAuthValCode('items.itemlost',$fw); @@ -189,19 +190,22 @@ foreach my $item (@items) { $item->{imageurl} = defined $item->{itype} ? getitemtypeimagelocation('intranet', $itemtypes->{ $item->{itype} }{imageurl}) : ''; - foreach (qw(datedue datelastseen onloan)) { - $item->{$_} = format_date($item->{$_}); - } + foreach (qw(datedue datelastseen onloan)) { + $item->{$_} = format_date($item->{$_}); + } # item damaged, lost, withdrawn loops $item->{itemlostloop} = GetAuthorisedValues($authvalcode_items_itemlost, $item->{itemlost}) if $authvalcode_items_itemlost; if ($item->{damaged}) { $item->{itemdamagedloop} = GetAuthorisedValues($authvalcode_items_damaged, $item->{damaged}) if $authvalcode_items_damaged; } - #get shelf location and collection code description if they are authorised value. + # get shelf location and collection code description if they are authorised value + # same thing for copy number my $shelfcode = $item->{'location'}; - $item->{'location'} = $shelflocations->{$shelfcode} if ( defined( $shelfcode ) && defined($shelflocations) && exists( $shelflocations->{$shelfcode} ) ); + $item->{'location'} = $shelflocations->{$shelfcode} if ( defined($shelfcode) && defined($shelflocations) && exists( $shelflocations->{$shelfcode} ) ); my $ccode = $item->{'ccode'}; $item->{'ccode'} = $collections->{$ccode} if ( defined( $ccode ) && defined($collections) && exists( $collections->{$ccode} ) ); + my $copynumber = $item->{'copynumber'}; + $item->{'copynumber'} = $copynumbers->{$copynumber} if ( defined($copynumber) && defined($copynumbers) && exists( $copynumbers->{$copynumber} ) ); foreach (qw(ccode enumchron copynumber itemnotes uri)) { $itemfields{$_} = 1 if ( $item->{$_} ); } @@ -211,20 +215,20 @@ foreach my $item (@items) { my $ItemBorrowerReserveInfo = GetMemberDetails( $reservedfor, 0); if (C4::Context->preference('HidePatronName')){ - $item->{'hidepatronname'} = 1; + $item->{'hidepatronname'} = 1; } if ( defined $reservedate ) { - $item->{backgroundcolor} = 'reserved'; - $item->{reservedate} = format_date($reservedate); - $item->{ReservedForBorrowernumber} = $reservedfor; - $item->{ReservedForSurname} = $ItemBorrowerReserveInfo->{'surname'}; - $item->{ReservedForFirstname} = $ItemBorrowerReserveInfo->{'firstname'}; - $item->{ExpectedAtLibrary} = $branches->{$expectedAt}{branchname}; - $item->{Reservedcardnumber} = $ItemBorrowerReserveInfo->{'cardnumber'}; + $item->{backgroundcolor} = 'reserved'; + $item->{reservedate} = format_date($reservedate); + $item->{ReservedForBorrowernumber} = $reservedfor; + $item->{ReservedForSurname} = $ItemBorrowerReserveInfo->{'surname'}; + $item->{ReservedForFirstname} = $ItemBorrowerReserveInfo->{'firstname'}; + $item->{ExpectedAtLibrary} = $branches->{$expectedAt}{branchname}; + $item->{Reservedcardnumber} = $ItemBorrowerReserveInfo->{'cardnumber'}; } - # Check the transit status + # Check the transit status my ( $transfertwhen, $transfertfrom, $transfertto ) = GetTransfers($item->{itemnumber}); if ( defined( $transfertwhen ) && ( $transfertwhen ne '' ) ) { $item->{transfertwhen} = format_date($transfertwhen); @@ -243,40 +247,41 @@ foreach my $item (@items) { # item has a host number if its biblio number does not match the current bib if ($item->{biblionumber} ne $biblionumber){ $item->{hostbiblionumber} = $item->{biblionumber}; - $item->{hosttitle} = GetBiblioData($item->{biblionumber})->{title}; + $item->{hosttitle} = GetBiblioData($item->{biblionumber})->{title}; } - - #count if item is used in analytical bibliorecords - my $countanalytics= GetAnalyticsCount($item->{itemnumber}); - if ($countanalytics > 0){ - $analytics_flag=1; - $item->{countanalytics} = $countanalytics; - } + #count if item is used in analytical bibliorecords + my $countanalytics= GetAnalyticsCount($item->{itemnumber}); + if ( defined $countanalytics) { + if ($countanalytics > 0){ + $analytics_flag=1; + $item->{countanalytics} = $countanalytics; + } + } push @itemloop, $item; } $template->param( norequests => $norequests ); $template->param( - MARCNOTES => $marcnotesarray, - MARCSUBJCTS => $marcsubjctsarray, - MARCAUTHORS => $marcauthorsarray, - MARCSERIES => $marcseriesarray, - MARCURLS => $marcurlsarray, - MARCISBNS => $marcisbnsarray, - MARCHOSTS => $marchostsarray, - subtitle => $subtitle, - itemdata_ccode => $itemfields{ccode}, - itemdata_enumchron => $itemfields{enumchron}, - itemdata_uri => $itemfields{uri}, - itemdata_copynumber => $itemfields{copynumber}, - volinfo => $itemfields{enumchron}, + MARCNOTES => $marcnotesarray, + MARCSUBJCTS => $marcsubjctsarray, + MARCAUTHORS => $marcauthorsarray, + MARCSERIES => $marcseriesarray, + MARCURLS => $marcurlsarray, + MARCISBNS => $marcisbnsarray, + MARCHOSTS => $marchostsarray, + subtitle => $subtitle, + itemdata_ccode => $itemfields{ccode}, + itemdata_enumchron => $itemfields{enumchron}, + itemdata_uri => $itemfields{uri}, + itemdata_copynumber => $itemfields{copynumber}, + volinfo => $itemfields{enumchron}, itemdata_itemnotes => $itemfields{itemnotes}, - z3950_search_params => C4::Search::z3950_search_args($dat), + z3950_search_params => C4::Search::z3950_search_args($dat), holdcount => $holdcount, - hostrecords => $hostrecords, - analytics_flag => $analytics_flag, - C4::Search::enabled_staff_search_views, + hostrecords => $hostrecords, + analytics_flag => $analytics_flag, + C4::Search::enabled_staff_search_views, ); if (C4::Context->preference("AlternateHoldingsField") && scalar @items == 0) { diff --git a/catalogue/moredetail.pl b/catalogue/moredetail.pl index f5bb904..476fe79 100755 --- a/catalogue/moredetail.pl +++ b/catalogue/moredetail.pl @@ -31,9 +31,9 @@ use C4::Output; use C4::Auth; use C4::Serials; use C4::Dates qw/format_date/; -use C4::Circulation; # to use itemissues -use C4::Members; # to use GetMember -use C4::Search; # enabled_staff_search_views +use C4::Circulation; # to use itemissues +use C4::Members; # to use GetMember +use C4::Search; # enabled_staff_search_views use C4::Members qw/GetHideLostItemsPreference/; my $query=new CGI; @@ -115,8 +115,9 @@ $data->{'count'}=$totalcount; $data->{'showncount'}=$showncount; $data->{'hiddencount'}=$hiddencount; # can be zero -my $ccodes= GetKohaAuthorisedValues('items.ccode',$fw); -my $itemtypes = GetItemTypes; +my $ccodes = GetKohaAuthorisedValues('items.ccode',$fw); +my $copynumbers = GetKohaAuthorisedValues('items.copynumber',$fw); +my $itemtypes = GetItemTypes; $data->{'itemtypename'} = $itemtypes->{$data->{'itemtype'}}->{'description'}; @@ -132,8 +133,15 @@ foreach my $item (@items){ $item->{'itype'} = $itemtypes->{ $item->{'itype'} }->{'description'}; $item->{'replacementprice'} = sprintf( "%.2f", $item->{'replacementprice'} ); $item->{$_} = format_date( $item->{$_} ) foreach qw/datelastborrowed dateaccessioned datelastseen lastreneweddate/; - $item->{'copyvol'} = $item->{'copynumber'}; - + if ( defined $item->{'copynumber'} ) { + $item->{'displaycopy'} = 1; + if ($copynumbers) { + $item->{'copyvol'} = $copynumbers->{ $item->{'copynumber'} } + } + else { + $item->{'copyvol'} = $item->{'copynumber'}; + } + } # item has a host number if its biblio number does not match the current bib if ($item->{biblionumber} ne $biblionumber){ @@ -170,9 +178,9 @@ foreach my $item (@items){ } } $template->param(count => $data->{'count'}, - subscriptionsnumber => $subscriptionsnumber, + subscriptionsnumber => $subscriptionsnumber, subscriptiontitle => $data->{title}, - C4::Search::enabled_staff_search_views, + C4::Search::enabled_staff_search_views, ); $template->param( diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/moredetail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/moredetail.tt index e79e9e8..167cf32 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/moredetail.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/moredetail.tt @@ -56,7 +56,7 @@ [% END %] [% IF ( ITEM_DAT.collection ) %]
    • Collection: [% ITEM_DAT.collection %]
    • [% END %]
    • Item Callnumber: [% ITEM_DAT.itemcallnumber %] 
    • - [% IF ( ITEM_DAT.copyvol ) %]
    • Copy / Vol : [% ITEM_DAT.copyvol %] 
    • [% END %] + [% IF ( ITEM_DAT.displaycopy ) %]
    • Copy / Vol : [% ITEM_DAT.copyvol %] 
    • [% END %] [% IF ( ITEM_DAT.replacementprice ) %]
    • Replacement Price: [% ITEM_DAT.replacementprice %] 
    • [% END %]

      Statuses [% IF ( ITEM_DAT.status_advisory ) %]( diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl index f82dde2..c24f8b8 100755 --- a/opac/opac-detail.pl +++ b/opac/opac-detail.pl @@ -400,12 +400,12 @@ my $hideitems = 1 if C4::Context->preference('hidelostitems') or scalar(@hiddeni # Hide items if ($hideitems) { for my $itm (@all_items) { - if ( C4::Context->preference('hidelostitems') ) { - push @items, $itm unless $itm->{itemlost} or any { $itm->{'itemnumber'} eq $_ } @hiddenitems; - } else { - push @items, $itm unless any { $itm->{'itemnumber'} eq $_ } @hiddenitems; + if ( C4::Context->preference('hidelostitems') ) { + push @items, $itm unless $itm->{itemlost} or any { $itm->{'itemnumber'} eq $_ } @hiddenitems; + } else { + push @items, $itm unless any { $itm->{'itemnumber'} eq $_ } @hiddenitems; + } } -} } else { # Or not @items = @all_items; @@ -420,8 +420,9 @@ if ( $itemtype ) { $dat->{'imageurl'} = getitemtypeimagelocation( 'opac', $itemtypes->{$itemtype}->{'imageurl'} ); $dat->{'description'} = $itemtypes->{$itemtype}->{'description'}; } -my $shelflocations =GetKohaAuthorisedValues('items.location',$dat->{'frameworkcode'}, 'opac'); -my $collections = GetKohaAuthorisedValues('items.ccode',$dat->{'frameworkcode'}, 'opac'); +my $shelflocations = GetKohaAuthorisedValues('items.location',$dat->{'frameworkcode'}, 'opac'); +my $collections = GetKohaAuthorisedValues('items.ccode',$dat->{'frameworkcode'}, 'opac'); +my $copynumbers = GetKohaAuthorisedValues('items.copynumber',$dat->{'frameworkcode'}, 'opac'); #coping with subscriptions my $subscriptionsnumber = CountSubscriptionFromBiblionumber($biblionumber); @@ -444,7 +445,7 @@ foreach my $subscription (@subscriptions) { #get the three latest serials. $serials_to_display = $subscription->{opacdisplaycount}; $serials_to_display = C4::Context->preference('OPACSerialIssueDisplayCount') unless $serials_to_display; - $cell{opacdisplaycount} = $serials_to_display; + $cell{opacdisplaycount} = $serials_to_display; $cell{latestserials} = GetLatestSerials( $subscription->{subscriptionid}, $serials_to_display ); push @subs, \%cell; @@ -467,11 +468,11 @@ my $branches = GetBranches(); my %itemfields; for my $itm (@items) { $norequests = 0 - if ( (not $itm->{'wthdrawn'} ) - && (not $itm->{'itemlost'} ) - && ($itm->{'itemnotforloan'}<0 || not $itm->{'itemnotforloan'} ) - && (not $itemtypes->{$itm->{'itype'}}->{notforloan} ) - && ($itm->{'itemnumber'} ) ); + if ( (not $itm->{'wthdrawn'} ) + && (not $itm->{'itemlost'} ) + && ($itm->{'itemnotforloan'}<0 || not $itm->{'itemnotforloan'} ) + && (not $itemtypes->{$itm->{'itype'}}->{notforloan} ) + && ($itm->{'itemnumber'} ) ); if ( defined $itm->{'publictype'} ) { # I can't actually find any case in which this is defined. --amoore 2008-12-09 @@ -480,10 +481,12 @@ for my $itm (@items) { $itm->{datedue} = format_date($itm->{datedue}); $itm->{datelastseen} = format_date($itm->{datelastseen}); - # get collection code description, too - if ( my $ccode = $itm->{'ccode'} ) { - $itm->{'ccode'} = $collections->{$ccode} if ( defined($collections) && exists( $collections->{$ccode} ) ); - } + # get collection code and copynumber description, too + my $ccode = $itm->{'ccode'}; + $itm->{'ccode'} = $collections->{$ccode} if ( defined($collections) && exists( $collections->{$ccode} ) ); + my $copynumber = $itm->{'copynumber'}; + $itm->{'copynumber'} = $copynumbers->{$copynumber} if ( defined($copynumbers) && defined($copynumber) && exists( $copynumbers->{$copynumber} ) ); + if ( defined $itm->{'location'} ) { $itm->{'location_description'} = $shelflocations->{ $itm->{'location'} }; } @@ -499,52 +502,52 @@ for my $itm (@items) { my $item_authorised_value_images = C4::Items::get_authorised_value_images( C4::Items::get_item_authorised_values( $itm->{'itemnumber'} ) ); # warn( Data::Dumper->Dump( [ $item_authorised_value_images ], [ 'item_authorised_value_images' ] ) ); - if ( $itm->{'itemlost'} ) { - my $lostimageinfo = List::Util::first { $_->{'category'} eq 'LOST' } @$item_authorised_value_images; - $itm->{'lostimageurl'} = $lostimageinfo->{ 'imageurl' }; - $itm->{'lostimagelabel'} = $lostimageinfo->{ 'label' }; - } + if ( $itm->{'itemlost'} ) { + my $lostimageinfo = List::Util::first { $_->{'category'} eq 'LOST' } @$item_authorised_value_images; + $itm->{'lostimageurl'} = $lostimageinfo->{ 'imageurl' }; + $itm->{'lostimagelabel'} = $lostimageinfo->{ 'label' }; + } - if( $itm->{'count_reserves'}){ - if( $itm->{'count_reserves'} eq "Waiting"){ $itm->{'waiting'} = 1; } - if( $itm->{'count_reserves'} eq "Reserved"){ $itm->{'onhold'} = 1; } - } - - my ( $transfertwhen, $transfertfrom, $transfertto ) = GetTransfers($itm->{itemnumber}); - if ( defined( $transfertwhen ) && $transfertwhen ne '' ) { + if( $itm->{'count_reserves'}){ + if( $itm->{'count_reserves'} eq "Waiting"){ $itm->{'waiting'} = 1; } + if( $itm->{'count_reserves'} eq "Reserved"){ $itm->{'onhold'} = 1; } + } + + my ( $transfertwhen, $transfertfrom, $transfertto ) = GetTransfers($itm->{itemnumber}); + if ( defined( $transfertwhen ) && $transfertwhen ne '' ) { $itm->{transfertwhen} = format_date($transfertwhen); $itm->{transfertfrom} = $branches->{$transfertfrom}{branchname}; $itm->{transfertto} = $branches->{$transfertto}{branchname}; - } + } } ## get notes and subjects from MARC record -my $dbh = C4::Context->dbh; -my $marcnotesarray = GetMarcNotes ($record,$marcflavour); -my $marcisbnsarray = GetMarcISBN ($record,$marcflavour); -my $marcauthorsarray = GetMarcAuthors ($record,$marcflavour); -my $marcsubjctsarray = GetMarcSubjects($record,$marcflavour); -my $marcseriesarray = GetMarcSeries ($record,$marcflavour); -my $marcurlsarray = GetMarcUrls ($record,$marcflavour); -my $marchostsarray = GetMarcHosts($record,$marcflavour); -my $subtitle = GetRecordValue('subtitle', $record, GetFrameworkCode($biblionumber)); +my $dbh = C4::Context->dbh; +my $marcnotesarray = GetMarcNotes ($record,$marcflavour); +my $marcisbnsarray = GetMarcISBN ($record,$marcflavour); +my $marcauthorsarray = GetMarcAuthors ($record,$marcflavour); +my $marcsubjctsarray = GetMarcSubjects($record,$marcflavour); +my $marcseriesarray = GetMarcSeries ($record,$marcflavour); +my $marcurlsarray = GetMarcUrls ($record,$marcflavour); +my $marchostsarray = GetMarcHosts($record,$marcflavour); +my $subtitle = GetRecordValue('subtitle', $record, GetFrameworkCode($biblionumber)); $template->param( - MARCNOTES => $marcnotesarray, - MARCSUBJCTS => $marcsubjctsarray, - MARCAUTHORS => $marcauthorsarray, - MARCSERIES => $marcseriesarray, - MARCURLS => $marcurlsarray, - MARCHOSTS => $marchostsarray, - norequests => $norequests, - RequestOnOpac => C4::Context->preference("RequestOnOpac"), - itemdata_ccode => $itemfields{ccode}, - itemdata_enumchron => $itemfields{enumchron}, - itemdata_uri => $itemfields{uri}, - itemdata_copynumber => $itemfields{copynumber}, - itemdata_itemnotes => $itemfields{itemnotes}, - authorised_value_images => $biblio_authorised_value_images, - subtitle => $subtitle, + MARCNOTES => $marcnotesarray, + MARCSUBJCTS => $marcsubjctsarray, + MARCAUTHORS => $marcauthorsarray, + MARCSERIES => $marcseriesarray, + MARCURLS => $marcurlsarray, + MARCHOSTS => $marchostsarray, + norequests => $norequests, + RequestOnOpac => C4::Context->preference("RequestOnOpac"), + itemdata_ccode => $itemfields{ccode}, + itemdata_enumchron => $itemfields{enumchron}, + itemdata_uri => $itemfields{uri}, + itemdata_copynumber => $itemfields{copynumber}, + itemdata_itemnotes => $itemfields{itemnotes}, + authorised_value_images => $biblio_authorised_value_images, + subtitle => $subtitle, ); if (C4::Context->preference("AlternateHoldingsField") && scalar @items == 0) { @@ -590,11 +593,11 @@ if ( $isbn or $ean or $oclc or $upc ) { $content_identifier_exists = 1; } $template->param( - normalized_upc => $upc, - normalized_ean => $ean, - normalized_oclc => $oclc, - normalized_isbn => $isbn, - content_identifier_exists => $content_identifier_exists, + normalized_upc => $upc, + normalized_ean => $ean, + normalized_oclc => $oclc, + normalized_isbn => $isbn, + content_identifier_exists => $content_identifier_exists, ); # COinS format FIXME: for books Only @@ -628,14 +631,14 @@ foreach ( @$reviews ) { $_->{cardnumber} = $borrowerData->{'cardnumber'}; $_->{datereviewed} = format_date($_->{datereviewed}); if ($borrowerData->{'borrowernumber'} eq $borrowernumber) { - $_->{your_comment} = 1; - $loggedincommenter = 1; - } + $_->{your_comment} = 1; + $loggedincommenter = 1; + } } if(C4::Context->preference("ISBD")) { - $template->param(ISBD => 1); + $template->param(ISBD => 1); } $template->param( @@ -676,14 +679,14 @@ foreach my $sc_field (@sc_fields) { $row_data{branch} = $sc_field->subfield('9'); if ($row_data{text} && $row_data{branch}) { - push (@serialcollections, \%row_data); + push (@serialcollections, \%row_data); } } if (scalar(@serialcollections) > 0) { $template->param( - serialcollection => 1, - serialcollections => \@serialcollections); + serialcollection => 1, + serialcollections => \@serialcollections); } # Amazon.com Stuff @@ -734,12 +737,12 @@ my $syndetics_elements; if ( C4::Context->preference("SyndeticsEnabled") ) { $template->param("SyndeticsEnabled" => 1); $template->param("SyndeticsClientCode" => C4::Context->preference("SyndeticsClientCode")); - eval { - $syndetics_elements = &get_syndetics_index($isbn,$upc,$oclc); - for my $element (values %$syndetics_elements) { - $template->param("Syndetics$element"."Exists" => 1 ); - #warn "Exists: "."Syndetics$element"."Exists"; - } + eval { + $syndetics_elements = &get_syndetics_index($isbn,$upc,$oclc); + for my $element (values %$syndetics_elements) { + $template->param("Syndetics$element"."Exists" => 1 ); + #warn "Exists: "."Syndetics$element"."Exists"; + } }; warn $@ if $@; } @@ -747,22 +750,22 @@ if ( C4::Context->preference("SyndeticsEnabled") ) { if ( C4::Context->preference("SyndeticsEnabled") && C4::Context->preference("SyndeticsSummary") && ( exists($syndetics_elements->{'SUMMARY'}) || exists($syndetics_elements->{'AVSUMMARY'}) ) ) { - eval { - my $syndetics_summary = &get_syndetics_summary($isbn,$upc,$oclc, $syndetics_elements); - $template->param( SYNDETICS_SUMMARY => $syndetics_summary ); - }; - warn $@ if $@; + eval { + my $syndetics_summary = &get_syndetics_summary($isbn,$upc,$oclc, $syndetics_elements); + $template->param( SYNDETICS_SUMMARY => $syndetics_summary ); + }; + warn $@ if $@; } if ( C4::Context->preference("SyndeticsEnabled") && C4::Context->preference("SyndeticsTOC") && exists($syndetics_elements->{'TOC'}) ) { - eval { - my $syndetics_toc = &get_syndetics_toc($isbn,$upc,$oclc); - $template->param( SYNDETICS_TOC => $syndetics_toc ); - }; - warn $@ if $@; + eval { + my $syndetics_toc = &get_syndetics_toc($isbn,$upc,$oclc); + $template->param( SYNDETICS_TOC => $syndetics_toc ); + }; + warn $@ if $@; } if ( C4::Context->preference("SyndeticsEnabled") @@ -772,7 +775,7 @@ if ( C4::Context->preference("SyndeticsEnabled") my $syndetics_excerpt = &get_syndetics_excerpt($isbn,$upc,$oclc); $template->param( SYNDETICS_EXCERPT => $syndetics_excerpt ); }; - warn $@ if $@; + warn $@ if $@; } if ( C4::Context->preference("SyndeticsEnabled") @@ -781,12 +784,12 @@ if ( C4::Context->preference("SyndeticsEnabled") my $syndetics_reviews = &get_syndetics_reviews($isbn,$upc,$oclc,$syndetics_elements); $template->param( SYNDETICS_REVIEWS => $syndetics_reviews ); }; - warn $@ if $@; + warn $@ if $@; } if ( C4::Context->preference("SyndeticsEnabled") && C4::Context->preference("SyndeticsAuthorNotes") - && exists($syndetics_elements->{'ANOTES'}) ) { + && exists($syndetics_elements->{'ANOTES'}) ) { eval { my $syndetics_anotes = &get_syndetics_anotes($isbn,$upc,$oclc); $template->param( SYNDETICS_ANOTES => $syndetics_anotes ); @@ -843,34 +846,34 @@ if (C4::Context->preference("OPACShelfBrowser")) { } if (C4::Context->preference("BakerTaylorEnabled")) { - $template->param( - BakerTaylorEnabled => 1, - BakerTaylorImageURL => &image_url(), - BakerTaylorLinkURL => &link_url(), - BakerTaylorBookstoreURL => C4::Context->preference('BakerTaylorBookstoreURL'), - ); - my ($bt_user, $bt_pass); - if ($isbn and - $bt_user = C4::Context->preference('BakerTaylorUsername') and - $bt_pass = C4::Context->preference('BakerTaylorPassword') ) - { - $template->param( - BakerTaylorContentURL => - sprintf("http://contentcafe2.btol.com/ContentCafeClient/ContentCafe.aspx?UserID=%s&Password=%s&ItemKey=%s&Options=Y", - $bt_user,$bt_pass,$isbn) - ); - } + $template->param( + BakerTaylorEnabled => 1, + BakerTaylorImageURL => &image_url(), + BakerTaylorLinkURL => &link_url(), + BakerTaylorBookstoreURL => C4::Context->preference('BakerTaylorBookstoreURL'), + ); + my ($bt_user, $bt_pass); + if ($isbn and + $bt_user = C4::Context->preference('BakerTaylorUsername') and + $bt_pass = C4::Context->preference('BakerTaylorPassword') ) + { + $template->param( + BakerTaylorContentURL => + sprintf("http://contentcafe2.btol.com/ContentCafeClient/ContentCafe.aspx?UserID=%s&Password=%s&ItemKey=%s&Options=Y", + $bt_user,$bt_pass,$isbn) + ); + } } my $tag_quantity; if (C4::Context->preference('TagsEnabled') and $tag_quantity = C4::Context->preference('TagsShowOnDetail')) { - $template->param( - TagsEnabled => 1, - TagsShowOnDetail => $tag_quantity, - TagsInputOnDetail => C4::Context->preference('TagsInputOnDetail') - ); - $template->param(TagLoop => get_tags({biblionumber=>$biblionumber, approved=>1, - 'sort'=>'-weight', limit=>$tag_quantity})); + $template->param( + TagsEnabled => 1, + TagsShowOnDetail => $tag_quantity, + TagsInputOnDetail => C4::Context->preference('TagsInputOnDetail') + ); + $template->param(TagLoop => get_tags({biblionumber=>$biblionumber, approved=>1, + 'sort'=>'-weight', limit=>$tag_quantity})); } if (C4::Context->preference("OPACURLOpenInNewWindow")) { -- 1.7.5.4 From srdjan at catalyst.net.nz Wed Jan 4 00:53:02 2012 From: srdjan at catalyst.net.nz (Srdjan Jankovic) Date: Wed, 4 Jan 2012 12:53:02 +1300 Subject: [Koha-patches] [PATCH] bug_5786: moved AllowOnShelfHolds to circ matrix (issuingrules) In-Reply-To: References: Message-ID: <1325634782-23822-1-git-send-email-srdjan@catalyst.net.nz> --- C4/Circulation.pm | 3 +- C4/Items.pm | 2 + C4/Reserves.pm | 72 ++++++++++++++++--- C4/VirtualShelves/Page.pm | 1 - admin/smart-rules.pl | 9 ++- admin/systempreferences.pl | 1 - .../mysql/it-IT/necessari/system_preferences.sql | 1 - installer/data/mysql/kohastructure.sql | 1 + installer/data/mysql/sysprefs.sql | 1 - installer/data/mysql/updatedatabase.pl | 20 ++++++ installer/html-template-to-template-toolkit.pl | 2 +- .../en/modules/admin/preferences/circulation.pref | 6 -- .../prog/en/modules/admin/preferences/opac.pref | 6 -- .../prog/en/modules/admin/smart-rules.tt | 25 +++++-- .../prog/en/modules/help/reserve/request.tt | 2 +- .../opac-tmpl/prog/en/modules/opac-ISBDdetail.tt | 6 -- .../opac-tmpl/prog/en/modules/opac-MARCdetail.tt | 6 -- koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt | 12 +--- .../prog/en/modules/opac-results-grouped.tt | 6 -- .../opac-tmpl/prog/en/modules/opac-results.tt | 8 +-- .../opac-tmpl/prog/en/modules/opac-shelves.tt | 6 -- opac/opac-ISBDdetail.pl | 2 - opac/opac-MARCdetail.pl | 1 - opac/opac-detail.pl | 2 - opac/opac-reserve.pl | 2 +- opac/opac-search.pl | 2 +- 26 files changed, 115 insertions(+), 90 deletions(-) diff --git a/C4/Circulation.pm b/C4/Circulation.pm index 9a6f4f2..df202e1 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -2200,7 +2200,8 @@ sub CanBookBeRenewed { LEFT JOIN biblioitems USING (biblioitemnumber) WHERE - (issuingrules.categorycode = borrowers.categorycode OR issuingrules.categorycode = '*') + (issuingrules.categorycode = borrowers.categorycode + OR issuingrules.categorycode = '*') AND (issuingrules.itemtype = $itype OR issuingrules.itemtype = '*') AND diff --git a/C4/Items.pm b/C4/Items.pm index 8802a4c..7c3a26f 100644 --- a/C4/Items.pm +++ b/C4/Items.pm @@ -160,6 +160,8 @@ sub GetItem { ($data->{'serialseq'} , $data->{'publisheddate'}) = $ssth->fetchrow_array(); } #if we don't have an items.itype, use biblioitems.itemtype. + # FIXME this should respect the itypes systempreference + # if (C4::Context->preference('item-level_itypes')) { if( ! $data->{'itype'} ) { my $sth = $dbh->prepare("SELECT itemtype FROM biblioitems WHERE biblionumber = ?"); $sth->execute($data->{'biblionumber'}); diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 359bbad..5a2d819 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -479,7 +479,6 @@ sub CanItemBeReserved{ if(my $rowcount = $sthcount->fetchrow_hashref()){ $reservecount = $rowcount->{count}; } - # we check if it's ok or not if( $reservecount < $allowedreserves ){ return 1; @@ -1321,7 +1320,7 @@ sub GetReserveInfo { =head2 IsAvailableForItemLevelRequest - my $is_available = IsAvailableForItemLevelRequest($itemnumber); + my $is_available = IsAvailableForItemLevelRequest($itemnumber,$borrowernumber,$branchcode); Checks whether a given item record is available for an item-level hold request. An item is available if @@ -1331,12 +1330,8 @@ item-level hold request. An item is available if * it is not withdrawn AND * does not have a not for loan value > 0 -Whether or not the item is currently on loan is -also checked - if the AllowOnShelfHolds system preference -is ON, an item can be requested even if it is currently -on loan to somebody else. If the system preference -is OFF, an item that is currently checked out cannot -be the target of an item-level hold request. +Need to check the issuingrules onshelfholds column, +if this is set items on the shelf can be placed on hold Note that IsAvailableForItemLevelRequest() does not check if the staff operator is authorized to place @@ -1348,9 +1343,9 @@ and canreservefromotherbranches. sub IsAvailableForItemLevelRequest { my $itemnumber = shift; - + my $borrowernumber = shift; + my $branchcode = shift; my $item = GetItem($itemnumber); - # must check the notforloan setting of the itemtype # FIXME - a lot of places in the code do this # or something similar - need to be @@ -1383,14 +1378,67 @@ sub IsAvailableForItemLevelRequest { $item->{wthdrawn} or $notforloan_per_itemtype; - - if (C4::Context->preference('AllowOnShelfHolds')) { + # check issuingrules + + if (OnShelfHoldsAllowed($itemnumber,$borrowernumber,$branchcode)) { return $available_per_item; } else { return ($available_per_item and ($item->{onloan} or GetReserveStatus($itemnumber) eq "W")); } } +=head2 OnShelfHoldsAllowed + + OnShelfHoldsAllowed($itemnumber,$borrowernumber,$branchcode); + +Checks issuingrules, using the borrowers categorycode, the itemtype, and branchcode to see if onshelf +holds are allowed, returns true if so. + +=cut + +sub OnShelfHoldsAllowed { + my ($itemnumber,$borrowernumber,$branchcode) = @_; + my $item = GetItem($itemnumber); + my $borrower = C4::Members::GetMember(borrowernumber => $borrowernumber); + my $itype; + my $dbh = C4::Context->dbh; + if (C4::Context->preference('item-level_itypes')) { + # We cant trust GetItem to honour the syspref, so safest to do it ourselves + # When GetItem is fixed, we can remove this + $itype = $item->{itype}; + } + else { + my $query = "SELECT itemtype FROM biblioitems WHERE biblioitemnumber = ? "; + my $sth = $dbh->prepare($query); + $sth->execute($item->{biblioitemnumber}); + if (my $data = $sth->fetchrow_hashref()){ + $itype = $data->{itemtype}; + } + } + + my $query = "SELECT onshelfholds,categorycode,itemtype,branchcode FROM issuingrules WHERE + (issuingrules.categorycode = ? OR issuingrules.categorycode = '*') + AND + (issuingrules.itemtype = ? OR issuingrules.itemtype = '*') + AND + (issuingrules.branchcode = ? OR issuingrules.branchcode = '*') + ORDER BY + issuingrules.categorycode desc, + issuingrules.itemtype desc, + issuingrules.branchcode desc + LIMIT 1"; + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare($query); + $sth->execute($borrower->{categorycode},$itype,$branchcode); + my $data = $sth->fetchrow_hashref; + if ($data->{onshelfholds}){ + return 1; + } + else { + return 0; + } +} + =head2 AlterPriority AlterPriority( $where, $borrowernumber, $biblionumber, $reservedate ); diff --git a/C4/VirtualShelves/Page.pm b/C4/VirtualShelves/Page.pm index 523527e..ff55dc0 100644 --- a/C4/VirtualShelves/Page.pm +++ b/C4/VirtualShelves/Page.pm @@ -183,7 +183,6 @@ sub shelfpage ($$$$$) { # explicitly fetch this shelf my ($shelfnumber2,$shelfname,$owner,$category,$sorton) = GetShelf($shelfnumber); - $template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') ); if (C4::Context->preference('TagsEnabled')) { $template->param(TagsEnabled => 1); foreach (qw(TagsShowOnList TagsInputOnList)) { diff --git a/admin/smart-rules.pl b/admin/smart-rules.pl index f290934..5bfdc7d 100755 --- a/admin/smart-rules.pl +++ b/admin/smart-rules.pl @@ -101,8 +101,8 @@ elsif ($op eq 'delete-branch-item') { # save the values entered elsif ($op eq 'add') { my $sth_search = $dbh->prepare("SELECT COUNT(*) AS total FROM issuingrules WHERE branchcode=? AND categorycode=? AND itemtype=?"); - my $sth_insert = $dbh->prepare("INSERT INTO issuingrules (branchcode, categorycode, itemtype, maxissueqty, renewalsallowed, reservesallowed, issuelength, hardduedate, hardduedatecompare, fine, finedays, firstremind, chargeperiod,rentaldiscount) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); - my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, reservesallowed=?, issuelength=?, hardduedate=?, hardduedatecompare=?, rentaldiscount=? WHERE branchcode=? AND categorycode=? AND itemtype=?"); + my $sth_insert = $dbh->prepare("INSERT INTO issuingrules (branchcode, categorycode, itemtype, maxissueqty, renewalsallowed, reservesallowed, issuelength, hardduedate, hardduedatecompare, fine, finedays, firstremind, chargeperiod, rentaldiscount, onshelfholds) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); + my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, reservesallowed=?, issuelength=?, hardduedate=?, hardduedatecompare=?, rentaldiscount=?, onshelfholds=? WHERE branchcode=? AND categorycode=? AND itemtype=?"); my $br = $branch; # branch my $bor = $input->param('categorycode'); # borrower category @@ -114,6 +114,7 @@ elsif ($op eq 'add') { my $maxissueqty = $input->param('maxissueqty'); my $renewalsallowed = $input->param('renewalsallowed'); my $reservesallowed = $input->param('reservesallowed'); + my $onshelfholds = $input->param('onshelfholds'); $maxissueqty =~ s/\s//g; $maxissueqty = undef if $maxissueqty !~ /^\d+/; my $issuelength = $input->param('issuelength'); @@ -126,9 +127,9 @@ elsif ($op eq 'add') { $sth_search->execute($br,$bor,$cat); my $res = $sth_search->fetchrow_hashref(); if ($res->{total}) { - $sth_update->execute($fine, $finedays,$firstremind, $chargeperiod, $maxissueqty, $renewalsallowed,$reservesallowed, $issuelength,$hardduedate,$hardduedatecompare,$rentaldiscount, $br,$bor,$cat); + $sth_update->execute($fine, $finedays,$firstremind, $chargeperiod, $maxissueqty, $renewalsallowed,$reservesallowed, $issuelength,$hardduedate,$hardduedatecompare,$rentaldiscount, $onshelfholds, $br,$bor,$cat); } else { - $sth_insert->execute($br,$bor,$cat,$maxissueqty,$renewalsallowed,$reservesallowed,$issuelength,$hardduedate,$hardduedatecompare,$fine,$finedays,$firstremind,$chargeperiod,$rentaldiscount); + $sth_insert->execute($br,$bor,$cat,$maxissueqty,$renewalsallowed,$reservesallowed,$issuelength,$hardduedate,$hardduedatecompare,$fine,$finedays,$firstremind,$chargeperiod,$rentaldiscount,$onshelfholds); } } elsif ($op eq "set-branch-defaults") { diff --git a/admin/systempreferences.pl b/admin/systempreferences.pl index 78d0768..6bd68ee 100755 --- a/admin/systempreferences.pl +++ b/admin/systempreferences.pl @@ -186,7 +186,6 @@ $tabsysprefs{HomeOrHoldingBranch} = "Circulation"; $tabsysprefs{HomeOrHoldingBranchReturn} = "Circulation"; $tabsysprefs{RandomizeHoldsQueueWeight} = "Circulation"; $tabsysprefs{StaticHoldsQueueWeight} = "Circulation"; -$tabsysprefs{AllowOnShelfHolds} = "Circulation"; $tabsysprefs{AllowHoldsOnDamagedItems} = "Circulation"; $tabsysprefs{UseBranchTransferLimits} = "Circulation"; $tabsysprefs{AllowHoldPolicyOverride} = "Circulation"; diff --git a/installer/data/mysql/it-IT/necessari/system_preferences.sql b/installer/data/mysql/it-IT/necessari/system_preferences.sql index b4ddfa0..7aaa066 100644 --- a/installer/data/mysql/it-IT/necessari/system_preferences.sql +++ b/installer/data/mysql/it-IT/necessari/system_preferences.sql @@ -17,7 +17,6 @@ -- 51 Franklin Street' WHERE variable = ' Fifth Floor' WHERE variable = ' Boston' WHERE variable = ' MA 02110-1301 USA. UPDATE systempreferences SET value = 'cataloguing' WHERE variable = 'AcqCreateItem'; -UPDATE systempreferences SET value = '1' WHERE variable = 'AllowOnShelfHolds'; UPDATE systempreferences SET value = '1' WHERE variable = 'AllowRenewalLimitOverride'; UPDATE systempreferences SET value = 'annual' WHERE variable = 'autoBarcode'; UPDATE systempreferences SET value = 'email' WHERE variable = 'AutoEmailPrimaryAddress'; diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 5287d9f..d608712 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -988,6 +988,7 @@ CREATE TABLE `issuingrules` ( `renewalsallowed` smallint(6) NOT NULL default "0", `reservesallowed` smallint(6) NOT NULL default "0", `branchcode` varchar(10) NOT NULL default '', + `onshelfholds` tinyint(1) NOT NULL default 0, PRIMARY KEY (`branchcode`,`categorycode`,`itemtype`), KEY `categorycode` (`categorycode`), KEY `itemtype` (`itemtype`) diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 128c9b2..a1a913a 100755 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -223,7 +223,6 @@ INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES ('XSLTDetailsDisplay','0','','Enable XSL stylesheet control over details page display on intranet','YesNo'), ('XSLTResultsDisplay','0','','Enable XSL stylesheet control over results page display on intranet','YesNo'); INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('AdvancedSearchTypes','itemtypes','itemtypes|ccode','Select which set of fields comprise the Type limit in the advanced search','Choice'); -INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('AllowOnShelfHolds', '0', '', 'Allow hold requests to be placed on items that are not on loan', 'YesNo'); INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('AllowHoldsOnDamagedItems', '1', '', 'Allow hold requests to be placed on damaged items', 'YesNo'); INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('OpacSuppression', '0', '', 'Turn ON the OPAC Suppression feature, requires further setup, ask your system administrator for details', 'YesNo'); -- FIXME: add FrameworksLoaded, noOPACUserLogin? diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index 67708fa..84b11d4 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -4585,6 +4585,26 @@ if (C4::Context->preference("Version") < TransformToNum($DBversion)) { SetVersion($DBversion); } +$DBversion = '3.06.03.XXX'; +if (C4::Context->preference("Version") < TransformToNum($DBversion)) { + # First create the column + $dbh->do("ALTER TABLE issuingrules ADD onshelfholds tinyint(1) default 0"); + # Now update the column + if (C4::Context->preference("AllowOnShelfHolds")){ + # Pref is on, set allow for all rules + $dbh->do("UPDATE issuingrules SET onshelfholds=1"); + } else { + # If the preference is not set, leave off + $dbh->do("UPDATE issuingrules SET onshelfholds=0"); + } + $dbh->do("ALTER TABLE issuingrules MODIFY onshelfholds tinyint(1) default 0 NOT NULL"); + # Remove from the systempreferences table + $dbh->do("DELETE FROM systempreferences WHERE variable = 'AllowOnShelfHolds'"); + + print "Upgrade to $DBversion done (Bug 5786 move AllowOnShelfHolds to circulation matrix)\n"; + SetVersion ($DBversion); +} + =head1 FUNCTIONS =head2 DropAllForeignKeys($table) diff --git a/installer/html-template-to-template-toolkit.pl b/installer/html-template-to-template-toolkit.pl index e99b195..5f0e0ac 100755 --- a/installer/html-template-to-template-toolkit.pl +++ b/installer/html-template-to-template-toolkit.pl @@ -32,7 +32,7 @@ my @globals = ("themelang","JacketImages","OPACAmazonCoverImages","GoogleJackets "SyndeticsEnabled", "OpacRenewalAllowed", "item_level_itypes","noItemTypeImages", "virtualshelves", "RequestOnOpac", "COinSinOPACResults", "OPACXSLTResultsDisplay", "OPACItemsResultsDisplay", "LibraryThingForLibrariesID", "opacuserlogin", "TagsEnabled", -"TagsShowOnList", "TagsInputOnList","loggedinusername","AllowOnShelfHolds","opacbookbag", +"TagsShowOnList", "TagsInputOnList","loggedinusername","opacbookbag", "OPACAmazonEnabled", "SyndeticsCoverImages","using_https"); # Arguments: diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref index f4946b5..4cb60ae 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -236,12 +236,6 @@ Circulation: no: "Don't allow" - hold requests to be placed on damaged items. - - - pref: AllowOnShelfHolds - choices: - yes: Allow - no: "Don't allow" - - hold requests to be placed on items that are not checked out. - - - pref: AllowHoldDateInFuture choices: yes: Allow diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref index d6ae2b2..0b076ca 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref @@ -319,12 +319,6 @@ OPAC: # choices: # - If ON, enables subject cloud on OPAC - - - pref: OPACItemHolds - choices: - yes: Allow - no: "Don't allow" - - patrons to place holds on specific items in the OPAC. If this is disabled, users can only put a hold on the next available item. - - - pref: OpacRenewalAllowed choices: yes: Allow diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt index d2f314f..e38e446 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt @@ -80,7 +80,8 @@ for="tobranch">Clone these rules to: Clone these rules to: Delete @@ -175,6 +183,7 @@ for="tobranch">Clone these rules to:

    + diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/help/reserve/request.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/help/reserve/request.tt index 3d7381b..a5a5cd0 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/help/reserve/request.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/help/reserve/request.tt @@ -72,4 +72,4 @@

    See the full documentation for Holds in the manual (online).

    -[% INCLUDE 'help-bottom.inc' %] \ No newline at end of file +[% INCLUDE 'help-bottom.inc' %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-ISBDdetail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-ISBDdetail.tt index f9984a7..d04e7b1 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-ISBDdetail.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-ISBDdetail.tt @@ -51,13 +51,7 @@ [% UNLESS ( norequests ) %] [% IF ( opacuserlogin ) %] [% IF ( RequestOnOpac ) %] - [% IF ( AllowOnShelfHolds ) %]
  • Place Hold
  • - [% ELSE %] - [% IF ( ItemsIssued ) %] -
  • Place Hold
  • - [% END %] - [% END %] [% END %] [% END %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-MARCdetail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-MARCdetail.tt index 284154e..200c0ed 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-MARCdetail.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-MARCdetail.tt @@ -206,13 +206,7 @@ $(document).ready(function(){ [% UNLESS ( norequests ) %] [% IF ( opacuserlogin ) %] [% IF ( RequestOnOpac ) %] - [% IF ( AllowOnShelfHolds ) %]
  • Place Hold
  • - [% ELSE %] - [% IF ( ItemsIssued ) %] -
  • Place Hold
  • - [% END %] - [% END %] [% END %] [% END %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt index d1b6570..fb367ca 100755 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt @@ -1016,16 +1016,10 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
      [% UNLESS ( norequests ) %] - [% IF ( opacuserlogin ) %] + [% IF ( opacuserlogin ) %] [% IF ( RequestOnOpac ) %] - [% IF ( AllowOnShelfHolds ) %] -
    • Place Hold
    • - [% ELSE %] - [% IF ( ItemsIssued ) %] -
    • Place Hold
    • - [% END %] - [% END %] - [% END %] +
    • Place Hold
    • + [% END %] [% END %] [% END %]
    • Print
    • diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results-grouped.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results-grouped.tt index 9e1b855..e08f7f9 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results-grouped.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results-grouped.tt @@ -260,13 +260,7 @@ function highlightOn() { [% IF ( RequestOnOpac ) %] [% UNLESS ( GROUP_RESULT.norequests ) %] [% IF ( opacuserlogin ) %] - [% IF ( AllowOnShelfHolds ) %] Place Hold - [% ELSE %] - [% IF ( GROUP_RESULT.itemsissued ) %] - Place Hold - [% END %] - [% END %] [% END %] [% END %] [% END %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt index 798e0d8..2256b3e 100755 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt @@ -510,13 +510,7 @@ $(document).ready(function(){ [% IF ( RequestOnOpac ) %] [% UNLESS ( SEARCH_RESULT.norequests ) %] [% IF ( opacuserlogin ) %] - [% IF ( AllowOnShelfHolds ) %] - Place Hold - [% ELSE %] - [% IF ( SEARCH_RESULT.itemsissued ) %] - Place Hold - [% END %] - [% END %] + Place Hold [% END %] [% END %] [% END %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-shelves.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-shelves.tt index 391037f..b9e2ed4 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-shelves.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-shelves.tt @@ -308,13 +308,7 @@ $(function() { [% IF ( RequestOnOpac ) %] [% UNLESS ( itemsloo.norequests ) %] [% IF ( opacuserlogin ) %] - [% IF ( AllowOnShelfHolds ) %] Place Hold - [% ELSE %] - [% IF ( itemsloo.itemsissued ) %] - Place Hold - [% END %] - [% END %] [% END %] [% END %] [% END %] diff --git a/opac/opac-ISBDdetail.pl b/opac/opac-ISBDdetail.pl index c80d41c..d978357 100755 --- a/opac/opac-ISBDdetail.pl +++ b/opac/opac-ISBDdetail.pl @@ -69,7 +69,6 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user( my $biblionumber = $query->param('biblionumber'); -$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') ); $template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) ); my $marcflavour = C4::Context->preference("marcflavour"); @@ -152,7 +151,6 @@ foreach ( @$reviews ) { $template->param( RequestOnOpac => C4::Context->preference("RequestOnOpac"), - AllowOnShelfHolds => C4::Context->preference('AllowOnShelfHolds'), norequests => $norequests, ISBD => $res, biblionumber => $biblionumber, diff --git a/opac/opac-MARCdetail.pl b/opac/opac-MARCdetail.pl index ffa0a6d..476fe50 100755 --- a/opac/opac-MARCdetail.pl +++ b/opac/opac-MARCdetail.pl @@ -81,7 +81,6 @@ $template->param( bibliotitle => $biblio->{title}, ); -$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') ); $template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) ); # adding the $RequestOnOpac param diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl index f82dde2..8111e9d 100755 --- a/opac/opac-detail.pl +++ b/opac/opac-detail.pl @@ -347,8 +347,6 @@ if ($session->param('busc')) { } - -$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') ); $template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) ); my $record = GetMarcBiblio($biblionumber); diff --git a/opac/opac-reserve.pl b/opac/opac-reserve.pl index b2144a9..3e573fc 100755 --- a/opac/opac-reserve.pl +++ b/opac/opac-reserve.pl @@ -471,7 +471,7 @@ foreach my $biblioNum (@biblionumbers) { $policy_holdallowed = 0; } - if (IsAvailableForItemLevelRequest($itemNum) and $policy_holdallowed and CanItemBeReserved($borrowernumber,$itemNum) and ($itemLoopIter->{already_reserved} ne 1)) { + if (IsAvailableForItemLevelRequest($itemNum,$borr->{'borrowernumber'},$itemInfo->{'homebranch'}) and $policy_holdallowed and CanItemBeReserved($borrowernumber,$itemNum) and !$itemLoopIter->{already_reserved}) { $itemLoopIter->{available} = 1; $numCopiesAvailable++; } diff --git a/opac/opac-search.pl b/opac/opac-search.pl index aba23a8..081bc81 100755 --- a/opac/opac-search.pl +++ b/opac/opac-search.pl @@ -100,7 +100,7 @@ if (C4::Context->preference("marcflavour") eq "UNIMARC" ) { elsif (C4::Context->preference("marcflavour") eq "MARC21" ) { $template->param('usmarc' => 1); } -$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') ); + $template->param( 'OPACNoResultsFound' => C4::Context->preference('OPACNoResultsFound') ); if (C4::Context->preference('BakerTaylorEnabled')) { -- 1.6.5 From tomascohen at gmail.com Wed Jan 4 17:27:15 2012 From: tomascohen at gmail.com (Tomas Cohen Arazi) Date: Wed, 4 Jan 2012 13:27:15 -0300 Subject: [Koha-patches] [PATCH] Bug 6000 : Performance enhancing Message-ID: <1325694435-26620-1-git-send-email-tomascohen@gmail.com> From: Henri-Damien LAURENT C4::Context.pm Loads all systempreferences at once And uses Memcached to cache them C4::Languages Using List::MoreUtils Memcaching get_langage_description Bug 6000 : Follow up Performance enhancing : C4/Languages.pm removing a call unused to getAllLanguages Doing better job at enabled languages Bug 6000: Rebase against origin/master + 6193 --- C4/Context.pm | 20 ++++++++--- C4/Languages.pm | 96 +++++++++++++++++++----------------------------------- 2 files changed, 49 insertions(+), 67 deletions(-) diff --git a/C4/Context.pm b/C4/Context.pm index d6c2e9a..3cae674 100644 --- a/C4/Context.pm +++ b/C4/Context.pm @@ -92,10 +92,19 @@ BEGIN { }); # Verify memcached available (set a variable and test the output) $ismemcached = $memcached->set('ismemcached','1'); + if ($ismemcached) { + require Memoize::Memcached; + import Memoize::Memcached qw(memoize_memcached); + + memoize_memcached('preference', + memcached => $memcached, + expire_time => 600000); #cache for 10 minutes + } } $VERSION = '3.00.00.036'; -} +}; + use DBI; use ZOOM; @@ -104,6 +113,7 @@ use C4::Boolean; use C4::Debug; use POSIX (); + =head1 NAME C4::Context - Maintain and manipulate the context of a Koha script @@ -533,12 +543,12 @@ sub preference { # Look up systempreferences.variable==$var my $sql = <<'END_SQL'; - SELECT value + SELECT variable, value FROM systempreferences - WHERE variable=? - LIMIT 1 END_SQL - $sysprefs{$var} = $dbh->selectrow_array( $sql, {}, $var ); + my $sysprefs_arrayref; + $sysprefs_arrayref = $dbh->selectcol_arrayref( $sql, { Columns=>[1,2] }); + %sysprefs= @$sysprefs_arrayref; return $sysprefs{$var}; } diff --git a/C4/Languages.pm b/C4/Languages.pm index 0cc288e..944f695 100644 --- a/C4/Languages.pm +++ b/C4/Languages.pm @@ -23,6 +23,7 @@ use strict; #use warnings; FIXME - Bug 2505 use Carp; use C4::Context; +use List::MoreUtils qw/any uniq/; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $DEBUG); eval { @@ -33,6 +34,7 @@ eval { memoize_memcached('getTranslatedLanguages', memcached => C4::Context->memcached, expire_time => 600); #cache for 10 minutes memoize_memcached('getFrameworkLanguages' , memcached => C4::Context->memcached, expire_time => 600); memoize_memcached('getAllLanguages', memcached => C4::Context->memcached, expire_time => 600); + memoize_memcached('language_get_description', memcached => C4::Context->memcached, expire_time => 600000); } }; @@ -79,8 +81,7 @@ Returns a reference to an array of hashes: sub getFrameworkLanguages { # get a hash with all language codes, names, and locale names my $all_languages = getAllLanguages(); - my @languages; - + # find the available directory names my $dir=C4::Context->config('intranetdir')."/installer/data/"; opendir (MYDIR,$dir); @@ -88,17 +89,11 @@ sub getFrameworkLanguages { closedir MYDIR; # pull out all data for the dir names that exist - for my $dirname (@listdir) { - for my $language_set (@$all_languages) { - - if ($dirname eq $language_set->{language_code}) { - push @languages, { - 'language_code'=>$dirname, - 'language_description'=>$language_set->{language_description}, - 'native_descrition'=>$language_set->{language_native_description} } - } - } - } + my @languages=grep { + my $language=$_; + any {$language->{languagecode} eq $_ + } @listdir + } @$all_languages; return \@languages; } @@ -119,49 +114,35 @@ Returns a reference to an array of hashes: sub getTranslatedLanguages { my ($interface, $theme, $current_language, $which) = @_; my $htdocs; - my $all_languages = getAllLanguages(); my @languages; my @enabled_languages; - if ($interface && $interface eq 'opac' ) { - @enabled_languages = split ",", C4::Context->preference('opaclanguages'); - $htdocs = C4::Context->config('opachtdocs'); - if ( $theme and -d "$htdocs/$theme" ) { - (@languages) = _get_language_dirs($htdocs,$theme); - } - else { - for my $theme ( _get_themes('opac') ) { - push @languages, _get_language_dirs($htdocs,$theme); - } - } + my ($preference,$config); + if ($interface && $interface eq 'intranet' ) { + $preference="language"; + $config='intrahtdocs'; } - elsif ($interface && $interface eq 'intranet' ) { - @enabled_languages = split ",", C4::Context->preference('language'); - $htdocs = C4::Context->config('intrahtdocs'); - if ( $theme and -d "$htdocs/$theme" ) { - @languages = _get_language_dirs($htdocs,$theme); - } - else { - foreach my $theme ( _get_themes('intranet') ) { - push @languages, _get_language_dirs($htdocs,$theme); - } - } + else { + $preference="opaclanguages"; + $config='opachtdocs'; + $interface ||='opac'; + + } + + my $languages= C4::Context->preference($preference) ||'en'; + @enabled_languages = split ",", $languages; + $htdocs = C4::Context->config($config); + if ( $theme and -d "$htdocs/$theme" ) { + (@languages) = _get_language_dirs($htdocs,$theme); } else { - @enabled_languages = split ",", C4::Context->preference('opaclanguages'); - my $htdocs = C4::Context->config('intrahtdocs'); - foreach my $theme ( _get_themes('intranet') ) { + for my $theme ( _get_themes($interface) ) { push @languages, _get_language_dirs($htdocs,$theme); } - $htdocs = C4::Context->config('opachtdocs'); - foreach my $theme ( _get_themes('opac') ) { - push @languages, _get_language_dirs($htdocs,$theme); - } - my %seen; - $seen{$_}++ for @languages; - @languages = keys %seen; + @languages=uniq @languages; } - return _build_languages_arrayref($all_languages,\@languages,$current_language,\@enabled_languages); + @enabled_languages=grep{my $enabled_language=$_;any{$_ eq $enabled_language}@languages}@enabled_languages; + return _build_languages_arrayref(\@enabled_languages,$current_language); } =head2 getAllLanguages @@ -178,8 +159,10 @@ Returns a reference to an array of hashes: =cut +my @languages_loop; + sub getAllLanguages { - my @languages_loop; + return \@languages_loop if scalar(@languages_loop); my $dbh=C4::Context->dbh; my $current_language = shift || 'en'; my $sth = $dbh->prepare('SELECT * FROM language_subtag_registry WHERE type=\'language\''); @@ -276,10 +259,9 @@ FIXME: this could be rewritten and simplified using map =cut sub _build_languages_arrayref { - my ($all_languages,$translated_languages,$current_language,$enabled_languages) = @_; + my ($translated_languages,$current_language) = @_; my @translated_languages = @$translated_languages; my @languages_loop; # the final reference to an array of hashrefs - my @enabled_languages = @$enabled_languages; # how many languages are enabled, if one, take note, some contexts won't need to display it my %seen_languages; # the language tags we've seen my %found_languages; @@ -291,15 +273,10 @@ sub _build_languages_arrayref { # separate the language string into its subtag types my $language_subtags_hashref = regex_lang_subtags($translated_language); - # is this language string 'enabled'? - for my $enabled_language (@enabled_languages) { - #warn "Checking out if $translated_language eq $enabled_language"; - $language_subtags_hashref->{'enabled'} = 1 if $translated_language eq $enabled_language; - } - # group this language, key by langtag $language_subtags_hashref->{'sublanguage_current'} = 1 if $translated_language eq $current_language; $language_subtags_hashref->{'rfc4646_subtag'} = $translated_language; + $language_subtags_hashref->{'enabled'} = 1; $language_subtags_hashref->{'native_description'} = language_get_description($language_subtags_hashref->{language},$language_subtags_hashref->{language},'language'); $language_subtags_hashref->{'script_description'} = language_get_description($language_subtags_hashref->{script},$language_subtags_hashref->{'language'},'script'); $language_subtags_hashref->{'region_description'} = language_get_description($language_subtags_hashref->{region},$language_subtags_hashref->{'language'},'region'); @@ -311,11 +288,6 @@ sub _build_languages_arrayref { while( my ($key, $value) = each %$language_groups) { # is this language group enabled? are any of the languages within it enabled? - my $enabled; - for my $enabled_language (@enabled_languages) { - my $regex_enabled_language = regex_lang_subtags($enabled_language); - $enabled = 1 if $key eq $regex_enabled_language->{language}; - } push @languages_loop, { # this is only use if there is one rfc4646_subtag => @$value[0]->{rfc4646_subtag}, @@ -324,7 +296,7 @@ sub _build_languages_arrayref { sublanguages_loop => $value, plural => $track_language_groups->{$key} >1 ? 1 : 0, current => $current_language_regex->{language} eq $key ? 1 : 0, - group_enabled => $enabled, + group_enabled=>1 }; } return \@languages_loop; -- 1.7.5.4 From srdjan at catalyst.net.nz Thu Jan 5 02:05:49 2012 From: srdjan at catalyst.net.nz (Srdjan Jankovic) Date: Thu, 5 Jan 2012 14:05:49 +1300 Subject: [Koha-patches] [PATCH] bug_7001: Issue and Reserve slips are notices. In-Reply-To: References: Message-ID: <1325725549-23904-1-git-send-email-srdjan@catalyst.net.nz> Branches can have their own version of notices - added branchcode to letter table. Support html notices - added is_html to letter table. GetPreparedletter() is the interface for compiling letters (notices). Sysprefs for notice and slips stylesheets. --- C4/Circulation.pm | 20 +- C4/Letters.pm | 583 +++++++++++++------- C4/Members.pm | 81 +++- C4/Message.pm | 12 +- C4/Print.pm | 139 ++---- C4/Reserves.pm | 103 +++-- C4/Suggestions.pm | 22 +- acqui/booksellers.pl | 7 +- circ/circulation.pl | 3 +- circ/hold-transfer-slip.pl | 27 +- .../data/mysql/de-DE/mandatory/sample_notices.sql | 2 +- .../data/mysql/en/mandatory/sample_notices.sql | 84 +++- .../data/mysql/es-ES/mandatory/sample_notices.sql | 2 +- .../mysql/fr-FR/1-Obligatoire/sample_notices.sql | 2 +- installer/data/mysql/it-IT/necessari/notices.sql | 2 +- installer/data/mysql/kohastructure.sql | 7 +- .../mysql/nb-NO/1-Obligatorisk/sample_notices.sql | 2 +- .../data/mysql/pl-PL/mandatory/sample_notices.sql | 2 +- .../data/mysql/ru-RU/mandatory/sample_notices.sql | 2 +- installer/data/mysql/sysprefs.sql | 3 + .../data/mysql/uk-UA/mandatory/sample_notices.sql | 2 +- installer/data/mysql/updatedatabase.pl | 101 ++++- .../prog/en/includes/circ-toolbar.inc | 4 +- .../en/modules/admin/preferences/circulation.pref | 5 + .../en/modules/admin/preferences/staff_client.pref | 5 + .../prog/en/modules/batch/print-notices.tt | 6 +- .../prog/en/modules/circ/hold-transfer-slip.tt | 54 -- .../prog/en/modules/circ/printslip.tt | 28 + .../prog/en/modules/members/moremember-receipt.tt | 76 --- .../intranet-tmpl/prog/en/modules/tools/letter.tt | 113 +++- members/memberentry.pl | 5 +- members/moremember.pl | 10 - members/printslip.pl | 89 +++ misc/cronjobs/advance_notices.pl | 78 ++-- misc/cronjobs/gather_print_notices.pl | 14 +- misc/cronjobs/overdue_notices.pl | 86 ++-- t/db_dependent/lib/KohaTest/Letters.pm | 5 +- t/db_dependent/lib/KohaTest/Letters/GetLetter.pm | 3 +- t/db_dependent/lib/KohaTest/Members.pm | 1 + t/db_dependent/lib/KohaTest/Print.pm | 5 +- t/db_dependent/lib/KohaTest/Reserves.pm | 1 + tools/letter.pl | 214 +++++--- 42 files changed, 1266 insertions(+), 744 deletions(-) delete mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/circ/hold-transfer-slip.tt create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt delete mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt create mode 100755 members/printslip.pl diff --git a/C4/Circulation.pm b/C4/Circulation.pm index 9a6f4f2..cff3fa7 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -2655,11 +2655,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) { @@ -2674,7 +2681,8 @@ sub SendCirculationAlert { $message->update; } } - $letter; + + return $letter; } =head2 updateWrongTransfer diff --git a/C4/Letters.pm b/C4/Letters.pm index 2420e4a..7f195d6 100644 --- a/C4/Letters.pm +++ b/C4/Letters.pm @@ -26,6 +26,7 @@ use Encode; use Carp; use C4::Members; +use C4::Members::Attributes qw(GetBorrowerAttributes); use C4::Branch; use C4::Log; use C4::SMS; @@ -42,7 +43,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 ); } @@ -117,13 +118,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) @@ -178,7 +192,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 "; @@ -234,70 +248,65 @@ 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; 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/<>/$userenv->{firstname}/g; - $letter->{content} =~ s/<>/$userenv->{surname}/g; - $letter->{content} =~ - s/<>/$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; # warn "sending to $mail{To} From $mail{From} subj $mail{Subject} Mess $mail{Message}"; - } } } elsif ( $type eq 'claimacquisition' ) { # warn "sending issues..."; - my $letter = getletter( 'claimacquisition', $letter ); # prepare the letter... # search the biblionumber @@ -307,52 +316,43 @@ sub SendAlerts { my $sthorders = $dbh->prepare($strsth); $sthorders->execute; my $dataorders = $sthorders->fetchall_arrayref( {} ); - parseletter( $letter, 'aqbooksellers', - $dataorders->[0]->{booksellerid} ); + my $sthbookseller = $dbh->prepare("select * from aqbooksellers where id=?"); $sthbookseller->execute( $dataorders->[0]->{booksellerid} ); my $databookseller = $sthbookseller->fetchrow_hashref; - # parsing branch info - my $userenv = C4::Context->userenv; - parseletter( $letter, 'branches', $userenv->{branch} ); - - # parsing librarian name - $letter->{content} =~ s/<>/$userenv->{firstname}/g; - $letter->{content} =~ s/<>/$userenv->{surname}/g; - $letter->{content} =~ - s/<>/$userenv->{emailaddress}/g; - foreach my $data ( @{$dataorders} ) { - if ( $letter->{content} =~ m/(<<.*>>)/ ) { - my $line = $1; - foreach my $field ( keys %{$data} ) { - $line =~ s/(<<[^\.]+.$field>>)/$data->{$field}/; - } - $letter->{content} =~ s/(<<.*>>)/$line\n$1/; - } + 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; } - $letter->{content} =~ s/<<[^>]*>>//g; - my $innerletter = $letter; + + my $userenv = C4::Context->userenv; + my $letter = GetPreparedLetter ( + module => 'claimacquisition', + letter_code => $letter_code, + branchcode => $userenv->{branch}, + tables => { + 'branches' => $userenv->{branch}, + 'aqbooksellers' => $databookseller, + }, + repeat => $dataorders, + want_librarian => 1, + ) or return; # ... then send mail - if ( $databookseller->{bookselleremail} - || $databookseller->{contemail} ) - { - my %mail = ( - To => $databookseller->{bookselleremail} - . ( - $databookseller->{contemail} - ? "," . $databookseller->{contemail} - : "" - ), - From => $userenv->{emailaddress}, - Subject => "" . $innerletter->{title}, - Message => "" . $innerletter->{content}, - 'Content-Type' => 'text/plain; charset="utf8"', - ); - sendmail(%mail) or carp $Mail::Sendmail::error; - } + 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; + if ( C4::Context->preference("LetterLog") ) { logaction( "ACQUISITION", @@ -360,16 +360,13 @@ sub SendAlerts { "", "order list : " . join( ",", @$externalid ) - . "\n$innerletter->{title}\n$innerletter->{content}" + . "\n$letter->{title}\n$letter->{content}" ); } } elsif ( $type eq 'claimissues' ) { # warn "sending issues..."; - my $letter = getletter( 'claimissues', $letter ); - - # prepare the letter... # search the biblionumber my $strsth = "select serial.*,subscription.*, biblio.* from serial LEFT JOIN subscription on serial.subscriptionid=subscription.subscriptionid LEFT JOIN biblio on serial.biblionumber=biblio.biblionumber where serial.serialid IN (" @@ -377,81 +374,76 @@ sub SendAlerts { my $sthorders = $dbh->prepare($strsth); $sthorders->execute; my $dataorders = $sthorders->fetchall_arrayref( {} ); - parseletter( $letter, 'aqbooksellers', - $dataorders->[0]->{aqbooksellerid} ); + my $sthbookseller = $dbh->prepare("select * from aqbooksellers where id=?"); $sthbookseller->execute( $dataorders->[0]->{aqbooksellerid} ); my $databookseller = $sthbookseller->fetchrow_hashref; - # parsing branch info - my $userenv = C4::Context->userenv; - parseletter( $letter, 'branches', $userenv->{branch} ); - - # parsing librarian name - $letter->{content} =~ s/<>/$userenv->{firstname}/g; - $letter->{content} =~ s/<>/$userenv->{surname}/g; - $letter->{content} =~ - s/<>/$userenv->{emailaddress}/g; - foreach my $data ( @{$dataorders} ) { - if ( $letter->{content} =~ m/(<<.*>>)/ ) { - my $line = $1; - foreach my $field ( keys %{$data} ) { - $line =~ s/(<<[^\.]+.$field>>)/$data->{$field}/; - } - $letter->{content} =~ s/(<<.*>>)/$line\n$1/; - } + 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; } - $letter->{content} =~ s/<<[^>]*>>//g; - my $innerletter = $letter; + + # prepare the letter... + my $userenv = C4::Context->userenv; + my $letter = GetPreparedLetter ( + module => 'claimissues', + letter_code => $letter_code, + branchcode => $userenv->{branch}, + tables => { + 'branches' => $userenv->{branch}, + 'aqbooksellers' => $databookseller, + }, + repeat => $dataorders, + want_librarian => 1, + ) or return; # ... then send mail - if ( $databookseller->{bookselleremail} - || $databookseller->{contemail} ) { - my $mail_to = $databookseller->{bookselleremail}; - if ($databookseller->{contemail}) { - if (!$mail_to) { - $mail_to = $databookseller->{contemail}; - } else { - $mail_to .= q|,|; - $mail_to .= $databookseller->{contemail}; - } - } - my $mail_subj = $innerletter->{title}; - my $mail_msg = $innerletter->{content}; - $mail_msg ||= q{}; - $mail_subj ||= q{}; + my $mail_subj = $letter->{title}; + my $mail_msg = $letter->{content}; + $mail_msg ||= q{}; + $mail_subj ||= q{}; - my %mail = ( - To => $mail_to, - From => $userenv->{emailaddress}, - Subject => $mail_subj, - Message => $mail_msg, - 'Content-Type' => 'text/plain; charset="utf8"', - ); - sendmail(%mail) or carp $Mail::Sendmail::error; - logaction( - "ACQUISITION", - "CLAIM ISSUE", - undef, - "To=" - . $databookseller->{contemail} - . " Title=" - . $innerletter->{title} - . " Content=" - . $innerletter->{content} - ) if C4::Context->preference("LetterLog"); - } + my %mail = ( + To => join( ','. @email), + From => $userenv->{emailaddress}, + Subject => $mail_subj, + Message => $mail_msg, + 'Content-Type' => 'text/plain; charset="utf8"', + ); + sendmail(%mail) or carp $Mail::Sendmail::error; + + logaction( + "ACQUISITION", + "CLAIM ISSUE", + 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 elsif ( $type eq 'members' ) { - # must parse the password special, before it's hashed. - $letter->{content} =~ s/<>/$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"), @@ -463,24 +455,148 @@ sub SendAlerts { } } -=head2 parseletter($letter, $table, $pk) - - 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) +=head2 GetPreparedLetter( %params ) + + %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 << >> << >> + 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 = @_; + + 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/<>/$userenv->{firstname}/go; + $letter->{content} =~ s/<>/$userenv->{surname}/go; + $letter->{content} =~ s/<>/$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>(.*)!s ) { + my $subcontent = $1; + my @lines = map { + my %subletter = ( title => '', content => $subcontent ); + _substitute_tables( \%subletter, $_ ); + $subletter{content}; + } @$tag_tables; + $letter->{content} =~ s!<$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/<>/$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; -sub parseletter_sth { + 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 @@ -494,9 +610,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)) { @@ -506,25 +625,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) - my $values = $sth->fetchrow_hashref; - + 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 ) = @_; + # TEMPORARY hack until the expirationdate column is added to reserves if ( $table eq 'reserves' && $values->{'waitingdate'} ) { my @waitingdate = split /-/, $values->{'waitingdate'}; @@ -538,16 +653,51 @@ sub parseletter { )->output(); } + if ($letter->{content} && $letter->{content} =~ /<>/) { + my @da = localtime(); + my $todaysdate = "$da[2]:$da[1] " . C4::Dates->today(); + $letter->{content} =~ s/<>/$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 = "<>"; + my $replacedby = join ',', @$val_ar; + $letter->{content} =~ s/$replacefield/$replacedby/g; + } + } } return $letter; } @@ -732,31 +882,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; } @@ -823,14 +974,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') ) { @@ -850,6 +1004,27 @@ sub _send_message_by_email ($;$$$) { } } +sub _wrap_html { + my ($content, $title) = @_; + + my $css = C4::Context->preference("NoticeCSS") || ''; + $css = qq{} if $css; + return < + + +$title + +$css + + +$content + + +EOS +} + sub _send_message_by_sms ($) { my $message = shift or return undef; my $member = C4::Members::GetMember( 'borrowernumber' => $message->{'borrowernumber'} ); diff --git a/C4/Members.pm b/C4/Members.pm index 1d7bc42..9f42cea 100644 --- a/C4/Members.pm +++ b/C4/Members.pm @@ -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, at ISA, at EXPORT, at EXPORT_OK,$debug); @@ -91,6 +93,8 @@ BEGIN { &DeleteMessage &GetMessages &GetMessagesCount + + &IssueSlip ); #Modify data @@ -2227,7 +2231,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; diff --git a/C4/Message.pm b/C4/Message.pm index 16272ff..4b88970 100644 --- a/C4/Message.pm +++ b/C4/Message.pm @@ -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: diff --git a/C4/Print.pm b/C4/Print.pm index 2ba7584..2343fa4 100644 --- a/C4/Print.pm +++ b/C4/Print.pm @@ -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'} + +COLLECT AT: $branchname -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. +BORROWER: +$bordata->{'surname'}, $bordata->{'firstname'} +card number: $bordata->{'cardnumber'} +Phone: $bordata->{'phone'} +$bordata->{'streetaddress'} +$bordata->{'suburb'} +$bordata->{'town'} +$bordata->{'emailaddress'} -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>. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +EOF =cut +=head2 printslip + + &printslip($slip) + +print a slip for the given $borrowernumber and $branchcode + +=cut + +sub printslip ($) { + my ($slip) = @_; + + return unless ( C4::Context->boolean_preference('printcirculationslips') ); + # FIXME - It'd be nifty if this could generate pretty PostScript. -sub remoteprint ($$) { - my ($items, $borrower) = @_; - (return) - unless ( C4::Context->boolean_preference('printcirculationslips') ); my $queue = ''; # FIXME - If 'queue' is undefined or empty, then presumably it should @@ -93,100 +111,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 { - 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 ($) { - 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__ diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 359bbad..d2af1c5 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -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 %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 $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 $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/g; - $letter->{'content'} =~ s/<>/$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 diff --git a/C4/Suggestions.pm b/C4/Suggestions.pm index ccc0c8e..6c10fdf 100644 --- a/C4/Suggestions.pm +++ b/C4/Suggestions.pm @@ -371,20 +371,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; diff --git a/acqui/booksellers.pl b/acqui/booksellers.pl index 634eb93..745d040 100755 --- a/acqui/booksellers.pl +++ b/acqui/booksellers.pl @@ -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 ) ) diff --git a/circ/circulation.pl b/circ/circulation.pl index c95e59b..f5d6cb6 100755 --- a/circ/circulation.pl +++ b/circ/circulation.pl @@ -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($branch, $borrowernumber); $query->param( 'borrowernumber', '' ); $borrowernumber = ''; } diff --git a/circ/hold-transfer-slip.pl b/circ/hold-transfer-slip.pl index f581464..492dac7 100755 --- a/circ/hold-transfer-slip.pl +++ b/circ/hold-transfer-slip.pl @@ -25,8 +25,6 @@ use C4::Output; use CGI; use C4::Auth; use C4::Reserves; -use C4::Branch; -use C4::Dates qw/format_date format_date_in_iso/; use vars qw($debug); @@ -41,7 +39,7 @@ 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 +48,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 ($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; diff --git a/installer/data/mysql/de-DE/mandatory/sample_notices.sql b/installer/data/mysql/de-DE/mandatory/sample_notices.sql index 166c36d..efdad91 100644 --- a/installer/data/mysql/de-DE/mandatory/sample_notices.sql +++ b/installer/data/mysql/de-DE/mandatory/sample_notices.sql @@ -11,7 +11,7 @@ VALUES ('circulation','ODUE','Mahnung','Mahnung','Liebe/r < ('reserves', 'HOLD_PRINT', 'Vormerkbenachrichtigung (Print)', 'Vormerkbenachrichtigung (Print)', '<>\r\n<>\r\n<>\r\n<>\r\n<> <>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<> <>\r\n<>\r\n<>\r\n<> <>\r\n<>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nLiebe(r) <> <>,\r\n\r\nF??r Sie liegt seit dem <> eine Vormerkung zur Abholung bereit:\r\n\r\nTitel: <>\r\nVerfasser: <>\r\nSignatur: <>\r\n'), ('circulation','CHECKIN','R??ckgabequittung (Zusammenfassung)','R??ckgabequittung','Die folgenden Medien wurden zur??ckgegeben:\r\n----\r\n<>\r\n----\r\nVielen Dank.'), ('circulation','CHECKOUT','Ausleihquittung (Zusammenfassung)','Ausleihquittung','Die folgenden Medien wurden entliehen:\r\n----\r\n<>\r\n----\r\nVielen Dank f??r Ihren Besuch in <>.'), -('reserves', 'HOLDPLACED', 'Neue Vormerkung', 'Neue Vormerkung','Folgender Titel wurde vorgemerkt: <> (<<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>>'), diff --git a/installer/data/mysql/en/mandatory/sample_notices.sql b/installer/data/mysql/en/mandatory/sample_notices.sql index 689fa0f..8c9f4bd 100644 --- a/installer/data/mysql/en/mandatory/sample_notices.sql +++ b/installer/data/mysql/en/mandatory/sample_notices.sql @@ -11,8 +11,90 @@ 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> + +<reserves> +<div> +<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> +</div> +</reserves>', 1); + diff --git a/installer/data/mysql/es-ES/mandatory/sample_notices.sql b/installer/data/mysql/es-ES/mandatory/sample_notices.sql index 689fa0f..bf3324d 100644 --- a/installer/data/mysql/es-ES/mandatory/sample_notices.sql +++ b/installer/data/mysql/es-ES/mandatory/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql b/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql index 977e59d..acffe73 100644 --- a/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql +++ b/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/it-IT/necessari/notices.sql b/installer/data/mysql/it-IT/necessari/notices.sql index 689fa0f..bf3324d 100644 --- a/installer/data/mysql/it-IT/necessari/notices.sql +++ b/installer/data/mysql/it-IT/necessari/notices.sql @@ -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>>'), diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 5287d9f..124c897 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -1168,10 +1168,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; -- @@ -2252,12 +2254,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; -- diff --git a/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql b/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql index cdb5529..08b452e 100644 --- a/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql +++ b/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/pl-PL/mandatory/sample_notices.sql b/installer/data/mysql/pl-PL/mandatory/sample_notices.sql index 6be2eb8..f0844f3 100644 --- a/installer/data/mysql/pl-PL/mandatory/sample_notices.sql +++ b/installer/data/mysql/pl-PL/mandatory/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/ru-RU/mandatory/sample_notices.sql b/installer/data/mysql/ru-RU/mandatory/sample_notices.sql index 689fa0f..bf3324d 100644 --- a/installer/data/mysql/ru-RU/mandatory/sample_notices.sql +++ b/installer/data/mysql/ru-RU/mandatory/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 128c9b2..e9aac60 100755 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -328,4 +328,7 @@ INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES(' INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('OpacKohaUrl','1',"Show 'Powered by Koha' text on OPAC footer.",NULL,NULL); 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('NoticeCSS','','Notices CSS url.',NULL,'free'); +INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('SlipCSS','','Slips CSS url.',NULL,'free'); + diff --git a/installer/data/mysql/uk-UA/mandatory/sample_notices.sql b/installer/data/mysql/uk-UA/mandatory/sample_notices.sql index 358205b..b637343 100644 --- a/installer/data/mysql/uk-UA/mandatory/sample_notices.sql +++ b/installer/data/mysql/uk-UA/mandatory/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index 67708fa..3913e79 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -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"; @@ -4585,6 +4584,106 @@ if (C4::Context->preference("Version") < TransformToNum($DBversion)) { SetVersion($DBversion); } +$DBversion = "3.06.03.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`"); + print "Added branchcode and is_html to letter table\n"; + + $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 `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; Add NoticeCSS and SlipCSS sysprefs)\n"; + SetVersion($DBversion); +} + =head1 FUNCTIONS =head2 DropAllForeignKeys($table) diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-toolbar.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/circ-toolbar.inc index 913076f..6fdd720 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-toolbar.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/circ-toolbar.inc @@ -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 %]&print=" + print_type, "printwindow"); + var handler = print_type.match(slip_re) ? "printslip" : "moremember"; + window.open("/cgi-bin/koha/members/" + handler + ".pl?borrowernumber=[% borrowernumber %]&print=" + print_type, "printwindow"); return false; } function searchToHold(){ diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref index f4946b5..b3b279c 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -91,6 +91,11 @@ Circulation: yes: Record no: "Don't record" - local use when an unissued item is checked in. + - + - 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 diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/staff_client.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/staff_client.pref index df0a434..efa33a8 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/staff_client.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/staff_client.pref @@ -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 diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/batch/print-notices.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/batch/print-notices.tt index 1904381..73f9e61 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/batch/print-notices.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/batch/print-notices.tt @@ -8,11 +8,7 @@ --> </style> [% IF ( stylesheet ) %] - <style type="text/css"> - <!-- - [% stylesheet %] - --> - </style> + <link rel="stylesheet" type="text/css" href="[% stylesheet %]"> [% END %] </head> <body> diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/hold-transfer-slip.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/hold-transfer-slip.tt deleted file mode 100644 index 18d45aa..0000000 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/hold-transfer-slip.tt +++ /dev/null @@ -1,54 +0,0 @@ -[% INCLUDE 'doc-head-open.inc' %] -<title>Koha -- Circulation: Transfers -[% INCLUDE 'doc-head-close-receipt.inc' %] - - -
      - -[% FOREACH reservedat IN reservedata %] - -
      Date: [% reservedat.pulldate %]
      -

      [% IF ( reservedat.transferrequired ) %]Transfer to [% reservedat.branchname %] [% ELSE %]Hold in [% reservedat.branchname %][% END %]

      - -
      - -

      [% reservedat.surname %], [% reservedat.firstname %]

      - -
        -
      • [% reservedat.cardnumber %]
      • - [% IF ( reservedat.phone ) %] -
      • [% reservedat.phone %]
      • - [% END %] -
      • - [% reservedat.address %]
        - [% IF ( reservedat.address2 ) %][% reservedat.address2 %]
        [% END %] - [% reservedat.city %] [% reservedat.zip %] -
      • - [% IF ( reservedat.email ) %] -
      • [% reservedat.email %]
      • - [% END %] -
      -
      -

      ITEM ON HOLD

      -

      [% reservedat.title |html %]

      -
      [% reservedat.author %]
      -
        - [% IF ( reservedat.barcode ) %]
      • [% reservedat.barcode %]
      • [% END %] - [% IF ( reservedat.itemcallnumber ) %]
      • [% reservedat.itemcallnumber %]
      • [% END %] - [% IF ( reservedat.waitingdate ) %]
      • [% reservedat.waitingdate %]
      • [% END %] -
      - [% IF ( reservedat.reservenotes ) %] -

      Notes: [% reservedat.reservenotes %]

      - [% END %] - - - -[% END %] -
      -[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt new file mode 100644 index 0000000..a790069 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt @@ -0,0 +1,28 @@ +[% INCLUDE 'doc-head-open.inc' %] +[% title %] + + + +[% IF stylesheet %] + +[% END %] + + + + +
      + +[% IF plain %] +
      +[% slip %]
      +
      +[% ELSE %] +[% slip %] +[% END %] + +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt deleted file mode 100644 index 4a85ccb..0000000 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt +++ /dev/null @@ -1,76 +0,0 @@ -[% INCLUDE 'doc-head-open.inc' %] -Print Receipt for [% cardnumber %] - - - - - - - - -
      - -

      [% LibraryName %]

      -[% IF ( branchname ) %][% branchname %]
      [% END %] -Checked out to [% firstname %] [% surname %]
      -([% cardnumber %])
      - -[% todaysdate %]
      - -[% IF ( quickslip ) %] -

      Checked Out Today

      -[% FOREACH issueloo IN issueloop %] -[% IF ( issueloo.red ) %][% ELSE %] -[% IF ( issueloo.today ) %] -

      [% issueloo.title |html %]
      -Barcode: [% issueloo.barcode %]
      -Date due: [% issueloo.date_due %]

      - [% END %] - [% END %] - [% END %] - -[% ELSE %] -

      Checked Out

      -[% FOREACH issueloo IN issueloop %] -[% IF ( issueloo.red ) %][% ELSE %] -

      [% issueloo.title |html %]
      -Barcode: [% issueloo.barcode %]
      -Date due: [% issueloo.date_due %]

      - [% END %] - [% END %] - -[% END %] - -[% IF ( quickslip ) %] -[% ELSE %] -[% IF ( overdues_exist ) %] -

      Overdues

      - [% FOREACH issueloo IN issueloop %] - [% IF ( issueloo.red ) %] -

      [% issueloo.title |html %]
      -Barcode: [% issueloo.barcode %]
      -Date due: [% issueloo.date_due %]

      -[% END %] -[% END %] -[% END %] -[% END %] - -[% IF ( koha_news_count ) %] -

      News

      - - [% FOREACH koha_new IN koha_news %] -
      [% koha_new.title %]
      -

      [% koha_new.new %]

      -

      Posted on [% koha_new.newdate %] - -


      - [% END %] -[% END %] - - -[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt index 063236e..b64477e 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt @@ -10,6 +10,10 @@ $(document).ready(function() { sortList: [[0,0]], headers: { 3: {sorter:false},4: { sorter: false }} }); + + $('#branch').change(function() { + $('#selectlibrary').submit(); + }); }); [% IF ( add_form ) %] @@ -114,7 +118,7 @@ $(document).ready(function() {
      - [% IF ( no_op_set ) %] +[% IF ( no_op_set ) %]
      + + [% UNLESS independant_branch %] +

      +
      + + Select a library : + + +

      + [% END %] +
      @@ -135,41 +155,71 @@ $(document).ready(function() { [% IF ( search ) %]

      You Searched for [% searchfield %]

      [% END %] - [% IF ( letter ) %]
    Order Date VendorClaimed date Check all
    Uncheck all
    [% lateorder.claimed_date %] [% UNLESS lateorder.budget_lock %] - + [% END %] Yes No
    Yes No
    + [% IF ( letter && !independant_branch) %] + [% select_for_copy = BLOCK %] + + [% END %] + [% END %] +
    + + - [% FOREACH lette IN letter %] - [% UNLESS ( loop.odd ) %] + + [% FOREACH lette IN letter %] + [% can_edit = lette.branchcode || !independant_branch %] + [% UNLESS ( loop.odd ) %] - [% ELSE %] + [% ELSE %] - [% END %] + [% END %] + + - [% END %] + [% END %] +
    Branch Module Code Name     
    [% lette.branchname || "(All libraries)" %] [% lette.module %] [% lette.code %] [% lette.name %] - Edit + [% IF can_edit %] + Edit + [% END %] - [% IF ( lette.protected ) %] - - - [% ELSE %] - Delete - [% END %] + [% IF !independant_branch || !lette.branchcode %] +
    + + + + + [% IF independant_branch %] + + [% ELSE %] + [% select_for_copy %] + [% END %] + +
    + [% END %] +
    + [% IF !lette.protected && can_edit %] + Delete + [% END %]
    - [% END %] +[% END %] - [% END %] - [% IF ( add_form ) %] +[% IF ( add_form ) %]
    @@ -182,6 +232,20 @@ $(document).ready(function() {
    [% IF ( modify ) %]Modify notice[% ELSE %]Add notice[% END %]
      + + [% IF independant_branch %] + + [% ELSE %] +
    1. + + +
    2. + [% END %]
    3. @@ -235,6 +299,9 @@ $(document).ready(function() {
    4. + +
    5. +
    6. @@ -253,16 +320,16 @@ $(document).ready(function() {
    - [% END %] +[% END %] - [% IF ( add_validate ) %] +[% IF ( add_validate ) %] Data recorded
    - [% END %] +[% END %] - [% IF ( delete_confirm ) %] +[% IF ( delete_confirm ) %]

    Delete Notice?

    @@ -290,14 +357,14 @@ $(document).ready(function() { - [% END %] +[% END %] - [% IF ( delete_confirmed ) %] +[% IF ( delete_confirmed ) %] Data deleted - [% END %] +[% END %] diff --git a/members/memberentry.pl b/members/memberentry.pl index c047873..f345351 100755 --- a/members/memberentry.pl +++ b/members/memberentry.pl @@ -338,10 +338,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" ); } } diff --git a/members/moremember.pl b/members/moremember.pl index 6e5407c..9277deb 100755 --- a/members/moremember.pl +++ b/members/moremember.pl @@ -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); @@ -483,13 +482,4 @@ $template->param( quickslip => $quickslip, ); -#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; diff --git a/members/printslip.pl b/members/printslip.pl new file mode 100755 index 0000000..eba8d68 --- /dev/null +++ b/members/printslip.pl @@ -0,0 +1,89 @@ +#!/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 at katipo.co.nz + last modified 21/1/2000 by chris at katipo.co.nz + modified 31/1/2001 by chris at 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; +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; +$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 ($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; diff --git a/misc/cronjobs/advance_notices.pl b/misc/cronjobs/advance_notices.pl index 1fa358f..09c4017 100755 --- a/misc/cronjobs/advance_notices.pl +++ b/misc/cronjobs/advance_notices.pl @@ -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 EEitems.contentEE 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", at 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", at 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", at 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", at 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; - } - } - - C4::Letters::parseletter( $params->{'letter'}, 'borrowers', $params->{'borrowernumber'} ); + my %table_params = ( 'borrowers' => $params->{'borrowernumber'} ); - if ( $params->{'branchcode'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'branches', $params->{'branchcode'} ); + if ( my $p = $params->{'branchcode'} ) { + $table_params{'branches'} = $p; } - if ( $params->{'itemnumber'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'issues', $params->{'itemnumber'} ); - C4::Letters::parseletter( $params->{'letter'}, 'items', $params->{'itemnumber'} ); + if ( my $p = $params->{'itemnumber'} ) { + $table_params{'issues'} = $p; + $table_params{'items'} = $p; } - if ( $params->{'biblionumber'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'biblio', $params->{'biblionumber'} ); - C4::Letters::parseletter( $params->{'letter'}, 'biblioitems', $params->{'biblionumber'} ); + if ( my $p = $params->{'biblionumber'} ) { + $table_params{'biblio'} = $p; + $table_params{'biblioitems'} = $p; } - 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; diff --git a/misc/cronjobs/gather_print_notices.pl b/misc/cronjobs/gather_print_notices.pl index a72d6a6..165b16e 100755 --- a/misc/cronjobs/gather_print_notices.pl +++ b/misc/cronjobs/gather_print_notices.pl @@ -39,11 +39,9 @@ use Getopt::Long; sub usage { print STDERR < \$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_contents .= $_ } - close STYLESHEET; -} $template->param( - stylesheet => $stylesheet_contents, + stylesheet => C4::Context->preference("NoticeCSS"), today => $today->output(), messages => \@messages, ); diff --git a/misc/cronjobs/overdue_notices.pl b/misc/cronjobs/overdue_notices.pl index 71e6a05..93061b4 100755 --- a/misc/cronjobs/overdue_notices.pl +++ b/misc/cronjobs/overdue_notices.pl @@ -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/<>/$todaysdate/g; - $params->{'letter'}->{content} =~ s/<>/$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>/o) { # process any fine tags... + $currency_format = $1; + $params->{'letter'}->{'content'} =~ s/.*<\/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_format = $1; } - if ($params->{'letter'}->{'content'} =~ m/(.*)<\/fine>/) { # process any fine tags... - my $formatted_fine = currency_format("$1", "$fine", FMT_SYMBOL); - $params->{'letter'}->{'content'} =~ s/.*<\/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>)/$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 diff --git a/t/db_dependent/lib/KohaTest/Letters.pm b/t/db_dependent/lib/KohaTest/Letters.pm index 97d58fb..f2d7b0d 100644 --- a/t/db_dependent/lib/KohaTest/Letters.pm +++ b/t/db_dependent/lib/KohaTest/Letters.pm @@ -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 ); diff --git a/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm b/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm index 76b6ab4..53e5439 100644 --- a/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm +++ b/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm @@ -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; diff --git a/t/db_dependent/lib/KohaTest/Members.pm b/t/db_dependent/lib/KohaTest/Members.pm index 5646be1..dfde7da 100644 --- a/t/db_dependent/lib/KohaTest/Members.pm +++ b/t/db_dependent/lib/KohaTest/Members.pm @@ -52,6 +52,7 @@ sub methods : Test( 1 ) { GetBorrowersWhoHaveNeverBorrowed GetBorrowersWithIssuesHistoryOlderThan GetBorrowersNamesAndLatestIssue + IssueSlip ); can_ok( $self->testing_class, @methods ); diff --git a/t/db_dependent/lib/KohaTest/Print.pm b/t/db_dependent/lib/KohaTest/Print.pm index 02fd5fb..d35ab34 100644 --- a/t/db_dependent/lib/KohaTest/Print.pm +++ b/t/db_dependent/lib/KohaTest/Print.pm @@ -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 ); } diff --git a/t/db_dependent/lib/KohaTest/Reserves.pm b/t/db_dependent/lib/KohaTest/Reserves.pm index 8b05dd0..6416ac3 100644 --- a/t/db_dependent/lib/KohaTest/Reserves.pm +++ b/t/db_dependent/lib/KohaTest/Reserves.pm @@ -33,6 +33,7 @@ sub methods : Test( 1 ) { GetReserveInfo _FixPriority _Findgroupreserve + ReserveSlip ); can_ok( $self->testing_class, @methods ); diff --git a/tools/letter.pl b/tools/letter.pl index f5dc0c6..7cfca55 100755 --- a/tools/letter.pl +++ b/tools/letter.pl @@ -46,14 +46,34 @@ use CGI; use C4::Auth; use C4::Context; use C4::Output; +use C4::Branch; # GetBranches -# 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,14 +87,12 @@ 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( { @@ -87,32 +105,38 @@ my ( $template, $borrowernumber, $cookie ) = get_template_and_user( } ); -if (!defined $op) { - $op = q{}; # silence errors from eq -} +my $my_branch = C4::Context->preference("IndependantBranches") + ? C4::Context->userenv()->{'branch'} + : undef; # we show only the TMPL_VAR names $op $template->param( + independant_branch => $my_branch, script_name => $script_name, 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 +149,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 +195,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 +216,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 ); $template->param( code => $code ); $template->param( module => $module); $template->param( name => $letter->{name}); @@ -226,40 +273,54 @@ 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 +328,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 { -- 1.6.5 From srdjan at catalyst.net.nz Thu Jan 5 02:45:17 2012 From: srdjan at catalyst.net.nz (Srdjan Jankovic) Date: Thu, 5 Jan 2012 14:45:17 +1300 Subject: [Koha-patches] [PATCH] bug_5786: moved AllowOnShelfHolds to circ matrix (issuingrules) In-Reply-To: References: Message-ID: <1325727917-25399-1-git-send-email-srdjan@catalyst.net.nz> --- C4/Circulation.pm | 3 +- C4/Items.pm | 2 + C4/Reserves.pm | 72 ++++++++++++++++--- C4/VirtualShelves/Page.pm | 1 - admin/smart-rules.pl | 9 ++- admin/systempreferences.pl | 1 - .../mysql/it-IT/necessari/system_preferences.sql | 1 - installer/data/mysql/kohastructure.sql | 1 + installer/data/mysql/sysprefs.sql | 1 - installer/data/mysql/updatedatabase.pl | 20 ++++++ installer/html-template-to-template-toolkit.pl | 2 +- .../en/modules/admin/preferences/circulation.pref | 6 -- .../prog/en/modules/admin/smart-rules.tt | 25 +++++-- .../prog/en/modules/help/reserve/request.tt | 2 +- .../opac-tmpl/prog/en/modules/opac-ISBDdetail.tt | 6 -- .../opac-tmpl/prog/en/modules/opac-MARCdetail.tt | 6 -- koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt | 12 +--- .../prog/en/modules/opac-results-grouped.tt | 6 -- .../opac-tmpl/prog/en/modules/opac-results.tt | 8 +-- .../opac-tmpl/prog/en/modules/opac-shelves.tt | 6 -- opac/opac-ISBDdetail.pl | 2 - opac/opac-MARCdetail.pl | 1 - opac/opac-detail.pl | 2 - opac/opac-reserve.pl | 2 +- opac/opac-search.pl | 2 +- 25 files changed, 115 insertions(+), 84 deletions(-) diff --git a/C4/Circulation.pm b/C4/Circulation.pm index 9a6f4f2..df202e1 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -2200,7 +2200,8 @@ sub CanBookBeRenewed { LEFT JOIN biblioitems USING (biblioitemnumber) WHERE - (issuingrules.categorycode = borrowers.categorycode OR issuingrules.categorycode = '*') + (issuingrules.categorycode = borrowers.categorycode + OR issuingrules.categorycode = '*') AND (issuingrules.itemtype = $itype OR issuingrules.itemtype = '*') AND diff --git a/C4/Items.pm b/C4/Items.pm index 8802a4c..7c3a26f 100644 --- a/C4/Items.pm +++ b/C4/Items.pm @@ -160,6 +160,8 @@ sub GetItem { ($data->{'serialseq'} , $data->{'publisheddate'}) = $ssth->fetchrow_array(); } #if we don't have an items.itype, use biblioitems.itemtype. + # FIXME this should respect the itypes systempreference + # if (C4::Context->preference('item-level_itypes')) { if( ! $data->{'itype'} ) { my $sth = $dbh->prepare("SELECT itemtype FROM biblioitems WHERE biblionumber = ?"); $sth->execute($data->{'biblionumber'}); diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 359bbad..5a2d819 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -479,7 +479,6 @@ sub CanItemBeReserved{ if(my $rowcount = $sthcount->fetchrow_hashref()){ $reservecount = $rowcount->{count}; } - # we check if it's ok or not if( $reservecount < $allowedreserves ){ return 1; @@ -1321,7 +1320,7 @@ sub GetReserveInfo { =head2 IsAvailableForItemLevelRequest - my $is_available = IsAvailableForItemLevelRequest($itemnumber); + my $is_available = IsAvailableForItemLevelRequest($itemnumber,$borrowernumber,$branchcode); Checks whether a given item record is available for an item-level hold request. An item is available if @@ -1331,12 +1330,8 @@ item-level hold request. An item is available if * it is not withdrawn AND * does not have a not for loan value > 0 -Whether or not the item is currently on loan is -also checked - if the AllowOnShelfHolds system preference -is ON, an item can be requested even if it is currently -on loan to somebody else. If the system preference -is OFF, an item that is currently checked out cannot -be the target of an item-level hold request. +Need to check the issuingrules onshelfholds column, +if this is set items on the shelf can be placed on hold Note that IsAvailableForItemLevelRequest() does not check if the staff operator is authorized to place @@ -1348,9 +1343,9 @@ and canreservefromotherbranches. sub IsAvailableForItemLevelRequest { my $itemnumber = shift; - + my $borrowernumber = shift; + my $branchcode = shift; my $item = GetItem($itemnumber); - # must check the notforloan setting of the itemtype # FIXME - a lot of places in the code do this # or something similar - need to be @@ -1383,14 +1378,67 @@ sub IsAvailableForItemLevelRequest { $item->{wthdrawn} or $notforloan_per_itemtype; - - if (C4::Context->preference('AllowOnShelfHolds')) { + # check issuingrules + + if (OnShelfHoldsAllowed($itemnumber,$borrowernumber,$branchcode)) { return $available_per_item; } else { return ($available_per_item and ($item->{onloan} or GetReserveStatus($itemnumber) eq "W")); } } +=head2 OnShelfHoldsAllowed + + OnShelfHoldsAllowed($itemnumber,$borrowernumber,$branchcode); + +Checks issuingrules, using the borrowers categorycode, the itemtype, and branchcode to see if onshelf +holds are allowed, returns true if so. + +=cut + +sub OnShelfHoldsAllowed { + my ($itemnumber,$borrowernumber,$branchcode) = @_; + my $item = GetItem($itemnumber); + my $borrower = C4::Members::GetMember(borrowernumber => $borrowernumber); + my $itype; + my $dbh = C4::Context->dbh; + if (C4::Context->preference('item-level_itypes')) { + # We cant trust GetItem to honour the syspref, so safest to do it ourselves + # When GetItem is fixed, we can remove this + $itype = $item->{itype}; + } + else { + my $query = "SELECT itemtype FROM biblioitems WHERE biblioitemnumber = ? "; + my $sth = $dbh->prepare($query); + $sth->execute($item->{biblioitemnumber}); + if (my $data = $sth->fetchrow_hashref()){ + $itype = $data->{itemtype}; + } + } + + my $query = "SELECT onshelfholds,categorycode,itemtype,branchcode FROM issuingrules WHERE + (issuingrules.categorycode = ? OR issuingrules.categorycode = '*') + AND + (issuingrules.itemtype = ? OR issuingrules.itemtype = '*') + AND + (issuingrules.branchcode = ? OR issuingrules.branchcode = '*') + ORDER BY + issuingrules.categorycode desc, + issuingrules.itemtype desc, + issuingrules.branchcode desc + LIMIT 1"; + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare($query); + $sth->execute($borrower->{categorycode},$itype,$branchcode); + my $data = $sth->fetchrow_hashref; + if ($data->{onshelfholds}){ + return 1; + } + else { + return 0; + } +} + =head2 AlterPriority AlterPriority( $where, $borrowernumber, $biblionumber, $reservedate ); diff --git a/C4/VirtualShelves/Page.pm b/C4/VirtualShelves/Page.pm index 523527e..ff55dc0 100644 --- a/C4/VirtualShelves/Page.pm +++ b/C4/VirtualShelves/Page.pm @@ -183,7 +183,6 @@ sub shelfpage ($$$$$) { # explicitly fetch this shelf my ($shelfnumber2,$shelfname,$owner,$category,$sorton) = GetShelf($shelfnumber); - $template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') ); if (C4::Context->preference('TagsEnabled')) { $template->param(TagsEnabled => 1); foreach (qw(TagsShowOnList TagsInputOnList)) { diff --git a/admin/smart-rules.pl b/admin/smart-rules.pl index f290934..5bfdc7d 100755 --- a/admin/smart-rules.pl +++ b/admin/smart-rules.pl @@ -101,8 +101,8 @@ elsif ($op eq 'delete-branch-item') { # save the values entered elsif ($op eq 'add') { my $sth_search = $dbh->prepare("SELECT COUNT(*) AS total FROM issuingrules WHERE branchcode=? AND categorycode=? AND itemtype=?"); - my $sth_insert = $dbh->prepare("INSERT INTO issuingrules (branchcode, categorycode, itemtype, maxissueqty, renewalsallowed, reservesallowed, issuelength, hardduedate, hardduedatecompare, fine, finedays, firstremind, chargeperiod,rentaldiscount) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); - my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, reservesallowed=?, issuelength=?, hardduedate=?, hardduedatecompare=?, rentaldiscount=? WHERE branchcode=? AND categorycode=? AND itemtype=?"); + my $sth_insert = $dbh->prepare("INSERT INTO issuingrules (branchcode, categorycode, itemtype, maxissueqty, renewalsallowed, reservesallowed, issuelength, hardduedate, hardduedatecompare, fine, finedays, firstremind, chargeperiod, rentaldiscount, onshelfholds) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); + my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, reservesallowed=?, issuelength=?, hardduedate=?, hardduedatecompare=?, rentaldiscount=?, onshelfholds=? WHERE branchcode=? AND categorycode=? AND itemtype=?"); my $br = $branch; # branch my $bor = $input->param('categorycode'); # borrower category @@ -114,6 +114,7 @@ elsif ($op eq 'add') { my $maxissueqty = $input->param('maxissueqty'); my $renewalsallowed = $input->param('renewalsallowed'); my $reservesallowed = $input->param('reservesallowed'); + my $onshelfholds = $input->param('onshelfholds'); $maxissueqty =~ s/\s//g; $maxissueqty = undef if $maxissueqty !~ /^\d+/; my $issuelength = $input->param('issuelength'); @@ -126,9 +127,9 @@ elsif ($op eq 'add') { $sth_search->execute($br,$bor,$cat); my $res = $sth_search->fetchrow_hashref(); if ($res->{total}) { - $sth_update->execute($fine, $finedays,$firstremind, $chargeperiod, $maxissueqty, $renewalsallowed,$reservesallowed, $issuelength,$hardduedate,$hardduedatecompare,$rentaldiscount, $br,$bor,$cat); + $sth_update->execute($fine, $finedays,$firstremind, $chargeperiod, $maxissueqty, $renewalsallowed,$reservesallowed, $issuelength,$hardduedate,$hardduedatecompare,$rentaldiscount, $onshelfholds, $br,$bor,$cat); } else { - $sth_insert->execute($br,$bor,$cat,$maxissueqty,$renewalsallowed,$reservesallowed,$issuelength,$hardduedate,$hardduedatecompare,$fine,$finedays,$firstremind,$chargeperiod,$rentaldiscount); + $sth_insert->execute($br,$bor,$cat,$maxissueqty,$renewalsallowed,$reservesallowed,$issuelength,$hardduedate,$hardduedatecompare,$fine,$finedays,$firstremind,$chargeperiod,$rentaldiscount,$onshelfholds); } } elsif ($op eq "set-branch-defaults") { diff --git a/admin/systempreferences.pl b/admin/systempreferences.pl index 78d0768..6bd68ee 100755 --- a/admin/systempreferences.pl +++ b/admin/systempreferences.pl @@ -186,7 +186,6 @@ $tabsysprefs{HomeOrHoldingBranch} = "Circulation"; $tabsysprefs{HomeOrHoldingBranchReturn} = "Circulation"; $tabsysprefs{RandomizeHoldsQueueWeight} = "Circulation"; $tabsysprefs{StaticHoldsQueueWeight} = "Circulation"; -$tabsysprefs{AllowOnShelfHolds} = "Circulation"; $tabsysprefs{AllowHoldsOnDamagedItems} = "Circulation"; $tabsysprefs{UseBranchTransferLimits} = "Circulation"; $tabsysprefs{AllowHoldPolicyOverride} = "Circulation"; diff --git a/installer/data/mysql/it-IT/necessari/system_preferences.sql b/installer/data/mysql/it-IT/necessari/system_preferences.sql index b4ddfa0..7aaa066 100644 --- a/installer/data/mysql/it-IT/necessari/system_preferences.sql +++ b/installer/data/mysql/it-IT/necessari/system_preferences.sql @@ -17,7 +17,6 @@ -- 51 Franklin Street' WHERE variable = ' Fifth Floor' WHERE variable = ' Boston' WHERE variable = ' MA 02110-1301 USA. UPDATE systempreferences SET value = 'cataloguing' WHERE variable = 'AcqCreateItem'; -UPDATE systempreferences SET value = '1' WHERE variable = 'AllowOnShelfHolds'; UPDATE systempreferences SET value = '1' WHERE variable = 'AllowRenewalLimitOverride'; UPDATE systempreferences SET value = 'annual' WHERE variable = 'autoBarcode'; UPDATE systempreferences SET value = 'email' WHERE variable = 'AutoEmailPrimaryAddress'; diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 5287d9f..d608712 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -988,6 +988,7 @@ CREATE TABLE `issuingrules` ( `renewalsallowed` smallint(6) NOT NULL default "0", `reservesallowed` smallint(6) NOT NULL default "0", `branchcode` varchar(10) NOT NULL default '', + `onshelfholds` tinyint(1) NOT NULL default 0, PRIMARY KEY (`branchcode`,`categorycode`,`itemtype`), KEY `categorycode` (`categorycode`), KEY `itemtype` (`itemtype`) diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 128c9b2..a1a913a 100755 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -223,7 +223,6 @@ INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES ('XSLTDetailsDisplay','0','','Enable XSL stylesheet control over details page display on intranet','YesNo'), ('XSLTResultsDisplay','0','','Enable XSL stylesheet control over results page display on intranet','YesNo'); INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('AdvancedSearchTypes','itemtypes','itemtypes|ccode','Select which set of fields comprise the Type limit in the advanced search','Choice'); -INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('AllowOnShelfHolds', '0', '', 'Allow hold requests to be placed on items that are not on loan', 'YesNo'); INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('AllowHoldsOnDamagedItems', '1', '', 'Allow hold requests to be placed on damaged items', 'YesNo'); INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('OpacSuppression', '0', '', 'Turn ON the OPAC Suppression feature, requires further setup, ask your system administrator for details', 'YesNo'); -- FIXME: add FrameworksLoaded, noOPACUserLogin? diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index 67708fa..84b11d4 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -4585,6 +4585,26 @@ if (C4::Context->preference("Version") < TransformToNum($DBversion)) { SetVersion($DBversion); } +$DBversion = '3.06.03.XXX'; +if (C4::Context->preference("Version") < TransformToNum($DBversion)) { + # First create the column + $dbh->do("ALTER TABLE issuingrules ADD onshelfholds tinyint(1) default 0"); + # Now update the column + if (C4::Context->preference("AllowOnShelfHolds")){ + # Pref is on, set allow for all rules + $dbh->do("UPDATE issuingrules SET onshelfholds=1"); + } else { + # If the preference is not set, leave off + $dbh->do("UPDATE issuingrules SET onshelfholds=0"); + } + $dbh->do("ALTER TABLE issuingrules MODIFY onshelfholds tinyint(1) default 0 NOT NULL"); + # Remove from the systempreferences table + $dbh->do("DELETE FROM systempreferences WHERE variable = 'AllowOnShelfHolds'"); + + print "Upgrade to $DBversion done (Bug 5786 move AllowOnShelfHolds to circulation matrix)\n"; + SetVersion ($DBversion); +} + =head1 FUNCTIONS =head2 DropAllForeignKeys($table) diff --git a/installer/html-template-to-template-toolkit.pl b/installer/html-template-to-template-toolkit.pl index e99b195..5f0e0ac 100755 --- a/installer/html-template-to-template-toolkit.pl +++ b/installer/html-template-to-template-toolkit.pl @@ -32,7 +32,7 @@ my @globals = ("themelang","JacketImages","OPACAmazonCoverImages","GoogleJackets "SyndeticsEnabled", "OpacRenewalAllowed", "item_level_itypes","noItemTypeImages", "virtualshelves", "RequestOnOpac", "COinSinOPACResults", "OPACXSLTResultsDisplay", "OPACItemsResultsDisplay", "LibraryThingForLibrariesID", "opacuserlogin", "TagsEnabled", -"TagsShowOnList", "TagsInputOnList","loggedinusername","AllowOnShelfHolds","opacbookbag", +"TagsShowOnList", "TagsInputOnList","loggedinusername","opacbookbag", "OPACAmazonEnabled", "SyndeticsCoverImages","using_https"); # Arguments: diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref index f4946b5..4cb60ae 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -236,12 +236,6 @@ Circulation: no: "Don't allow" - hold requests to be placed on damaged items. - - - pref: AllowOnShelfHolds - choices: - yes: Allow - no: "Don't allow" - - hold requests to be placed on items that are not checked out. - - - pref: AllowHoldDateInFuture choices: yes: Allow diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt index d2f314f..e38e446 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt @@ -80,7 +80,8 @@ for="tobranch">Clone these rules to: Clone these rules to: Delete @@ -175,6 +183,7 @@ for="tobranch">Clone these rules to: + diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/help/reserve/request.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/help/reserve/request.tt index 3d7381b..a5a5cd0 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/help/reserve/request.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/help/reserve/request.tt @@ -72,4 +72,4 @@

    See the full documentation for Holds in the manual (online).

    -[% INCLUDE 'help-bottom.inc' %] \ No newline at end of file +[% INCLUDE 'help-bottom.inc' %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-ISBDdetail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-ISBDdetail.tt index f9984a7..d04e7b1 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-ISBDdetail.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-ISBDdetail.tt @@ -51,13 +51,7 @@ [% UNLESS ( norequests ) %] [% IF ( opacuserlogin ) %] [% IF ( RequestOnOpac ) %] - [% IF ( AllowOnShelfHolds ) %]
  • Place Hold
  • - [% ELSE %] - [% IF ( ItemsIssued ) %] -
  • Place Hold
  • - [% END %] - [% END %] [% END %] [% END %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-MARCdetail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-MARCdetail.tt index 284154e..200c0ed 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-MARCdetail.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-MARCdetail.tt @@ -206,13 +206,7 @@ $(document).ready(function(){ [% UNLESS ( norequests ) %] [% IF ( opacuserlogin ) %] [% IF ( RequestOnOpac ) %] - [% IF ( AllowOnShelfHolds ) %]
  • Place Hold
  • - [% ELSE %] - [% IF ( ItemsIssued ) %] -
  • Place Hold
  • - [% END %] - [% END %] [% END %] [% END %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt index d1b6570..fb367ca 100755 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt @@ -1016,16 +1016,10 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
      [% UNLESS ( norequests ) %] - [% IF ( opacuserlogin ) %] + [% IF ( opacuserlogin ) %] [% IF ( RequestOnOpac ) %] - [% IF ( AllowOnShelfHolds ) %] -
    • Place Hold
    • - [% ELSE %] - [% IF ( ItemsIssued ) %] -
    • Place Hold
    • - [% END %] - [% END %] - [% END %] +
    • Place Hold
    • + [% END %] [% END %] [% END %]
    • Print
    • diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results-grouped.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results-grouped.tt index 9e1b855..e08f7f9 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results-grouped.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results-grouped.tt @@ -260,13 +260,7 @@ function highlightOn() { [% IF ( RequestOnOpac ) %] [% UNLESS ( GROUP_RESULT.norequests ) %] [% IF ( opacuserlogin ) %] - [% IF ( AllowOnShelfHolds ) %] Place Hold - [% ELSE %] - [% IF ( GROUP_RESULT.itemsissued ) %] - Place Hold - [% END %] - [% END %] [% END %] [% END %] [% END %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt index 798e0d8..2256b3e 100755 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt @@ -510,13 +510,7 @@ $(document).ready(function(){ [% IF ( RequestOnOpac ) %] [% UNLESS ( SEARCH_RESULT.norequests ) %] [% IF ( opacuserlogin ) %] - [% IF ( AllowOnShelfHolds ) %] - Place Hold - [% ELSE %] - [% IF ( SEARCH_RESULT.itemsissued ) %] - Place Hold - [% END %] - [% END %] + Place Hold [% END %] [% END %] [% END %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-shelves.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-shelves.tt index 391037f..b9e2ed4 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-shelves.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-shelves.tt @@ -308,13 +308,7 @@ $(function() { [% IF ( RequestOnOpac ) %] [% UNLESS ( itemsloo.norequests ) %] [% IF ( opacuserlogin ) %] - [% IF ( AllowOnShelfHolds ) %] Place Hold - [% ELSE %] - [% IF ( itemsloo.itemsissued ) %] - Place Hold - [% END %] - [% END %] [% END %] [% END %] [% END %] diff --git a/opac/opac-ISBDdetail.pl b/opac/opac-ISBDdetail.pl index c80d41c..d978357 100755 --- a/opac/opac-ISBDdetail.pl +++ b/opac/opac-ISBDdetail.pl @@ -69,7 +69,6 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user( my $biblionumber = $query->param('biblionumber'); -$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') ); $template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) ); my $marcflavour = C4::Context->preference("marcflavour"); @@ -152,7 +151,6 @@ foreach ( @$reviews ) { $template->param( RequestOnOpac => C4::Context->preference("RequestOnOpac"), - AllowOnShelfHolds => C4::Context->preference('AllowOnShelfHolds'), norequests => $norequests, ISBD => $res, biblionumber => $biblionumber, diff --git a/opac/opac-MARCdetail.pl b/opac/opac-MARCdetail.pl index ffa0a6d..476fe50 100755 --- a/opac/opac-MARCdetail.pl +++ b/opac/opac-MARCdetail.pl @@ -81,7 +81,6 @@ $template->param( bibliotitle => $biblio->{title}, ); -$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') ); $template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) ); # adding the $RequestOnOpac param diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl index f82dde2..8111e9d 100755 --- a/opac/opac-detail.pl +++ b/opac/opac-detail.pl @@ -347,8 +347,6 @@ if ($session->param('busc')) { } - -$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') ); $template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) ); my $record = GetMarcBiblio($biblionumber); diff --git a/opac/opac-reserve.pl b/opac/opac-reserve.pl index b2144a9..3e573fc 100755 --- a/opac/opac-reserve.pl +++ b/opac/opac-reserve.pl @@ -471,7 +471,7 @@ foreach my $biblioNum (@biblionumbers) { $policy_holdallowed = 0; } - if (IsAvailableForItemLevelRequest($itemNum) and $policy_holdallowed and CanItemBeReserved($borrowernumber,$itemNum) and ($itemLoopIter->{already_reserved} ne 1)) { + if (IsAvailableForItemLevelRequest($itemNum,$borr->{'borrowernumber'},$itemInfo->{'homebranch'}) and $policy_holdallowed and CanItemBeReserved($borrowernumber,$itemNum) and !$itemLoopIter->{already_reserved}) { $itemLoopIter->{available} = 1; $numCopiesAvailable++; } diff --git a/opac/opac-search.pl b/opac/opac-search.pl index aba23a8..081bc81 100755 --- a/opac/opac-search.pl +++ b/opac/opac-search.pl @@ -100,7 +100,7 @@ if (C4::Context->preference("marcflavour") eq "UNIMARC" ) { elsif (C4::Context->preference("marcflavour") eq "MARC21" ) { $template->param('usmarc' => 1); } -$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') ); + $template->param( 'OPACNoResultsFound' => C4::Context->preference('OPACNoResultsFound') ); if (C4::Context->preference('BakerTaylorEnabled')) { -- 1.6.5 From srdjan at catalyst.net.nz Fri Jan 6 06:12:01 2012 From: srdjan at catalyst.net.nz (Srdjan Jankovic) Date: Fri, 6 Jan 2012 18:12:01 +1300 Subject: [Koha-patches] [PATCH] bug_7264: Branch popup In-Reply-To: References: Message-ID: <1325826721-6636-1-git-send-email-srdjan@catalyst.net.nz> --- C4/Items.pm | 109 ++++++++---------- koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt | 122 +++++++++++++++++++- opac/opac-detail.pl | 12 ++- 3 files changed, 181 insertions(+), 62 deletions(-) diff --git a/C4/Items.pm b/C4/Items.pm index 0b91b65..37af776 100644 --- a/C4/Items.pm +++ b/C4/Items.pm @@ -1167,6 +1167,40 @@ If this is set, it is set to C. sub GetItemsInfo { my ( $biblionumber ) = @_; my $dbh = C4::Context->dbh; + + my $sth_auth_val = $dbh->prepare( + 'SELECT authorised_value + FROM marc_subfield_structure + WHERE kohafield=? + ' + ); + + $sth_auth_val->execute("items.notforloan"); + my ($authorised_valuecode_notforloan) = $sth_auth_val->fetchrow; + my $sthnflstatus = $dbh->prepare( + "SELECT lib FROM authorised_values + WHERE category=? + AND authorised_value=?" + ); + + $sth_auth_val->execute("items.restricted"); + my ($authorised_valuecode_restricted) = $sth_auth_val->fetchrow; + my $restrictedstatus = $dbh->prepare( + "SELECT lib,lib_opac FROM authorised_values + WHERE category=? + AND authorised_value=?" + ); + + $sth_auth_val->execute("items.stack"); + my ($authorised_valuecode_stack) = $sth_auth_val->fetchrow; + my $stackstatus = $dbh->prepare( + "SELECT lib + FROM authorised_values + WHERE category=? + AND authorised_value=? + " + ); + # note biblioitems.* must be avoided to prevent large marc and marcxml fields from killing performance. my $query = " SELECT items.*, @@ -1185,7 +1219,15 @@ sub GetItemsInfo { items.notforloan as itemnotforloan, itemtypes.description, itemtypes.notforloan as notforloan_per_itemtype, - branchurl + branches.branchcode, + branches.branchname, + branches.branchaddress1, + branches.branchaddress2, + branches.branchaddress3, + branches.branchphone, + branches.branchemail, + branches.branchnotes, + branches.branchurl FROM items LEFT JOIN branches ON items.holdingbranch = branches.branchcode LEFT JOIN biblio ON biblio.biblionumber = items.biblionumber @@ -1235,57 +1277,20 @@ sub GetItemsInfo { # value. $count_reserves = $restype; } - #get branch information..... - my $bsth = $dbh->prepare( - "SELECT * FROM branches WHERE branchcode = ? - " - ); - $bsth->execute( $data->{'holdingbranch'} ); - if ( my $bdata = $bsth->fetchrow_hashref ) { - $data->{'branchname'} = $bdata->{'branchname'}; - } $data->{'datedue'} = $datedue; $data->{'count_reserves'} = $count_reserves; # get notforloan complete status if applicable - my $sthnflstatus = $dbh->prepare( - 'SELECT authorised_value - FROM marc_subfield_structure - WHERE kohafield="items.notforloan" - ' - ); - - $sthnflstatus->execute; - my ($authorised_valuecode) = $sthnflstatus->fetchrow; - if ($authorised_valuecode) { - $sthnflstatus = $dbh->prepare( - "SELECT lib FROM authorised_values - WHERE category=? - AND authorised_value=?" - ); - $sthnflstatus->execute( $authorised_valuecode, + if ($authorised_valuecode_notforloan) { + $sthnflstatus->execute( $authorised_valuecode_notforloan, $data->{itemnotforloan} ); my ($lib) = $sthnflstatus->fetchrow; $data->{notforloanvalue} = $lib; } # get restricted status and description if applicable - my $restrictedstatus = $dbh->prepare( - 'SELECT authorised_value - FROM marc_subfield_structure - WHERE kohafield="items.restricted" - ' - ); - - $restrictedstatus->execute; - ($authorised_valuecode) = $restrictedstatus->fetchrow; - if ($authorised_valuecode) { - $restrictedstatus = $dbh->prepare( - "SELECT lib,lib_opac FROM authorised_values - WHERE category=? - AND authorised_value=?" - ); - $restrictedstatus->execute( $authorised_valuecode, + if ($authorised_valuecode_restricted) { + $restrictedstatus->execute( $authorised_valuecode_restricted, $data->{restricted} ); if ( my $rstdata = $restrictedstatus->fetchrow_hashref ) { @@ -1295,24 +1300,8 @@ sub GetItemsInfo { } # my stack procedures - my $stackstatus = $dbh->prepare( - 'SELECT authorised_value - FROM marc_subfield_structure - WHERE kohafield="items.stack" - ' - ); - $stackstatus->execute; - - ($authorised_valuecode) = $stackstatus->fetchrow; - if ($authorised_valuecode) { - $stackstatus = $dbh->prepare( - "SELECT lib - FROM authorised_values - WHERE category=? - AND authorised_value=? - " - ); - $stackstatus->execute( $authorised_valuecode, $data->{stack} ); + if ($authorised_valuecode_stack) { + $stackstatus->execute( $authorised_valuecode_stack, $data->{stack} ); my ($lib) = $stackstatus->fetchrow; $data->{stack} = $lib; } diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt index 8cba98b..515c1e4 100755 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt @@ -188,6 +188,101 @@ function renderPagination(index, total, ul, highlIndex) }//renderPagination [% END %] +var branch_info = [% branch_info_json %]; +function branch_popup(branchcode) { + if (branchcode == "") return; + + var b_i = branch_info[branchcode]; + if (!b_i) return; + + var info = "" + b_i.branchname + "
      " + + b_i.branchaddress1; + if (b_i.branchaddress2) info = info + "
      " + b_i.branchaddress2; + if (b_i.branchaddress3) info = info + "
      " + b_i.branchaddress3; + if (b_i.branchnotes) info = info + "

      " + b_i.branchnotes; + if (b_i.branchphone) info = info + "

      Tel. " + b_i.branchphone; + if (b_i.branchemail) info = info + "

      " + b_i.branchemail + ""; + if (b_i.branchurl) info = info + "

      " + b_i.branchurl + ""; + + popup(info); +} + +// create the popup box - remember to give it some width in your styling +document.write(''); + +var minMargin = 15; // set how much minimal space there should be to + // between the popup and everything else (borders, mouse) +var ready = false; // we are ready when the mouse event is set up +var default_width = '200px'; // will be set to width from css in document.ready + +var follow_mouse = true; +jQuery(document).ready(function(){ + $('#pup').hide(); + default_width = $('#pup').width(); + // set dynamic coords when the mouse moves + $(document).mousemove(function(e){ + if (!follow_mouse) return; + + var x,y; + + x = $(document).scrollLeft() + e.clientX; + y = $(document).scrollTop() + e.clientY; + + x += 10; // important: if the popup is where the mouse is, the hoverOver/hoverOut events flicker + + var x_y = nudge(x,y); // avoids edge overflow + + // remember: the popup is still hidden + $('#pup').css('top', x_y[1] + 'px'); + $('#pup').css('left', x_y[0] + 'px'); + }); + + ready = true; +}); + +// avoid edge overflow +function nudge(x,y) +{ + var win = $(window); + + // When the mouse is too far on the right, put window to the left + var xtreme = $(document).scrollLeft() + win.width() - $('#pup').width() - minMargin; + if(x > xtreme) { + x -= $('#pup').width() + 2 * minMargin; + } + x = max(x, 0); + + // When the mouse is too far down, move window up + if((y + $('#pup').height()) > (win.height() + $(document).scrollTop())) { + y -= $('#pup').height() + minMargin; + } + + return [ x, y ]; +} + +function popup(msg, width) +{ + if (typeof width === "undefined"){ + width = default_width; + } + // write content and display + if (ready) { + $('#pup').width(width).html(msg).show(); + follow_mouse = false; + } + // make sure popup goes away on mouse out + $(this).mouseout(function(e){ + follow_mouse = true; + $('#pup').hide().width(default_width); + }); +} + + +function max(a,b){ + if (a>b) return a; + else return b; +} + YAHOO.util.Event.onContentReady("furtherm", function () { $("#furtherm").css("display","block").css("visibility","hidden"); @@ -206,6 +301,20 @@ YAHOO.util.Event.onContentReady("furtherm", function () { //]]> + [% IF ( opacuserlogin ) %][% IF ( loggedinusername ) %][% IF ( TagsEnabled ) %][% END %][% END %][% END %] @@ -586,7 +695,18 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
    [% FOREACH ITEM_RESULT IN ITEM_RESULTS %] [% IF ( item_level_itypes ) %][% END %] - + [% IF ( itemdata_ccode ) %][% END %] [% IF ( itemdata_enumchron ) %][% END %] diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl index e2fb069..a0fecbc 100755 --- a/opac/opac-detail.pl +++ b/opac/opac-detail.pl @@ -465,6 +465,7 @@ my $biblio_authorised_value_images = C4::Items::get_authorised_value_images( C4: my $norequests = 1; my $branches = GetBranches(); my %itemfields; +my %itembranches; for my $itm (@items) { $norequests = 0 if ( (not $itm->{'wthdrawn'} ) @@ -516,6 +517,13 @@ for my $itm (@items) { $itm->{transfertfrom} = $branches->{$transfertfrom}{branchname}; $itm->{transfertto} = $branches->{$transfertto}{branchname}; } + + if (my $branchcode = $itm->{branchcode}) { + $itembranches{$branchcode} ||= { map { $_ => $itm->{$_} } + qw( branchname branchaddress1 branchaddress2 branchaddress3 + branchphone branchemail branchnotes branchurl ) + }; + } } ## get notes and subjects from MARC record @@ -535,7 +543,7 @@ my $subtitle = GetRecordValue('subtitle', $record, GetFrameworkCode($bib MARCAUTHORS => $marcauthorsarray, MARCSERIES => $marcseriesarray, MARCURLS => $marcurlsarray, - MARCHOSTS => $marchostsarray, + MARCHOSTS => $marchostsarray, norequests => $norequests, RequestOnOpac => C4::Context->preference("RequestOnOpac"), itemdata_ccode => $itemfields{ccode}, @@ -633,8 +641,10 @@ if(C4::Context->preference("ISBD")) { $template->param(ISBD => 1); } +use JSON; $template->param( ITEM_RESULTS => \@items, + branch_info_json => encode_json(\%itembranches), subscriptionsnumber => $subscriptionsnumber, biblionumber => $biblionumber, subscriptions => \@subs, -- 1.6.5 From christophe.croullebois at biblibre.com Fri Jan 6 11:38:46 2012 From: christophe.croullebois at biblibre.com (Christophe Croullebois) Date: Fri, 6 Jan 2012 11:38:46 +0100 Subject: [Koha-patches] [PATCH] [SIGNED-OFF] Bug 5358: Show cancelled orders in basket page Message-ID: <1325846326-18563-1-git-send-email-christophe.croullebois@biblibre.com> From: Julian Maurice Signed-off-by: Christophe Croullebois --- C4/Acquisition.pm | 37 ++++++++++++++++ acqui/basket.pl | 6 +++ .../intranet-tmpl/prog/en/modules/acqui/basket.tt | 44 ++++++++++++++++++++ 3 files changed, 87 insertions(+), 0 deletions(-) diff --git a/C4/Acquisition.pm b/C4/Acquisition.pm index 7127f24..2814977 100644 --- a/C4/Acquisition.pm +++ b/C4/Acquisition.pm @@ -54,6 +54,7 @@ BEGIN { &GetOrderNumber &GetLateOrders &GetOrderFromItemnumber &SearchOrder &GetHistory &GetRecentAcqui &ModReceiveOrder &ModOrderBiblioitemNumber + &GetCancelledOrders &NewOrderItem &ModOrderItem @@ -1041,6 +1042,42 @@ sub ModOrderBiblioitemNumber { $sth->execute( $biblioitemnumber, $ordernumber, $biblionumber ); } +=head3 GetCancelledOrders + + my @orders = GetCancelledOrders($basketno, $orderby); + +Returns cancelled orders for a basket + +=cut + +sub GetCancelledOrders { + my ( $basketno, $orderby ) = @_; + + return () unless $basketno; + + my $dbh = C4::Context->dbh; + my $query = " + SELECT biblio.*, biblioitems.*, aqorders.*, aqbudgets.* + FROM aqorders + LEFT JOIN aqbudgets ON aqbudgets.budget_id = aqorders.budget_id + LEFT JOIN biblio ON biblio.biblionumber = aqorders.biblionumber + LEFT JOIN biblioitems ON biblioitems.biblionumber = biblio.biblionumber + WHERE basketno = ? + AND (datecancellationprinted IS NOT NULL + AND datecancellationprinted <> '0000-00-00') + "; + + $orderby = "aqorders.datecancellationprinted desc, aqorders.timestamp desc" + unless $orderby; + $query .= " ORDER BY $orderby"; + my $sth = $dbh->prepare($query); + $sth->execute($basketno); + my $results = $sth->fetchall_arrayref( {} ); + + return @$results; +} + + #------------------------------------------------------------# =head3 ModReceiveOrder diff --git a/acqui/basket.pl b/acqui/basket.pl index b836280..c528156 100755 --- a/acqui/basket.pl +++ b/acqui/basket.pl @@ -343,6 +343,11 @@ my $total_est_gste; last; } + my @cancelledorders = GetCancelledOrders($basketno); + foreach (@cancelledorders) { + $_->{'line_total'} = sprintf("%.2f", $_->{'ecost'} * $_->{'quantity'}); + } + $template->param( basketno => $basketno, basketname => $basket->{'basketname'}, @@ -359,6 +364,7 @@ my $total_est_gste; name => $bookseller->{'name'}, entrydate => C4::Dates->new($results[0]->{'entrydate'},'iso')->output, books_loop => \@books_loop, + cancelledorders_loop => \@cancelledorders, gist_rate => sprintf( "%.2f", $gist * 100 ) . '%', total_rrp_gste => sprintf( "%.2f", $total_rrp_gste ), total_est_gste => sprintf( "%.2f", $total_est_gste ), diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt index 7bf1843..aaea6c0 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt @@ -12,6 +12,7 @@ 10: { sorter: false } } }); + $("#cancelledorderst").tablesorter(); }); function confirm_close() { var is_confirmed = confirm(_('Are you sure you want to close this basket?')); @@ -332,6 +333,49 @@ [% IF ( listincgst ) %]** Vendor's listings already include tax. [% END %] + [% IF (cancelledorders_loop) %] +
    +

    Cancelled orders

    +
    Yes No
    [% UNLESS ( noItemTypeImages ) %][% IF ( ITEM_RESULT.imageurl ) %][% ITEM_RESULT.description %][% END %][% END %] [% ITEM_RESULT.description %][% UNLESS ( singleBranchMode ) %][% IF ( ITEM_RESULT.branchurl ) %][% ITEM_RESULT.branchname %][% ELSE %][% ITEM_RESULT.branchname %][% END %][% END %] [% ITEM_RESULT.location_description %] + + [% UNLESS ( singleBranchMode ) %] + [% IF ( ITEM_RESULT.branchurl ) %] + [% ITEM_RESULT.branchname %] + [% ELSE %] + [% ITEM_RESULT.branchname %] + [% END %] + [% END %] + + [% ITEM_RESULT.location_description %] + [% ITEM_RESULT.ccode %][% IF ( ITEM_RESULT.itemcallnumber ) %] [% ITEM_RESULT.itemcallnumber %][% IF ( OPACShelfBrowser ) %] (Browse Shelf)[% END %][% END %][% ITEM_RESULT.enumchron %]
    + + + + + + + + + + + + [% FOREACH order IN cancelledorders_loop %] + + + + + + + + + [% END %] + +
    OrderRRPEst.Qty.TotalFund
    +

    + [% IF ( order.order_received ) %] (rcvd)[% END %] + [% IF (order.title) %] + [% order.title |html %] by [% order.author %]
    + [% ELSE %] + Deleted bibliographic record, can't find title
    + [% END %] + [% IF ( order.notes ) %] [% order.notes %][% END %] + [% IF ( order.isbn ) %] - [% order.isbn %][% END %] + [% IF ( order.issn ) %] - [% order.issn %][% END %] + [% IF ( order.publishercode ) %], [% order.publishercode %][% END %] + [% IF ( order.publicationyear ) %], [% order.publicationyear %][% END %] +

    +

    [% order.rrp %]

    [% order.ecost %]

    [% order.quantity %]

    [% order.line_total %]

    [% order.budget_name %]

    +
    + [% END %]
    [% UNLESS ( closedate ) %] [% INCLUDE 'acquisitions-add-to-basket.inc' %] -- 1.7.0.4 From jonathan.druart at biblibre.com Fri Jan 6 16:09:00 2012 From: jonathan.druart at biblibre.com (Jonathan Druart) Date: Fri, 6 Jan 2012 16:09:00 +0100 Subject: [Koha-patches] [PATCH 1/1] Bug 7154: Followup: Adds tables on modify + class filled wih AV Message-ID: <1325862540-24289-1-git-send-email-jonathan.druart@biblibre.com> - FIX display/hide attr on memberentry.pl when category changes - Attr classes filled with AV 'PA_CLASS' category (you have to create AV with a new category 'PA_CLASS' to fill class list) - Use tables (classes separation) on member modification and attr management (admin). Theses array are sorted by name. --- admin/patron-attr-types.pl | 28 +++++- .../prog/en/modules/admin/patron-attr-types.tt | 62 +++++++---- .../prog/en/modules/members/memberentrygen.tt | 108 +++++++++++--------- members/memberentry.pl | 17 +++- members/moremember.pl | 2 +- 5 files changed, 136 insertions(+), 81 deletions(-) diff --git a/admin/patron-attr-types.pl b/admin/patron-attr-types.pl index 377159b..5011bcb 100755 --- a/admin/patron-attr-types.pl +++ b/admin/patron-attr-types.pl @@ -22,6 +22,8 @@ use strict; use warnings; use CGI; +use List::MoreUtils qw/uniq/; + use C4::Auth; use C4::Context; use C4::Output; @@ -84,6 +86,7 @@ sub add_attribute_type_form { confirm_op => 'add_attribute_type_confirmed', ); authorised_value_category_list($template); + pa_classes($template); } sub error_add_attribute_type_form { @@ -237,9 +240,9 @@ sub edit_attribute_type_form { $template->param(display_checkout_checked => 'checked="checked"'); } authorised_value_category_list($template, $attr_type->authorised_value_category()); + pa_classes( $template, $attr_type->class ); $template->param ( category_type => $attr_type->category_type ); - $template->param ( class => $attr_type->class ); $template->param( attribute_type_form => 1, @@ -251,9 +254,21 @@ sub edit_attribute_type_form { sub patron_attribute_type_list { my $template = shift; - + my @attr_types = C4::Members::AttributeTypes::GetAttributeTypes(); - $template->param(available_attribute_types => \@attr_types); + my @classes = sort uniq( map {$_->{class}} @attr_types ); + my @attributes_loop; + for my $class (@classes) { + my @items; + for my $attr (@attr_types) { + push @items, $attr if $attr->{class} eq $class + } + push @attributes_loop, { + class => $class, + items => \@items + }; + } + $template->param(available_attribute_types => \@attributes_loop); $template->param(display_list => 1); } @@ -270,3 +285,10 @@ sub authorised_value_category_list { } $template->param(authorised_value_categories => \@list); } + +sub pa_classes { + my $template = shift; + my $selected = @_ ? shift : ''; + + $template->param(classes_val_loop => GetAuthorisedValues( 'PA_CLASS', $selected ) ); +} diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/patron-attr-types.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/patron-attr-types.tt index 4d32646..968791d 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/patron-attr-types.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/patron-attr-types.tt @@ -201,8 +201,21 @@ function CheckAttributeTypeForm(f) {
  • - - Group attributes types with a block title + + Group attributes types with a block title (based on Authorised values category 'PA_CLASS')
  • @@ -267,29 +280,32 @@ function CheckAttributeTypeForm(f) { — it was already absent from the database.
    [% END %] [% IF ( available_attribute_types ) %] - - - - - - - - - - - [% FOREACH available_attribute_type IN available_attribute_types %] + [% FOREACH attribute IN available_attribute_types %] + [% IF attribute.class %] +

    [% attribute.class %]

    + [% END %] +
    ClassCodeDescriptionActions
    + - - - - + + + - [% END %] - -
    [% available_attribute_type.class |html %][% available_attribute_type.code |html %][% available_attribute_type.description %] - Edit - Delete - CodeDescriptionActions
    + + + [% FOREACH item IN attribute.items %] + + [% item.code |html %] + [% item.description %] + + Edit + Delete + + + [% END %] + + + [% END %] [% ELSE %]

    There are no saved patron attribute types.

    [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt index 9c31271..d355111 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt @@ -63,16 +63,19 @@ } function update_category_code(category_type) { - var mytable = $("#attributes_table>tbody"); + if ( $(category_type).is("select") ) { + category_type = $("#categorycode").find("option:selected").attr("data-typename"); + } + var mytables = $(".attributes_table>tbody"); - mytable.find("tr").each(function(){ + mytables.find("tr").each(function(){ $(this).hide() }); - mytable.find("tr[data-category_type="+category_type+"]").each(function(){ + mytables.find("tr[data-category_type="+category_type+"]").each(function(){ $(this).show(); }); - mytable.find("tr[data-category_type='']").each(function(){ + mytables.find("tr[data-category_type='']").each(function(){ $(this).show(); }); @@ -1192,7 +1195,7 @@ [% IF ( opduplicate ) %] [% ELSE %] - + [% END %] @@ -1207,62 +1210,67 @@
    Additional attributes and identifiers - + [% FOREACH pa_loo IN patron_attributes %] + [% IF pa_loo.class %] +

    [% pa_loo.class %]

    +
    + [% ELSE %] +
    + [% END %] - - [% FOREACH patron_attribute IN patron_attributes %] - - - - + + - - - [% END %] + [% IF ( patron_attribute.password_allowed ) %] + (Password: ) + [% END %] + + + + [% END %] -
    Class Type Value
    [% patron_attribute.class %] - [% patron_attribute.code %] ([% patron_attribute.description %]) - - - [% IF ( patron_attribute.use_dropdown ) %] -
    + [% patron_attribute.code %] ([% patron_attribute.description %]) + + + [% IF ( patron_attribute.use_dropdown ) %] + + [% ELSE %] + [% IF ( opduplicate ) %] + [% ELSE %] - + [% END %] [% END %] - - [% ELSE %] - [% IF ( opduplicate ) %] - - [% ELSE %] - - [% END %] - [% END %] - [% IF ( patron_attribute.password_allowed ) %] - (Password: ) - [% END %] - - Clear - [% IF ( patron_attribute.repeatable ) %] - New - [% END %] -
    + Clear + [% IF ( patron_attribute.repeatable ) %] + New + [% END %] +
    + + [% END %]
    [% END %][% END %][% END %] diff --git a/members/memberentry.pl b/members/memberentry.pl index 51ff108..8211880 100755 --- a/members/memberentry.pl +++ b/members/memberentry.pl @@ -25,6 +25,7 @@ use warnings; # external modules use CGI; # use Digest::MD5 qw(md5_base64); +use List::MoreUtils qw/uniq/; # internal modules use C4::Auth; @@ -407,7 +408,7 @@ if ($op eq 'add'){ if ($op eq "modify") { $template->param( updtype => 'M',modify => 1 ); $template->param( step_1=>1, step_2=>1, step_3=>1, step_4=>1, step_5 => 1, step_6 => 1) unless $step; - if ( $step = 4 ) { + if ( $step == 4 ) { $template->param( category_type => $borrower_data->{'categorycode'} ); } } @@ -751,6 +752,7 @@ sub patron_attributes_form { return; } my $attributes = C4::Members::Attributes::GetBorrowerAttributes($borrowernumber); + my @classes = sort uniq( map {$_->{class}} @$attributes ); # map patron's attributes into a more convenient structure my %attr_hash = (); @@ -760,6 +762,7 @@ sub patron_attributes_form { my @attribute_loop = (); my $i = 0; + my %items_by_class; foreach my $type_code (map { $_->{code} } @types) { my $attr_type = C4::Members::AttributeTypes->fetch($type_code); my $entry = { @@ -784,8 +787,7 @@ sub patron_attributes_form { } $i++; $newentry->{form_id} = "patron_attr_$i"; - #use Data::Dumper; die Dumper($entry) if $entry->{use_dropdown}; - push @attribute_loop, $newentry; + push @{$items_by_class{$attr_type->class()}}, $newentry; } } else { $i++; @@ -795,9 +797,16 @@ sub patron_attributes_form { $newentry->{auth_val_loop} = GetAuthorisedValues($attr_type->authorised_value_category()); } $newentry->{form_id} = "patron_attr_$i"; - push @attribute_loop, $newentry; + push @{$items_by_class{$attr_type->class()}}, $newentry; } } + while ( my ($class, @items) = each %items_by_class ) { + push @attribute_loop, { + class => $class, + items => @items + } + } + $template->param(patron_attributes => \@attribute_loop); } diff --git a/members/moremember.pl b/members/moremember.pl index e48538e..d12203e 100755 --- a/members/moremember.pl +++ b/members/moremember.pl @@ -432,7 +432,7 @@ $template->param(%$data); if (C4::Context->preference('ExtendedPatronAttributes')) { my $attributes = C4::Members::Attributes::GetBorrowerAttributes($borrowernumber); - my @classes = uniq( map {$_->{class}} @$attributes ); + my @classes = sort uniq( map {$_->{class}} @$attributes ); my @attributes_loop; for my $class (@classes) { my @items; -- 1.7.7.3 From jonathan.druart at biblibre.com Fri Jan 6 16:11:07 2012 From: jonathan.druart at biblibre.com (Jonathan Druart) Date: Fri, 6 Jan 2012 16:11:07 +0100 Subject: [Koha-patches] [PATCH 1/1] Bug 7166: Adds edit order notes when the basket is closed Message-ID: <1325862667-24427-1-git-send-email-jonathan.druart@biblibre.com> When you are on parcel.pl or basket.pl you can now add or edit a note for each order. To test: Create orders with and without note. Edit/Add the note on basket.pl page Close the basket. Check you can add/edit the order note on parcel.pl page --- acqui/modordernotes.pl | 72 ++++++++++++++++++++ acqui/neworderempty.pl | 5 ++ .../intranet-tmpl/prog/en/modules/acqui/basket.tt | 17 +++-- .../prog/en/modules/acqui/modordernotes.tt | 47 +++++++++++++ .../prog/en/modules/acqui/neworderempty.tt | 12 ++-- .../intranet-tmpl/prog/en/modules/acqui/parcel.tt | 6 ++ 6 files changed, 147 insertions(+), 12 deletions(-) create mode 100755 acqui/modordernotes.pl create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/acqui/modordernotes.tt diff --git a/acqui/modordernotes.pl b/acqui/modordernotes.pl new file mode 100755 index 0000000..1518ad4 --- /dev/null +++ b/acqui/modordernotes.pl @@ -0,0 +1,72 @@ +#!/usr/bin/perl + +# Copyright 2011 BibLibre SARL +# 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 NAME + +modordernotes.pl + +=head1 DESCRIPTION + +Modify just notes when basket is closed. + +=cut + +use Modern::Perl; + +use CGI; +use C4::Auth; +use C4::Output; +use C4::Acquisition; + +my $input = new CGI; +my ($template, $loggedinuser, $cookie, $flags) = get_template_and_user( { + template_name => 'acqui/modordernotes.tmpl', + query => $input, + type => 'intranet', + authnotrequired => 0, + flagsrequired => { 'acquisition' => '*' }, + debug => 1, +} ); + +my $op = $input->param('op'); +my $ordernumber = $input->param('ordernumber'); +my $referrer = $input->param('referrer') || $input->referer(); + +my $order = GetOrder($ordernumber); + +if($op and $op eq 'save') { + my $ordernotes = $input->param('ordernotes'); + $order->{'notes'} = $ordernotes; + ModOrder($order); +} else { + $template->param( + ordernotes => $order->{'notes'}, + ); +} + +if($op) { + $template->param($op => 1); +} + +$template->param( + ordernumber => $ordernumber, + referrer => $referrer, +); + + +output_html_with_http_headers $input, $cookie, $template->output; diff --git a/acqui/neworderempty.pl b/acqui/neworderempty.pl index 459dfe8..2075b92 100755 --- a/acqui/neworderempty.pl +++ b/acqui/neworderempty.pl @@ -121,6 +121,11 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user( } ); +if(!$basketno) { + my $order = GetOrder($ordernumber); + $basketno = $order->{'basketno'}; +} + my $basket = GetBasket($basketno); my $contract = &GetContract($basket->{contractnumber}); diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt index 7bf1843..14b647b 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt @@ -277,13 +277,18 @@

    [% IF ( books_loo.order_received ) %] (rcvd)[% END %] [% books_loo.title |html %] by [% books_loo.author %] - [% IF ( books_loo.notes ) %] [% books_loo.notes %][% END %] - [% IF ( books_loo.isbn ) %] - [% books_loo.isbn %][% END %] - [% IF ( books_loo.issn ) %] - [% books_loo.issn %][% END %] - [% IF ( books_loo.publishercode ) %], [% books_loo.publishercode %][% END %] - [% IF ( books_loo.publicationyear ) %], [% books_loo.publicationyear %][% END %] +
    + [% IF ( books_loo.notes ) %] + [% books_loo.notes|html %] - Change note + [% ELSE %] + Add note + [% END %] + [% IF ( books_loo.isbn ) %] - [% books_loo.isbn %][% END %] + [% IF ( books_loo.issn ) %] - [% books_loo.issn %][% END %] + [% IF ( books_loo.publishercode ) %], [% books_loo.publishercode %][% END %] + [% IF ( books_loo.publicationyear ) %], [% books_loo.publicationyear %][% END %]

    - + [% books_loo.rrp %] [% books_loo.ecost %] [% books_loo.quantity %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/modordernotes.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/modordernotes.tt new file mode 100644 index 0000000..ea205d7 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/modordernotes.tt @@ -0,0 +1,47 @@ +[% INCLUDE 'doc-head-open.inc' %] +Koha › Acquisition › Change order notes +[% INCLUDE 'doc-head-close.inc' %] + + + + +[% INCLUDE 'header.inc' %] + + + +
    + +
    +
    +
    + [% IF ( save ) %] +

    Order [% ordernumber %] successfully modified.

    +

    Return to previous page

    + [% ELSE %] +

    Change order notes (order no. [% ordernumber %])

    + +
    +
    + + +
    + + + +
    + + +
    +
    + [% END %] +
    +
    +
    +[% INCLUDE 'intranet-bottom.inc' %] + diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt index d58582e..291f408 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt @@ -171,9 +171,9 @@ $(document).ready(function() [% IF ( basketno ) %]
    -
    +
    Basket details -
      +
        [% IF ( basketnote ) %]
      1. Internal note: [% basketnote %]
      2. [% END %] [% IF ( basketbooksellernote ) %]
      3. Vendor note: [% basketbooksellernote %]
      4. [% END %] [% IF ( basketcontractno ) %] @@ -199,12 +199,12 @@ $(document).ready(function() -
        - +
        [% END %] + [% END %] -
      -
    + +
    [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt index eb5492e..7f99a90 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt @@ -241,6 +241,12 @@ [% IF ( loop_order.author ) %] by [% loop_order.author %][% END %] [% IF ( loop_order.isbn ) %] – [% loop_order.isbn %][% END %] [% IF ( loop_order.publishercode ) %]
    Publisher :[% loop_order.publishercode %][% END %] +
    + [% IF ( loop_order.notes ) %] + [% loop_order.notes|html %] - Change note + [% ELSE %] + Add note + [% END %] MARC | Card [% loop_order.quantity %] -- 1.7.7.3 From adrien.saurat at biblibre.com Mon Jan 9 10:59:42 2012 From: adrien.saurat at biblibre.com (Adrien Saurat) Date: Mon, 9 Jan 2012 10:59:42 +0100 Subject: [Koha-patches] [PATCH] Bug 7241: corrects log action for CIRC and CATALOGUING Message-ID: <1326103182-6570-1-git-send-email-adrien.saurat@biblibre.com> For CIRCULATION: ISSUE and RETURN actions now store itemnumber instead of biblionumber. For CATALOGUING: we now know if the code stored in the object field is an item or a biblio (thanks to a new field called objectinfo). --- C4/Biblio.pm | 6 +++--- C4/Circulation.pm | 4 ++-- C4/Items.pm | 8 ++++---- C4/Log.pm | 6 +++--- installer/data/mysql/kohastructure.sql | 1 + installer/data/mysql/updatedatabase.pl | 7 +++++++ 6 files changed, 20 insertions(+), 12 deletions(-) diff --git a/C4/Biblio.pm b/C4/Biblio.pm index ac78ae3..1ff4947 100644 --- a/C4/Biblio.pm +++ b/C4/Biblio.pm @@ -274,7 +274,7 @@ sub AddBiblio { # now add the record ModBiblioMarc( $record, $biblionumber, $frameworkcode ) unless $defer_marc_save; - logaction( "CATALOGUING", "ADD", $biblionumber, "biblio" ) if C4::Context->preference("CataloguingLog"); + logaction( "CATALOGUING", "ADD", $biblionumber, "", "BIBLIO" ) if C4::Context->preference("CataloguingLog"); return ( $biblionumber, $biblioitemnumber ); } @@ -304,7 +304,7 @@ sub ModBiblio { if ( C4::Context->preference("CataloguingLog") ) { my $newrecord = GetMarcBiblio($biblionumber); - logaction( "CATALOGUING", "MODIFY", $biblionumber, "BEFORE=>" . $newrecord->as_formatted ); + logaction( "CATALOGUING", "MODIFY", $biblionumber, "BEFORE=>" . $newrecord->as_formatted, "BIBLIO" ); } # Cleaning up invalid fields must be done early or SetUTF8Flag is liable to @@ -452,7 +452,7 @@ sub DelBiblio { # from being generated by _koha_delete_biblioitems $error = _koha_delete_biblio( $dbh, $biblionumber ); - logaction( "CATALOGUING", "DELETE", $biblionumber, "" ) if C4::Context->preference("CataloguingLog"); + logaction( "CATALOGUING", "DELETE", $biblionumber, "", "BIBLIO" ) if C4::Context->preference("CataloguingLog"); return; } diff --git a/C4/Circulation.pm b/C4/Circulation.pm index 9a6f4f2..22b674a 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -1071,7 +1071,7 @@ sub AddIssue { } } - logaction("CIRCULATION", "ISSUE", $borrower->{'borrowernumber'}, $biblio->{'biblionumber'}) + logaction("CIRCULATION", "ISSUE", $borrower->{'borrowernumber'}, $item->{'itemnumber'}) if C4::Context->preference("IssueLog"); } return ($datedue); # not necessarily the same as when it came in! @@ -1640,7 +1640,7 @@ sub AddReturn { }); } - logaction("CIRCULATION", "RETURN", $borrowernumber, $item->{'biblionumber'}) + logaction("CIRCULATION", "RETURN", $borrowernumber, $item->{'itemnumber'}) if C4::Context->preference("ReturnLog"); # FIXME: make this comment intelligible. diff --git a/C4/Items.pm b/C4/Items.pm index 8802a4c..c2b8626 100644 --- a/C4/Items.pm +++ b/C4/Items.pm @@ -270,7 +270,7 @@ sub AddItem { ModZebra( $item->{biblionumber}, "specialUpdate", "biblioserver", undef, undef ); - logaction("CATALOGUING", "ADD", $itemnumber, "item") if C4::Context->preference("CataloguingLog"); + logaction("CATALOGUING", "ADD", $itemnumber, Dumper($item), "ITEM") if C4::Context->preference("CataloguingLog"); return ($item->{biblionumber}, $item->{biblioitemnumber}, $itemnumber); } @@ -362,7 +362,7 @@ sub AddItemBatchFromMarc { push @itemnumbers, $itemnumber; # FIXME not checking error $item->{'itemnumber'} = $itemnumber; - logaction("CATALOGUING", "ADD", $itemnumber, "item") if C4::Context->preference("CataloguingLog"); + logaction("CATALOGUING", "ADD", $itemnumber, Dumper($item), "ITEM") if C4::Context->preference("CataloguingLog"); my $new_item_marc = _marc_from_item_hash($item, $frameworkcode, $unlinked_item_subfields); $item_field->replace_with($new_item_marc->field($itemtag)); @@ -521,7 +521,7 @@ sub ModItem { # item status is possible ModZebra( $biblionumber, "specialUpdate", "biblioserver", undef, undef ); - logaction("CATALOGUING", "MODIFY", $itemnumber, Dumper($item)) if C4::Context->preference("CataloguingLog"); + logaction("CATALOGUING", "MODIFY", $itemnumber, Dumper($item), "ITEM") if C4::Context->preference("CataloguingLog"); } =head2 ModItemTransfer @@ -590,7 +590,7 @@ sub DelItem { # This last update statement makes that the timestamp column in deleteditems is updated too. If you remove these lines, please add a line to update the timestamp separately. See Bugzilla report 7146 and Biblio.pm (DelBiblio). #search item field code - logaction("CATALOGUING", "DELETE", $itemnumber, "item") if C4::Context->preference("CataloguingLog"); + logaction("CATALOGUING", "DELETE", $itemnumber, "", "ITEM") if C4::Context->preference("CataloguingLog"); } =head2 CheckItemPreSave diff --git a/C4/Log.pm b/C4/Log.pm index 6b8ff17..7041482 100644 --- a/C4/Log.pm +++ b/C4/Log.pm @@ -66,7 +66,7 @@ number is set to 0, which is the same as the superlibrarian's number. #' sub logaction { - my ($modulename, $actionname, $objectnumber, $infos)=@_; + my ($modulename, $actionname, $objectnumber, $infos, $objectinfo)=@_; # Get ID of logged in user. if called from a batch job, # no user session exists and C4::Context->userenv() returns @@ -75,8 +75,8 @@ sub logaction { my $usernumber = (ref($userenv) eq 'HASH') ? $userenv->{'number'} : 0; my $dbh = C4::Context->dbh; - my $sth=$dbh->prepare("Insert into action_logs (timestamp,user,module,action,object,info) values (now(),?,?,?,?,?)"); - $sth->execute($usernumber,$modulename,$actionname,$objectnumber,$infos); + my $sth=$dbh->prepare("Insert into action_logs (timestamp,user,module,action,object,info,objectinfo) values (now(),?,?,?,?,?,?)"); + $sth->execute($usernumber,$modulename,$actionname,$objectnumber,$infos,$objectinfo); $sth->finish; } diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 5287d9f..7713677 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -2392,6 +2392,7 @@ CREATE TABLE `action_logs` ( `module` text, `action` text, `object` int(11) default NULL, + `objectinfo` text, `info` text, PRIMARY KEY (`action_id`), KEY (`timestamp`,`user`) diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index a4942d8..b64d048 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -4585,6 +4585,13 @@ if (C4::Context->preference("Version") < TransformToNum($DBversion)) { SetVersion($DBversion); } +$DBversion = "XXX"; +if (C4::Context->preference("Version") < TransformToNum($DBversion)) { + $dbh->do("ALTER TABLE `action_logs` ADD `objectinfo` TEXT NULL AFTER `object`"); + print "Upgrade to $DBversion done (Add objectinfo column to action_logs)\n"; + SetVersion($DBversion); +} + =head1 FUNCTIONS =head2 DropAllForeignKeys($table) -- 1.7.4.1 From f.demians at tamil.fr Mon Jan 9 11:41:00 2012 From: f.demians at tamil.fr (=?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Demians?=) Date: Mon, 9 Jan 2012 11:41:00 +0100 Subject: [Koha-patches] [PATCH] Bug 7421 Add UNIMARC DOM Filter Message-ID: <1326105660-7109-1-git-send-email-f.demians@tamil.fr> --- .../authorities/authority-koha-indexdefs.xml | 511 ++++++ .../authorities/authority-zebra-indexdefs.xsl | 1829 ++++++++++++++++++++ 2 files changed, 2340 insertions(+), 0 deletions(-) create mode 100644 etc/zebradb/marc_defs/unimarc/authorities/authority-koha-indexdefs.xml create mode 100644 etc/zebradb/marc_defs/unimarc/authorities/authority-zebra-indexdefs.xsl diff --git a/etc/zebradb/marc_defs/unimarc/authorities/authority-koha-indexdefs.xml b/etc/zebradb/marc_defs/unimarc/authorities/authority-koha-indexdefs.xml new file mode 100644 index 0000000..7f2a48b --- /dev/null +++ b/etc/zebradb/marc_defs/unimarc/authorities/authority-koha-indexdefs.xml @@ -0,0 +1,511 @@ + + + + j + x + y + z + + + + Record-status:w + + + Encoding-level:w + + + + + Local-Number:w + + + + + Kind-of-record:w + + + Descriptive-cataloging-rules:w + + + Subject-heading-thesaurus:w + + + Heading-use-main-or-added-entry:w + + + Heading-use-subject-added-entry:w + + + Heading-use-series-added-entry:w + + + + + Personal-name:w + Personal-name:p + Personal-name:s + + + Personal-name-heading:w + Personal-name-heading:p + Personal-name-heading:s + Heading:w + Heading:p + Heading:s + + + Match-heading:p + Match-heading:s + + + + Personal-name-see-from:w + Personal-name-see-from:p + Personal-name-see-from:s + See-from:w + See-from:p + See-from:s + + + Match-heading-see-from:p + Match-heading-see-from:s + + + + Personal-name-see-also-from:w + Personal-name-see-also-from:p + Personal-name-see-also-from:s + See-also-from:w + See-also-from:p + See-also-from:s + + + + + Corporate-name:w + Corporate-name:p + + + Corporate-name-heading:w + Corporate-name-heading:p + Corporate-name-heading:s + Heading:w + Heading:p + Heading:s + + + Match-heading:p + Match-heading:s + + + + Corporate-name-see-from:w + Corporate-name-see-from:p + Corporate-name-see-from:s + See-from:w + See-from:p + See-from:s + + + Match-heading-see-from:p + Match-heading-see-from:s + + + + Corporate-name-see-also-from:w + Corporate-name-see-also-from:p + Corporate-name-see-also-from:s + See-also-from:w + See-also-from:p + See-also-from:s + + + + + Meeting-name:w + Meeting-name:p + + + Meeting-name-heading:w + Meeting-name-heading:p + Meeting-name-heading:s + Heading:w + Heading:p + Heading:s + + + Match-heading:p + Match-heading:s + + + + Meeting-name-see-from:w + Meeting-name-see-from:p + Meeting-name-see-from:s + See-from:w + See-from:p + See-from:s + + + Match-heading-see-from:p + Match-heading-see-from:s + + + + Meeting-name-see-also-from:w + Meeting-name-see-also-from:p + Meeting-name-see-also-from:s + See-also-from:w + See-also-from:p + See-also-from:s + + + + + Title-uniform:w + Title-uniform:p + + + Title-uniform-heading:w + Title-uniform-heading:p + Title-uniform-heading:s + Heading:w + Heading:p + Heading:s + + + Match-heading:p + Match-heading:s + + + + Title-uniform-see-from:w + Title-uniform-see-from:p + Title-uniform-see-from:s + See-from:w + See-from:p + See-from:s + + + Match-heading-see-from:p + Match-heading-see-from:s + + + + Title-uniform-see-also-from:w + Title-uniform-see-also-from:p + Title-uniform-see-also-from:s + See-also-from:w + See-also-from:p + See-also-from:s + + + + + Chronological-term:w + Chronological-term:p + + + Chronological-term-heading:w + Chronological-term-heading:p + Chronological-term-heading:s + Heading:w + Heading:p + Heading:s + + + Match-heading:p + Match-heading:s + + + + Chronological-term-see-from:w + Chronological-term-see-from:p + Chronological-term-see-from:s + See-from:w + See-from:p + See-from:s + + + Match-heading-see-from:p + Match-heading-see-from:s + + + + Chronological-term-see-also-from:w + Chronological-term-see-also-from:p + Chronological-term-see-also-from:s + See-also-from:w + See-also-from:p + See-also-from:s + + + + + + Subject-topical:w + Subject-topical:p + + + Subject-topical-heading:w + Subject-topical-heading:p + Subject-topical-heading:s + Heading:w + Heading:p + Heading:s + + + Match-heading:p + Match-heading:s + + + + Subject-topical-see-from:w + Subject-topical-see-from:p + Subject-topical-see-from:s + See-from:w + See-from:p + See-from:s + + + Match-heading-see-from:p + Match-heading-see-from:s + + + + Subject-topical-see-also-from:w + Subject-topical-see-also-from:p + Subject-topical-see-also-from:s + See-also-from:w + See-also-from:p + See-also-from:s + + + + + Name-geographic:w + Name-geographic:p + + + Name-geographic-heading:w + Name-geographic-heading:p + Name-geographic-heading:s + Heading:w + Heading:p + Heading:s + + + Match-heading:p + Match-heading:s + + + + Name-geographic-see-from:w + Name-geographic-see-from:p + Name-geographic-see-from:s + See-from:w + See-from:p + See-from:s + + + Match-heading-see-from:p + Match-heading-see-from:s + + + + Name-geographic-see-also-from:w + Name-geographic-see-also-from:p + Name-geographic-see-also-from:s + See-also-from:w + See-also-from:p + See-also-from:s + + + + + Term-genre-form:w + Term-genre-form:p + + + Term-genre-form-heading:w + Term-genre-form-heading:p + Term-genre-form-heading:s + Heading:w + Heading:p + Heading:s + + + Match-heading:p + Match-heading:s + + + + Term-genre-form-see-from:w + Term-genre-form-see-from:p + Term-genre-form-see-from:s + See-from:w + See-from:p + See-from:s + + + Match-heading-see-from:p + Match-heading-see-from:s + + + + Term-genre-form-see-also-from:w + Term-genre-form-see-also-from:p + Term-genre-form-see-also-from:s + See-also-from:w + See-also-from:p + See-also-from:s + + + + + General-subdivision:w + General-subdivision:p + General-subdivision:s + Subdivision:w + Subdivision:p + Subdivision:s + + + Match-subdivision:p + Match-subdivision:s + + + + General-subdivision-see-from:w + General-subdivision-see-from:p + General-subdivision-see-from:s + Subdivision-see-from:w + Subdivision-see-from:p + Subdivision-see-from:s + + + Match-subdivision-see-from:p + Match-subdivision-see-from:s + + + + General-subdivision-see-also-from:w + General-subdivision-see-also-from:p + General-subdivision-see-also-from:s + Subdivision-see-also-from:w + Subdivision-see-also-from:p + Subdivision-see-also-from:s + + + + + Geographic-subdivision:w + Geographic-subdivision:p + Geographic-subdivision:s + Subdivision:w + Subdivision:p + Subdivision:s + + + Match-subdivision:p + Match-subdivision:s + + + + Geographic-subdivision-see-from:w + Geographic-subdivision-see-from:p + Geographic-subdivision-see-from:s + Subdivision-see-from:w + Subdivision-see-from:p + Subdivision-see-from:s + + + Match-subdivision-see-from:p + Match-subdivision-see-from:s + + + + Geographic-subdivision-see-also-from:w + Geographic-subdivision-see-also-from:p + Geographic-subdivision-see-also-from:s + Subdivision-see-also-from:w + Subdivision-see-also-from:p + Subdivision-see-also-from:s + + + + + Chronological-subdivision:w + Chronological-subdivision:p + Chronological-subdivision:s + Subdivision:w + Subdivision:p + Subdivision:s + + + Match-subdivision:p + Match-subdivision:s + + + + Chronological-subdivision-see-from:w + Chronological-subdivision-see-from:p + Chronological-subdivision-see-from:s + Subdivision-see-from:w + Subdivision-see-from:p + Subdivision-see-from:s + + + Match-subdivision-see-from:p + Match-subdivision-see-from:s + + + + Chronological-subdivision-see-also-from:w + Chronological-subdivision-see-also-from:p + Chronological-subdivision-see-also-from:s + Subdivision-see-also-from:w + Subdivision-see-also-from:p + Subdivision-see-also-from:s + + + + + Form-subdivision:w + Form-subdivision:p + Form-subdivision:s + Subdivision:w + Subdivision:p + Subdivision:s + + + Match-subdivision:p + Match-subdivision:s + + + + Form-subdivision-see-from:w + Form-subdivision-see-from:p + Form-subdivision-see-from:s + Subdivision-see-from:w + Subdivision-see-from:p + Subdivision-see-from:s + + + Match-subdivision-see-from:p + Match-subdivision-see-from:s + + + + Form-subdivision-see-also-from:w + Form-subdivision-see-also-from:p + Form-subdivision-see-also-from:s + Subdivision-see-also-from:w + Subdivision-see-also-from:p + Subdivision-see-also-from:s + + + + authtype:w + + diff --git a/etc/zebradb/marc_defs/unimarc/authorities/authority-zebra-indexdefs.xsl b/etc/zebradb/marc_defs/unimarc/authorities/authority-zebra-indexdefs.xsl new file mode 100644 index 0000000..e5e128d --- /dev/null +++ b/etc/zebradb/marc_defs/unimarc/authorities/authority-zebra-indexdefs.xsl @@ -0,0 +1,1829 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + + + + + + + + + + + generalsubdiv + + + formsubdiv + + + chronologicalsubdiv + + + geographicsubdiv + + + + + + + + + + + + + + + + j + x + y + z + + + + + + lcsh + + + lcac + + + mesh + + + nal + + + cash + + + notapplicable + + + aat + + + sears + + + rvm + + + + + + + + notdefined + + + + + notdefined + + + + + + + + -- 1.7.8 From adrien.saurat at biblibre.com Mon Jan 9 11:57:10 2012 From: adrien.saurat at biblibre.com (Adrien Saurat) Date: Mon, 9 Jan 2012 11:57:10 +0100 Subject: [Koha-patches] [PATCH] Bug 7357: display serial title instead of '---' Message-ID: <1326106630-8008-1-git-send-email-adrien.saurat@biblibre.com> The full title of a serial is now displayed even if several lines have the same title. --- C4/Serials.pm | 8 -------- .../prog/en/modules/serials/serials-home.tt | 4 +--- 2 files changed, 1 insertions(+), 11 deletions(-) diff --git a/C4/Serials.pm b/C4/Serials.pm index 1471184..9ec4630 100644 --- a/C4/Serials.pm +++ b/C4/Serials.pm @@ -612,14 +612,6 @@ sub GetSubscriptions { my $odd = 1; while ( my $line = $sth->fetchrow_hashref ) { - if ( $previousbiblio eq $line->{biblionumber} ) { - $line->{title} = ""; - $line->{issn} = ""; - } else { - $previousbiblio = $line->{biblionumber}; - $odd = -$odd; - } - $line->{toggle} = 1 if $odd == 1; $line->{'cannotedit'} = ( C4::Context->preference('IndependantBranches') && C4::Context->userenv diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/serials-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/serials/serials-home.tt index 7753fd3..fb310d5 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/serials-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/serials/serials-home.tt @@ -99,9 +99,7 @@ Serials updated : [% IF ( subscription.issn ) %][% subscription.issn %] [% END %] - [% IF ( subscription.title ) %][% subscription.title |html %][% ELSE %] - --- - [% END %] + [% subscription.title |html %] [% IF ( subscription.notes ) %][% subscription.notes %][% END %] [% IF ( subscription.internalnotes ) %]([% subscription.internalnotes %])[% END %] -- 1.7.4.1 From M.de.Rooy at rijksmuseum.nl Mon Jan 9 13:22:52 2012 From: M.de.Rooy at rijksmuseum.nl (Marcel de Rooy) Date: Mon, 9 Jan 2012 12:22:52 +0000 Subject: [Koha-patches] [PATCH] 7310 Fixing typo in opac-results.tt Message-ID: <809BE39CD64BFD4EB9036172EBCCFA313A6E70@S-MAIL-1B.rijksmuseum.intra> This makes the second and higher public list appear again in the AddTo combo of the search results screen. --- .../opac-tmpl/prog/en/modules/opac-results.tt | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt index 798e0d8..a132902 100755 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt @@ -107,7 +107,7 @@ $(document).ready(function(){ param1 += ""[% FOREACH addpubshelvesloo IN addpubshelvesloop %]+""[% FOREACH addpubshelvesloo IN addpubshelvesloop %]+"
    diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt index 05bdb47..e06b607 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt @@ -26,7 +26,7 @@ [% END %] [% IF ( CAN_user_tools_edit_notices ) %] -
    Notices
    +
    Notices & Slips
    Define notices (print and email notification messages for overdues, etc.)
    [% END %] diff --git a/members/memberentry.pl b/members/memberentry.pl index 6de07bf..20f1cf0 100755 --- a/members/memberentry.pl +++ b/members/memberentry.pl @@ -345,10 +345,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" ); } } diff --git a/members/moremember.pl b/members/moremember.pl index 6e5407c..9277deb 100755 --- a/members/moremember.pl +++ b/members/moremember.pl @@ -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); @@ -483,13 +482,4 @@ $template->param( quickslip => $quickslip, ); -#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; diff --git a/members/printslip.pl b/members/printslip.pl new file mode 100755 index 0000000..eba8d68 --- /dev/null +++ b/members/printslip.pl @@ -0,0 +1,89 @@ +#!/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 at katipo.co.nz + last modified 21/1/2000 by chris at katipo.co.nz + modified 31/1/2001 by chris at 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; +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; +$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 ($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; diff --git a/misc/cronjobs/advance_notices.pl b/misc/cronjobs/advance_notices.pl index 1fa358f..09c4017 100755 --- a/misc/cronjobs/advance_notices.pl +++ b/misc/cronjobs/advance_notices.pl @@ -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 EEitems.contentEE 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", at 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", at 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", at 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", at 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; - } - } - - C4::Letters::parseletter( $params->{'letter'}, 'borrowers', $params->{'borrowernumber'} ); + my %table_params = ( 'borrowers' => $params->{'borrowernumber'} ); - if ( $params->{'branchcode'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'branches', $params->{'branchcode'} ); + if ( my $p = $params->{'branchcode'} ) { + $table_params{'branches'} = $p; } - if ( $params->{'itemnumber'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'issues', $params->{'itemnumber'} ); - C4::Letters::parseletter( $params->{'letter'}, 'items', $params->{'itemnumber'} ); + if ( my $p = $params->{'itemnumber'} ) { + $table_params{'issues'} = $p; + $table_params{'items'} = $p; } - if ( $params->{'biblionumber'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'biblio', $params->{'biblionumber'} ); - C4::Letters::parseletter( $params->{'letter'}, 'biblioitems', $params->{'biblionumber'} ); + if ( my $p = $params->{'biblionumber'} ) { + $table_params{'biblio'} = $p; + $table_params{'biblioitems'} = $p; } - 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; diff --git a/misc/cronjobs/gather_print_notices.pl b/misc/cronjobs/gather_print_notices.pl index a72d6a6..165b16e 100755 --- a/misc/cronjobs/gather_print_notices.pl +++ b/misc/cronjobs/gather_print_notices.pl @@ -39,11 +39,9 @@ use Getopt::Long; sub usage { print STDERR < \$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_contents .= $_ } - close STYLESHEET; -} $template->param( - stylesheet => $stylesheet_contents, + stylesheet => C4::Context->preference("NoticeCSS"), today => $today->output(), messages => \@messages, ); diff --git a/misc/cronjobs/overdue_notices.pl b/misc/cronjobs/overdue_notices.pl index 71e6a05..93061b4 100755 --- a/misc/cronjobs/overdue_notices.pl +++ b/misc/cronjobs/overdue_notices.pl @@ -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/<>/$todaysdate/g; - $params->{'letter'}->{content} =~ s/<>/$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>/o) { # process any fine tags... + $currency_format = $1; + $params->{'letter'}->{'content'} =~ s/.*<\/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_format = $1; } - if ($params->{'letter'}->{'content'} =~ m/(.*)<\/fine>/) { # process any fine tags... - my $formatted_fine = currency_format("$1", "$fine", FMT_SYMBOL); - $params->{'letter'}->{'content'} =~ s/.*<\/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>)/$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 diff --git a/t/db_dependent/lib/KohaTest/Letters.pm b/t/db_dependent/lib/KohaTest/Letters.pm index 97d58fb..f2d7b0d 100644 --- a/t/db_dependent/lib/KohaTest/Letters.pm +++ b/t/db_dependent/lib/KohaTest/Letters.pm @@ -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 ); diff --git a/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm b/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm index 76b6ab4..53e5439 100644 --- a/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm +++ b/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm @@ -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; diff --git a/t/db_dependent/lib/KohaTest/Members.pm b/t/db_dependent/lib/KohaTest/Members.pm index 5646be1..dfde7da 100644 --- a/t/db_dependent/lib/KohaTest/Members.pm +++ b/t/db_dependent/lib/KohaTest/Members.pm @@ -52,6 +52,7 @@ sub methods : Test( 1 ) { GetBorrowersWhoHaveNeverBorrowed GetBorrowersWithIssuesHistoryOlderThan GetBorrowersNamesAndLatestIssue + IssueSlip ); can_ok( $self->testing_class, @methods ); diff --git a/t/db_dependent/lib/KohaTest/Print.pm b/t/db_dependent/lib/KohaTest/Print.pm index 02fd5fb..d35ab34 100644 --- a/t/db_dependent/lib/KohaTest/Print.pm +++ b/t/db_dependent/lib/KohaTest/Print.pm @@ -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 ); } diff --git a/t/db_dependent/lib/KohaTest/Reserves.pm b/t/db_dependent/lib/KohaTest/Reserves.pm index 8b05dd0..6416ac3 100644 --- a/t/db_dependent/lib/KohaTest/Reserves.pm +++ b/t/db_dependent/lib/KohaTest/Reserves.pm @@ -33,6 +33,7 @@ sub methods : Test( 1 ) { GetReserveInfo _FixPriority _Findgroupreserve + ReserveSlip ); can_ok( $self->testing_class, @methods ); diff --git a/tools/letter.pl b/tools/letter.pl index f5dc0c6..e9e5cc4 100755 --- a/tools/letter.pl +++ b/tools/letter.pl @@ -46,14 +46,34 @@ use CGI; use C4::Auth; use C4::Context; use C4::Output; +use C4::Branch; # GetBranches -# 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,14 +87,12 @@ 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( { @@ -87,32 +105,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") + ? 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 +150,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 +196,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 +217,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 +274,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 +328,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 { -- 1.6.5 From srdjan at catalyst.net.nz Fri Jan 13 04:46:01 2012 From: srdjan at catalyst.net.nz (Srdjan Jankovic) Date: Fri, 13 Jan 2012 16:46:01 +1300 Subject: [Koha-patches] [PATCH] bug_7001: Issue and Reserve slips are notices. In-Reply-To: References: Message-ID: <1326426361-958-1-git-send-email-srdjan@catalyst.net.nz> 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. --- C4/Circulation.pm | 20 +- C4/Letters.pm | 583 +++++++++++++------- C4/Members.pm | 81 +++- C4/Members/Attributes.pm | 18 + C4/Message.pm | 12 +- C4/Print.pm | 146 ++---- C4/Reserves.pm | 103 +++-- C4/Suggestions.pm | 22 +- acqui/booksellers.pl | 7 +- circ/circulation.pl | 3 +- circ/hold-transfer-slip.pl | 27 +- .../data/mysql/de-DE/mandatory/sample_notices.sql | 2 +- .../data/mysql/en/mandatory/sample_notices.sql | 84 +++- .../data/mysql/es-ES/mandatory/sample_notices.sql | 2 +- .../mysql/fr-FR/1-Obligatoire/sample_notices.sql | 2 +- installer/data/mysql/it-IT/necessari/notices.sql | 2 +- installer/data/mysql/kohastructure.sql | 7 +- .../mysql/nb-NO/1-Obligatorisk/sample_notices.sql | 2 +- .../data/mysql/pl-PL/mandatory/sample_notices.sql | 2 +- .../data/mysql/ru-RU/mandatory/sample_notices.sql | 2 +- installer/data/mysql/sysprefs.sql | 3 + .../data/mysql/uk-UA/mandatory/sample_notices.sql | 2 +- installer/data/mysql/updatedatabase.pl | 100 ++++- .../prog/en/includes/circ-toolbar.inc | 4 +- .../en/modules/admin/preferences/circulation.pref | 5 + .../en/modules/admin/preferences/staff_client.pref | 5 + .../prog/en/modules/batch/print-notices.tt | 6 +- .../prog/en/modules/circ/hold-transfer-slip.tt | 54 -- .../prog/en/modules/circ/printslip.tt | 28 + .../prog/en/modules/members/moremember-receipt.tt | 76 --- .../intranet-tmpl/prog/en/modules/tools/letter.tt | 157 ++++-- .../prog/en/modules/tools/tools-home.tt | 2 +- members/memberentry.pl | 5 +- members/moremember.pl | 10 - members/printslip.pl | 89 +++ misc/cronjobs/advance_notices.pl | 78 ++-- misc/cronjobs/gather_print_notices.pl | 14 +- misc/cronjobs/overdue_notices.pl | 86 ++-- t/db_dependent/lib/KohaTest/Letters.pm | 5 +- t/db_dependent/lib/KohaTest/Letters/GetLetter.pm | 3 +- t/db_dependent/lib/KohaTest/Members.pm | 1 + t/db_dependent/lib/KohaTest/Print.pm | 5 +- t/db_dependent/lib/KohaTest/Reserves.pm | 1 + tools/letter.pl | 228 ++++++--- 44 files changed, 1320 insertions(+), 774 deletions(-) delete mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/circ/hold-transfer-slip.tt create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt delete mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt create mode 100755 members/printslip.pl diff --git a/C4/Circulation.pm b/C4/Circulation.pm index 9a6f4f2..cff3fa7 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -2655,11 +2655,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) { @@ -2674,7 +2681,8 @@ sub SendCirculationAlert { $message->update; } } - $letter; + + return $letter; } =head2 updateWrongTransfer diff --git a/C4/Letters.pm b/C4/Letters.pm index 2420e4a..7f195d6 100644 --- a/C4/Letters.pm +++ b/C4/Letters.pm @@ -26,6 +26,7 @@ use Encode; use Carp; use C4::Members; +use C4::Members::Attributes qw(GetBorrowerAttributes); use C4::Branch; use C4::Log; use C4::SMS; @@ -42,7 +43,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 ); } @@ -117,13 +118,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) @@ -178,7 +192,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 "; @@ -234,70 +248,65 @@ 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; 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/<>/$userenv->{firstname}/g; - $letter->{content} =~ s/<>/$userenv->{surname}/g; - $letter->{content} =~ - s/<>/$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; # warn "sending to $mail{To} From $mail{From} subj $mail{Subject} Mess $mail{Message}"; - } } } elsif ( $type eq 'claimacquisition' ) { # warn "sending issues..."; - my $letter = getletter( 'claimacquisition', $letter ); # prepare the letter... # search the biblionumber @@ -307,52 +316,43 @@ sub SendAlerts { my $sthorders = $dbh->prepare($strsth); $sthorders->execute; my $dataorders = $sthorders->fetchall_arrayref( {} ); - parseletter( $letter, 'aqbooksellers', - $dataorders->[0]->{booksellerid} ); + my $sthbookseller = $dbh->prepare("select * from aqbooksellers where id=?"); $sthbookseller->execute( $dataorders->[0]->{booksellerid} ); my $databookseller = $sthbookseller->fetchrow_hashref; - # parsing branch info - my $userenv = C4::Context->userenv; - parseletter( $letter, 'branches', $userenv->{branch} ); - - # parsing librarian name - $letter->{content} =~ s/<>/$userenv->{firstname}/g; - $letter->{content} =~ s/<>/$userenv->{surname}/g; - $letter->{content} =~ - s/<>/$userenv->{emailaddress}/g; - foreach my $data ( @{$dataorders} ) { - if ( $letter->{content} =~ m/(<<.*>>)/ ) { - my $line = $1; - foreach my $field ( keys %{$data} ) { - $line =~ s/(<<[^\.]+.$field>>)/$data->{$field}/; - } - $letter->{content} =~ s/(<<.*>>)/$line\n$1/; - } + 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; } - $letter->{content} =~ s/<<[^>]*>>//g; - my $innerletter = $letter; + + my $userenv = C4::Context->userenv; + my $letter = GetPreparedLetter ( + module => 'claimacquisition', + letter_code => $letter_code, + branchcode => $userenv->{branch}, + tables => { + 'branches' => $userenv->{branch}, + 'aqbooksellers' => $databookseller, + }, + repeat => $dataorders, + want_librarian => 1, + ) or return; # ... then send mail - if ( $databookseller->{bookselleremail} - || $databookseller->{contemail} ) - { - my %mail = ( - To => $databookseller->{bookselleremail} - . ( - $databookseller->{contemail} - ? "," . $databookseller->{contemail} - : "" - ), - From => $userenv->{emailaddress}, - Subject => "" . $innerletter->{title}, - Message => "" . $innerletter->{content}, - 'Content-Type' => 'text/plain; charset="utf8"', - ); - sendmail(%mail) or carp $Mail::Sendmail::error; - } + 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; + if ( C4::Context->preference("LetterLog") ) { logaction( "ACQUISITION", @@ -360,16 +360,13 @@ sub SendAlerts { "", "order list : " . join( ",", @$externalid ) - . "\n$innerletter->{title}\n$innerletter->{content}" + . "\n$letter->{title}\n$letter->{content}" ); } } elsif ( $type eq 'claimissues' ) { # warn "sending issues..."; - my $letter = getletter( 'claimissues', $letter ); - - # prepare the letter... # search the biblionumber my $strsth = "select serial.*,subscription.*, biblio.* from serial LEFT JOIN subscription on serial.subscriptionid=subscription.subscriptionid LEFT JOIN biblio on serial.biblionumber=biblio.biblionumber where serial.serialid IN (" @@ -377,81 +374,76 @@ sub SendAlerts { my $sthorders = $dbh->prepare($strsth); $sthorders->execute; my $dataorders = $sthorders->fetchall_arrayref( {} ); - parseletter( $letter, 'aqbooksellers', - $dataorders->[0]->{aqbooksellerid} ); + my $sthbookseller = $dbh->prepare("select * from aqbooksellers where id=?"); $sthbookseller->execute( $dataorders->[0]->{aqbooksellerid} ); my $databookseller = $sthbookseller->fetchrow_hashref; - # parsing branch info - my $userenv = C4::Context->userenv; - parseletter( $letter, 'branches', $userenv->{branch} ); - - # parsing librarian name - $letter->{content} =~ s/<>/$userenv->{firstname}/g; - $letter->{content} =~ s/<>/$userenv->{surname}/g; - $letter->{content} =~ - s/<>/$userenv->{emailaddress}/g; - foreach my $data ( @{$dataorders} ) { - if ( $letter->{content} =~ m/(<<.*>>)/ ) { - my $line = $1; - foreach my $field ( keys %{$data} ) { - $line =~ s/(<<[^\.]+.$field>>)/$data->{$field}/; - } - $letter->{content} =~ s/(<<.*>>)/$line\n$1/; - } + 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; } - $letter->{content} =~ s/<<[^>]*>>//g; - my $innerletter = $letter; + + # prepare the letter... + my $userenv = C4::Context->userenv; + my $letter = GetPreparedLetter ( + module => 'claimissues', + letter_code => $letter_code, + branchcode => $userenv->{branch}, + tables => { + 'branches' => $userenv->{branch}, + 'aqbooksellers' => $databookseller, + }, + repeat => $dataorders, + want_librarian => 1, + ) or return; # ... then send mail - if ( $databookseller->{bookselleremail} - || $databookseller->{contemail} ) { - my $mail_to = $databookseller->{bookselleremail}; - if ($databookseller->{contemail}) { - if (!$mail_to) { - $mail_to = $databookseller->{contemail}; - } else { - $mail_to .= q|,|; - $mail_to .= $databookseller->{contemail}; - } - } - my $mail_subj = $innerletter->{title}; - my $mail_msg = $innerletter->{content}; - $mail_msg ||= q{}; - $mail_subj ||= q{}; + my $mail_subj = $letter->{title}; + my $mail_msg = $letter->{content}; + $mail_msg ||= q{}; + $mail_subj ||= q{}; - my %mail = ( - To => $mail_to, - From => $userenv->{emailaddress}, - Subject => $mail_subj, - Message => $mail_msg, - 'Content-Type' => 'text/plain; charset="utf8"', - ); - sendmail(%mail) or carp $Mail::Sendmail::error; - logaction( - "ACQUISITION", - "CLAIM ISSUE", - undef, - "To=" - . $databookseller->{contemail} - . " Title=" - . $innerletter->{title} - . " Content=" - . $innerletter->{content} - ) if C4::Context->preference("LetterLog"); - } + my %mail = ( + To => join( ','. @email), + From => $userenv->{emailaddress}, + Subject => $mail_subj, + Message => $mail_msg, + 'Content-Type' => 'text/plain; charset="utf8"', + ); + sendmail(%mail) or carp $Mail::Sendmail::error; + + logaction( + "ACQUISITION", + "CLAIM ISSUE", + 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 elsif ( $type eq 'members' ) { - # must parse the password special, before it's hashed. - $letter->{content} =~ s/<>/$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"), @@ -463,24 +455,148 @@ sub SendAlerts { } } -=head2 parseletter($letter, $table, $pk) - - 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) +=head2 GetPreparedLetter( %params ) + + %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 << >> << >> + 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 = @_; + + 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/<>/$userenv->{firstname}/go; + $letter->{content} =~ s/<>/$userenv->{surname}/go; + $letter->{content} =~ s/<>/$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>(.*)!s ) { + my $subcontent = $1; + my @lines = map { + my %subletter = ( title => '', content => $subcontent ); + _substitute_tables( \%subletter, $_ ); + $subletter{content}; + } @$tag_tables; + $letter->{content} =~ s!<$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/<>/$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; -sub parseletter_sth { + 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 @@ -494,9 +610,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)) { @@ -506,25 +625,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) - my $values = $sth->fetchrow_hashref; - + 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 ) = @_; + # TEMPORARY hack until the expirationdate column is added to reserves if ( $table eq 'reserves' && $values->{'waitingdate'} ) { my @waitingdate = split /-/, $values->{'waitingdate'}; @@ -538,16 +653,51 @@ sub parseletter { )->output(); } + if ($letter->{content} && $letter->{content} =~ /<>/) { + my @da = localtime(); + my $todaysdate = "$da[2]:$da[1] " . C4::Dates->today(); + $letter->{content} =~ s/<>/$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 = "<>"; + my $replacedby = join ',', @$val_ar; + $letter->{content} =~ s/$replacefield/$replacedby/g; + } + } } return $letter; } @@ -732,31 +882,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; } @@ -823,14 +974,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') ) { @@ -850,6 +1004,27 @@ sub _send_message_by_email ($;$$$) { } } +sub _wrap_html { + my ($content, $title) = @_; + + my $css = C4::Context->preference("NoticeCSS") || ''; + $css = qq{} if $css; + return < + + +$title + +$css + + +$content + + +EOS +} + sub _send_message_by_sms ($) { my $message = shift or return undef; my $member = C4::Members::GetMember( 'borrowernumber' => $message->{'borrowernumber'} ); diff --git a/C4/Members.pm b/C4/Members.pm index 1d7bc42..9f42cea 100644 --- a/C4/Members.pm +++ b/C4/Members.pm @@ -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, at ISA, at EXPORT, at EXPORT_OK,$debug); @@ -91,6 +93,8 @@ BEGIN { &DeleteMessage &GetMessages &GetMessagesCount + + &IssueSlip ); #Modify data @@ -2227,7 +2231,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; diff --git a/C4/Members/Attributes.pm b/C4/Members/Attributes.pm index 4ae5600..33affa8 100644 --- a/C4/Members/Attributes.pm +++ b/C4/Members/Attributes.pm @@ -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); diff --git a/C4/Message.pm b/C4/Message.pm index 16272ff..4b88970 100644 --- a/C4/Message.pm +++ b/C4/Message.pm @@ -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: diff --git a/C4/Print.pm b/C4/Print.pm index f810816..7fb55cf 100644 --- a/C4/Print.pm +++ b/C4/Print.pm @@ -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 + +BORROWER: +$bordata->{'surname'}, $bordata->{'firstname'} +card number: $bordata->{'cardnumber'} +Phone: $bordata->{'phone'} +$bordata->{'streetaddress'} +$bordata->{'suburb'} +$bordata->{'town'} +$bordata->{'emailaddress'} -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>. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +EOF =cut +=head2 printslip + + &printslip($slip) + +print a slip for the given $borrowernumber and $branchcode + +=cut + +sub printslip ($) { + my ($slip) = @_; + + return unless ( C4::Context->boolean_preference('printcirculationslips') ); + # FIXME - It'd be nifty if this could generate pretty PostScript. -sub remoteprint ($$) { - my ($items, $borrower) = @_; - (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__ diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 359bbad..d2af1c5 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -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 %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 $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 $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/g; - $letter->{'content'} =~ s/<>/$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 diff --git a/C4/Suggestions.pm b/C4/Suggestions.pm index ccc0c8e..6c10fdf 100644 --- a/C4/Suggestions.pm +++ b/C4/Suggestions.pm @@ -371,20 +371,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; diff --git a/acqui/booksellers.pl b/acqui/booksellers.pl index 634eb93..745d040 100755 --- a/acqui/booksellers.pl +++ b/acqui/booksellers.pl @@ -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 ) ) diff --git a/circ/circulation.pl b/circ/circulation.pl index 1b6c619..e43a452 100755 --- a/circ/circulation.pl +++ b/circ/circulation.pl @@ -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($branch, $borrowernumber); $query->param( 'borrowernumber', '' ); $borrowernumber = ''; } diff --git a/circ/hold-transfer-slip.pl b/circ/hold-transfer-slip.pl index f581464..492dac7 100755 --- a/circ/hold-transfer-slip.pl +++ b/circ/hold-transfer-slip.pl @@ -25,8 +25,6 @@ use C4::Output; use CGI; use C4::Auth; use C4::Reserves; -use C4::Branch; -use C4::Dates qw/format_date format_date_in_iso/; use vars qw($debug); @@ -41,7 +39,7 @@ 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 +48,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 ($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; diff --git a/installer/data/mysql/de-DE/mandatory/sample_notices.sql b/installer/data/mysql/de-DE/mandatory/sample_notices.sql index 166c36d..efdad91 100644 --- a/installer/data/mysql/de-DE/mandatory/sample_notices.sql +++ b/installer/data/mysql/de-DE/mandatory/sample_notices.sql @@ -11,7 +11,7 @@ VALUES ('circulation','ODUE','Mahnung','Mahnung','Liebe/r < ('reserves', 'HOLD_PRINT', 'Vormerkbenachrichtigung (Print)', 'Vormerkbenachrichtigung (Print)', '<>\r\n<>\r\n<>\r\n<>\r\n<> <>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<> <>\r\n<>\r\n<>\r\n<> <>\r\n<>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nLiebe(r) <> <>,\r\n\r\nF??r Sie liegt seit dem <> eine Vormerkung zur Abholung bereit:\r\n\r\nTitel: <>\r\nVerfasser: <>\r\nSignatur: <>\r\n'), ('circulation','CHECKIN','R??ckgabequittung (Zusammenfassung)','R??ckgabequittung','Die folgenden Medien wurden zur??ckgegeben:\r\n----\r\n<>\r\n----\r\nVielen Dank.'), ('circulation','CHECKOUT','Ausleihquittung (Zusammenfassung)','Ausleihquittung','Die folgenden Medien wurden entliehen:\r\n----\r\n<>\r\n----\r\nVielen Dank f??r Ihren Besuch in <>.'), -('reserves', 'HOLDPLACED', 'Neue Vormerkung', 'Neue Vormerkung','Folgender Titel wurde vorgemerkt: <> (<<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>>'), diff --git a/installer/data/mysql/en/mandatory/sample_notices.sql b/installer/data/mysql/en/mandatory/sample_notices.sql index 689fa0f..8c9f4bd 100644 --- a/installer/data/mysql/en/mandatory/sample_notices.sql +++ b/installer/data/mysql/en/mandatory/sample_notices.sql @@ -11,8 +11,90 @@ 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> + +<reserves> +<div> +<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> +</div> +</reserves>', 1); + diff --git a/installer/data/mysql/es-ES/mandatory/sample_notices.sql b/installer/data/mysql/es-ES/mandatory/sample_notices.sql index 689fa0f..bf3324d 100644 --- a/installer/data/mysql/es-ES/mandatory/sample_notices.sql +++ b/installer/data/mysql/es-ES/mandatory/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql b/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql index 977e59d..acffe73 100644 --- a/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql +++ b/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/it-IT/necessari/notices.sql b/installer/data/mysql/it-IT/necessari/notices.sql index 689fa0f..bf3324d 100644 --- a/installer/data/mysql/it-IT/necessari/notices.sql +++ b/installer/data/mysql/it-IT/necessari/notices.sql @@ -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>>'), diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index e53a74e..4dc0d53 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -1168,10 +1168,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; -- @@ -2252,12 +2254,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; -- diff --git a/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql b/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql index cdb5529..08b452e 100644 --- a/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql +++ b/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/pl-PL/mandatory/sample_notices.sql b/installer/data/mysql/pl-PL/mandatory/sample_notices.sql index 6be2eb8..f0844f3 100644 --- a/installer/data/mysql/pl-PL/mandatory/sample_notices.sql +++ b/installer/data/mysql/pl-PL/mandatory/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/ru-RU/mandatory/sample_notices.sql b/installer/data/mysql/ru-RU/mandatory/sample_notices.sql index 689fa0f..bf3324d 100644 --- a/installer/data/mysql/ru-RU/mandatory/sample_notices.sql +++ b/installer/data/mysql/ru-RU/mandatory/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 918df5c..3bf50fa 100755 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -330,3 +330,6 @@ 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'); + diff --git a/installer/data/mysql/uk-UA/mandatory/sample_notices.sql b/installer/data/mysql/uk-UA/mandatory/sample_notices.sql index 358205b..b637343 100644 --- a/installer/data/mysql/uk-UA/mandatory/sample_notices.sql +++ b/installer/data/mysql/uk-UA/mandatory/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index a4ad03f..e5555fb 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -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"; @@ -4605,6 +4604,105 @@ 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`"); + print "Added branchcode and is_html to letter table\n"; + + $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 `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; Add NoticeCSS and SlipCSS sysprefs)\n"; + SetVersion($DBversion); +} =head1 FUNCTIONS diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-toolbar.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/circ-toolbar.inc index 913076f..6fdd720 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-toolbar.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/circ-toolbar.inc @@ -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 %]&print=" + print_type, "printwindow"); + var handler = print_type.match(slip_re) ? "printslip" : "moremember"; + window.open("/cgi-bin/koha/members/" + handler + ".pl?borrowernumber=[% borrowernumber %]&print=" + print_type, "printwindow"); return false; } function searchToHold(){ diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref index 817ce57..2e9945f 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -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 diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/staff_client.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/staff_client.pref index df0a434..efa33a8 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/staff_client.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/staff_client.pref @@ -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 diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/batch/print-notices.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/batch/print-notices.tt index 1904381..73f9e61 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/batch/print-notices.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/batch/print-notices.tt @@ -8,11 +8,7 @@ --> </style> [% IF ( stylesheet ) %] - <style type="text/css"> - <!-- - [% stylesheet %] - --> - </style> + <link rel="stylesheet" type="text/css" href="[% stylesheet %]"> [% END %] </head> <body> diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/hold-transfer-slip.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/hold-transfer-slip.tt deleted file mode 100644 index 18d45aa..0000000 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/hold-transfer-slip.tt +++ /dev/null @@ -1,54 +0,0 @@ -[% INCLUDE 'doc-head-open.inc' %] -<title>Koha -- Circulation: Transfers -[% INCLUDE 'doc-head-close-receipt.inc' %] - - -
    - -[% FOREACH reservedat IN reservedata %] - -
    Date: [% reservedat.pulldate %]
    -

    [% IF ( reservedat.transferrequired ) %]Transfer to [% reservedat.branchname %] [% ELSE %]Hold in [% reservedat.branchname %][% END %]

    - -
    - -

    [% reservedat.surname %], [% reservedat.firstname %]

    - -
      -
    • [% reservedat.cardnumber %]
    • - [% IF ( reservedat.phone ) %] -
    • [% reservedat.phone %]
    • - [% END %] -
    • - [% reservedat.address %]
      - [% IF ( reservedat.address2 ) %][% reservedat.address2 %]
      [% END %] - [% reservedat.city %] [% reservedat.zip %] -
    • - [% IF ( reservedat.email ) %] -
    • [% reservedat.email %]
    • - [% END %] -
    -
    -

    ITEM ON HOLD

    -

    [% reservedat.title |html %]

    -
    [% reservedat.author %]
    -
      - [% IF ( reservedat.barcode ) %]
    • [% reservedat.barcode %]
    • [% END %] - [% IF ( reservedat.itemcallnumber ) %]
    • [% reservedat.itemcallnumber %]
    • [% END %] - [% IF ( reservedat.waitingdate ) %]
    • [% reservedat.waitingdate %]
    • [% END %] -
    - [% IF ( reservedat.reservenotes ) %] -

    Notes: [% reservedat.reservenotes %]

    - [% END %] - - - -[% END %] -
    -[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt new file mode 100644 index 0000000..a790069 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt @@ -0,0 +1,28 @@ +[% INCLUDE 'doc-head-open.inc' %] +[% title %] + + + +[% IF stylesheet %] + +[% END %] + + + + +
    + +[% IF plain %] +
    +[% slip %]
    +
    +[% ELSE %] +[% slip %] +[% END %] + +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt deleted file mode 100644 index 4a85ccb..0000000 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt +++ /dev/null @@ -1,76 +0,0 @@ -[% INCLUDE 'doc-head-open.inc' %] -Print Receipt for [% cardnumber %] - - - - - - - - -
    - -

    [% LibraryName %]

    -[% IF ( branchname ) %][% branchname %]
    [% END %] -Checked out to [% firstname %] [% surname %]
    -([% cardnumber %])
    - -[% todaysdate %]
    - -[% IF ( quickslip ) %] -

    Checked Out Today

    -[% FOREACH issueloo IN issueloop %] -[% IF ( issueloo.red ) %][% ELSE %] -[% IF ( issueloo.today ) %] -

    [% issueloo.title |html %]
    -Barcode: [% issueloo.barcode %]
    -Date due: [% issueloo.date_due %]

    - [% END %] - [% END %] - [% END %] - -[% ELSE %] -

    Checked Out

    -[% FOREACH issueloo IN issueloop %] -[% IF ( issueloo.red ) %][% ELSE %] -

    [% issueloo.title |html %]
    -Barcode: [% issueloo.barcode %]
    -Date due: [% issueloo.date_due %]

    - [% END %] - [% END %] - -[% END %] - -[% IF ( quickslip ) %] -[% ELSE %] -[% IF ( overdues_exist ) %] -

    Overdues

    - [% FOREACH issueloo IN issueloop %] - [% IF ( issueloo.red ) %] -

    [% issueloo.title |html %]
    -Barcode: [% issueloo.barcode %]
    -Date due: [% issueloo.date_due %]

    -[% END %] -[% END %] -[% END %] -[% END %] - -[% IF ( koha_news_count ) %] -

    News

    - - [% FOREACH koha_new IN koha_news %] -
    [% koha_new.title %]
    -

    [% koha_new.new %]

    -

    Posted on [% koha_new.newdate %] - -


    - [% END %] -[% END %] - - -[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt index 063236e..8e12d05 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt @@ -5,14 +5,29 @@ -
    - +[% IF ( no_op_set ) %] +
    + + [% UNLESS independant_branch %] +

    + Select a library : + +

    + [% END %] +

    + + +

    +
    + [% IF ( search ) %]

    You Searched for [% searchfield %]

    [% END %] - [% IF ( letter ) %] + [% IF ( letter && !independant_branch) %] + [% select_for_copy = BLOCK %] + + [% END %] + [% END %] +
    + + - [% FOREACH lette IN letter %] - [% UNLESS ( loop.odd ) %] + + [% FOREACH lette IN letter %] + [% can_edit = lette.branchcode || !independant_branch %] + [% UNLESS ( loop.odd ) %] - [% ELSE %] + [% ELSE %] - [% END %] + [% END %] + + - [% END %] + [% END %] +
    Branch Module Code Name     
    [% lette.branchname || "(All libraries)" %] [% lette.module %] [% lette.code %] [% lette.name %] - Edit + [% IF can_edit %] + Edit + [% END %] + + [% IF !independant_branch || !lette.branchcode %] +
    + + + + + [% IF independant_branch %] + + [% ELSE %] + [% select_for_copy %] + [% END %] + +
    + [% END %]
    - [% IF ( lette.protected ) %] - - - [% ELSE %] - Delete - [% END %] + [% IF !lette.protected && can_edit %] + Delete + [% END %]
    - [% END %] +[% END %] - [% END %] - [% IF ( add_form ) %] +[% IF ( add_form ) %] -
    - + + [% IF ( modify ) %] @@ -182,6 +229,20 @@ $(document).ready(function() {
    [% IF ( modify ) %]Modify notice[% ELSE %]Add notice[% END %]
      + + [% IF independant_branch %] + + [% ELSE %] +
    1. + + +
    2. + [% END %]
    3. @@ -235,6 +296,9 @@ $(document).ready(function() {
    4. + +
    5. +
    6. @@ -252,27 +316,31 @@ $(document).ready(function() {
    +
    +
    - [% END %] +[% END %] - [% IF ( add_validate ) %] +[% IF ( add_validate ) %] Data recorded
    - [% END %] +[% END %] - [% IF ( delete_confirm ) %] +[% IF ( delete_confirm ) %]

    Delete Notice?

    + + @@ -280,6 +348,7 @@ $(document).ready(function() {
    Branch Module Code Name
    [% branchname %] [% module %] [% code %] [% name %]
    + @@ -290,14 +359,14 @@ $(document).ready(function() {
    - [% END %] +[% END %] - [% IF ( delete_confirmed ) %] +[% IF ( delete_confirmed ) %] Data deleted
    - [% END %] +[% END %]
    diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt index 05bdb47..e06b607 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt @@ -26,7 +26,7 @@ [% END %] [% IF ( CAN_user_tools_edit_notices ) %] -
    Notices
    +
    Notices & Slips
    Define notices (print and email notification messages for overdues, etc.)
    [% END %] diff --git a/members/memberentry.pl b/members/memberentry.pl index 6de07bf..20f1cf0 100755 --- a/members/memberentry.pl +++ b/members/memberentry.pl @@ -345,10 +345,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" ); } } diff --git a/members/moremember.pl b/members/moremember.pl index 6e5407c..9277deb 100755 --- a/members/moremember.pl +++ b/members/moremember.pl @@ -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); @@ -483,13 +482,4 @@ $template->param( quickslip => $quickslip, ); -#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; diff --git a/members/printslip.pl b/members/printslip.pl new file mode 100755 index 0000000..eba8d68 --- /dev/null +++ b/members/printslip.pl @@ -0,0 +1,89 @@ +#!/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 at katipo.co.nz + last modified 21/1/2000 by chris at katipo.co.nz + modified 31/1/2001 by chris at 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; +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; +$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 ($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; diff --git a/misc/cronjobs/advance_notices.pl b/misc/cronjobs/advance_notices.pl index 1fa358f..09c4017 100755 --- a/misc/cronjobs/advance_notices.pl +++ b/misc/cronjobs/advance_notices.pl @@ -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 EEitems.contentEE 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", at 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", at 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", at 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", at 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; - } - } - - C4::Letters::parseletter( $params->{'letter'}, 'borrowers', $params->{'borrowernumber'} ); + my %table_params = ( 'borrowers' => $params->{'borrowernumber'} ); - if ( $params->{'branchcode'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'branches', $params->{'branchcode'} ); + if ( my $p = $params->{'branchcode'} ) { + $table_params{'branches'} = $p; } - if ( $params->{'itemnumber'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'issues', $params->{'itemnumber'} ); - C4::Letters::parseletter( $params->{'letter'}, 'items', $params->{'itemnumber'} ); + if ( my $p = $params->{'itemnumber'} ) { + $table_params{'issues'} = $p; + $table_params{'items'} = $p; } - if ( $params->{'biblionumber'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'biblio', $params->{'biblionumber'} ); - C4::Letters::parseletter( $params->{'letter'}, 'biblioitems', $params->{'biblionumber'} ); + if ( my $p = $params->{'biblionumber'} ) { + $table_params{'biblio'} = $p; + $table_params{'biblioitems'} = $p; } - 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; diff --git a/misc/cronjobs/gather_print_notices.pl b/misc/cronjobs/gather_print_notices.pl index a72d6a6..165b16e 100755 --- a/misc/cronjobs/gather_print_notices.pl +++ b/misc/cronjobs/gather_print_notices.pl @@ -39,11 +39,9 @@ use Getopt::Long; sub usage { print STDERR < \$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_contents .= $_ } - close STYLESHEET; -} $template->param( - stylesheet => $stylesheet_contents, + stylesheet => C4::Context->preference("NoticeCSS"), today => $today->output(), messages => \@messages, ); diff --git a/misc/cronjobs/overdue_notices.pl b/misc/cronjobs/overdue_notices.pl index 71e6a05..93061b4 100755 --- a/misc/cronjobs/overdue_notices.pl +++ b/misc/cronjobs/overdue_notices.pl @@ -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/<>/$todaysdate/g; - $params->{'letter'}->{content} =~ s/<>/$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>/o) { # process any fine tags... + $currency_format = $1; + $params->{'letter'}->{'content'} =~ s/.*<\/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_format = $1; } - if ($params->{'letter'}->{'content'} =~ m/(.*)<\/fine>/) { # process any fine tags... - my $formatted_fine = currency_format("$1", "$fine", FMT_SYMBOL); - $params->{'letter'}->{'content'} =~ s/.*<\/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>)/$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 diff --git a/t/db_dependent/lib/KohaTest/Letters.pm b/t/db_dependent/lib/KohaTest/Letters.pm index 97d58fb..f2d7b0d 100644 --- a/t/db_dependent/lib/KohaTest/Letters.pm +++ b/t/db_dependent/lib/KohaTest/Letters.pm @@ -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 ); diff --git a/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm b/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm index 76b6ab4..53e5439 100644 --- a/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm +++ b/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm @@ -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; diff --git a/t/db_dependent/lib/KohaTest/Members.pm b/t/db_dependent/lib/KohaTest/Members.pm index 5646be1..dfde7da 100644 --- a/t/db_dependent/lib/KohaTest/Members.pm +++ b/t/db_dependent/lib/KohaTest/Members.pm @@ -52,6 +52,7 @@ sub methods : Test( 1 ) { GetBorrowersWhoHaveNeverBorrowed GetBorrowersWithIssuesHistoryOlderThan GetBorrowersNamesAndLatestIssue + IssueSlip ); can_ok( $self->testing_class, @methods ); diff --git a/t/db_dependent/lib/KohaTest/Print.pm b/t/db_dependent/lib/KohaTest/Print.pm index 02fd5fb..d35ab34 100644 --- a/t/db_dependent/lib/KohaTest/Print.pm +++ b/t/db_dependent/lib/KohaTest/Print.pm @@ -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 ); } diff --git a/t/db_dependent/lib/KohaTest/Reserves.pm b/t/db_dependent/lib/KohaTest/Reserves.pm index 8b05dd0..6416ac3 100644 --- a/t/db_dependent/lib/KohaTest/Reserves.pm +++ b/t/db_dependent/lib/KohaTest/Reserves.pm @@ -33,6 +33,7 @@ sub methods : Test( 1 ) { GetReserveInfo _FixPriority _Findgroupreserve + ReserveSlip ); can_ok( $self->testing_class, @methods ); diff --git a/tools/letter.pl b/tools/letter.pl index f5dc0c6..6188a9e 100755 --- a/tools/letter.pl +++ b/tools/letter.pl @@ -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,14 +88,12 @@ 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( { @@ -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") + ? 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; } -- 1.6.5 From srdjan at catalyst.net.nz Fri Jan 13 08:05:22 2012 From: srdjan at catalyst.net.nz (Srdjan Jankovic) Date: Fri, 13 Jan 2012 20:05:22 +1300 Subject: [Koha-patches] [PATCH] bug_7243: Be selective when summing up charges for blocking issues In-Reply-To: References: Message-ID: <1326438322-28787-1-git-send-email-srdjan@catalyst.net.nz> Added RentalsInNoissueCharges and ManInvlsInNoissueCharges sys prefs C4::Members::GetMemberAccountRecords() changes: * Input params: $borrowernumber, $fines_only * If $fines_only is true, discard assount records of type: 'Res' 'Rent' if RentalsInNoissueCharges is Mo authorised_values MANUAL_INV if ManInvlsInNoissueCharges is No * Dropped input param $date, it is not used Set $fines_only to true when calling GetMemberAccountRecords() from C4::Circulation::CanBookBeIssued() and C4::Members::patronflags(). That way only fines decide whether an item can be issued, and not other non-fine charges --- C4/Circulation.pm | 2 +- C4/Members.pm | 21 ++++++++++++------- circ/circulation.pl | 13 +++++------ installer/data/mysql/sysprefs.sql | 2 + installer/data/mysql/updatedatabase.pl | 8 +++++++ .../en/modules/admin/preferences/circulation.pref | 12 +++++++++++ opac/opac-user.pl | 1 - 7 files changed, 42 insertions(+), 17 deletions(-) diff --git a/C4/Circulation.pm b/C4/Circulation.pm index 9a6f4f2..5181326 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -729,7 +729,7 @@ sub CanBookBeIssued { # DEBTS my ($amount) = - C4::Members::GetMemberAccountRecords( $borrower->{'borrowernumber'}, '' && $duedate->output('iso') ); + C4::Members::GetMemberAccountRecords( $borrower->{'borrowernumber'}, 'FINES ONLY' ); my $amountlimit = C4::Context->preference("noissuescharge"); my $allowfineoverride = C4::Context->preference("AllowFineOverride"); my $allfinesneedoverride = C4::Context->preference("AllFinesNeedOverride"); diff --git a/C4/Members.pm b/C4/Members.pm index 1d7bc42..cfa393a 100644 --- a/C4/Members.pm +++ b/C4/Members.pm @@ -420,7 +420,7 @@ sub patronflags { my %flags; my ( $patroninformation) = @_; my $dbh=C4::Context->dbh; - my ($amount) = GetMemberAccountRecords( $patroninformation->{'borrowernumber'}); + my ($amount) = GetMemberAccountRecords( $patroninformation->{'borrowernumber'}, 'FINES ONLY'); if ( $amount > 0 ) { my %flaginfo; my $noissuescharge = C4::Context->preference("noissuescharge") || 5; @@ -1094,7 +1094,7 @@ sub GetAllIssues { =head2 GetMemberAccountRecords - ($total, $acctlines, $count) = &GetMemberAccountRecords($borrowernumber); + ($total, $acctlines, $count) = &GetMemberAccountRecords($borrowernumber, $fines_only); Looks up accounting data for the patron with the given borrowernumber. @@ -1104,11 +1104,13 @@ keys are the fields of the C table in the Koha database. C<$count> is the number of elements in C<$acctlines>. C<$total> is the total amount outstanding for all of the account lines. +If C<$fines_only> flag is set to true, only fines are taken in account + =cut #' sub GetMemberAccountRecords { - my ($borrowernumber,$date) = @_; + my ($borrowernumber, $fines_only) = @_; my $dbh = C4::Context->dbh; my @acctlines; my $numlines = 0; @@ -1116,14 +1118,17 @@ sub GetMemberAccountRecords { SELECT * FROM accountlines WHERE borrowernumber=?); - my @bind = ($borrowernumber); - if ($date && $date ne ''){ - $strsth.=" AND date < ? "; - push(@bind,$date); + if ($fines_only) { + my @not_fines = (qq{'Res'}); + push @not_fines, qq{'Rent'} + unless C4::Context->preference('RentalsInNoissueCharges'); + push @not_fines, qq{(SELECT authorised_value FROM authorised_values WHERE category = 'MANUAL_INV')} + unless C4::Context->preference('ManInvInNoissueCharges'); + $strsth .= " AND accounttype NOT IN (".join( ',', @not_fines ).")"; } $strsth.=" ORDER BY date desc,timestamp DESC"; my $sth= $dbh->prepare( $strsth ); - $sth->execute( @bind ); + $sth->execute( $borrowernumber ); my $total = 0; while ( my $data = $sth->fetchrow_hashref ) { if ( $data->{itemnumber} ) { diff --git a/circ/circulation.pl b/circ/circulation.pl index 1b6c619..866d7c3 100755 --- a/circ/circulation.pl +++ b/circ/circulation.pl @@ -188,8 +188,7 @@ if ( $print eq 'yes' && $borrowernumber ne '' ) { my $borrowerslist; my $message; if ($findborrower) { - my $borrowers = Search($findborrower, 'cardnumber'); - my @borrowers = @$borrowers; + my $borrowers = Search($findborrower, 'cardnumber') || []; if (C4::Context->preference("AddPatronLists")) { $template->param( "AddPatronLists_".C4::Context->preference("AddPatronLists")=> "1", @@ -200,17 +199,17 @@ if ($findborrower) { $template->param(categories=>$categories); } } - if ( $#borrowers == -1 ) { + if ( @$borrowers == 0 ) { $query->param( 'findborrower', '' ); $message = "'$findborrower'"; } - elsif ( $#borrowers == 0 ) { - $query->param( 'borrowernumber', $borrowers[0]->{'borrowernumber'} ); + elsif ( @$borrowers == 1 ) { + $borrowernumber = $borrowers->[0]->{'borrowernumber'}; + $query->param( 'borrowernumber', $borrowernumber ); $query->param( 'barcode', '' ); - $borrowernumber = $borrowers[0]->{'borrowernumber'}; } else { - $borrowerslist = \@borrowers; + $borrowerslist = $borrowers; } } diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 918df5c..5257070 100755 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -330,3 +330,5 @@ 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 ('RentalsInNoissueCharges', '1', 'Include rental charges when summing up charges for NoissueCharge.',NULL,'YesNo'); +INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('ManInvInNoissueCharges', '1', 'Include MAN_INV charges when summing up charges for NoissueCharge.',NULL,'YesNo'); diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index a4ad03f..c490b9e 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -4605,6 +4605,14 @@ if (C4::Context->preference("Version") < TransformToNum($DBversion)) { SetVersion ($DBversion); } +$DBversion = "3.07.00.XXX"; +if (C4::Context->preference("Version") < TransformToNum($DBversion)) { + $dbh->do("INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('RentalsInNoissueCharges', '1', 'Include rental charges when summing up charges for NoissueCharge.',NULL,'YesNo');"); + $dbh->do("INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('ManInvInNoissueCharges', '1', 'Include MAN_INV charges when summing up charges for NoissueCharge.',NULL,'YesNo');"); + print "Upgrade to $DBversion done (Add sysprefs RentalsInNoissueCharges and ManInvInNoissueCharges.)\n"; + SetVersion($DBversion); +} + =head1 FUNCTIONS diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref index 817ce57..5778504 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -202,6 +202,18 @@ Circulation: class: integer - '[% local_currency %] in fines.' - + - pref: RentalsInNoissueCharges + choices: + yes: Include + no: "Don't include" + - rental charges when summing up charges for NoissueCharge. + - + - pref: ManInvInNoissueCharges + choices: + yes: Include + no: "Don't include" + - MAN_INV charges when summing up charges for NoissueCharge. + - - pref: ReturnBeforeExpiry choices: yes: Require diff --git a/opac/opac-user.pl b/opac/opac-user.pl index f6ed484..3717e3c 100755 --- a/opac/opac-user.pl +++ b/opac/opac-user.pl @@ -138,7 +138,6 @@ $template->param( BORROWER_INFO => \@bordat, OPACMySummaryHTML => (C4::Context->preference("OPACMySummaryHTML")) ? 1 : 0, surname => $borr->{surname}, showname => $borr->{showname}, - ); #get issued items .... -- 1.6.5 From srdjan at catalyst.net.nz Fri Jan 13 08:43:24 2012 From: srdjan at catalyst.net.nz (Srdjan Jankovic) Date: Fri, 13 Jan 2012 20:43:24 +1300 Subject: [Koha-patches] [PATCH] bug_7001: Issue and Reserve slips are notices. In-Reply-To: References: Message-ID: <1326440604-29945-1-git-send-email-srdjan@catalyst.net.nz> 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. --- C4/Circulation.pm | 20 +- C4/Letters.pm | 583 +++++++++++++------- C4/Members.pm | 81 +++- C4/Members/Attributes.pm | 18 + C4/Message.pm | 12 +- C4/Print.pm | 146 ++---- C4/Reserves.pm | 103 +++-- C4/Suggestions.pm | 22 +- acqui/booksellers.pl | 7 +- circ/circulation.pl | 3 +- circ/hold-transfer-slip.pl | 30 +- .../data/mysql/de-DE/mandatory/sample_notices.sql | 2 +- .../data/mysql/en/mandatory/sample_notices.sql | 84 +++- .../data/mysql/es-ES/mandatory/sample_notices.sql | 2 +- .../mysql/fr-FR/1-Obligatoire/sample_notices.sql | 2 +- installer/data/mysql/it-IT/necessari/notices.sql | 2 +- installer/data/mysql/kohastructure.sql | 7 +- .../mysql/nb-NO/1-Obligatorisk/sample_notices.sql | 2 +- .../data/mysql/pl-PL/mandatory/sample_notices.sql | 2 +- .../data/mysql/ru-RU/mandatory/sample_notices.sql | 2 +- installer/data/mysql/sysprefs.sql | 3 + .../data/mysql/uk-UA/mandatory/sample_notices.sql | 2 +- installer/data/mysql/updatedatabase.pl | 100 ++++- .../prog/en/includes/circ-toolbar.inc | 4 +- .../en/modules/admin/preferences/circulation.pref | 5 + .../en/modules/admin/preferences/staff_client.pref | 5 + .../prog/en/modules/batch/print-notices.tt | 6 +- .../prog/en/modules/circ/hold-transfer-slip.tt | 54 -- .../prog/en/modules/circ/printslip.tt | 28 + .../prog/en/modules/members/moremember-receipt.tt | 76 --- .../intranet-tmpl/prog/en/modules/tools/letter.tt | 157 ++++-- .../prog/en/modules/tools/tools-home.tt | 2 +- members/memberentry.pl | 5 +- members/moremember.pl | 10 - members/printslip.pl | 92 +++ misc/cronjobs/advance_notices.pl | 78 ++-- misc/cronjobs/gather_print_notices.pl | 14 +- misc/cronjobs/overdue_notices.pl | 86 ++-- t/db_dependent/lib/KohaTest/Letters.pm | 5 +- t/db_dependent/lib/KohaTest/Letters/GetLetter.pm | 3 +- t/db_dependent/lib/KohaTest/Members.pm | 1 + t/db_dependent/lib/KohaTest/Print.pm | 5 +- t/db_dependent/lib/KohaTest/Reserves.pm | 1 + tools/letter.pl | 228 ++++++--- 44 files changed, 1326 insertions(+), 774 deletions(-) delete mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/circ/hold-transfer-slip.tt create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt delete mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt create mode 100755 members/printslip.pl diff --git a/C4/Circulation.pm b/C4/Circulation.pm index 9a6f4f2..cff3fa7 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -2655,11 +2655,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) { @@ -2674,7 +2681,8 @@ sub SendCirculationAlert { $message->update; } } - $letter; + + return $letter; } =head2 updateWrongTransfer diff --git a/C4/Letters.pm b/C4/Letters.pm index 2420e4a..7f195d6 100644 --- a/C4/Letters.pm +++ b/C4/Letters.pm @@ -26,6 +26,7 @@ use Encode; use Carp; use C4::Members; +use C4::Members::Attributes qw(GetBorrowerAttributes); use C4::Branch; use C4::Log; use C4::SMS; @@ -42,7 +43,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 ); } @@ -117,13 +118,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) @@ -178,7 +192,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 "; @@ -234,70 +248,65 @@ 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; 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/<>/$userenv->{firstname}/g; - $letter->{content} =~ s/<>/$userenv->{surname}/g; - $letter->{content} =~ - s/<>/$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; # warn "sending to $mail{To} From $mail{From} subj $mail{Subject} Mess $mail{Message}"; - } } } elsif ( $type eq 'claimacquisition' ) { # warn "sending issues..."; - my $letter = getletter( 'claimacquisition', $letter ); # prepare the letter... # search the biblionumber @@ -307,52 +316,43 @@ sub SendAlerts { my $sthorders = $dbh->prepare($strsth); $sthorders->execute; my $dataorders = $sthorders->fetchall_arrayref( {} ); - parseletter( $letter, 'aqbooksellers', - $dataorders->[0]->{booksellerid} ); + my $sthbookseller = $dbh->prepare("select * from aqbooksellers where id=?"); $sthbookseller->execute( $dataorders->[0]->{booksellerid} ); my $databookseller = $sthbookseller->fetchrow_hashref; - # parsing branch info - my $userenv = C4::Context->userenv; - parseletter( $letter, 'branches', $userenv->{branch} ); - - # parsing librarian name - $letter->{content} =~ s/<>/$userenv->{firstname}/g; - $letter->{content} =~ s/<>/$userenv->{surname}/g; - $letter->{content} =~ - s/<>/$userenv->{emailaddress}/g; - foreach my $data ( @{$dataorders} ) { - if ( $letter->{content} =~ m/(<<.*>>)/ ) { - my $line = $1; - foreach my $field ( keys %{$data} ) { - $line =~ s/(<<[^\.]+.$field>>)/$data->{$field}/; - } - $letter->{content} =~ s/(<<.*>>)/$line\n$1/; - } + 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; } - $letter->{content} =~ s/<<[^>]*>>//g; - my $innerletter = $letter; + + my $userenv = C4::Context->userenv; + my $letter = GetPreparedLetter ( + module => 'claimacquisition', + letter_code => $letter_code, + branchcode => $userenv->{branch}, + tables => { + 'branches' => $userenv->{branch}, + 'aqbooksellers' => $databookseller, + }, + repeat => $dataorders, + want_librarian => 1, + ) or return; # ... then send mail - if ( $databookseller->{bookselleremail} - || $databookseller->{contemail} ) - { - my %mail = ( - To => $databookseller->{bookselleremail} - . ( - $databookseller->{contemail} - ? "," . $databookseller->{contemail} - : "" - ), - From => $userenv->{emailaddress}, - Subject => "" . $innerletter->{title}, - Message => "" . $innerletter->{content}, - 'Content-Type' => 'text/plain; charset="utf8"', - ); - sendmail(%mail) or carp $Mail::Sendmail::error; - } + 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; + if ( C4::Context->preference("LetterLog") ) { logaction( "ACQUISITION", @@ -360,16 +360,13 @@ sub SendAlerts { "", "order list : " . join( ",", @$externalid ) - . "\n$innerletter->{title}\n$innerletter->{content}" + . "\n$letter->{title}\n$letter->{content}" ); } } elsif ( $type eq 'claimissues' ) { # warn "sending issues..."; - my $letter = getletter( 'claimissues', $letter ); - - # prepare the letter... # search the biblionumber my $strsth = "select serial.*,subscription.*, biblio.* from serial LEFT JOIN subscription on serial.subscriptionid=subscription.subscriptionid LEFT JOIN biblio on serial.biblionumber=biblio.biblionumber where serial.serialid IN (" @@ -377,81 +374,76 @@ sub SendAlerts { my $sthorders = $dbh->prepare($strsth); $sthorders->execute; my $dataorders = $sthorders->fetchall_arrayref( {} ); - parseletter( $letter, 'aqbooksellers', - $dataorders->[0]->{aqbooksellerid} ); + my $sthbookseller = $dbh->prepare("select * from aqbooksellers where id=?"); $sthbookseller->execute( $dataorders->[0]->{aqbooksellerid} ); my $databookseller = $sthbookseller->fetchrow_hashref; - # parsing branch info - my $userenv = C4::Context->userenv; - parseletter( $letter, 'branches', $userenv->{branch} ); - - # parsing librarian name - $letter->{content} =~ s/<>/$userenv->{firstname}/g; - $letter->{content} =~ s/<>/$userenv->{surname}/g; - $letter->{content} =~ - s/<>/$userenv->{emailaddress}/g; - foreach my $data ( @{$dataorders} ) { - if ( $letter->{content} =~ m/(<<.*>>)/ ) { - my $line = $1; - foreach my $field ( keys %{$data} ) { - $line =~ s/(<<[^\.]+.$field>>)/$data->{$field}/; - } - $letter->{content} =~ s/(<<.*>>)/$line\n$1/; - } + 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; } - $letter->{content} =~ s/<<[^>]*>>//g; - my $innerletter = $letter; + + # prepare the letter... + my $userenv = C4::Context->userenv; + my $letter = GetPreparedLetter ( + module => 'claimissues', + letter_code => $letter_code, + branchcode => $userenv->{branch}, + tables => { + 'branches' => $userenv->{branch}, + 'aqbooksellers' => $databookseller, + }, + repeat => $dataorders, + want_librarian => 1, + ) or return; # ... then send mail - if ( $databookseller->{bookselleremail} - || $databookseller->{contemail} ) { - my $mail_to = $databookseller->{bookselleremail}; - if ($databookseller->{contemail}) { - if (!$mail_to) { - $mail_to = $databookseller->{contemail}; - } else { - $mail_to .= q|,|; - $mail_to .= $databookseller->{contemail}; - } - } - my $mail_subj = $innerletter->{title}; - my $mail_msg = $innerletter->{content}; - $mail_msg ||= q{}; - $mail_subj ||= q{}; + my $mail_subj = $letter->{title}; + my $mail_msg = $letter->{content}; + $mail_msg ||= q{}; + $mail_subj ||= q{}; - my %mail = ( - To => $mail_to, - From => $userenv->{emailaddress}, - Subject => $mail_subj, - Message => $mail_msg, - 'Content-Type' => 'text/plain; charset="utf8"', - ); - sendmail(%mail) or carp $Mail::Sendmail::error; - logaction( - "ACQUISITION", - "CLAIM ISSUE", - undef, - "To=" - . $databookseller->{contemail} - . " Title=" - . $innerletter->{title} - . " Content=" - . $innerletter->{content} - ) if C4::Context->preference("LetterLog"); - } + my %mail = ( + To => join( ','. @email), + From => $userenv->{emailaddress}, + Subject => $mail_subj, + Message => $mail_msg, + 'Content-Type' => 'text/plain; charset="utf8"', + ); + sendmail(%mail) or carp $Mail::Sendmail::error; + + logaction( + "ACQUISITION", + "CLAIM ISSUE", + 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 elsif ( $type eq 'members' ) { - # must parse the password special, before it's hashed. - $letter->{content} =~ s/<>/$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"), @@ -463,24 +455,148 @@ sub SendAlerts { } } -=head2 parseletter($letter, $table, $pk) - - 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) +=head2 GetPreparedLetter( %params ) + + %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 << >> << >> + 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 = @_; + + 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/<>/$userenv->{firstname}/go; + $letter->{content} =~ s/<>/$userenv->{surname}/go; + $letter->{content} =~ s/<>/$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>(.*)!s ) { + my $subcontent = $1; + my @lines = map { + my %subletter = ( title => '', content => $subcontent ); + _substitute_tables( \%subletter, $_ ); + $subletter{content}; + } @$tag_tables; + $letter->{content} =~ s!<$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/<>/$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; -sub parseletter_sth { + 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 @@ -494,9 +610,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)) { @@ -506,25 +625,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) - my $values = $sth->fetchrow_hashref; - + 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 ) = @_; + # TEMPORARY hack until the expirationdate column is added to reserves if ( $table eq 'reserves' && $values->{'waitingdate'} ) { my @waitingdate = split /-/, $values->{'waitingdate'}; @@ -538,16 +653,51 @@ sub parseletter { )->output(); } + if ($letter->{content} && $letter->{content} =~ /<>/) { + my @da = localtime(); + my $todaysdate = "$da[2]:$da[1] " . C4::Dates->today(); + $letter->{content} =~ s/<>/$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 = "<>"; + my $replacedby = join ',', @$val_ar; + $letter->{content} =~ s/$replacefield/$replacedby/g; + } + } } return $letter; } @@ -732,31 +882,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; } @@ -823,14 +974,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') ) { @@ -850,6 +1004,27 @@ sub _send_message_by_email ($;$$$) { } } +sub _wrap_html { + my ($content, $title) = @_; + + my $css = C4::Context->preference("NoticeCSS") || ''; + $css = qq{} if $css; + return < + + +$title + +$css + + +$content + + +EOS +} + sub _send_message_by_sms ($) { my $message = shift or return undef; my $member = C4::Members::GetMember( 'borrowernumber' => $message->{'borrowernumber'} ); diff --git a/C4/Members.pm b/C4/Members.pm index 1d7bc42..9f42cea 100644 --- a/C4/Members.pm +++ b/C4/Members.pm @@ -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, at ISA, at EXPORT, at EXPORT_OK,$debug); @@ -91,6 +93,8 @@ BEGIN { &DeleteMessage &GetMessages &GetMessagesCount + + &IssueSlip ); #Modify data @@ -2227,7 +2231,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; diff --git a/C4/Members/Attributes.pm b/C4/Members/Attributes.pm index 4ae5600..33affa8 100644 --- a/C4/Members/Attributes.pm +++ b/C4/Members/Attributes.pm @@ -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); diff --git a/C4/Message.pm b/C4/Message.pm index 16272ff..4b88970 100644 --- a/C4/Message.pm +++ b/C4/Message.pm @@ -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: diff --git a/C4/Print.pm b/C4/Print.pm index f810816..7fb55cf 100644 --- a/C4/Print.pm +++ b/C4/Print.pm @@ -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 + +BORROWER: +$bordata->{'surname'}, $bordata->{'firstname'} +card number: $bordata->{'cardnumber'} +Phone: $bordata->{'phone'} +$bordata->{'streetaddress'} +$bordata->{'suburb'} +$bordata->{'town'} +$bordata->{'emailaddress'} -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>. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +EOF =cut +=head2 printslip + + &printslip($slip) + +print a slip for the given $borrowernumber and $branchcode + +=cut + +sub printslip ($) { + my ($slip) = @_; + + return unless ( C4::Context->boolean_preference('printcirculationslips') ); + # FIXME - It'd be nifty if this could generate pretty PostScript. -sub remoteprint ($$) { - my ($items, $borrower) = @_; - (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__ diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 359bbad..d2af1c5 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -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 %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 $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 $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/g; - $letter->{'content'} =~ s/<>/$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 diff --git a/C4/Suggestions.pm b/C4/Suggestions.pm index ccc0c8e..6c10fdf 100644 --- a/C4/Suggestions.pm +++ b/C4/Suggestions.pm @@ -371,20 +371,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; diff --git a/acqui/booksellers.pl b/acqui/booksellers.pl index 634eb93..745d040 100755 --- a/acqui/booksellers.pl +++ b/acqui/booksellers.pl @@ -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 ) ) diff --git a/circ/circulation.pl b/circ/circulation.pl index 1b6c619..20e8f6f 100755 --- a/circ/circulation.pl +++ b/circ/circulation.pl @@ -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 = ''; } diff --git a/circ/hold-transfer-slip.pl b/circ/hold-transfer-slip.pl index f581464..d7c2e72 100755 --- a/circ/hold-transfer-slip.pl +++ b/circ/hold-transfer-slip.pl @@ -25,8 +25,6 @@ use C4::Output; use CGI; use C4::Auth; 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; diff --git a/installer/data/mysql/de-DE/mandatory/sample_notices.sql b/installer/data/mysql/de-DE/mandatory/sample_notices.sql index 166c36d..efdad91 100644 --- a/installer/data/mysql/de-DE/mandatory/sample_notices.sql +++ b/installer/data/mysql/de-DE/mandatory/sample_notices.sql @@ -11,7 +11,7 @@ VALUES ('circulation','ODUE','Mahnung','Mahnung','Liebe/r < ('reserves', 'HOLD_PRINT', 'Vormerkbenachrichtigung (Print)', 'Vormerkbenachrichtigung (Print)', '<>\r\n<>\r\n<>\r\n<>\r\n<> <>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<> <>\r\n<>\r\n<>\r\n<> <>\r\n<>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nLiebe(r) <> <>,\r\n\r\nF??r Sie liegt seit dem <> eine Vormerkung zur Abholung bereit:\r\n\r\nTitel: <>\r\nVerfasser: <>\r\nSignatur: <>\r\n'), ('circulation','CHECKIN','R??ckgabequittung (Zusammenfassung)','R??ckgabequittung','Die folgenden Medien wurden zur??ckgegeben:\r\n----\r\n<>\r\n----\r\nVielen Dank.'), ('circulation','CHECKOUT','Ausleihquittung (Zusammenfassung)','Ausleihquittung','Die folgenden Medien wurden entliehen:\r\n----\r\n<>\r\n----\r\nVielen Dank f??r Ihren Besuch in <>.'), -('reserves', 'HOLDPLACED', 'Neue Vormerkung', 'Neue Vormerkung','Folgender Titel wurde vorgemerkt: <> (<<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>>'), diff --git a/installer/data/mysql/en/mandatory/sample_notices.sql b/installer/data/mysql/en/mandatory/sample_notices.sql index 689fa0f..8c9f4bd 100644 --- a/installer/data/mysql/en/mandatory/sample_notices.sql +++ b/installer/data/mysql/en/mandatory/sample_notices.sql @@ -11,8 +11,90 @@ 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> + +<reserves> +<div> +<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> +</div> +</reserves>', 1); + diff --git a/installer/data/mysql/es-ES/mandatory/sample_notices.sql b/installer/data/mysql/es-ES/mandatory/sample_notices.sql index 689fa0f..bf3324d 100644 --- a/installer/data/mysql/es-ES/mandatory/sample_notices.sql +++ b/installer/data/mysql/es-ES/mandatory/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql b/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql index 977e59d..acffe73 100644 --- a/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql +++ b/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/it-IT/necessari/notices.sql b/installer/data/mysql/it-IT/necessari/notices.sql index 689fa0f..bf3324d 100644 --- a/installer/data/mysql/it-IT/necessari/notices.sql +++ b/installer/data/mysql/it-IT/necessari/notices.sql @@ -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>>'), diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index e53a74e..4dc0d53 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -1168,10 +1168,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; -- @@ -2252,12 +2254,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; -- diff --git a/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql b/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql index cdb5529..08b452e 100644 --- a/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql +++ b/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/pl-PL/mandatory/sample_notices.sql b/installer/data/mysql/pl-PL/mandatory/sample_notices.sql index 6be2eb8..f0844f3 100644 --- a/installer/data/mysql/pl-PL/mandatory/sample_notices.sql +++ b/installer/data/mysql/pl-PL/mandatory/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/ru-RU/mandatory/sample_notices.sql b/installer/data/mysql/ru-RU/mandatory/sample_notices.sql index 689fa0f..bf3324d 100644 --- a/installer/data/mysql/ru-RU/mandatory/sample_notices.sql +++ b/installer/data/mysql/ru-RU/mandatory/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 918df5c..3bf50fa 100755 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -330,3 +330,6 @@ 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'); + diff --git a/installer/data/mysql/uk-UA/mandatory/sample_notices.sql b/installer/data/mysql/uk-UA/mandatory/sample_notices.sql index 358205b..b637343 100644 --- a/installer/data/mysql/uk-UA/mandatory/sample_notices.sql +++ b/installer/data/mysql/uk-UA/mandatory/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index a4ad03f..e5555fb 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -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"; @@ -4605,6 +4604,105 @@ 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`"); + print "Added branchcode and is_html to letter table\n"; + + $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 `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; Add NoticeCSS and SlipCSS sysprefs)\n"; + SetVersion($DBversion); +} =head1 FUNCTIONS diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-toolbar.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/circ-toolbar.inc index 913076f..6fdd720 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-toolbar.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/circ-toolbar.inc @@ -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 %]&print=" + print_type, "printwindow"); + var handler = print_type.match(slip_re) ? "printslip" : "moremember"; + window.open("/cgi-bin/koha/members/" + handler + ".pl?borrowernumber=[% borrowernumber %]&print=" + print_type, "printwindow"); return false; } function searchToHold(){ diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref index 817ce57..2e9945f 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -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 diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/staff_client.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/staff_client.pref index df0a434..efa33a8 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/staff_client.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/staff_client.pref @@ -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 diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/batch/print-notices.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/batch/print-notices.tt index 1904381..73f9e61 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/batch/print-notices.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/batch/print-notices.tt @@ -8,11 +8,7 @@ --> </style> [% IF ( stylesheet ) %] - <style type="text/css"> - <!-- - [% stylesheet %] - --> - </style> + <link rel="stylesheet" type="text/css" href="[% stylesheet %]"> [% END %] </head> <body> diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/hold-transfer-slip.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/hold-transfer-slip.tt deleted file mode 100644 index 18d45aa..0000000 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/hold-transfer-slip.tt +++ /dev/null @@ -1,54 +0,0 @@ -[% INCLUDE 'doc-head-open.inc' %] -<title>Koha -- Circulation: Transfers -[% INCLUDE 'doc-head-close-receipt.inc' %] - - -
    - -[% FOREACH reservedat IN reservedata %] - -
    Date: [% reservedat.pulldate %]
    -

    [% IF ( reservedat.transferrequired ) %]Transfer to [% reservedat.branchname %] [% ELSE %]Hold in [% reservedat.branchname %][% END %]

    - -
    - -

    [% reservedat.surname %], [% reservedat.firstname %]

    - -
      -
    • [% reservedat.cardnumber %]
    • - [% IF ( reservedat.phone ) %] -
    • [% reservedat.phone %]
    • - [% END %] -
    • - [% reservedat.address %]
      - [% IF ( reservedat.address2 ) %][% reservedat.address2 %]
      [% END %] - [% reservedat.city %] [% reservedat.zip %] -
    • - [% IF ( reservedat.email ) %] -
    • [% reservedat.email %]
    • - [% END %] -
    -
    -

    ITEM ON HOLD

    -

    [% reservedat.title |html %]

    -
    [% reservedat.author %]
    -
      - [% IF ( reservedat.barcode ) %]
    • [% reservedat.barcode %]
    • [% END %] - [% IF ( reservedat.itemcallnumber ) %]
    • [% reservedat.itemcallnumber %]
    • [% END %] - [% IF ( reservedat.waitingdate ) %]
    • [% reservedat.waitingdate %]
    • [% END %] -
    - [% IF ( reservedat.reservenotes ) %] -

    Notes: [% reservedat.reservenotes %]

    - [% END %] - - - -[% END %] -
    -[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt new file mode 100644 index 0000000..a790069 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt @@ -0,0 +1,28 @@ +[% INCLUDE 'doc-head-open.inc' %] +[% title %] + + + +[% IF stylesheet %] + +[% END %] + + + + +
    + +[% IF plain %] +
    +[% slip %]
    +
    +[% ELSE %] +[% slip %] +[% END %] + +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt deleted file mode 100644 index 4a85ccb..0000000 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt +++ /dev/null @@ -1,76 +0,0 @@ -[% INCLUDE 'doc-head-open.inc' %] -Print Receipt for [% cardnumber %] - - - - - - - - -
    - -

    [% LibraryName %]

    -[% IF ( branchname ) %][% branchname %]
    [% END %] -Checked out to [% firstname %] [% surname %]
    -([% cardnumber %])
    - -[% todaysdate %]
    - -[% IF ( quickslip ) %] -

    Checked Out Today

    -[% FOREACH issueloo IN issueloop %] -[% IF ( issueloo.red ) %][% ELSE %] -[% IF ( issueloo.today ) %] -

    [% issueloo.title |html %]
    -Barcode: [% issueloo.barcode %]
    -Date due: [% issueloo.date_due %]

    - [% END %] - [% END %] - [% END %] - -[% ELSE %] -

    Checked Out

    -[% FOREACH issueloo IN issueloop %] -[% IF ( issueloo.red ) %][% ELSE %] -

    [% issueloo.title |html %]
    -Barcode: [% issueloo.barcode %]
    -Date due: [% issueloo.date_due %]

    - [% END %] - [% END %] - -[% END %] - -[% IF ( quickslip ) %] -[% ELSE %] -[% IF ( overdues_exist ) %] -

    Overdues

    - [% FOREACH issueloo IN issueloop %] - [% IF ( issueloo.red ) %] -

    [% issueloo.title |html %]
    -Barcode: [% issueloo.barcode %]
    -Date due: [% issueloo.date_due %]

    -[% END %] -[% END %] -[% END %] -[% END %] - -[% IF ( koha_news_count ) %] -

    News

    - - [% FOREACH koha_new IN koha_news %] -
    [% koha_new.title %]
    -

    [% koha_new.new %]

    -

    Posted on [% koha_new.newdate %] - -


    - [% END %] -[% END %] - - -[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt index 063236e..8e12d05 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt @@ -5,14 +5,29 @@ -
    - +[% IF ( no_op_set ) %] +
    + + [% UNLESS independant_branch %] +

    + Select a library : + +

    + [% END %] +

    + + +

    +
    + [% IF ( search ) %]

    You Searched for [% searchfield %]

    [% END %] - [% IF ( letter ) %] + [% IF ( letter && !independant_branch) %] + [% select_for_copy = BLOCK %] + + [% END %] + [% END %] +
    + + - [% FOREACH lette IN letter %] - [% UNLESS ( loop.odd ) %] + + [% FOREACH lette IN letter %] + [% can_edit = lette.branchcode || !independant_branch %] + [% UNLESS ( loop.odd ) %] - [% ELSE %] + [% ELSE %] - [% END %] + [% END %] + + - [% END %] + [% END %] +
    Branch Module Code Name     
    [% lette.branchname || "(All libraries)" %] [% lette.module %] [% lette.code %] [% lette.name %] - Edit + [% IF can_edit %] + Edit + [% END %] + + [% IF !independant_branch || !lette.branchcode %] +
    + + + + + [% IF independant_branch %] + + [% ELSE %] + [% select_for_copy %] + [% END %] + +
    + [% END %]
    - [% IF ( lette.protected ) %] - - - [% ELSE %] - Delete - [% END %] + [% IF !lette.protected && can_edit %] + Delete + [% END %]
    - [% END %] +[% END %] - [% END %] - [% IF ( add_form ) %] +[% IF ( add_form ) %] -
    - + + [% IF ( modify ) %] @@ -182,6 +229,20 @@ $(document).ready(function() {
    [% IF ( modify ) %]Modify notice[% ELSE %]Add notice[% END %]
      + + [% IF independant_branch %] + + [% ELSE %] +
    1. + + +
    2. + [% END %]
    3. @@ -235,6 +296,9 @@ $(document).ready(function() {
    4. + +
    5. +
    6. @@ -252,27 +316,31 @@ $(document).ready(function() {
    +
    +
    - [% END %] +[% END %] - [% IF ( add_validate ) %] +[% IF ( add_validate ) %] Data recorded
    - [% END %] +[% END %] - [% IF ( delete_confirm ) %] +[% IF ( delete_confirm ) %]

    Delete Notice?

    + + @@ -280,6 +348,7 @@ $(document).ready(function() {
    Branch Module Code Name
    [% branchname %] [% module %] [% code %] [% name %]
    + @@ -290,14 +359,14 @@ $(document).ready(function() {
    - [% END %] +[% END %] - [% IF ( delete_confirmed ) %] +[% IF ( delete_confirmed ) %] Data deleted
    - [% END %] +[% END %]
    diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt index 05bdb47..e06b607 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt @@ -26,7 +26,7 @@ [% END %] [% IF ( CAN_user_tools_edit_notices ) %] -
    Notices
    +
    Notices & Slips
    Define notices (print and email notification messages for overdues, etc.)
    [% END %] diff --git a/members/memberentry.pl b/members/memberentry.pl index 6de07bf..20f1cf0 100755 --- a/members/memberentry.pl +++ b/members/memberentry.pl @@ -345,10 +345,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" ); } } diff --git a/members/moremember.pl b/members/moremember.pl index 6e5407c..9277deb 100755 --- a/members/moremember.pl +++ b/members/moremember.pl @@ -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); @@ -483,13 +482,4 @@ $template->param( quickslip => $quickslip, ); -#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; diff --git a/members/printslip.pl b/members/printslip.pl new file mode 100755 index 0000000..91a3c34 --- /dev/null +++ b/members/printslip.pl @@ -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 at katipo.co.nz + last modified 21/1/2000 by chris at katipo.co.nz + modified 31/1/2001 by chris at 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; +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; diff --git a/misc/cronjobs/advance_notices.pl b/misc/cronjobs/advance_notices.pl index 1fa358f..09c4017 100755 --- a/misc/cronjobs/advance_notices.pl +++ b/misc/cronjobs/advance_notices.pl @@ -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 EEitems.contentEE 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", at 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", at 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", at 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", at 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; - } - } - - C4::Letters::parseletter( $params->{'letter'}, 'borrowers', $params->{'borrowernumber'} ); + my %table_params = ( 'borrowers' => $params->{'borrowernumber'} ); - if ( $params->{'branchcode'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'branches', $params->{'branchcode'} ); + if ( my $p = $params->{'branchcode'} ) { + $table_params{'branches'} = $p; } - if ( $params->{'itemnumber'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'issues', $params->{'itemnumber'} ); - C4::Letters::parseletter( $params->{'letter'}, 'items', $params->{'itemnumber'} ); + if ( my $p = $params->{'itemnumber'} ) { + $table_params{'issues'} = $p; + $table_params{'items'} = $p; } - if ( $params->{'biblionumber'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'biblio', $params->{'biblionumber'} ); - C4::Letters::parseletter( $params->{'letter'}, 'biblioitems', $params->{'biblionumber'} ); + if ( my $p = $params->{'biblionumber'} ) { + $table_params{'biblio'} = $p; + $table_params{'biblioitems'} = $p; } - 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; diff --git a/misc/cronjobs/gather_print_notices.pl b/misc/cronjobs/gather_print_notices.pl index a72d6a6..165b16e 100755 --- a/misc/cronjobs/gather_print_notices.pl +++ b/misc/cronjobs/gather_print_notices.pl @@ -39,11 +39,9 @@ use Getopt::Long; sub usage { print STDERR < \$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_contents .= $_ } - close STYLESHEET; -} $template->param( - stylesheet => $stylesheet_contents, + stylesheet => C4::Context->preference("NoticeCSS"), today => $today->output(), messages => \@messages, ); diff --git a/misc/cronjobs/overdue_notices.pl b/misc/cronjobs/overdue_notices.pl index 71e6a05..93061b4 100755 --- a/misc/cronjobs/overdue_notices.pl +++ b/misc/cronjobs/overdue_notices.pl @@ -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/<>/$todaysdate/g; - $params->{'letter'}->{content} =~ s/<>/$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>/o) { # process any fine tags... + $currency_format = $1; + $params->{'letter'}->{'content'} =~ s/.*<\/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_format = $1; } - if ($params->{'letter'}->{'content'} =~ m/(.*)<\/fine>/) { # process any fine tags... - my $formatted_fine = currency_format("$1", "$fine", FMT_SYMBOL); - $params->{'letter'}->{'content'} =~ s/.*<\/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>)/$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 diff --git a/t/db_dependent/lib/KohaTest/Letters.pm b/t/db_dependent/lib/KohaTest/Letters.pm index 97d58fb..f2d7b0d 100644 --- a/t/db_dependent/lib/KohaTest/Letters.pm +++ b/t/db_dependent/lib/KohaTest/Letters.pm @@ -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 ); diff --git a/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm b/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm index 76b6ab4..53e5439 100644 --- a/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm +++ b/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm @@ -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; diff --git a/t/db_dependent/lib/KohaTest/Members.pm b/t/db_dependent/lib/KohaTest/Members.pm index 5646be1..dfde7da 100644 --- a/t/db_dependent/lib/KohaTest/Members.pm +++ b/t/db_dependent/lib/KohaTest/Members.pm @@ -52,6 +52,7 @@ sub methods : Test( 1 ) { GetBorrowersWhoHaveNeverBorrowed GetBorrowersWithIssuesHistoryOlderThan GetBorrowersNamesAndLatestIssue + IssueSlip ); can_ok( $self->testing_class, @methods ); diff --git a/t/db_dependent/lib/KohaTest/Print.pm b/t/db_dependent/lib/KohaTest/Print.pm index 02fd5fb..d35ab34 100644 --- a/t/db_dependent/lib/KohaTest/Print.pm +++ b/t/db_dependent/lib/KohaTest/Print.pm @@ -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 ); } diff --git a/t/db_dependent/lib/KohaTest/Reserves.pm b/t/db_dependent/lib/KohaTest/Reserves.pm index 8b05dd0..6416ac3 100644 --- a/t/db_dependent/lib/KohaTest/Reserves.pm +++ b/t/db_dependent/lib/KohaTest/Reserves.pm @@ -33,6 +33,7 @@ sub methods : Test( 1 ) { GetReserveInfo _FixPriority _Findgroupreserve + ReserveSlip ); can_ok( $self->testing_class, @methods ); diff --git a/tools/letter.pl b/tools/letter.pl index f5dc0c6..6188a9e 100755 --- a/tools/letter.pl +++ b/tools/letter.pl @@ -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,14 +88,12 @@ 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( { @@ -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") + ? 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; } -- 1.6.5 From adrien.saurat at biblibre.com Fri Jan 13 14:45:53 2012 From: adrien.saurat at biblibre.com (Adrien Saurat) Date: Fri, 13 Jan 2012 14:45:53 +0100 Subject: [Koha-patches] [PATCH] Bug 7442: Corrects selection of authorities Message-ID: <1326462353-11139-1-git-send-email-adrien.saurat@biblibre.com> When editing a biblio record, if an authority is searched the generated links now behave correctly (if 200$x or 200$y exist they won't have their own link). --- authorities/auth_finder.pl | 25 ++++++++++++++++--------- 1 files changed, 16 insertions(+), 9 deletions(-) diff --git a/authorities/auth_finder.pl b/authorities/auth_finder.pl index 99ac2c1..6a2b052 100755 --- a/authorities/auth_finder.pl +++ b/authorities/auth_finder.pl @@ -72,16 +72,23 @@ if ( $op eq "do_search" ) { $resultsperpage, $authtypecode, $orderby); # If an authority heading is repeated, add an arrayref to those repetions - # First heading -- Second heading for my $heading ( @$results ) { - my @repets = split / -- /, $heading->{summary}; - if ( @repets > 1 ) { - my @repets_loop; - for (my $i = 0; $i < @repets; $i++) { - push @repets_loop, - { index => $index, repet => $i+1, value => $repets[$i] }; - } - $heading->{repets} = \@repets_loop; + my $record = GetAuthority($heading->{'authid'}); + my $auth_name = ''; # will be displayed in the link tooltip + my $cpt = 0; + my @repets_loop; + foreach my $field ($record->field('200')) { + $auth_name = $field->subfield('a'); + if ($field->subfield('b')) { $auth_name .= ', ' . $field->subfield('b') } + $cpt++; + push @repets_loop, + { index => $index, repet => $cpt, value => $auth_name }; + } + if ( $cpt < 2 ) { + undef @repets_loop; + } + else { + $heading->{repets} = \@repets_loop } } # multi page display gestion -- 1.7.4.1 From adrien.saurat at biblibre.com Fri Jan 13 16:49:50 2012 From: adrien.saurat at biblibre.com (Adrien Saurat) Date: Fri, 13 Jan 2012 16:49:50 +0100 Subject: [Koha-patches] [PATCH] Bug 7434: display of serialseq in overdue report Message-ID: <1326469790-14579-1-git-send-email-adrien.saurat@biblibre.com> If the number of a serial is stored in serial.serialseq, it will be now displayer after the author name in the overdues report. --- circ/overdue.pl | 6 +++++- .../intranet-tmpl/prog/en/modules/circ/overdue.tt | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/circ/overdue.pl b/circ/overdue.pl index e59961a..a894454 100755 --- a/circ/overdue.pl +++ b/circ/overdue.pl @@ -256,12 +256,15 @@ if ($noreport) { biblio.biblionumber, borrowers.branchcode, items.itemcallnumber, - items.replacementprice + items.replacementprice, + serial.serialseq FROM issues LEFT JOIN borrowers ON (issues.borrowernumber=borrowers.borrowernumber ) LEFT JOIN items ON (issues.itemnumber=items.itemnumber) LEFT JOIN biblioitems ON (biblioitems.biblioitemnumber=items.biblioitemnumber) LEFT JOIN biblio ON (biblio.biblionumber=items.biblionumber ) + LEFT JOIN serialitems ON (serialitems.itemnumber = items.itemnumber) + LEFT JOIN serial ON (serial.serialid = serialitems.serialid) WHERE 1=1 "; # placeholder, since it is possible that none of the additional # conditions will be selected by user $strsth.=" AND date_due < '" . $todaysdate . "' " unless ($showall); @@ -334,6 +337,7 @@ if ($noreport) { branchcode => $data->{branchcode}, itemcallnumber => $data->{itemcallnumber}, replacementprice => $data->{replacementprice}, + serialseq => $data->{serialseq}, patron_attr_value_loop => \@patron_attr_value_loop, }; } diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/overdue.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/overdue.tt index e196399..78d73b6 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/overdue.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/overdue.tt @@ -120,7 +120,7 @@ [% IF ( overdueloo.email ) %][email][% END %] [% IF ( overdueloo.phone ) %]([% overdueloo.phone %])[% ELSIF ( overdueloo.mobile ) %]([% overdueloo.mobile %])[% ELSIF ( overdueloo.phonepro ) %]([% overdueloo.phonepro %])[% END %] [% overdueloo.branchcode %] - [% INCLUDE 'biblio-default-view.inc' biblionumber = overdueloo.biblionumber %][% overdueloo.title |html %] [% overdueloo.subtitle %] [% IF ( overdueloo.author ) %], by [% overdueloo.author %][% END %] + [% INCLUDE 'biblio-default-view.inc' biblionumber = overdueloo.biblionumber %][% overdueloo.title |html %] [% overdueloo.subtitle %] [% IF ( overdueloo.author ) %], by [% overdueloo.author %][% END %][% IF ( overdueloo.serialseq ) %], [% overdueloo.serialseq %][% END %] [% overdueloo.barcode %] [% overdueloo.itemcallnumber %] -- 1.7.4.1 From julian.maurice at biblibre.com Fri Jan 13 17:13:34 2012 From: julian.maurice at biblibre.com (julian.maurice at biblibre.com) Date: Fri, 13 Jan 2012 17:13:34 +0100 Subject: [Koha-patches] [PATCH 1/2] Bug 7175: orderreceive.pl cosmetic changes Message-ID: <1326471215-20191-1-git-send-email-julian.maurice@biblibre.com> From: Julian Maurice - use warnings - replace @$results[0] by $order when $count == 1 --- acqui/orderreceive.pl | 59 +++++++++++++++++++++--------------------------- 1 files changed, 26 insertions(+), 33 deletions(-) diff --git a/acqui/orderreceive.pl b/acqui/orderreceive.pl index 753071d..dc03a1d 100755 --- a/acqui/orderreceive.pl +++ b/acqui/orderreceive.pl @@ -61,7 +61,8 @@ The biblionumber of this order. =cut use strict; -#use warnings; FIXME - Bug 2505 +use warnings; + use CGI; use C4::Context; use C4::Koha; # GetKohaAuthorisedValues GetItemTypes @@ -81,7 +82,7 @@ my $input = new CGI; my $dbh = C4::Context->dbh; my $supplierid = $input->param('supplierid'); -my $ordernumber = $input->param('ordernumber'); +my $ordernumber = $input->param('ordernumber'); my $search = $input->param('receive'); my $invoice = $input->param('invoice'); my $freight = $input->param('freight'); @@ -95,13 +96,6 @@ my $input_gst = ($input->param('gst') eq '' ? undef : $input->param('gst')); my $gst= $input_gst // $bookseller->{gstrate} // C4::Context->preference("gist") // 0; my $results = SearchOrder($ordernumber,$search); - -my $count = scalar @$results; -my $order = GetOrder($ordernumber); - - -my $date = @$results[0]->{'entrydate'}; - my ( $template, $loggedinuser, $cookie ) = get_template_and_user( { template_name => "acqui/orderreceive.tmpl", @@ -113,8 +107,10 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user( } ); +my $count = scalar @$results; # prepare the form for receiving if ( $count == 1 ) { + my $order = $results->[0]; if (C4::Context->preference('AcqCreateItem') eq 'receiving') { # prepare empty item form my $cell = PrepareItemrecordDisplay('','','','ACQ'); @@ -128,40 +124,37 @@ if ( $count == 1 ) { $template->param(items => \@itemloop); } - if ( @$results[0]->{'quantityreceived'} == 0 ) { - @$results[0]->{'quantityreceived'} = ''; - } - if ( @$results[0]->{'unitprice'} == 0 ) { - @$results[0]->{'unitprice'} = ''; + if ( $order->{'unitprice'} == 0 ) { + $order->{'unitprice'} = ''; } - my $authorisedby = @$results[0]->{'authorisedby'}; + my $authorisedby = $order->{'authorisedby'}; my $member = GetMember( borrowernumber => $authorisedby ); - my $budget = GetBudget( @$results[0]->{'budget_id'} ); + my $budget = GetBudget( $order->{'budget_id'} ); $template->param( count => 1, - biblionumber => @$results[0]->{'biblionumber'}, - ordernumber => @$results[0]->{'ordernumber'}, - biblioitemnumber => @$results[0]->{'biblioitemnumber'}, - supplierid => @$results[0]->{'booksellerid'}, + biblionumber => $order->{'biblionumber'}, + ordernumber => $order->{'ordernumber'}, + biblioitemnumber => $order->{'biblioitemnumber'}, + supplierid => $order->{'booksellerid'}, freight => $freight, gst => $gst, name => $bookseller->{'name'}, - date => format_date($date), - title => @$results[0]->{'title'}, - author => @$results[0]->{'author'}, - copyrightdate => @$results[0]->{'copyrightdate'}, - isbn => @$results[0]->{'isbn'}, - seriestitle => @$results[0]->{'seriestitle'}, + date => format_date($order->{entrydate}), + title => $order->{'title'}, + author => $order->{'author'}, + copyrightdate => $order->{'copyrightdate'}, + isbn => $order->{'isbn'}, + seriestitle => $order->{'seriestitle'}, bookfund => $budget->{budget_name}, - quantity => @$results[0]->{'quantity'}, - quantityreceivedplus1 => @$results[0]->{'quantityreceived'} + 1, - quantityreceived => @$results[0]->{'quantityreceived'}, - rrp => @$results[0]->{'rrp'}, - ecost => @$results[0]->{'ecost'}, - unitprice => @$results[0]->{'unitprice'}, + quantity => $order->{'quantity'}, + quantityreceivedplus1 => $order->{'quantityreceived'} + 1, + quantityreceived => $order->{'quantityreceived'}, + rrp => $order->{'rrp'}, + ecost => $order->{'ecost'}, + unitprice => $order->{'unitprice'}, memberfirstname => $member->{firstname} || "", membersurname => $member->{surname} || "", invoice => $invoice, @@ -191,7 +184,7 @@ else { ); } my $op = $input->param('op'); -if ($op eq 'edit'){ +if ($op and $op eq 'edit'){ $template->param(edit => 1); } output_html_with_http_headers $input, $cookie, $template->output; -- 1.7.8.3 From julian.maurice at biblibre.com Fri Jan 13 17:13:35 2012 From: julian.maurice at biblibre.com (julian.maurice at biblibre.com) Date: Fri, 13 Jan 2012 17:13:35 +0100 Subject: [Koha-patches] [PATCH 2/2] Bug 7175: Allow to choose which items to receive In-Reply-To: <1326471215-20191-1-git-send-email-julian.maurice@biblibre.com> References: <1326471215-20191-1-git-send-email-julian.maurice@biblibre.com> Message-ID: <1326471215-20191-2-git-send-email-julian.maurice@biblibre.com> From: Julian Maurice If AcqCreateItem=ordering, when you receive an order, you now have a list of all created items and checkboxes that permit you to choose which items you want to receive. A 'Edit' link open additem.pl page in a popup to allow you edit the items before receiving them (popup is automatically closed after modification, and orderreceive.pl page is reloaded to show modifications) --- C4/Acquisition.pm | 41 ++++++++++- acqui/finishreceive.pl | 13 +++- acqui/orderreceive.pl | 15 +++- cataloguing/additem.pl | 1 + .../prog/en/modules/acqui/orderreceive.tt | 75 +++++++++++++++++--- .../prog/en/modules/cataloguing/additem.tt | 9 +++ 6 files changed, 132 insertions(+), 22 deletions(-) diff --git a/C4/Acquisition.pm b/C4/Acquisition.pm index 2814977..ac0bde0 100644 --- a/C4/Acquisition.pm +++ b/C4/Acquisition.pm @@ -56,7 +56,7 @@ BEGIN { &ModReceiveOrder &ModOrderBiblioitemNumber &GetCancelledOrders - &NewOrderItem &ModOrderItem + &NewOrderItem &ModOrderItem &ModItemOrder &GetParcels &GetParcel &GetContracts &GetContract @@ -1017,6 +1017,29 @@ sub ModOrderItem { return 0; } +=head3 ModItemOrder + + ModItemOrder($itemnumber, $ordernumber); + +Modifies the ordernumber of an item in aqorders_items. + +=cut + +sub ModItemOrder { + my ($itemnumber, $ordernumber) = @_; + + return unless ($itemnumber and $ordernumber); + + my $dbh = C4::Context->dbh; + my $query = qq{ + UPDATE aqorders_items + SET ordernumber = ? + WHERE itemnumber = ? + }; + my $sth = $dbh->prepare($query); + return $sth->execute($ordernumber, $itemnumber); +} + #------------------------------------------------------------# @@ -1102,7 +1125,7 @@ C<$ordernumber>. sub ModReceiveOrder { my ( $biblionumber, $ordernumber, $quantrec, $user, $cost, - $invoiceno, $freight, $rrp, $budget_id, $datereceived + $invoiceno, $freight, $rrp, $budget_id, $datereceived, $received_items ) = @_; my $dbh = C4::Context->dbh; @@ -1148,7 +1171,19 @@ sub ModReceiveOrder { $order->{'quantity'} -= $quantrec; $order->{'quantityreceived'} = 0; my $newOrder = NewOrder($order); -} else { + # Change ordernumber in aqorders_items for items not received + my @orderitems = GetItemnumbersFromOrder( $order->{'ordernumber'} ); + my $count = scalar @orderitems; + + for (my $i=0; $i<$count; $i++){ + foreach (@$received_items){ + splice (@orderitems, $i, 1) if ($orderitems[$i] == $_); + } + } + foreach (@orderitems) { + ModItemOrder($_, $newOrder); + } + } else { $sth=$dbh->prepare("update aqorders set quantityreceived=?,datereceived=?,booksellerinvoicenumber=?, unitprice=?,freight=?,rrp=? diff --git a/acqui/finishreceive.pl b/acqui/finishreceive.pl index 71b13d6..25e6e63 100755 --- a/acqui/finishreceive.pl +++ b/acqui/finishreceive.pl @@ -108,10 +108,15 @@ if ($quantityrec > $origquantityrec ) { my ($biblionumber,$bibitemnum,$itemnumber) = AddItemFromMarc($record,$biblionumber); } } - + + my @received_items = (); + if(C4::Context->preference('AcqCreateItem') eq 'ordering') { + @received_items = $input->param('items_to_receive'); + } + # save the quantity received. - if( $quantityrec > 0 ) { - $datereceived = ModReceiveOrder($biblionumber,$ordernumber, $quantityrec ,$user,$unitprice,$invoiceno,$freight,$replacement,undef,$datereceived); - } + if( $quantityrec > 0 ) { + $datereceived = ModReceiveOrder($biblionumber,$ordernumber, $quantityrec ,$user,$unitprice,$invoiceno,$freight,$replacement,undef,$datereceived, \@received_items); + } } print $input->redirect("/cgi-bin/koha/acqui/parcel.pl?invoice=$invoiceno&supplierid=$supplierid&freight=$freight&gst=$gst&datereceived=$datereceived$error_url_str"); diff --git a/acqui/orderreceive.pl b/acqui/orderreceive.pl index dc03a1d..c4bab7f 100755 --- a/acqui/orderreceive.pl +++ b/acqui/orderreceive.pl @@ -111,17 +111,23 @@ my $count = scalar @$results; # prepare the form for receiving if ( $count == 1 ) { my $order = $results->[0]; - if (C4::Context->preference('AcqCreateItem') eq 'receiving') { + my $AcqCreateItem = C4::Context->preference('AcqCreateItem'); + if ($AcqCreateItem eq 'receiving') { # prepare empty item form my $cell = PrepareItemrecordDisplay('','','','ACQ'); unless ($cell) { $cell = PrepareItemrecordDisplay('','','',''); $template->param('NoACQframework' => 1); } - my @itemloop; - push @itemloop,$cell; - $template->param(items => \@itemloop); + $template->param(itemform => $cell); + } elsif ($AcqCreateItem eq 'ordering') { + my @itemnumbers = GetItemnumbersFromOrder($order->{ordernumber}); + my @items; + foreach (@itemnumbers) { + push @items, GetItem($_); + } + $template->param(items => \@items); } if ( $order->{'unitprice'} == 0 ) { @@ -134,6 +140,7 @@ if ( $count == 1 ) { my $budget = GetBudget( $order->{'budget_id'} ); $template->param( + AcqCreateItem => $AcqCreateItem, count => 1, biblionumber => $order->{'biblionumber'}, ordernumber => $order->{'ordernumber'}, diff --git a/cataloguing/additem.pl b/cataloguing/additem.pl index a734d0f..089550b 100755 --- a/cataloguing/additem.pl +++ b/cataloguing/additem.pl @@ -729,6 +729,7 @@ $template->param( itemtagsubfield => $itemtagsubfield, op => $nextop, opisadd => ($nextop eq "saveitem") ? 0 : 1, + popup => $input->param('popup') ? 1: 0, C4::Search::enabled_staff_search_views, ); diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt index ea422c8..aac58ea 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt @@ -2,6 +2,31 @@ Koha › Acquisitions › Receipt summary for : [% name %] [% IF ( invoice ) %]invoice, [% invoice %][% END %] [% INCLUDE 'doc-head-close.inc' %] + [% INCLUDE 'header.inc' %] @@ -35,17 +60,46 @@ [% seriestitle %] - [% IF ( items ) %] + [% IF (AcqCreateItem == 'ordering') %] + [% IF (items.size) %] +
    + Items + + + + + + + + + + + + + [% FOREACH item IN items %] + + + + + + + + + [% END %] + +
    Receive?BarcodeHome branchLocationCall number 
    [% item.barcode %][% item.homebranch %][% item.location %][% item.itemcallnumber %]Edit
    +
    + [% END %] + [% ELSIF (AcqCreateItem == 'receiving') %]
    Item [% IF ( NoACQframework ) %]

    No ACQ framework, using default. You should create a framework with code ACQ, the items framework would be used

    [% END %] - [% FOREACH item IN items %]
    -
      [% FOREACH iteminformatio IN item.iteminformation %]
    1. +
        [% FOREACH iteminformatio IN itemform.iteminformation %]
      1. @@ -62,21 +116,20 @@
      2. [% END %]
      - Add - + Add +
    - - - - + + + + - + [% END %]
    - [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt index 673b08b..7454129 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt @@ -4,6 +4,12 @@ - -
    - -[% FOREACH reservedat IN reservedata %] - -
    Date: [% reservedat.pulldate %]
    -

    [% IF ( reservedat.transferrequired ) %]Transfer to [% reservedat.branchname %] [% ELSE %]Hold in [% reservedat.branchname %][% END %]

    - -
    - -

    [% reservedat.surname %], [% reservedat.firstname %]

    - -
      -
    • [% reservedat.cardnumber %]
    • - [% IF ( reservedat.phone ) %] -
    • [% reservedat.phone %]
    • - [% END %] -
    • - [% reservedat.address %]
      - [% IF ( reservedat.address2 ) %][% reservedat.address2 %]
      [% END %] - [% reservedat.city %] [% reservedat.zip %] -
    • - [% IF ( reservedat.email ) %] -
    • [% reservedat.email %]
    • - [% END %] -
    -
    -

    ITEM ON HOLD

    -

    [% reservedat.title |html %]

    -
    [% reservedat.author %]
    -
      - [% IF ( reservedat.barcode ) %]
    • [% reservedat.barcode %]
    • [% END %] - [% IF ( reservedat.itemcallnumber ) %]
    • [% reservedat.itemcallnumber %]
    • [% END %] - [% IF ( reservedat.waitingdate ) %]
    • [% reservedat.waitingdate %]
    • [% END %] -
    - [% IF ( reservedat.reservenotes ) %] -

    Notes: [% reservedat.reservenotes %]

    - [% END %] - - - -[% END %] -
    -[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt new file mode 100644 index 0000000..a790069 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt @@ -0,0 +1,28 @@ +[% INCLUDE 'doc-head-open.inc' %] +[% title %] + + + +[% IF stylesheet %] + +[% END %] + + + + +
    + +[% IF plain %] +
    +[% slip %]
    +
    +[% ELSE %] +[% slip %] +[% END %] + +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt deleted file mode 100644 index 4a85ccb..0000000 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt +++ /dev/null @@ -1,76 +0,0 @@ -[% INCLUDE 'doc-head-open.inc' %] -Print Receipt for [% cardnumber %] - - - - - - - - -
    - -

    [% LibraryName %]

    -[% IF ( branchname ) %][% branchname %]
    [% END %] -Checked out to [% firstname %] [% surname %]
    -([% cardnumber %])
    - -[% todaysdate %]
    - -[% IF ( quickslip ) %] -

    Checked Out Today

    -[% FOREACH issueloo IN issueloop %] -[% IF ( issueloo.red ) %][% ELSE %] -[% IF ( issueloo.today ) %] -

    [% issueloo.title |html %]
    -Barcode: [% issueloo.barcode %]
    -Date due: [% issueloo.date_due %]

    - [% END %] - [% END %] - [% END %] - -[% ELSE %] -

    Checked Out

    -[% FOREACH issueloo IN issueloop %] -[% IF ( issueloo.red ) %][% ELSE %] -

    [% issueloo.title |html %]
    -Barcode: [% issueloo.barcode %]
    -Date due: [% issueloo.date_due %]

    - [% END %] - [% END %] - -[% END %] - -[% IF ( quickslip ) %] -[% ELSE %] -[% IF ( overdues_exist ) %] -

    Overdues

    - [% FOREACH issueloo IN issueloop %] - [% IF ( issueloo.red ) %] -

    [% issueloo.title |html %]
    -Barcode: [% issueloo.barcode %]
    -Date due: [% issueloo.date_due %]

    -[% END %] -[% END %] -[% END %] -[% END %] - -[% IF ( koha_news_count ) %] -

    News

    - - [% FOREACH koha_new IN koha_news %] -
    [% koha_new.title %]
    -

    [% koha_new.new %]

    -

    Posted on [% koha_new.newdate %] - -


    - [% END %] -[% END %] - - -[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt index 063236e..8e12d05 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt @@ -5,14 +5,29 @@ -
    - +[% IF ( no_op_set ) %] +
    + + [% UNLESS independant_branch %] +

    + Select a library : + +

    + [% END %] +

    + + +

    +
    + [% IF ( search ) %]

    You Searched for [% searchfield %]

    [% END %] - [% IF ( letter ) %] + [% IF ( letter && !independant_branch) %] + [% select_for_copy = BLOCK %] + + [% END %] + [% END %] +
    + + - [% FOREACH lette IN letter %] - [% UNLESS ( loop.odd ) %] + + [% FOREACH lette IN letter %] + [% can_edit = lette.branchcode || !independant_branch %] + [% UNLESS ( loop.odd ) %] - [% ELSE %] + [% ELSE %] - [% END %] + [% END %] + + - [% END %] + [% END %] +
    Branch Module Code Name     
    [% lette.branchname || "(All libraries)" %] [% lette.module %] [% lette.code %] [% lette.name %] - Edit + [% IF can_edit %] + Edit + [% END %] + + [% IF !independant_branch || !lette.branchcode %] +
    + + + + + [% IF independant_branch %] + + [% ELSE %] + [% select_for_copy %] + [% END %] + +
    + [% END %]
    - [% IF ( lette.protected ) %] - - - [% ELSE %] - Delete - [% END %] + [% IF !lette.protected && can_edit %] + Delete + [% END %]
    - [% END %] +[% END %] - [% END %] - [% IF ( add_form ) %] +[% IF ( add_form ) %] -
    - + + [% IF ( modify ) %] @@ -182,6 +229,20 @@ $(document).ready(function() {
    [% IF ( modify ) %]Modify notice[% ELSE %]Add notice[% END %]
      + + [% IF independant_branch %] + + [% ELSE %] +
    1. + + +
    2. + [% END %]
    3. @@ -235,6 +296,9 @@ $(document).ready(function() {
    4. + +
    5. +
    6. @@ -252,27 +316,31 @@ $(document).ready(function() {
    +
    +
    - [% END %] +[% END %] - [% IF ( add_validate ) %] +[% IF ( add_validate ) %] Data recorded
    - [% END %] +[% END %] - [% IF ( delete_confirm ) %] +[% IF ( delete_confirm ) %]

    Delete Notice?

    + + @@ -280,6 +348,7 @@ $(document).ready(function() {
    Branch Module Code Name
    [% branchname %] [% module %] [% code %] [% name %]
    + @@ -290,14 +359,14 @@ $(document).ready(function() {
    - [% END %] +[% END %] - [% IF ( delete_confirmed ) %] +[% IF ( delete_confirmed ) %] Data deleted
    - [% END %] +[% END %]
    diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt index 05bdb47..e06b607 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt @@ -26,7 +26,7 @@ [% END %] [% IF ( CAN_user_tools_edit_notices ) %] -
    Notices
    +
    Notices & Slips
    Define notices (print and email notification messages for overdues, etc.)
    [% END %] diff --git a/members/memberentry.pl b/members/memberentry.pl index 6de07bf..20f1cf0 100755 --- a/members/memberentry.pl +++ b/members/memberentry.pl @@ -345,10 +345,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" ); } } diff --git a/members/moremember.pl b/members/moremember.pl index 6e5407c..9277deb 100755 --- a/members/moremember.pl +++ b/members/moremember.pl @@ -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); @@ -483,13 +482,4 @@ $template->param( quickslip => $quickslip, ); -#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; diff --git a/members/printslip.pl b/members/printslip.pl new file mode 100755 index 0000000..3a499cd --- /dev/null +++ b/members/printslip.pl @@ -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 at katipo.co.nz + last modified 21/1/2000 by chris at katipo.co.nz + modified 31/1/2001 by chris at 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; diff --git a/misc/cronjobs/advance_notices.pl b/misc/cronjobs/advance_notices.pl index 1fa358f..09c4017 100755 --- a/misc/cronjobs/advance_notices.pl +++ b/misc/cronjobs/advance_notices.pl @@ -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 EEitems.contentEE 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", at 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", at 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", at 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", at 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; - } - } - - C4::Letters::parseletter( $params->{'letter'}, 'borrowers', $params->{'borrowernumber'} ); + my %table_params = ( 'borrowers' => $params->{'borrowernumber'} ); - if ( $params->{'branchcode'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'branches', $params->{'branchcode'} ); + if ( my $p = $params->{'branchcode'} ) { + $table_params{'branches'} = $p; } - if ( $params->{'itemnumber'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'issues', $params->{'itemnumber'} ); - C4::Letters::parseletter( $params->{'letter'}, 'items', $params->{'itemnumber'} ); + if ( my $p = $params->{'itemnumber'} ) { + $table_params{'issues'} = $p; + $table_params{'items'} = $p; } - if ( $params->{'biblionumber'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'biblio', $params->{'biblionumber'} ); - C4::Letters::parseletter( $params->{'letter'}, 'biblioitems', $params->{'biblionumber'} ); + if ( my $p = $params->{'biblionumber'} ) { + $table_params{'biblio'} = $p; + $table_params{'biblioitems'} = $p; } - 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; diff --git a/misc/cronjobs/gather_print_notices.pl b/misc/cronjobs/gather_print_notices.pl index a72d6a6..165b16e 100755 --- a/misc/cronjobs/gather_print_notices.pl +++ b/misc/cronjobs/gather_print_notices.pl @@ -39,11 +39,9 @@ use Getopt::Long; sub usage { print STDERR < \$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_contents .= $_ } - close STYLESHEET; -} $template->param( - stylesheet => $stylesheet_contents, + stylesheet => C4::Context->preference("NoticeCSS"), today => $today->output(), messages => \@messages, ); diff --git a/misc/cronjobs/overdue_notices.pl b/misc/cronjobs/overdue_notices.pl index 71e6a05..93061b4 100755 --- a/misc/cronjobs/overdue_notices.pl +++ b/misc/cronjobs/overdue_notices.pl @@ -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/<>/$todaysdate/g; - $params->{'letter'}->{content} =~ s/<>/$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>/o) { # process any fine tags... + $currency_format = $1; + $params->{'letter'}->{'content'} =~ s/.*<\/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_format = $1; } - if ($params->{'letter'}->{'content'} =~ m/(.*)<\/fine>/) { # process any fine tags... - my $formatted_fine = currency_format("$1", "$fine", FMT_SYMBOL); - $params->{'letter'}->{'content'} =~ s/.*<\/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>)/$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 diff --git a/t/db_dependent/lib/KohaTest/Letters.pm b/t/db_dependent/lib/KohaTest/Letters.pm index 97d58fb..f2d7b0d 100644 --- a/t/db_dependent/lib/KohaTest/Letters.pm +++ b/t/db_dependent/lib/KohaTest/Letters.pm @@ -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 ); diff --git a/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm b/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm index 76b6ab4..53e5439 100644 --- a/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm +++ b/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm @@ -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; diff --git a/t/db_dependent/lib/KohaTest/Members.pm b/t/db_dependent/lib/KohaTest/Members.pm index 5646be1..dfde7da 100644 --- a/t/db_dependent/lib/KohaTest/Members.pm +++ b/t/db_dependent/lib/KohaTest/Members.pm @@ -52,6 +52,7 @@ sub methods : Test( 1 ) { GetBorrowersWhoHaveNeverBorrowed GetBorrowersWithIssuesHistoryOlderThan GetBorrowersNamesAndLatestIssue + IssueSlip ); can_ok( $self->testing_class, @methods ); diff --git a/t/db_dependent/lib/KohaTest/Print.pm b/t/db_dependent/lib/KohaTest/Print.pm index 02fd5fb..d35ab34 100644 --- a/t/db_dependent/lib/KohaTest/Print.pm +++ b/t/db_dependent/lib/KohaTest/Print.pm @@ -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 ); } diff --git a/t/db_dependent/lib/KohaTest/Reserves.pm b/t/db_dependent/lib/KohaTest/Reserves.pm index 8b05dd0..6416ac3 100644 --- a/t/db_dependent/lib/KohaTest/Reserves.pm +++ b/t/db_dependent/lib/KohaTest/Reserves.pm @@ -33,6 +33,7 @@ sub methods : Test( 1 ) { GetReserveInfo _FixPriority _Findgroupreserve + ReserveSlip ); can_ok( $self->testing_class, @methods ); diff --git a/tools/letter.pl b/tools/letter.pl index f5dc0c6..6188a9e 100755 --- a/tools/letter.pl +++ b/tools/letter.pl @@ -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,14 +88,12 @@ 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( { @@ -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") + ? 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; } -- 1.6.5 From srdjan at catalyst.net.nz Mon Jan 16 08:00:06 2012 From: srdjan at catalyst.net.nz (Srdjan Jankovic) Date: Mon, 16 Jan 2012 20:00:06 +1300 Subject: [Koha-patches] [PATCH] bug_7001: Issue and Reserve slips are notices. In-Reply-To: References: Message-ID: <1326697206-7008-1-git-send-email-srdjan@catalyst.net.nz> 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. --- C4/Circulation.pm | 20 +- C4/Letters.pm | 583 +++++++++++++------- C4/Members.pm | 81 +++- C4/Members/Attributes.pm | 18 + C4/Message.pm | 12 +- C4/Print.pm | 146 ++---- C4/Reserves.pm | 103 +++-- C4/Suggestions.pm | 22 +- acqui/booksellers.pl | 7 +- circ/circulation.pl | 3 +- circ/hold-transfer-slip.pl | 32 +- .../data/mysql/de-DE/mandatory/sample_notices.sql | 2 +- .../data/mysql/en/mandatory/sample_notices.sql | 84 +++- .../data/mysql/es-ES/mandatory/sample_notices.sql | 2 +- .../mysql/fr-FR/1-Obligatoire/sample_notices.sql | 2 +- installer/data/mysql/it-IT/necessari/notices.sql | 2 +- installer/data/mysql/kohastructure.sql | 7 +- .../mysql/nb-NO/1-Obligatorisk/sample_notices.sql | 2 +- .../data/mysql/pl-PL/mandatory/sample_notices.sql | 2 +- .../data/mysql/ru-RU/mandatory/sample_notices.sql | 2 +- installer/data/mysql/sysprefs.sql | 3 + .../data/mysql/uk-UA/mandatory/sample_notices.sql | 2 +- installer/data/mysql/updatedatabase.pl | 99 ++++- .../prog/en/includes/circ-toolbar.inc | 4 +- .../en/modules/admin/preferences/circulation.pref | 5 + .../en/modules/admin/preferences/staff_client.pref | 5 + .../prog/en/modules/batch/print-notices.tt | 6 +- .../prog/en/modules/circ/hold-transfer-slip.tt | 54 -- .../prog/en/modules/circ/printslip.tt | 28 + .../prog/en/modules/members/moremember-receipt.tt | 76 --- .../intranet-tmpl/prog/en/modules/tools/letter.tt | 157 ++++-- .../prog/en/modules/tools/tools-home.tt | 2 +- members/memberentry.pl | 5 +- members/moremember.pl | 10 - members/printslip.pl | 92 +++ misc/cronjobs/advance_notices.pl | 78 ++-- misc/cronjobs/gather_print_notices.pl | 14 +- misc/cronjobs/overdue_notices.pl | 86 ++-- t/db_dependent/lib/KohaTest/Letters.pm | 5 +- t/db_dependent/lib/KohaTest/Letters/GetLetter.pm | 3 +- t/db_dependent/lib/KohaTest/Members.pm | 1 + t/db_dependent/lib/KohaTest/Print.pm | 5 +- t/db_dependent/lib/KohaTest/Reserves.pm | 1 + tools/letter.pl | 228 ++++++--- 44 files changed, 1326 insertions(+), 775 deletions(-) delete mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/circ/hold-transfer-slip.tt create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt delete mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt create mode 100755 members/printslip.pl diff --git a/C4/Circulation.pm b/C4/Circulation.pm index 9a6f4f2..cff3fa7 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -2655,11 +2655,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) { @@ -2674,7 +2681,8 @@ sub SendCirculationAlert { $message->update; } } - $letter; + + return $letter; } =head2 updateWrongTransfer diff --git a/C4/Letters.pm b/C4/Letters.pm index 2420e4a..7f195d6 100644 --- a/C4/Letters.pm +++ b/C4/Letters.pm @@ -26,6 +26,7 @@ use Encode; use Carp; use C4::Members; +use C4::Members::Attributes qw(GetBorrowerAttributes); use C4::Branch; use C4::Log; use C4::SMS; @@ -42,7 +43,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 ); } @@ -117,13 +118,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) @@ -178,7 +192,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 "; @@ -234,70 +248,65 @@ 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; 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/<>/$userenv->{firstname}/g; - $letter->{content} =~ s/<>/$userenv->{surname}/g; - $letter->{content} =~ - s/<>/$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; # warn "sending to $mail{To} From $mail{From} subj $mail{Subject} Mess $mail{Message}"; - } } } elsif ( $type eq 'claimacquisition' ) { # warn "sending issues..."; - my $letter = getletter( 'claimacquisition', $letter ); # prepare the letter... # search the biblionumber @@ -307,52 +316,43 @@ sub SendAlerts { my $sthorders = $dbh->prepare($strsth); $sthorders->execute; my $dataorders = $sthorders->fetchall_arrayref( {} ); - parseletter( $letter, 'aqbooksellers', - $dataorders->[0]->{booksellerid} ); + my $sthbookseller = $dbh->prepare("select * from aqbooksellers where id=?"); $sthbookseller->execute( $dataorders->[0]->{booksellerid} ); my $databookseller = $sthbookseller->fetchrow_hashref; - # parsing branch info - my $userenv = C4::Context->userenv; - parseletter( $letter, 'branches', $userenv->{branch} ); - - # parsing librarian name - $letter->{content} =~ s/<>/$userenv->{firstname}/g; - $letter->{content} =~ s/<>/$userenv->{surname}/g; - $letter->{content} =~ - s/<>/$userenv->{emailaddress}/g; - foreach my $data ( @{$dataorders} ) { - if ( $letter->{content} =~ m/(<<.*>>)/ ) { - my $line = $1; - foreach my $field ( keys %{$data} ) { - $line =~ s/(<<[^\.]+.$field>>)/$data->{$field}/; - } - $letter->{content} =~ s/(<<.*>>)/$line\n$1/; - } + 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; } - $letter->{content} =~ s/<<[^>]*>>//g; - my $innerletter = $letter; + + my $userenv = C4::Context->userenv; + my $letter = GetPreparedLetter ( + module => 'claimacquisition', + letter_code => $letter_code, + branchcode => $userenv->{branch}, + tables => { + 'branches' => $userenv->{branch}, + 'aqbooksellers' => $databookseller, + }, + repeat => $dataorders, + want_librarian => 1, + ) or return; # ... then send mail - if ( $databookseller->{bookselleremail} - || $databookseller->{contemail} ) - { - my %mail = ( - To => $databookseller->{bookselleremail} - . ( - $databookseller->{contemail} - ? "," . $databookseller->{contemail} - : "" - ), - From => $userenv->{emailaddress}, - Subject => "" . $innerletter->{title}, - Message => "" . $innerletter->{content}, - 'Content-Type' => 'text/plain; charset="utf8"', - ); - sendmail(%mail) or carp $Mail::Sendmail::error; - } + 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; + if ( C4::Context->preference("LetterLog") ) { logaction( "ACQUISITION", @@ -360,16 +360,13 @@ sub SendAlerts { "", "order list : " . join( ",", @$externalid ) - . "\n$innerletter->{title}\n$innerletter->{content}" + . "\n$letter->{title}\n$letter->{content}" ); } } elsif ( $type eq 'claimissues' ) { # warn "sending issues..."; - my $letter = getletter( 'claimissues', $letter ); - - # prepare the letter... # search the biblionumber my $strsth = "select serial.*,subscription.*, biblio.* from serial LEFT JOIN subscription on serial.subscriptionid=subscription.subscriptionid LEFT JOIN biblio on serial.biblionumber=biblio.biblionumber where serial.serialid IN (" @@ -377,81 +374,76 @@ sub SendAlerts { my $sthorders = $dbh->prepare($strsth); $sthorders->execute; my $dataorders = $sthorders->fetchall_arrayref( {} ); - parseletter( $letter, 'aqbooksellers', - $dataorders->[0]->{aqbooksellerid} ); + my $sthbookseller = $dbh->prepare("select * from aqbooksellers where id=?"); $sthbookseller->execute( $dataorders->[0]->{aqbooksellerid} ); my $databookseller = $sthbookseller->fetchrow_hashref; - # parsing branch info - my $userenv = C4::Context->userenv; - parseletter( $letter, 'branches', $userenv->{branch} ); - - # parsing librarian name - $letter->{content} =~ s/<>/$userenv->{firstname}/g; - $letter->{content} =~ s/<>/$userenv->{surname}/g; - $letter->{content} =~ - s/<>/$userenv->{emailaddress}/g; - foreach my $data ( @{$dataorders} ) { - if ( $letter->{content} =~ m/(<<.*>>)/ ) { - my $line = $1; - foreach my $field ( keys %{$data} ) { - $line =~ s/(<<[^\.]+.$field>>)/$data->{$field}/; - } - $letter->{content} =~ s/(<<.*>>)/$line\n$1/; - } + 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; } - $letter->{content} =~ s/<<[^>]*>>//g; - my $innerletter = $letter; + + # prepare the letter... + my $userenv = C4::Context->userenv; + my $letter = GetPreparedLetter ( + module => 'claimissues', + letter_code => $letter_code, + branchcode => $userenv->{branch}, + tables => { + 'branches' => $userenv->{branch}, + 'aqbooksellers' => $databookseller, + }, + repeat => $dataorders, + want_librarian => 1, + ) or return; # ... then send mail - if ( $databookseller->{bookselleremail} - || $databookseller->{contemail} ) { - my $mail_to = $databookseller->{bookselleremail}; - if ($databookseller->{contemail}) { - if (!$mail_to) { - $mail_to = $databookseller->{contemail}; - } else { - $mail_to .= q|,|; - $mail_to .= $databookseller->{contemail}; - } - } - my $mail_subj = $innerletter->{title}; - my $mail_msg = $innerletter->{content}; - $mail_msg ||= q{}; - $mail_subj ||= q{}; + my $mail_subj = $letter->{title}; + my $mail_msg = $letter->{content}; + $mail_msg ||= q{}; + $mail_subj ||= q{}; - my %mail = ( - To => $mail_to, - From => $userenv->{emailaddress}, - Subject => $mail_subj, - Message => $mail_msg, - 'Content-Type' => 'text/plain; charset="utf8"', - ); - sendmail(%mail) or carp $Mail::Sendmail::error; - logaction( - "ACQUISITION", - "CLAIM ISSUE", - undef, - "To=" - . $databookseller->{contemail} - . " Title=" - . $innerletter->{title} - . " Content=" - . $innerletter->{content} - ) if C4::Context->preference("LetterLog"); - } + my %mail = ( + To => join( ','. @email), + From => $userenv->{emailaddress}, + Subject => $mail_subj, + Message => $mail_msg, + 'Content-Type' => 'text/plain; charset="utf8"', + ); + sendmail(%mail) or carp $Mail::Sendmail::error; + + logaction( + "ACQUISITION", + "CLAIM ISSUE", + 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 elsif ( $type eq 'members' ) { - # must parse the password special, before it's hashed. - $letter->{content} =~ s/<>/$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"), @@ -463,24 +455,148 @@ sub SendAlerts { } } -=head2 parseletter($letter, $table, $pk) - - 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) +=head2 GetPreparedLetter( %params ) + + %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 << >> << >> + 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 = @_; + + 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/<>/$userenv->{firstname}/go; + $letter->{content} =~ s/<>/$userenv->{surname}/go; + $letter->{content} =~ s/<>/$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>(.*)!s ) { + my $subcontent = $1; + my @lines = map { + my %subletter = ( title => '', content => $subcontent ); + _substitute_tables( \%subletter, $_ ); + $subletter{content}; + } @$tag_tables; + $letter->{content} =~ s!<$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/<>/$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; -sub parseletter_sth { + 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 @@ -494,9 +610,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)) { @@ -506,25 +625,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) - my $values = $sth->fetchrow_hashref; - + 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 ) = @_; + # TEMPORARY hack until the expirationdate column is added to reserves if ( $table eq 'reserves' && $values->{'waitingdate'} ) { my @waitingdate = split /-/, $values->{'waitingdate'}; @@ -538,16 +653,51 @@ sub parseletter { )->output(); } + if ($letter->{content} && $letter->{content} =~ /<>/) { + my @da = localtime(); + my $todaysdate = "$da[2]:$da[1] " . C4::Dates->today(); + $letter->{content} =~ s/<>/$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 = "<>"; + my $replacedby = join ',', @$val_ar; + $letter->{content} =~ s/$replacefield/$replacedby/g; + } + } } return $letter; } @@ -732,31 +882,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; } @@ -823,14 +974,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') ) { @@ -850,6 +1004,27 @@ sub _send_message_by_email ($;$$$) { } } +sub _wrap_html { + my ($content, $title) = @_; + + my $css = C4::Context->preference("NoticeCSS") || ''; + $css = qq{} if $css; + return < + + +$title + +$css + + +$content + + +EOS +} + sub _send_message_by_sms ($) { my $message = shift or return undef; my $member = C4::Members::GetMember( 'borrowernumber' => $message->{'borrowernumber'} ); diff --git a/C4/Members.pm b/C4/Members.pm index 1d7bc42..9f42cea 100644 --- a/C4/Members.pm +++ b/C4/Members.pm @@ -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, at ISA, at EXPORT, at EXPORT_OK,$debug); @@ -91,6 +93,8 @@ BEGIN { &DeleteMessage &GetMessages &GetMessagesCount + + &IssueSlip ); #Modify data @@ -2227,7 +2231,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; diff --git a/C4/Members/Attributes.pm b/C4/Members/Attributes.pm index 4ae5600..33affa8 100644 --- a/C4/Members/Attributes.pm +++ b/C4/Members/Attributes.pm @@ -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); diff --git a/C4/Message.pm b/C4/Message.pm index 16272ff..4b88970 100644 --- a/C4/Message.pm +++ b/C4/Message.pm @@ -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: diff --git a/C4/Print.pm b/C4/Print.pm index f810816..7fb55cf 100644 --- a/C4/Print.pm +++ b/C4/Print.pm @@ -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 + +BORROWER: +$bordata->{'surname'}, $bordata->{'firstname'} +card number: $bordata->{'cardnumber'} +Phone: $bordata->{'phone'} +$bordata->{'streetaddress'} +$bordata->{'suburb'} +$bordata->{'town'} +$bordata->{'emailaddress'} -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>. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +EOF =cut +=head2 printslip + + &printslip($slip) + +print a slip for the given $borrowernumber and $branchcode + +=cut + +sub printslip ($) { + my ($slip) = @_; + + return unless ( C4::Context->boolean_preference('printcirculationslips') ); + # FIXME - It'd be nifty if this could generate pretty PostScript. -sub remoteprint ($$) { - my ($items, $borrower) = @_; - (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__ diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 359bbad..d2af1c5 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -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 %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 $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 $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/g; - $letter->{'content'} =~ s/<>/$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 diff --git a/C4/Suggestions.pm b/C4/Suggestions.pm index ccc0c8e..6c10fdf 100644 --- a/C4/Suggestions.pm +++ b/C4/Suggestions.pm @@ -371,20 +371,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; diff --git a/acqui/booksellers.pl b/acqui/booksellers.pl index 634eb93..745d040 100755 --- a/acqui/booksellers.pl +++ b/acqui/booksellers.pl @@ -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 ) ) diff --git a/circ/circulation.pl b/circ/circulation.pl index 1b6c619..20e8f6f 100755 --- a/circ/circulation.pl +++ b/circ/circulation.pl @@ -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 = ''; } diff --git a/circ/hold-transfer-slip.pl b/circ/hold-transfer-slip.pl index f581464..8ae5d2a 100755 --- a/circ/hold-transfer-slip.pl +++ b/circ/hold-transfer-slip.pl @@ -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; diff --git a/installer/data/mysql/de-DE/mandatory/sample_notices.sql b/installer/data/mysql/de-DE/mandatory/sample_notices.sql index 166c36d..efdad91 100644 --- a/installer/data/mysql/de-DE/mandatory/sample_notices.sql +++ b/installer/data/mysql/de-DE/mandatory/sample_notices.sql @@ -11,7 +11,7 @@ VALUES ('circulation','ODUE','Mahnung','Mahnung','Liebe/r < ('reserves', 'HOLD_PRINT', 'Vormerkbenachrichtigung (Print)', 'Vormerkbenachrichtigung (Print)', '<>\r\n<>\r\n<>\r\n<>\r\n<> <>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<> <>\r\n<>\r\n<>\r\n<> <>\r\n<>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nLiebe(r) <> <>,\r\n\r\nF??r Sie liegt seit dem <> eine Vormerkung zur Abholung bereit:\r\n\r\nTitel: <>\r\nVerfasser: <>\r\nSignatur: <>\r\n'), ('circulation','CHECKIN','R??ckgabequittung (Zusammenfassung)','R??ckgabequittung','Die folgenden Medien wurden zur??ckgegeben:\r\n----\r\n<>\r\n----\r\nVielen Dank.'), ('circulation','CHECKOUT','Ausleihquittung (Zusammenfassung)','Ausleihquittung','Die folgenden Medien wurden entliehen:\r\n----\r\n<>\r\n----\r\nVielen Dank f??r Ihren Besuch in <>.'), -('reserves', 'HOLDPLACED', 'Neue Vormerkung', 'Neue Vormerkung','Folgender Titel wurde vorgemerkt: <> (<<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>>'), diff --git a/installer/data/mysql/en/mandatory/sample_notices.sql b/installer/data/mysql/en/mandatory/sample_notices.sql index 689fa0f..8c9f4bd 100644 --- a/installer/data/mysql/en/mandatory/sample_notices.sql +++ b/installer/data/mysql/en/mandatory/sample_notices.sql @@ -11,8 +11,90 @@ 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> + +<reserves> +<div> +<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> +</div> +</reserves>', 1); + diff --git a/installer/data/mysql/es-ES/mandatory/sample_notices.sql b/installer/data/mysql/es-ES/mandatory/sample_notices.sql index 689fa0f..bf3324d 100644 --- a/installer/data/mysql/es-ES/mandatory/sample_notices.sql +++ b/installer/data/mysql/es-ES/mandatory/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql b/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql index 977e59d..acffe73 100644 --- a/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql +++ b/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/it-IT/necessari/notices.sql b/installer/data/mysql/it-IT/necessari/notices.sql index 689fa0f..bf3324d 100644 --- a/installer/data/mysql/it-IT/necessari/notices.sql +++ b/installer/data/mysql/it-IT/necessari/notices.sql @@ -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>>'), diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 4fd4106..a535db4 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -1168,10 +1168,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; -- @@ -2252,12 +2254,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; -- diff --git a/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql b/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql index cdb5529..08b452e 100644 --- a/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql +++ b/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/pl-PL/mandatory/sample_notices.sql b/installer/data/mysql/pl-PL/mandatory/sample_notices.sql index 6be2eb8..f0844f3 100644 --- a/installer/data/mysql/pl-PL/mandatory/sample_notices.sql +++ b/installer/data/mysql/pl-PL/mandatory/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/ru-RU/mandatory/sample_notices.sql b/installer/data/mysql/ru-RU/mandatory/sample_notices.sql index 689fa0f..bf3324d 100644 --- a/installer/data/mysql/ru-RU/mandatory/sample_notices.sql +++ b/installer/data/mysql/ru-RU/mandatory/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 918df5c..3bf50fa 100755 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -330,3 +330,6 @@ 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'); + diff --git a/installer/data/mysql/uk-UA/mandatory/sample_notices.sql b/installer/data/mysql/uk-UA/mandatory/sample_notices.sql index 358205b..b637343 100644 --- a/installer/data/mysql/uk-UA/mandatory/sample_notices.sql +++ b/installer/data/mysql/uk-UA/mandatory/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index 0a3603d..2f2233a 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -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"; @@ -4619,6 +4618,104 @@ 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 `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 and RESERVESLIP letters; Add NoticeCSS and SlipCSS sysprefs)\n"; + SetVersion($DBversion); +} =head1 FUNCTIONS diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-toolbar.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/circ-toolbar.inc index 913076f..6fdd720 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-toolbar.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/circ-toolbar.inc @@ -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 %]&print=" + print_type, "printwindow"); + var handler = print_type.match(slip_re) ? "printslip" : "moremember"; + window.open("/cgi-bin/koha/members/" + handler + ".pl?borrowernumber=[% borrowernumber %]&print=" + print_type, "printwindow"); return false; } function searchToHold(){ diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref index 817ce57..2e9945f 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -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 diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/staff_client.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/staff_client.pref index df0a434..efa33a8 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/staff_client.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/staff_client.pref @@ -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 diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/batch/print-notices.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/batch/print-notices.tt index 1904381..73f9e61 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/batch/print-notices.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/batch/print-notices.tt @@ -8,11 +8,7 @@ --> </style> [% IF ( stylesheet ) %] - <style type="text/css"> - <!-- - [% stylesheet %] - --> - </style> + <link rel="stylesheet" type="text/css" href="[% stylesheet %]"> [% END %] </head> <body> diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/hold-transfer-slip.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/hold-transfer-slip.tt deleted file mode 100644 index 18d45aa..0000000 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/hold-transfer-slip.tt +++ /dev/null @@ -1,54 +0,0 @@ -[% INCLUDE 'doc-head-open.inc' %] -<title>Koha -- Circulation: Transfers -[% INCLUDE 'doc-head-close-receipt.inc' %] - - -
    - -[% FOREACH reservedat IN reservedata %] - -
    Date: [% reservedat.pulldate %]
    -

    [% IF ( reservedat.transferrequired ) %]Transfer to [% reservedat.branchname %] [% ELSE %]Hold in [% reservedat.branchname %][% END %]

    - -
    - -

    [% reservedat.surname %], [% reservedat.firstname %]

    - -
      -
    • [% reservedat.cardnumber %]
    • - [% IF ( reservedat.phone ) %] -
    • [% reservedat.phone %]
    • - [% END %] -
    • - [% reservedat.address %]
      - [% IF ( reservedat.address2 ) %][% reservedat.address2 %]
      [% END %] - [% reservedat.city %] [% reservedat.zip %] -
    • - [% IF ( reservedat.email ) %] -
    • [% reservedat.email %]
    • - [% END %] -
    -
    -

    ITEM ON HOLD

    -

    [% reservedat.title |html %]

    -
    [% reservedat.author %]
    -
      - [% IF ( reservedat.barcode ) %]
    • [% reservedat.barcode %]
    • [% END %] - [% IF ( reservedat.itemcallnumber ) %]
    • [% reservedat.itemcallnumber %]
    • [% END %] - [% IF ( reservedat.waitingdate ) %]
    • [% reservedat.waitingdate %]
    • [% END %] -
    - [% IF ( reservedat.reservenotes ) %] -

    Notes: [% reservedat.reservenotes %]

    - [% END %] - - - -[% END %] -
    -[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt new file mode 100644 index 0000000..a790069 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt @@ -0,0 +1,28 @@ +[% INCLUDE 'doc-head-open.inc' %] +[% title %] + + + +[% IF stylesheet %] + +[% END %] + + + + +
    + +[% IF plain %] +
    +[% slip %]
    +
    +[% ELSE %] +[% slip %] +[% END %] + +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt deleted file mode 100644 index 4a85ccb..0000000 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt +++ /dev/null @@ -1,76 +0,0 @@ -[% INCLUDE 'doc-head-open.inc' %] -Print Receipt for [% cardnumber %] - - - - - - - - -
    - -

    [% LibraryName %]

    -[% IF ( branchname ) %][% branchname %]
    [% END %] -Checked out to [% firstname %] [% surname %]
    -([% cardnumber %])
    - -[% todaysdate %]
    - -[% IF ( quickslip ) %] -

    Checked Out Today

    -[% FOREACH issueloo IN issueloop %] -[% IF ( issueloo.red ) %][% ELSE %] -[% IF ( issueloo.today ) %] -

    [% issueloo.title |html %]
    -Barcode: [% issueloo.barcode %]
    -Date due: [% issueloo.date_due %]

    - [% END %] - [% END %] - [% END %] - -[% ELSE %] -

    Checked Out

    -[% FOREACH issueloo IN issueloop %] -[% IF ( issueloo.red ) %][% ELSE %] -

    [% issueloo.title |html %]
    -Barcode: [% issueloo.barcode %]
    -Date due: [% issueloo.date_due %]

    - [% END %] - [% END %] - -[% END %] - -[% IF ( quickslip ) %] -[% ELSE %] -[% IF ( overdues_exist ) %] -

    Overdues

    - [% FOREACH issueloo IN issueloop %] - [% IF ( issueloo.red ) %] -

    [% issueloo.title |html %]
    -Barcode: [% issueloo.barcode %]
    -Date due: [% issueloo.date_due %]

    -[% END %] -[% END %] -[% END %] -[% END %] - -[% IF ( koha_news_count ) %] -

    News

    - - [% FOREACH koha_new IN koha_news %] -
    [% koha_new.title %]
    -

    [% koha_new.new %]

    -

    Posted on [% koha_new.newdate %] - -


    - [% END %] -[% END %] - - -[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt index 063236e..8e12d05 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt @@ -5,14 +5,29 @@ -
    - +[% IF ( no_op_set ) %] +
    + + [% UNLESS independant_branch %] +

    + Select a library : + +

    + [% END %] +

    + + +

    +
    + [% IF ( search ) %]

    You Searched for [% searchfield %]

    [% END %] - [% IF ( letter ) %] + [% IF ( letter && !independant_branch) %] + [% select_for_copy = BLOCK %] + + [% END %] + [% END %] +
    + + - [% FOREACH lette IN letter %] - [% UNLESS ( loop.odd ) %] + + [% FOREACH lette IN letter %] + [% can_edit = lette.branchcode || !independant_branch %] + [% UNLESS ( loop.odd ) %] - [% ELSE %] + [% ELSE %] - [% END %] + [% END %] + + - [% END %] + [% END %] +
    Branch Module Code Name     
    [% lette.branchname || "(All libraries)" %] [% lette.module %] [% lette.code %] [% lette.name %] - Edit + [% IF can_edit %] + Edit + [% END %] + + [% IF !independant_branch || !lette.branchcode %] +
    + + + + + [% IF independant_branch %] + + [% ELSE %] + [% select_for_copy %] + [% END %] + +
    + [% END %]
    - [% IF ( lette.protected ) %] - - - [% ELSE %] - Delete - [% END %] + [% IF !lette.protected && can_edit %] + Delete + [% END %]
    - [% END %] +[% END %] - [% END %] - [% IF ( add_form ) %] +[% IF ( add_form ) %] -
    - + + [% IF ( modify ) %] @@ -182,6 +229,20 @@ $(document).ready(function() {
    [% IF ( modify ) %]Modify notice[% ELSE %]Add notice[% END %]
      + + [% IF independant_branch %] + + [% ELSE %] +
    1. + + +
    2. + [% END %]
    3. @@ -235,6 +296,9 @@ $(document).ready(function() {
    4. + +
    5. +
    6. @@ -252,27 +316,31 @@ $(document).ready(function() {
    +
    +
    - [% END %] +[% END %] - [% IF ( add_validate ) %] +[% IF ( add_validate ) %] Data recorded
    - [% END %] +[% END %] - [% IF ( delete_confirm ) %] +[% IF ( delete_confirm ) %]

    Delete Notice?

    + + @@ -280,6 +348,7 @@ $(document).ready(function() {
    Branch Module Code Name
    [% branchname %] [% module %] [% code %] [% name %]
    + @@ -290,14 +359,14 @@ $(document).ready(function() {
    - [% END %] +[% END %] - [% IF ( delete_confirmed ) %] +[% IF ( delete_confirmed ) %] Data deleted
    - [% END %] +[% END %]
    diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt index 05bdb47..e06b607 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt @@ -26,7 +26,7 @@ [% END %] [% IF ( CAN_user_tools_edit_notices ) %] -
    Notices
    +
    Notices & Slips
    Define notices (print and email notification messages for overdues, etc.)
    [% END %] diff --git a/members/memberentry.pl b/members/memberentry.pl index 6de07bf..20f1cf0 100755 --- a/members/memberentry.pl +++ b/members/memberentry.pl @@ -345,10 +345,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" ); } } diff --git a/members/moremember.pl b/members/moremember.pl index 6e5407c..9277deb 100755 --- a/members/moremember.pl +++ b/members/moremember.pl @@ -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); @@ -483,13 +482,4 @@ $template->param( quickslip => $quickslip, ); -#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; diff --git a/members/printslip.pl b/members/printslip.pl new file mode 100755 index 0000000..3a499cd --- /dev/null +++ b/members/printslip.pl @@ -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 at katipo.co.nz + last modified 21/1/2000 by chris at katipo.co.nz + modified 31/1/2001 by chris at 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; diff --git a/misc/cronjobs/advance_notices.pl b/misc/cronjobs/advance_notices.pl index 1fa358f..09c4017 100755 --- a/misc/cronjobs/advance_notices.pl +++ b/misc/cronjobs/advance_notices.pl @@ -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 EEitems.contentEE 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", at 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", at 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", at 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", at 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; - } - } - - C4::Letters::parseletter( $params->{'letter'}, 'borrowers', $params->{'borrowernumber'} ); + my %table_params = ( 'borrowers' => $params->{'borrowernumber'} ); - if ( $params->{'branchcode'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'branches', $params->{'branchcode'} ); + if ( my $p = $params->{'branchcode'} ) { + $table_params{'branches'} = $p; } - if ( $params->{'itemnumber'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'issues', $params->{'itemnumber'} ); - C4::Letters::parseletter( $params->{'letter'}, 'items', $params->{'itemnumber'} ); + if ( my $p = $params->{'itemnumber'} ) { + $table_params{'issues'} = $p; + $table_params{'items'} = $p; } - if ( $params->{'biblionumber'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'biblio', $params->{'biblionumber'} ); - C4::Letters::parseletter( $params->{'letter'}, 'biblioitems', $params->{'biblionumber'} ); + if ( my $p = $params->{'biblionumber'} ) { + $table_params{'biblio'} = $p; + $table_params{'biblioitems'} = $p; } - 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; diff --git a/misc/cronjobs/gather_print_notices.pl b/misc/cronjobs/gather_print_notices.pl index a72d6a6..165b16e 100755 --- a/misc/cronjobs/gather_print_notices.pl +++ b/misc/cronjobs/gather_print_notices.pl @@ -39,11 +39,9 @@ use Getopt::Long; sub usage { print STDERR < \$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_contents .= $_ } - close STYLESHEET; -} $template->param( - stylesheet => $stylesheet_contents, + stylesheet => C4::Context->preference("NoticeCSS"), today => $today->output(), messages => \@messages, ); diff --git a/misc/cronjobs/overdue_notices.pl b/misc/cronjobs/overdue_notices.pl index 71e6a05..93061b4 100755 --- a/misc/cronjobs/overdue_notices.pl +++ b/misc/cronjobs/overdue_notices.pl @@ -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/<>/$todaysdate/g; - $params->{'letter'}->{content} =~ s/<>/$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>/o) { # process any fine tags... + $currency_format = $1; + $params->{'letter'}->{'content'} =~ s/.*<\/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_format = $1; } - if ($params->{'letter'}->{'content'} =~ m/(.*)<\/fine>/) { # process any fine tags... - my $formatted_fine = currency_format("$1", "$fine", FMT_SYMBOL); - $params->{'letter'}->{'content'} =~ s/.*<\/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>)/$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 diff --git a/t/db_dependent/lib/KohaTest/Letters.pm b/t/db_dependent/lib/KohaTest/Letters.pm index 97d58fb..f2d7b0d 100644 --- a/t/db_dependent/lib/KohaTest/Letters.pm +++ b/t/db_dependent/lib/KohaTest/Letters.pm @@ -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 ); diff --git a/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm b/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm index 76b6ab4..53e5439 100644 --- a/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm +++ b/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm @@ -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; diff --git a/t/db_dependent/lib/KohaTest/Members.pm b/t/db_dependent/lib/KohaTest/Members.pm index 5646be1..dfde7da 100644 --- a/t/db_dependent/lib/KohaTest/Members.pm +++ b/t/db_dependent/lib/KohaTest/Members.pm @@ -52,6 +52,7 @@ sub methods : Test( 1 ) { GetBorrowersWhoHaveNeverBorrowed GetBorrowersWithIssuesHistoryOlderThan GetBorrowersNamesAndLatestIssue + IssueSlip ); can_ok( $self->testing_class, @methods ); diff --git a/t/db_dependent/lib/KohaTest/Print.pm b/t/db_dependent/lib/KohaTest/Print.pm index 02fd5fb..d35ab34 100644 --- a/t/db_dependent/lib/KohaTest/Print.pm +++ b/t/db_dependent/lib/KohaTest/Print.pm @@ -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 ); } diff --git a/t/db_dependent/lib/KohaTest/Reserves.pm b/t/db_dependent/lib/KohaTest/Reserves.pm index 8b05dd0..6416ac3 100644 --- a/t/db_dependent/lib/KohaTest/Reserves.pm +++ b/t/db_dependent/lib/KohaTest/Reserves.pm @@ -33,6 +33,7 @@ sub methods : Test( 1 ) { GetReserveInfo _FixPriority _Findgroupreserve + ReserveSlip ); can_ok( $self->testing_class, @methods ); diff --git a/tools/letter.pl b/tools/letter.pl index f5dc0c6..6188a9e 100755 --- a/tools/letter.pl +++ b/tools/letter.pl @@ -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,14 +88,12 @@ 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( { @@ -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") + ? 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; } -- 1.6.5 From Katrin.Fischer.83 at web.de Mon Jan 16 23:12:32 2012 From: Katrin.Fischer.83 at web.de (Katrin Fischer) Date: Mon, 16 Jan 2012 23:12:32 +0100 Subject: [Koha-patches] [PATCH] Bug 4300: Fix display of textual holdings (866) Message-ID: <1326751952-9986-1-git-send-email-Katrin.Fischer.83@web.de> Fixed problems: - only $z, but not $a was shown - only first $z for each 866 field was shown - each 866 field produced a ; even if no $z was present After patch was applied: - OPAC displays 866 $a and $z, separating each field with ; - Staff displays 866 $a, $x and $z, separating each field with ; Example(s) for testing: 866 $a1-86 (1941-1987)$xbound in 2 v. per year$zSome issues missing 866 $a1-86 (1941-1987) 866 $a--86 (1941-1897)$xinternal note 866 $zfirst note,$zsecond note --- .../prog/en/xslt/MARC21slim2intranetDetail.xsl | 12 ++++++++++++ .../prog/en/xslt/MARC21slim2OPACDetail.xsl | 16 +++++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slim2intranetDetail.xsl b/koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slim2intranetDetail.xsl index 9e16667..abc0975 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slim2intranetDetail.xsl +++ b/koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slim2intranetDetail.xsl @@ -588,6 +588,18 @@ + + + + Holdings Note: + + + axz + + ; + + + diff --git a/koha-tmpl/opac-tmpl/prog/en/xslt/MARC21slim2OPACDetail.xsl b/koha-tmpl/opac-tmpl/prog/en/xslt/MARC21slim2OPACDetail.xsl index 43e2658..f6d3efd 100755 --- a/koha-tmpl/opac-tmpl/prog/en/xslt/MARC21slim2OPACDetail.xsl +++ b/koha-tmpl/opac-tmpl/prog/en/xslt/MARC21slim2OPACDetail.xsl @@ -717,14 +717,16 @@ - + - Holdings Note: - - - .; - - + Holdings Note: + + + az + + ; + + -- 1.7.5.4 From adrien.saurat at biblibre.com Tue Jan 17 12:01:27 2012 From: adrien.saurat at biblibre.com (Adrien Saurat) Date: Tue, 17 Jan 2012 12:01:27 +0100 Subject: [Koha-patches] [PATCH] Bug 7450: missing placeholders in authorised_values.pl Message-ID: <1326798087-6753-1-git-send-email-adrien.saurat@biblibre.com> --- admin/authorised_values.pl | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-) diff --git a/admin/authorised_values.pl b/admin/authorised_values.pl index d7872d6..f5dbc46 100755 --- a/admin/authorised_values.pl +++ b/admin/authorised_values.pl @@ -104,13 +104,13 @@ if ($op eq 'add_form') { my $duplicate_entry = 0; if ( $id ) { # Update - my $sth = $dbh->prepare( "SELECT category, authorised_value FROM authorised_values WHERE id='$id' "); - $sth->execute(); + my $sth = $dbh->prepare( "SELECT category, authorised_value FROM authorised_values WHERE id = ? "); + $sth->execute($id); my ($category, $authorised_value) = $sth->fetchrow_array(); if ( $authorised_value ne $new_authorised_value ) { my $sth = $dbh->prepare_cached( "SELECT COUNT(*) FROM authorised_values " . - "WHERE category = '$new_category' AND authorised_value = '$new_authorised_value' and id<>$id"); - $sth->execute(); + "WHERE category = ? AND authorised_value = ? and id <> ? "); + $sth->execute($new_category, $new_authorised_value, $id); ($duplicate_entry) = $sth->fetchrow_array(); warn "**** duplicate_entry = $duplicate_entry"; } @@ -133,8 +133,8 @@ if ($op eq 'add_form') { } else { # Insert my $sth = $dbh->prepare_cached( "SELECT COUNT(*) FROM authorised_values " . - "WHERE category = '$new_category' AND authorised_value = '$new_authorised_value' "); - $sth->execute(); + "WHERE category = ? AND authorised_value = ? "); + $sth->execute($new_category, $new_authorised_value); ($duplicate_entry) = $sth->fetchrow_array(); unless ( $duplicate_entry ) { my $sth=$dbh->prepare( 'INSERT INTO authorised_values -- 1.7.4.1 From dpavlin at rot13.org Tue Jan 17 15:25:46 2012 From: dpavlin at rot13.org (Dobrica Pavlinusic) Date: Tue, 17 Jan 2012 15:25:46 +0100 Subject: [Koha-patches] [PATCH] $subfield_data{id} is used for AJAX value_builders and hidden fields Message-ID: <1326810346-28523-1-git-send-email-dpavlin@rot13.org> In current version of code, it gets initialized too late, so it produces unitialized warnings for hidden fields (which is non-fatal) and breaks generated JavaScript for AJAX value_builders (which is fatal) This bug was introduced in ticket 6106 which is modification of 5955 which didn't have this particular problem. http://bugs.koha-community.org/show_bug.cgi?id=7451 --- C4/Biblio.pm | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/C4/Biblio.pm b/C4/Biblio.pm index ac78ae3..f3c57d5 100644 --- a/C4/Biblio.pm +++ b/C4/Biblio.pm @@ -2507,6 +2507,7 @@ sub PrepareItemrecordDisplay { $subfield_data{subfield} = $subfield; $subfield_data{countsubfield} = $cntsubf++; $subfield_data{kohafield} = $tagslib->{$tag}->{$subfield}->{'kohafield'}; + $subfield_data{id} = "tag_".$tag."_subfield_".$subfield."_". int(rand(1000000)); # $subfield_data{marc_lib}=$tagslib->{$tag}->{$subfield}->{lib}; $subfield_data{marc_lib} = $tagslib->{$tag}->{$subfield}->{lib}; @@ -2642,11 +2643,9 @@ sub PrepareItemrecordDisplay { my $plugin = C4::Context->intranetdir . "/cataloguing/value_builder/" . $tagslib->{$tag}->{$subfield}->{'value_builder'}; if (do $plugin) { my $temp; + $subfield_data{random} = int(rand(1000000)); # why do we need 2 different randoms? my $extended_param = plugin_parameters( $dbh, $temp, $tagslib, $subfield_data{id}, undef ); my ( $function_name, $javascript ) = plugin_javascript( $dbh, $temp, $tagslib, $subfield_data{id}, undef ); - $subfield_data{random} = int(rand(1000000)); # why do we need 2 different randoms? - my $index_subfield = int(rand(1000000)); - $subfield_data{id} = "tag_".$tag."_subfield_".$subfield."_".$index_subfield; $subfield_data{marc_value} = qq[ -- 1.7.2.5 From dpavlin at rot13.org Tue Jan 17 15:27:23 2012 From: dpavlin at rot13.org (Dobrica Pavlinusic) Date: Tue, 17 Jan 2012 15:27:23 +0100 Subject: [Koha-patches] [PATCH] Bug 7451 - PrepareItemrecordDisplay missing $subfield_data{id} which breaks AJAX value_builders Message-ID: <1326810443-28601-1-git-send-email-dpavlin@rot13.org> In current version of code, it gets initialized too late, so it produces unitialized warnings for hidden fields (which is non-fatal) and breaks generated JavaScript for AJAX value_builders (which is fatal) This bug was introduced in ticket 6106 which is modification of 5955 which didn't have this particular problem. http://bugs.koha-community.org/show_bug.cgi?id=7451 --- C4/Biblio.pm | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/C4/Biblio.pm b/C4/Biblio.pm index ac78ae3..f3c57d5 100644 --- a/C4/Biblio.pm +++ b/C4/Biblio.pm @@ -2507,6 +2507,7 @@ sub PrepareItemrecordDisplay { $subfield_data{subfield} = $subfield; $subfield_data{countsubfield} = $cntsubf++; $subfield_data{kohafield} = $tagslib->{$tag}->{$subfield}->{'kohafield'}; + $subfield_data{id} = "tag_".$tag."_subfield_".$subfield."_". int(rand(1000000)); # $subfield_data{marc_lib}=$tagslib->{$tag}->{$subfield}->{lib}; $subfield_data{marc_lib} = $tagslib->{$tag}->{$subfield}->{lib}; @@ -2642,11 +2643,9 @@ sub PrepareItemrecordDisplay { my $plugin = C4::Context->intranetdir . "/cataloguing/value_builder/" . $tagslib->{$tag}->{$subfield}->{'value_builder'}; if (do $plugin) { my $temp; + $subfield_data{random} = int(rand(1000000)); # why do we need 2 different randoms? my $extended_param = plugin_parameters( $dbh, $temp, $tagslib, $subfield_data{id}, undef ); my ( $function_name, $javascript ) = plugin_javascript( $dbh, $temp, $tagslib, $subfield_data{id}, undef ); - $subfield_data{random} = int(rand(1000000)); # why do we need 2 different randoms? - my $index_subfield = int(rand(1000000)); - $subfield_data{id} = "tag_".$tag."_subfield_".$subfield."_".$index_subfield; $subfield_data{marc_value} = qq[ -- 1.7.2.5 From dpavlin at rot13.org Tue Jan 17 15:29:25 2012 From: dpavlin at rot13.org (Dobrica Pavlinusic) Date: Tue, 17 Jan 2012 15:29:25 +0100 Subject: [Koha-patches] [PATCH] $subfield_data{id} is used for AJAX value_builders and hidden fields In-Reply-To: <1326810346-28523-1-git-send-email-dpavlin@rot13.org> References: <1326810346-28523-1-git-send-email-dpavlin@rot13.org> Message-ID: <20120117142925.GE7924@rot13.org> On Tue, Jan 17, 2012 at 03:25:46PM +0100, Dobrica Pavlinusic wrote: > In current version of code, it gets initialized too late, so it produces > unitialized warnings for hidden fields (which is non-fatal) and breaks > generated JavaScript for AJAX value_builders (which is fatal) > > This bug was introduced in ticket 6106 which is modification of 5955 > which didn't have this particular problem. > > http://bugs.koha-community.org/show_bug.cgi?id=7451 Sorry about spamming koha-patches list with two variants of the same bug, feel free to ignore this one which doesn't have nice Subject: line. -- Dobrica Pavlinusic 2share!2flame dpavlin at rot13.org Unix addict. Internet consultant. http://www.rot13.org/~dpavlin From oleonard at myacpl.org Tue Jan 17 21:32:34 2012 From: oleonard at myacpl.org (Owen Leonard) Date: Tue, 17 Jan 2012 15:32:34 -0500 Subject: [Koha-patches] [PATCH] Bug 5503 [REVISED] comments shouldn't show patron's full name Message-ID: <1326832354-17049-1-git-send-email-oleonard@myacpl.org> Adding a few choices for what information can be displayed alongside comments in the OPAC: - nothing - full name - first name - last name - first name and last name first initial - username Signed-off-by: Nicole C. Engard Tested by choosing each choice and previewing an individual title with a comment and confirming the name was displayed properly. Then choosing each option and prevewing the recent comments page. All tests passed. --- installer/data/mysql/sysprefs.sql | 2 +- installer/data/mysql/updatedatabase.pl | 7 ++++ .../prog/en/modules/admin/preferences/opac.pref | 11 +++++-- koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt | 30 ++++++++++++------- .../opac-tmpl/prog/en/modules/opac-showreviews.tt | 16 +++++++++- opac/opac-showreviews.pl | 2 + 6 files changed, 51 insertions(+), 17 deletions(-) diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 918df5c..f79cb32 100755 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -103,7 +103,7 @@ INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('ReturnBeforeExpiry',0,'If ON, checkout will be prevented if returndate is after patron card expiry',NULL,'YesNo'); INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('ReturnLog',1,'If ON, enables the circulation (returns) log',NULL,'YesNo'); INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('reviewson',1,'If ON, enables patron reviews of bibliographic records in the OPAC','','YesNo'); -INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('ShowReviewer',1,'If ON, name of reviewer will be shown above comments in OPAC','','YesNo'); +INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('ShowReviewer','full','Choose how a commenter''s identity is presented alongside comments in the OPAC','none|full|first|surname|firstandinitial|username','Choice'); INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('ShowReviewerPhoto',1,'If ON, photo of reviewer will be shown beside comments in OPAC','','YesNo'); INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('SpecifyDueDate',1,'Define whether to display \"Specify Due Date\" form in Circulation','','YesNo'); INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('SubscriptionHistory','simplified','Define the display preference for serials issue history in OPAC','simplified|full','Choice'); diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index 0a3603d..12cf172 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -4619,6 +4619,13 @@ if (C4::Context->preference("Version") < TransformToNum($DBversion)) { SetVersion ($DBversion); } +$DBversion = "3.07.00.XXX"; +if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { + $dbh->do(" UPDATE `koha`.`systempreferences` SET `value` = 'none', `options` = 'none|full|first|surname|firstandinitial|username', `explanation` = 'Choose how a commenter''s identity is presented alongside comments in the OPAC', `type` = 'Choice' WHERE `systempreferences`.`variable` = 'ShowReviewer' AND `systempreferences`.`variable` = 0"); + $dbh->do(" UPDATE `koha`.`systempreferences` SET `value` = 'full', `options` = 'none|full|first|surname|firstandinitial|username', `explanation` = 'Choose how a commenter''s identity is presented alongside comments in the OPAC', `type` = 'Choice' WHERE `systempreferences`.`variable` = 'ShowReviewer' AND `systempreferences`.`variable` = 1"); + print "Adding additional options for the display of commenter's identity in the OPAC: Full name, first name, last name, first name and last name first initial, username, or no information\n"; + SetVersion($DBversion); +} =head1 FUNCTIONS diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref index d6ae2b2..cd051de 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref @@ -270,11 +270,16 @@ OPAC: no: "Don't allow" - patrons to make comments on items on the OPAC. - + - Show - pref: ShowReviewer choices: - yes: Show - no: Hide - - reviewer's name above comments in OPAC. + none: no name + full: full name + first: first name + surname: last name + firstandinitial: first name and last name initial + username: username + - of commenter with comments in OPAC. - - pref: ShowReviewerPhoto choices: diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt index 066f4ff..8b9b54b 100755 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt @@ -867,18 +867,26 @@ YAHOO.util.Event.onContentReady("furtherm", function () {

    [% ELSE %]
    - [% IF ( ShowReviewer ) %] - [% IF ( review.avatarurl ) %] - - [% END %] -
    - Comment by - [% review.title %] - [% review.firstname %] - [% review.surname %] -
    + [% IF ( ShowReviewer != "none" ) %] + [% IF ( review.avatarurl ) %] + + [% END %] + [% SWITCH ShowReviewer %] + [% CASE 'full' %] +
    Comment by [% review.title %] [% review.firstname %] [% review.surname %]
    + [% CASE 'first' %] +
    Comment by [% review.firstname %]
    + [% CASE 'surname' %] +
    Comment by [% review.surname %]
    + [% CASE 'firstandinitial' %] +
    Comment by [% review.firstname %] [% review.surname|truncate(2,'.') %]
    + [% CASE 'username' %] +
    Comment by [% review.userid %]
    + [% END %] + [% review.datereviewed %] + [% ELSIF ( ShowReviewer == "none") %] +
    Patron comment on [% review.datereviewed %]
    [% END %] - [% review.datereviewed %]

    [% FILTER html_break %] [% review.review |html %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-showreviews.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-showreviews.tt index fdea679..d548361 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-showreviews.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-showreviews.tt @@ -54,8 +54,20 @@ $(document).ready(function(){ [% review.review |html %] [% END %] Added [% review.datereviewed %] [% IF ( review.your_comment ) %] by you[% ELSE %] - [% IF ( ShowReviewer ) %] by - [% review.firstname %] [% review.surname %][% END %][% END %]

    + [% IF ( ShowReviewer != "none" ) %] by + [% SWITCH ShowReviewer %] + [% CASE 'full' %] + [% review.borrtitle %] [% review.firstname %] [% review.surname %] + [% CASE 'first' %] + [% review.firstname %] + [% CASE 'surname' %] + [% review.surname %] + [% CASE 'firstandinitial' %] + [% review.firstname %] [% review.surname|truncate(2,'.') %] + [% CASE 'username' %] + [% review.userid %] + [% END %] + [% END %][% END %]

    [% IF ( review.BiblioDefaultViewmarc ) %] diff --git a/opac/opac-showreviews.pl b/opac/opac-showreviews.pl index 74f4684..449ffcd 100755 --- a/opac/opac-showreviews.pl +++ b/opac/opac-showreviews.pl @@ -101,8 +101,10 @@ for my $result (@$reviews){ $result->{size} = $bib->{'size'}; $result->{notes} = $bib->{'notes'}; $result->{timestamp} = $bib->{'timestamp'}; + $result->{borrtitle} = $borr->{'title'}; $result->{firstname} = $borr->{'firstname'}; $result->{surname} = $borr->{'surname'}; + $result->{userid} = $borr->{'userid'}; if ($libravatar_enabled and $borr->{'email'}) { $result->{avatarurl} = libravatar_url(email => $borr->{'email'}, size => 40, https => $ENV{HTTPS}); } -- 1.7.3 From oleonard at myacpl.org Tue Jan 17 22:09:07 2012 From: oleonard at myacpl.org (Owen Leonard) Date: Tue, 17 Jan 2012 16:09:07 -0500 Subject: [Koha-patches] [PATCH] Bug 6598 [REVISED] OPACFineNoRenewals syspreference does not stop user renewing in opac Message-ID: <1326834547-20504-1-git-send-email-oleonard@myacpl.org> This patch standardizes the condition under which renewal controls are displayed at the page (as opposed to item) level. In some places "canrenew" was used, in others "patron_flagged" was used. Now "canrenew" controls renew controls and "patron_flagged" only triggers the display of user warnings. This patch also allows for renewal information to be displayed for each item in situations where OPAC renewals are allowed but disabled for whatever reason. This gives the patron information about used/available renew counts but hides renew controls. --- koha-tmpl/opac-tmpl/prog/en/modules/opac-user.tt | 21 +++++++++------------ opac/opac-user.pl | 6 +++--- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-user.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-user.tt index b78fc03..ffcd293 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-user.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-user.tt @@ -58,7 +58,6 @@ $.tablesorter.addParser({
    - [% IF ( bor_messages ) %]

    Messages For You

    @@ -89,7 +88,7 @@ $.tablesorter.addParser({
    [% END %] - [% IF ( BORROWER_INF.flagged ) %] + [% IF ( patron_flagged ) %]
      [% IF ( userdebarred ) %] @@ -196,7 +195,7 @@ $.tablesorter.addParser({ [% IF ( show_barcode ) %]Barcode[% END %] Call No. [% IF ( OpacRenewalAllowed ) %] - [% UNLESS patron_flagged %]Renew[% END %] + Renew [% END %] [% IF ( OPACFinesTab ) %] Fines @@ -244,12 +243,10 @@ $.tablesorter.addParser({ [% IF ( show_barcode ) %][% ISSUE.barcode %][% END %] [% ISSUE.itemcallnumber %] [% IF ( OpacRenewalAllowed ) %] - [% UNLESS patron_flagged %] - [% IF ( ISSUE.status ) %] Renew ([% ISSUE.renewsleft %] of [% ISSUE.renewsallowed %] renewals remaining) + [% IF ( ISSUE.status ) %][% IF ( canrenew ) %] Renew[% END %] ([% ISSUE.renewsleft %] of [% ISSUE.renewsallowed %] renewals remaining) [% ELSE %] Not renewable[% IF ( ISSUE.too_many ) %] ([% ISSUE.renewsleft %] of [% ISSUE.renewsallowed %] renewals remaining)[% ELSE %][% IF ( ISSUE.on_reserve ) %] (On hold)[% END %][% END %] [% END %] - [% END %] [% END %] [% IF ( OPACFinesTab ) %] [% IF ( ISSUE.charges ) %]Yes[% ELSE %]No[% END %] @@ -271,7 +268,7 @@ $.tablesorter.addParser({ [% FOREACH ISSUE IN ISSUES %] [% END %] - [% UNLESS patron_flagged %][% END %] + [% END %] [% ELSE %] @@ -293,7 +290,8 @@ $.tablesorter.addParser({ Call No. Due [% IF ( OpacRenewalAllowed ) %] - [% UNLESS patron_flagged %]Renew[% END %][% END %] + Renew +[% END %] [% IF ( OPACFinesTab ) %] Fines [% END %] @@ -325,15 +323,14 @@ $.tablesorter.addParser({ [% OVERDUE.itemcallnumber %] [% OVERDUE.date_due %] [% IF ( OpacRenewalAllowed ) %] - [% UNLESS patron_flagged %] [% IF ( OVERDUE.debarred ) %]Account Frozen [% ELSIF ( OVERDUE.status ) %] -Renew ([% OVERDUE.renewsleft %] of [% OVERDUE.renewsallowed %] renewals remaining) -[% ELSIF ( OVERDUE.onreserve ) %]On Reserve +[% IF ( canrenew ) %]Renew[% END %] ([% OVERDUE.renewsleft %] of [% OVERDUE.renewsallowed %] renewals remaining) +[% ELSIF ( OVERDUE.onreserve ) %]On hold [% ELSE %]No renewals left [% END %] -[% END %][% END %] +[% END %] [% IF ( OPACFinesTab ) %] [% IF ( OVERDUE.charges ) %]Yes[% ELSE %]No[% END %] [% END %] diff --git a/opac/opac-user.pl b/opac/opac-user.pl index f6ed484..ff1fecf 100755 --- a/opac/opac-user.pl +++ b/opac/opac-user.pl @@ -67,6 +67,7 @@ my ( $template, $borrowernumber, $cookie ) = get_template_and_user( my $OPACDisplayRequestPriority = (C4::Context->preference("OPACDisplayRequestPriority")) ? 1 : 0; my $patronupdate = $query->param('patronupdate'); +my $canrenew = 1; # get borrower information .... my ( $borr ) = GetMemberDetails( $borrowernumber ); @@ -92,6 +93,7 @@ if ($debar) { if ( $userdebarred || $borr->{'gonenoaddress'} || $borr->{'lost'} ) { $borr->{'flagged'} = 1; + $canrenew = 0; } if ( $borr->{'amountoutstanding'} > 5 ) { @@ -105,6 +107,7 @@ $no_renewal_amt ||= 0; if ( $borr->{amountoutstanding} > $no_renewal_amt ) { $borr->{'flagged'} = 1; + $canrenew = 0; $template->param( renewal_blocked_fines => sprintf( '%.02f', $no_renewal_amt ), ); @@ -144,13 +147,11 @@ $template->param( BORROWER_INFO => \@bordat, #get issued items .... my $count = 0; -my $toggle = 0; my $overdues_count = 0; my @overdues; my @issuedat; my $itemtypes = GetItemTypes(); my ($issues) = GetPendingIssues($borrowernumber); -my $canrenew = 0; if ($issues){ foreach my $issue ( sort { $b->{'date_due'} cmp $a->{'date_due'} } @$issues ) { # check for reserves @@ -181,7 +182,6 @@ if ($issues){ ($issue->{'renewcount'},$issue->{'renewsallowed'},$issue->{'renewsleft'}) = GetRenewCount($borrowernumber, $issue->{'itemnumber'}); if($status && C4::Context->preference("OpacRenewalAllowed")){ $issue->{'status'} = $status; - $canrenew = 1; } $issue->{'too_many'} = 1 if $renewerror and $renewerror eq 'too_many'; $issue->{'on_reserve'} = 1 if $renewerror and $renewerror eq 'on_reserve'; -- 1.7.3 From lrea at nekls.org Tue Jan 17 22:44:41 2012 From: lrea at nekls.org (lrea at nekls.org) Date: Tue, 17 Jan 2012 15:44:41 -0600 Subject: [Koha-patches] =?utf-8?q?=5BPATCH=5D_Bug_6350_-_Adding_new_develo?= =?utf-8?q?pers_to_history=2Etxt_Jesse_Maseto_Connor_Dewar_Sam_Sand?= =?utf-8?q?ers?= Message-ID: <1326836681-18022-1-git-send-email-lrea@nekls.org> From: Liz Rea --- docs/history.txt | 4 +++- koha-tmpl/intranet-tmpl/prog/en/modules/about.tt | 3 +++ 2 files changed, 6 insertions(+), 1 deletions(-) diff --git a/docs/history.txt b/docs/history.txt index 48ab538..9c3cea8 100644 --- a/docs/history.txt +++ b/docs/history.txt @@ -592,4 +592,6 @@ December 7 2011 Jon Aker becomes the 164th developer to have a patch pushed December 13 2011 Fabio Tiana becomes the 165th developer to have a patch pushed December 15 2011 Duncan Tyler becomes the 166th developer to have a patch pushed December 15 2011 Marc Balmer becomes the 167th developer to have a patch pushed - +January 16 2012 Jesse Maseto becomes the 168th developer to have a patch pushed +January 17 2012 Connor Dewar becomes the 169th developer to have a patch pushed (as part of the Catalyst Open Source Academy) +January 17 2012 Sam Sanders becomes the 170th developer to have a patch pushed (as part of the Catalyst Open Source Academy) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/about.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/about.tt index 5b7a30c..46f0724 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/about.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/about.tt @@ -158,6 +158,7 @@
    • Elliott Davis
    • Doug Dearden
    • Kip DeGraaf
    • +
    • Connor Dewar
    • Fr?d?ric Demians
    • Jonathan Druart
    • Serhij Dubyk
    • @@ -214,6 +215,7 @@
    • Gynn Lomax
    • Robert Lyon (Corporate Serials)
    • Francois Marier
    • +
    • Jesse Maseto
    • Fr?re S?bastien Marie
    • Ricardo Dias Marques
    • Julian Maurice
    • @@ -244,6 +246,7 @@
    • Marcel de Rooy
    • Salvador Zaragoza Rubio
    • Brice Sanchez
    • +
    • Sam Sanders
    • Robin Sheat
    • John Seymour
    • Juan Romay Sieira
    • -- 1.7.2.5 From gcollum at gmail.com Wed Jan 18 02:37:20 2012 From: gcollum at gmail.com (Garry Collum) Date: Tue, 17 Jan 2012 20:37:20 -0500 Subject: [Koha-patches] [PATCH 34/34] Bug 7203: Fixes typo - 'Mange' to 'Manage' in several files. Message-ID: <1326850640-3925-1-git-send-email-gcollum@gmail.com> Found 3 instances of the typo while looking for the typo reference in Bug 7203. Fixed labels/label-edit-batch.tt, labels/label-edit-layout.tt, and patroncards/edit-layout.tt. --- .../prog/en/modules/labels/label-edit-batch.tt | 2 +- .../prog/en/modules/labels/label-edit-layout.tt | 2 +- .../prog/en/modules/patroncards/edit-layout.tt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-edit-batch.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-edit-batch.tt index 5a6b09e..9a1708e 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-edit-batch.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-edit-batch.tt @@ -27,7 +27,7 @@ HomeToolsLabels Home › - Mange Label Batches › + Manage Label Batches › Manage Batch Number [% batch_id %]
    diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-edit-layout.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-edit-layout.tt index 4610aca..cd799a8 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-edit-layout.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-edit-layout.tt @@ -26,7 +26,7 @@ HomeToolsLabels Home › - Mange Label Layouts › + Manage Label Layouts › [% IF ( layout_id ) %]Edit[% ELSE %]Create[% END %] Label Layout
    diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/patroncards/edit-layout.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/patroncards/edit-layout.tt index c40551d..b8b0942 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/patroncards/edit-layout.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/patroncards/edit-layout.tt @@ -140,7 +140,7 @@ HomeToolsPatron Card Creator › - Mange Patron Card Layouts › + Manage Patron Card Layouts › [% IF ( layout_id ) %]Edit[% ELSE %]Create[% END %] Patron Card Layout
    -- 1.7.5.4 From jonathan.druart at biblibre.com Wed Jan 18 11:28:27 2012 From: jonathan.druart at biblibre.com (Jonathan Druart) Date: Wed, 18 Jan 2012 11:28:27 +0100 Subject: [Koha-patches] =?utf-8?q?=5BPATCH_1/1=5D_Bug_7289=3A_Adds_edition?= =?utf-8?q?statement_field_in_neworderempty?= Message-ID: <1326882507-14315-1-git-send-email-jonathan.druart@biblibre.com> --- acqui/addorder.pl | 1 + acqui/neworderempty.pl | 1 + .../marc21/mandatory/marc21_framework_DEFAULT.sql | 2 +- .../marc21/optional/marc21_fastadd_framework.sql | 2 +- .../optional/marc21_simple_bib_frameworks.sql | 16 ++++++++-------- .../mandatory/unimarc_framework_DEFAULT.sql | 2 +- .../Obligatoire/framework_DEFAULT.sql | 2 +- .../prog/en/modules/acqui/neworderempty.tt | 10 ++++++++++ 8 files changed, 24 insertions(+), 12 deletions(-) diff --git a/acqui/addorder.pl b/acqui/addorder.pl index 121d20d..279084b 100755 --- a/acqui/addorder.pl +++ b/acqui/addorder.pl @@ -206,6 +206,7 @@ if ( $orderinfo->{quantity} ne '0' ) { "biblioitems.publicationyear" => $$orderinfo{publicationyear} ? $$orderinfo{publicationyear}: "", "biblio.copyrightdate" => $$orderinfo{publicationyear} ? $$orderinfo{publicationyear}: "", "biblioitems.itemtype" => $$orderinfo{itemtype} ? $$orderinfo{itemtype} : "", + "biblioitems.editionstatement"=> $$orderinfo{editionstatement} ? $$orderinfo{editionstatement} : "", }); # create the record in catalogue, with framework '' diff --git a/acqui/neworderempty.pl b/acqui/neworderempty.pl index 459dfe8..9d88e26 100755 --- a/acqui/neworderempty.pl +++ b/acqui/neworderempty.pl @@ -376,6 +376,7 @@ $template->param( title => $data->{'title'}, author => $data->{'author'}, publicationyear => $data->{'publicationyear'} ? $data->{'publicationyear'} : $data->{'copyrightdate'}, + editionstatement => $data->{'editionstatement'}, budget_loop => $budget_loop, isbn => $data->{'isbn'}, seriestitle => $data->{'seriestitle'}, diff --git a/installer/data/mysql/en/marcflavour/marc21/mandatory/marc21_framework_DEFAULT.sql b/installer/data/mysql/en/marcflavour/marc21/mandatory/marc21_framework_DEFAULT.sql index b81bd2b..62c64ad 100644 --- a/installer/data/mysql/en/marcflavour/marc21/mandatory/marc21_framework_DEFAULT.sql +++ b/installer/data/mysql/en/marcflavour/marc21/mandatory/marc21_framework_DEFAULT.sql @@ -1005,7 +1005,7 @@ INSERT INTO `marc_subfield_structure` (`tagfield`, `tagsubfield`, `liblibrarian` ('247', 'x', 'International Standard Serial Number', 'International Standard Serial Number', 0, 0, '', 2, '', '', '', NULL, -6, '', '', '', NULL), ('250', '6', 'Linkage', 'Linkage', 0, 0, '', 2, '', '', '', NULL, -6, '', '', '', NULL), ('250', '8', 'Field link and sequence number', 'Field link and sequence number', 1, 0, '', 2, '', '', '', NULL, -6, '', '', '', NULL), - ('250', 'a', 'Edition statement', 'Edition statement', 0, 0, '', 2, '', '', '', NULL, 0, '', '', '', NULL), + ('250', 'a', 'Edition statement', 'Edition statement', 0, 0, 'biblioitems.editionstatement', 2, '', '', '', NULL, 0, '', '', '', NULL), ('250', 'b', 'Remainder of edition statement', 'Remainder of edition statement', 0, 0, '', 2, '', '', '', NULL, 0, '', '', '', NULL), ('254', '6', 'Linkage', 'Linkage', 0, 0, '', 2, '', '', '', NULL, -6, '', '', '', NULL), ('254', '8', 'Field link and sequence number', 'Field link and sequence number', 1, 0, '', 2, '', '', '', NULL, -6, '', '', '', NULL), diff --git a/installer/data/mysql/en/marcflavour/marc21/optional/marc21_fastadd_framework.sql b/installer/data/mysql/en/marcflavour/marc21/optional/marc21_fastadd_framework.sql index 0ba4025..40180d0 100644 --- a/installer/data/mysql/en/marcflavour/marc21/optional/marc21_fastadd_framework.sql +++ b/installer/data/mysql/en/marcflavour/marc21/optional/marc21_fastadd_framework.sql @@ -74,7 +74,7 @@ INSERT IGNORE INTO `marc_subfield_structure` (`tagfield`, `tagsubfield`, `liblib ('245','s','Version','Version',0,0,'',0,'','','',0,0,'FA',NULL,'',''), ('250','6','Linkage','Linkage',0,0,'',0,'','','',0,0,'FA',NULL,'',''), ('250','8','Field link and sequence number','Field link and sequence number',1,0,'',0,'','','',0,0,'FA',NULL,'',''), - ('250','a','Edition statement','Edition statement',0,0,'',0,'','','',0,0,'FA',NULL,'',''), + ('250','a','Edition statement','Edition statement',0,0,'biblioitems.editionstatement',0,'','','',0,0,'FA',NULL,'',''), ('250','b','Remainder of edition statement','Remainder of edition statement',0,0,'',0,'','','',0,0,'FA',NULL,'',''), ('260','6','Linkage','Linkage',0,0,'',0,'','','',0,0,'FA',NULL,'',''), ('260','8','Field link and sequence number','Field link and sequence number',1,0,'',0,'','','',0,0,'FA',NULL,'',''), diff --git a/installer/data/mysql/en/marcflavour/marc21/optional/marc21_simple_bib_frameworks.sql b/installer/data/mysql/en/marcflavour/marc21/optional/marc21_simple_bib_frameworks.sql index 7cee9c8..2a1d37e 100644 --- a/installer/data/mysql/en/marcflavour/marc21/optional/marc21_simple_bib_frameworks.sql +++ b/installer/data/mysql/en/marcflavour/marc21/optional/marc21_simple_bib_frameworks.sql @@ -1030,7 +1030,7 @@ INSERT INTO `marc_subfield_structure` (`tagfield`, `tagsubfield`, `liblibrarian` ('247', 'x', 'International Standard Serial Number', 'International Standard Serial Number', 0, 0, '', 2, '', '', '', NULL, -6, 'BKS', '', '', NULL), ('250', '6', 'Linkage', 'Linkage', 0, 0, '', 2, '', '', '', NULL, -6, 'BKS', '', '', NULL), ('250', '8', 'Field link and sequence number', 'Field link and sequence number', 1, 0, '', 2, '', '', '', NULL, -6, 'BKS', '', '', NULL), - ('250', 'a', 'Edition statement', 'Edition statement', 0, 0, '', 2, '', '', '', NULL, 0, 'BKS', '', '', NULL), + ('250', 'a', 'Edition statement', 'Edition statement', 0, 0, 'biblioitems.editionstatement', 2, '', '', '', NULL, 0, 'BKS', '', '', NULL), ('250', 'b', 'Remainder of edition statement', 'Remainder of edition statement', 0, 0, '', 2, '', '', '', NULL, 0, 'BKS', '', '', NULL), ('254', '6', 'Linkage', 'Linkage', 0, 0, '', 2, '', '', '', NULL, -6, 'BKS', '', '', NULL), ('254', '8', 'Field link and sequence number', 'Field link and sequence number', 1, 0, '', 2, '', '', '', NULL, -6, 'BKS', '', '', NULL), @@ -4959,7 +4959,7 @@ INSERT INTO `marc_subfield_structure` (`tagfield`, `tagsubfield`, `liblibrarian` ('247', 'x', 'International Standard Serial Number', 'International Standard Serial Number', 0, 0, '', 2, '', '', '', NULL, -1, 'CF', '', '', NULL), ('250', '6', 'Linkage', 'Linkage', 0, 0, '', 2, '', '', '', NULL, -6, 'CF', '', '', NULL), ('250', '8', 'Field link and sequence number', 'Field link and sequence number', 1, 0, '', 2, '', '', '', NULL, -6, 'CF', '', '', NULL), - ('250', 'a', 'Edition statement', 'Edition statement', 0, 0, '', 2, '', '', '', NULL, -1, 'CF', '', '', NULL), + ('250', 'a', 'Edition statement', 'Edition statement', 0, 0, 'biblioitems.editionstatement', 2, '', '', '', NULL, -1, 'CF', '', '', NULL), ('250', 'b', 'Remainder of edition statement', 'Remainder of edition statement', 0, 0, '', 2, '', '', '', NULL, -1, 'CF', '', '', NULL), ('254', '6', 'Linkage', 'Linkage', 0, 0, '', 2, '', '', '', NULL, -6, 'CF', '', '', NULL), ('254', '8', 'Field link and sequence number', 'Field link and sequence number', 1, 0, '', 2, '', '', '', NULL, -6, 'CF', '', '', NULL), @@ -8887,7 +8887,7 @@ INSERT INTO `marc_subfield_structure` (`tagfield`, `tagsubfield`, `liblibrarian` ('247', 'x', 'International Standard Serial Number', 'International Standard Serial Number', 0, 0, '', 2, '', '', '', NULL, -6, 'SR', '', '', NULL), ('250', '6', 'Linkage', 'Linkage', 0, 0, '', 2, '', '', '', NULL, -6, 'SR', '', '', NULL), ('250', '8', 'Field link and sequence number', 'Field link and sequence number', 1, 0, '', 2, '', '', '', NULL, -6, 'SR', '', '', NULL), - ('250', 'a', 'Edition statement', 'Edition statement', 0, 0, '', 2, '', '', '', NULL, -1, 'SR', '', '', NULL), + ('250', 'a', 'Edition statement', 'Edition statement', 0, 0, 'biblioitems.editionstatement', 2, '', '', '', NULL, -1, 'SR', '', '', NULL), ('250', 'b', 'Remainder of edition statement', 'Remainder of edition statement', 0, 0, '', 2, '', '', '', NULL, -1, 'SR', '', '', NULL), ('254', '6', 'Linkage', 'Linkage', 0, 0, '', 2, '', '', '', NULL, -6, 'SR', '', '', NULL), ('254', '8', 'Field link and sequence number', 'Field link and sequence number', 1, 0, '', 2, '', '', '', NULL, -6, 'SR', '', '', NULL), @@ -12815,7 +12815,7 @@ INSERT INTO `marc_subfield_structure` (`tagfield`, `tagsubfield`, `liblibrarian` ('247', 'x', 'International Standard Serial Number', 'International Standard Serial Number', 0, 0, '', 2, '', '', '', NULL, -6, 'VR', '', '', NULL), ('250', '6', 'Linkage', 'Linkage', 0, 0, '', 2, '', '', '', NULL, -6, 'VR', '', '', NULL), ('250', '8', 'Field link and sequence number', 'Field link and sequence number', 1, 0, '', 2, '', '', '', NULL, -6, 'VR', '', '', NULL), - ('250', 'a', 'Edition statement', 'Edition statement', 0, 0, '', 2, '', '', '', NULL, -1, 'VR', '', '', NULL), + ('250', 'a', 'Edition statement', 'Edition statement', 0, 0, 'biblioitems.editionstatement', 2, '', '', '', NULL, -1, 'VR', '', '', NULL), ('250', 'b', 'Remainder of edition statement', 'Remainder of edition statement', 0, 0, '', 2, '', '', '', NULL, -1, 'VR', '', '', NULL), ('254', '6', 'Linkage', 'Linkage', 0, 0, '', 2, '', '', '', NULL, -6, 'VR', '', '', NULL), ('254', '8', 'Field link and sequence number', 'Field link and sequence number', 1, 0, '', 2, '', '', '', NULL, -6, 'VR', '', '', NULL), @@ -16741,7 +16741,7 @@ INSERT INTO `marc_subfield_structure` (`tagfield`, `tagsubfield`, `liblibrarian` ('247', 'x', 'International Standard Serial Number', 'International Standard Serial Number', 0, 0, '', 2, '', '', '', NULL, -6, 'AR', '', '', NULL), ('250', '6', 'Linkage', 'Linkage', 0, 0, '', 2, '', '', '', NULL, -6, 'AR', '', '', NULL), ('250', '8', 'Field link and sequence number', 'Field link and sequence number', 1, 0, '', 2, '', '', '', NULL, -6, 'AR', '', '', NULL), - ('250', 'a', 'Edition statement', 'Edition statement', 0, 0, '', 2, '', '', '', NULL, -1, 'AR', '', '', NULL), + ('250', 'a', 'Edition statement', 'Edition statement', 0, 0, 'biblioitems.editionstatement', 2, '', '', '', NULL, -1, 'AR', '', '', NULL), ('250', 'b', 'Remainder of edition statement', 'Remainder of edition statement', 0, 0, '', 2, '', '', '', NULL, -1, 'AR', '', '', NULL), ('254', '6', 'Linkage', 'Linkage', 0, 0, '', 2, '', '', '', NULL, -6, 'AR', '', '', NULL), ('254', '8', 'Field link and sequence number', 'Field link and sequence number', 1, 0, '', 2, '', '', '', NULL, -6, 'AR', '', '', NULL), @@ -20667,7 +20667,7 @@ INSERT INTO `marc_subfield_structure` (`tagfield`, `tagsubfield`, `liblibrarian` ('247', 'x', 'International Standard Serial Number', 'International Standard Serial Number', 0, 0, '', 2, '', '', '', NULL, -6, 'KT', '', '', NULL), ('250', '6', 'Linkage', 'Linkage', 0, 0, '', 2, '', '', '', NULL, -6, 'KT', '', '', NULL), ('250', '8', 'Field link and sequence number', 'Field link and sequence number', 1, 0, '', 2, '', '', '', NULL, -6, 'KT', '', '', NULL), - ('250', 'a', 'Edition statement', 'Edition statement', 0, 0, '', 2, '', '', '', NULL, -1, 'KT', '', '', NULL), + ('250', 'a', 'Edition statement', 'Edition statement', 0, 0, 'biblioitems.editionstatement', 2, '', '', '', NULL, -1, 'KT', '', '', NULL), ('250', 'b', 'Remainder of edition statement', 'Remainder of edition statement', 0, 0, '', 2, '', '', '', NULL, -1, 'KT', '', '', NULL), ('254', '6', 'Linkage', 'Linkage', 0, 0, '', 2, '', '', '', NULL, -6, 'KT', '', '', NULL), ('254', '8', 'Field link and sequence number', 'Field link and sequence number', 1, 0, '', 2, '', '', '', NULL, -6, 'KT', '', '', NULL), @@ -24595,7 +24595,7 @@ INSERT INTO `marc_subfield_structure` (`tagfield`, `tagsubfield`, `liblibrarian` ('247', 'x', 'International Standard Serial Number', 'International Standard Serial Number', 0, 0, '', 2, '', '', '', NULL, -6, 'IR', '', '', NULL), ('250', '6', 'Linkage', 'Linkage', 0, 0, '', 2, '', '', '', NULL, -6, 'IR', '', '', NULL), ('250', '8', 'Field link and sequence number', 'Field link and sequence number', 1, 0, '', 2, '', '', '', NULL, -6, 'IR', '', '', NULL), - ('250', 'a', 'Edition statement', 'Edition statement', 0, 0, '', 2, '', '', '', NULL, 0, 'IR', '', '', NULL), + ('250', 'a', 'Edition statement', 'Edition statement', 0, 0, 'biblioitems.editionstatement', 2, '', '', '', NULL, 0, 'IR', '', '', NULL), ('250', 'b', 'Remainder of edition statement', 'Remainder of edition statement', 0, 0, '', 2, '', '', '', NULL, 0, 'IR', '', '', NULL), ('254', '6', 'Linkage', 'Linkage', 0, 0, '', 2, '', '', '', NULL, -6, 'IR', '', '', NULL), ('254', '8', 'Field link and sequence number', 'Field link and sequence number', 1, 0, '', 2, '', '', '', NULL, -6, 'IR', '', '', NULL), @@ -28518,7 +28518,7 @@ INSERT INTO `marc_subfield_structure` (`tagfield`, `tagsubfield`, `liblibrarian` ('247', 'x', 'International Standard Serial Number', 'International Standard Serial Number', 0, 0, '', 2, '', '', '', NULL, -1, 'SER', '', '', NULL), ('250', '6', 'Linkage', 'Linkage', 0, 0, '', 2, '', '', '', NULL, -6, 'SER', '', '', NULL), ('250', '8', 'Field link and sequence number', 'Field link and sequence number', 1, 0, '', 2, '', '', '', NULL, -6, 'SER', '', '', NULL), - ('250', 'a', 'Edition statement', 'Edition statement', 0, 0, '', 2, '', '', '', NULL, -1, 'SER', '', '', NULL), + ('250', 'a', 'Edition statement', 'Edition statement', 0, 0, 'biblioitems.editionstatement', 2, '', '', '', NULL, -1, 'SER', '', '', NULL), ('250', 'b', 'Remainder of edition statement', 'Remainder of edition statement', 0, 0, '', 2, '', '', '', NULL, -1, 'SER', '', '', NULL), ('254', '6', 'Linkage', 'Linkage', 0, 0, '', 2, '', '', '', NULL, -6, 'SER', '', '', NULL), ('254', '8', 'Field link and sequence number', 'Field link and sequence number', 1, 0, '', 2, '', '', '', NULL, -6, 'SER', '', '', NULL), diff --git a/installer/data/mysql/en/marcflavour/unimarc/mandatory/unimarc_framework_DEFAULT.sql b/installer/data/mysql/en/marcflavour/unimarc/mandatory/unimarc_framework_DEFAULT.sql index b3c0f4b..02093d3 100644 --- a/installer/data/mysql/en/marcflavour/unimarc/mandatory/unimarc_framework_DEFAULT.sql +++ b/installer/data/mysql/en/marcflavour/unimarc/mandatory/unimarc_framework_DEFAULT.sql @@ -438,7 +438,7 @@ INSERT INTO `marc_subfield_structure` (`tagfield`, `tagsubfield`, `liblibrarian` ('200', 'i', 'Name of a Part', 'Name of a Part', 0, 0, '', 2, '', '', '', 0, 0, '', '', '', NULL), ('200', 'v', 'Volume Designation', 'Volume Designation', 0, 0, '', 2, '', '', '', 0, 0, '', '', '', NULL), ('200', 'z', 'Language of Paralel Title Proper', 'Language of Paralel Title Proper', 0, 0, '', 2, '', '', '', 0, 0, '', '', '', NULL), - ('205', 'a', 'Edition Statement', 'Edition Statement', 0, 0, '', 2, '', '', '', 0, 0, '', '', '', NULL), + ('205', 'a', 'Edition Statement', 'Edition Statement', 0, 0, 'biblioitems.editionstatement', 2, '', '', '', 0, 0, '', '', '', NULL), ('205', 'b', 'Issue Statement', 'Issue Statement', 0, 0, '', 2, '', '', '', 0, 0, '', '', '', NULL), ('205', 'd', 'Parallel Edition Statement', 'Parallel Edition Statement', 0, 0, '', 2, '', '', '', 0, 0, '', '', '', NULL), ('205', 'f', 'Statement of Responsibility Relating to Edition', 'Statement of Responsibility Relating to Edition', 0, 0, '', 2, '', '', '', 0, 0, '', '', '', NULL), diff --git a/installer/data/mysql/fr-FR/marcflavour/unimarc_lecture_pub/Obligatoire/framework_DEFAULT.sql b/installer/data/mysql/fr-FR/marcflavour/unimarc_lecture_pub/Obligatoire/framework_DEFAULT.sql index 63be2d6..789b015 100644 --- a/installer/data/mysql/fr-FR/marcflavour/unimarc_lecture_pub/Obligatoire/framework_DEFAULT.sql +++ b/installer/data/mysql/fr-FR/marcflavour/unimarc_lecture_pub/Obligatoire/framework_DEFAULT.sql @@ -1156,7 +1156,7 @@ INSERT INTO `marc_subfield_structure` (`tagfield`, `tagsubfield`, `liblibrarian` INSERT INTO `marc_subfield_structure` (`tagfield`, `tagsubfield`, `liblibrarian`, `libopac`, `repeatable`, `mandatory`, `kohafield`, `tab`, `authorised_value`, `authtypecode`, `value_builder`, `isurl`, `hidden`, `frameworkcode`, `seealso`, `link`, `defaultvalue`) VALUES ('200', 'i', 'titre partie', '', 1, 0, 'biblio.unititle', 0, '', '', '', 0, -1, '', '', '', NULL); INSERT INTO `marc_subfield_structure` (`tagfield`, `tagsubfield`, `liblibrarian`, `libopac`, `repeatable`, `mandatory`, `kohafield`, `tab`, `authorised_value`, `authtypecode`, `value_builder`, `isurl`, `hidden`, `frameworkcode`, `seealso`, `link`, `defaultvalue`) VALUES ('200', 'v', 'num?ro de volume', '', 0, 0, '', -1, '', '', '', 0, 0, '', '', '', NULL); INSERT INTO `marc_subfield_structure` (`tagfield`, `tagsubfield`, `liblibrarian`, `libopac`, `repeatable`, `mandatory`, `kohafield`, `tab`, `authorised_value`, `authtypecode`, `value_builder`, `isurl`, `hidden`, `frameworkcode`, `seealso`, `link`, `defaultvalue`) VALUES ('200', 'z', 'langue du titre parall?le', '', 0, 0, '', -1, '', '', '', 0, 0, '', '', '', NULL); -INSERT INTO `marc_subfield_structure` (`tagfield`, `tagsubfield`, `liblibrarian`, `libopac`, `repeatable`, `mandatory`, `kohafield`, `tab`, `authorised_value`, `authtypecode`, `value_builder`, `isurl`, `hidden`, `frameworkcode`, `seealso`, `link`, `defaultvalue`) VALUES ('205', 'a', 'mention d''?dition', '', 0, 0, '', -1, '', '', '', 0, 0, '', '', '', NULL); +INSERT INTO `marc_subfield_structure` (`tagfield`, `tagsubfield`, `liblibrarian`, `libopac`, `repeatable`, `mandatory`, `kohafield`, `tab`, `authorised_value`, `authtypecode`, `value_builder`, `isurl`, `hidden`, `frameworkcode`, `seealso`, `link`, `defaultvalue`) VALUES ('205', 'a', 'mention d''?dition', '', 0, 0, 'biblioitems.editionstatement', -1, '', '', '', 0, 0, '', '', '', NULL); INSERT INTO `marc_subfield_structure` (`tagfield`, `tagsubfield`, `liblibrarian`, `libopac`, `repeatable`, `mandatory`, `kohafield`, `tab`, `authorised_value`, `authtypecode`, `value_builder`, `isurl`, `hidden`, `frameworkcode`, `seealso`, `link`, `defaultvalue`) VALUES ('205', 'b', 'mention de parution', '', 1, 0, '', -1, '', '', '', 0, 0, '', '', '', NULL); INSERT INTO `marc_subfield_structure` (`tagfield`, `tagsubfield`, `liblibrarian`, `libopac`, `repeatable`, `mandatory`, `kohafield`, `tab`, `authorised_value`, `authtypecode`, `value_builder`, `isurl`, `hidden`, `frameworkcode`, `seealso`, `link`, `defaultvalue`) VALUES ('205', 'd', 'mention parall?le d''?dition', '', 1, 0, '', -1, '', '', '', 0, 0, '', '', '', NULL); INSERT INTO `marc_subfield_structure` (`tagfield`, `tagsubfield`, `liblibrarian`, `libopac`, `repeatable`, `mandatory`, `kohafield`, `tab`, `authorised_value`, `authtypecode`, `value_builder`, `isurl`, `hidden`, `frameworkcode`, `seealso`, `link`, `defaultvalue`) VALUES ('205', 'f', 'mention de responsabilit? relative ? l''?dition', '', 1, 0, '', -1, '', '', '', 0, 0, '', '', '', NULL); diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt index a6f26c4..aaeff6a 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt @@ -266,6 +266,16 @@ $(document).ready(function()
  • [% IF ( biblionumber ) %] + Publisher mention: + [% editionstatement %] + + [% ELSE %] + + + [% END %] +
  • +
  • + [% IF ( biblionumber ) %] Publication year: [% publicationyear %] [% ELSE %] -- 1.7.7.3 From jonathan.druart at biblibre.com Wed Jan 18 14:40:40 2012 From: jonathan.druart at biblibre.com (Jonathan Druart) Date: Wed, 18 Jan 2012 14:40:40 +0100 Subject: [Koha-patches] =?utf-8?q?=5BPATCH_1/1=5D_Bug_5346=3A_Linking_sugg?= =?utf-8?q?estions_and_orders=2E?= Message-ID: <1326894040-23494-1-git-send-email-jonathan.druart@biblibre.com> Display suggestion info in acquisition module: basket.pl neworderempty.pl orderreceive.pl parcel.pl To Test: Create a suggestion and accept it. Create a new order from this suggestion Receive this order For each step, check if suggestion info are visible. --- C4/Suggestions.pm | 60 +++++++++++++++++++- acqui/basket.pl | 9 +++ acqui/neworderempty.pl | 7 ++- acqui/orderreceive.pl | 8 ++- acqui/parcel.pl | 13 ++++- .../intranet-tmpl/prog/en/modules/acqui/basket.tt | 6 ++ .../prog/en/modules/acqui/neworderempty.tt | 14 ++++- .../prog/en/modules/acqui/orderreceive.tt | 13 ++++ .../intranet-tmpl/prog/en/modules/acqui/parcel.tt | 12 ++++ t/db_dependent/Suggestions.t | 8 ++- 10 files changed, 141 insertions(+), 9 deletions(-) diff --git a/C4/Suggestions.pm b/C4/Suggestions.pm index ccc0c8e..c9461f5 100644 --- a/C4/Suggestions.pm +++ b/C4/Suggestions.pm @@ -40,6 +40,8 @@ our @EXPORT = qw< GetSuggestion GetSuggestionByStatus GetSuggestionFromBiblionumber + GetSuggestionInfoFromBiblionumber + GetSuggestionInfo ModStatus ModSuggestion NewSuggestion @@ -209,13 +211,65 @@ sub GetSuggestionFromBiblionumber { my $query = q{ SELECT suggestionid FROM suggestions - WHERE biblionumber=? + WHERE biblionumber=? LIMIT 1 }; my $dbh=C4::Context->dbh; my $sth = $dbh->prepare($query); $sth->execute($biblionumber); - my ($ordernumber) = $sth->fetchrow; - return $ordernumber; + my ($suggestionid) = $sth->fetchrow; + return $suggestionid; +} + +=head2 GetSuggestionInfoFromBiblionumber + +Get a suggestion and borrower's informations from it's biblionumber. + +return : +all informations (suggestion and borrower) of the suggestion which is related to the biblionumber given. + +=cut + +sub GetSuggestionInfoFromBiblionumber { + my ($biblionumber) = @_; + my $query = qq{ + SELECT suggestions.*, + U1.surname AS surnamesuggestedby, + U1.firstname AS firstnamesuggestedby, + U1.borrowernumber AS borrnumsuggestedby + FROM suggestions + LEFT JOIN borrowers AS U1 ON suggestedby=U1.borrowernumber + WHERE biblionumber = ? LIMIT 1 + }; + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare($query); + $sth->execute($biblionumber); + return $sth->fetchrow_hashref; +} + +=head2 GetSuggestionInfo + +Get a suggestion and borrower's informations from it's suggestionid + +return : +all informations (suggestion and borrower) of the suggestion which is related to the suggestionid given. + +=cut + +sub GetSuggestionInfo { + my ($suggestionid) = @_; + my $query = qq{ + SELECT suggestions.*, + U1.surname AS surnamesuggestedby, + U1.firstname AS firstnamesuggestedby, + U1.borrowernumber AS borrnumsuggestedby + FROM suggestions + LEFT JOIN borrowers AS U1 ON suggestedby=U1.borrowernumber + WHERE suggestionid = ? LIMIT 1 + }; + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare($query); + $sth->execute($suggestionid); + return $sth->fetchrow_hashref; } =head2 GetSuggestionByStatus diff --git a/acqui/basket.pl b/acqui/basket.pl index c528156..5d4faa3 100755 --- a/acqui/basket.pl +++ b/acqui/basket.pl @@ -34,6 +34,8 @@ use C4::Debug; use C4::Biblio; use C4::Members qw/GetMember/; #needed for permissions checking for changing basketgroup of a basket use C4::Items; +use C4::Suggestions; + =head1 NAME basket.pl @@ -237,6 +239,7 @@ if ( $op eq 'delete_confirm' ) { my $qty_total; my @books_loop; + my $suggestion; for my $order ( @results ) { my $rrp = $order->{'listprice'} || 0; @@ -303,6 +306,12 @@ if ( $op eq 'delete_confirm' ) { } else { $line{'title'} = "Deleted bibliographic notice, can't find title."; } + + $suggestion = GetSuggestionInfoFromBiblionumber($line{biblionumber}); + $line{suggestionid} = $suggestion->{suggestionid}; + $line{surnamesuggestedby} = $suggestion->{surnamesuggestedby}; + $line{firstnamesuggestedby} = $suggestion->{firstnamesuggestedby}; + push @books_loop, \%line; } diff --git a/acqui/neworderempty.pl b/acqui/neworderempty.pl index 459dfe8..4c3daaf 100755 --- a/acqui/neworderempty.pl +++ b/acqui/neworderempty.pl @@ -204,6 +204,9 @@ else { #modify order $booksellerid = $data2->{'booksellerid'}; } +my $suggestion; +$suggestion = GetSuggestionInfo($suggestionid) if $suggestionid; + # get currencies (for change rates calcs if needed) my $active_currency = GetCurrency(); my $default_currency; @@ -359,7 +362,9 @@ $template->param( authorisedbyname => $basket->{'authorisedbyname'}, closedate => C4::Dates->new($basket->{'closedate'},'iso')->output, # order details - suggestionid => $suggestionid, + suggestionid => $suggestion->{suggestionid}, + surnamesuggestedby => $suggestion->{surnamesuggestedby}, + firstnamesuggestedby => $suggestion->{firstnamesuggestedby}, biblionumber => $biblionumber, uncertainprice => $data->{'uncertainprice'}, authorisedbyname => $borrower->{'firstname'} . " " . $borrower->{'surname'}, diff --git a/acqui/orderreceive.pl b/acqui/orderreceive.pl index 753071d..451f858 100755 --- a/acqui/orderreceive.pl +++ b/acqui/orderreceive.pl @@ -75,6 +75,7 @@ use C4::Members; use C4::Branch; # GetBranches use C4::Items; use C4::Biblio; +use C4::Suggestions; my $input = new CGI; @@ -135,6 +136,8 @@ if ( $count == 1 ) { @$results[0]->{'unitprice'} = ''; } + my $suggestion = GetSuggestionInfoFromBiblionumber(@$results[0]->{'biblionumber'}); + my $authorisedby = @$results[0]->{'authorisedby'}; my $member = GetMember( borrowernumber => $authorisedby ); @@ -167,7 +170,10 @@ if ( $count == 1 ) { invoice => $invoice, datereceived => $datereceived->output(), datereceived_iso => $datereceived->output('iso'), - notes => $order->{notes} + notes => $order->{notes}, + suggestionid => $suggestion->{suggestionid}, + surnamesuggestedby => $suggestion->{surnamesuggestedby}, + firstnamesuggestedby => $suggestion->{firstnamesuggestedby}, ); } else { diff --git a/acqui/parcel.pl b/acqui/parcel.pl index c256c60..46582d3 100755 --- a/acqui/parcel.pl +++ b/acqui/parcel.pl @@ -67,6 +67,7 @@ use C4::Items; use CGI; use C4::Output; use C4::Dates qw/format_date format_date_in_iso/; +use C4::Suggestions; use JSON; my $input=new CGI; @@ -178,6 +179,11 @@ for (my $i = 0 ; $i < $countlines ; $i++) { $totalprice += $parcelitems[$i]->{'unitprice'}; $line{unitprice} = sprintf($cfstr, $parcelitems[$i]->{'unitprice'}); + my $suggestion = GetSuggestionInfoFromBiblionumber($line{biblionumber}); + $line{suggestionid} = $suggestion->{suggestionid}; + $line{surnamesuggestedby} = $suggestion->{surnamesuggestedby}; + $line{firstnamesuggestedby} = $suggestion->{firstnamesuggestedby}; + #double FIXME - totalfreight is redefined later. # FIXME - each order in a parcel holds the freight for the whole parcel. This means if you receive a parcel with items from multiple budgets, you'll see the freight charge in each budget.. @@ -230,7 +236,12 @@ for (my $i = 0 ; $i < $countpendings ; $i++) { $itemholds += $nb; } } - + + my $suggestion = GetSuggestionInfoFromBiblionumber($line{biblionumber}); + $line{suggestionid} = $suggestion->{suggestionid}; + $line{surnamesuggestedby} = $suggestion->{surnamesuggestedby}; + $line{firstnamesuggestedby} = $suggestion->{firstnamesuggestedby}; + # if the biblio is not in other orders and if there is no items elsewhere and no subscriptions and no holds we can then show the link "Delete order and Biblio" see bug 5680 $line{can_del_bib} = 1 if $countbiblio <= 1 && $itemcount == scalar @items && !(@subscriptions) && !($holds); $line{items} = ($itemcount) - (scalar @items); diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt index aaea6c0..1632278 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt @@ -283,6 +283,12 @@ [% IF ( books_loo.issn ) %] - [% books_loo.issn %][% END %] [% IF ( books_loo.publishercode ) %], [% books_loo.publishercode %][% END %] [% IF ( books_loo.publicationyear ) %], [% books_loo.publicationyear %][% END %] + [% IF ( books_loo.suggestionid ) %] +
    + Suggested by [% books_loo.surnamesuggestedby %] + [% IF ( books_loo.firstnamesuggestedby ) %],?[% books_loo.firstnamesuggestedby %] [% END %] + (from suggestion #[% books_loo.suggestionid %]) + [% END %]

    [% books_loo.rrp %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt index a6f26c4..411980a 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt @@ -166,7 +166,6 @@ $(document).ready(function() [% ELSE %] New order [% END %] - [% IF ( suggestionid ) %](defined from suggestion #[% suggestionid %])[% END %] [% IF ( basketno ) %] @@ -310,6 +309,19 @@ $(document).ready(function() [% END %] + + [% IF ( suggestionid ) %] +
    + Suggestion +
      +
    1. + Suggested by + [% surnamesuggestedby %][% IF ( firstnamesuggestedby ) %],?[% firstnamesuggestedby %][% END %] (from suggestion #[% suggestionid %]) +
    2. +
    +
    + [% END %] + [% IF ( items ) %]
    Item diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt index ea422c8..fe8287d 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt @@ -35,6 +35,19 @@ [% seriestitle %]
  • + + [% IF ( suggestionid ) %] +
    + Suggestion +
      +
    1. + Suggested by + [% surnamesuggestedby %][% IF ( firstnamesuggestedby ) %],?[% firstnamesuggestedby %][% END %] (from suggestion #[% suggestionid %]) +
    2. +
    +
    + [% END %] + [% IF ( items ) %]
    Item diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt index eb5492e..34a55b0 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt @@ -241,6 +241,12 @@ [% IF ( loop_order.author ) %] by [% loop_order.author %][% END %] [% IF ( loop_order.isbn ) %] – [% loop_order.isbn %][% END %] [% IF ( loop_order.publishercode ) %]
    Publisher :[% loop_order.publishercode %][% END %] + [% IF ( loop_order.suggestionid ) %] +
    + Suggested by [% loop_order.surnamesuggestedby %] + [% IF ( loop_order.firstnamesuggestedby ) %],?[% loop_order.firstnamesuggestedby %] [% END %] + (from suggestion #[% loop_order.suggestionid %]) + [% END %] MARC | Card [% loop_order.quantity %] @@ -361,6 +367,12 @@ [% IF ( loop_receive.author ) %] / [% loop_receive.author %][% END %] [% IF ( loop_receive.isbn ) %] - [% loop_receive.isbn %][% END %] [% IF ( loop_receive.publishercode ) %]
    Publisher :[% loop_receive.publishercode %][% END %] + [% IF ( loop_receive.suggestionid ) %] +
    + Suggested by [% loop_receive.surnamesuggestedby %] + [% IF ( loop_receive.firstnamesuggestedby ) %],?[% loop_receive.firstnamesuggestedby %] [% END %] + (from suggestion #[% loop_receive.suggestionid %] + [% END %] MARC | Card [% loop_receive.quantityreceived %] diff --git a/t/db_dependent/Suggestions.t b/t/db_dependent/Suggestions.t index 001dc24..f285929 100644 --- a/t/db_dependent/Suggestions.t +++ b/t/db_dependent/Suggestions.t @@ -9,16 +9,20 @@ use Data::Dumper; use C4::Suggestions; -use Test::More tests =>6; +use Test::More tests =>9; BEGIN { use_ok('C4::Suggestions'); } -my ($suggestionid, $suggestion, $status); +my ($suggestionid, $suggestion, $status, $biblionumber); +$biblionumber = 1; ok($suggestionid= NewSuggestion( {title=>'Petit trait? de philosohpie',author=>'Hubert de Chardass?',publishercode=>'Albin Michel'} ), "NewSuggestion OK"); ok($suggestion= GetSuggestion( $suggestionid), "GetSuggestion OK"); ok($status= ModSuggestion( {title=>'test Modif Simple', suggestionid=>$suggestionid} ), "ModSuggestion Simple OK"); ok($status= ModSuggestion( {STATUS=>'STALLED', suggestionid=>$suggestionid} ), "ModSuggestion Status OK"); +ok($status= ModSuggestion( {suggestionid => $suggestionid, biblionumber => $biblionumber } ), "ModSuggestion, set biblionumber OK" ); +ok($suggestion= GetSuggestionFromBiblionumber( $biblionumber ), "GetSuggestionFromBiblionumber OK"); +ok($suggestion= GetSuggestionInfoFromBiblionumber( $biblionumber ), "GetSuggestionInfoFromBiblionumber OK"); ok(@{SearchSuggestion( {STATUS=>'STALLED'} )}>0, "SearchSuggestion Status OK"); -- 1.7.7.3 From julian.maurice at biblibre.com Thu Jan 19 09:43:24 2012 From: julian.maurice at biblibre.com (julian.maurice at biblibre.com) Date: Thu, 19 Jan 2012 09:43:24 +0100 Subject: [Koha-patches] [PATCH 1/2] [SIGNED-OFF] Updating perlcriticrc to allow Modern::Perl to suffice instead of use warnings; and use strict; Message-ID: <1326962605-659-1-git-send-email-julian.maurice@biblibre.com> From: Chris Cormack http://bugs.koha-community.org/show_bug.cgi?id=6836 Signed-off-by: Julian Maurice --- t/perlcriticrc | 8 +++++++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/t/perlcriticrc b/t/perlcriticrc index 287273c..69b3d74 100644 --- a/t/perlcriticrc +++ b/t/perlcriticrc @@ -2,4 +2,10 @@ exclude = Miscellanea::RequireRcsKeywords [Perl::Critic::Policy::BuiltinFunctions::ProhibitStringyEval] -allow_includes =1 \ No newline at end of file +allow_includes =1 + +[TestingAndDebugging::RequireUseStrict] +equivalent_modules = Modern::Perl + +[TestingAndDebugging::RequireUseWarnings] +equivalent_modules = Modern::Perl \ No newline at end of file -- 1.7.8.3 From julian.maurice at biblibre.com Thu Jan 19 09:43:25 2012 From: julian.maurice at biblibre.com (julian.maurice at biblibre.com) Date: Thu, 19 Jan 2012 09:43:25 +0100 Subject: [Koha-patches] [PATCH 2/2] [SIGNED-OFF] Bug 6836: Adding dependency on Modern::Perl In-Reply-To: <1326962605-659-1-git-send-email-julian.maurice@biblibre.com> References: <1326962605-659-1-git-send-email-julian.maurice@biblibre.com> Message-ID: <1326962605-659-2-git-send-email-julian.maurice@biblibre.com> From: Chris Cormack Signed-off-by: Julian Maurice --- C4/Installer/PerlDependencies.pm | 5 +++++ debian/control | 1 + 2 files changed, 6 insertions(+), 0 deletions(-) diff --git a/C4/Installer/PerlDependencies.pm b/C4/Installer/PerlDependencies.pm index 5b3023c..9f1a4b8 100644 --- a/C4/Installer/PerlDependencies.pm +++ b/C4/Installer/PerlDependencies.pm @@ -479,6 +479,11 @@ our $PERL_DEPS = { 'required' => '0', 'min_ver' => '1.03', }, + 'Modern::Perl' => { + 'usage' => 'Core', + 'required' => '1', + 'min_ver' => '1.03', + }, }; 1; diff --git a/debian/control b/debian/control index 0384e18..e0827f9 100644 --- a/debian/control +++ b/debian/control @@ -46,6 +46,7 @@ Build-Depends: libcgi-session-driver-memcached-perl, libmarc-xml-perl, libmemoize-memcached-perl, libmime-lite-perl, + libmodern-perl-perl, libnet-ldap-perl, libnet-server-perl, libnet-z3950-zoom-perl, -- 1.7.8.3 From M.de.Rooy at rijksmuseum.nl Thu Jan 19 10:55:23 2012 From: M.de.Rooy at rijksmuseum.nl (Marcel de Rooy) Date: Thu, 19 Jan 2012 09:55:23 +0000 Subject: [Koha-patches] [PATCH] Bug 3264 UnCloneField() / minus button in MARC editor can clear all subfields (authorities AND biblio) In-Reply-To: <1326966709-24356-1-git-send-email-m.de.rooy@rijksmuseum.nl> References: <1326966709-24356-1-git-send-email-m.de.rooy@rijksmuseum.nl> Message-ID: <809BE39CD64BFD4EB9036172EBCCFA31033C7A34@S-MAIL-1A.rijksmuseum.intra> All subfields following the removed subfield were not saved. Problem is in C4/Biblio routine TransformHtmlToMarc. If the field is emptied, the param list contains a code param but no subfield param. The while loop handling the subfields could not handle that. Also added a FIXME because the whole routine depends on an assumption about the order of cgi parameters that is not strictly guaranteed. --- C4/Biblio.pm | 27 ++++++++++++++++----------- 1 files changed, 16 insertions(+), 11 deletions(-) diff --git a/C4/Biblio.pm b/C4/Biblio.pm index 9e84ffd..a790f1d 100644 --- a/C4/Biblio.pm +++ b/C4/Biblio.pm @@ -2137,6 +2137,7 @@ sub TransformHtmlToMarc { my $record = MARC::Record->new(); my $i = 0; my @fields; +#FIXME This code assumes that the CGI params will be in the same order as the fields in the template; this is no absolute guarantee! while ( $params[$i] ) { # browse all CGI params my $param = $params[$i]; my $newfield = 0; @@ -2176,19 +2177,23 @@ sub TransformHtmlToMarc { # > 009, deal with subfields } else { - while ( defined $params[$j] && $params[$j] =~ /_code_/ ) { # browse all it's subfield - my $inner_param = $params[$j]; - if ($newfield) { - if ( $cgi->param( $params[ $j + 1 ] ) ne '' ) { # only if there is a value (code => value) - $newfield->add_subfields( $cgi->param($inner_param) => $cgi->param( $params[ $j + 1 ] ) ); - } - } else { - if ( $cgi->param( $params[ $j + 1 ] ) ne '' ) { # creating only if there is a value (code => value) - $newfield = MARC::Field->new( $tag, $ind1, $ind2, $cgi->param($inner_param) => $cgi->param( $params[ $j + 1 ] ), ); - } + # browse subfields for this tag (reason for _code_ match) + while(defined $params[$j] && $params[$j] =~ /_code_/) { + last unless defined $params[$j+1]; + #if next param ne subfield, then it was probably empty + #try next param by incrementing j + if($params[$j+1]!~/_subfield_/) {$j++; next; } + my $fval= $cgi->param($params[$j+1]); + #check if subfield value not empty and field exists + if($fval ne '' && $newfield) { + $newfield->add_subfields( $cgi->param($params[$j]) => $fval); + } + elsif($fval ne '') { + $newfield = MARC::Field->new( $tag, $ind1, + $ind2, $cgi->param($params[$j]) => $fval ); } $j += 2; - } + } #end-of-while + $i= $j-1; #update i for outer loop accordingly } push @fields, $newfield if ($newfield); } -- 1.6.0.6 From jonathan.druart at biblibre.com Thu Jan 19 10:58:46 2012 From: jonathan.druart at biblibre.com (Jonathan Druart) Date: Thu, 19 Jan 2012 10:58:46 +0100 Subject: [Koha-patches] [PATCH 1/1] [SIGNED-OFF] Bug 6752: Be stricter with utf-8 encoding of output Message-ID: <1326967126-9730-1-git-send-email-jonathan.druart@biblibre.com> From: Colin Campbell use encoding(UTF-8) rather than utf-8 for stricter encoding Marking output as ':utf8' only flags the data as utf8 using :encoding(UTF-8) also checks it as valid utf-8 see binmode in perlfunc for more details In accordance with the robustness principle input filehandles have not been changed as code may make the undocumented assumption that invalid utf-8 is present in the imput Fixes errors reported by t/00-testcritic.t Where feasable some filehandles have been made lexical rather than reusing global filehandle vars --- admin/aqplan.pl | 2 +- authorities/authorities-list.pl | 2 +- misc/cronjobs/MARC21_parse_test.pl | 2 +- misc/cronjobs/overdue_notices.pl | 2 +- .../22_to_30/export_Authorities_xml.pl | 6 ++-- misc/migration_tools/bulkmarcimport.pl | 2 +- misc/migration_tools/rebuild_zebra.pl | 28 ++++++++++---------- misc/sax_parser_test.pl | 2 +- misc/translator/xgettext.pl | 2 +- opac/ilsdi.pl | 2 +- opac/oai.pl | 2 +- reports/guided_reports.pl | 2 +- reports/serials_stats.pl | 2 +- svc/bib | 2 +- svc/new_bib | 2 +- t/db_dependent/lib/KohaTest.pm | 6 ++-- tools/export.pl | 2 +- 17 files changed, 34 insertions(+), 34 deletions(-) diff --git a/admin/aqplan.pl b/admin/aqplan.pl index 9c75431..ffb1145 100755 --- a/admin/aqplan.pl +++ b/admin/aqplan.pl @@ -463,7 +463,7 @@ output_html_with_http_headers $input, $cookie, $template->output; sub _print_to_csv { my ( $header, $results ) = @_; - binmode STDOUT, ":encoding(UTF-8)"; + binmode STDOUT, ':encoding(UTF-8)'; my $csv = Text::CSV_XS->new( { sep_char => $del, diff --git a/authorities/authorities-list.pl b/authorities/authorities-list.pl index eec3233..2b15856 100755 --- a/authorities/authorities-list.pl +++ b/authorities/authorities-list.pl @@ -4,7 +4,7 @@ use warnings; use C4::Context; use C4::AuthoritiesMarc; use utf8; -use open qw( :std :utf8 ); +use open qw[ :std :encoding(utf8) ]; my $dbh=C4::Context->dbh; my $datatypes_query = $dbh->prepare(< ':utf8'; +use open OUT => ':encoding(UTF-8)'; use Getopt::Long qw(:config auto_help auto_version); use Pod::Usage; diff --git a/misc/cronjobs/overdue_notices.pl b/misc/cronjobs/overdue_notices.pl index 71e6a05..5896abd 100755 --- a/misc/cronjobs/overdue_notices.pl +++ b/misc/cronjobs/overdue_notices.pl @@ -323,7 +323,7 @@ if (@branchcodes) { # these are the fields that will be substituted into <> my @item_content_fields = split( /,/, $itemscontent ); -binmode( STDOUT, ":utf8" ); +binmode STDOUT, ':encoding(UTF-8)'; our $csv; # the Text::CSV_XS object diff --git a/misc/migration_tools/22_to_30/export_Authorities_xml.pl b/misc/migration_tools/22_to_30/export_Authorities_xml.pl index 70647ee..42d2e5c 100755 --- a/misc/migration_tools/22_to_30/export_Authorities_xml.pl +++ b/misc/migration_tools/22_to_30/export_Authorities_xml.pl @@ -23,7 +23,7 @@ $rq->execute; #ATTENTION : Mettre la base en utf8 auparavant. #BEWARE : Set database into utf8 before. while (my ($authid)=$rq->fetchrow){ -open FILEOUTPUT,">:utf8", "./$filename/$authid.xml" or die "unable to open $filename"; +open my $fileoutput, '>:encoding(UTF-8)', "./$filename/$authid.xml" or die "unable to open $filename"; my $record=AUTHgetauthority($dbh,$authid); if (! utf8::is_utf8($record)) { utf8::decode($record); @@ -44,7 +44,7 @@ open FILEOUTPUT,">:utf8", "./$filename/$authid.xml" or die "unable to open $file # } else { # $record->encoding( 'UTF-8' ); # } - print FILEOUTPUT $record->as_xml(); -close FILEOUPUT; + print {$fileoutput} $record->as_xml(); +close $fileoutput; } diff --git a/misc/migration_tools/bulkmarcimport.pl b/misc/migration_tools/bulkmarcimport.pl index 4f738e8..70d5eb7 100755 --- a/misc/migration_tools/bulkmarcimport.pl +++ b/misc/migration_tools/bulkmarcimport.pl @@ -30,7 +30,7 @@ use Getopt::Long; use IO::File; use Pod::Usage; -binmode(STDOUT, ":utf8"); +binmode STDOUT, ':encoding(UTF-8)'; my ( $input_marc_file, $number, $offset) = ('',0,0); my ($version, $delete, $test_parameter, $skip_marc8_conversion, $char_encoding, $verbose, $commit, $fk_off,$format,$biblios,$authorities,$keepids,$match, $isbn_check, $logfile); my ($sourcetag,$sourcesubfield,$idmapfl); diff --git a/misc/migration_tools/rebuild_zebra.pl b/misc/migration_tools/rebuild_zebra.pl index cd12277..31e8125 100755 --- a/misc/migration_tools/rebuild_zebra.pl +++ b/misc/migration_tools/rebuild_zebra.pl @@ -309,7 +309,7 @@ sub export_marc_records_from_sth { my ($record_type, $sth, $directory, $as_xml, $noxml, $nosanitize) = @_; my $num_exported = 0; - open (OUT, ">:utf8 ", "$directory/exported_records") or die $!; + open my $fh, '>:encoding(UTF-8) ', "$directory/exported_records" or die $!; my $i = 0; my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField("items.itemnumber",''); while (my ($record_number) = $sth->fetchrow_array) { @@ -337,7 +337,7 @@ sub export_marc_records_from_sth { } } if ( $marcxml ) { - print OUT $marcxml if $marcxml; + print {$fh} $marcxml if $marcxml; $num_exported++; } next; @@ -350,7 +350,7 @@ sub export_marc_records_from_sth { # to care, though, at least if you're using the GRS-1 filter. It does # care if you're using the DOM filter, which requires valid XML file(s). eval { - print OUT ($as_xml) ? $marc->as_xml_record(C4::Context->preference('marcflavour')) : $marc->as_usmarc(); + print {$fh} ($as_xml) ? $marc->as_xml_record(C4::Context->preference('marcflavour')) : $marc->as_usmarc(); $num_exported++; }; if ($@) { @@ -359,7 +359,7 @@ sub export_marc_records_from_sth { } } print "\nRecords exported: $num_exported\n" if ( $verbose_logging ); - close OUT; + close $fh; return $num_exported; } @@ -367,7 +367,7 @@ sub export_marc_records_from_list { my ($record_type, $entries, $directory, $as_xml, $noxml, $records_deleted) = @_; my $num_exported = 0; - open (OUT, ">:utf8 ", "$directory/exported_records") or die $!; + open my $fh, '>:encoding(UTF-8)', "$directory/exported_records" or die $!; my $i = 0; # Skip any deleted records. We check for this anyway, but this reduces error spam @@ -384,12 +384,12 @@ sub export_marc_records_from_list { # strung together with no single root element. zebraidx doesn't seem # to care, though, at least if you're using the GRS-1 filter. It does # care if you're using the DOM filter, which requires valid XML file(s). - print OUT ($as_xml) ? $marc->as_xml_record(C4::Context->preference('marcflavour')) : $marc->as_usmarc(); + print {$fh} ($as_xml) ? $marc->as_xml_record(C4::Context->preference('marcflavour')) : $marc->as_usmarc(); $num_exported++; } } print "\nRecords exported: $num_exported\n" if ( $verbose_logging ); - close OUT; + close $fh; return $num_exported; } @@ -397,7 +397,7 @@ sub generate_deleted_marc_records { my ($record_type, $entries, $directory, $as_xml) = @_; my $records_deleted = {}; - open (OUT, ">:utf8 ", "$directory/exported_records") or die $!; + open my $fh, '>:encoding(UTF-8)', "$directory/exported_records" or die $!; my $i = 0; foreach my $record_number (map { $_->{biblio_auth_number} } @$entries ) { print "\r$i" unless ($i++ %100 or !$verbose_logging); @@ -413,12 +413,12 @@ sub generate_deleted_marc_records { fix_unimarc_100($marc); } - print OUT ($as_xml) ? $marc->as_xml_record(C4::Context->preference("marcflavour")) : $marc->as_usmarc(); + print {$fh} ($as_xml) ? $marc->as_xml_record(C4::Context->preference("marcflavour")) : $marc->as_usmarc(); $records_deleted->{$record_number} = 1; } print "\nRecords exported: $i\n" if ( $verbose_logging ); - close OUT; + close $fh; return $records_deleted; @@ -824,8 +824,8 @@ if ($authorities) { # AUTHORITIES : copying mandatory files # unless (-f C4::Context->zebraconfig('authorityserver')->{config}) { - open ZD,">:utf8 ",C4::Context->zebraconfig('authorityserver')->{config}; - print ZD " + open my $zd, '>:encoding(UTF-8)' ,C4::Context->zebraconfig('authorityserver')->{config}; + print {$zd} " # generated by KOHA/misc/migration_tools/rebuild_zebra.pl profilePath:\${srcdir:-.}:$authorityserverdir/tab/:$tabdir/tab/:\${srcdir:-.}/tab/ @@ -969,8 +969,8 @@ if ($biblios) { # BIBLIOS : copying mandatory files # unless (-f C4::Context->zebraconfig('biblioserver')->{config}) { - open ZD,">:utf8 ",C4::Context->zebraconfig('biblioserver')->{config}; - print ZD " + open my $zd, '>:encoding(UTF-8)', C4::Context->zebraconfig('biblioserver')->{config}; + print {$zd} " # generated by KOHA/misc/migrtion_tools/rebuild_zebra.pl profilePath:\${srcdir:-.}:$biblioserverdir/tab/:$tabdir/tab/:\${srcdir:-.}/tab/ diff --git a/misc/sax_parser_test.pl b/misc/sax_parser_test.pl index b2e5974..fb56de1 100755 --- a/misc/sax_parser_test.pl +++ b/misc/sax_parser_test.pl @@ -9,7 +9,7 @@ use Encode; my $parser = XML::SAX::ParserFactory->parser( Handler => MySAXHandler->new ); -binmode STDOUT, ":utf8"; +binmode STDOUT, ':encoding(UTF-8)'; print "\x{65}\x{301}\n"; $parser->parse_string(encode_utf8("\x{65}\x{301}")); $parser->parse_string("\xEF\xBB\xBF\x{65}\x{301}"); diff --git a/misc/translator/xgettext.pl b/misc/translator/xgettext.pl index 21e3fc5..f7a940b 100755 --- a/misc/translator/xgettext.pl +++ b/misc/translator/xgettext.pl @@ -351,7 +351,7 @@ if (defined $output && $output ne '-') { print STDERR "$0: Outputting to STDOUT...\n" if $verbose_p; open(OUTPUT, ">&STDOUT"); } -#binmode( OUTPUT, ":utf8" ); +binmode OUTPUT, ':encoding(UTF-8)'; if (defined $files_from) { print STDERR "$0: Opening input file list \"$files_from\"\n" if $verbose_p; diff --git a/opac/ilsdi.pl b/opac/ilsdi.pl index 48fd7ba..419c0f2 100755 --- a/opac/ilsdi.pl +++ b/opac/ilsdi.pl @@ -228,7 +228,7 @@ if ( $service and any { $service eq $_ } @services ) { } # Output XML by passing the hashref to XMLOut -binmode(STDOUT, ":utf8"); +binmode STDOUT, ':encoding(UTF-8)'; print CGI::header('-type'=>'text/xml', '-charset'=>'utf-8'); print XMLout( $out, diff --git a/opac/oai.pl b/opac/oai.pl index 038b6d1..2ef3f28 100755 --- a/opac/oai.pl +++ b/opac/oai.pl @@ -41,7 +41,7 @@ else { ); } -binmode( STDOUT, ":utf8" ); +binmode STDOUT, ':encoding(UTF-8)'; my $repository = C4::OAI::Repository->new(); # __END__ Main Prog diff --git a/reports/guided_reports.pl b/reports/guided_reports.pl index f5667a2..27377e0 100755 --- a/reports/guided_reports.pl +++ b/reports/guided_reports.pl @@ -539,7 +539,7 @@ elsif ($phase eq 'Run this report'){ } elsif ($phase eq 'Export'){ - binmode STDOUT, ':utf8'; + binmode STDOUT, ':encoding(UTF-8)'; # export results to tab separated text or CSV my $sql = $input->param('sql'); # FIXME: use sql from saved report ID#, not new user-supplied SQL! diff --git a/reports/serials_stats.pl b/reports/serials_stats.pl index 640ef60..88918cc 100755 --- a/reports/serials_stats.pl +++ b/reports/serials_stats.pl @@ -103,7 +103,7 @@ if($do_it){ $template->param(datas => \@datas, do_it => 1); }else{ - binmode STDOUT, ':utf8'; + binmode STDOUT, ':encoding(UTF-8)'; print $input->header(-type => 'application/vnd.sun.xml.calc', -encoding => 'utf-8', -name => "$basename.csv", diff --git a/svc/bib b/svc/bib index 29121ca..4808559 100755 --- a/svc/bib +++ b/svc/bib @@ -27,7 +27,7 @@ use C4::Biblio; use XML::Simple; my $query = new CGI; -binmode STDOUT, ":utf8"; +binmode STDOUT, ':encoding(UTF-8)'; my ($status, $cookie, $sessionID) = check_api_auth($query, { editcatalogue => 'edit_catalogue'} ); unless ($status eq "ok") { diff --git a/svc/new_bib b/svc/new_bib index b84eaea..dba1fc7 100755 --- a/svc/new_bib +++ b/svc/new_bib @@ -28,7 +28,7 @@ use XML::Simple; use C4::Charset; my $query = new CGI; -binmode STDOUT, ":utf8"; +binmode STDOUT, ':encoding(UTF-8)'; my ($status, $cookie, $sessionID) = check_api_auth($query, { editcatalogue => 'edit_catalogue'} ); unless ($status eq "ok") { diff --git a/t/db_dependent/lib/KohaTest.pm b/t/db_dependent/lib/KohaTest.pm index 70c963d..d8cf495 100644 --- a/t/db_dependent/lib/KohaTest.pm +++ b/t/db_dependent/lib/KohaTest.pm @@ -625,11 +625,11 @@ sub reindex_marc { mkdir "$directory/$record_type"; my $sth = $dbh->prepare($record_type eq "biblio" ? "SELECT marc FROM biblioitems" : "SELECT marc FROM auth_header"); $sth->execute(); - open OUT, ">:utf8", "$directory/$record_type/records"; + open my $out, '>:encoding(UTF-8)', "$directory/$record_type/records"; while (my ($blob) = $sth->fetchrow_array) { - print OUT $blob; + print {$out} $blob; } - close OUT; + close $out; my $zebra_server = "${record_type}server"; my $zebra_config = C4::Context->zebraconfig($zebra_server)->{'config'}; my $zebra_db_dir = C4::Context->zebraconfig($zebra_server)->{'directory'}; diff --git a/tools/export.pl b/tools/export.pl index 4b3e3f5..66763d6 100755 --- a/tools/export.pl +++ b/tools/export.pl @@ -56,7 +56,7 @@ my ($template, $loggedinuser, $cookie) } if ($op eq "export") { - binmode(STDOUT,":utf8"); + binmode STDOUT, ':encoding(UTF-8)'; print $query->header( -type => 'application/octet-stream', -charset => 'utf-8', -attachment=>$filename); -- 1.7.7.3 From julian.maurice at biblibre.com Thu Jan 19 11:04:28 2012 From: julian.maurice at biblibre.com (julian.maurice at biblibre.com) Date: Thu, 19 Jan 2012 11:04:28 +0100 Subject: [Koha-patches] [PATCH] [SIGNED-OFF] Update CircAutoPrintQuickSlip description Message-ID: <1326967468-4541-1-git-send-email-julian.maurice@biblibre.com> From: "Nicole C. Engard" This patch simply removes the repeated string in the description for this preference. http://bugs.koha-community.org/show_bug.cgi?id=7429 Signed-off-by: Julian Maurice --- .../en/modules/admin/preferences/circulation.pref | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref index 817ce57..30bcb9b 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -92,7 +92,7 @@ Circulation: no: "Don't record" - local use when an unissued item is checked in. - - - When an empty an empty barcode field is submitted in circulation + - When an empty barcode field is submitted in circulation - pref: CircAutoPrintQuickSlip choices: yes: "open a print quick slip window" -- 1.7.8.3 From oleonard at myacpl.org Thu Jan 19 18:52:13 2012 From: oleonard at myacpl.org (Owen Leonard) Date: Thu, 19 Jan 2012 12:52:13 -0500 Subject: [Koha-patches] [PATCH] Bug 5877 Follow-up for Offline circulation improvements Message-ID: <1326995533-28743-1-git-send-email-oleonard@myacpl.org> Internationalization fix: Offline circulation operations in Circulation.pm return English strings for display in the template. These strings can't be translated, so we must check their values in the JavaScript and return a translatable string based on their values. Interface change: Switching to text links for checking/unchecking checkboxes since that is more consistent with other areas in Koha. --- C4/Circulation.pm | 2 +- .../prog/en/modules/offline_circ/list.tt | 38 +++++++++++++++++--- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/C4/Circulation.pm b/C4/Circulation.pm index 00cdc10..1e013b2 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -3105,7 +3105,7 @@ sub ProcessOfflineIssue { if ( $borrower->{borrowernumber} ) { my $itemnumber = C4::Items::GetItemnumberFromBarcode( $operation->{barcode} ); unless ($itemnumber) { - return "barcode not found"; + return "Barcode not found."; } my $issue = GetOpenIssue( $itemnumber ); diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/list.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/list.tt index 8b1f69b..e286cc8 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/list.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/list.tt @@ -2,10 +2,20 @@ Koha › Circulation › Offline Circulation [% INCLUDE "doc-head-close.inc" %] + @@ -42,11 +69,12 @@ [% IF ( pending_operations ) %]
    - +

    | +

    - + -- 1.7.3 From alex.arnaud at biblibre.com Fri Jan 20 10:02:42 2012 From: alex.arnaud at biblibre.com (alex.arnaud at biblibre.com) Date: Fri, 20 Jan 2012 10:02:42 +0100 Subject: [Koha-patches] [PATCH] bug 7343 - Fix empty values in statistic 1 and 2 dropboxes in neworderempty Message-ID: <1327050162-9133-1-git-send-email-alex.arnaud@biblibre.com> From: Alex Arnaud --- acqui/fetch_sort_dropbox.pl | 93 ++++++++++++++++++++ .../prog/en/modules/acqui/neworderempty.tt | 10 +- 2 files changed, 98 insertions(+), 5 deletions(-) create mode 100755 acqui/fetch_sort_dropbox.pl diff --git a/acqui/fetch_sort_dropbox.pl b/acqui/fetch_sort_dropbox.pl new file mode 100755 index 0000000..95b7b20 --- /dev/null +++ b/acqui/fetch_sort_dropbox.pl @@ -0,0 +1,93 @@ +#!/usr/bin/perl + +# Copyright 2008-2009 BibLibre SARL +# +# 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. + +use strict; +use warnings; +use CGI; +use C4::Context; +use C4::Output; +use C4::Auth; +use C4::Budgets; + +=head1 NAME + +fetch_sort_dropbox.pl + +=head1 DESCRIPTION + + This script fetches sort values for a given budget id. Currently it is used to dynamically fill + 'Statistic 1' and 'Statistic 2' comboboxes in neworderempty page. Values retrieved depend on + categories of authorized values defined in funds configuration. + +=head1 CGI PARAMETERS + +=over 4 + +=item budget_id + +Budget identifier + +=item sort + +Sort number. 1 or 2 for the moment. + +=back + +=cut + +my $input = new CGI; + +my $budget_id = $input->param('budget_id'); +my $sort_id = $input->param('sort'); + +my ( $template, $loggedinuser, $cookie ) = get_template_and_user( + { template_name => "acqui/ajax.tmpl", + query => $input, + type => "intranet", + authnotrequired => 0, + flagsrequired => {editcatalogue => 'edit_catalogue'}, + debug => 0, + } +); + +my $budget = GetBudget($budget_id); +my $dropbox_values = GetAuthvalueDropbox( $budget->{'sort'.$sort_id.'_authcat'}, '' ); + +my @authorised_values; +my %authorised_lib; + +foreach ( @$dropbox_values) { + push @authorised_values, $_->{value}; + $authorised_lib{$_->{value}} = $_->{label}; +} + +my $budget_authvalue_dropbox = CGI::scrolling_list( + -values => \@authorised_values, + -labels => \%authorised_lib, + -default => $authorised_values[0], +); + + +# strip off select tags +$budget_authvalue_dropbox =~ s/^\//; +$budget_authvalue_dropbox =~ s/\<\/select\>$//; +chomp $budget_authvalue_dropbox; + +$template->param( return => $budget_authvalue_dropbox ); +output_html_with_http_headers $input, $cookie, $template->output; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt index a6f26c4..e1dbbde 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt @@ -476,9 +476,9 @@ $(document).ready(function() @@ -491,12 +491,12 @@ $(document).ready(function() [% IF CGIsort2 %] - [% FOREACH sort_opt IN CGIsort2 %] [% IF sort_opt.default %] - + [% ELSE %] - + [% END %] [% END %] -- 1.7.0.4 From colin.campbell at ptfs-europe.com Fri Jan 20 16:21:50 2012 From: colin.campbell at ptfs-europe.com (Colin Campbell) Date: Fri, 20 Jan 2012 15:21:50 +0000 Subject: [Koha-patches] [PATCH] Bug 7454 Initialize return arrays in ILS/Transaction/RenewAll Message-ID: <1327072910-6149-1-git-send-email-colin.campbell@ptfs-europe.com> Explicitly clear these arrays and update them directly. In practice item numbers were already in them when called so that more items were being returned than were actually renewed (or failed) --- C4/SIP/ILS/Transaction/RenewAll.pm | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/C4/SIP/ILS/Transaction/RenewAll.pm b/C4/SIP/ILS/Transaction/RenewAll.pm index a712806..2e49bf7 100644 --- a/C4/SIP/ILS/Transaction/RenewAll.pm +++ b/C4/SIP/ILS/Transaction/RenewAll.pm @@ -38,6 +38,8 @@ sub do_renew_all { my $patron = $self->{patron}; # SIP's patron my $borrower = GetMember('cardnumber'=>$patron->id); # Koha's patron my $all_ok = 1; + $self->{renewed} = []; + $self->{unrenewed} = []; foreach my $itemx (@{$patron->{items}}) { my $item_id = $itemx->{barcode}; my $item = new ILS::Item $item_id; @@ -52,9 +54,9 @@ sub do_renew_all { $self->do_renew_for($borrower); if ($self->ok) { $item->{due_date} = $self->{due}; - push @{$self->renewed }, $item_id; + push @{$self->{renewed} }, $item_id; } else { - push @{$self->unrenewed}, $item_id; + push @{$self->{unrenewed}}, $item_id; } } $self->ok($all_ok); -- 1.7.5.1 From gcollum at gmail.com Fri Jan 20 17:29:52 2012 From: gcollum at gmail.com (Garry Collum) Date: Fri, 20 Jan 2012 11:29:52 -0500 Subject: [Koha-patches] [PATCH] Bug 7114: Fixes the Funds' page display after the Filter link is clicked. Message-ID: <1327076992-1315-1-git-send-email-gcollum@gmail.com> On the funds page there is a Fund Filters form and a menu underneath this form. When the form is hidden the contents of the page shift to the left overlapping the menu. The menu underneath the fund filters form must have been a later edition. This patch removes the line of javascript that shifts the contents of the page after the form is hidden. --- .../prog/en/modules/admin/aqbudgets.tt | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudgets.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudgets.tt index 12a70bc..7fa91f7 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudgets.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudgets.tt @@ -133,7 +133,6 @@ $("#filterbutton").click(function() { $("#fundfilters").slideToggle(0); - $("#content").css({ marginLeft: $("#content").css("marginLeft") == "4em"?"15em":"4em"}); }); }); //]]> -- 1.7.5.4 From gcollum at gmail.com Fri Jan 20 18:31:41 2012 From: gcollum at gmail.com (Garry Collum) Date: Fri, 20 Jan 2012 12:31:41 -0500 Subject: [Koha-patches] [PATCH] Bug 7098: Adds koha_url elements to sco.css. Message-ID: <1327080701-1735-1-git-send-email-gcollum@gmail.com> The 'Powered by Koha' link was not styled in self-cko. The koha_url elements were missing from sco.css. The elements within opac.css were copied and added to sco.css. --- koha-tmpl/opac-tmpl/prog/en/css/sco.css | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/koha-tmpl/opac-tmpl/prog/en/css/sco.css b/koha-tmpl/opac-tmpl/prog/en/css/sco.css index 1b1b5d5..54dfaeb 100644 --- a/koha-tmpl/opac-tmpl/prog/en/css/sco.css +++ b/koha-tmpl/opac-tmpl/prog/en/css/sco.css @@ -226,3 +226,15 @@ div.button a:active { div.button a:active { border : 1px inset #666; } + +div.koha_url { + border-top: none !important; +} +span.koha_url { + position: absolute; + right: 0; +} +a.koha_url { + text-decoration: none; + color: #666666; +} -- 1.7.5.4 From januszop at gmail.com Fri Jan 20 21:47:01 2012 From: januszop at gmail.com (Janusz Kaczmarek) Date: Fri, 20 Jan 2012 21:47:01 +0100 Subject: [Koha-patches] [PATCH] Bug 5572: Changes to sub merge in C4::AuthoritiesMarc to refine authorities merging -- safer version Message-ID: <1327092421-15624-1-git-send-email-januszop@gmail.com> --- C4/AuthoritiesMarc.pm | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-) diff --git a/C4/AuthoritiesMarc.pm b/C4/AuthoritiesMarc.pm index b3c5070..eb3cd99 100644 --- a/C4/AuthoritiesMarc.pm +++ b/C4/AuthoritiesMarc.pm @@ -1338,6 +1338,13 @@ sub merge { $oConnection->option("preferredRecordSyntax"=>$oldSyntax); } #warn scalar(@reccache)." biblios to update"; + #Get a list of authority controlled subfields + $sth = $dbh->prepare("select distinct tagsubfield from auth_subfield_structure where authtypecode=? and tagfield=? and tab >=0 and hidden = 0"); + $sth->execute($authtypecodeto, $auth_tag_to_report_to); + my @subfields_controlled_by_auth_to; + while (my ($tagsubfield) = $sth->fetchrow) { + push @subfields_controlled_by_auth_to, $tagsubfield ; + } # Get All candidate Tags for the change # (This will reduce the search scope in marc records). $sth = $dbh->prepare("select distinct tagfield from marc_subfield_structure where authtypecode=?"); @@ -1370,6 +1377,9 @@ sub merge { $field_to->add_subfields($subfield->[0] =>$subfield->[1]); $exclude.= $subfield->[0]; } + foreach my $subt (@subfields_controlled_by_auth_to) { + $exclude.= $subt; + } $exclude='['.$exclude.']'; # add subfields in $field not included in @record_to my @restore= grep {$_->[0]!~/$exclude/} $field->subfields(); -- 1.7.2.5 From gcollum at gmail.com Sat Jan 21 19:57:58 2012 From: gcollum at gmail.com (Garry Collum) Date: Sat, 21 Jan 2012 13:57:58 -0500 Subject: [Koha-patches] [PATCH] Bug 7318: Fixes category display in patroncards Patron Search results. Message-ID: <1327172278-2470-1-git-send-email-gcollum@gmail.com> Category description and type were not being sent to the template. This patch fixes that issue, which also fixes the display. The display was showing 'Category Description (category type)'. It now displays 'Category Description (category code) to be consistent with the search label. This patch also assigns an empty string to $member to get rid of some 'uninitialized' errors in the logs. --- .../prog/en/modules/patroncards/members-search.tt | 2 +- patroncards/members-search.pl | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/patroncards/members-search.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/patroncards/members-search.tt index 4d651b7..cbd1db5 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/patroncards/members-search.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/patroncards/members-search.tt @@ -114,7 +114,7 @@ function add_item(borrowernum,batch_id,type_id){ - + diff --git a/patroncards/members-search.pl b/patroncards/members-search.pl index dfa0462..276814a 100755 --- a/patroncards/members-search.pl +++ b/patroncards/members-search.pl @@ -33,9 +33,20 @@ my $batch_id = $cgi->param('batch_id') || 0; my $startfrom = $cgi->param('startfrom')||1; my $resultsperpage = $cgi->param('resultsperpage')||C4::Context->preference("PatronsPerPage")||20; my $category = $cgi->param('category') || undef; -my $member = $cgi->param('member') || undef; +my $member = $cgi->param('member') || ''; my $orderby = $cgi->param('orderby') || undef; +my @categories=C4::Category->all; +my %categories_display; + +foreach my $category (@categories) { + my $hash={ + category_description=>$$category{description}, + category_type=>$$category{category_type} + }; + $categories_display{$$category{categorycode}} = $hash; +} + my ($template, $loggedinuser, $cookie) = get_template_and_user({ template_name => "patroncards/members-search.tmpl", query => $cgi, @@ -60,13 +71,12 @@ if ($member || $category) { my ($od,$issue,$fines) = GetMemberIssuesAndFines($results->[$i]{'borrowernumber'}); my %row = ( count => $i + 1, + %{$categories_display{$results->[$i]{categorycode}}}, borrowernumber => $results->[$i]{'borrowernumber'}, cardnumber => $results->[$i]{'cardnumber'}, surname => $results->[$i]{'surname'}, firstname => $results->[$i]{'firstname'}, categorycode => $results->[$i]{'categorycode'}, - category_type => $results->[$i]{'category_type'}, - category_description => $results->[$i]{'description'}, address => $results->[$i]{'address'}, address2 => $results->[$i]{'address2'}, city => $results->[$i]{'city'}, -- 1.7.5.4 From srdjan at catalyst.net.nz Mon Jan 23 01:49:26 2012 From: srdjan at catalyst.net.nz (Srdjan Jankovic) Date: Mon, 23 Jan 2012 13:49:26 +1300 Subject: [Koha-patches] [PATCH] bug 6039: Cancel All waiting holds button In-Reply-To: References: Message-ID: <1327279766-10744-1-git-send-email-srdjan@catalyst.net.nz> TransferWhenCancelAllWaitingHolds syspref --- circ/waitingreserves.pl | 102 +++++++++++++------- installer/data/mysql/sysprefs.sql | 1 + installer/data/mysql/updatedatabase.pl | 7 ++ .../en/modules/admin/preferences/circulation.pref | 6 + .../prog/en/modules/circ/waitingreserves.tt | 20 +++- 5 files changed, 99 insertions(+), 37 deletions(-) diff --git a/circ/waitingreserves.pl b/circ/waitingreserves.pl index 128d1eb..17b7be6 100755 --- a/circ/waitingreserves.pl +++ b/circ/waitingreserves.pl @@ -46,6 +46,7 @@ my $borrowernumber = $input->param('borrowernumber'); my $fbr = $input->param('fbr') || ''; my $tbr = $input->param('tbr') || ''; my $all_branches = $input->param('allbranches') || ''; +my $cancelall = $input->param('cancelall'); my $cancel; @@ -62,42 +63,23 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user( my $default = C4::Context->userenv->{'branch'}; +my $transfer_when_cancel_all = C4::Context->preference('TransferWhenCancelAllWaitingHolds'); +$template->param( TransferWhenCancelAllWaitingHolds => 1 ) if $transfer_when_cancel_all; + +my @cancel_result; # if we have a return from the form we launch the subroutine CancelReserve if ($item) { - my ( $messages, $nextreservinfo ) = ModReserveCancelAll( $item, $borrowernumber ); - # if we have a result - if ($nextreservinfo) { - my $borrowerinfo = GetMemberDetails( $nextreservinfo ); - my $iteminfo = GetBiblioFromItemNumber($item); - if ( $messages->{'transfert'} ) { - $template->param( - messagetransfert => $messages->{'transfert'}, - branchname => GetBranchName($messages->{'transfert'}), - ); - } - - $template->param( - message => 1, - nextreservnumber => $nextreservinfo, - nextreservsurname => $borrowerinfo->{'surname'}, - nextreservfirstname => $borrowerinfo->{'firstname'}, - nextreservitem => $item, - nextreservtitle => $iteminfo->{'title'}, - waiting => ($messages->{'waiting'}) ? 1 : 0, - ); - } - -# if the document is not in his homebranch location and there is not reservation after, we transfer it - if ($fbr ne $tbr and not $nextreservinfo) { - ModItemTransfer( $item, $fbr, $tbr ); - } + my $res = cancel( $item, $borrowernumber, $fbr, $tbr ); + push @cancel_result, $res if $res; } + if ( C4::Context->preference('IndependantBranches') ) { undef $all_branches; } else { - $template->param( all_branches_link => $input->url . '?allbranches=1&' . $input->query_string ) + $template->param( all_branches_link => $input->url . '?allbranches=1' ) unless $all_branches; } +$template->param( all_branches => 1 ) if $all_branches; my (@reservloop, @overloop); my ($reservcount, $overcount); @@ -107,8 +89,24 @@ my @getreserves = $all_branches ? GetReservesForBranch() : GetReservesForBranch( my $today = Date_to_Days(&Today); foreach my $num (@getreserves) { next unless ($num->{'waitingdate'} && $num->{'waitingdate'} ne '0000-00-00'); - my %getreserv; - my $gettitle = GetBiblioFromItemNumber( $num->{'itemnumber'} ); + + my $itemnumber = $num->{'itemnumber'}; + my $gettitle = GetBiblioFromItemNumber( $itemnumber ); + my $borrowernum = $num->{'borrowernumber'}; + my $holdingbranch = $gettitle->{'holdingbranch'}; + my $homebranch = $gettitle->{'homebranch'}; + + if ($cancelall) { + my $res = cancel( $itemnumber, $borrowernum, $holdingbranch, $homebranch, !$transfer_when_cancel_all ); + push @cancel_result, $res if $res; + next; + } + + my %getreserv = ( + itemnumber => $itemnumber, + borrowernum => $borrowernum, + ); + # fix up item type for display $gettitle->{'itemtype'} = C4::Context->preference('item-level_itypes') ? $gettitle->{'itype'} : $gettitle->{'itemtype'}; my $getborrower = GetMember(borrowernumber => $num->{'borrowernumber'}); @@ -122,17 +120,15 @@ foreach my $num (@getreserves) { $getreserv{'itemtype'} = $itemtypeinfo->{'description'}; $getreserv{'title'} = $gettitle->{'title'}; - $getreserv{'itemnumber'} = $gettitle->{'itemnumber'}; $getreserv{'biblionumber'} = $gettitle->{'biblionumber'}; $getreserv{'barcode'} = $gettitle->{'barcode'}; $getreserv{'branchname'} = GetBranchName($gettitle->{'homebranch'}); $getreserv{'homebranch'} = $gettitle->{'homebranch'}; $getreserv{'holdingbranch'} = $gettitle->{'holdingbranch'}; $getreserv{'itemcallnumber'} = $gettitle->{'itemcallnumber'}; - if ( $gettitle->{'homebranch'} ne $gettitle->{'holdingbranch'} ) { + if ( $homebranch ne $holdingbranch ) { $getreserv{'dotransfer'} = 1; } - $getreserv{'borrowernum'} = $getborrower->{'borrowernumber'}; $getreserv{'borrowername'} = $getborrower->{'surname'}; $getreserv{'borrowerfirstname'} = $getborrower->{'firstname'}; $getreserv{'borrowerphone'} = $getborrower->{'phone'}; @@ -150,6 +146,7 @@ foreach my $num (@getreserves) { } +$template->param(cancel_result => \@cancel_result) if @cancel_result; $template->param( reserveloop => \@reservloop, reservecount => $reservcount, @@ -161,3 +158,42 @@ $template->param( ); output_html_with_http_headers $input, $cookie, $template->output; + +exit; + +sub cancel { + my ($item, $borrowernumber, $fbr, $tbr, $skip_transfers ) = @_; + + my $transfer = $fbr ne $tbr; # XXX && !$nextreservinfo; + + return if $transfer && $skip_transfers; + + my ( $messages, $nextreservinfo ) = ModReserveCancelAll( $item, $borrowernumber ); + +# if the document is not in his homebranch location and there is not reservation after, we transfer it + if ($transfer && !$nextreservinfo) { + ModItemTransfer( $item, $fbr, $tbr ); + } + # if we have a result + if ($nextreservinfo) { + my %res; + my $borrowerinfo = GetMemberDetails( $nextreservinfo ); + my $iteminfo = GetBiblioFromItemNumber($item); + if ( $messages->{'transfert'} ) { + $res{messagetransfert} = $messages->{'transfert'}; + $res{branchname} = GetBranchName($messages->{'transfert'}); + } + + $res{message} = 1; + $res{nextreservnumber} = $nextreservinfo; + $res{nextreservsurname} = $borrowerinfo->{'surname'}; + $res{nextreservfirstname} = $borrowerinfo->{'firstname'}; + $res{nextreservitem} = $item; + $res{nextreservtitle} = $iteminfo->{'title'}; + $res{waiting} = $messages->{'waiting'} ? 1 : 0; + + return \%res; + } + + return; +} diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 918df5c..740e665 100755 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -330,3 +330,4 @@ 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('TransferWhenCancelAllWaitingHolds','0','Transfer items when cancelling all waiting holds',NULL,'YesNo'); diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index b12196c..4b9ae48 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -4626,6 +4626,13 @@ if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { SetVersion($DBversion); } +$DBversion = "3.07.00.XXX"; +if (C4::Context->preference("Version") < TransformToNum($DBversion)) { + $dbh->do("INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('TransferWhenCancelAllWaitingHolds','0','Transfer items when cancelling all waiting holds',NULL,'YesNo')"); + print "Upgrade to $DBversion done (Add sysprefs to control transfer when cancel all waiting holds)\n"; + SetVersion ($DBversion); +} + =head1 FUNCTIONS =head2 DropAllForeignKeys($table) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref index 30bcb9b..7d7d682 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -317,6 +317,12 @@ Circulation: yes: Enable no: "Don't enable" - "the ability to place holds on multiple biblio from the search results" + - + - pref: TransferWhenCancelAllWaitingHolds + choices: + yes: Transfer + no: "Don't transfer" + - items when cancelling all waiting holds. Fines Policy: - - Calculate fines based on days overdue diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/waitingreserves.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/waitingreserves.tt index 7ecc3a1..14b6906 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/waitingreserves.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/waitingreserves.tt @@ -44,7 +44,8 @@ $.tablesorter.addParser({ View all branches [% END %] - [% IF ( messagetransfert ) %] + [% IF ( cancel_result ) %] + [% IF ( cancel_result.messagetransfert ) %]

    Hold find for ([% nextreservtitle %]), must be transferred

    This hold placed by : [% nextreservsurname %] [% nextreservfirstname %] at the library : [% branchname %] , Please transfer this hold. @@ -54,7 +55,7 @@ $.tablesorter.addParser({

    [% END %] - [% IF ( waiting ) %] + [% IF ( cancel_result.waiting ) %]

    This hold is waiting

    This hold ([% nextreservtitle %]) was placed by : [% nextreservsurname %] [% nextreservfirstname %], @@ -65,7 +66,7 @@ $.tablesorter.addParser({

    [% END %] - [% UNLESS ( message ) %] + [% ELSE %]

    Holds listed here have been awaiting pickup for more than [% ReservesMaxPickUpDelay %] days.

    - [% IF ( overloop ) %] + [% IF ( overloop ) %] +

    +
    + + + + [% UNLESS TransferWhenCancelAllWaitingHolds %] + Only items that need not be transferred will be cancelled (TransferWhenCancelAllWaitingHolds sypref) + [% END %] +

    +
      Date Action Barcode [% resultsloo.cardnumber %] [% resultsloo.surname %], [% resultsloo.firstname %]
    [% resultsloo.address %][% IF ( resultsloo.address2 ) %]
    [% resultsloo.address2 %][% END %][% IF ( resultsloo.city ) %]
    [% resultsloo.city %][% END %]
    [% resultsloo.category_description %] ([% resultsloo.category_type %])[% resultsloo.category_description %] ([% resultsloo.categorycode %]) [% resultsloo.branchcode %] [% resultsloo.dateexpiry %] [% resultsloo.borrowernotes %]
    -- 1.6.5 From srdjan at catalyst.net.nz Mon Jan 23 04:33:31 2012 From: srdjan at catalyst.net.nz (Srdjan Jankovic) Date: Mon, 23 Jan 2012 16:33:31 +1300 Subject: [Koha-patches] [PATCH] bug_7001: Issue and Reserve slips are notices. In-Reply-To: References: Message-ID: <1327289611-11980-1-git-send-email-srdjan@catalyst.net.nz> 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. --- C4/Circulation.pm | 20 +- C4/Letters.pm | 549 +++++++++++++------- C4/Members.pm | 81 +++- C4/Members/Attributes.pm | 18 + C4/Message.pm | 12 +- C4/Print.pm | 146 ++---- C4/Reserves.pm | 103 +++-- C4/Suggestions.pm | 22 +- acqui/booksellers.pl | 7 +- circ/circulation.pl | 3 +- circ/hold-transfer-slip.pl | 32 +- .../data/mysql/de-DE/mandatory/sample_notices.sql | 2 +- .../data/mysql/en/mandatory/sample_notices.sql | 84 +++- .../data/mysql/es-ES/mandatory/sample_notices.sql | 2 +- .../mysql/fr-FR/1-Obligatoire/sample_notices.sql | 2 +- installer/data/mysql/it-IT/necessari/notices.sql | 2 +- installer/data/mysql/kohastructure.sql | 7 +- .../mysql/nb-NO/1-Obligatorisk/sample_notices.sql | 2 +- .../data/mysql/pl-PL/mandatory/sample_notices.sql | 2 +- .../data/mysql/ru-RU/mandatory/sample_notices.sql | 2 +- installer/data/mysql/sysprefs.sql | 3 + .../data/mysql/uk-UA/mandatory/sample_notices.sql | 2 +- installer/data/mysql/updatedatabase.pl | 100 ++++- .../prog/en/includes/circ-toolbar.inc | 4 +- .../en/modules/admin/preferences/circulation.pref | 5 + .../en/modules/admin/preferences/staff_client.pref | 5 + .../prog/en/modules/batch/print-notices.tt | 6 +- .../prog/en/modules/circ/hold-transfer-slip.tt | 54 -- .../prog/en/modules/circ/printslip.tt | 28 + .../prog/en/modules/members/moremember-receipt.tt | 76 --- .../intranet-tmpl/prog/en/modules/tools/letter.tt | 162 +++++-- .../prog/en/modules/tools/tools-home.tt | 2 +- members/memberentry.pl | 5 +- members/moremember.pl | 10 - members/printslip.pl | 92 ++++ misc/cronjobs/advance_notices.pl | 78 ++-- misc/cronjobs/gather_print_notices.pl | 14 +- misc/cronjobs/overdue_notices.pl | 86 ++-- t/db_dependent/lib/KohaTest/Letters.pm | 5 +- t/db_dependent/lib/KohaTest/Letters/GetLetter.pm | 3 +- t/db_dependent/lib/KohaTest/Members.pm | 1 + t/db_dependent/lib/KohaTest/Print.pm | 5 +- t/db_dependent/lib/KohaTest/Reserves.pm | 1 + tools/letter.pl | 228 ++++++--- 44 files changed, 1308 insertions(+), 765 deletions(-) delete mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/circ/hold-transfer-slip.tt create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt delete mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt create mode 100755 members/printslip.pl diff --git a/C4/Circulation.pm b/C4/Circulation.pm index 0b5068c..3ec7edb 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -2656,11 +2656,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) { @@ -2675,7 +2682,8 @@ sub SendCirculationAlert { $message->update; } } - $letter; + + return $letter; } =head2 updateWrongTransfer diff --git a/C4/Letters.pm b/C4/Letters.pm index 28c6984..adc7b12 100644 --- a/C4/Letters.pm +++ b/C4/Letters.pm @@ -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/<>/$userenv->{firstname}/g; - $letter->{content} =~ s/<>/$userenv->{surname}/g; - $letter->{content} =~ - s/<>/$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 @orders_infos; - while ( my $row = $sthorders->fetchrow_arrayref() ) { - my %rec = (); - @rec{@fields} = @$row; - push @orders_infos, \%rec; + my $dataorders = $sthorders->fetchall_arrayref( {} ); + + 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/<>/$userenv->{firstname}/g; - $letter->{content} =~ s/<>/$userenv->{surname}/g; - $letter->{content} =~ s/<>/$userenv->{emailaddress}/g; - - # Get Fields remplacement - my $order_format = $1 if ( $letter->{content} =~ m/(.*<\/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_content\n$order_format/xms; - } - $letter->{content} =~ s/.*<\/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" }; - } - - warn "sending to From $userenv->{emailaddress} subj $innerletter->{title} Mess $innerletter->{content}" if $debug; - } + 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; - # send an "account details" notice to a newly created user + 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 elsif ( $type eq 'members' ) { - # must parse the password special, before it's hashed. - $letter->{content} =~ s/<>/$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) - - 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) +=head2 GetPreparedLetter( %params ) + + %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 << >> << >> + 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 = @_; + + 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; -sub parseletter_sth { + 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/<>/$userenv->{firstname}/go; + $letter->{content} =~ s/<>/$userenv->{surname}/go; + $letter->{content} =~ s/<>/$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>(.*)!s ) { + my $subcontent = $1; + my @lines = map { + my %subletter = ( title => '', content => $subcontent ); + _substitute_tables( \%subletter, $_ ); + $subletter{content}; + } @$tag_tables; + $letter->{content} =~ s!<$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/<>/$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) - my $values = $sth->fetchrow_hashref; - + 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 ) = @_; + # 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} =~ /<>/) { + my @da = localtime(); + my $todaysdate = "$da[2]:$da[1] " . C4::Dates->today(); + $letter->{content} =~ s/<>/$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 = "<>"; + 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{} if $css; + return < + + +$title + +$css + + +$content + + +EOS +} + sub _send_message_by_sms ($) { my $message = shift or return undef; my $member = C4::Members::GetMember( 'borrowernumber' => $message->{'borrowernumber'} ); diff --git a/C4/Members.pm b/C4/Members.pm index 1d7bc42..9f42cea 100644 --- a/C4/Members.pm +++ b/C4/Members.pm @@ -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, at ISA, at EXPORT, at EXPORT_OK,$debug); @@ -91,6 +93,8 @@ BEGIN { &DeleteMessage &GetMessages &GetMessagesCount + + &IssueSlip ); #Modify data @@ -2227,7 +2231,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; diff --git a/C4/Members/Attributes.pm b/C4/Members/Attributes.pm index 4ae5600..33affa8 100644 --- a/C4/Members/Attributes.pm +++ b/C4/Members/Attributes.pm @@ -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); diff --git a/C4/Message.pm b/C4/Message.pm index 16272ff..4b88970 100644 --- a/C4/Message.pm +++ b/C4/Message.pm @@ -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: diff --git a/C4/Print.pm b/C4/Print.pm index f810816..7fb55cf 100644 --- a/C4/Print.pm +++ b/C4/Print.pm @@ -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 + +BORROWER: +$bordata->{'surname'}, $bordata->{'firstname'} +card number: $bordata->{'cardnumber'} +Phone: $bordata->{'phone'} +$bordata->{'streetaddress'} +$bordata->{'suburb'} +$bordata->{'town'} +$bordata->{'emailaddress'} -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>. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +EOF =cut +=head2 printslip + + &printslip($slip) + +print a slip for the given $borrowernumber and $branchcode + +=cut + +sub printslip ($) { + my ($slip) = @_; + + return unless ( C4::Context->boolean_preference('printcirculationslips') ); + # FIXME - It'd be nifty if this could generate pretty PostScript. -sub remoteprint ($$) { - my ($items, $borrower) = @_; - (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__ diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 359bbad..d2af1c5 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -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 %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 $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 $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/g; - $letter->{'content'} =~ s/<>/$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 diff --git a/C4/Suggestions.pm b/C4/Suggestions.pm index ccc0c8e..6c10fdf 100644 --- a/C4/Suggestions.pm +++ b/C4/Suggestions.pm @@ -371,20 +371,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; diff --git a/acqui/booksellers.pl b/acqui/booksellers.pl index 634eb93..745d040 100755 --- a/acqui/booksellers.pl +++ b/acqui/booksellers.pl @@ -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 ) ) diff --git a/circ/circulation.pl b/circ/circulation.pl index 1b6c619..20e8f6f 100755 --- a/circ/circulation.pl +++ b/circ/circulation.pl @@ -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 = ''; } diff --git a/circ/hold-transfer-slip.pl b/circ/hold-transfer-slip.pl index f581464..8ae5d2a 100755 --- a/circ/hold-transfer-slip.pl +++ b/circ/hold-transfer-slip.pl @@ -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; diff --git a/installer/data/mysql/de-DE/mandatory/sample_notices.sql b/installer/data/mysql/de-DE/mandatory/sample_notices.sql index 0d172db..f668d99 100644 --- a/installer/data/mysql/de-DE/mandatory/sample_notices.sql +++ b/installer/data/mysql/de-DE/mandatory/sample_notices.sql @@ -11,7 +11,7 @@ VALUES ('circulation','ODUE','Mahnung','Mahnung','Liebe/r < ('reserves', 'HOLD_PRINT', 'Vormerkbenachrichtigung (Print)', 'Vormerkbenachrichtigung (Print)', '<>\r\n<>\r\n<>\r\n<>\r\n<> <>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<> <>\r\n<>\r\n<>\r\n<> <>\r\n<>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nLiebe(r) <> <>,\r\n\r\nF??r Sie liegt seit dem <> eine Vormerkung zur Abholung bereit:\r\n\r\nTitel: <>\r\nVerfasser: <>\r\nSignatur: <>\r\n'), ('circulation','CHECKIN','R??ckgabequittung (Zusammenfassung)','R??ckgabequittung','Die folgenden Medien wurden zur??ckgegeben:\r\n----\r\n<>\r\n----\r\nVielen Dank.'), ('circulation','CHECKOUT','Ausleihquittung (Zusammenfassung)','Ausleihquittung','Die folgenden Medien wurden entliehen:\r\n----\r\n<>\r\n----\r\nVielen Dank f??r Ihren Besuch in <>.'), -('reserves', 'HOLDPLACED', 'Neue Vormerkung', 'Neue Vormerkung','Folgender Titel wurde vorgemerkt: <> (<<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>>'), diff --git a/installer/data/mysql/en/mandatory/sample_notices.sql b/installer/data/mysql/en/mandatory/sample_notices.sql index 5ca7eaf..a600373 100644 --- a/installer/data/mysql/en/mandatory/sample_notices.sql +++ b/installer/data/mysql/en/mandatory/sample_notices.sql @@ -11,8 +11,90 @@ 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> + +<reserves> +<div> +<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> +</div> +</reserves>', 1); + diff --git a/installer/data/mysql/es-ES/mandatory/sample_notices.sql b/installer/data/mysql/es-ES/mandatory/sample_notices.sql index 78b80fa..0450bd0 100644 --- a/installer/data/mysql/es-ES/mandatory/sample_notices.sql +++ b/installer/data/mysql/es-ES/mandatory/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql b/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql index 9e9f66d..4eb1210 100644 --- a/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql +++ b/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/it-IT/necessari/notices.sql b/installer/data/mysql/it-IT/necessari/notices.sql index 78b80fa..0450bd0 100644 --- a/installer/data/mysql/it-IT/necessari/notices.sql +++ b/installer/data/mysql/it-IT/necessari/notices.sql @@ -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>>'), diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 5673e35..014c1bd 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -1168,10 +1168,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; -- @@ -2252,12 +2254,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; -- diff --git a/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql b/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql index 762da91..f40da36 100644 --- a/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql +++ b/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/pl-PL/mandatory/sample_notices.sql b/installer/data/mysql/pl-PL/mandatory/sample_notices.sql index c101b0b..73102af 100644 --- a/installer/data/mysql/pl-PL/mandatory/sample_notices.sql +++ b/installer/data/mysql/pl-PL/mandatory/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/ru-RU/mandatory/sample_notices.sql b/installer/data/mysql/ru-RU/mandatory/sample_notices.sql index 5ca7eaf..e13782a 100644 --- a/installer/data/mysql/ru-RU/mandatory/sample_notices.sql +++ b/installer/data/mysql/ru-RU/mandatory/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 918df5c..3bf50fa 100755 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -330,3 +330,6 @@ 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'); + diff --git a/installer/data/mysql/uk-UA/mandatory/sample_notices.sql b/installer/data/mysql/uk-UA/mandatory/sample_notices.sql index 6ab0e18..a908f6c 100644 --- a/installer/data/mysql/uk-UA/mandatory/sample_notices.sql +++ b/installer/data/mysql/uk-UA/mandatory/sample_notices.sql @@ -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>>'), diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index b12196c..27d98cf 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -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"; @@ -4626,6 +4625,105 @@ 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 `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 and RESERVESLIP letters; Add NoticeCSS and SlipCSS sysprefs)\n"; + SetVersion($DBversion); +} + =head1 FUNCTIONS =head2 DropAllForeignKeys($table) diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-toolbar.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/circ-toolbar.inc index 913076f..6fdd720 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-toolbar.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/circ-toolbar.inc @@ -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 %]&print=" + print_type, "printwindow"); + var handler = print_type.match(slip_re) ? "printslip" : "moremember"; + window.open("/cgi-bin/koha/members/" + handler + ".pl?borrowernumber=[% borrowernumber %]&print=" + print_type, "printwindow"); return false; } function searchToHold(){ diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref index 30bcb9b..fe3153a 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -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 diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/staff_client.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/staff_client.pref index df0a434..efa33a8 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/staff_client.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/staff_client.pref @@ -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 diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/batch/print-notices.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/batch/print-notices.tt index 1904381..73f9e61 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/batch/print-notices.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/batch/print-notices.tt @@ -8,11 +8,7 @@ --> </style> [% IF ( stylesheet ) %] - <style type="text/css"> - <!-- - [% stylesheet %] - --> - </style> + <link rel="stylesheet" type="text/css" href="[% stylesheet %]"> [% END %] </head> <body> diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/hold-transfer-slip.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/hold-transfer-slip.tt deleted file mode 100644 index 18d45aa..0000000 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/hold-transfer-slip.tt +++ /dev/null @@ -1,54 +0,0 @@ -[% INCLUDE 'doc-head-open.inc' %] -<title>Koha -- Circulation: Transfers -[% INCLUDE 'doc-head-close-receipt.inc' %] - - -
    - -[% FOREACH reservedat IN reservedata %] - -
    Date: [% reservedat.pulldate %]
    -

    [% IF ( reservedat.transferrequired ) %]Transfer to [% reservedat.branchname %] [% ELSE %]Hold in [% reservedat.branchname %][% END %]

    - -
    - -

    [% reservedat.surname %], [% reservedat.firstname %]

    - -
      -
    • [% reservedat.cardnumber %]
    • - [% IF ( reservedat.phone ) %] -
    • [% reservedat.phone %]
    • - [% END %] -
    • - [% reservedat.address %]
      - [% IF ( reservedat.address2 ) %][% reservedat.address2 %]
      [% END %] - [% reservedat.city %] [% reservedat.zip %] -
    • - [% IF ( reservedat.email ) %] -
    • [% reservedat.email %]
    • - [% END %] -
    -
    -

    ITEM ON HOLD

    -

    [% reservedat.title |html %]

    -
    [% reservedat.author %]
    -
      - [% IF ( reservedat.barcode ) %]
    • [% reservedat.barcode %]
    • [% END %] - [% IF ( reservedat.itemcallnumber ) %]
    • [% reservedat.itemcallnumber %]
    • [% END %] - [% IF ( reservedat.waitingdate ) %]
    • [% reservedat.waitingdate %]
    • [% END %] -
    - [% IF ( reservedat.reservenotes ) %] -

    Notes: [% reservedat.reservenotes %]

    - [% END %] - - - -[% END %] -
    -[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt new file mode 100644 index 0000000..a790069 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt @@ -0,0 +1,28 @@ +[% INCLUDE 'doc-head-open.inc' %] +[% title %] + + + +[% IF stylesheet %] + +[% END %] + + + + +
    + +[% IF plain %] +
    +[% slip %]
    +
    +[% ELSE %] +[% slip %] +[% END %] + +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt deleted file mode 100644 index 4a85ccb..0000000 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt +++ /dev/null @@ -1,76 +0,0 @@ -[% INCLUDE 'doc-head-open.inc' %] -Print Receipt for [% cardnumber %] - - - - - - - - -
    - -

    [% LibraryName %]

    -[% IF ( branchname ) %][% branchname %]
    [% END %] -Checked out to [% firstname %] [% surname %]
    -([% cardnumber %])
    - -[% todaysdate %]
    - -[% IF ( quickslip ) %] -

    Checked Out Today

    -[% FOREACH issueloo IN issueloop %] -[% IF ( issueloo.red ) %][% ELSE %] -[% IF ( issueloo.today ) %] -

    [% issueloo.title |html %]
    -Barcode: [% issueloo.barcode %]
    -Date due: [% issueloo.date_due %]

    - [% END %] - [% END %] - [% END %] - -[% ELSE %] -

    Checked Out

    -[% FOREACH issueloo IN issueloop %] -[% IF ( issueloo.red ) %][% ELSE %] -

    [% issueloo.title |html %]
    -Barcode: [% issueloo.barcode %]
    -Date due: [% issueloo.date_due %]

    - [% END %] - [% END %] - -[% END %] - -[% IF ( quickslip ) %] -[% ELSE %] -[% IF ( overdues_exist ) %] -

    Overdues

    - [% FOREACH issueloo IN issueloop %] - [% IF ( issueloo.red ) %] -

    [% issueloo.title |html %]
    -Barcode: [% issueloo.barcode %]
    -Date due: [% issueloo.date_due %]

    -[% END %] -[% END %] -[% END %] -[% END %] - -[% IF ( koha_news_count ) %] -

    News

    - - [% FOREACH koha_new IN koha_news %] -
    [% koha_new.title %]
    -

    [% koha_new.new %]

    -

    Posted on [% koha_new.newdate %] - -


    - [% END %] -[% END %] - - -[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt index 063236e..eec2384 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt @@ -5,14 +5,29 @@ -
    - +[% IF ( no_op_set ) %] +
    + + [% UNLESS independant_branch %] +

    + Select a library : + +

    + [% END %] +

    + + +

    + + [% IF ( search ) %]

    You Searched for [% searchfield %]

    [% END %] - [% IF ( letter ) %]
    Available since
    + [% IF ( letter && !independant_branch) %] + [% select_for_copy = BLOCK %] + + [% END %] + [% END %] +
    + + - [% FOREACH lette IN letter %] - [% UNLESS ( loop.odd ) %] + + [% FOREACH lette IN letter %] + [% can_edit = lette.branchcode || !independant_branch %] + [% UNLESS ( loop.odd ) %] - [% ELSE %] + [% ELSE %] - [% END %] + [% END %] + + - [% END %] + [% END %] +
    Branch Module Code Name     
    [% lette.branchname || "(All libraries)" %] [% lette.module %] [% lette.code %] [% lette.name %] - Edit + [% IF can_edit %] + Edit + [% END %] + + [% IF !independant_branch || !lette.branchcode %] +
    + + + + + [% IF independant_branch %] + + [% ELSE %] + [% select_for_copy %] + [% END %] + +
    + [% END %]
    - [% IF ( lette.protected ) %] - - - [% ELSE %] - Delete - [% END %] + [% IF !lette.protected && can_edit %] + Delete + [% END %]
    - [% END %] +[% END %] - [% END %] - [% IF ( add_form ) %] +[% IF ( add_form ) %] -
    - + + [% IF ( modify ) %] @@ -182,6 +229,20 @@ $(document).ready(function() {
    [% IF ( modify ) %]Modify notice[% ELSE %]Add notice[% END %]
      + + [% IF independant_branch %] + + [% ELSE %] +
    1. + + +
    2. + [% END %]
    3. @@ -235,6 +296,14 @@ $(document).ready(function() {
    4. + + [% IF is_html %] + + [% ELSE %] + + [% END %] +
    5. +
    6. @@ -252,27 +321,31 @@ $(document).ready(function() {
    +
    +
    - [% END %] +[% END %] - [% IF ( add_validate ) %] +[% IF ( add_validate ) %] Data recorded
    - [% END %] +[% END %] - [% IF ( delete_confirm ) %] +[% IF ( delete_confirm ) %]

    Delete Notice?

    + + @@ -280,6 +353,7 @@ $(document).ready(function() {
    Branch Module Code Name
    [% branchname %] [% module %] [% code %] [% name %]
    + @@ -290,14 +364,14 @@ $(document).ready(function() {
    - [% END %] +[% END %] - [% IF ( delete_confirmed ) %] +[% IF ( delete_confirmed ) %] Data deleted
    - [% END %] +[% END %]
    diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt index 05bdb47..e06b607 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt @@ -26,7 +26,7 @@ [% END %] [% IF ( CAN_user_tools_edit_notices ) %] -
    Notices
    +
    Notices & Slips
    Define notices (print and email notification messages for overdues, etc.)
    [% END %] diff --git a/members/memberentry.pl b/members/memberentry.pl index 6de07bf..20f1cf0 100755 --- a/members/memberentry.pl +++ b/members/memberentry.pl @@ -345,10 +345,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" ); } } diff --git a/members/moremember.pl b/members/moremember.pl index 6e5407c..9277deb 100755 --- a/members/moremember.pl +++ b/members/moremember.pl @@ -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); @@ -483,13 +482,4 @@ $template->param( quickslip => $quickslip, ); -#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; diff --git a/members/printslip.pl b/members/printslip.pl new file mode 100755 index 0000000..3a499cd --- /dev/null +++ b/members/printslip.pl @@ -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 at katipo.co.nz + last modified 21/1/2000 by chris at katipo.co.nz + modified 31/1/2001 by chris at 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; diff --git a/misc/cronjobs/advance_notices.pl b/misc/cronjobs/advance_notices.pl index 1fa358f..09c4017 100755 --- a/misc/cronjobs/advance_notices.pl +++ b/misc/cronjobs/advance_notices.pl @@ -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 EEitems.contentEE 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", at 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", at 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", at 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", at 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; - } - } - - C4::Letters::parseletter( $params->{'letter'}, 'borrowers', $params->{'borrowernumber'} ); + my %table_params = ( 'borrowers' => $params->{'borrowernumber'} ); - if ( $params->{'branchcode'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'branches', $params->{'branchcode'} ); + if ( my $p = $params->{'branchcode'} ) { + $table_params{'branches'} = $p; } - if ( $params->{'itemnumber'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'issues', $params->{'itemnumber'} ); - C4::Letters::parseletter( $params->{'letter'}, 'items', $params->{'itemnumber'} ); + if ( my $p = $params->{'itemnumber'} ) { + $table_params{'issues'} = $p; + $table_params{'items'} = $p; } - if ( $params->{'biblionumber'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'biblio', $params->{'biblionumber'} ); - C4::Letters::parseletter( $params->{'letter'}, 'biblioitems', $params->{'biblionumber'} ); + if ( my $p = $params->{'biblionumber'} ) { + $table_params{'biblio'} = $p; + $table_params{'biblioitems'} = $p; } - 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; diff --git a/misc/cronjobs/gather_print_notices.pl b/misc/cronjobs/gather_print_notices.pl index a72d6a6..165b16e 100755 --- a/misc/cronjobs/gather_print_notices.pl +++ b/misc/cronjobs/gather_print_notices.pl @@ -39,11 +39,9 @@ use Getopt::Long; sub usage { print STDERR < \$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_contents .= $_ } - close STYLESHEET; -} $template->param( - stylesheet => $stylesheet_contents, + stylesheet => C4::Context->preference("NoticeCSS"), today => $today->output(), messages => \@messages, ); diff --git a/misc/cronjobs/overdue_notices.pl b/misc/cronjobs/overdue_notices.pl index 71e6a05..93061b4 100755 --- a/misc/cronjobs/overdue_notices.pl +++ b/misc/cronjobs/overdue_notices.pl @@ -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/<>/$todaysdate/g; - $params->{'letter'}->{content} =~ s/<>/$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>/o) { # process any fine tags... + $currency_format = $1; + $params->{'letter'}->{'content'} =~ s/.*<\/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_format = $1; } - if ($params->{'letter'}->{'content'} =~ m/(.*)<\/fine>/) { # process any fine tags... - my $formatted_fine = currency_format("$1", "$fine", FMT_SYMBOL); - $params->{'letter'}->{'content'} =~ s/.*<\/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>)/$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 diff --git a/t/db_dependent/lib/KohaTest/Letters.pm b/t/db_dependent/lib/KohaTest/Letters.pm index 97d58fb..f2d7b0d 100644 --- a/t/db_dependent/lib/KohaTest/Letters.pm +++ b/t/db_dependent/lib/KohaTest/Letters.pm @@ -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 ); diff --git a/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm b/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm index 76b6ab4..53e5439 100644 --- a/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm +++ b/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm @@ -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; diff --git a/t/db_dependent/lib/KohaTest/Members.pm b/t/db_dependent/lib/KohaTest/Members.pm index 5646be1..dfde7da 100644 --- a/t/db_dependent/lib/KohaTest/Members.pm +++ b/t/db_dependent/lib/KohaTest/Members.pm @@ -52,6 +52,7 @@ sub methods : Test( 1 ) { GetBorrowersWhoHaveNeverBorrowed GetBorrowersWithIssuesHistoryOlderThan GetBorrowersNamesAndLatestIssue + IssueSlip ); can_ok( $self->testing_class, @methods ); diff --git a/t/db_dependent/lib/KohaTest/Print.pm b/t/db_dependent/lib/KohaTest/Print.pm index 02fd5fb..d35ab34 100644 --- a/t/db_dependent/lib/KohaTest/Print.pm +++ b/t/db_dependent/lib/KohaTest/Print.pm @@ -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 ); } diff --git a/t/db_dependent/lib/KohaTest/Reserves.pm b/t/db_dependent/lib/KohaTest/Reserves.pm index 8b05dd0..6416ac3 100644 --- a/t/db_dependent/lib/KohaTest/Reserves.pm +++ b/t/db_dependent/lib/KohaTest/Reserves.pm @@ -33,6 +33,7 @@ sub methods : Test( 1 ) { GetReserveInfo _FixPriority _Findgroupreserve + ReserveSlip ); can_ok( $self->testing_class, @methods ); diff --git a/tools/letter.pl b/tools/letter.pl index 04cd7d2..17c0e77 100755 --- a/tools/letter.pl +++ b/tools/letter.pl @@ -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,14 +88,12 @@ 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( { @@ -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") + ? 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; } -- 1.6.5 From srdjan at catalyst.net.nz Mon Jan 23 05:07:06 2012 From: srdjan at catalyst.net.nz (Srdjan Jankovic) Date: Mon, 23 Jan 2012 17:07:06 +1300 Subject: [Koha-patches] [PATCH] bug_6488: Take in account opachiddenitems when searching in opac In-Reply-To: References: Message-ID: <1327291626-21375-1-git-send-email-srdjan@catalyst.net.nz> Changed searchResults() interface Added trailing \n when parsing OpacHiddenItems to make YAML happy XSLTParse4Display() and buildKohaItemsNamespace() take hidden items as input param Removed numbering from the search results, looks wrong with hidden items --- C4/Items.pm | 52 +++++++------ C4/Search.pm | 83 +++++++++++--------- C4/XSLT.pm | 11 ++- catalogue/search.pl | 2 +- cataloguing/addbooks.pl | 2 +- .../opac-tmpl/prog/en/modules/opac-results.tt | 1 - opac/opac-search.pl | 4 +- 7 files changed, 86 insertions(+), 69 deletions(-) diff --git a/C4/Items.pm b/C4/Items.pm index 72fdf8e..31960e0 100644 --- a/C4/Items.pm +++ b/C4/Items.pm @@ -1629,41 +1629,45 @@ sub GetHiddenItemnumbers { my @resultitems; my $yaml = C4::Context->preference('OpacHiddenItems'); + $yaml = "$yaml\n"; # YAML is anal on ending \n. Surplus does not hurt my $hidingrules; eval { - $hidingrules = YAML::Load($yaml); + $hidingrules = YAML::Load($yaml); }; if ($@) { - warn "Unable to parse OpacHiddenItems syspref : $@"; - return (); - } else { + warn "Unable to parse OpacHiddenItems syspref : $@"; + return (); + } my $dbh = C4::Context->dbh; - # For each item - foreach my $item (@items) { + # For each item + foreach my $item (@items) { - # We check each rule - foreach my $field (keys %$hidingrules) { - my $query = "SELECT $field from items where itemnumber = ?"; - my $sth = $dbh->prepare($query); - $sth->execute($item->{'itemnumber'}); - my ($result) = $sth->fetchrow; + # We check each rule + foreach my $field (keys %$hidingrules) { + my $val; + if (exists $item->{$field}) { + $val = $item->{$field}; + } + else { + my $query = "SELECT $field from items where itemnumber = ?"; + $val = $dbh->selectrow_array($query, undef, $item->{'itemnumber'}); + } + $val = '' unless defined $val; - # If the results matches the values in the yaml file - if (any { $result eq $_ } @{$hidingrules->{$field}}) { + # If the results matches the values in the yaml file + if (any { $val eq $_ } @{$hidingrules->{$field}}) { - # We add the itemnumber to the list - push @resultitems, $item->{'itemnumber'}; + # We add the itemnumber to the list + push @resultitems, $item->{'itemnumber'}; - # If at least one rule matched for an item, no need to test the others - last; - } - } - } - return @resultitems; + # If at least one rule matched for an item, no need to test the others + last; + } + } } - - } + return @resultitems; +} =head3 get_item_authorised_values diff --git a/C4/Search.pm b/C4/Search.pm index 4a8de5c..7e34a52 100644 --- a/C4/Search.pm +++ b/C4/Search.pm @@ -31,6 +31,7 @@ use C4::Branch; use C4::Reserves; # CheckReserves use C4::Debug; use C4::Items; +use C4::Charset; use YAML; use URI::Escape; @@ -1413,11 +1414,16 @@ Format results in a form suitable for passing to the template # IMO this subroutine is pretty messy still -- it's responsible for # building the HTML output for the template sub searchResults { - my ( $search_context, $searchdesc, $hits, $results_per_page, $offset, $scan, @marcresults, $hidelostitems ) = @_; + my ( $search_context, $searchdesc, $hits, $results_per_page, $offset, $scan, $marcresults ) = @_; my $dbh = C4::Context->dbh; my @newresults; - $search_context = 'opac' unless $search_context eq 'opac' or $search_context eq 'intranet'; + $search_context = 'opac' if !$search_context || $search_context ne 'intranet'; + my ($is_opac, $hidelostitems); + if ($search_context eq 'opac') { + $hidelostitems = C4::Context->preference('hidelostitems'); + $is_opac = 1; + } #Build branchnames hash #find branchname @@ -1480,12 +1486,11 @@ sub searchResults { my $marcflavour = C4::Context->preference("marcflavour"); # We get the biblionumber position in MARC my ($bibliotag,$bibliosubf)=GetMarcFromKohaField('biblio.biblionumber',''); - my $fw; # loop through all of the records we've retrieved for ( my $i = $offset ; $i <= $times - 1 ; $i++ ) { - my $marcrecord = MARC::File::USMARC::decode( $marcresults[$i] ); - $fw = $scan + my $marcrecord = MARC::File::USMARC::decode( $marcresults->[$i] ); + my $fw = $scan ? undef : $bibliotag < 10 ? GetFrameworkCode($marcrecord->field($bibliotag)->data) @@ -1603,18 +1608,18 @@ sub searchResults { my $other_count = 0; my $wthdrawn_count = 0; my $itemlost_count = 0; + my $hideatopac_count = 0; my $itembinding_count = 0; my $itemdamaged_count = 0; my $item_in_transit_count = 0; my $can_place_holds = 0; - my $item_onhold_count = 0; + my $item_onhold_count = 0; my $items_count = scalar(@fields); - my $maxitems = - ( C4::Context->preference('maxItemsinSearchResults') ) - ? C4::Context->preference('maxItemsinSearchResults') - 1 - : 1; + my $maxitems_pref = C4::Context->preference('maxItemsinSearchResults'); + my $maxitems = $maxitems_pref ? $maxitems_pref - 1 : 1; # loop through every item + my @hiddenitems; foreach my $field (@fields) { my $item; @@ -1624,9 +1629,11 @@ sub searchResults { } # Hidden items - my @items = ($item); - my (@hiddenitems) = GetHiddenItemnumbers(@items); - $item->{'hideatopac'} = 1 if (@hiddenitems); + if ($is_opac) { + my @hi = GetHiddenItemnumbers($item); + $item->{'hideatopac'} = @hi; + push @hiddenitems, @hi; + } my $hbranch = C4::Context->preference('HomeOrHoldingBranch') eq 'homebranch' ? 'homebranch' : 'holdingbranch'; my $otherbranch = C4::Context->preference('HomeOrHoldingBranch') eq 'homebranch' ? 'holdingbranch' : 'homebranch'; @@ -1710,6 +1717,7 @@ sub searchResults { $wthdrawn_count++ if $item->{wthdrawn}; $itemlost_count++ if $item->{itemlost}; $itemdamaged_count++ if $item->{damaged}; + $hideatopac_count++ if $item->{hideatopac}; $item_in_transit_count++ if $transfertwhen ne ''; $item_onhold_count++ if $reservestatus eq 'Waiting'; $item->{status} = $item->{wthdrawn} . "-" . $item->{itemlost} . "-" . $item->{damaged} . "-" . $item->{notforloan}; @@ -1748,11 +1756,11 @@ sub searchResults { } } } # notforloan, item level and biblioitem level + + next if $is_opac && $hideatopac_count >= $items_count; + next if $hidelostitems && $itemlost_count >= $items_count; + my ( $availableitemscount, $onloanitemscount, $otheritemscount ); - $maxitems = - ( C4::Context->preference('maxItemsinSearchResults') ) - ? C4::Context->preference('maxItemsinSearchResults') - 1 - : 1; for my $key ( sort keys %$onloan_items ) { (++$onloanitemscount > $maxitems) and last; push @onloan_items_loop, $onloan_items->{$key}; @@ -1766,20 +1774,7 @@ sub searchResults { push @available_items_loop, $available_items->{$key} } - # XSLT processing of some stuff - use C4::Charset; - SetUTF8Flag($marcrecord); - $debug && warn $marcrecord->as_formatted; - if (!$scan && $search_context eq 'opac' && C4::Context->preference("OPACXSLTResultsDisplay")) { - # FIXME note that XSLTResultsDisplay (use of XSLT to format staff interface bib search results) - # is not implemented yet - $oldbiblio->{XSLTResultsRecord} = XSLTParse4Display($oldbiblio->{biblionumber}, $marcrecord, 'Results', - $search_context, 1); - # the last parameter tells Koha to clean up the problematic ampersand entities that Zebra outputs - - } - - # if biblio level itypes are used and itemtype is notforloan, it can't be reserved either + # if biblio level itypes are used and itemtype is notforloan, it can't be reserved either if (!C4::Context->preference("item-level_itypes")) { if ($itemtypes{ $oldbiblio->{itemtype} }->{notforloan}) { $can_place_holds = 0; @@ -1803,8 +1798,8 @@ sub searchResults { $oldbiblio->{intransitcount} = $item_in_transit_count; $oldbiblio->{onholdcount} = $item_onhold_count; $oldbiblio->{orderedcount} = $ordered_count; - $oldbiblio->{isbn} =~ - s/-//g; # deleting - in isbn to enable amazon content + # deleting - in isbn to enable amazon content + $oldbiblio->{isbn} =~ s/-//g; if (C4::Context->preference("AlternateHoldingsField") && $items_count == 0) { my $fieldspec = C4::Context->preference("AlternateHoldingsField"); @@ -1834,10 +1829,24 @@ sub searchResults { $oldbiblio->{'alternateholdings_count'} = $alternateholdingscount; } - push( @newresults, $oldbiblio ) - if(not $hidelostitems - or (($items_count > $itemlost_count ) - && $hidelostitems)); + # XSLT processing of some stuff + if (!$scan && $search_context eq 'opac' && C4::Context->preference("OPACXSLTResultsDisplay")) { + SetUTF8Flag($marcrecord); + $debug && warn $marcrecord->as_formatted; + # FIXME note that XSLTResultsDisplay (use of XSLT to format staff interface bib search results) + # is not implemented yet + $oldbiblio->{XSLTResultsRecord} + = XSLTParse4Display($oldbiblio->{biblionumber}, + $marcrecord, + 'Results', + $search_context, + 1, # clean up the problematic ampersand entities that Zebra outputs + \@hiddenitems + ); + + } + + push( @newresults, $oldbiblio ); } return @newresults; diff --git a/C4/XSLT.pm b/C4/XSLT.pm index d22a3ac..06dfaf4 100755 --- a/C4/XSLT.pm +++ b/C4/XSLT.pm @@ -121,12 +121,12 @@ sub getAuthorisedValues4MARCSubfields { my $stylesheet; sub XSLTParse4Display { - my ( $biblionumber, $orig_record, $xsl_suffix, $interface, $fixamps ) = @_; + my ( $biblionumber, $orig_record, $xsl_suffix, $interface, $fixamps, $hidden_items ) = @_; $interface = 'opac' unless $interface; # grab the XML, run it through our stylesheet, push it out to the browser my $record = transformMARCXML4XSLT($biblionumber, $orig_record); #return $record->as_formatted(); - my $itemsxml = buildKohaItemsNamespace($biblionumber); + my $itemsxml = buildKohaItemsNamespace($biblionumber, $hidden_items); my $xmlrecord = $record->as_xml(C4::Context->preference('marcflavour')); my $sysxml = "\n"; foreach my $syspref ( qw/ hidelostitems OPACURLOpenInNewWindow @@ -180,8 +180,13 @@ sub XSLTParse4Display { } sub buildKohaItemsNamespace { - my ($biblionumber) = @_; + my ($biblionumber, $hidden_items) = @_; + my @items = C4::Items::GetItemsInfo($biblionumber); + if ($hidden_items && @$hidden_items) { + my %hi = map {$_ => 1} @$hidden_items; + @items = grep { !$hi{$_->{itemnumber}} } @items; + } my $branches = GetBranches(); my $itemtypes = GetItemTypes(); my $xml = ''; diff --git a/catalogue/search.pl b/catalogue/search.pl index 96163d6..49e63bc 100755 --- a/catalogue/search.pl +++ b/catalogue/search.pl @@ -547,7 +547,7 @@ for (my $i=0;$i<@servers;$i++) { $hits = $results_hashref->{$server}->{"hits"}; my $page = $cgi->param('page') || 0; my @newresults = searchResults('intranet', $query_desc, $hits, $results_per_page, $offset, $scan, - @{$results_hashref->{$server}->{"RECORDS"}}); + $results_hashref->{$server}->{"RECORDS"}); $total = $total + $results_hashref->{$server}->{"hits"}; ## If there's just one result, redirect to the detail page if ($total == 1) { diff --git a/cataloguing/addbooks.pl b/cataloguing/addbooks.pl index 270b16d..b768a29 100755 --- a/cataloguing/addbooks.pl +++ b/cataloguing/addbooks.pl @@ -86,7 +86,7 @@ if ($query) { # format output # SimpleSearch() give the results per page we want, so 0 offet here my $total = @{$marcresults}; - my @newresults = searchResults( 'intranet', $query, $total, $results_per_page, 0, 0, @{$marcresults} ); + my @newresults = searchResults( 'intranet', $query, $total, $results_per_page, 0, 0, $marcresults ); foreach my $line (@newresults) { if ( not exists $line->{'size'} ) { $line->{'size'} = "" } } diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt index e7c6e2d..2071845 100755 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt @@ -380,7 +380,6 @@ $(document).ready(function(){ [% IF ( opacbookbag ) %] [% ELSE %] [% IF ( virtualshelves ) %] [% ELSE %] [% IF ( RequestOnOpac ) %][% UNLESS ( SEARCH_RESULT.norequests ) %][% IF ( opacuserlogin ) %] [% END %][% END %][% END %][% END %][% END %] - [% SEARCH_RESULT.result_number %]. [% UNLESS ( item_level_itypes ) %] [% UNLESS ( noItemTypeImages ) %] diff --git a/opac/opac-search.pl b/opac/opac-search.pl index 12baf3b..5a9ee45 100755 --- a/opac/opac-search.pl +++ b/opac/opac-search.pl @@ -485,12 +485,12 @@ for (my $i=0;$i<@servers;$i++) { # we want as specified by $offset and $results_per_page, # we need to set the offset parameter of searchResults to 0 my @group_results = searchResults( 'opac', $query_desc, $group->{'group_count'},$results_per_page, 0, $scan, - @{ $group->{"RECORDS"} }, C4::Context->preference('hidelostitems')); + $group->{"RECORDS"}); push @newresults, { group_label => $group->{'group_label'}, GROUP_RESULTS => \@group_results }; } } else { @newresults = searchResults('opac', $query_desc, $hits, $results_per_page, $offset, $scan, - @{$results_hashref->{$server}->{"RECORDS"}},, C4::Context->preference('hidelostitems')); + $results_hashref->{$server}->{"RECORDS"}); } # must define a value for size if not present in DB -- 1.6.5 From srdjan at catalyst.net.nz Mon Jan 23 08:11:36 2012 From: srdjan at catalyst.net.nz (Srdjan Jankovic) Date: Mon, 23 Jan 2012 20:11:36 +1300 Subject: [Koha-patches] [PATCH] bug_7420: Added overduefinescap to issuingrules In-Reply-To: References: Message-ID: <1327302696-5998-1-git-send-email-srdjan@catalyst.net.nz> Replaced existing MaxFine syspref logic with overduefinescap. Repurposed MaxFine to be the overall overdue limit for all items overdue. Implemented new MaxFine logic in UpdateFine(). --- C4/Overdues.pm | 35 ++++++++++++++++---- admin/smart-rules.pl | 9 +++-- installer/data/mysql/kohastructure.sql | 1 + installer/data/mysql/sysprefs.sql | 2 +- installer/data/mysql/updatedatabase.pl | 21 ++++++++++++ .../prog/en/modules/admin/preferences/patrons.pref | 3 +- .../prog/en/modules/admin/smart-rules.tt | 3 ++ 7 files changed, 61 insertions(+), 13 deletions(-) diff --git a/C4/Overdues.pm b/C4/Overdues.pm index 660e10b..03192c0 100644 --- a/C4/Overdues.pm +++ b/C4/Overdues.pm @@ -298,7 +298,7 @@ sub CalcFine { } else { # a zero (or null) chargeperiod means no charge. } - $amount = C4::Context->preference('maxFine') if(C4::Context->preference('maxFine') && ( $amount > C4::Context->preference('maxFine'))); + $amount = $data->{overduefinescap} if $data->{overduefinescap} && $amount > $data->{overduefinescap}; $debug and warn sprintf("CalcFine returning (%s, %s, %s, %s)", $amount, $data->{'chargename'}, $days_minus_grace, $daystocharge); return ($amount, $data->{'chargename'}, $days_minus_grace, $daystocharge); # FIXME: chargename is NEVER populated anywhere. @@ -508,14 +508,35 @@ sub UpdateFine { # "REF" is Cash Refund my $sth = $dbh->prepare( "SELECT * FROM accountlines - WHERE itemnumber=? - AND borrowernumber=? - AND accounttype IN ('FU','O','F','M') - AND description like ? " + WHERE borrowernumber=? + AND accounttype IN ('FU','O','F','M')" ); - $sth->execute( $itemnum, $borrowernumber, "%$due%" ); + $sth->execute( $borrowernumber ); + my $data; + my $total_amount_other = 0.00; + my $due_qr = qr/$due/; + while (my $rec = $sth->fetchrow_hashref) { + if ($rec->{itemnumber} == $itemnum && $rec->{description} =~ /$due_qr/) { + if ($data) { + warn "Not a unique accountlines record for item $itemnum borrower $borrowernumber"; + } else { + $data = $rec; + next; + } + } + $total_amount_other += $rec->{'amount'}; + } + if (my $maxfine = C4::Context->preference('MaxFine')) { + if ($total_amount_other + $amount > $maxfine) { + my $new_amount = $maxfine - $total_amount_other; + warn "Reducing fine for item $itemnum borrower $borrowernumber from $amount to $new_amount - MaxFine reached"; + return if $new_amount <= 0.00; + + $amount = $new_amount; + } + } - if ( my $data = $sth->fetchrow_hashref ) { + if ( $data ) { # we're updating an existing fine. Only modify if amount changed # Note that in the current implementation, you cannot pay against an accruing fine diff --git a/admin/smart-rules.pl b/admin/smart-rules.pl index f290934..dc6bb52 100755 --- a/admin/smart-rules.pl +++ b/admin/smart-rules.pl @@ -101,8 +101,8 @@ elsif ($op eq 'delete-branch-item') { # save the values entered elsif ($op eq 'add') { my $sth_search = $dbh->prepare("SELECT COUNT(*) AS total FROM issuingrules WHERE branchcode=? AND categorycode=? AND itemtype=?"); - my $sth_insert = $dbh->prepare("INSERT INTO issuingrules (branchcode, categorycode, itemtype, maxissueqty, renewalsallowed, reservesallowed, issuelength, hardduedate, hardduedatecompare, fine, finedays, firstremind, chargeperiod,rentaldiscount) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); - my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, reservesallowed=?, issuelength=?, hardduedate=?, hardduedatecompare=?, rentaldiscount=? WHERE branchcode=? AND categorycode=? AND itemtype=?"); + my $sth_insert = $dbh->prepare("INSERT INTO issuingrules (branchcode, categorycode, itemtype, maxissueqty, renewalsallowed, reservesallowed, issuelength, hardduedate, hardduedatecompare, fine, finedays, firstremind, chargeperiod,rentaldiscount,overduefinescap) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); + my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, reservesallowed=?, issuelength=?, hardduedate=?, hardduedatecompare=?, rentaldiscount=?, overduefinescap=? WHERE branchcode=? AND categorycode=? AND itemtype=?"); my $br = $branch; # branch my $bor = $input->param('categorycode'); # borrower category @@ -121,14 +121,15 @@ elsif ($op eq 'add') { $hardduedate = format_date_in_iso($hardduedate); my $hardduedatecompare = $input->param('hardduedatecompare'); my $rentaldiscount = $input->param('rentaldiscount'); + my $overduefinescap = $input->param('overduefinescap') || undef; $debug and warn "Adding $br, $bor, $cat, $fine, $maxissueqty"; $sth_search->execute($br,$bor,$cat); my $res = $sth_search->fetchrow_hashref(); if ($res->{total}) { - $sth_update->execute($fine, $finedays,$firstremind, $chargeperiod, $maxissueqty, $renewalsallowed,$reservesallowed, $issuelength,$hardduedate,$hardduedatecompare,$rentaldiscount, $br,$bor,$cat); + $sth_update->execute($fine, $finedays,$firstremind, $chargeperiod, $maxissueqty, $renewalsallowed,$reservesallowed, $issuelength,$hardduedate,$hardduedatecompare,$rentaldiscount,$overduefinescap, $br,$bor,$cat); } else { - $sth_insert->execute($br,$bor,$cat,$maxissueqty,$renewalsallowed,$reservesallowed,$issuelength,$hardduedate,$hardduedatecompare,$fine,$finedays,$firstremind,$chargeperiod,$rentaldiscount); + $sth_insert->execute($br,$bor,$cat,$maxissueqty,$renewalsallowed,$reservesallowed,$issuelength,$hardduedate,$hardduedatecompare,$fine,$finedays,$firstremind,$chargeperiod,$rentaldiscount,$overduefinescap); } } elsif ($op eq "set-branch-defaults") { diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 5673e35..d591912 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -988,6 +988,7 @@ CREATE TABLE `issuingrules` ( `renewalsallowed` smallint(6) NOT NULL default "0", `reservesallowed` smallint(6) NOT NULL default "0", `branchcode` varchar(10) NOT NULL default '', + overduefinescap decimal default NULL, PRIMARY KEY (`branchcode`,`categorycode`,`itemtype`), KEY `categorycode` (`categorycode`), KEY `itemtype` (`itemtype`) diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 918df5c..4a1cf8d 100755 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -62,7 +62,7 @@ INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES -- this is selected by the web installer now -- INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('marcflavour','MARC21','Define global MARC flavor (MARC21 or UNIMARC) used for character encoding','MARC21|UNIMARC','Choice'); INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('MARCOrgCode','OSt','Define MARC Organization Code - http://www.loc.gov/marc/organizations/orgshome.html','','free'); -INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('MaxFine',9999,'Maximum fine a patron can have for a single late return','','Integer'); +INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('MAXFINE',NULL,'Maximum fine a patron can have for all late returns at one moment. Single item caps are specified in the circulation rules matrix.','','Integer'); INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('maxoutstanding',5,'maximum amount withstanding to be able make holds','','Integer'); INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('maxreserves',50,'Define maximum number of holds a patron can place','','Integer'); INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('maxItemsInSearchResults',20,'Specify the maximum number of items to display for each result on a page of results',NULL,'free'); diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index b12196c..85daf12 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -4626,6 +4626,27 @@ if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { SetVersion($DBversion); } +###### XXX space ######## +# This is an attempt to make .XXX versions mergeable with master version +# Please keep new XXX patches between XXX space markers +# Master submitters: when making a real version, please push patch outside +# (above) the markers and leave the markers with this instructions in the file + +$DBversion = '3.07.00.XXX'; +if (C4::Context->preference("Version") < TransformToNum($DBversion)) { + $dbh->do("ALTER TABLE issuingrules ADD overduefinescap decimal DEFAULT NULL"); + my $maxfine = C4::Context->preference('MaxFine'); + if ($maxfine && $maxfine < 900) { # an arbitrary value that tells us it's not "some huge value" + $dbh->do("UPDATE issuingrules SET overduefinescap=?",undef,$maxfine); + $dbh->do("UPDATE systempreferences SET value = NULL WHERE variable = 'MaxFine'"); + } + $dbh->do("UPDATE systempreferences SET explanation = 'Maximum fine a patron can have for all late returns at one moment. Single item caps are specified in the circulation rules matrix.' WHERE variable = 'MaxFine'"); + print "Upgrade to $DBversion done (Bug 7420 add overduefinescap to circulation matrix)\n"; + SetVersion ($DBversion); +} + +###### XXX space ######## + =head1 FUNCTIONS =head2 DropAllForeignKeys($table) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref index 0e2f73b..8deeed6 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref @@ -73,10 +73,11 @@ Patrons: no: "Don't allow" - "staff to access a patron's checkout history (it is stored regardless)." - - - The late fine for a specific checkout will only go up to + - The late fine for all checkouts will only go up to - pref: MaxFine class: currency - '[% local_currency %].' + - Empty value means no limit. Single item caps are specified in the circulation rules matrix. - - pref: memberofinstitution choices: diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt index d2f314f..28a6b61 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt @@ -77,6 +77,7 @@ for="tobranch">Clone these rules to: Clone these rules to: [% rule.finedays %] [% rule.renewalsallowed %] [% rule.reservesallowed %] @@ -172,6 +174,7 @@ for="tobranch">Clone these rules to: + -- 1.6.5 From srdjan at catalyst.net.nz Mon Jan 23 08:48:03 2012 From: srdjan at catalyst.net.nz (Srdjan Jankovic) Date: Mon, 23 Jan 2012 20:48:03 +1300 Subject: [Koha-patches] [PATCH] bug_7458: call number plugin In-Reply-To: References: Message-ID: <1327304883-6974-1-git-send-email-srdjan@catalyst.net.nz> --- cataloguing/value_builder/callnumber-KU.pl | 127 ++++++++++++++++++++++++++++ 1 files changed, 127 insertions(+), 0 deletions(-) create mode 100755 cataloguing/value_builder/callnumber-KU.pl diff --git a/cataloguing/value_builder/callnumber-KU.pl b/cataloguing/value_builder/callnumber-KU.pl new file mode 100755 index 0000000..885026f --- /dev/null +++ b/cataloguing/value_builder/callnumber-KU.pl @@ -0,0 +1,127 @@ +#!/usr/bin/perl + +# Copyright 2010 BibLibre SARL +# +# 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. + +use strict; +use warnings; +use C4::Auth; +use CGI; +use C4::Context; + +=head1 DESCRIPTION + +Is used for callnumber computation. + +User must supply a letter prefix (unspecified length) followed by an empty space followed by a "number". +"Number" is i4 character long, and is either a number sequence which is 0 padded +or two letters which are 01 padded. +If input does not conform with this format any processing is omitted. + +Some examples of legal values that trigger auto allocation: + +AAA 0 - returns largest number AAA 0xxx incremented by 1 or AAA 0000 +BBB 12 - returns largest number BBB 12xx incremented by 1 or BBB 1200 +CCC QW - returns largest number CCC QWxx incremented by 1 or CCC QW01 + +=cut + +sub plugin_parameters { +} + +sub plugin_javascript { + my ($dbh,$record,$tagslib,$field_number,$tabloop) = @_; + my $res=" + + "; + + return ($field_number,$res); +} + +my $BASE_CALLNUMBER_RE = qr/^(\w+) (\w+)$/; +sub plugin { + my ($input) = @_; + my $code = $input->param('code'); + + my ($template, $loggedinuser, $cookie) = get_template_and_user({ + template_name => "cataloguing/value_builder/ajax.tmpl", + query => $input, + type => "intranet", + authnotrequired => 0, + flagsrequired => {editcatalogue => '*'}, + debug => 1, + }); + + my $ret; + my ($alpha, $num) = ($code =~ $BASE_CALLNUMBER_RE); + if (defined $num) { # otherwise no point + my $dbh = C4::Context->dbh; + if ( my $max = $dbh->selectrow_array("SELECT MAX(itemcallnumber) + FROM items + WHERE itemcallnumber LIKE ?", undef, "$code%") ) { + (undef, $num) = ($max =~ $BASE_CALLNUMBER_RE); + my ($num_alpha, $num_num) = ($num =~ m/^(\D+)?(\d+)$/); + my $len = length($num_num); + $num_num++; + if ($len == length($num_num)) { # no overflow + $ret = $num_alpha . $num_num + } + } + else { # pad with 0 + my $pad_len = 4 - length($num); + if ($pad_len > 0) { + if ($num =~ m/^\d+$/) { + $ret = $num. ("0" x $pad_len); + } else { + $ret = $num ; + $ret .= "0" x ($pad_len - 1) if $pad_len > 1; + $ret .= "1"; + } + } + } + } + $ret = "$alpha $ret" if $ret; + + $template->param( + return => $ret || $code + ); + output_html_with_http_headers $input, $cookie, $template->output; +} + +1; -- 1.6.5 From stephane.delaune at biblibre.com Mon Jan 23 16:11:08 2012 From: stephane.delaune at biblibre.com (=?UTF-8?q?St=C3=A9phane=20Delaune?=) Date: Mon, 23 Jan 2012 16:11:08 +0100 Subject: [Koha-patches] [PATCH] Bug 7460: Add template toolkit's FILTER html_line_break on opac details description's tab Message-ID: <1327331468-32339-1-git-send-email-stephane.delaune@biblibre.com> --- koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt index 066f4ff..8e4bfcc 100755 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt @@ -692,7 +692,7 @@ YAHOO.util.Event.onContentReady("furtherm", function () { [% IF ( MARCNOTES ) %] [% FOREACH MARCNOTE IN MARCNOTES %] -

    [% MARCNOTE.marcnote %]

    +

    [% MARCNOTE.marcnote FILTER html_line_break %]

    [% END %] [% ELSE %] [% IF ( notes ) %] -- 1.7.0.4 From srdjan at catalyst.net.nz Tue Jan 24 04:48:18 2012 From: srdjan at catalyst.net.nz (Srdjan Jankovic) Date: Tue, 24 Jan 2012 16:48:18 +1300 Subject: [Koha-patches] [PATCH] bug_7190: Do not reverse writeoffs when item is returned In-Reply-To: References: Message-ID: <1327376898-389-1-git-send-email-srdjan@catalyst.net.nz> --- C4/Circulation.pm | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/C4/Circulation.pm b/C4/Circulation.pm index 0b5068c..2282d5c 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -1866,10 +1866,11 @@ sub _FixAccountForLostAndReturned { my $item_id = @_ ? shift : $itemnumber; # Send the barcode if you want that logged in the description my $dbh = C4::Context->dbh; # check for charge made for lost book - my $sth = $dbh->prepare("SELECT * FROM accountlines WHERE (itemnumber = ?) AND (accounttype='L' OR accounttype='Rep') ORDER BY date DESC"); + my $sth = $dbh->prepare("SELECT * FROM accountlines WHERE itemnumber = ? AND accounttype IN ('L', 'Rep', 'W') ORDER BY date DESC"); $sth->execute($itemnumber); my $data = $sth->fetchrow_hashref; $data or return; # bail if there is nothing to do + $data->{accounttype} eq 'W' and return; # Written off # writeoff this amount my $offset; -- 1.6.5 From oleonard at myacpl.org Tue Jan 24 14:56:49 2012 From: oleonard at myacpl.org (Owen Leonard) Date: Tue, 24 Jan 2012 08:56:49 -0500 Subject: [Koha-patches] [PATCH] Bug 6865 - Follow-up, Replace image-based gradient backgrounds with CSS3 gradients Message-ID: <1327413409-2998-1-git-send-email-oleonard@myacpl.org> Staff client login screen has a separate CSS file which wasn't included in the original changes for Bug 6865. This caused a 404 error (missing background image). --- koha-tmpl/intranet-tmpl/prog/en/css/login.css | 19 ++++++++++++++----- 1 files changed, 14 insertions(+), 5 deletions(-) diff --git a/koha-tmpl/intranet-tmpl/prog/en/css/login.css b/koha-tmpl/intranet-tmpl/prog/en/css/login.css index 5ed2c64..cbb7d81 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/css/login.css +++ b/koha-tmpl/intranet-tmpl/prog/en/css/login.css @@ -129,11 +129,20 @@ label { } .submit input, .submit input:focus, .button { - background: url(../../img/button-bg.gif ); - border: 1px solid #999; - border-left-color: #ccc; - border-top-color: #ccc; - color: #333; + border: 1px outset #999999; + border-top-color: #666; + border-left-color: #666; + -moz-border-radius : 2px; + padding: 0.25em; + background: #ffffff; /* Old browsers */ + background: -moz-linear-gradient(top, #ffffff 0%, #f7f7f7 35%, #e0e0e0 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(35%,#f7f7f7), color-stop(100%,#e0e0e0)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #ffffff 0%,#f7f7f7 35%,#e0e0e0 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #ffffff 0%,#f7f7f7 35%,#e0e0e0 100%); /* Opera11.10+ */ + background: -ms-linear-gradient(top, #ffffff 0%,#f7f7f7 35%,#e0e0e0 100%); /* IE10+ */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#e0e0e0',GradientType=0 ); /* IE6-9 */ + background: linear-gradient(top, #ffffff 0%,#f7f7f7 35%,#e0e0e0 100%); /* W3C */ + color: #333333; padding: 0.25em; } -- 1.7.3 From oleonard at myacpl.org Tue Jan 24 15:15:27 2012 From: oleonard at myacpl.org (Owen Leonard) Date: Tue, 24 Jan 2012 09:15:27 -0500 Subject: [Koha-patches] [PATCH] Bug 7461 - Cart offering to remove items when closing Message-ID: <1327414527-3470-1-git-send-email-oleonard@myacpl.org> The "hide window" button in the cart called a quit() function which deletes any checked items. My understanding of the "hide window" button is that it should *only* hide the window, not perform any other operations. I'm removing the calls to the quit() function in both the OPAC and staff client and adding a CSS class, "close," which is already tied via jQuery to the window.close() function. To test in both OPAC and staff client: Add items to the cart. Try clicking the "hide window" button with items selected and without. In both cases the window should close without affecting the contents of the cart. --- .../intranet-tmpl/prog/en/modules/basket/basket.tt | 2 +- koha-tmpl/opac-tmpl/prog/en/modules/opac-basket.tt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/basket/basket.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/basket/basket.tt index 0896075..4239b4f 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/basket/basket.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/basket/basket.tt @@ -108,7 +108,7 @@ function placeHold () {
  • - Hide Window + Hide Window
  • diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-basket.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-basket.tt index 62be158..a229521 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-basket.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-basket.tt @@ -128,7 +128,7 @@ function tagAdded() {
  • Download
  • Print
  • Empty and Close
  • -
  • Hide Window
  • +
  • Hide Window
  • [% END %] -- 1.7.3 From oleonard at myacpl.org Tue Jan 24 16:46:25 2012 From: oleonard at myacpl.org (Owen Leonard) Date: Tue, 24 Jan 2012 10:46:25 -0500 Subject: [Koha-patches] [PATCH] Bug 6210 - Follow up, Choose framework on merge Message-ID: <1327419985-4542-1-git-send-email-oleonard@myacpl.org> - Adding subtitle to the display of titles to be merged - Adding a link to preview the MARC record of titles to be merged - Fixing up markup of form to improve appearance - Correcting breadcrumbs --- cataloguing/merge.pl | 11 ++++- .../prog/en/modules/cataloguing/merge.tt | 44 ++++++++----------- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/cataloguing/merge.pl b/cataloguing/merge.pl index 59b1d02..020001d 100755 --- a/cataloguing/merge.pl +++ b/cataloguing/merge.pl @@ -127,12 +127,19 @@ if ($merge) { } else { my $data1 = GetBiblioData($biblionumber[0]); + my $record1 = GetMarcBiblio($biblionumber[0]); + my $data2 = GetBiblioData($biblionumber[1]); + my $record2 = GetMarcBiblio($biblionumber[1]); # Checks if both records use the same framework my $frameworkcode1 = &GetFrameworkCode($biblionumber[0]); my $frameworkcode2 = &GetFrameworkCode($biblionumber[1]); + + my $subtitle1 = GetRecordValue('subtitle', $record1, $frameworkcode1); + my $subtitle2 = GetRecordValue('subtitle', $record2, $frameworkcode1); + if ($mergereference) { my $framework; @@ -170,7 +177,9 @@ if ($merge) { biblio1 => $biblionumber[0], biblio2 => $biblionumber[1], title1 => $data1->{'title'}, - title2 => $data2->{'title'} + subtitle1 => $subtitle1, + title2 => $data2->{'title'}, + subtitle2 => $subtitle2 ); if ($frameworkcode1 ne $frameworkcode2) { my $frameworks = getframeworks; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/merge.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/merge.tt index 5a48385..9235fdd 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/merge.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/merge.tt @@ -1,5 +1,6 @@ [% INCLUDE 'doc-head-open.inc' %] Koha › Cataloging › Merging records +[% INCLUDE 'greybox.inc' %] [% INCLUDE 'doc-head-close.inc' %] [% IF ( stylesheet ) %] - + [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/hold-transfer-slip.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/hold-transfer-slip.tt deleted file mode 100644 index 18d45aa..0000000 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/hold-transfer-slip.tt +++ /dev/null @@ -1,54 +0,0 @@ -[% INCLUDE 'doc-head-open.inc' %] -Koha -- Circulation: Transfers -[% INCLUDE 'doc-head-close-receipt.inc' %] - - -
    - -[% FOREACH reservedat IN reservedata %] - -
    Date: [% reservedat.pulldate %]
    -

    [% IF ( reservedat.transferrequired ) %]Transfer to [% reservedat.branchname %] [% ELSE %]Hold in [% reservedat.branchname %][% END %]

    - -
    - -

    [% reservedat.surname %], [% reservedat.firstname %]

    - -
      -
    • [% reservedat.cardnumber %]
    • - [% IF ( reservedat.phone ) %] -
    • [% reservedat.phone %]
    • - [% END %] -
    • - [% reservedat.address %]
      - [% IF ( reservedat.address2 ) %][% reservedat.address2 %]
      [% END %] - [% reservedat.city %] [% reservedat.zip %] -
    • - [% IF ( reservedat.email ) %] -
    • [% reservedat.email %]
    • - [% END %] -
    -
    -

    ITEM ON HOLD

    -

    [% reservedat.title |html %]

    -
    [% reservedat.author %]
    -
      - [% IF ( reservedat.barcode ) %]
    • [% reservedat.barcode %]
    • [% END %] - [% IF ( reservedat.itemcallnumber ) %]
    • [% reservedat.itemcallnumber %]
    • [% END %] - [% IF ( reservedat.waitingdate ) %]
    • [% reservedat.waitingdate %]
    • [% END %] -
    - [% IF ( reservedat.reservenotes ) %] -

    Notes: [% reservedat.reservenotes %]

    - [% END %] - - - -[% END %] -
    -[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt new file mode 100644 index 0000000..a790069 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt @@ -0,0 +1,28 @@ +[% INCLUDE 'doc-head-open.inc' %] +[% title %] + + + +[% IF stylesheet %] + +[% END %] + + + + +
    + +[% IF plain %] +
    +[% slip %]
    +
    +[% ELSE %] +[% slip %] +[% END %] + +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt index 063236e..eec2384 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt @@ -5,14 +5,29 @@ -
    - +[% IF ( no_op_set ) %] +
    + + [% UNLESS independant_branch %] +

    + Select a library : + +

    + [% END %] +

    + + +

    +
    + [% IF ( search ) %]

    You Searched for [% searchfield %]

    [% END %] - [% IF ( letter ) %] + [% IF ( letter && !independant_branch) %] + [% select_for_copy = BLOCK %] + + [% END %] + [% END %] +
    + + - [% FOREACH lette IN letter %] - [% UNLESS ( loop.odd ) %] + + [% FOREACH lette IN letter %] + [% can_edit = lette.branchcode || !independant_branch %] + [% UNLESS ( loop.odd ) %] - [% ELSE %] + [% ELSE %] - [% END %] + [% END %] + + - [% END %] + [% END %] +
    Branch Module Code Name     
    [% lette.branchname || "(All libraries)" %] [% lette.module %] [% lette.code %] [% lette.name %] - Edit + [% IF can_edit %] + Edit + [% END %] + + [% IF !independant_branch || !lette.branchcode %] +
    + + + + + [% IF independant_branch %] + + [% ELSE %] + [% select_for_copy %] + [% END %] + +
    + [% END %]
    - [% IF ( lette.protected ) %] - - - [% ELSE %] - Delete - [% END %] + [% IF !lette.protected && can_edit %] + Delete + [% END %]
    - [% END %] +[% END %] - [% END %] - [% IF ( add_form ) %] +[% IF ( add_form ) %] -
    - + + [% IF ( modify ) %] @@ -182,6 +229,20 @@ $(document).ready(function() {
    [% IF ( modify ) %]Modify notice[% ELSE %]Add notice[% END %]
      + + [% IF independant_branch %] + + [% ELSE %] +
    1. + + +
    2. + [% END %]
    3. @@ -235,6 +296,14 @@ $(document).ready(function() {
    4. + + [% IF is_html %] + + [% ELSE %] + + [% END %] +
    5. +
    6. @@ -252,27 +321,31 @@ $(document).ready(function() {
    +
    +
    - [% END %] +[% END %] - [% IF ( add_validate ) %] +[% IF ( add_validate ) %] Data recorded
    - [% END %] +[% END %] - [% IF ( delete_confirm ) %] +[% IF ( delete_confirm ) %]

    Delete Notice?

    + + @@ -280,6 +353,7 @@ $(document).ready(function() {
    Branch Module Code Name
    [% branchname %] [% module %] [% code %] [% name %]
    + @@ -290,14 +364,14 @@ $(document).ready(function() {
    - [% END %] +[% END %] - [% IF ( delete_confirmed ) %] +[% IF ( delete_confirmed ) %] Data deleted
    - [% END %] +[% END %]
    diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt index b71a1ee..5cc3bbf 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt @@ -26,7 +26,7 @@ [% END %] [% IF ( CAN_user_tools_edit_notices ) %] -
    Notices
    +
    Notices & Slips
    Define notices (print and email notification messages for overdues, etc.)
    [% END %] diff --git a/members/memberentry.pl b/members/memberentry.pl index 6de07bf..20f1cf0 100755 --- a/members/memberentry.pl +++ b/members/memberentry.pl @@ -345,10 +345,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" ); } } diff --git a/members/moremember.pl b/members/moremember.pl index 6e5407c..9277deb 100755 --- a/members/moremember.pl +++ b/members/moremember.pl @@ -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); @@ -483,13 +482,4 @@ $template->param( quickslip => $quickslip, ); -#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; diff --git a/members/printslip.pl b/members/printslip.pl new file mode 100755 index 0000000..3a499cd --- /dev/null +++ b/members/printslip.pl @@ -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 at katipo.co.nz + last modified 21/1/2000 by chris at katipo.co.nz + modified 31/1/2001 by chris at 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; diff --git a/misc/cronjobs/advance_notices.pl b/misc/cronjobs/advance_notices.pl index 1fa358f..09c4017 100755 --- a/misc/cronjobs/advance_notices.pl +++ b/misc/cronjobs/advance_notices.pl @@ -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 EEitems.contentEE 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", at 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", at 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", at 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", at 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; - } - } - - C4::Letters::parseletter( $params->{'letter'}, 'borrowers', $params->{'borrowernumber'} ); + my %table_params = ( 'borrowers' => $params->{'borrowernumber'} ); - if ( $params->{'branchcode'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'branches', $params->{'branchcode'} ); + if ( my $p = $params->{'branchcode'} ) { + $table_params{'branches'} = $p; } - if ( $params->{'itemnumber'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'issues', $params->{'itemnumber'} ); - C4::Letters::parseletter( $params->{'letter'}, 'items', $params->{'itemnumber'} ); + if ( my $p = $params->{'itemnumber'} ) { + $table_params{'issues'} = $p; + $table_params{'items'} = $p; } - if ( $params->{'biblionumber'} ) { - C4::Letters::parseletter( $params->{'letter'}, 'biblio', $params->{'biblionumber'} ); - C4::Letters::parseletter( $params->{'letter'}, 'biblioitems', $params->{'biblionumber'} ); + if ( my $p = $params->{'biblionumber'} ) { + $table_params{'biblio'} = $p; + $table_params{'biblioitems'} = $p; } - 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; diff --git a/misc/cronjobs/gather_print_notices.pl b/misc/cronjobs/gather_print_notices.pl index a72d6a6..165b16e 100755 --- a/misc/cronjobs/gather_print_notices.pl +++ b/misc/cronjobs/gather_print_notices.pl @@ -39,11 +39,9 @@ use Getopt::Long; sub usage { print STDERR < \$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_contents .= $_ } - close STYLESHEET; -} $template->param( - stylesheet => $stylesheet_contents, + stylesheet => C4::Context->preference("NoticeCSS"), today => $today->output(), messages => \@messages, ); diff --git a/misc/cronjobs/overdue_notices.pl b/misc/cronjobs/overdue_notices.pl index 71e6a05..93061b4 100755 --- a/misc/cronjobs/overdue_notices.pl +++ b/misc/cronjobs/overdue_notices.pl @@ -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/<>/$todaysdate/g; - $params->{'letter'}->{content} =~ s/<>/$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>/o) { # process any fine tags... + $currency_format = $1; + $params->{'letter'}->{'content'} =~ s/.*<\/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_format = $1; } - if ($params->{'letter'}->{'content'} =~ m/(.*)<\/fine>/) { # process any fine tags... - my $formatted_fine = currency_format("$1", "$fine", FMT_SYMBOL); - $params->{'letter'}->{'content'} =~ s/.*<\/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>)/$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 diff --git a/t/db_dependent/lib/KohaTest/Letters.pm b/t/db_dependent/lib/KohaTest/Letters.pm index 97d58fb..f2d7b0d 100644 --- a/t/db_dependent/lib/KohaTest/Letters.pm +++ b/t/db_dependent/lib/KohaTest/Letters.pm @@ -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 ); diff --git a/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm b/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm index 76b6ab4..53e5439 100644 --- a/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm +++ b/t/db_dependent/lib/KohaTest/Letters/GetLetter.pm @@ -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; diff --git a/t/db_dependent/lib/KohaTest/Members.pm b/t/db_dependent/lib/KohaTest/Members.pm index 5646be1..dfde7da 100644 --- a/t/db_dependent/lib/KohaTest/Members.pm +++ b/t/db_dependent/lib/KohaTest/Members.pm @@ -52,6 +52,7 @@ sub methods : Test( 1 ) { GetBorrowersWhoHaveNeverBorrowed GetBorrowersWithIssuesHistoryOlderThan GetBorrowersNamesAndLatestIssue + IssueSlip ); can_ok( $self->testing_class, @methods ); diff --git a/t/db_dependent/lib/KohaTest/Print.pm b/t/db_dependent/lib/KohaTest/Print.pm index 02fd5fb..d35ab34 100644 --- a/t/db_dependent/lib/KohaTest/Print.pm +++ b/t/db_dependent/lib/KohaTest/Print.pm @@ -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 ); } diff --git a/t/db_dependent/lib/KohaTest/Reserves.pm b/t/db_dependent/lib/KohaTest/Reserves.pm index 8b05dd0..6416ac3 100644 --- a/t/db_dependent/lib/KohaTest/Reserves.pm +++ b/t/db_dependent/lib/KohaTest/Reserves.pm @@ -33,6 +33,7 @@ sub methods : Test( 1 ) { GetReserveInfo _FixPriority _Findgroupreserve + ReserveSlip ); can_ok( $self->testing_class, @methods ); diff --git a/tools/letter.pl b/tools/letter.pl index 04cd7d2..17c0e77 100755 --- a/tools/letter.pl +++ b/tools/letter.pl @@ -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,14 +88,12 @@ 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( { @@ -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") + ? 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; } -- 1.6.5 From srdjan at catalyst.net.nz Fri Jan 27 03:22:21 2012 From: srdjan at catalyst.net.nz (Srdjan Jankovic) Date: Fri, 27 Jan 2012 15:22:21 +1300 Subject: [Koha-patches] [PATCH] bug_7231: Call GetMarcPrice() in acqui/neworderempty.pl for staged imports In-Reply-To: References: Message-ID: <1327630941-32002-1-git-send-email-srdjan@catalyst.net.nz> --- acqui/neworderempty.pl | 26 ++++---------------------- 1 files changed, 4 insertions(+), 22 deletions(-) diff --git a/acqui/neworderempty.pl b/acqui/neworderempty.pl index 459dfe8..5ca0d64 100755 --- a/acqui/neworderempty.pl +++ b/acqui/neworderempty.pl @@ -80,7 +80,7 @@ use C4::Dates; use C4::Bookseller qw/ GetBookSellerFromId /; use C4::Acquisition; use C4::Suggestions; # GetSuggestion -use C4::Biblio; # GetBiblioData +use C4::Biblio; # GetBiblioData GetMarcPrice use C4::Output; use C4::Input; use C4::Koha; @@ -121,6 +121,7 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user( } ); +my $marcflavour = C4::Context->preference('marcflavour'); my $basket = GetBasket($basketno); my $contract = &GetContract($basket->{contractnumber}); @@ -154,26 +155,7 @@ if ( $ordernumber eq '' and defined $params->{'breedingid'}){ $params->{'frameworkcode'} or $params->{'frameworkcode'} = ""; ( $biblionumber, $bibitemnum ) = AddBiblio( $marcrecord, $params->{'frameworkcode'} ); # get the price if there is one. - # filter by storing only the 1st number - # we suppose the currency is correct, as we have no possibilities to get it. - if ($marcrecord->subfield("345","d")) { - $listprice = $marcrecord->subfield("345","d"); - if ($listprice =~ /^([\d\.,]*)/) { - $listprice = $1; - $listprice =~ s/,/\./; - } else { - $listprice = 0; - } - } - elsif ($marcrecord->subfield("010","d")) { - $listprice = $marcrecord->subfield("010","d"); - if ($listprice =~ /^([\d\.,]*)/) { - $listprice = $1; - $listprice =~ s/,/\./; - } else { - $listprice = 0; - } - } + $listprice = GetMarcPrice($marcrecord, $marcflavour); SetImportRecordStatus($params->{'breedingid'}, 'imported'); } @@ -429,7 +411,7 @@ sub MARCfindbreeding { } } # fix the unimarc 100 coded field (with unicode information) - if (C4::Context->preference('marcflavour') eq 'UNIMARC' && $record->subfield(100,'a')) { + if ($marcflavour eq 'UNIMARC' && $record->subfield(100,'a')) { my $f100a=$record->subfield(100,'a'); my $f100 = $record->field(100); my $f100temp = $f100->as_string; -- 1.6.5 From srdjan at catalyst.net.nz Fri Jan 27 05:00:26 2012 From: srdjan at catalyst.net.nz (Srdjan Jankovic) Date: Fri, 27 Jan 2012 17:00:26 +1300 Subject: [Koha-patches] [PATCH] bug_7140: Added item description to complement icon to search result and biblio detail pages In-Reply-To: References: Message-ID: <1327636826-11971-1-git-send-email-srdjan@catalyst.net.nz> --- C4/Search.pm | 5 +- .../prog/en/modules/catalogue/detail.tt | 14 ++--- .../prog/en/modules/catalogue/results.tt | 69 +++++++++++++------- 3 files changed, 54 insertions(+), 34 deletions(-) diff --git a/C4/Search.pm b/C4/Search.pm index 4a8de5c..574dc94 100644 --- a/C4/Search.pm +++ b/C4/Search.pm @@ -1622,6 +1622,7 @@ sub searchResults { foreach my $code ( keys %subfieldstosearch ) { $item->{$code} = $field->subfield( $subfieldstosearch{$code} ); } + $item->{description} = $itemtypes{ $item->{itype} }{description}; # Hidden items my @items = ($item); @@ -1650,6 +1651,7 @@ sub searchResults { $onloan_items->{$key}->{branchname} = $item->{branchname}; $onloan_items->{$key}->{location} = $shelflocations->{ $item->{location} }; $onloan_items->{$key}->{itemcallnumber} = $item->{itemcallnumber}; + $onloan_items->{$key}->{description} = $item->{description}; $onloan_items->{$key}->{imageurl} = getitemtypeimagelocation( $search_context, $itemtypes{ $item->{itype} }->{imageurl} ); # if something's checked out and lost, mark it as 'long overdue' if ( $item->{itemlost} ) { @@ -1733,6 +1735,7 @@ sub searchResults { $other_items->{$key}->{notforloan} = GetAuthorisedValueDesc('','',$item->{notforloan},'','',$notforloan_authorised_value) if $notforloan_authorised_value; $other_items->{$key}->{count}++ if $item->{$hbranch}; $other_items->{$key}->{location} = $shelflocations->{ $item->{location} }; + $other_items->{$key}->{description} = $item->{description}; $other_items->{$key}->{imageurl} = getitemtypeimagelocation( $search_context, $itemtypes{ $item->{itype} }->{imageurl} ); } # item is available @@ -1740,7 +1743,7 @@ sub searchResults { $can_place_holds = 1; $available_count++; $available_items->{$prefix}->{count}++ if $item->{$hbranch}; - foreach (qw(branchname itemcallnumber hideatopac)) { + foreach (qw(branchname itemcallnumber hideatopac description)) { $available_items->{$prefix}->{$_} = $item->{$_}; } $available_items->{$prefix}->{location} = $shelflocations->{ $item->{location} }; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt index 38a26c9..494b764 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt @@ -261,16 +261,12 @@ function verify_images() { [% FOREACH itemloo IN itemloop %] [% IF ( item_level_itypes ) %] - - [% IF ( noItemTypeImages ) %] - [% itemloo.description %] - [% ELSE %] - [% IF ( itemloo.imageurl ) %] + + [% IF !noItemTypeImages && itemloo.imageurl %] [% itemloo.description %] - [% ELSE %] - [% itemloo.description %] - [% END %] - [% END %] + [% END %] + [% itemloo.description %] + [% END %] [% UNLESS ( singlebranchmode ) %][% itemloo.branchname %] [% END %] [% itemloo.homebranch %][% itemloo.location %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt index 18a992d..bf63b89 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt @@ -470,17 +470,18 @@ YAHOO.util.Event.onContentReady("searchheader", function () { [% END %]

    [% UNLESS ( item_level_itypes ) %] - [% UNLESS ( noItemTypeImages ) %][% IF ( SEARCH_RESULT.imageurl ) %] - - [% END %][% END %] + [% IF !noItemTypeImages && SEARCH_RESULT.imageurl %] + [% SEARCH_RESULT.description %] + [% END %] + [% SEARCH_RESULT.description %] [% END %] [% SEARCH_RESULT.summary %]

    [% ELSE %]

    [% UNLESS ( item_level_itypes ) %] - [% UNLESS ( noItemTypeImages ) %][% IF ( SEARCH_RESULT.imageurl ) %] + [% IF !noItemTypeImages && SEARCH_RESULT.imageurl %] - [% END %][% END %] + [% END %] [% END %] [% IF ( SEARCH_RESULT.author ) %] @@ -532,41 +533,56 @@ YAHOO.util.Event.onContentReady("searchheader", function () {

      [% FOREACH available_items_loo IN SEARCH_RESULT.available_items_loop %] - [% IF ( noItemTypeImages ) %]
    • [% ELSE %][% IF ( item_level_itypes ) %][% IF ( available_items_loo.imageurl ) %]
    • [% available_items_loo.description %][% ELSE %]
    • [% END %][% ELSE %]
    • [% END %][% END %] + [% IF item_level_itypes && !noItemTypeImages && available_items_loo.imageurl %] +
    • + [% available_items_loo.description %] + [% ELSE %] +
    • + [% END %] [% IF ( available_items_loo.branchname ) %][% available_items_loo.branchname %][% END %] [% IF ( available_items_loo.location ) %][% available_items_loo.location %][% END %] [% IF ( available_items_loo.itemcallnumber ) %][[% available_items_loo.itemcallnumber %]][% END %] - ([% available_items_loo.count %])
    • - [% END %]
    + ([% available_items_loo.count %]) + [% IF item_level_itypes && available_items_loo.description %] +
    [% available_items_loo.description %] + [% END %] + + [% END %] + [% END %] [% IF ( SEARCH_RESULT.onloancount ) %] [% SEARCH_RESULT.onloancount %] on loan:
      [% FOREACH onloan_items_loo IN SEARCH_RESULT.onloan_items_loop %] - [% IF ( noItemTypeImages ) %]
    • [% ELSE %][% IF ( item_level_itypes ) %] - [% IF ( onloan_items_loo.imageurl ) %] -
    • [% onloan_items_loo.description %] - [% ELSE %]
    • [% END %] - [% ELSE %]
    • [% END %][% END %] - + [% IF item_level_itypes && !noItemTypeImages && onloan_items_loo.imageurl %] +
    • + [% onloan_items_loo.description %] + [% ELSE %] +
    • + [% END %] [% IF ( onloan_items_loo.branchname ) %][% onloan_items_loo.branchname %][% END %] [% IF ( onloan_items_loo.location ) %][% onloan_items_loo.location %][% END %] [% IF ( onloan_items_loo.itemcallnumber ) %][[% onloan_items_loo.itemcallnumber %]][% END %] - ([% onloan_items_loo.count %][% IF ( onloan_items_loo.longoverdue ) %], [% onloan_items_loo.longoverdue %] long overdue[% END %]) date due: [% onloan_items_loo.due_date %]
    • - [% END %]
    + ([% onloan_items_loo.count %][% IF ( onloan_items_loo.longoverdue ) %], [% onloan_items_loo.longoverdue %] long overdue[% END %]) date due: [% onloan_items_loo.due_date %] + [% IF item_level_itypes && onloan_items_loo.description %] +
    [% onloan_items_loo.description %] + [% END %] + + [% END %] + [% END %] [% IF ( SEARCH_RESULT.othercount ) %] [% SEARCH_RESULT.othercount %] unavailable:
      [% FOREACH other_items_loo IN SEARCH_RESULT.other_items_loop %] - [% IF ( noItemTypeImages ) %]
    • [% ELSE %][% IF ( item_level_itypes ) %] - [% IF ( other_items_loo.imageurl ) %] -
    • [% other_items_loo.description %] - [% ELSE %]
    • [% END %] - [% ELSE %]
    • [% END %][% END %] - + [% IF item_level_itypes && !noItemTypeImages && other_items_loo.imageurl %] +
    • + [% other_items_loo.description %] + [% ELSE %] +
    • + [% END %] [% IF ( other_items_loo.branchname ) %][% other_items_loo.branchname %][% END %] [% IF ( other_items_loo.location ) %][% other_items_loo.location %][% END %] [% IF ( other_items_loo.itemcallnumber ) %][[% other_items_loo.itemcallnumber %]][% END %] @@ -576,8 +592,13 @@ YAHOO.util.Event.onContentReady("searchheader", function () { [% IF ( other_items_loo.intransit ) %](In transit)[% END %] [% IF ( other_items_loo.onhold ) %](On hold)[% END %] [% IF ( other_items_loo.notforloan ) %][% other_items_loo.notforloan %][% END %] - ([% other_items_loo.count %])
    • - [% END %]
    + ([% other_items_loo.count %]) + [% IF item_level_itypes && other_items_loo.description %] +
    [% other_items_loo.description %] + [% END %] + + [% END %] + [% END %] [% ELSE %] [% IF ( SEARCH_RESULT.ALTERNATEHOLDINGS.count ) %] -- 1.6.5 From gcollum at gmail.com Sat Jan 28 21:14:49 2012 From: gcollum at gmail.com (Garry Collum) Date: Sat, 28 Jan 2012 15:14:49 -0500 Subject: [Koha-patches] [PATCH] Bug 7431: Fixes the display of the due date in opac item specific holds. Message-ID: <1327781689-1864-1-git-send-email-gcollum@gmail.com> Fixes the reference to the due date in opac-reserve from date_due to dateDue as defined int opac-reserve.pl. --- .../opac-tmpl/prog/en/modules/opac-reserve.tt | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt index ca49152..7e2683a 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt @@ -508,8 +508,8 @@ [% itemLoo.enumchron %] [% END %] - [% IF ( itemLoo.date_due ) %] - Due [% itemLoo.date_due %] + [% IF ( itemLoo.dateDue ) %] + Due [% itemLoo.dateDue %] [% ELSIF ( itemLoo.transfertwhen ) %] In transit from [% itemLoo.transfertfrom %], to [% itemLoo.transfertto %], since [% itemLoo.transfertwhen %] -- 1.7.5.4 From srdjan at catalyst.net.nz Mon Jan 30 03:33:20 2012 From: srdjan at catalyst.net.nz (Srdjan Jankovic) Date: Mon, 30 Jan 2012 15:33:20 +1300 Subject: [Koha-patches] [PATCH] bug_7458: A call number plugin In-Reply-To: References: Message-ID: <1327890800-15652-1-git-send-email-srdjan@catalyst.net.nz> --- cataloguing/value_builder/callnumber-KU.pl | 129 ++++++++++++++++++++++++++++ 1 files changed, 129 insertions(+), 0 deletions(-) create mode 100755 cataloguing/value_builder/callnumber-KU.pl diff --git a/cataloguing/value_builder/callnumber-KU.pl b/cataloguing/value_builder/callnumber-KU.pl new file mode 100755 index 0000000..66bd75e --- /dev/null +++ b/cataloguing/value_builder/callnumber-KU.pl @@ -0,0 +1,129 @@ +#!/usr/bin/perl + +# Copyright 2010 BibLibre SARL +# +# 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. + +use strict; +use warnings; +use C4::Auth; +use CGI; +use C4::Context; + +=head1 DESCRIPTION + +Is used for callnumber computation. + +User must supply a letter prefix (unspecified length) followed by an empty space followed by a "number". +"Number" is 4 character long, and is either a number sequence which is 0 padded +or two letters which are 01 padded. +If input does not conform with this format any processing is omitted. + +Some examples of legal values that trigger auto allocation: + +AAA 0 - returns first unused number AAA 0xxx starting with AAA 0000 +BBB 12 - returns first unused number BBB 12xx starting with BBB 1200 +CCC QW - returns first unused number CCC QWxx starting with CCC QW01 + +=cut + +sub plugin_parameters { +} + +sub plugin_javascript { + my ($dbh,$record,$tagslib,$field_number,$tabloop) = @_; + my $res=" + + "; + + return ($field_number,$res); +} + +my $BASE_CALLNUMBER_RE = qr/^(\w+) (\w+)$/; +sub plugin { + my ($input) = @_; + my $code = $input->param('code'); + + my ($template, $loggedinuser, $cookie) = get_template_and_user({ + template_name => "cataloguing/value_builder/ajax.tmpl", + query => $input, + type => "intranet", + authnotrequired => 0, + flagsrequired => {editcatalogue => '*'}, + debug => 1, + }); + + my $ret; + my ($alpha, $num) = ($code =~ $BASE_CALLNUMBER_RE); + if (defined $num) { # otherwise no point + my $dbh = C4::Context->dbh; + my $pad_len = 4 - length($num); + for (my $i = $pad_len - 1; $i >= 0; $i--) { + my $padded = $code . ("0" x $i); + if ( my $max = $dbh->selectrow_array("SELECT MAX(itemcallnumber) + FROM items + WHERE itemcallnumber LIKE ?", undef, "$padded%") ) { + my (undef, $num1) = ($max =~ $BASE_CALLNUMBER_RE); + my ($num_alpha, $num_num) = ($num1 =~ m/^(\D+)?(\d+)$/); + my $len = length($num_num); + $num_num++; + if ($len == length($num_num)) { # no overflow + $ret = $num_alpha . $num_num; + last; + } + } + } + unless ($ret) { + if ($num =~ m/^\d+$/) { + $ret = $num . ("0" x $pad_len); + } else { + $ret = $num ; + $ret .= "0" x ($pad_len - 1) if $pad_len > 1; + $ret .= "1"; + } + } + } + $ret = "$alpha $ret" if $ret; + + $template->param( + return => $ret || $code + ); + output_html_with_http_headers $input, $cookie, $template->output; +} + +1; -- 1.6.5 From srdjan at catalyst.net.nz Mon Jan 30 10:10:32 2012 From: srdjan at catalyst.net.nz (Srdjan Jankovic) Date: Mon, 30 Jan 2012 22:10:32 +1300 Subject: [Koha-patches] [PATCH] bug_7458: A call number plugin In-Reply-To: References: Message-ID: <1327914632-21808-1-git-send-email-srdjan@catalyst.net.nz> --- cataloguing/value_builder/callnumber-KU.pl | 130 ++++++++++++++++++++++++++++ 1 files changed, 130 insertions(+), 0 deletions(-) create mode 100755 cataloguing/value_builder/callnumber-KU.pl diff --git a/cataloguing/value_builder/callnumber-KU.pl b/cataloguing/value_builder/callnumber-KU.pl new file mode 100755 index 0000000..3719ac0 --- /dev/null +++ b/cataloguing/value_builder/callnumber-KU.pl @@ -0,0 +1,130 @@ +#!/usr/bin/perl + +# Copyright 2010 BibLibre SARL +# +# 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. + +use strict; +use warnings; +use C4::Auth; +use CGI; +use C4::Context; + +=head1 DESCRIPTION + +Is used for callnumber computation. + +User must supply a letter prefix (unspecified length) followed by an empty space followed by a "number". +"Number" is 4 character long, and is either a number sequence which is 0 padded +or two letters which are 01 padded. +If input does not conform with this format any processing is omitted. + +Some examples of legal values that trigger auto allocation: + +AAA 0 - returns first unused number AAA 0xxx starting with AAA 0000 +BBB 12 - returns first unused number BBB 12xx starting with BBB 1200 +CCC QW - returns first unused number CCC QWxx starting with CCC QW01 + +=cut + +sub plugin_parameters { +} + +sub plugin_javascript { + my ($dbh,$record,$tagslib,$field_number,$tabloop) = @_; + my $res=" + + "; + + return ($field_number,$res); +} + +my $BASE_CALLNUMBER_RE = qr/^(\w+) (\w+)$/; +sub plugin { + my ($input) = @_; + my $code = $input->param('code'); + + my ($template, $loggedinuser, $cookie) = get_template_and_user({ + template_name => "cataloguing/value_builder/ajax.tmpl", + query => $input, + type => "intranet", + authnotrequired => 0, + flagsrequired => {editcatalogue => '*'}, + debug => 1, + }); + + my $ret; + my ($alpha, $num) = ($code =~ $BASE_CALLNUMBER_RE); + if (defined $num) { # otherwise no point + my $dbh = C4::Context->dbh; + my $pad_len = 4 - length($num); + for (my $i = $pad_len - 1; $i >= 0; $i--) { + my $padded = $code . ("0" x $i); + if ( my $max = $dbh->selectrow_array("SELECT MAX(itemcallnumber) + FROM items + WHERE itemcallnumber LIKE ?", undef, "$padded%") ) { + my (undef, $num1) = ($max =~ $BASE_CALLNUMBER_RE); + my ($num_alpha, $num_num) = ($num1 =~ m/^(\D+)?(\d+)$/); + my $len = length($num_num); + $num_num++; + if ($len == length($num_num)) { # no overflow + $ret = "$alpha $num_alpha" . $num_num; + last; + } + } + else { + $ret = $padded ; + $pad_len -= $i; + if ($num =~ m/^\d+$/) { + $ret .= "0" x $pad_len; + } else { + $ret .= "0" x ($pad_len - 1) if $pad_len > 1; + $ret .= "1"; + } + last; + } + } + } + + $template->param( + return => $ret || $code + ); + output_html_with_http_headers $input, $cookie, $template->output; +} + +1; -- 1.6.5 From srdjan at catalyst.net.nz Mon Jan 30 10:55:08 2012 From: srdjan at catalyst.net.nz (Srdjan Jankovic) Date: Mon, 30 Jan 2012 22:55:08 +1300 Subject: [Koha-patches] [PATCH] bug_7458: A call number plugin In-Reply-To: References: Message-ID: <1327917308-22773-1-git-send-email-srdjan@catalyst.net.nz> --- cataloguing/value_builder/callnumber-KU.pl | 132 ++++++++++++++++++++++++++++ 1 files changed, 132 insertions(+), 0 deletions(-) create mode 100755 cataloguing/value_builder/callnumber-KU.pl diff --git a/cataloguing/value_builder/callnumber-KU.pl b/cataloguing/value_builder/callnumber-KU.pl new file mode 100755 index 0000000..becee75 --- /dev/null +++ b/cataloguing/value_builder/callnumber-KU.pl @@ -0,0 +1,132 @@ +#!/usr/bin/perl + +# Copyright 2010 BibLibre SARL +# +# 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. + +use strict; +use warnings; +use C4::Auth; +use CGI; +use C4::Context; + +=head1 DESCRIPTION + +Is used for callnumber computation. + +User must supply a letter prefix (unspecified length) followed by an empty space followed by a "number". +"Number" is 4 character long, and is either a number sequence which is 0 padded +or two letters which are 01 padded. +If input does not conform with this format any processing is omitted. + +Some examples of legal values that trigger auto allocation: + +AAA 0 - returns first unused number AAA 0xxx starting with AAA 0000 +BBB 12 - returns first unused number BBB 12xx starting with BBB 1200 +CCC QW - returns first unused number CCC QWxx starting with CCC QW01 + +=cut + +sub plugin_parameters { +} + +sub plugin_javascript { + my ($dbh,$record,$tagslib,$field_number,$tabloop) = @_; + my $res=" + + "; + + return ($field_number,$res); +} + +my $BASE_CALLNUMBER_RE = qr/^(\w+) (\w+)$/; +sub plugin { + my ($input) = @_; + my $code = $input->param('code'); + + my ($template, $loggedinuser, $cookie) = get_template_and_user({ + template_name => "cataloguing/value_builder/ajax.tmpl", + query => $input, + type => "intranet", + authnotrequired => 0, + flagsrequired => {editcatalogue => '*'}, + debug => 1, + }); + + my $ret; + my ($alpha, $num) = ($code =~ $BASE_CALLNUMBER_RE); + if (defined $num) { # otherwise no point + my ($num_alpha, $num_num) = ($num =~ m/^(\D+)?(\d+)?$/); + $num_alpha ||= ''; + my $pad_len = 4 - length($num); + + my $padded = $code; + if ($num_alpha) { + $padded .= "0" x ($pad_len - 1) if $pad_len > 1; + $padded .= "1"; + } else { + $padded .= "0" x $pad_len; + } + + my $dbh = C4::Context->dbh; + if ( my $first = $dbh->selectrow_array("SELECT itemcallnumber + FROM items + WHERE itemcallnumber = ?", undef, $padded) ) { + my $max = $dbh->selectrow_array("SELECT MIN(itemcallnumber) + FROM items + WHERE itemcallnumber LIKE ? + AND itemcallnumber >= ?", undef, "$alpha $num_alpha%", $code); + my ($num1) = ($max =~ m/(\d+)$/o); + my $len = length($num1); + $num1++; + if ($len == length($num1)) { # no overflow + $ret = "$alpha $num_alpha" . $num1; + } + } + else { + $ret = $padded; + } + } + + $template->param( + return => $ret || $code + ); + output_html_with_http_headers $input, $cookie, $template->output; +} + +1; -- 1.6.5 From oleonard at myacpl.org Mon Jan 30 16:12:59 2012 From: oleonard at myacpl.org (Owen Leonard) Date: Mon, 30 Jan 2012 10:12:59 -0500 Subject: [Koha-patches] [PATCH] Bug 3215 - It would be nice if "Add to Cart" changed to "Remove from Cart" Message-ID: <1327936379-11073-1-git-send-email-oleonard@myacpl.org> "Add to Cart" links in the OPAC should reflect whether a title is already in the Cart. On the results, list, and detail pages the "Add to Cart" link will say "In your cart (remove)" if the title is in your cart. The "(remove)" link will remove the title. This patch adds a check of the biblionumbers in the cart to the relevant scripts and sets a variable for the template governing whether to show "Add to cart" or "In your cart." Pages to test: - the search results page - any detail page (normal, MARC, ISBD) - any list contents page (/cgi-bin/koha/opac-shelves.pl?viewshelf=XX) Situations to test: - Add a single item to the Cart from the above pages The link should change from "Add to cart" to "In your cart (remove)" The count of items in your cart should reflect the addition, and the notification box should appear. - Remove a single item from the Cart from the above pages The link should change from "In your cart (remove)" to "Add to cart." The count of items in your cart should reflect the removal, and the notification box should appear. - View an item which is already in the cart from the above pages The cart links should reflect whether the title is already in the cart. - Remove one or more items from the Cart via the cart pop-up window View the above pages as you do so to verify that the operation is reflected immediately by the state of the "in your cart" links. - Empty the Cart from the cart pop-up window View the above pages as you do so to verify that the operation is reflected immediately by the state of the "in your cart" links. Tested in Firefox 9, Chrome 16, IE 7, and Opera 11.6 on Win 7 --- C4/VirtualShelves/Page.pm | 11 ++++ koha-tmpl/opac-tmpl/prog/en/css/opac.css | 16 ++++++ .../opac-tmpl/prog/en/includes/doc-head-close.inc | 3 + koha-tmpl/opac-tmpl/prog/en/js/basket.js | 58 ++++++++++++++++++-- .../opac-tmpl/prog/en/modules/opac-ISBDdetail.tt | 10 +++- .../opac-tmpl/prog/en/modules/opac-MARCdetail.tt | 10 +++- koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt | 8 +++- .../opac-tmpl/prog/en/modules/opac-results.tt | 8 +++- .../opac-tmpl/prog/en/modules/opac-shelves.tt | 9 +++- opac/opac-ISBDdetail.pl | 11 ++++ opac/opac-MARCdetail.pl | 11 ++++ opac/opac-detail.pl | 11 ++++ opac/opac-search.pl | 12 ++++ 13 files changed, 162 insertions(+), 16 deletions(-) diff --git a/C4/VirtualShelves/Page.pm b/C4/VirtualShelves/Page.pm index cfa4f60..7cab246 100644 --- a/C4/VirtualShelves/Page.pm +++ b/C4/VirtualShelves/Page.pm @@ -68,6 +68,14 @@ sub shelfpage ($$$$$) { my ( $shelflimit, $shelfoffset, $shelveslimit, $shelvesoffset ); my $marcflavour = C4::Context->preference("marcflavour"); + # get biblionumbers stored in the cart + my @cart_list; + my $cart_cookie = ( $type eq 'opac' ? "bib_list" : "intranet_bib_list" ); + if($query->cookie($cart_cookie)){ + my $cart_list = $query->cookie($cart_cookie); + @cart_list = split(/\//, $cart_list); + } + $shelflimit = ( $type eq 'opac' ? C4::Context->preference('OPACnumSearchResults') : C4::Context->preference('numSearchResults') ); $shelflimit = $shelflimit || 20; $shelfoffset = ( $itemoff - 1 ) * $shelflimit; # Sets the offset to begin retrieving items at @@ -227,6 +235,9 @@ sub shelfpage ($$$$$) { my @items_infos = &GetItemsLocationInfo( $this_item->{'biblionumber'}); $this_item->{'itemsissued'} = CountItemsIssued( $this_item->{'biblionumber'} ); $this_item->{'ITEM_RESULTS'} = \@items_infos; + if ( grep {$_ eq $biblionumber} @cart_list) { + $this_item->{'incart'} = 1; + } if (C4::Context->preference('TagsEnabled') and $tag_quantity = C4::Context->preference('TagsShowOnList')) { $this_item->{'TagLoop'} = get_tags({ diff --git a/koha-tmpl/opac-tmpl/prog/en/css/opac.css b/koha-tmpl/opac-tmpl/prog/en/css/opac.css index f904af2..f2b1467 100755 --- a/koha-tmpl/opac-tmpl/prog/en/css/opac.css +++ b/koha-tmpl/opac-tmpl/prog/en/css/opac.css @@ -453,6 +453,18 @@ a .term { background-image:url(../../images/cart2.gif); } +#action a.cartRemove, .actions a.cartRemove { + color: #cc3333; + font-size : 90%; + margin : 0; + padding: 0; +} + +#action a.incart { + background-image:url(../../images/cart2.gif); + color : #666; +} + /* toolbar buttons */ #toolbar { @@ -1296,6 +1308,9 @@ padding-left : .4em; color: #707070; padding : 0 0 .5em 0; } +.results_summary .results_summary { + font-size : 100%; +} .m880 { display:block; @@ -1498,6 +1513,7 @@ div.lang{ box-shadow: 1px 1px 3px #666; -moz-box-shadow: 1px 1px 3px #666; -webkit-box-shadow: 1px 1px 3px #666; + z-index: 2; } diff --git a/koha-tmpl/opac-tmpl/prog/en/includes/doc-head-close.inc b/koha-tmpl/opac-tmpl/prog/en/includes/doc-head-close.inc index 18e5917..3907f34 100644 --- a/koha-tmpl/opac-tmpl/prog/en/includes/doc-head-close.inc +++ b/koha-tmpl/opac-tmpl/prog/en/includes/doc-head-close.inc @@ -48,12 +48,15 @@ [% IF ( opacbookbag ) %]var MSG_BASKET_EMPTY = _("Your cart is currently empty"); var MSG_RECORD_IN_BASKET = _("This item is already in your cart"); var MSG_RECORD_ADDED = _("This item has been added to your cart"); + var MSG_RECORD_REMOVED = _("This item has been removed from your cart"); var MSG_NRECORDS_ADDED = _(" item(s) added to your cart"); var MSG_NRECORDS_IN_BASKET = _("already in your cart"); var MSG_NO_RECORD_SELECTED = _("No item was selected"); var MSG_NO_RECORD_ADDED = _("No item was added to your cart"); var MSG_CONFIRM_DEL_BASKET = _("Are you sure you want to empty your cart?"); var MSG_CONFIRM_DEL_RECORDS = _("Are you sure you want to remove the selected items?"); + var MSG_ITEM_IN_CART = _("In your cart"); + var MSG_ITEM_NOT_IN_CART = _("Add to your cart"); $("#cartDetails").ready(function(){ $("#cmspan").html("<\/i><\/i><\/span> "+_("Cart")+"<\/span><\/span><\/a>"); }); [% ELSE %][% IF ( virtualshelves ) %] var MSG_NO_RECORD_SELECTED = _("No item was selected");[% END %][% END %] [% IF ( opacuserlogin ) %][% IF ( TagsEnabled ) %]var MSG_TAGS_DISABLED = _("Sorry, tags are not enabled on this system."); diff --git a/koha-tmpl/opac-tmpl/prog/en/js/basket.js b/koha-tmpl/opac-tmpl/prog/en/js/basket.js index c83e001..573f3b3 100644 --- a/koha-tmpl/opac-tmpl/prog/en/js/basket.js +++ b/koha-tmpl/opac-tmpl/prog/en/js/basket.js @@ -128,10 +128,12 @@ function addRecord(val, selection,NoMsgAlert) { if (write) { writeCookie(nameCookie, valCookie); if (selection) { // when adding a selection of records + updateLink(val,"add"); return 1; } if (! NoMsgAlert ) { showCartUpdate(MSG_RECORD_ADDED); + updateLink(val,"add"); } } } @@ -229,12 +231,24 @@ function selRecord(num, status) { document.myform.records.value = str; } +function delSingleRecord(biblionumber){ + var nameCookie = "bib_list"; + var valCookie = readCookie(nameCookie); + var arrayRecords = valCookie.split("/"); + var pos = jQuery.inArray(biblionumber,arrayRecords); + arrayRecords.splice(pos,1); + valCookie = arrayRecords.join("/"); + writeCookie( nameCookie, valCookie ); + updateBasket( arrayRecords.length-1 ); + updateLink(biblionumber,"del"); + showCartUpdate(MSG_RECORD_REMOVED); +} + function delSelRecords() { var recordsSel = 0; var end = 0; var nameCookie = "bib_list"; var valCookie = readCookie(nameCookie, 1); - if (valCookie) { var str = document.myform.records.value; if (str.length > 0){ @@ -243,9 +257,10 @@ function delSelRecords() { while (!end){ s = str.indexOf("/"); if (s>0){ - num = str.substring(0, s) + num = str.substring(0, s); str = delRecord(num,str); str2 = delRecord(num,str2); + updateLink(num,"del",top.opener); } else { end = 1; } @@ -312,6 +327,7 @@ function delBasket() { rep = confirm(MSG_CONFIRM_DEL_BASKET); if (rep) { delCookie(nameCookie); + updateAllLinks(top.opener); document.location = "about:blank"; updateBasket(0,top.opener); window.close(); @@ -383,11 +399,11 @@ function showLess() { function updateBasket(updated_value,target) { if(target){ - target.$('#basketcount').html(""+updated_value+""); - target.$('#cartDetails').html(_("Your cart contains ")+updated_value+_(" items")); + target.$('#basketcount').html(""+updated_value+""); + target.$('#cartDetails').html(_("Your cart contains ")+updated_value+_(" items")); } else { - $('#basketcount').html(""+updated_value+""); - $('#cartDetails').html(_("Your cart contains ")+updated_value+_(" items")); + $('#basketcount').html(""+updated_value+""); + $('#cartDetails').html(_("Your cart contains ")+updated_value+_(" items")); } var basketcount = updated_value; } @@ -458,6 +474,36 @@ function hideLists(){ $("#listsDetails").fadeOut("fast"); } +function updateLink(val,op,target){ + if(target){ + if(op == "add"){ + target.$("a.cart"+val).html(MSG_ITEM_IN_CART).addClass("incart"); + target.$("a.cartR"+val).show(); + } else { + target.$("a.cart"+val).html(MSG_ITEM_NOT_IN_CART).removeClass("incart").addClass("addtocart cart"+val); + target.$("a.cartR"+val).hide(); + } + } else { + if(op == "add"){ + $("a.cart"+val).html(MSG_ITEM_IN_CART).addClass("incart"); + $("a.cartR"+val).show(); + } else { + $("a.cart"+val).html(MSG_ITEM_NOT_IN_CART).removeClass("incart").addClass("addtocart cart"+val); + $("a.cartR"+val).hide(); + } + } +} + +function updateAllLinks(target){ + if(target){ + target.$("a.incart").html(MSG_ITEM_NOT_IN_CART).removeClass("incart").addClass("addtocart"); + target.$("a.cartRemove").hide(); + } else { + $("a.incart").html(MSG_ITEM_NOT_IN_CART).removeClass("incart").addClass("addtocart"); + $("a.cartRemove").hide(); + } +} + $("#cartDetails").ready(function(){ $("#cartDetails,#cartmenulink").click(function(){ hideCart(); }); $("#cartmenulink").click(function(){ openBasket(); return false; }); diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-ISBDdetail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-ISBDdetail.tt index f9984a7..e954d17 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-ISBDdetail.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-ISBDdetail.tt @@ -70,9 +70,13 @@ [% END %][% END %] [% END %] - [% IF ( opacbookbag ) %]
  • - Add to Your Cart -
  • [% END %] + [% IF ( opacbookbag ) %] + [% IF ( incart ) %] +
  • In your cart (remove)
  • + [% ELSE %] +
  • Add to your cart
  • + [% END %] + [% END %]
  • More searches
  • diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-MARCdetail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-MARCdetail.tt index 284154e..cc716d4 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-MARCdetail.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-MARCdetail.tt @@ -227,9 +227,13 @@ $(document).ready(function(){ [% END %][% END %] [% END %] - [% IF ( opacbookbag ) %]
  • - Add to Your Cart -
  • [% END %] + [% IF ( opacbookbag ) %] + [% IF ( incart ) %] +
  • In your cart (remove)
  • + [% ELSE %] +
  • Add to your cart
  • + [% END %] + [% END %]
  • More searches
  • diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt index 6e70bf9..d1a4319 100755 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt @@ -1058,7 +1058,13 @@ YAHOO.util.Event.onContentReady("furtherm", function () { [% END %][% END %] [% END %] - [% IF ( opacbookbag ) %]
  • Add to Your Cart
  • [% END %] + [% IF ( opacbookbag ) %] + [% IF ( incart ) %] +
  • In your cart (remove)
  • + [% ELSE %] +
  • Add to your cart
  • + [% END %] + [% END %]
  • More searches
  • diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt index 5359dbc..e887d8f 100755 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt @@ -525,7 +525,13 @@ $(document).ready(function(){ [% IF ( opacuserlogin ) %][% IF ( loggedinusername ) %][% IF ( virtualshelves ) %]Save to Lists [% END %][% END %][% END %] - [% IF ( opacbookbag ) %]Add to Cart[% END %] + [% IF ( opacbookbag ) %] + [% IF ( SEARCH_RESULT.incart ) %] + In your Cart (remove) + [% ELSE %] + Add to Cart + [% END %] + [% END %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-shelves.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-shelves.tt index 391037f..d3dc082 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-shelves.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-shelves.tt @@ -321,8 +321,13 @@ $(function() { [% IF ( opacuserlogin ) %][% IF ( loggedinusername ) %][% IF ( virtualshelves ) %]Save to another list [% END %][% END %][% END %] - - [% IF ( opacbookbag ) %]Add to Cart[% ELSE %]nocart[% END %] + [% IF ( opacbookbag ) %] + [% IF ( itemsloo.incart ) %] + In your cart (remove) + [% ELSE %] + Add to Cart + [% END %] + [% END %] diff --git a/opac/opac-ISBDdetail.pl b/opac/opac-ISBDdetail.pl index c80d41c..4f373b5 100755 --- a/opac/opac-ISBDdetail.pl +++ b/opac/opac-ISBDdetail.pl @@ -69,6 +69,17 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user( my $biblionumber = $query->param('biblionumber'); +# get biblionumbers stored in the cart +my @cart_list; + +if($query->cookie("bib_list")){ + my $cart_list = $query->cookie("bib_list"); + @cart_list = split(/\//, $cart_list); + if ( grep {$_ eq $biblionumber} @cart_list) { + $template->param( incart => 1 ); + } +} + $template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') ); $template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) ); diff --git a/opac/opac-MARCdetail.pl b/opac/opac-MARCdetail.pl index f408cd2..a14815c 100755 --- a/opac/opac-MARCdetail.pl +++ b/opac/opac-MARCdetail.pl @@ -81,6 +81,17 @@ $template->param( bibliotitle => $biblio->{title}, ); +# get biblionumbers stored in the cart +my @cart_list; + +if($query->cookie("bib_list")){ + my $cart_list = $query->cookie("bib_list"); + @cart_list = split(/\//, $cart_list); + if ( grep {$_ eq $biblionumber} @cart_list) { + $template->param( incart => 1 ); + } +} + $template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') ); $template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) ); diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl index c4d8218..ce5d3c3 100755 --- a/opac/opac-detail.pl +++ b/opac/opac-detail.pl @@ -74,6 +74,17 @@ if ( ! $record ) { } $template->param( biblionumber => $biblionumber ); +# get biblionumbers stored in the cart +my @cart_list; + +if($query->cookie("bib_list")){ + my $cart_list = $query->cookie("bib_list"); + @cart_list = split(/\//, $cart_list); + if ( grep {$_ eq $biblionumber} @cart_list) { + $template->param( incart => 1 ); + } +} + SetUTF8Flag($record); diff --git a/opac/opac-search.pl b/opac/opac-search.pl index 08a4687..31775b0 100755 --- a/opac/opac-search.pl +++ b/opac/opac-search.pl @@ -88,6 +88,14 @@ if ($template_name eq 'opac-results.tmpl') { $template->param('COinSinOPACResults' => C4::Context->preference('COinSinOPACResults')); } +# get biblionumbers stored in the cart +my @cart_list; + +if($cgi->cookie("bib_list")){ + my $cart_list = $cgi->cookie("bib_list"); + @cart_list = split(/\//, $cart_list); +} + if ($format eq 'rss2' or $format eq 'opensearchdescription' or $format eq 'atom') { $template->param($format => 1); $template->param(timestamp => strftime("%Y-%m-%dT%H:%M:%S-00:00", gmtime)) if ($format eq 'atom'); @@ -497,6 +505,10 @@ for (my $i=0;$i<@servers;$i++) { # in order to avoid problems generated by the default size value in TT foreach my $line (@newresults) { if ( not exists $line->{'size'} ) { $line->{'size'} = "" } + # while we're checking each line, see if item is in the cart + if ( grep {$_ eq $line->{'biblionumber'}} @cart_list) { + $line->{'incart'} = 1; + } } my $tag_quantity; -- 1.7.3 From melia at test.bywatersolutions.com Thu Jan 26 02:13:39 2012 From: melia at test.bywatersolutions.com (Melia Meggs) Date: Wed, 25 Jan 2012 19:13:39 -0600 Subject: [Koha-patches] [PATCH] bug_7458: call number plugin In-Reply-To: References: Message-ID: <1327540419-26853-1-git-send-email-melia@test.bywatersolutions.com> From: Srdjan Jankovic Signed-off-by: Melia Meggs This patch is a call number plugin that generates the next available call number. After typing in an appropriate three or four letter prefix, followed by one or two numbers in subfield o - Full Call Number on the Add Item screen, this plugin will generate the next available call number with that prefix that is not yet in use. --- cataloguing/value_builder/callnumber-KU.pl | 127 ++++++++++++++++++++++++++++ 1 files changed, 127 insertions(+), 0 deletions(-) create mode 100755 cataloguing/value_builder/callnumber-KU.pl diff --git a/cataloguing/value_builder/callnumber-KU.pl b/cataloguing/value_builder/callnumber-KU.pl new file mode 100755 index 0000000..885026f --- /dev/null +++ b/cataloguing/value_builder/callnumber-KU.pl @@ -0,0 +1,127 @@ +#!/usr/bin/perl + +# Copyright 2010 BibLibre SARL +# +# 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. + +use strict; +use warnings; +use C4::Auth; +use CGI; +use C4::Context; + +=head1 DESCRIPTION + +Is used for callnumber computation. + +User must supply a letter prefix (unspecified length) followed by an empty space followed by a "number". +"Number" is i4 character long, and is either a number sequence which is 0 padded +or two letters which are 01 padded. +If input does not conform with this format any processing is omitted. + +Some examples of legal values that trigger auto allocation: + +AAA 0 - returns largest number AAA 0xxx incremented by 1 or AAA 0000 +BBB 12 - returns largest number BBB 12xx incremented by 1 or BBB 1200 +CCC QW - returns largest number CCC QWxx incremented by 1 or CCC QW01 + +=cut + +sub plugin_parameters { +} + +sub plugin_javascript { + my ($dbh,$record,$tagslib,$field_number,$tabloop) = @_; + my $res=" + + "; + + return ($field_number,$res); +} + +my $BASE_CALLNUMBER_RE = qr/^(\w+) (\w+)$/; +sub plugin { + my ($input) = @_; + my $code = $input->param('code'); + + my ($template, $loggedinuser, $cookie) = get_template_and_user({ + template_name => "cataloguing/value_builder/ajax.tmpl", + query => $input, + type => "intranet", + authnotrequired => 0, + flagsrequired => {editcatalogue => '*'}, + debug => 1, + }); + + my $ret; + my ($alpha, $num) = ($code =~ $BASE_CALLNUMBER_RE); + if (defined $num) { # otherwise no point + my $dbh = C4::Context->dbh; + if ( my $max = $dbh->selectrow_array("SELECT MAX(itemcallnumber) + FROM items + WHERE itemcallnumber LIKE ?", undef, "$code%") ) { + (undef, $num) = ($max =~ $BASE_CALLNUMBER_RE); + my ($num_alpha, $num_num) = ($num =~ m/^(\D+)?(\d+)$/); + my $len = length($num_num); + $num_num++; + if ($len == length($num_num)) { # no overflow + $ret = $num_alpha . $num_num + } + } + else { # pad with 0 + my $pad_len = 4 - length($num); + if ($pad_len > 0) { + if ($num =~ m/^\d+$/) { + $ret = $num. ("0" x $pad_len); + } else { + $ret = $num ; + $ret .= "0" x ($pad_len - 1) if $pad_len > 1; + $ret .= "1"; + } + } + } + } + $ret = "$alpha $ret" if $ret; + + $template->param( + return => $ret || $code + ); + output_html_with_http_headers $input, $cookie, $template->output; +} + +1; -- 1.7.2.5 From f.demians at tamil.fr Mon Jan 30 19:15:23 2012 From: f.demians at tamil.fr (=?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Demians?=) Date: Mon, 30 Jan 2012 19:15:23 +0100 Subject: [Koha-patches] =?utf-8?q?=5BPATCH=5D_Bug_6299_Add_relator_codes_f?= =?utf-8?q?or_fr-FR?= Message-ID: <1327947323-10210-1-git-send-email-f.demians@tamil.fr> --- .../marc21/Optionnel/marc21_relatorterms.sql | 207 ++++++++++++++++++++ .../marc21/Optionnel/marc21_relatorterms.txt | 1 + 2 files changed, 208 insertions(+), 0 deletions(-) create mode 100644 installer/data/mysql/fr-FR/marcflavour/marc21/Optionnel/marc21_relatorterms.sql create mode 100644 installer/data/mysql/fr-FR/marcflavour/marc21/Optionnel/marc21_relatorterms.txt diff --git a/installer/data/mysql/fr-FR/marcflavour/marc21/Optionnel/marc21_relatorterms.sql b/installer/data/mysql/fr-FR/marcflavour/marc21/Optionnel/marc21_relatorterms.sql new file mode 100644 index 0000000..8e1af42 --- /dev/null +++ b/installer/data/mysql/fr-FR/marcflavour/marc21/Optionnel/marc21_relatorterms.sql @@ -0,0 +1,207 @@ +-- MARC code list for Relators, taken from +-- http://www.marc21.ca/040010-220-f.html +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','acp','Copiste d'art'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','act','Acteur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','adp','Adaptateur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','aft','Auteur de la postface, de l'achev? d'imprimer, etc.'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','anl','Analyste'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','anm','Animateur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','ann','Annotateur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','ant','Ant?c?dent bibliographique'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','app','Candidat'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','aqt','Auteur mentionn? dans une citation ou des extraits de textes'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','arc','Architecte'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','ard','Directeur artistique'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','arr','Arrangeur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','art','Artiste'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','asg','Cessionnaire'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','asn','Nom associ?'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','att','Nom attribu?'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','auc','Commissaire-priseur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','aud','Auteur du dialogue'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','aui','Auteur de l'introduction, etc.'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','aus','Auteur d'un sc?nario, etc.'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','aut','Auteur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','bdd','Concepteur de reliures'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','bjd','Concepteur de jaquettes'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','bkp','Producteur de livres'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','bnd','Relieur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','bpd','Concepteur d'ex-libris'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','bsl','Libraire'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','ccp','Concepteur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','chr','Chor?graphe'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','clb','Collaborateur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','cli','Client'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','cll','Calligraphiste'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','clt','Responsable de la phototypie'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','cmm','Commentateur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','cmp','Compositeur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','cmt','Compositeur (Imprimerie)'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','cnd','Chef d'orchestre'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','cns','Censeur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','coe','Contestant-intim?'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','col','Collectionneur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','com','Compilateur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','cos','Contestant'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','cot','Contestant-appelant'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','cov','Concepteur de pages couvertures'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','cpc','Demandeur du droit d'auteur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','cpe','Plaignant-intim?'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','cph','Titulaire du droit d'auteur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','cpl','Plaignant'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','cpt','Plaignant-appelant'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','cre','Cr?ateur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','crp','Correspondant'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','crr','R?viseur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','csl','Expert-conseil'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','cst','Costumier'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','ctb','Collaborateur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','cte','Contest?-intim?'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','ctg','Cartographe'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','ctr','Contractant'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','cts','Contest?'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','ctt','Contest?-appelant'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','cur','Conservateur d'exposition'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','cwt','Commentateur d'un texte ?crit'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','dfd','D?fendeur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','dfe','D?fendeur-intim?'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','dft','D?fendeur-appelant'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','dgg','Institution ?mettrice d'un dipl?me'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','dis','Doctorant'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','dln','Dessinateur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','dnc','Danseur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','dnr','Donateur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','dpc','Entit? illustr?e'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','dpt','D?posant'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','drm','Dessinateur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','drt','Directeur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','dsr','Designer'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','dst','Distributeur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','dtc','Contributeur de donn?es'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','dte','D?dicataire'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','dtm','Gestionnaire de donn?es'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','dub','Auteur douteux'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','edt','?diteur intellectuel'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','egr','Graveur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','elg','?lectricien'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','elt','Galvanotypeur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','eng','Ing?nieur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','etr','Aquafortiste'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','exp','Expert'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','fac','Copiste'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','fld','Directeur local'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','flm','Monteur de films'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','fmo','Ancien propri?taire'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','fnd','Bailleur de fonds'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','fpy','Premi?re partie'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','frg','Faussaire'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','gis','Sp?cialiste de l'information g?ographique'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','grt','Graphiste'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','grt] (Graphiste) avant mars 1988 seulement',' [Cod?'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','hnr','Personne honor?e'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','hst','H?te'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','ill','Illustrateur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','ilu','Enlumineur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','inv','Inventeur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','itr','Instrumentiste'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','ive','Personne interrog?e'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','ivr','Interviewer'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','lbr','Laboratoire'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','lbt','Librettiste'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','ldr','Directeur de laboratoire'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','led','Chef'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','lee','Partie adverse-intim?'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','lel','Partie adverse'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','len','Pr?teur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','let','Partie adverse-appelant'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','lgd','?clairagiste'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','lie','Requ?rant-intim?'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','lil','Requ?rant'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','lit','Requ?rant-appelant'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','lsa','Architecte-paysagiste'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','lse','Porteur de licence'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','lso','Donneur de licence'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','ltg','Lithographe'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','lyr','Parolier'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','mcp','Copiste de musique'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','mdc','Agent de liaison sur les m?tadonn?es'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','mfr','Fabricant'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','mke','Baliseur de donn?es'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','mod','Animateur de d?bat'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','mon','Moniteur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','msd','Directeur musical'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','mte','Graveur sur m?tal'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','mus','Musicien'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','nrt','Narrateur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','opn','Opposant'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','orm','Organisateur de r?union'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','oth','Autre'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','own','Propri?taire'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','pbd','Directeur de la publication'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','pbl','?diteur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','pdr','Directeur de projet'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','pht','Photographe'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','plt','Clicheur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','pma','Agence de r?glementation'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','pmn','Directeur de production'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','pop','Imprimeur de planches'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','ppm','Papetier'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','ppt','Marionnettiste'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','prc','Agent de liaison du processus'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','prd','Personnel de la r?alisation'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','prf','Interpr?te'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','prg','Programmeur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','prm','Graveur, (arts visuels)'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','pro','Producteur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','prt','Imprimeur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','pta','Demandeur de brevet'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','pte','Demandeur-intim?'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','ptf','Demandeur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','pth','Titulaire de brevet'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','ptt','Demandeur-appelant'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','rce','Ing?nieur du son'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','rcp','Destinataire'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','red','R?dacteur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','ren','Perspectiviste'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','res','Chercheur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','rev','Critique'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','rps','Service d'archives'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','rpt','Reporteur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','rpy','Partie responsable'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','rse','R?pondant-intim?'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','rsg','Metteur en sc?ne'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','rsp','R?pondant'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','rst','R?pondant-appelant'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','rth','Chef d'?quipe de chercheurs'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','rtm','Membre d'?quipe de chercheurs'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','sad','Conseiller scientifique'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','sce','Sc?nariste'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','scl','Sculpteur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','scr','Scribe'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','sds','Concepteur du son'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','sec','Secr?taire'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','sgn','Signataire'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','sht','Organisme de soutien'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','sng','Chanteur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','spk','Intervenant'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','spn','Commanditaire'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','spy','Deuxi?me partie'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','srv','Arpenteur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','std','D?corateur de sc?ne'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','stl','Conteur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','stm','R?gisseur de plateau'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','stn','Organisme de normalisation'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','str','St?r?otypeur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','tcd','Directeur technique'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','tch','Professeur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','ths','Directeur de th?se'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','trc','Transcripteur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','trl','Traducteur'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','tyd','Concepteur de caract?res typographiques'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','tyg','Typographe'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','vdg','Vid?aste'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','wam','Auteur du mat?riel d'appoint'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','wdc','Xylographe'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','wde','Graveur sur bois de bout'); +INSERT INTO authorised_values (category, authorised_value, lib) VALUES ('RELTERMS','wit','T?moin'); + diff --git a/installer/data/mysql/fr-FR/marcflavour/marc21/Optionnel/marc21_relatorterms.txt b/installer/data/mysql/fr-FR/marcflavour/marc21/Optionnel/marc21_relatorterms.txt new file mode 100644 index 0000000..abed2b4 --- /dev/null +++ b/installer/data/mysql/fr-FR/marcflavour/marc21/Optionnel/marc21_relatorterms.txt @@ -0,0 +1 @@ +MARC Code List for Relators, as of http://www.marc21.ca/040010-220-f.html -- 1.7.8 From srdjan at catalyst.net.nz Tue Jan 31 01:16:25 2012 From: srdjan at catalyst.net.nz (Srdjan Jankovic) Date: Tue, 31 Jan 2012 13:16:25 +1300 Subject: [Koha-patches] [PATCH] bug_7458: A call number plugin In-Reply-To: References: Message-ID: <1327968985-6719-1-git-send-email-srdjan@catalyst.net.nz> --- cataloguing/value_builder/callnumber-KU.pl | 132 ++++++++++++++++++++++++++++ 1 files changed, 132 insertions(+), 0 deletions(-) create mode 100755 cataloguing/value_builder/callnumber-KU.pl diff --git a/cataloguing/value_builder/callnumber-KU.pl b/cataloguing/value_builder/callnumber-KU.pl new file mode 100755 index 0000000..79795fa --- /dev/null +++ b/cataloguing/value_builder/callnumber-KU.pl @@ -0,0 +1,132 @@ +#!/usr/bin/perl + +# Copyright 2012 CatalystIT Ltd +# +# 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. + +use strict; +use warnings; +use C4::Auth; +use CGI; +use C4::Context; + +=head1 DESCRIPTION + +Is used for callnumber computation. + +User must supply a letter prefix (unspecified length) followed by an empty space followed by a "number". +"Number" is 4 character long, and is either a number sequence which is 0 padded +or two letters which are 01 padded. +If input does not conform with this format any processing is omitted. + +Some examples of legal values that trigger auto allocation: + +AAA 0 - returns first unused number AAA 0xxx starting with AAA 0000 +BBB 12 - returns first unused number BBB 12xx starting with BBB 1200 +CCC QW - returns first unused number CCC QWxx starting with CCC QW01 + +=cut + +sub plugin_parameters { +} + +sub plugin_javascript { + my ($dbh,$record,$tagslib,$field_number,$tabloop) = @_; + my $res=" + + "; + + return ($field_number,$res); +} + +my $BASE_CALLNUMBER_RE = qr/^(\w+) (\w+)$/; +sub plugin { + my ($input) = @_; + my $code = $input->param('code'); + + my ($template, $loggedinuser, $cookie) = get_template_and_user({ + template_name => "cataloguing/value_builder/ajax.tmpl", + query => $input, + type => "intranet", + authnotrequired => 0, + flagsrequired => {editcatalogue => '*'}, + debug => 1, + }); + + my $ret; + my ($alpha, $num) = ($code =~ $BASE_CALLNUMBER_RE); + if (defined $num) { # otherwise no point + my ($num_alpha, $num_num) = ($num =~ m/^(\D+)?(\d+)?$/); + $num_alpha ||= ''; + my $pad_len = 4 - length($num); + + my $padded = $code; + if ($num_alpha) { + $padded .= "0" x ($pad_len - 1) if $pad_len > 1; + $padded .= "1"; + } else { + $padded .= "0" x $pad_len; + } + + my $dbh = C4::Context->dbh; + if ( my $first = $dbh->selectrow_array("SELECT itemcallnumber + FROM items + WHERE itemcallnumber = ?", undef, $padded) ) { + my $max = $dbh->selectrow_array("SELECT MIN(itemcallnumber) + FROM items + WHERE itemcallnumber LIKE ? + AND itemcallnumber >= ?", undef, "$alpha $num_alpha%", $code); + my ($num1) = ($max =~ m/(\d+)$/o); + my $len = length($num1); + $num1++; + if ($len == length($num1)) { # no overflow + $ret = "$alpha $num_alpha" . $num1; + } + } + else { + $ret = $padded; + } + } + + $template->param( + return => $ret || $code + ); + output_html_with_http_headers $input, $cookie, $template->output; +} + +1; -- 1.6.5 From srdjan at catalyst.net.nz Tue Jan 31 03:37:52 2012 From: srdjan at catalyst.net.nz (Srdjan Jankovic) Date: Tue, 31 Jan 2012 15:37:52 +1300 Subject: [Koha-patches] [PATCH] bug_7190: Do not reverse writeoffs when item is returned In-Reply-To: References: Message-ID: <1327977472-2761-1-git-send-email-srdjan@catalyst.net.nz> --- C4/Circulation.pm | 3 ++- .../prog/en/modules/members/paycollect.tt | 2 ++ members/paycollect.pl | 2 ++ 3 files changed, 6 insertions(+), 1 deletions(-) diff --git a/C4/Circulation.pm b/C4/Circulation.pm index 0b5068c..2bf5d51 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -1866,10 +1866,11 @@ sub _FixAccountForLostAndReturned { my $item_id = @_ ? shift : $itemnumber; # Send the barcode if you want that logged in the description my $dbh = C4::Context->dbh; # check for charge made for lost book - my $sth = $dbh->prepare("SELECT * FROM accountlines WHERE (itemnumber = ?) AND (accounttype='L' OR accounttype='Rep') ORDER BY date DESC"); + my $sth = $dbh->prepare("SELECT * FROM accountlines WHERE itemnumber = ? AND accounttype IN ('L', 'Rep', 'W') ORDER BY date DESC, accountno DESC"); $sth->execute($itemnumber); my $data = $sth->fetchrow_hashref; $data or return; # bail if there is nothing to do + $data->{accounttype} eq 'W' and return; # Written off # writeoff this amount my $offset; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/paycollect.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/paycollect.tt index 08ee909..0682aea 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/paycollect.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/paycollect.tt @@ -94,6 +94,7 @@ function moneyFormat(textObj) {
    + @@ -148,6 +149,7 @@ function moneyFormat(textObj) { + diff --git a/members/paycollect.pl b/members/paycollect.pl index cbddc05..3037b37 100755 --- a/members/paycollect.pl +++ b/members/paycollect.pl @@ -67,6 +67,7 @@ if ( $individual || $writeoff ) { my $amount = $input->param('amount'); my $amountoutstanding = $input->param('amountoutstanding'); $accountno = $input->param('accountno'); + my $itemnumber = $input->param('itemnumber'); my $description = $input->param('description'); my $title = $input->param('title'); my $notify_id = $input->param('notify_id'); @@ -78,6 +79,7 @@ if ( $individual || $writeoff ) { amount => $amount, amountoutstanding => $amountoutstanding, title => $title, + itemnumber => $itemnumber, description => $description, notify_id => $notify_id, notify_level => $notify_level, -- 1.6.5 From adrien.saurat at biblibre.com Tue Jan 31 11:30:30 2012 From: adrien.saurat at biblibre.com (Adrien Saurat) Date: Tue, 31 Jan 2012 11:30:30 +0100 Subject: [Koha-patches] [PATCH] Bug 4969: allows deletion of vendor with no basket Message-ID: <1328005830-6924-1-git-send-email-adrien.saurat@biblibre.com> --- acqui/supplier.pl | 6 +++++- .../prog/en/includes/acquisitions-toolbar.inc | 4 ++++ 2 files changed, 9 insertions(+), 1 deletions(-) diff --git a/acqui/supplier.pl b/acqui/supplier.pl index 3faa560..a24db4a 100755 --- a/acqui/supplier.pl +++ b/acqui/supplier.pl @@ -117,7 +117,11 @@ if ( $op eq 'display' ) { contracts => $contracts, ); } elsif ( $op eq 'delete' ) { - DelBookseller($id); + # no further message needed for the user + # the DELETE button only appears in the template if basketcount == 0 + if ( $supplier->{'basketcount'} == 0 ) { + DelBookseller($id); + } print $query->redirect('/cgi-bin/koha/acqui/acqui-home.pl'); exit; } else { diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/acquisitions-toolbar.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/acquisitions-toolbar.inc index f81b303..0385d94 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/acquisitions-toolbar.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/acquisitions-toolbar.inc @@ -16,6 +16,7 @@ new YAHOO.widget.Button("newsupplier"); new YAHOO.widget.Button("newbasket"); new YAHOO.widget.Button("editsupplier"); + new YAHOO.widget.Button("deletesupplier"); new YAHOO.widget.Button("receive"); new YAHOO.widget.Button("newcontract"); new YAHOO.widget.Button("editcontracts"); @@ -46,6 +47,9 @@ [% IF ( id ) %] [% IF ( CAN_user_acquisition_vendors_manage ) %]
  • Edit
  • + [% UNLESS basketcount %] +
  • Delete
  • + [% END %]
  • New Contract
  • Contracts
  • [% UNLESS ( basketcount ) %] -- 1.7.4.1 From adrien.saurat at biblibre.com Tue Jan 31 15:18:06 2012 From: adrien.saurat at biblibre.com (Adrien Saurat) Date: Tue, 31 Jan 2012 15:18:06 +0100 Subject: [Koha-patches] [PATCH] Bug 7457: log cleaning on basket.pl Message-ID: <1328019486-12720-1-git-send-email-adrien.saurat@biblibre.com> --- acqui/basket.pl | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/acqui/basket.pl b/acqui/basket.pl index c528156..b559732 100755 --- a/acqui/basket.pl +++ b/acqui/basket.pl @@ -229,12 +229,12 @@ if ( $op eq 'delete_confirm' ) { my $gist = $bookseller->{gstrate} // C4::Context->preference("gist") // 0; $gist = 0 if $gist == 0.0000; my $discount = $bookseller->{'discount'} / 100; - my $total_rrp; # RRP Total, its value will be assigned to $total_rrp_gsti or $total_rrp_gste depending of $bookseller->{'listincgst'} - my $total_rrp_gsti; # RRP Total, GST included - my $total_rrp_gste; # RRP Total, GST excluded - my $gist_rrp; - my $total_rrp_est; - + my $total_rrp = 0; # RRP Total, its value will be assigned to $total_rrp_gsti or $total_rrp_gste depending of $bookseller->{'listincgst'} + my $total_rrp_gsti = 0; # RRP Total, GST included + my $total_rrp_gste = 0; # RRP Total, GST excluded + my $gist_rrp = 0; + my $total_rrp_est = 0; + my $qty_total; my @books_loop; @@ -281,7 +281,7 @@ if ( $op eq 'delete_confirm' ) { $line{biblios} = $countbiblio - 1; $line{left_subscription} = 1 if scalar @subscriptions >= 1; $line{subscriptions} = scalar @subscriptions; - $line{left_holds} = 1 if $holds >= 1; + ($holds >= 1) ? $line{left_holds} = 1 : $line{left_holds} = 0; $line{left_holds_on_order} = 1 if $line{left_holds}==1 && ($line{items} == 0 || $itemholds ); $line{holds} = $holds; $line{holds_on_order} = $itemholds?$itemholds:$holds if $line{left_holds_on_order}; -- 1.7.4.1