From 36824651d2afe4ba3f5e5bf422ac48195cc51ebc Mon Sep 17 00:00:00 2001
From: Stefan Berndtsson <stefan.berndtsson@ub.gu.se>
Date: Tue, 20 Nov 2018 11:35:45 +0100
Subject: [PATCH] Bug 21886: Add option to send notices from owning library
 instead of issuing library
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The provided patch adds the following functionality:

* Add --owning to both advance_notice.pl and overdue_notice.pl
* Add --library to advance_notice.pl like the way overdue_notice.pl already works

When specifying "--owning" both scripts will use items.homebranch instead of
issues.branchcode to determine sending library.

For advance_notice.pl this affects non-digest DUE and PREDUE, but not digest notices.

To test:

1.  Have a patron who wants advance notices as email with 2 days in advance (not digest)
2.  Have the first overdue date set 3 days past due date
3.  Have issue for that patron where date_due is 2 days away where the item homebranch differs from the issuing branch
4.  Have issue for that patron where date_due is 3 days old
5.  Run advance_notices.pl without --owning
6.  Run overdue_notices.pl without --owning
7.  Confirm that two messages were created for that patron with the sender being the issuing branch
8.  Delete messages or create two more issues according to (3) and (4)
9.  Run advance_notices.pl with --owning
10. Run overdue_notices.pl with --owning
11. Confirm that the two messages created has the item homebranch as sender

Extra feature for advance_notices.pl is that it adds "--library" the same way overdue_notices.pl has.
Adding variants of that flag in steps (5) and (9) above can confirm this option as well.

Sponsored-by: Gothenburg University Library
Signed-off-by: Björn Nylén <bjorn.nylen@ub.lu.se>
Signed-off-by: Timothy Alexis Vass <timothy_alexis.vass@ub.lu.se>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
---
 C4/Circulation.pm                | 19 +++++++++++---
 misc/cronjobs/advance_notices.pl | 43 +++++++++++++++++++++++++++++---
 misc/cronjobs/overdue_notices.pl | 23 ++++++++++++++---
 3 files changed, 76 insertions(+), 9 deletions(-)

diff --git a/C4/Circulation.pm b/C4/Circulation.pm
index 29b3347666..236063c01f 100644
--- a/C4/Circulation.pm
+++ b/C4/Circulation.pm
@@ -2617,8 +2617,21 @@ sub GetUpcomingDueIssues {
 
     $params->{'days_in_advance'} = 7 unless exists $params->{'days_in_advance'};
     my $dbh = C4::Context->dbh;
-
-    my $statement = <<END_SQL;
+    my $statement;
+    if($params->{'owning_library'}) {
+	$statement = <<"END_SQL";
+SELECT *
+FROM (
+    SELECT issues.*, items.itype as itemtype, items.homebranch, TO_DAYS( date_due )-TO_DAYS( NOW() ) as days_until_due, branches.branchemail
+    FROM issues
+    LEFT JOIN items USING (itemnumber)
+    LEFT OUTER JOIN branches ON (branches.branchcode = items.homebranch)
+    WHERE returndate is NULL
+) tmp
+WHERE days_until_due >= 0 AND days_until_due <= ?
+END_SQL
+    } else {
+	$statement = <<"END_SQL";
 SELECT *
 FROM (
     SELECT issues.*, items.itype as itemtype, items.homebranch, TO_DAYS( date_due )-TO_DAYS( NOW() ) as days_until_due, branches.branchemail
@@ -2629,7 +2642,7 @@ FROM (
 ) tmp
 WHERE days_until_due >= 0 AND days_until_due <= ?
 END_SQL
-
+    }
     my @bind_parameters = ( $params->{'days_in_advance'} );
     
     my $sth = $dbh->prepare( $statement );
diff --git a/misc/cronjobs/advance_notices.pl b/misc/cronjobs/advance_notices.pl
index d8dcf73a51..39e9171c59 100755
--- a/misc/cronjobs/advance_notices.pl
+++ b/misc/cronjobs/advance_notices.pl
@@ -125,6 +125,16 @@ Enabling this flag ensures that the issuing library is the sender of
 the digested message.  It has no effect unless the borrower has
 chosen 'Digests only' on the advance messages.
 
+=item B<-library>
+
+select notices for one specific library. Use the value in the
+branches.branchcode table. This option can be repeated in order
+to select notices for a group of libraries.
+
+=item B<--owning>
+
+Use the address information from the item homebranch library instead of the issuing library.
+
 =back
 
 =head1 DESCRIPTION
@@ -191,6 +201,8 @@ my $mindays     = 0;                                                # -m: Maximu
 my $maxdays     = 30;                                               # -e: the End of the time period
 my $verbose     = 0;                                                # -v: verbose
 my $digest_per_branch = 0;                                          # -digest-per-branch: Prepare and send digests per branch
+my @branchcodes; # Branch(es) passed as parameter
+my $owning_library = 0;
 my $itemscontent = join(',',qw( date_due title author barcode ));
 
 my $help    = 0;
@@ -199,6 +211,8 @@ my $man     = 0;
 GetOptions(
             'help|?'         => \$help,
             'man'            => \$man,
+            'library=s'      => \@branchcodes,
+            'owning'         => \$owning_library,
             'c'              => \$confirm,
             'n'              => \$nomail,
             'm:i'            => \$maxdays,
@@ -226,11 +240,16 @@ unless ($confirm) {
 }
 cronlogaction();
 
+my %branches = map { $_ => 1 } @branchcodes if @branchcodes;
+
 # The fields that will be substituted into <<items.content>>
 my @item_content_fields = split(/,/,$itemscontent);
 
 warn 'getting upcoming due issues' if $verbose;
-my $upcoming_dues = C4::Circulation::GetUpcomingDueIssues( { days_in_advance => $maxdays } );
+my $upcoming_dues = C4::Circulation::GetUpcomingDueIssues( {
+    days_in_advance => $maxdays,
+    owning_library => $owning_library
+ } );
 warn 'found ' . scalar( @$upcoming_dues ) . ' issues' if $verbose;
 
 # hash of borrowernumber to number of items upcoming
@@ -275,6 +294,15 @@ UPCOMINGITEM: foreach my $upcoming ( @$upcoming_dues ) {
                 $due_digest->{ $upcoming->{borrowernumber} }->{count}++;
             }
         } else {
+	    my $branchcode;
+	    if($owning_library) {
+		$branchcode = $upcoming->{'homebranch'};
+	    } else {
+		$branchcode = $upcoming->{'branchcode'};
+	    }
+	    # Skip this DUE if we specify list of libraries and this one is not part of it
+	    next if (@branchcodes && !$branches{$branchcode});
+
             my $item = Koha::Items->find( $upcoming->{itemnumber} );
             my $letter_type = 'DUE';
             $sth->execute($upcoming->{'borrowernumber'},$upcoming->{'itemnumber'},'0');
@@ -287,7 +315,7 @@ UPCOMINGITEM: foreach my $upcoming ( @$upcoming_dues ) {
             foreach my $transport ( keys %{$borrower_preferences->{'transports'}} ) {
                 my $letter = parse_letter( { letter_code    => $letter_type,
                                       borrowernumber => $upcoming->{'borrowernumber'},
-                                      branchcode     => $upcoming->{'branchcode'},
+                                      branchcode     => $branchcode,
                                       biblionumber   => $item->biblionumber,
                                       itemnumber     => $upcoming->{'itemnumber'},
                                       substitute     => { 'items.content' => $titles },
@@ -313,6 +341,15 @@ UPCOMINGITEM: foreach my $upcoming ( @$upcoming_dues ) {
                 $upcoming_digest->{ $upcoming->{borrowernumber} }->{count}++;
             }
         } else {
+	    my $branchcode;
+	    if($owning_library) {
+		$branchcode = $upcoming->{'homebranch'};
+	    } else {
+		$branchcode = $upcoming->{'branchcode'};
+	    }
+	    # Skip this PREDUE if we specify list of libraries and this one is not part of it
+	    next if (@branchcodes && !$branches{$branchcode});
+
             my $item = Koha::Items->find( $upcoming->{itemnumber} );
             my $letter_type = 'PREDUE';
             $sth->execute($upcoming->{'borrowernumber'},$upcoming->{'itemnumber'},$borrower_preferences->{'days_in_advance'});
@@ -325,7 +362,7 @@ UPCOMINGITEM: foreach my $upcoming ( @$upcoming_dues ) {
             foreach my $transport ( keys %{$borrower_preferences->{'transports'}} ) {
                 my $letter = parse_letter( { letter_code    => $letter_type,
                                       borrowernumber => $upcoming->{'borrowernumber'},
-                                      branchcode     => $upcoming->{'branchcode'},
+                                      branchcode     => $branchcode,
                                       biblionumber   => $item->biblionumber,
                                       itemnumber     => $upcoming->{'itemnumber'},
                                       substitute     => { 'items.content' => $titles },
diff --git a/misc/cronjobs/overdue_notices.pl b/misc/cronjobs/overdue_notices.pl
index 01200d8435..21b1878189 100755
--- a/misc/cronjobs/overdue_notices.pl
+++ b/misc/cronjobs/overdue_notices.pl
@@ -75,6 +75,7 @@ overdue_notices.pl
    -list-all                      list all overdues
    -date         <yyyy-mm-dd>     emulate overdues run for this date
    -email        <email_type>     type of email that will be used. Can be 'email', 'emailpro' or 'B_email'. Repeatable.
+   --owning                        Send notices from item homebranch library instead of issuing library
 
 =head1 OPTIONS
 
@@ -183,6 +184,10 @@ use it in order to send overdues on a specific date and not Now. Format: YYYY-MM
 
 Allows to specify which type of email will be used. Can be email, emailpro or B_email. Repeatable.
 
+=item B<--owning>
+
+Use the address information from the item homebranch library instead of the issuing library.
+
 =back
 
 =head1 DESCRIPTION
@@ -292,6 +297,7 @@ my $verbose = 0;
 my $nomail  = 0;
 my $MAX     = 90;
 my $test_mode = 0;
+my $owning_library = 0;
 my @branchcodes; # Branch(es) passed as parameter
 my @emails_to_use;    # Emails to use for messaging
 my @emails;           # Emails given in command-line parameters
@@ -323,6 +329,7 @@ GetOptions(
     'borcat=s'       => \@myborcat,
     'borcatout=s'    => \@myborcatout,
     'email=s'        => \@emails,
+    'owning'         => \$owning_library,
 ) or pod2usage(2);
 pod2usage(1) if $help;
 pod2usage( -verbose => 2 ) if $man;
@@ -461,7 +468,7 @@ foreach my $branchcode (@branches) {
 
     $verbose and warn sprintf "branchcode : '%s' using %s\n", $branchcode, $branch_email_address;
 
-    my $sth2 = $dbh->prepare( <<"END_SQL" );
+    my $sql2 = <<"END_SQL";
 SELECT biblio.*, items.*, issues.*, biblioitems.itemtype, branchname
   FROM issues,items,biblio, biblioitems, branches b
   WHERE items.itemnumber=issues.itemnumber
@@ -469,11 +476,17 @@ SELECT biblio.*, items.*, issues.*, biblioitems.itemtype, branchname
     AND b.branchcode = items.homebranch
     AND biblio.biblionumber   = biblioitems.biblionumber
     AND issues.borrowernumber = ?
-    AND issues.branchcode = ?
     AND items.itemlost = 0
     AND TO_DAYS($date)-TO_DAYS(issues.date_due) >= 0
 END_SQL
 
+    if($owning_library) {
+      $sql2 .= ' AND items.homebranch = ? ';
+    } else {
+      $sql2 .= ' AND issues.branchcode = ? ';
+    }
+    my $sth2 = $dbh->prepare($sql2);
+
     my $query = "SELECT * FROM overduerules WHERE delay1 IS NOT NULL AND branchcode = ? ";
     $query .= " AND categorycode IN (".join( ',' , ('?') x @myborcat ).") " if (@myborcat);
     $query .= " AND categorycode NOT IN (".join( ',' , ('?') x @myborcatout ).") " if (@myborcatout);
@@ -528,7 +541,11 @@ AND    TO_DAYS($date)-TO_DAYS(issues.date_due) >= 0
 END_SQL
             my @borrower_parameters;
             if ($branchcode) {
-                $borrower_sql .= ' AND issues.branchcode=? ';
+		if($owning_library) {
+		    $borrower_sql .= ' AND items.homebranch=? ';
+		} else {
+		    $borrower_sql .= ' AND issues.branchcode=? ';
+		}
                 push @borrower_parameters, $branchcode;
             }
             if ( $overdue_rules->{categorycode} ) {
-- 
2.20.1