Bug 11650: multiplicated authorities after link_bibs_to_authorities.pl
[koha_fer] / C4 / Overdues.pm
index 660e10b..169b36c 100644 (file)
@@ -23,6 +23,8 @@ use strict;
 #use warnings; FIXME - Bug 2505
 use Date::Calc qw/Today Date_to_Days/;
 use Date::Manip qw/UnixDate/;
 #use warnings; FIXME - Bug 2505
 use Date::Calc qw/Today Date_to_Days/;
 use Date::Manip qw/UnixDate/;
+use List::MoreUtils qw( uniq );
+
 use C4::Circulation;
 use C4::Context;
 use C4::Accounts;
 use C4::Circulation;
 use C4::Context;
 use C4::Accounts;
@@ -33,7 +35,7 @@ use vars qw($VERSION @ISA @EXPORT);
 
 BEGIN {
        # set the version for version checking
 
 BEGIN {
        # set the version for version checking
-       $VERSION = 3.01;
+    $VERSION = 3.07.00.049;
        require Exporter;
        @ISA    = qw(Exporter);
        # subs to rename (and maybe merge some...)
        require Exporter;
        @ISA    = qw(Exporter);
        # subs to rename (and maybe merge some...)
@@ -41,25 +43,16 @@ BEGIN {
         &CalcFine
         &Getoverdues
         &checkoverdues
         &CalcFine
         &Getoverdues
         &checkoverdues
-        &CheckAccountLineLevelInfo
-        &CheckAccountLineItemInfo
-        &CheckExistantNotifyid
-        &GetNextIdNotify
-        &GetNotifyId
         &NumberNotifyId
         &AmountNotify
         &NumberNotifyId
         &AmountNotify
-        &UpdateAccountLines
         &UpdateFine
         &UpdateFine
-        &GetOverdueDelays
-        &GetOverduerules
         &GetFine
         &GetFine
-        &CreateItemAccountLine
-        &ReplacementCost2
         
         &CheckItemNotify
         &GetOverduesForBranch
         &RemoveNotifyLine
         &AddNotifyLine
         
         &CheckItemNotify
         &GetOverduesForBranch
         &RemoveNotifyLine
         &AddNotifyLine
+        &GetOverdueMessageTransportTypes
        );
        # subs to remove
        push @EXPORT, qw(
        );
        # subs to remove
        push @EXPORT, qw(
@@ -72,18 +65,13 @@ BEGIN {
        push @EXPORT, qw(
         &GetIssuesIteminfo
        );
        push @EXPORT, qw(
         &GetIssuesIteminfo
        );
-    #
-       # &GetIssuingRules - delete.
-       # use C4::Circulation::GetIssuingRule instead.
-       
-       # subs to move to Members.pm
-       push @EXPORT, qw(
-        &CheckBorrowerDebarred
-       );
+
+     # &GetIssuingRules - delete.
+   # use C4::Circulation::GetIssuingRule instead.
+
        # subs to move to Biblio.pm
        push @EXPORT, qw(
         &GetItems
        # subs to move to Biblio.pm
        push @EXPORT, qw(
         &GetItems
-        &ReplacementCost
        );
 }
 
        );
 }
 
@@ -124,7 +112,7 @@ sub Getoverdues {
    SELECT issues.*, items.itype as itemtype, items.homebranch, items.barcode
      FROM issues 
 LEFT JOIN items       USING (itemnumber)
    SELECT issues.*, items.itype as itemtype, items.homebranch, items.barcode
      FROM issues 
 LEFT JOIN items       USING (itemnumber)
-    WHERE date_due < CURDATE() 
+    WHERE date_due < NOW()
 ";
     } else {
         $statement = "
 ";
     } else {
         $statement = "
@@ -132,7 +120,7 @@ LEFT JOIN items       USING (itemnumber)
      FROM issues 
 LEFT JOIN items       USING (itemnumber)
 LEFT JOIN biblioitems USING (biblioitemnumber)
      FROM issues 
 LEFT JOIN items       USING (itemnumber)
 LEFT JOIN biblioitems USING (biblioitemnumber)
-    WHERE date_due < CURDATE() 
+    WHERE date_due < NOW()
 ";
     }
 
 ";
     }
 
@@ -199,7 +187,7 @@ sub checkoverdues {
          LEFT JOIN biblio      ON items.biblionumber     = biblio.biblionumber
          LEFT JOIN biblioitems ON items.biblioitemnumber = biblioitems.biblioitemnumber
             WHERE issues.borrowernumber  = ?
          LEFT JOIN biblio      ON items.biblionumber     = biblio.biblionumber
          LEFT JOIN biblioitems ON items.biblioitemnumber = biblioitems.biblioitemnumber
             WHERE issues.borrowernumber  = ?
-            AND   issues.date_due < CURDATE()"
+            AND   issues.date_due < NOW()"
     );
     # FIXME: SELECT * across 4 tables?  do we really need the marc AND marcxml blobs??
     $sth->execute($borrowernumber);
     );
     # FIXME: SELECT * across 4 tables?  do we really need the marc AND marcxml blobs??
     $sth->execute($borrowernumber);
@@ -209,9 +197,9 @@ sub checkoverdues {
 
 =head2 CalcFine
 
 
 =head2 CalcFine
 
-    ($amount, $chargename, $daycount, $daycounttotal) = &CalcFine($item, 
-                                  $categorycode, $branch, $days_overdue, 
-                                  $description, $start_date, $end_date );
+    ($amount, $chargename,  $daycounttotal) = &CalcFine($item,
+                                  $categorycode, $branch,
+                                  $start_dt, $end_dt );
 
 Calculates the fine for a book.
 
 
 Calculates the fine for a book.
 
@@ -229,13 +217,8 @@ the book.
 
 C<$branchcode> is the library (string) whose issuingrules govern this transaction.
 
 
 C<$branchcode> is the library (string) whose issuingrules govern this transaction.
 
-C<$days_overdue> is the number of days elapsed since the book's due date.
-  NOTE: supplying days_overdue is deprecated.
-
-C<$start_date> & C<$end_date> are C4::Dates objects 
+C<$start_date> & C<$end_date> are DateTime objects
 defining the date range over which to determine the fine.
 defining the date range over which to determine the fine.
-Note that if these are defined, we ignore C<$difference> and C<$dues> , 
-but retain these for backwards-comptibility with extant fines scripts.
 
 Fines scripts should just supply the date range over which to calculate the fine.
 
 
 Fines scripts should just supply the date range over which to calculate the fine.
 
@@ -246,10 +229,8 @@ C<$amount> is the fine owed by the patron (see above).
 C<$chargename> is the chargename field from the applicable record in
 the categoryitem table, whatever that is.
 
 C<$chargename> is the chargename field from the applicable record in
 the categoryitem table, whatever that is.
 
-C<$daycount> is the number of days between start and end dates, Calendar adjusted (where needed), 
-minus any applicable grace period.
-
-C<$daycounttotal> is C<$daycount> without consideration of grace period.
+C<$unitcount> is the number of chargeable units (days between start and end dates, Calendar adjusted where needed,
+minus any applicable grace period, or hours)
 
 FIXME - What is chargename supposed to be ?
 
 
 FIXME - What is chargename supposed to be ?
 
@@ -259,52 +240,75 @@ or "Final Notice".  But CalcFine never defined any value.
 =cut
 
 sub CalcFine {
 =cut
 
 sub CalcFine {
-    my ( $item, $bortype, $branchcode, $difference ,$dues , $start_date, $end_date  ) = @_;
-       $debug and warn sprintf("CalcFine(%s, %s, %s, %s, %s, %s, %s)",
-                       ($item ? '{item}' : 'UNDEF'), 
-                       ($bortype    || 'UNDEF'), 
-                       ($branchcode || 'UNDEF'), 
-                       ($difference || 'UNDEF'), 
-                       ($dues       || 'UNDEF'), 
-                       ($start_date ? ($start_date->output('iso') || 'Not a C4::Dates object') : 'UNDEF'), 
-                       (  $end_date ? (  $end_date->output('iso') || 'Not a C4::Dates object') : 'UNDEF')
-       );
-    my $dbh = C4::Context->dbh;
+    my ( $item, $bortype, $branchcode, $due_dt, $end_date  ) = @_;
+    my $start_date = $due_dt->clone();
+    # get issuingrules (fines part will be used)
+    my $itemtype = $item->{itemtype} || $item->{itype};
+    my $data = C4::Circulation::GetIssuingRule($bortype, $itemtype, $branchcode);
+    my $fine_unit = $data->{lengthunit};
+    $fine_unit ||= 'days';
+
+    my $chargeable_units = _get_chargeable_units($fine_unit, $start_date, $end_date, $branchcode);
+    my $units_minus_grace = $chargeable_units - $data->{firstremind};
     my $amount = 0;
     my $amount = 0;
-       my $daystocharge;
-       # get issuingrules (fines part will be used)
-    $debug and warn sprintf("CalcFine calling GetIssuingRule(%s, %s, %s)", $bortype, $item->{'itemtype'}, $branchcode);
-    my $data = C4::Circulation::GetIssuingRule($bortype, $item->{'itemtype'}, $branchcode);
-       if($difference) {
-               # if $difference is supplied, the difference has already been calculated, but we still need to adjust for the calendar.
-       # use copy-pasted functions from calendar module.  (deprecated -- these functions will be removed from C4::Overdues ).
-           my $countspecialday    =    &GetSpecialHolidays($dues,$item->{itemnumber});
-           my $countrepeatableday = &GetRepeatableHolidays($dues,$item->{itemnumber},$difference);    
-           my $countalldayclosed  = $countspecialday + $countrepeatableday;
-           $daystocharge = $difference - $countalldayclosed;
-       } else {
-               # if $difference is not supplied, we have C4::Dates objects giving us the date range, and we use the calendar module.
-               if(C4::Context->preference('finesCalendar') eq 'noFinesWhenClosed') {
-                       my $calendar = C4::Calendar->new( branchcode => $branchcode );
-                       $daystocharge = $calendar->daysBetween( $start_date, $end_date );
-               } else {
-                       $daystocharge = Date_to_Days(split('-',$end_date->output('iso'))) - Date_to_Days(split('-',$start_date->output('iso')));
-               }
-       }
-       # correct for grace period.
-       my $days_minus_grace = $daystocharge - $data->{'firstremind'};
-    if ($data->{'chargeperiod'} > 0 && $days_minus_grace > 0 ) { 
-        $amount = int($daystocharge / $data->{'chargeperiod'}) * $data->{'fine'};
+    if ($data->{'chargeperiod'}  && ($units_minus_grace > 0)  ) {
+        if ( C4::Context->preference('FinesIncludeGracePeriod') ) {
+            $amount = int($chargeable_units / $data->{'chargeperiod'}) * $data->{'fine'};# TODO fine calc should be in cents
+        } else {
+            $amount = int($units_minus_grace / $data->{'chargeperiod'}) * $data->{'fine'};
+        }
     } else {
     } else {
-        # a zero (or null)  chargeperiod means no charge.
+        # a zero (or null) chargeperiod or negative units_minus_grace value means no charge.
     }
     }
-       $amount = C4::Context->preference('maxFine') if(C4::Context->preference('maxFine') && ( $amount > C4::Context->preference('maxFine')));
-       $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);
+    $amount = $data->{overduefinescap} if $data->{overduefinescap} && $amount > $data->{overduefinescap};
+    $debug and warn sprintf("CalcFine returning (%s, %s, %s, %s)", $amount, $data->{'chargename'}, $units_minus_grace, $chargeable_units);
+    return ($amount, $data->{'chargename'}, $units_minus_grace, $chargeable_units);
     # FIXME: chargename is NEVER populated anywhere.
 }
 
 
     # FIXME: chargename is NEVER populated anywhere.
 }
 
 
+=head2 _get_chargeable_units
+
+    _get_chargeable_units($unit, $start_date_ $end_date, $branchcode);
+
+return integer value of units between C<$start_date> and C<$end_date>, factoring in holidays for C<$branchcode>.
+
+C<$unit> is 'days' or 'hours' (default is 'days').
+
+C<$start_date> and C<$end_date> are the two DateTimes to get the number of units between.
+
+C<$branchcode> is the branch whose calendar to use for finding holidays.
+
+=cut
+
+sub _get_chargeable_units {
+    my ($unit, $dt1, $dt2, $branchcode) = @_;
+    my $charge_units = 0;
+    my $charge_duration;
+    if ($unit eq 'hours') {
+        if(C4::Context->preference('finesCalendar') eq 'noFinesWhenClosed') {
+            my $calendar = Koha::Calendar->new( branchcode => $branchcode );
+            $charge_duration = $calendar->hours_between( $dt1, $dt2 );
+        } else {
+            $charge_duration = $dt2->delta_ms( $dt1 );
+        }
+        if($charge_duration->in_units('hours') == 0 && $charge_duration->in_units('seconds') > 0){
+            return 1;
+        }
+        return $charge_duration->in_units('hours');
+    }
+    else { # days
+        if(C4::Context->preference('finesCalendar') eq 'noFinesWhenClosed') {
+            my $calendar = Koha::Calendar->new( branchcode => $branchcode );
+            $charge_duration = $calendar->days_between( $dt1, $dt2 );
+        } else {
+            $charge_duration = $dt2->delta_days( $dt1 );
+        }
+        return $charge_duration->in_units('days');
+    }
+}
+
+
 =head2 GetSpecialHolidays
 
     &GetSpecialHolidays($date_dues,$itemnumber);
 =head2 GetSpecialHolidays
 
     &GetSpecialHolidays($date_dues,$itemnumber);
@@ -508,14 +512,39 @@ sub UpdateFine {
        #   "REF" is Cash Refund
     my $sth = $dbh->prepare(
         "SELECT * FROM accountlines
        #   "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/;
+    # Cycle through the fines and
+    # - find line that relates to the requested $itemnum
+    # - accumulate fines for other items
+    # so we can update $itemnum fine taking in account fine caps
+    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->{'amountoutstanding'};
+    }
+
+    if (my $maxfine = C4::Context->preference('MaxFine')) {
+        if ($total_amount_other + $amount > $maxfine) {
+            my $new_amount = $maxfine - $total_amount_other;
+            return if $new_amount <= 0.00;
+            warn "Reducing fine for item $itemnum borrower $borrowernumber from $amount to $new_amount - MaxFine reached";
+            $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
 
                # we're updating an existing fine.  Only modify if amount changed
         # Note that in the current implementation, you cannot pay against an accruing fine
@@ -593,7 +622,6 @@ category he or she belongs to.
 
 =cut
 
 
 =cut
 
-#'
 sub BorType {
     my ($borrowernumber) = @_;
     my $dbh              = C4::Context->dbh;
 sub BorType {
     my ($borrowernumber) = @_;
     my $dbh              = C4::Context->dbh;
@@ -606,27 +634,6 @@ sub BorType {
     return $sth->fetchrow_hashref;
 }
 
     return $sth->fetchrow_hashref;
 }
 
-=head2 ReplacementCost
-
-    $cost = &ReplacementCost($itemnumber);
-
-Returns the replacement cost of the item with the given item number.
-
-=cut
-
-#'
-sub ReplacementCost {
-    my ($itemnum) = @_;
-    my $dbh       = C4::Context->dbh;
-    my $sth       =
-      $dbh->prepare("Select replacementprice from items where itemnumber=?");
-    $sth->execute($itemnum);
-
-    # FIXME - Use fetchrow_array or a slice.
-    my $data = $sth->fetchrow_hashref;
-    return ( $data->{'replacementprice'} );
-}
-
 =head2 GetFine
 
     $data->{'sum(amountoutstanding)'} = &GetFine($itemnum,$borrowernumber);
 =head2 GetFine
 
     $data->{'sum(amountoutstanding)'} = &GetFine($itemnum,$borrowernumber);
@@ -639,7 +646,6 @@ C<$borrowernumber> is the borrowernumber
 
 =cut 
 
 
 =cut 
 
-
 sub GetFine {
     my ( $itemnum, $borrowernumber ) = @_;
     my $dbh   = C4::Context->dbh();
 sub GetFine {
     my ( $itemnum, $borrowernumber ) = @_;
     my $dbh   = C4::Context->dbh();
@@ -655,96 +661,6 @@ sub GetFine {
     return 0;
 }
 
     return 0;
 }
 
-
-=head2 GetIssuingRules
-
-FIXME - This sub should be deprecated and removed.
-It ignores branch and defaults.
-
-    $data = &GetIssuingRules($itemtype,$categorycode);
-
-Looks up for all issuingrules an item info 
-
-C<$itemnumber> is a reference-to-hash whose keys are all of the fields
-from the borrowers and categories tables of the Koha database. Thus,
-
-C<$categorycode> contains  information about borrowers category 
-
-C<$data> contains all information about both the borrower and
-category he or she belongs to.
-=cut 
-
-sub GetIssuingRules {
-       warn "GetIssuingRules is deprecated: use GetIssuingRule from C4::Circulation instead.";
-   my ($itemtype,$categorycode)=@_;
-   my $dbh   = C4::Context->dbh();    
-   my $query=qq|SELECT *
-        FROM issuingrules
-        WHERE issuingrules.itemtype=?
-            AND issuingrules.categorycode=?
-        |;
-    my $sth = $dbh->prepare($query);
-    #  print $query;
-    $sth->execute($itemtype,$categorycode);
-    return $sth->fetchrow_hashref;
-}
-
-
-sub ReplacementCost2 {
-    my ( $itemnum, $borrowernumber ) = @_;
-    my $dbh   = C4::Context->dbh();
-    my $query = "SELECT amountoutstanding
-         FROM accountlines
-             WHERE accounttype like 'L'
-         AND amountoutstanding > 0
-         AND itemnumber = ?
-         AND borrowernumber= ?";
-    my $sth = $dbh->prepare($query);
-    $sth->execute( $itemnum, $borrowernumber );
-    my $data = $sth->fetchrow_hashref();
-    return ( $data->{'amountoutstanding'} );
-}
-
-
-=head2 GetNextIdNotify
-
-    ($result) = &GetNextIdNotify($reference);
-
-Returns the new file number
-
-C<$result> contains the next file number
-
-C<$reference> contains the beggining of file number
-
-=cut
-
-sub GetNextIdNotify {
-    my ($reference) = @_;
-    my $query = qq|SELECT max(notify_id)
-         FROM accountlines
-         WHERE notify_id  like \"$reference%\"
-         |;
-
-    # AND borrowernumber=?|;
-    my $dbh = C4::Context->dbh;
-    my $sth = $dbh->prepare($query);
-    $sth->execute();
-    my $result = $sth->fetchrow;
-    my $count;
-    if ( $result eq '' ) {
-        ( $result = $reference . "01" );
-    }
-    else {
-        $count = substr( $result, 6 ) + 1;
-
-        if ( $count < 10 ) {
-            ( $count = "0" . $count );
-        }
-        $result = $reference . $count;
-    }
-    return $result;
-}
-
 =head2 NumberNotifyId
 
     (@notify) = &NumberNotifyId($borrowernumber);
 =head2 NumberNotifyId
 
     (@notify) = &NumberNotifyId($borrowernumber);
@@ -797,135 +713,6 @@ sub AmountNotify{
     return ($totalnotify);
 }
 
     return ($totalnotify);
 }
 
-
-=head2 GetNotifyId
-
-    ($notify_id) = &GetNotifyId($borrowernumber,$itemnumber);
-
-Returns the file number per borrower and itemnumber
-
-C<$borrowernumber> is a reference-to-hash whose keys are all of the fields
-from the items tables of the Koha database. Thus,
-
-C<$itemnumber> contains the borrower categorycode
-
-C<$notify_id> contains the file number for the borrower number nad item number
-
-=cut
-
-sub GetNotifyId {
-    my ( $borrowernumber, $itemnumber ) = @_;
-    my $query = qq|SELECT notify_id
-           FROM accountlines
-           WHERE borrowernumber=?
-          AND itemnumber=?
-           AND (accounttype='FU' or accounttype='O')|;
-    my $dbh = C4::Context->dbh;
-    my $sth = $dbh->prepare($query);
-    $sth->execute( $borrowernumber, $itemnumber );
-    my ($notify_id) = $sth->fetchrow;
-    $sth->finish;
-    return ($notify_id);
-}
-
-=head2 CreateItemAccountLine
-
-    () = &CreateItemAccountLine($borrowernumber, $itemnumber, $date, $amount,
-                               $description, $accounttype, $amountoutstanding, 
-                               $timestamp, $notify_id, $level);
-
-update the account lines with file number or with file level
-
-C<$items> is a reference-to-hash whose keys are all of the fields
-from the items tables of the Koha database. Thus,
-
-C<$itemnumber> contains the item number
-
-C<$borrowernumber> contains the borrower number
-
-C<$date> contains the date of the day
-
-C<$amount> contains item price
-
-C<$description> contains the descritpion of accounttype 
-
-C<$accounttype> contains the account type
-
-C<$amountoutstanding> contains the $amountoutstanding 
-
-C<$timestamp> contains the timestamp with time and the date of the day
-
-C<$notify_id> contains the file number
-
-C<$level> contains the file level
-
-=cut
-
-sub CreateItemAccountLine {
-    my (
-        $borrowernumber, $itemnumber,  $date,              $amount,
-        $description,    $accounttype, $amountoutstanding, $timestamp,
-        $notify_id,      $level
-    ) = @_;
-    my $dbh         = C4::Context->dbh;
-    my $nextaccntno = C4::Accounts::getnextacctno($borrowernumber);
-    my $query       = "INSERT into accountlines
-         (borrowernumber,accountno,itemnumber,date,amount,description,accounttype,amountoutstanding,timestamp,notify_id,notify_level)
-          VALUES
-             (?,?,?,?,?,?,?,?,?,?,?)";
-
-    my $sth = $dbh->prepare($query);
-    $sth->execute(
-        $borrowernumber, $nextaccntno,       $itemnumber,
-        $date,           $amount,            $description,
-        $accounttype,    $amountoutstanding, $timestamp,
-        $notify_id,      $level
-    );
-}
-
-=head2 UpdateAccountLines
-
-    () = &UpdateAccountLines($notify_id,$notify_level,$borrowernumber,$itemnumber);
-
-update the account lines with file number or with file level
-
-C<$items> is a reference-to-hash whose keys are all of the fields
-from the items tables of the Koha database. Thus,
-
-C<$itemnumber> contains the item number
-
-C<$notify_id> contains the file number
-
-C<$notify_level> contains the file level
-
-C<$borrowernumber> contains the borrowernumber
-
-=cut
-
-sub UpdateAccountLines {
-    my ( $notify_id, $notify_level, $borrowernumber, $itemnumber ) = @_;
-    my $query;
-    if ( $notify_id eq '' ) {
-        $query = qq|UPDATE accountlines
-    SET  notify_level=?
-    WHERE borrowernumber=? AND itemnumber=?
-    AND (accounttype='FU' or accounttype='O')|;
-    } else {
-        $query = qq|UPDATE accountlines
-     SET notify_id=?, notify_level=?
-   WHERE borrowernumber=?
-    AND itemnumber=?
-    AND (accounttype='FU' or accounttype='O')|;
-    }
-
-    my $sth = C4::Context->dbh->prepare($query);
-    if ( $notify_id eq '' ) {
-        $sth->execute( $notify_level, $borrowernumber, $itemnumber );
-    } else {
-        $sth->execute( $notify_id, $notify_level, $borrowernumber, $itemnumber );
-    }
-}
-
 =head2 GetItems
 
     ($items) = &GetItems($itemnumber);
 =head2 GetItems
 
     ($items) = &GetItems($itemnumber);
@@ -955,29 +742,6 @@ sub GetItems {
     return ($items);
 }
 
     return ($items);
 }
 
-=head2 GetOverdueDelays
-
-    (@delays) = &GetOverdueDelays($categorycode);
-
-Returns the list of all delays from overduerules.
-
-C<@delays> it's an array contains the three delays from overduerules table
-
-C<$categorycode> contains the borrower categorycode
-
-=cut
-
-sub GetOverdueDelays {
-    my ($category) = @_;
-    my $query      = qq|SELECT delay1,delay2,delay3
-                FROM overduerules
-                WHERE categorycode=?|;
-    my $sth = C4::Context->dbh->prepare($query);
-    $sth->execute($category);
-    my (@delays) = $sth->fetchrow_array;
-    return (@delays);
-}
-
 =head2 GetBranchcodesWithOverdueRules
 
     my @branchcodes = C4::Overdues::GetBranchcodesWithOverdueRules()
 =head2 GetBranchcodesWithOverdueRules
 
     my @branchcodes = C4::Overdues::GetBranchcodesWithOverdueRules()
@@ -998,156 +762,6 @@ sub GetBranchcodesWithOverdueRules {
     return @branches;
 }
 
     return @branches;
 }
 
-=head2 CheckAccountLineLevelInfo
-
-    ($exist) = &CheckAccountLineLevelInfo($borrowernumber,$itemnumber,$accounttype,notify_level);
-
-Check and Returns the list of all overdue books.
-
-C<$exist> contains number of line in accounlines
-with the same .biblionumber,itemnumber,accounttype,and notify_level
-
-C<$borrowernumber> contains the borrower number
-
-C<$itemnumber> contains item number
-
-C<$accounttype> contains account type
-
-C<$notify_level> contains the accountline level 
-
-
-=cut
-
-sub CheckAccountLineLevelInfo {
-    my ( $borrowernumber, $itemnumber, $level ) = @_;
-    my $dbh   = C4::Context->dbh;
-    my $query = qq|SELECT count(*)
-            FROM accountlines
-            WHERE borrowernumber =?
-            AND itemnumber = ?
-            AND notify_level=?|;
-    my $sth = $dbh->prepare($query);
-    $sth->execute( $borrowernumber, $itemnumber, $level );
-    my ($exist) = $sth->fetchrow;
-    return ($exist);
-}
-
-=head2 GetOverduerules
-
-    ($overduerules) = &GetOverduerules($categorycode);
-
-Returns the value of borrowers (debarred or not) with notify level
-
-C<$overduerules> return value of debbraed field in overduerules table
-
-C<$category> contains the borrower categorycode
-
-C<$notify_level> contains the notify level
-
-=cut
-
-sub GetOverduerules {
-    my ( $category, $notify_level ) = @_;
-    my $dbh   = C4::Context->dbh;
-    my $query = qq|SELECT debarred$notify_level
-                     FROM overduerules
-                    WHERE categorycode=?|;
-    my $sth = $dbh->prepare($query);
-    $sth->execute($category);
-    my ($overduerules) = $sth->fetchrow;
-    return ($overduerules);
-}
-
-
-=head2 CheckBorrowerDebarred
-
-    ($debarredstatus) = &CheckBorrowerDebarred($borrowernumber);
-
-Check if the borrowers is already debarred
-
-C<$debarredstatus> return 0 for not debarred and return 1 for debarred
-
-C<$borrowernumber> contains the borrower number
-
-=cut
-
-# FIXME: Shouldn't this be in C4::Members?
-sub CheckBorrowerDebarred {
-    my ($borrowernumber) = @_;
-    my $dbh   = C4::Context->dbh;
-    my $query = qq|
-        SELECT debarred
-        FROM borrowers
-        WHERE borrowernumber=?
-        AND debarred > NOW()
-    |;
-    my $sth = $dbh->prepare($query);
-    $sth->execute($borrowernumber);
-    my $debarredstatus = $sth->fetchrow;
-    return $debarredstatus;
-}
-
-
-=head2 CheckExistantNotifyid
-
-    ($exist) = &CheckExistantNotifyid($borrowernumber,$itemnumber,$accounttype,$notify_id);
-
-Check and Returns the notify id if exist else return 0.
-
-C<$exist> contains a notify_id 
-
-C<$borrowernumber> contains the borrower number
-
-C<$date_due> contains the date of item return 
-
-
-=cut
-
-sub CheckExistantNotifyid {
-    my ( $borrowernumber, $date_due ) = @_;
-    my $dbh   = C4::Context->dbh;
-    my $query = qq|SELECT notify_id FROM accountlines
-             LEFT JOIN issues ON issues.itemnumber= accountlines.itemnumber
-             WHERE accountlines.borrowernumber =?
-              AND date_due = ?|;
-    my $sth = $dbh->prepare($query);
-    $sth->execute( $borrowernumber, $date_due );
-    return $sth->fetchrow || 0;
-}
-
-=head2 CheckAccountLineItemInfo
-
-    ($exist) = &CheckAccountLineItemInfo($borrowernumber,$itemnumber,$accounttype,$notify_id);
-
-Check and Returns the list of all overdue items from the same file number(notify_id).
-
-C<$exist> contains number of line in accounlines
-with the same .biblionumber,itemnumber,accounttype,notify_id
-
-C<$borrowernumber> contains the borrower number
-
-C<$itemnumber> contains item number
-
-C<$accounttype> contains account type
-
-C<$notify_id> contains the file number 
-
-=cut
-
-sub CheckAccountLineItemInfo {
-    my ( $borrowernumber, $itemnumber, $accounttype, $notify_id ) = @_;
-    my $dbh   = C4::Context->dbh;
-    my $query = qq|SELECT count(*) FROM accountlines
-             WHERE borrowernumber =?
-             AND itemnumber = ?
-              AND accounttype= ?
-            AND notify_id = ?|;
-    my $sth = $dbh->prepare($query);
-    $sth->execute( $borrowernumber, $itemnumber, $accounttype, $notify_id );
-    my ($exist) = $sth->fetchrow;
-    return ($exist);
-}
-
 =head2 CheckItemNotify
 
 Sql request to check if the document has alreday been notified
 =head2 CheckItemNotify
 
 Sql request to check if the document has alreday been notified
@@ -1185,6 +799,7 @@ sub GetOverduesForBranch {
     my $dbh = C4::Context->dbh;
     my $select = "
     SELECT
     my $dbh = C4::Context->dbh;
     my $select = "
     SELECT
+            borrowers.cardnumber,
             borrowers.borrowernumber,
             borrowers.surname,
             borrowers.firstname,
             borrowers.borrowernumber,
             borrowers.surname,
             borrowers.firstname,
@@ -1218,7 +833,7 @@ sub GetOverduesForBranch {
     WHERE (accountlines.amountoutstanding  != '0.000000')
       AND (accountlines.accounttype         = 'FU'      )
       AND (issues.branchcode =  ?   )
     WHERE (accountlines.amountoutstanding  != '0.000000')
       AND (accountlines.accounttype         = 'FU'      )
       AND (issues.branchcode =  ?   )
-      AND (issues.date_due  < CURDATE())
+      AND (issues.date_due  < NOW())
     ";
     my @getoverdues;
     my $i = 0;
     ";
     my @getoverdues;
     my $i = 0;
@@ -1294,6 +909,36 @@ sub RemoveNotifyLine {
     return 1;
 }
 
     return 1;
 }
 
+=head2 GetOverdueMessageTransportTypes
+
+    my $message_transport_types = GetOverdueMessageTransportTypes( $branchcode, $categorycode, $letternumber);
+
+    return a arrayref with all message_transport_type for given branchcode, categorycode and letternumber(1,2 or 3)
+
+=cut
+
+sub GetOverdueMessageTransportTypes {
+    my ( $branchcode, $categorycode, $letternumber ) = @_;
+    return unless $categorycode and $letternumber;
+    my $dbh = C4::Context->dbh;
+    my $sth = $dbh->prepare("
+        SELECT message_transport_type FROM overduerules_transport_types
+        WHERE branchcode = ? AND categorycode = ? AND letternumber = ?
+    ");
+    $sth->execute( $branchcode, $categorycode, $letternumber );
+    my @mtts;
+    while ( my $mtt = $sth->fetchrow ) {
+        push @mtts, $mtt;
+    }
+
+    # Put 'print' in first if exists
+    # It avoid to sent a print notice with an email or sms template is no email or sms is defined
+    @mtts = uniq( 'print', @mtts )
+        if grep {/^print$/} @mtts;
+
+    return \@mtts;
+}
+
 1;
 __END__
 
 1;
 __END__