Bug 5548: Hard Due Dates Circ Rule
authorIan Walls <ian.walls@bywatersolutions.com>
Mon, 28 Mar 2011 21:17:09 +0000 (17:17 -0400)
committerChris Cormack <chrisc@catalyst.net.nz>
Wed, 30 Mar 2011 07:35:45 +0000 (20:35 +1300)
Implements the RFC found at http://wiki.koha-community.org/wiki/Hard_Due_Dates_Circ_Rule_RFC.  See squashed commits
messages below for details of implementation.

Squashed commit of the following:

commit 871b91af00871146eb1216ebf5ce673dda2c5925
Author: Ian Walls <ian.walls@bywatersolutions.com>
Date:   Tue Dec 28 15:09:49 2010 -0500

    Hard Due Dates dev part 3: implementing the due dates in circ

    CalcDateDue now calls GetLoanLength, rather than each invocation running separately one after another.  Therefore, instead of
    the 'loanlength' param, CalcDateDue now takes 'itype', and uses the info to get both the issuelength and the hardduedate info (if it exists)

    Global Due Date no longer populates in the sticky due date field in Circ, since it can't be determined before the item is scanned.  Any specified
    due date still overrides the circulation rules, if allowed.

    Hard Due Dates in the past will return an error message, but can be manually specified if truly desired.

    Also, a small fix to updatedatabase.pl to allow the old data to populate if possible.

commit 14d5505f3c01287a2464a759f0076c1d4b665c49
Author: Ian Walls <ian.walls@bywatersolutions.com>
Date:   Mon Dec 27 18:28:11 2010 -0500

    HardDueDates dev part 2:  adding admin interface

    Adds columns to Smart Rules page, including calendar for easy date selection.

    Removes globalDueDate and ceilingDueDates from system preferences editors

commit 76e3e3d86a7a54c6ce4253e7f68278b4dc75a0bb
Author: Ian Walls <ian.walls@bywatersolutions.com>
Date:   Mon Dec 27 15:58:05 2010 -0500

    HardDueDates dev part 1: database changes

    Adds two new columns to issuingrules, a hardduedate and a hardduedatecompare.  If globalduedate is set, use that as the universal value
    for all circ rules.  Else, if ceilingduedate is set, use that as the universal value.  Adjust the comparison accordingly (-1 before, 0
    exact, 1 after).  the old system preferences globalDueDate and ceilingDueDate are then removed.

    Rebased onto 3.03.00.032

Signed-off-by: Ian Walls <ian.walls@bywatersolutions.com>
Signed-off-by: Jared Camins-Esakov <jcamins@bywatersolutions.com>
Signed-off-by: Chris Cormack <chrisc@catalyst.net.nz>
15 files changed:
C4/Circulation.pm
admin/smart-rules.pl
admin/systempreferences.pl
circ/circulation.pl
installer/data/mysql/de-DE/mandatory/sysprefs.sql
installer/data/mysql/en/mandatory/sysprefs.sql
installer/data/mysql/fr-FR/1-Obligatoire/unimarc_standard_systemprefs.sql
installer/data/mysql/it-IT/necessari/sysprefs.sql
installer/data/mysql/kohastructure.sql
installer/data/mysql/pl-PL/mandatory/sysprefs.sql
installer/data/mysql/ru-RU/mandatory/system_preferences_full_optimal_for_install_only.sql
installer/data/mysql/uk-UA/mandatory/system_preferences_full_optimal_for_install_only.sql
installer/data/mysql/updatedatabase.pl
koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref
koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tmpl

index 625a31e..dad54e3 100644 (file)
@@ -684,8 +684,7 @@ sub CanBookBeIssued {
 
         my $branch = _GetCircControlBranch($item,$borrower);
         my $itype = ( C4::Context->preference('item-level_itypes') ) ? $item->{'itype'} : $biblioitem->{'itemtype'};
-        my $loanlength = GetLoanLength( $borrower->{'categorycode'}, $itype, $branch );
-        $duedate = CalcDateDue( C4::Dates->new( $issuedate, 'iso' ), $loanlength, $branch, $borrower );
+        $duedate = CalcDateDue( C4::Dates->new( $issuedate, 'iso' ), $itype, $branch, $borrower );
 
         # Offline circ calls AddIssue directly, doesn't run through here
         #  So issuingimpossible should be ok.
@@ -1042,8 +1041,7 @@ sub AddIssue {
           );
         unless ($datedue) {
             my $itype = ( C4::Context->preference('item-level_itypes') ) ? $biblio->{'itype'} : $biblio->{'itemtype'};
-            my $loanlength = GetLoanLength( $borrower->{'categorycode'}, $itype, $branch );
-            $datedue = CalcDateDue( C4::Dates->new( $issuedate, 'iso' ), $loanlength, $branch, $borrower );
+            $datedue = CalcDateDue( C4::Dates->new( $issuedate, 'iso' ), $itype, $branch, $borrower );
 
         }
         $sth->execute(
@@ -1173,6 +1171,66 @@ sub GetLoanLength {
     return 21;
 }
 
+
+=head2 GetHardDueDate
+
+  my ($hardduedate,$hardduedatecompare) = &GetHardDueDate($borrowertype,$itemtype,branchcode)
+
+Get the Hard Due Date and it's comparison for an itemtype, a borrower type and a branch
+
+=cut
+
+sub GetHardDueDate {
+    my ( $borrowertype, $itemtype, $branchcode ) = @_;
+    my $dbh = C4::Context->dbh;
+    my $sth =
+      $dbh->prepare(
+"select hardduedate, hardduedatecompare from issuingrules where categorycode=? and itemtype=? and branchcode=?"
+      );
+    $sth->execute( $borrowertype, $itemtype, $branchcode );
+    my $results = $sth->fetchrow_hashref;
+    return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
+      if defined($results) && $results->{hardduedate} ne 'NULL';
+
+    $sth->execute( $borrowertype, "*", $branchcode );
+    $results = $sth->fetchrow_hashref;
+    return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
+      if defined($results) && $results->{hardduedate} ne 'NULL';
+
+    $sth->execute( "*", $itemtype, $branchcode );
+    $results = $sth->fetchrow_hashref;
+    return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
+      if defined($results) && $results->{hardduedate} ne 'NULL';
+
+    $sth->execute( "*", "*", $branchcode );
+    $results = $sth->fetchrow_hashref;
+    return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
+      if defined($results) && $results->{hardduedate} ne 'NULL';
+
+    $sth->execute( $borrowertype, $itemtype, "*" );
+    $results = $sth->fetchrow_hashref;
+    return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
+      if defined($results) && $results->{hardduedate} ne 'NULL';
+
+    $sth->execute( $borrowertype, "*", "*" );
+    $results = $sth->fetchrow_hashref;
+    return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
+      if defined($results) && $results->{hardduedate} ne 'NULL';
+
+    $sth->execute( "*", $itemtype, "*" );
+    $results = $sth->fetchrow_hashref;
+    return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
+      if defined($results) && $results->{hardduedate} ne 'NULL';
+
+    $sth->execute( "*", "*", "*" );
+    $results = $sth->fetchrow_hashref;
+    return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
+      if defined($results) && $results->{hardduedate} ne 'NULL';
+
+    # if no rule is set => return undefined
+    return (undef, undef);
+}
+
 =head2 GetIssuingRule
 
   my $irule = &GetIssuingRule($borrowertype,$itemtype,branchcode)
@@ -2197,15 +2255,12 @@ sub AddRenewal {
     unless ($datedue) {
 
         my $borrower = C4::Members::GetMemberDetails( $borrowernumber, 0 ) or return undef;
-        my $loanlength = GetLoanLength(
-                    $borrower->{'categorycode'},
-                    (C4::Context->preference('item-level_itypes')) ? $biblio->{'itype'} : $biblio->{'itemtype'} ,
-                               $issuedata->{'branchcode'}  );   # that's the circ control branch.
+        my $itemtype = (C4::Context->preference('item-level_itypes')) ? $biblio->{'itype'} : $biblio->{'itemtype'} ,
 
         $datedue = (C4::Context->preference('RenewalPeriodBase') eq 'date_due') ?
                                         C4::Dates->new($issuedata->{date_due}, 'iso') :
                                         C4::Dates->new();
-        $datedue =  CalcDateDue($datedue,$loanlength,$issuedata->{'branchcode'},$borrower);
+        $datedue =  CalcDateDue($datedue,$itemtype,$issuedata->{'branchcode'},$borrower);
     }
 
     # Update the issues record to have the new due date, and a new count
@@ -2628,17 +2683,20 @@ sub UpdateHoldingbranch {
 
 =head2 CalcDateDue
 
-$newdatedue = CalcDateDue($startdate,$loanlength,$branchcode);
-this function calculates the due date given the loan length ,
+$newdatedue = CalcDateDue($startdate,$itemtype,$branchcode,$borrower);
+
+this function calculates the due date given the start date and configured circulation rules,
 checking against the holidays calendar as per the 'useDaysMode' syspref.
 C<$startdate>   = C4::Dates object representing start date of loan period (assumed to be today)
+C<$itemtype>  = itemtype code of item in question
 C<$branch>  = location whose calendar to use
-C<$loanlength>  = loan length prior to adjustment
+C<$borrower> = Borrower object
 =cut
 
 sub CalcDateDue { 
-       my ($startdate,$loanlength,$branch,$borrower) = @_;
+       my ($startdate,$itemtype,$branch,$borrower) = @_;
        my $datedue;
+        my $loanlength = GetLoanLength($borrower->{'categorycode'},$itemtype, $branch);
 
        if(C4::Context->preference('useDaysMode') eq 'Days') {  # ignoring calendar
                my $timedue = time + ($loanlength) * 86400;
@@ -2650,19 +2708,27 @@ sub CalcDateDue {
                $datedue = $calendar->addDate($startdate, $loanlength);
        }
 
+       # if Hard Due Dates are used, retreive them and apply as necessary
+        my ($hardduedate, $hardduedatecompare) = GetHardDueDate($borrower->{'categorycode'},$itemtype, $branch);
+       if ( $hardduedate->output('iso') && $hardduedate->output('iso') ne '0000-00-00') {
+            # if the calculated due date is after the 'before' Hard Due Date (ceiling), override
+            if ( $datedue->output( 'iso' ) gt $hardduedate->output( 'iso' ) && $hardduedatecompare == -1) {
+                $datedue = $hardduedate;
+            # if the calculated date is before the 'after' Hard Due Date (floor), override
+            } elsif ( $datedue->output( 'iso' ) lt $hardduedate->output( 'iso' ) && $hardduedatecompare == 1) {
+                $datedue = $hardduedate;               
+            # if the hard due date is set to 'exactly', overrride
+            } elsif ( $hardduedatecompare == 0) {
+                $datedue = $hardduedate;
+            }
+            # in all other cases, keep the date due as it is
+       }
+
        # if ReturnBeforeExpiry ON the datedue can't be after borrower expirydate
        if ( C4::Context->preference('ReturnBeforeExpiry') && $datedue->output('iso') gt $borrower->{dateexpiry} ) {
            $datedue = C4::Dates->new( $borrower->{dateexpiry}, 'iso' );
        }
 
-       # if ceilingDueDate ON the datedue can't be after the ceiling date
-       if ( C4::Context->preference('ceilingDueDate')
-             && ( C4::Context->preference('ceilingDueDate') =~ C4::Dates->regexp('syspref') ) ) {
-            my $ceilingDate = C4::Dates->new( C4::Context->preference('ceilingDueDate') );
-            if ( $datedue->output( 'iso' ) gt $ceilingDate->output( 'iso' ) ) {
-                $datedue = $ceilingDate;
-            }
-       }
 
        return $datedue;
 }
index 9ad132c..3c77f93 100755 (executable)
@@ -26,6 +26,7 @@ use C4::Auth;
 use C4::Koha;
 use C4::Debug;
 use C4::Branch; # GetBranches
+use C4::Dates qw/format_date format_date_in_iso/;
 
 my $input = new CGI;
 my $dbh = C4::Context->dbh;
@@ -100,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, fine, finedays, firstremind, chargeperiod,rentaldiscount) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)");
-    my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, reservesallowed=?, issuelength=?, 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) 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 $br = $branch; # branch
     my $bor  = $input->param('categorycode'); # borrower category
@@ -116,15 +117,18 @@ elsif ($op eq 'add') {
     $maxissueqty =~ s/\s//g;
     $maxissueqty = undef if $maxissueqty !~ /^\d+/;
     my $issuelength  = $input->param('issuelength');
+    my $hardduedate = $input->param('hardduedate');
+    $hardduedate = format_date_in_iso($hardduedate);
+    my $hardduedatecompare = $input->param('hardduedatecompare');
     my $rentaldiscount = $input->param('rentaldiscount');
     $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,$rentaldiscount, $br,$bor,$cat);
+        $sth_update->execute($fine, $finedays,$firstremind, $chargeperiod, $maxissueqty, $renewalsallowed,$reservesallowed, $issuelength,$hardduedate,$hardduedatecompare,$rentaldiscount, $br,$bor,$cat);
     } else {
-        $sth_insert->execute($br,$bor,$cat,$maxissueqty,$renewalsallowed,$reservesallowed,$issuelength,$fine,$finedays,$firstremind,$chargeperiod,$rentaldiscount);
+        $sth_insert->execute($br,$bor,$cat,$maxissueqty,$renewalsallowed,$reservesallowed,$issuelength,$hardduedate,$hardduedatecompare,$fine,$finedays,$firstremind,$chargeperiod,$rentaldiscount);
     }
 } 
 elsif ($op eq "set-branch-defaults") {
@@ -377,6 +381,14 @@ while (my $row = $sth2->fetchrow_hashref) {
     $row->{'humancategorycode'} ||= $row->{'categorycode'};
     $row->{'default_humancategorycode'} = 1 if $row->{'humancategorycode'} eq '*';
     $row->{'fine'} = sprintf('%.2f', $row->{'fine'});
+    if ($row->{'hardduedate'} ne '0000-00-00') {
+       $row->{'hardduedate'} = format_date( $row->{'hardduedate'});
+       $row->{'hardduedatebefore'} = 1 if ($row->{'hardduedatecompare'} == -1);
+       $row->{'hardduedateexact'} = 1 if ($row->{'hardduedatecompare'} ==  0);
+       $row->{'hardduedateafter'} = 1 if ($row->{'hardduedatecompare'} ==  1);
+    } else {
+       $row->{'hardduedate'} = 0;
+    }
     push @row_loop, $row;
 }
 $sth->finish;
index 4e72229..87ecac4 100755 (executable)
@@ -162,7 +162,6 @@ $tabsysprefs{IssuingInProcess}               = "Circulation";
 $tabsysprefs{patronimages}                   = "Circulation";
 $tabsysprefs{printcirculationslips}          = "Circulation";
 $tabsysprefs{ReturnBeforeExpiry}             = "Circulation";
-$tabsysprefs{ceilingDueDate}                 = "Circulation";
 $tabsysprefs{SpecifyDueDate}                 = "Circulation";
 $tabsysprefs{AutomaticItemReturn}            = "Circulation";
 $tabsysprefs{ReservesMaxPickUpDelay}         = "Circulation";
@@ -175,7 +174,6 @@ $tabsysprefs{canreservefromotherbranches}    = "Circulation";
 $tabsysprefs{finesMode}                      = "Circulation";
 $tabsysprefs{numReturnedItemsToShow}         = "Circulation";
 $tabsysprefs{emailLibrarianWhenHoldIsPlaced} = "Circulation";
-$tabsysprefs{globalDueDate}                  = "Circulation";
 $tabsysprefs{itemBarcodeInputFilter}         = "Circulation";
 $tabsysprefs{WebBasedSelfCheck}              = "Circulation";
 $tabsysprefs{ShowPatronImageInWebBasedSelfCheck} = "Circulation";
index 1ed4afd..e521e19 100755 (executable)
@@ -136,11 +136,8 @@ if ( $barcode ) {
     }
 }
 
-my ($datedue,$invalidduedate,$globalduedate);
+my ($datedue,$invalidduedate);
 
-if(C4::Context->preference('globalDueDate') && (C4::Context->preference('globalDueDate') =~ C4::Dates->regexp('syspref'))){
-        $globalduedate = C4::Dates->new(C4::Context->preference('globalDueDate'));
-}
 my $duedatespec_allow = C4::Context->preference('SpecifyDueDate');
 if($duedatespec_allow){
     if ($duedatespec) {
@@ -157,16 +154,7 @@ if($duedatespec_allow){
             $invalidduedate = 1;
             $template->param(IMPOSSIBLE=>1, INVALID_DATE=>$duedatespec);
         }
-    } else {
-        # pass global due date to tmpl if specifyduedate is true 
-        # and we have no barcode (loading circ page but not checking out)
-        if($globalduedate &&  ! $barcode ){
-            $duedatespec = $globalduedate->output();
-            $stickyduedate = 1;
-        }
     }
-} else {
-    $datedue = $globalduedate if ($globalduedate);
 }
 
 my $todaysdate = C4::Dates->new->output('iso');
@@ -311,10 +299,6 @@ if ($barcode) {
         unless($confirm_required) {
             AddIssue( $borrower, $barcode, $datedue, $cancelreserve );
             $inprocess = 1;
-            if($globalduedate && ! $stickyduedate && $duedatespec_allow ){
-                $duedatespec = $globalduedate->output();
-                $stickyduedate = 1;
-            }
         }
     }
     
index c9bf007..2e1069e 100644 (file)
@@ -150,8 +150,6 @@ INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('emailLibrarianWhenHoldIsPlaced',0,'If ON, emails the librarian whenever a hold is placed',NULL,'YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('numReturnedItemsToShow','20','Number of returned items to show on the check-in page',NULL,'Integer');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('finesMode','test','Choose the fines mode, \'off\', \'test\' (emails admin report) or \'production\' (accrue overdue fines).  Requires accruefines cronjob.','off|test|production','Choice');
-INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('globalDueDate','','If set, allows a global static due date for all checkouts','10','free');
-INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('ceilingDueDate','','If set, date due will not be past this date.  Enter date according to the dateformat System Preference',NULL,'free');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('itemBarcodeInputFilter','','If set, allows specification of a item barcode input filter','whitespace|T-prefix|cuecat','Choice');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('singleBranchMode',0,'Operate in Single-branch mode, hide branch selection in the OPAC',NULL,'YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('URLLinkText','','Text to display as the link anchor in the OPAC',NULL,'free');
index 64cb64d..9f47292 100644 (file)
@@ -151,8 +151,6 @@ INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('emailLibrarianWhenHoldIsPlaced',0,'If ON, emails the librarian whenever a hold is placed',NULL,'YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('numReturnedItemsToShow','20','Number of returned items to show on the check-in page',NULL,'Integer');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('finesMode','test','Choose the fines mode, \'off\', \'test\' (emails admin report) or \'production\' (accrue overdue fines).  Requires accruefines cronjob.','off|test|production','Choice');
-INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('globalDueDate','','If set, allows a global static due date for all checkouts','10','free');
-INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('ceilingDueDate','','If set, date due will not be past this date.  Enter date according to the dateformat System Preference',NULL,'free');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('itemBarcodeInputFilter','','If set, allows specification of a item barcode input filter','whitespace|T-prefix|cuecat|libsuite8','Choice');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('singleBranchMode',0,'Operate in Single-branch mode, hide branch selection in the OPAC',NULL,'YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('URLLinkText','','Text to display as the link anchor in the OPAC',NULL,'free');
index f3fac34..c58f69c 100644 (file)
@@ -151,8 +151,6 @@ INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('emailLibrarianWhenHoldIsPlaced',0,'Si activé, envoie un mail à la bibliothèque lorsqu''une réservation est posée',NULL,'YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('numReturnedItemsToShow','20','Nombre d''exemplaires rendus à afficher sur la page de retour',NULL,'Integer');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('finesMode','test','Choisissez un mode pour le calcul des amendes : Test ou Production.','test|production','Choice');
-INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('globalDueDate','','Si défini, autorise une date de retour statique pour tous les prêts','10','free');
-INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('ceilingDueDate','','Si présent, les dates de retour des prêts ne pourront être antérieures à cette date. Formatez cette date conformément à la préférence système dateformat.',NULL,'free');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('itemBarcodeInputFilter','','Si activé, permet de définir le format des codes à barre','whitespace|T-prefix|cuecat','Choice');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('singleBranchMode',0,'Activer s''il n''y a qu''une seule bibliothèque sur ce catalogue, cela cache le sélecteur de bibliothèque inutile',NULL,'YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('URLLinkText','','Texte à afficher dans l''ancre du logo de l''OPAC',NULL,'free');
index 03700d5..3c3d3c8 100644 (file)
@@ -61,7 +61,6 @@ insert into `systempreferences` (`variable`, `value`, `options`, `explanation`,
 -- insert into `systempreferences` (`variable`, `value`, `options`, `explanation`, `type`) values('FrameworksLoaded','auth_val.sql|authority_framework.sql|class_sources.sql|message_transport_types.sql|notices.sql|parameters.sql|patron_categories.sql|sample_holidays.sql|sample_itemtypes.sql|sample_labels.sql|sample_news.sql|sample_notices_message_attributes.sql|sample_notices_message_transports.sql|stopwords.sql|subtag_registry.sql|sysprefs.sql|unimarc_framework.sql|userflags.sql|userpermissions.sql',NULL,'Frameworks loaded through webinstaller','choice');
 insert into `systempreferences` (`variable`, `value`, `options`, `explanation`, `type`) values('FRBRizeEditions','1','','Se ON, Koha farà delle richieste a uno o più ISBN web services per trovare gli ISBN associabili e li visualizzarà in un tab \'Edizioni\' nella visualizzazione dettagliata','YesNo');
 insert into `systempreferences` (`variable`, `value`, `options`, `explanation`, `type`) values('gist','0','','Valore predefinito per la Goods and Services  tax (l\'IVA) calcolato non in %, ma in forma numerica (0.12 for 12%), impostare a 0 per disabilitarla.','Float');
-insert into `systempreferences` (`variable`, `value`, `options`, `explanation`, `type`) values('globalDueDate','','10','Se impostata forza un’unica data di scadenza per tutti i prestiti','free');
 insert into `systempreferences` (`variable`, `value`, `options`, `explanation`, `type`) values('GoogleJackets','1','','Se ON, visualizza le copertine usando Google Books','YesNo');
 insert into `systempreferences` (`variable`, `value`, `options`, `explanation`, `type`) values('hidelostitems','0','','Se ON, viene disabilitata la visualizzazione nell\'OPAC delle copie perse.','YesNo');
 insert into `systempreferences` (`variable`, `value`, `options`, `explanation`, `type`) values('hide_marc','0','','Se su ON, disabilita la visualizzazione dei campi del MARC, codici di sottocampi e indicatori (mostra ancora i dati)','YesNo');
@@ -224,7 +223,6 @@ INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('casAuthentication', '0', 'Enable or disable CAS authentication', '', 'YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('casLogout', '0', 'Does a logout from Koha should also log the user out of CAS?', '', 'YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('casServerUrl', 'https://localhost:8443/cas', 'URL of the cas server', '', 'Free');
-INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('ceilingDueDate','','If set, date due will not be past this date.  Enter date according to the dateformat System Preference',NULL,'free');
 INSERT INTO `systempreferences` (variable,value,options,explanation,type)  VALUES ('CurrencyFormat','FR','US|FR','Determines the display format of currencies. eg: \'36000\' is displayed as \'360 000,00\'  in \'FR\' or \'360,000.00\'  in \'US\'.','Choice');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('DisplayMultiPlaceHold','1','Display the ability to place multiple holds or not','','YesNo');
 INSERT INTO systempreferences (variable,value,options,explanation,type)VALUES('DisplayOPACiconsXSLT', '1', '', 'If ON, displays the format, audience, type icons in XSLT MARC21 results and display pages.', 'YesNo');
index b9e4df6..1171cb1 100644 (file)
@@ -966,6 +966,8 @@ CREATE TABLE `issuingrules` (
   `chargename` varchar(100) default NULL,
   `maxissueqty` int(4) default NULL,
   `issuelength` int(4) default NULL,
+  `hardduedate` date default NULL,
+  `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 '',
index 5a75e97..70ad079 100644 (file)
@@ -149,8 +149,6 @@ INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('emailLibrarianWhenHoldIsPlaced',0,'If ON, emails the librarian whenever a hold is placed',NULL,'YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('numReturnedItemsToShow','20','Number of returned items to show on the check-in page',NULL,'Integer');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('finesMode','test','Choose the fines mode, \'off\', \'test\' (emails admin report) or \'production\' (accrue overdue fines).  Requires accruefines cronjob.','off|test|production','Choice');
-INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('globalDueDate','','If set, allows a global static due date for all checkouts','10','free');
-INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('ceilingDueDate','','If set, date due will not be past this date.  Enter date according to the dateformat System Preference',NULL,'free');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('itemBarcodeInputFilter','','If set, allows specification of a item barcode input filter','whitespace|T-prefix|cuecat','Choice');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('singleBranchMode',0,'Operate in Single-branch mode, hide branch selection in the OPAC',NULL,'YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('URLLinkText','','Text to display as the link anchor in the OPAC',NULL,'free');
index 3d20f0e..448e617 100644 (file)
@@ -177,7 +177,6 @@ INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('noItemTypeImages',0,'If ON, disables item-type images',NULL,'YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('emailLibrarianWhenHoldIsPlaced',0,'If ON, emails the librarian whenever a hold is placed',NULL,'YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('finesMode','test','Choose the fines mode, \'off\', \'test\' (emails admin report) or \'production\' (accrue overdue fines).  Requires accruefines cronjob.','off|test|production','Choice');
-INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('globalDueDate','','If set, allows a global static due date for all checkouts','10','free');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('itemBarcodeInputFilter','','If set, allows specification of a item barcode input filter','whitespace|T-prefix|cuecat','Choice');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('singleBranchMode',0,'Operate in Single-branch mode, hide branch selection in the OPAC',NULL,'YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('URLLinkText','','Text to display as the link anchor in the OPAC',NULL,'free');
@@ -286,7 +285,6 @@ INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('intranetbookbag','1','If ON, enables display of Cart feature in the intranet','','YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('opacSerialDefaultTab', 'subscriptions', 'Define the default tab for serials in OPAC.', 'holdings|serialcollection|subscriptions', 'Choice');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('numReturnedItemsToShow','20','Number of returned items to show on the check-in page',NULL,'Integer');
-INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('ceilingDueDate','','If set, date due will not be past this date.  Enter date according to the dateformat System Preference',NULL,'free');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OAI-PMH:ConfFile','','If empty, Koha OAI Server operates in normal mode, otherwise it operates in extended mode.',NULL,'File');
 ('OPACXSLTDetailsDisplay','0','','Enable XSL stylesheet control over details page display on OPAC','YesNo'),
 ('OPACXSLTResultsDisplay','0','','Enable XSL stylesheet control over results page display on OPAC','YesNo'),
index 42baaaa..f8b1ea0 100644 (file)
@@ -176,7 +176,6 @@ INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('noItemTypeImages',0,'If ON, disables item-type images',NULL,'YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('emailLibrarianWhenHoldIsPlaced',0,'If ON, emails the librarian whenever a hold is placed',NULL,'YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('finesMode','test','Choose the fines mode, \'off\', \'test\' (emails admin report) or \'production\' (accrue overdue fines).  Requires accruefines cronjob.','off|test|production','Choice');
-INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('globalDueDate','','If set, allows a global static due date for all checkouts','10','free');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('itemBarcodeInputFilter','','If set, allows specification of a item barcode input filter','whitespace|T-prefix|cuecat','Choice');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('singleBranchMode',0,'Operate in Single-branch mode, hide branch selection in the OPAC',NULL,'YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('URLLinkText','','Text to display as the link anchor in the OPAC',NULL,'free');
@@ -311,7 +310,6 @@ INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('intranetbookbag','1','If ON, enables display of Cart feature in the intranet','','YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('opacSerialDefaultTab', 'subscriptions', 'Define the default tab for serials in OPAC.', 'holdings|serialcollection|subscriptions', 'Choice');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('numReturnedItemsToShow','20','Number of returned items to show on the check-in page',NULL,'Integer');
-INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('ceilingDueDate','','If set, date due will not be past this date.  Enter date according to the dateformat System Preference',NULL,'free');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OAI-PMH:ConfFile','','If empty, Koha OAI Server operates in normal mode, otherwise it operates in extended mode.',NULL,'File');
 ('OPACXSLTDetailsDisplay','0','','Enable XSL stylesheet control over details page display on OPAC','YesNo'),
 ('OPACXSLTResultsDisplay','0','','Enable XSL stylesheet control over results page display on OPAC','YesNo'),
index e45c543..afa35f8 100755 (executable)
@@ -37,6 +37,7 @@ use Getopt::Long;
 # Koha modules
 use C4::Context;
 use C4::Installer;
+use C4::Dates;
 
 use MARC::Record;
 use MARC::File::XML ( BinaryEncoding => 'utf8' );
@@ -4148,6 +4149,23 @@ if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
     SetVersion ($DBversion);
 }
 
+$DBversion = '3.03.00.XXX';
+if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
+    $dbh->do("ALTER TABLE `issuingrules` ADD hardduedate date default NULL AFTER issuelength");
+    $dbh->do("ALTER TABLE `issuingrules` ADD hardduedatecompare tinyint NOT NULL default 0 AFTER hardduedate");
+    my $duedate;
+    if (C4::Context->preference("globalDueDate")) {
+      $duedate = C4::Dates::format_date_in_iso(C4::Context->preference("globalDueDate"));
+      $dbh->do("UPDATE `issuingrules` SET hardduedate = '$duedate', hardduedatecompare = 0");
+    } elsif (C4::Context->preference("ceilingDueDate")) {
+      $duedate = C4::Dates::format_date_in_iso(C4::Context->preference("ceilingDueDate"));
+      $dbh->do("UPDATE `issuingrules` SET hardduedate = '$duedate', hardduedatecompare = -1");
+    }
+    $dbh->do("DELETE FROM `systempreferences` WHERE variable = 'globalDueDate' OR variable = 'ceilingDueDate'");
+    print "Upgrade to $DBversion done (Move global and ceiling due dates to Circ Rules level)\n";
+    SetVersion ($DBversion);
+}
+
 =head1 FUNCTIONS
 
 =head2 DropAllForeignKeys($table)
index e0eac4d..6670dee 100644 (file)
@@ -148,16 +148,6 @@ Circulation:
                   homebranch: the library the item is from.
                   holdingbranch: the library the item was checked out from.
         -
-            - Make all checkouts have a due date of
-            - pref: globalDueDate
-              class: date
-            - .
-        -
-            - Make all checkouts due on or before
-            - pref: ceilingDueDate
-              class: date
-            - .
-        -
             - Calculate the due date using 
             - pref: useDaysMode
               choices:
index 92a44ce..bde70b2 100644 (file)
@@ -12,7 +12,12 @@ $(document).ready(function() {
 });
 //]]>
 </script>
-
+<!-- Enable Calendar system -->
+<link rel="stylesheet" type="text/css" href="<!-- TMPL_VAR name="themelang" -->/lib/calendar/calendar-system.css" />
+<script type="text/javascript" src="<!-- TMPL_VAR name="themelang" -->/lib/calendar/calendar.js"></script>
+<script type="text/javascript" src="<!-- TMPL_VAR name="themelang" -->/lib/calendar/calendar-en.js"></script>
+<script type="text/javascript" src="<!-- TMPL_VAR name="themelang" -->/lib/calendar/calendar-setup.js"></script>
+<!-- End Calendar system additions -->
 </head>
 <body>
 <!-- TMPL_INCLUDE NAME="header.inc" -->
@@ -68,6 +73,7 @@ for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde
                 <th>Item Type</th>
                 <th>Current Checkouts Allowed</th>
                 <th>Loan Period (day)</th>
+                <th>Hard Due Date</th>
                 <th>Fine Amount</th>
                 <th>Fine Charging Interval</th>
                 <th>Fine Grace period (day)</th>
@@ -102,6 +108,13 @@ for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde
                                                                <!-- /TMPL_IF -->
                                                        </td>
                                                        <td><!-- TMPL_VAR NAME="issuelength" --></td>
+                                                        <td><!-- TMPL_IF NAME="hardduedate" -->
+                                                               <!-- TMPL_IF NAME="hardduedatebefore" -->before <!-- TMPL_VAR NAME="hardduedate" --></td>
+                                                               <!-- TMPL_ELSE --><!-- TMPL_IF NAME="hardduedateexact" -->on <!-- TMPL_VAR NAME="hardduedate" --></td>
+                                                                                 <!-- TMPL_ELSE --><!-- TMPL_IF NAME="hardduedateafter" -->after <!-- TMPL_VAR NAME="hardduedate" --></td><!-- /TMPL_IF -->
+                                                                                 <!-- /TMPL_IF -->
+                                                               <!-- /TMPL_IF -->
+                                                            <!-- TMPL_ELSE -->None defined<!-- /TMPL_IF -->   
                                                        <td><!-- TMPL_VAR NAME="fine" --></td>
                                                        <td><!-- TMPL_VAR NAME="chargeperiod" --></td>
                                                        <td><!-- TMPL_VAR NAME="firstremind" --></td>
@@ -133,6 +146,29 @@ for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde
                     </td>
                     <td><input name="maxissueqty" size="3" /></td>
                     <td><input name="issuelength" size="3" /> </td>
+                    <td><select name="hardduedatecompare">
+                           <option value="-1">Before</option>
+                           <option value="0">Exactly on</option>
+                           <option value="1">After</option>
+                        </select>
+                        <input type="text" size="10" id="hardduedate" name="hardduedate" value="<!-- TMPL_VAR NAME="hardduedate" -->" />
+                        <!-- TMPL_INCLUDE NAME="date-format.inc" -->
+                        <img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar"  border="0" id="CalendarDueDate" style="cursor: pointer;"/>
+                        <script language="JavaScript" type="text/javascript">
+                             function refocus(calendar) {
+                                 document.getElementById('hardduedate').focus();
+                                 calendar.hide();
+                             };
+                             Calendar.setup(
+                             {
+                             inputField : "hardduedate",
+                             ifFormat : "%m/%d/%Y",
+                             button : "CalendarDueDate",
+                             onClose: refocus
+                             }
+                             );
+                 </script>
+                    </td>
                     <td><input name="fine" size="4" /></td>
                     <td><input name="chargeperiod" size="2" /></td>
                     <td><input name="firstremind" size="2" /> </td>