@@ -, +, @@ Checkin Notices need to get date_due from old_issues Add full set of item fields : ensure dates are formatted Could specify some fields for item that were not being substituted ensure contents is set and that dates are formatted Need to format dates in advance_notices Add issuedate, barcode, return_date and call no to item notice fields Allow these to be separately designated in circulation notices item.contents remains the preferred way in batch notices tidy up digest notices Need to be tolerant of the format of the itemscontent parameter specifically strip whitespace when separating out filenames --- C4/Circulation.pm | 1 + C4/Letters.pm | 57 ++++++++++++++++++++++++++++++------- misc/cronjobs/advance_notices.pl | 13 ++++++-- misc/cronjobs/overdue_notices.pl | 4 ++- tools/letter.pl | 6 ++++ 5 files changed, 65 insertions(+), 16 deletions(-) --- a/C4/Circulation.pm +++ a/C4/Circulation.pm @@ -2523,6 +2523,7 @@ sub SendCirculationAlert { C4::Letters::parseletter($letter, 'biblioitems', $item->{biblionumber}); C4::Letters::parseletter($letter, 'borrowers', $borrower->{borrowernumber}); C4::Letters::parseletter($letter, 'branches', $branch); + C4::Letters::parseletter($letter, 'items', $item->{itemnumber}, $type); my @transports = @{ $borrower_preferences->{transports} }; # warn "no transports" unless @transports; for (@transports) { --- a/C4/Letters.pm +++ a/C4/Letters.pm @@ -30,6 +30,7 @@ use C4::Log; use C4::SMS; use C4::Debug; use Date::Calc qw( Add_Delta_Days ); +use C4::Dates qw/format_date/; use Encode; use Carp; @@ -477,12 +478,17 @@ sub parseletter_sth { carp "ERROR: parseletter_sth() called without argument (table)"; return; } - # check cache first + my $itemselect = + 'SELECT barcode, itemcallnumber, location, holdingbranch, date_due, issuedate, author, title from items ' + . 'left join issues on issues.itemnumber = items.itemnumber ' + . 'LEFT JOIN biblio on items.biblionumber = biblio.biblionumber ' + . 'WHERE items.itemnumber = ? '; +# check cache first (defined $handles{$table}) and return $handles{$table}; my $query = ($table eq 'biblio' ) ? "SELECT * FROM $table WHERE biblionumber = ?" : ($table eq 'biblioitems' ) ? "SELECT * FROM $table WHERE biblionumber = ?" : - ($table eq 'items' ) ? "SELECT * FROM $table WHERE itemnumber = ?" : + ($table eq 'items' ) ? $itemselect : ($table eq 'reserves' ) ? "SELECT * FROM $table WHERE borrowernumber = ? and biblionumber = ?" : ($table eq 'borrowers' ) ? "SELECT * FROM $table WHERE borrowernumber = ?" : ($table eq 'branches' ) ? "SELECT * FROM $table WHERE branchcode = ?" : @@ -510,6 +516,13 @@ sub parseletter { warn "parseletter_sth('$table') failed to return a valid sth. No substitution will be done for that table."; return; } + my $check_in_notice; + if ($table eq 'items') { + if ($pk2 && $pk2 eq 'CHECKIN') { + $check_in_notice = 1; + } + $pk2 = undef; + } if ( $pk2 ) { $sth->execute($pk, $pk2); } else { @@ -531,17 +544,39 @@ sub parseletter { )->output(); } - # 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; + if ($table ne 'items' ) { + 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; + } } + + if ($table eq 'items') { + if ($check_in_notice) { + # need to get dates from old_issues + my $dates = C4::Context->dbh->selectrow_arrayref( +'SELECT issuedate, date_due FROM old_issues where itemnumber = ? AND DATE(timestamp) = CURDATE() ORDER BY timestamp DESC LIMIT 1', + {}, $pk); + $values->{issuedate} = ${ $dates}[0]; + $values->{date_due} = ${ $dates}[1]; + } + $values->{issuedate} = format_date($values->{issuedate}); + $values->{date_due} = format_date($values->{date_due}); + $values->{content} = join "\t", $values->{issuedate}, $values->{title}, $values->{barcode}, $values->{author}; + for my $field ( qw( issuedate date_due barcode holdingbranch location itemcallnumber content)) { + my $replacefield = "<<$table.$field>>"; + my $replacedby = $values->{$field} || ''; + ($letter->{title} ) and $letter->{title} =~ s/$replacefield/$replacedby/g; + ($letter->{content}) and $letter->{content} =~ s/$replacefield/$replacedby/g; + } + } + return $letter; } --- a/misc/cronjobs/advance_notices.pl +++ a/misc/cronjobs/advance_notices.pl @@ -55,6 +55,7 @@ use C4::Members; use C4::Members::Messaging; use C4::Overdues; use C4::Dates qw/format_date/; +use DBI; # These are defaults for command line options. @@ -150,7 +151,7 @@ UPCOMINGITEM: foreach my $upcoming ( @$upcoming_dues ) { if ( $borrower_preferences->{'wants_digest'} ) { # cache this one to process after we've run through all of the items. - $due_digest->{$upcoming->{'borrowernumber'}}++; + push @{$due_digest->{$upcoming->{borrowernumber}}}, $upcoming->{itemnumber}; } else { my $biblio = C4::Biblio::GetBiblioFromItemNumber( $upcoming->{'itemnumber'} ); my $letter_type = 'DUE'; @@ -179,7 +180,7 @@ UPCOMINGITEM: foreach my $upcoming ( @$upcoming_dues ) { if ( $borrower_preferences->{'wants_digest'} ) { # cache this one to process after we've run through all of the items. - $upcoming_digest->{$upcoming->{'borrowernumber'}}++; + push @{$due_digest->{$upcoming->{borrowernumber}}}, $upcoming->{itemnumber}; } else { my $biblio = C4::Biblio::GetBiblioFromItemNumber( $upcoming->{'itemnumber'} ); my $letter_type = 'PREDUE'; @@ -231,7 +232,9 @@ SELECT biblio.*, items.*, issues.* AND (TO_DAYS(date_due)-TO_DAYS(NOW()) = ?) END_SQL -PATRON: while ( my ( $borrowernumber, $count ) = each %$upcoming_digest ) { +PATRON: for my $borrowernumber ( keys %{ $upcoming_digest} ) { + my @items = @{$upcoming_digest->{$borrowernumber}}; + my $count = scalar @items; my $borrower_preferences = C4::Members::Messaging::GetMessagingPreferences( { borrowernumber => $borrowernumber, message_name => 'advance notice' } ); # warn( Data::Dumper->Dump( [ $borrower_preferences ], [ 'borrower_preferences' ] ) ); @@ -267,7 +270,9 @@ PATRON: while ( my ( $borrowernumber, $count ) = each %$upcoming_digest ) { } # Now, run through all the people that want digests and send them -PATRON: while ( my ( $borrowernumber, $count ) = each %$due_digest ) { +PATRON: for my $borrowernumber ( keys %{ $upcoming_digest} ) { + my @items = @{$upcoming_digest->{$borrowernumber}}; + my $count = scalar @items; my $borrower_preferences = C4::Members::Messaging::GetMessagingPreferences( { borrowernumber => $borrowernumber, message_name => 'item due' } ); # warn( Data::Dumper->Dump( [ $borrower_preferences ], [ 'borrower_preferences' ] ) ); --- a/misc/cronjobs/overdue_notices.pl +++ a/misc/cronjobs/overdue_notices.pl @@ -320,7 +320,9 @@ if (@branchcodes) { } # these are the fields that will be substituted into <> -my @item_content_fields = split( /,/, $itemscontent ); +$itemscontent=~s/^\s*//; +$itemscontent=~s/\s*$//; +my @item_content_fields = split( /\s*,\s*/, $itemscontent ); binmode( STDOUT, ":utf8" ); --- a/tools/letter.pl +++ a/tools/letter.pl @@ -169,9 +169,15 @@ sub add_form { push @{$field_selection}, add_fields('suggestions', 'borrowers', 'biblio'); } else { + my @item_field_names = qw(barcode itemcallnumber date_due issuedate); + push @{$field_selection}, add_fields('biblio','biblioitems'), {value => q{}, text => '---ITEMS---' }, {value => 'items.content', text => 'items.content'}, + {value => 'items.barcode', text => 'items.barcode'}, + {value => 'items.itemcallnumber', text => 'items.itemcallnumber'}, + {value => 'items.date_due', text => 'items.date_due'}, + {value => 'items.issuedate', text => 'items.issuedate'}, add_fields('borrowers'); } --