moving readingrec to members directory
[koha-ffzg.git] / updater / updatedatabase
index 06337b9..3add675 100755 (executable)
@@ -20,6 +20,9 @@ use Getopt::Long;
 # Koha modules
 use C4::Context;
 
+use MARC::Record;
+use MARC::File::XML;
+
 # FIXME - The user might be installing a new database, so can't rely
 # on /etc/koha.conf anyway.
 
@@ -42,6 +45,7 @@ GetOptions(
        );
 my $dbh = C4::Context->dbh;
 print "connected to your DB. Checking & modifying it\n" unless $silent;
+$|=1; # flushes output
 
 #-------------------
 # Defines
@@ -72,9 +76,29 @@ my %requiretables = (
                                    `info` TEXT default '' ,
                                    PRIMARY KEY ( `timestamp` , `user` )
                            )",
+       letter          => "(
+                                       module varchar(20) NOT NULL default '',
+                                       code varchar(20) NOT NULL default '',
+                                       name varchar(100) NOT NULL default '',
+                                       title varchar(200) NOT NULL default '',
+                                       content text,
+                                       PRIMARY KEY  (module,code)
+                               )",
+       alert           =>"(
+                                       alertid int(11) NOT NULL auto_increment,
+                                       borrowernumber int(11) NOT NULL default '0',
+                                       type varchar(10) NOT NULL default '',
+                                       externalid varchar(20) NOT NULL default '',
+                                       PRIMARY KEY  (alertid),
+                                       KEY borrowernumber (borrowernumber),
+                                       KEY type (type,externalid)
+                               )",
+
 );
 
 my %requirefields = (
+       subscription => { 'letter' => 'char(20) NULL', 'distributedto' => 'text NULL'},
+       itemtypes => { 'imageurl' => 'char(200) NULL'},
 #    tablename        => { 'field' => 'fieldtype' },
 );
 
@@ -122,7 +146,147 @@ my %tabledata = (
             explanation         => 'Turn Branch independancy management On an Off',
            type                => 'YesNo',
         },
-
+               {
+            uniquefieldrequired => 'variable',
+            variable            => 'ReturnBeforeExpiry',
+            value               => 'Off',
+           forceupdate         => { 'explanation' => 1,
+                                    'type' => 1},
+            explanation         => 'If Yes, Returndate on issuing can\'t be after borrower card expiry',
+           type                => 'YesNo',
+        },
+        {
+            uniquefieldrequired => 'variable',
+            variable            => 'opacstylesheet',
+            value               => '',
+           forceupdate         => { 'explanation' => 1,
+                                    'type' => 1},
+            explanation         => 'Enter a complete URL to use an alternate stylesheet in OPAC',
+           type                => 'free',
+        },
+        {
+            uniquefieldrequired => 'variable',
+            variable            => 'opacsmallimage',
+            value               => '',
+           forceupdate         => { 'explanation' => 1,
+                                    'type' => 1},
+            explanation         => 'Enter a complete URL to an image, will be on top/left instead of the Koha logo',
+           type                => 'free',
+        },
+        {
+            uniquefieldrequired => 'variable',
+            variable            => 'opaclargeimage',
+            value               => '',
+           forceupdate         => { 'explanation' => 1,
+                                    'type' => 1},
+            explanation         => 'Enter a complete URL to an image, will be on the main page, instead of the Koha logo',
+           type                => 'free',
+        },
+        {
+            uniquefieldrequired => 'variable',
+            variable            => 'delimiter',
+            value               => ';',
+           forceupdate         => { 'explanation' => 1,
+                                    'type' => 1},
+            explanation         => 'separator for reports exported to spreadsheet',
+           type                => 'free',
+        },
+        {
+            uniquefieldrequired => 'variable',
+            variable            => 'MIME',
+            value               => 'OPENOFFICE.ORG',
+            forceupdate                => { 'explanation' => 1,
+                                    'type' => 1,
+                                    'options' => 1},
+            explanation         => 'Define the default application for report exportations into files',
+               type            => 'Choice',
+               options         => 'EXCEL|OPENOFFICE.ORG'
+        },
+        {
+            uniquefieldrequired => 'variable',
+            variable            => 'Delimiter',
+            value               => ';',
+               forceupdate             => { 'explanation' => 1,
+                                    'type' => 1,
+                                    'options' => 1},
+            explanation         => 'Define the default separator character for report exportations into files',
+               type            => 'Choice',
+               options         => ';|tabulation|,|/|\|#'
+        },
+        {
+            uniquefieldrequired => 'variable',
+            variable            => 'SubscriptionHistory',
+            value               => ';',
+               forceupdate             => { 'explanation' => 1,
+                                    'type' => 1,
+                                    'options' => 1},
+            explanation         => 'Define the information level for serials history in OPAC',
+               type            => 'Choice',
+               options         => 'simplified|full'
+        },
+        {
+            uniquefieldrequired => 'variable',
+            variable            => 'hidelostitems',
+            value               => 'No',
+           forceupdate         => { 'explanation' => 1,
+                                    'type' => 1},
+            explanation         => 'show or hide "lost" items in OPAC.',
+           type                => 'YesNo',
+        },
+                {
+            uniquefieldrequired => 'variable',
+            variable            => 'IndependantBranches',
+            value               => '0',
+            forceupdate         => { 'explanation' => 1,
+                                     'type' => 1},
+            explanation         => 'Turn Branch independancy management On an Off',
+            type                => 'YesNo',
+        },
+                {
+            uniquefieldrequired => 'variable',
+            variable            => 'ReturnBeforeExpiry',
+            value               => '0',
+            forceupdate         => { 'explanation' => 1,
+                                     'type' => 1},
+            explanation         => 'If Yes, Returndate on issuing can\'t be after borrower card expiry',
+            type                => 'YesNo',
+        },
+        {
+            uniquefieldrequired => 'variable',
+            variable            => 'Disable_Dictionary',
+            value               => '0',
+            forceupdate         => { 'explanation' => 1,
+                                     'type' => 1},
+            explanation         => 'Disables Dictionary buttons if set to yes',
+            type                => 'YesNo',
+        },
+        {
+            uniquefieldrequired => 'variable',
+            variable            => 'hide_marc',
+            value               => '0',
+            forceupdate         => { 'explanation' => 1,
+                                     'type' => 1},
+            explanation         => 'hide marc specific datas like subfield code & indicators to library',
+            type                => 'YesNo',
+        },
+        {
+            uniquefieldrequired => 'variable',
+            variable            => 'NotifyBorrowerDeparture',
+            value               => '0',
+            forceupdate         => { 'explanation' => 1,
+                                     'type' => 1},
+            explanation         => 'Delay before expiry where a notice is sent when issuing',
+            type                => 'Integer',
+        },
+        {
+            uniquefieldrequired => 'variable',
+            variable            => 'OpacPasswordChange',
+            value               => '1',
+            forceupdate         => { 'explanation' => 1,
+                                     'type' => 1},
+            explanation         => 'Enable/Disable password change in OPAC (disable it when using LDAP auth)',
+            type                => 'YesNo',
+        },
     ],
 
 );
@@ -136,6 +300,16 @@ my %fielddefinitions = (
 #             default => ''
 #         },
 #     ],
+       serial => [
+        {
+            field   => 'notes',
+            type    => 'TEXT',
+            null    => 'NULL',
+            key     => '',
+            default => '',
+            extra   => ''
+        },
+    ],
 );
 
 #-------------------
@@ -226,6 +400,7 @@ foreach $table ( keys %fielddefinitions ) {
        {
                $definitions->{$column}->{type}    = $type;
                $definitions->{$column}->{null}    = $null;
+               $definitions->{$column}->{null}    = 'NULL' if $null eq 'YES';
                $definitions->{$column}->{key}     = $key;
                $definitions->{$column}->{default} = $default;
                $definitions->{$column}->{extra}   = $extra;
@@ -235,18 +410,19 @@ foreach $table ( keys %fielddefinitions ) {
                my $field   = $row->{field};
                my $type    = $row->{type};
                my $null    = $row->{null};
+#              $null    = 'YES' if $row->{null} eq 'NULL';
                my $key     = $row->{key};
                my $default = $row->{default};
-               $default="''" unless $default;
+               my $null    = $row->{null};
+#              $default="''" unless $default;
                my $extra   = $row->{extra};
                my $def     = $definitions->{$field};
+
                unless ( $type eq $def->{type}
                        && $null eq $def->{null}
                        && $key eq $def->{key}
-                       && $default eq $def->{default}
                        && $extra eq $def->{extra} )
                {
-
                        if ( $null eq '' ) {
                                $null = 'NOT NULL';
                        }
@@ -256,6 +432,7 @@ foreach $table ( keys %fielddefinitions ) {
                        unless ( $extra eq 'auto_increment' ) {
                                $extra = '';
                        }
+
                        # if it's a new column use "add", if it's an old one, use "change".
                        my $action;
                        if ($definitions->{$field}->{type}) {
@@ -278,6 +455,37 @@ foreach $table ( keys %fielddefinitions ) {
 
 
 # Populate tables with required data
+
+
+# synch table and deletedtable.
+foreach my $table (('borrowers','items','biblio','biblioitems')) {
+       my %deletedborrowers;
+       print "synch'ing $table\n";
+       $sth = $dbh->prepare("show columns from deleted$table");
+       $sth->execute;
+       while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow ) {
+               $deletedborrowers{$column}=1;
+       }
+       $sth = $dbh->prepare("show columns from $table");
+       $sth->execute;
+       my $previous;
+       while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow ) {
+               unless ($deletedborrowers{$column}) {
+                       my $newcol="alter table deleted$table add $column $type";
+                       if ($null eq 'YES') {
+                               $newcol .= " NULL ";
+                       } else {
+                               $newcol .= " NOT NULL ";
+                       }
+                       $newcol .= "default $default" if $default;
+                       $newcol .= " after $previous" if $previous;
+                       $previous=$column;
+                       print "creating column $column\n";
+                       $dbh->do($newcol);
+               }
+       }
+}
+
 foreach my $table ( keys %tabledata ) {
     print "Checking for data required in table $table...\n" unless $silent;
     my $tablerows = $tabledata{$table};
@@ -322,6 +530,86 @@ foreach my $table ( keys %tabledata ) {
     }
 }
 
+#
+# SPECIFIC STUFF
+#
+#
+# create frameworkcode row in biblio table & fill it with marc_biblio.frameworkcode.
+#
+
+# 1st, get how many biblio we will have to do...
+$sth = $dbh->prepare('select count(*) from marc_biblio');
+$sth->execute;
+my ($totaltodo) = $sth->fetchrow;
+
+$sth = $dbh->prepare("show columns from biblio");
+$sth->execute();
+my $definitions;
+my $bibliofwexist=0;
+while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow ){
+       $bibliofwexist=1 if $column eq 'frameworkcode';
+}
+unless ($bibliofwexist) {
+       print "moving biblioframework to biblio table\n";
+       $dbh->do('ALTER TABLE `biblio` ADD `frameworkcode` VARCHAR( 4 ) NOT NULL AFTER `biblionumber`');
+       $sth = $dbh->prepare('select biblionumber,frameworkcode from marc_biblio');
+       $sth->execute;
+       my $sth_update = $dbh->prepare('update biblio set frameworkcode=? where biblionumber=?');
+       my $totaldone=0;
+       while (my ($biblionumber,$frameworkcode) = $sth->fetchrow) {
+               $sth_update->execute($frameworkcode,$biblionumber);
+               $totaldone++;
+               print "\r$totaldone / $totaltodo" unless ($totaldone % 100);
+       }
+       print "\rdone\n";
+}
+
+#
+# moving MARC data from marc_subfield_table to biblioitems.marc
+#
+$sth = $dbh->prepare("show columns from biblioitems");
+$sth->execute();
+my $definitions;
+my $marcdone=0;
+while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow ){
+       $marcdone=1 if ($type eq 'blob' && $column eq 'marc') ;
+}
+unless ($marcdone) {
+       print "moving MARC record to biblioitems table\n";
+       # changing marc field type
+       $dbh->do('ALTER TABLE `biblioitems` CHANGE `marc` `marc` BLOB NULL DEFAULT NULL ');
+       # adding marc xml, just for convenience
+       $dbh->do('ALTER TABLE `biblioitems` ADD `marcxml` TEXT NOT NULL');
+       # moving data from marc_subfield_value to biblio
+       $sth = $dbh->prepare('select bibid,biblionumber from marc_biblio');
+       $sth->execute;
+       my $sth_update = $dbh->prepare('update biblioitems set marc=?, marcxml=? where biblionumber=?');
+       my $totaldone=0;
+       while (my ($bibid,$biblionumber) = $sth->fetchrow) {
+               my $record = MARCgetbiblio($dbh,$bibid);
+               $sth_update->execute($record->as_usmarc(),$record->as_xml(),$biblionumber);
+               $totaldone++;
+               print "\r$totaldone / $totaltodo" unless ($totaldone % 100);
+       }
+       print "\rdone\n";
+}
+
+# MOVE all tables TO UTF-8 and innoDB
+$sth = $dbh->prepare("show table status");
+$sth->execute;
+while ( my $table = $sth->fetchrow_hashref ) {
+       if ($table->{Engine} ne 'InnoDB') {
+               $dbh->do("ALTER TABLE $table->{Name} TYPE = innodb");
+               print "moving $table->{Name} to InnoDB\n";
+       }
+       unless ($table->{Collation} =~ /^utf8/) {
+               $dbh->do("ALTER TABLE $table->{Name} DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci");
+               # FIXME : maybe a ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8 would be better, def char set seems to work fine. If any problem encountered, let's try with convert !
+               print "moving $table->{Name} to utf8\n";
+       } else {
+       }
+}
+
 # at last, remove useless fields
 foreach $table ( keys %uselessfields ) {
        my @fields = split /,/,$uselessfields{$table};
@@ -348,9 +636,272 @@ foreach $table ( keys %uselessfields ) {
 
 $sth->finish;
 
+#
+# those 2 subs are a copy of Biblio.pm, version 2.2.4
+# they are useful only once, for moving from 2.2 to 3.0
+# the MARCgetbiblio & MARCgetitem subs in Biblio.pm
+# are still here, but uses other tables
+# (the ones that are filled by updatedatabase !)
+#
+sub MARCgetbiblio {
+
+    # Returns MARC::Record of the biblio passed in parameter.
+    my ( $dbh, $bibid ) = @_;
+    my $record = MARC::Record->new();
+#      warn "". $bidid;
+
+    my $sth =
+      $dbh->prepare(
+"select bibid,subfieldid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,subfieldvalue,valuebloblink
+                                from marc_subfield_table
+                                where bibid=? order by tag,tagorder,subfieldorder
+                        "
+    );
+    my $sth2 =
+      $dbh->prepare(
+        "select subfieldvalue from marc_blob_subfield where blobidlink=?");
+    $sth->execute($bibid);
+    my $prevtagorder = 1;
+    my $prevtag      = 'XXX';
+    my $previndicator;
+    my $field;        # for >=10 tags
+    my $prevvalue;    # for <10 tags
+    while ( my $row = $sth->fetchrow_hashref ) {
+
+        if ( $row->{'valuebloblink'} ) {    #---- search blob if there is one
+            $sth2->execute( $row->{'valuebloblink'} );
+            my $row2 = $sth2->fetchrow_hashref;
+            $sth2->finish;
+            $row->{'subfieldvalue'} = $row2->{'subfieldvalue'};
+        }
+        if ( $row->{tagorder} ne $prevtagorder || $row->{tag} ne $prevtag ) {
+            $previndicator .= "  ";
+            if ( $prevtag < 10 ) {
+                               if ($prevtag ne '000') {
+                       $record->add_fields( ( sprintf "%03s", $prevtag ), $prevvalue ) unless $prevtag eq "XXX";    # ignore the 1st loop
+                               } else {
+                                       $record->leader(sprintf("%24s",$prevvalue));
+                               }
+            }
+            else {
+                $record->add_fields($field) unless $prevtag eq "XXX";
+            }
+            undef $field;
+            $prevtagorder  = $row->{tagorder};
+            $prevtag       = $row->{tag};
+            $previndicator = $row->{tag_indicator};
+            if ( $row->{tag} < 10 ) {
+                $prevvalue = $row->{subfieldvalue};
+            }
+            else {
+                $field = MARC::Field->new(
+                    ( sprintf "%03s", $prevtag ),
+                    substr( $row->{tag_indicator} . '  ', 0, 1 ),
+                    substr( $row->{tag_indicator} . '  ', 1, 1 ),
+                    $row->{'subfieldcode'},
+                    $row->{'subfieldvalue'}
+                );
+            }
+        }
+        else {
+            if ( $row->{tag} < 10 ) {
+                $record->add_fields( ( sprintf "%03s", $row->{tag} ),
+                    $row->{'subfieldvalue'} );
+            }
+            else {
+                $field->add_subfields( $row->{'subfieldcode'},
+                    $row->{'subfieldvalue'} );
+            }
+            $prevtag       = $row->{tag};
+            $previndicator = $row->{tag_indicator};
+        }
+    }
+
+    # the last has not been included inside the loop... do it now !
+    if ( $prevtag ne "XXX" )
+    { # check that we have found something. Otherwise, prevtag is still XXX and we
+         # must return an empty record, not make MARC::Record fail because we try to
+         # create a record with XXX as field :-(
+        if ( $prevtag < 10 ) {
+            $record->add_fields( $prevtag, $prevvalue );
+        }
+        else {
+
+            #                  my $field = MARC::Field->new( $prevtag, "", "", %subfieldlist);
+            $record->add_fields($field);
+        }
+    }
+    return $record;
+}
+
+sub MARCgetitem {
+
+    # Returns MARC::Record of the biblio passed in parameter.
+    my ( $dbh, $bibid, $itemnumber ) = @_;
+    my $record = MARC::Record->new();
+
+    # search MARC tagorder
+    my $sth2 =
+      $dbh->prepare(
+"select tagorder from marc_subfield_table,marc_subfield_structure where marc_subfield_table.tag=marc_subfield_structure.tagfield and marc_subfield_table.subfieldcode=marc_subfield_structure.tagsubfield and bibid=? and kohafield='items.itemnumber' and subfieldvalue=?"
+    );
+    $sth2->execute( $bibid, $itemnumber );
+    my ($tagorder) = $sth2->fetchrow_array();
+
+    #---- TODO : the leader is missing
+    my $sth =
+      $dbh->prepare(
+"select bibid,subfieldid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,subfieldvalue,valuebloblink
+                                from marc_subfield_table
+                                where bibid=? and tagorder=? order by subfieldcode,subfieldorder
+                        "
+    );
+    $sth2 =
+      $dbh->prepare(
+        "select subfieldvalue from marc_blob_subfield where blobidlink=?");
+    $sth->execute( $bibid, $tagorder );
+    while ( my $row = $sth->fetchrow_hashref ) {
+        if ( $row->{'valuebloblink'} ) {    #---- search blob if there is one
+            $sth2->execute( $row->{'valuebloblink'} );
+            my $row2 = $sth2->fetchrow_hashref;
+            $sth2->finish;
+            $row->{'subfieldvalue'} = $row2->{'subfieldvalue'};
+        }
+        if ( $record->field( $row->{'tag'} ) ) {
+            my $field;
+
+#--- this test must stay as this, because of strange behaviour of mySQL/Perl DBI with char var containing a number...
+            #--- sometimes, eliminates 0 at beginning, sometimes no ;-\\\
+            if ( length( $row->{'tag'} ) < 3 ) {
+                $row->{'tag'} = "0" . $row->{'tag'};
+            }
+            $field = $record->field( $row->{'tag'} );
+            if ($field) {
+                my $x =
+                  $field->add_subfields( $row->{'subfieldcode'},
+                    $row->{'subfieldvalue'} );
+                $record->delete_field($field);
+                $record->add_fields($field);
+            }
+        }
+        else {
+            if ( length( $row->{'tag'} ) < 3 ) {
+                $row->{'tag'} = "0" . $row->{'tag'};
+            }
+            my $temp =
+              MARC::Field->new( $row->{'tag'}, " ", " ",
+                $row->{'subfieldcode'} => $row->{'subfieldvalue'} );
+            $record->add_fields($temp);
+        }
+
+    }
+    return $record;
+}
+
+
 exit;
 
 # $Log$
+# Revision 1.126  2006/01/06 16:39:42  tipaul
+# synch'ing head and rel_2_2 (from 2.2.5, including npl templates)
+# Seems not to break too many things, but i'm probably wrong here.
+# at least, new features/bugfixes from 2.2.5 are here (tested on some features on my head local copy)
+#
+# - removing useless directories (koha-html and koha-plucene)
+#
+# Revision 1.125  2006/01/04 15:54:55  tipaul
+# utf8 is a : go for beta test in HEAD.
+# some explanations :
+# - updater/updatedatabase => will transform all tables in innoDB (not related to utf8, just to warn you) AND collate them in utf8 / utf8_general_ci. The SQL command is : ALTER TABLE tablename DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci.
+# - *-top.inc will show the pages in utf8
+# - THE HARD THING : for me, mysql-client and mysql-server were set up to communicate in iso8859-1, whatever the mysql collation ! Thus, pages were improperly shown, as datas were transmitted in iso8859-1 format ! After a full day of investigation, someone on usenet pointed "set NAMES 'utf8'" to explain that I wanted utf8. I could put this in my.cnf, but if I do that, ALL databases will "speak" in utf8, that's not what we want. Thus, I added a line in Context.pm : everytime a DB handle is opened, the communication is set to utf8.
+# - using marcxml field and no more the iso2709 raw marc biblioitems.marc field.
+#
+# Revision 1.124  2005/10/27 12:09:05  tipaul
+# new features for serial module :
+# - the last 5 issues are now shown, and their status can be changed (but not reverted to "waited", as there can be only one "waited")
+# - the library can create a "distribution list". this paper contains a list of borrowers (selected from the borrower list, or manually entered), and print it for a given issue. once printed, the sheet can be put on the issue and distributed to every reader on the list (one by one).
+#
+# Revision 1.123  2005/10/26 09:13:37  tipaul
+# big commit, still breaking things...
+#
+# * synch with rel_2_2. Probably the last non manual synch, as rel_2_2 should not be modified deeply.
+# * code cleaning (cleaning warnings from perl -w) continued
+#
+# Revision 1.122  2005/09/02 14:18:38  tipaul
+# new feature : image for itemtypes.
+#
+# * run updater/updatedatabase to create imageurl field in itemtypes.
+# * go to Koha >> parameters >> itemtypes >> modify (or add) an itemtype. You will see around 20 nice images to choose between (thanks to owen). If you prefer your own image, you also can type a complete url (http://www.myserver.lib/path/to/my/image.gif)
+# * go to OPAC, and search something. In the result list, you now have the picture instead of the text itemtype.
+#
+# Revision 1.121  2005/08/24 08:49:03  hdl
+# Adding a note field in serial table.
+# This will allow librarian to mention a note on a peculiar waiting serial number.
+#
+# Revision 1.120  2005/08/09 14:10:32  tipaul
+# 1st commit to go to zebra.
+# don't update your cvs if you want to have a working head...
+#
+# this commit contains :
+# * updater/updatedatabase : get rid with marc_* tables, but DON'T remove them. As a lot of things uses them, it would not be a good idea for instance to drop them. If you really want to play, you can rename them to test head without them but being still able to reintroduce them...
+# * Biblio.pm : modify MARCgetbiblio to find the raw marc record in biblioitems.marc field, not from marc_subfield_table, modify MARCfindframeworkcode to find frameworkcode in biblio.frameworkcode, modify some other subs to use biblio.biblionumber & get rid of bibid.
+# * other files : get rid of bibid and use biblionumber instead.
+#
+# What is broken :
+# * does not do anything on zebra yet.
+# * if you rename marc_subfield_table, you can't search anymore.
+# * you can view a biblio & bibliodetails, go to MARC editor, but NOT save any modif.
+# * don't try to add a biblio, it would add data poorly... (don't try to delete either, it may work, but that would be a surprise ;-) )
+#
+# IMPORTANT NOTE : you need MARC::XML package (http://search.cpan.org/~esummers/MARC-XML-0.7/lib/MARC/File/XML.pm), that requires a recent version of MARC::Record
+# Updatedatabase stores the iso2709 data in biblioitems.marc field & an xml version in biblioitems.marcxml Not sure we will keep it when releasing the stable version, but I think it's a good idea to have something readable in sql, at least for development stage.
+#
+# Revision 1.119  2005/08/04 16:07:58  tipaul
+# Synch really broke this script...
+#
+# Revision 1.118  2005/08/04 16:02:55  tipaul
+# oops... error in synch between 2.2 and head
+#
+# Revision 1.117  2005/08/04 14:24:39  tipaul
+# synch'ing 2.2 and head
+#
+# Revision 1.116  2005/08/04 08:55:54  tipaul
+# Letters / alert system, continuing...
+#
+# * adding a package Letters.pm, that manages Letters & alerts.
+# * adding feature : it's now possible to define a "letter" for any subscription created. If a letter is defined, users in OPAC can put an alert on the subscription. When an issue is marked "arrived", all users in the alert will recieve a mail (as defined in the "letter"). This last part (= send the mail) is not yet developped. (Should be done this week)
+# * adding feature : it's now possible to "put to an alert" in OPAC, for any serial subscription. The alert is stored in a new table, called alert. An alert can be put only if the librarian has activated them in subscription (and they activate it just by choosing a "letter" to sent to borrowers on new issues)
+# * adding feature : librarian can see in borrower detail which alerts they have put, and a user can see in opac-detail which alert they have put too.
+#
+# Note that the system should be generic enough to manage any type of alert.
+# I plan to extend it soon to virtual shelves : a borrower will be able to put an alert on a virtual shelf, to be warned when something is changed in the virtual shelf (mail being sent once a day by cron, or manually by the shelf owner. Anyway, a mail won't be sent on every change, users would be spammed by Koha ;-) )
+#
+# Revision 1.115  2005/08/02 16:15:34  tipaul
+# adding 2 fields to letter system :
+# * module (acquisition, catalogue...) : it will be usefull to show the librarian only letters he may be interested by.
+# * title, that will be used as mail subject.
+#
+# Revision 1.114  2005/07/28 15:10:13  tipaul
+# Introducing new "Letters" system : Letters will be used everytime you want to sent something to someone (through mail or paper). For example, sending a mail for overdues use letter that you can put as parameters. Sending a mail to a borrower when a suggestion is validated uses a letter too.
+# the letter table contains 3 fields :
+# * code => the code of the letter
+# * name => the complete name of the letter
+# * content => the complete text. It's a TEXT field type, so has no limits.
+#
+# My next goal now is to work on point 2-I "serial issue alert"
+# With this feature, in serials, a user can subscribe the "issue alert". For every issue arrived/missing, a mail is sent to all subscribers of this list. The mail warns the user that the issue is arrive or missing. Will be in head.
+# (see mail on koha-devel, 2005/04/07)
+#
+# The "serial issue alert" will be the 1st to use this letter system that probably needs some tweaking ;-)
+#
+# Once it will be stabilised default letters (in any languages) could be added during installer to help the library begin with this new feature.
+#
+# Revision 1.113  2005/07/28 08:38:41  tipaul
+# For instance, the return date does not rely on the borrower expiration date. A systempref will be added in Koha, to modify return date calculation schema :
+# * ReturnBeforeExpiry = yes => return date can't be after expiry date
+# * ReturnBeforeExpiry = no  => return date can be after expiry date
+#
 # Revision 1.112  2005/07/26 08:19:47  hdl
 # Adding IndependantBranches System preference variable in order to manage Branch independancy.
 #