@ -21,6 +21,7 @@ use strict;
use C4::Context ;
use C4::Koha ;
use C4::Biblio ;
use C4::Matcher ;
require Exporter ;
@ -52,6 +53,18 @@ use C4::ImportBatch;
AddImportBatch
AddBiblioToBatch
ModBiblioInBatch
BatchStageMarcRecords
BatchFindBibDuplicates
BatchCommitBibRecords
GetImportBatchStatus
SetImportBatchStatus
GetImportBatchOverlayAction
SetImportBatchOverlayAction
GetImportRecordOverlayStatus
SetImportRecordOverlayStatus
SetImportRecordMatches
) ;
= head2 GetZ3950BatchId
@ -140,12 +153,14 @@ sub AddImportBatch {
my $ import_record_id = AddBiblioToBatch ( $ batch_id , $ record_sequence , $ marc_record , $ encoding , $ z3950random ) ;
= back
= cut
sub AddBiblioToBatch {
my ( $ batch_id , $ record_sequence , $ marc_record , $ encoding , $ z3950random ) = @ _ ;
my $ import_record_id = _create_import_record ( $ batch_id , $ record_sequence , $ marc_record , 'bib' , $ encoding , $ z3950random ) ;
my $ import_record_id = _create_import_record ( $ batch_id , $ record_sequence , $ marc_record , 'biblio ' , $ encoding , $ z3950random ) ;
_add_biblio_fields ( $ import_record_id , $ marc_record ) ;
return $ import_record_id ;
}
@ -156,6 +171,8 @@ sub AddBiblioToBatch {
ModBiblioInBatch ( $ import_record_id , $ marc_record ) ;
= back
= cut
sub ModBiblioInBatch {
@ -166,6 +183,326 @@ sub ModBiblioInBatch {
}
= head2 BatchStageMarcRecords
= over 4
( $ batch_id , $ num_records , @ invalid_records ) = BatchStageMarcRecords ( $ marc_flavor , $ marc_records , $ file_name ,
$ comments , $ branch_code , $ leave_as_staging ) ;
= back
= cut
sub BatchStageMarcRecords {
my ( $ marc_flavor , $ marc_records , $ file_name , $ comments , $ branch_code , $ leave_as_staging ) = @ _ ;
my $ batch_id = AddImportBatch ( 'create_new' , 'staging' , 'batch' , $ file_name , $ comments ) ;
my @ invalid_records = ( ) ;
my $ num_valid = 0 ;
# FIXME - for now, we're dealing only with bibs
my $ rec_num = 0 ;
foreach my $ marc_blob ( split ( /\x1D/ , $ marc_records ) ) {
$ rec_num + + ;
my $ marc_record = FixEncoding ( $ marc_blob , "\x1D" ) ;
my $ import_record_id ;
if ( scalar ( $ marc_record - > fields ( ) ) == 0 ) {
push @ invalid_records , $ marc_blob ;
} else {
$ num_valid + + ;
$ import_record_id = AddBiblioToBatch ( $ batch_id , $ rec_num , $ marc_record , $ marc_flavor , int ( rand ( 99999 ) ) ) ;
}
}
unless ( $ leave_as_staging ) {
SetImportBatchStatus ( $ batch_id , 'staged' ) ;
}
# FIXME batch_code, number of bibs, number of items
return ( $ batch_id , $ num_valid , @ invalid_records ) ;
}
= head2 BatchFindBibDuplicates
= over4
my $ num_with_matches = BatchFindBibDuplicates ( $ batch_id , $ matcher , $ max_matches ) ;
= back
Goes through the records loaded in the batch and attempts to
find duplicates for each one . Sets the overlay action to
'replace' if it was 'create_new' , and sets the overlay status
of each record to 'no_match' or 'auto_match' as appropriate .
The $ max_matches parameter is optional ; if it is not supplied ,
it defaults to 10 .
= cut
sub BatchFindBibDuplicates {
my $ batch_id = shift ;
my $ matcher = shift ;
my $ max_matches = @ _ ? shift : 10 ;
my $ dbh = C4::Context - > dbh ;
my $ old_overlay_action = GetImportBatchOverlayAction ( $ batch_id ) ;
if ( $ old_overlay_action eq "create_new" ) {
SetImportBatchOverlayAction ( $ batch_id , 'replace' ) ;
}
my $ sth = $ dbh - > prepare ( " SELECT import_record_id , marc
FROM import_records
JOIN import_biblios USING ( import_record_id )
WHERE import_batch_id = ? " ) ;
$ sth - > execute ( $ batch_id ) ;
my $ num_with_matches = 0 ;
while ( my $ rowref = $ sth - > fetchrow_hashref ) {
my $ marc_record = MARC::Record - > new_from_usmarc ( $ rowref - > { 'marc' } ) ;
my @ matches = $ matcher - > get_matches ( $ marc_record , $ max_matches ) ;
if ( scalar ( @ matches ) > 0 ) {
$ num_with_matches + + ;
SetImportRecordMatches ( $ rowref - > { 'import_record_id' } , @ matches ) ;
SetImportRecordOverlayStatus ( $ rowref - > { 'import_record_id' } , 'auto_match' ) ;
} else {
SetImportRecordOverlayStatus ( $ rowref - > { 'import_record_id' } , 'no_match' ) ;
}
}
$ sth - > finish ( ) ;
return $ num_with_matches ;
}
= head2 BatchCommitBibRecords
= over 4
my ( $ num_added , $ num_updated , $ num_ignored ) = BatchCommitBibRecords ( $ batch_id ) ;
= back
= cut
sub BatchCommitBibRecords {
my $ batch_id = shift ;
my $ num_added = 0 ;
my $ num_updated = 0 ;
my $ num_ignored = 0 ;
# commit (i.e., save, all records in the batch)
# FIXME biblio only at the moment
SetImportBatchStatus ( 'importing' ) ;
my $ overlay_action = GetImportBatchOverlayAction ( $ batch_id ) ;
my $ dbh = C4::Context - > dbh ;
my $ sth = $ dbh - > prepare ( " SELECT import_record_id , status , overlay_status , marc
FROM import_records
JOIN import_biblios USING ( import_record_id )
WHERE import_batch_id = ? " ) ;
$ sth - > execute ( $ batch_id ) ;
while ( my $ rowref = $ sth - > fetchrow_hashref ) {
if ( $ rowref - > { 'status' } eq 'error' or $ rowref - > { 'status' } eq 'imported' ) {
$ num_ignored + + ;
}
my $ marc_record = MARC::Record - > new_from_usmarc ( $ rowref - > { 'marc' } ) ;
if ( $ overlay_action eq 'create_new' or
( $ overlay_action eq 'replace' and $ rowref - > { 'overlay_status' } eq 'no_match' ) ) {
$ num_added + + ;
my ( $ biblionumber , $ biblioitemnumber ) = AddBiblio ( $ marc_record , '' ) ;
} else {
$ num_updated + + ;
my $ biblionumber = GetBestRecordMatch ( $ rowref - > { 'import_record_id' } ) ;
my ( $ count , $ oldbiblio ) = GetBiblio ( $ biblionumber ) ;
my $ oldxml = GetXmlBiblio ( $ biblionumber ) ;
ModBiblio ( $ marc_record , $ biblionumber , $ oldbiblio - > { 'frameworkcode' } ) ;
my $ dbh = C4::Context - > dbh ;
my $ sth = $ dbh - > prepare ( "UPDATE import_records SET marcxml_old = ? WHERE import_record_id = ?" ) ;
$ sth - > execute ( $ oldxml , $ rowref - > { 'import_record_id' } ) ;
$ sth - > finish ( ) ;
SetImportRecordOverlayStatus ( $ rowref - > { 'import_record_id' } , 'match_applied' ) ;
}
}
$ sth - > finish ( ) ;
SetImportBatchStatus ( 'imported' ) ;
return ( $ num_added , $ num_updated , $ num_ignored ) ;
}
= head2 GetBestRecordMatch
= over 4
my $ record_id = GetBestRecordMatch ( $ import_record_id ) ;
= back
= cut
sub GetBestRecordMatch {
my ( $ import_record_id ) = @ _ ;
my $ dbh = C4::Context - > dbh ;
my $ sth = $ dbh - > prepare ( " SELECT candidate_match_id
FROM import_record_matches
WHERE import_record_id = ?
ORDER BY score DESC , candidate_match_id DESC " ) ;
$ sth - > execute ( $ import_record_id ) ;
my ( $ record_id ) = $ sth - > fetchrow_array ( ) ;
$ sth - > finish ( ) ;
return $ record_id ;
}
= head2 GetImportBatchStatus
= over 4
my $ status = GetImportBatchStatus ( $ batch_id ) ;
= back
= cut
sub GetImportBatchStatus {
my ( $ batch_id ) = @ _ ;
my $ dbh = C4::Context - > dbh ;
my $ sth = $ dbh - > prepare ( "SELECT import_status FROM import_batches WHERE batch_id = ?" ) ;
$ sth - > execute ( $ batch_id ) ;
my ( $ status ) = $ sth - > fetchrow_array ( ) ;
$ sth - > finish ( ) ;
return ;
}
= head2 SetImportBatchStatus
= over 4
SetImportBatchStatus ( $ batch_id , $ new_status ) ;
= back
= cut
sub SetImportBatchStatus {
my ( $ batch_id , $ new_status ) = @ _ ;
my $ dbh = C4::Context - > dbh ;
my $ sth = $ dbh - > prepare ( "UPDATE import_batches SET import_status = ? WHERE import_batch_id = ?" ) ;
$ sth - > execute ( $ new_status , $ batch_id ) ;
$ sth - > finish ( ) ;
}
= head2 GetImportBatchOverlayAction
= over 4
my $ overlay_action = GetImportBatchOverlayAction ( $ batch_id ) ;
= back
= cut
sub GetImportBatchOverlayAction {
my ( $ batch_id ) = @ _ ;
my $ dbh = C4::Context - > dbh ;
my $ sth = $ dbh - > prepare ( "SELECT overlay_action FROM import_batches WHERE import_batch_id = ?" ) ;
$ sth - > execute ( $ batch_id ) ;
my ( $ overlay_action ) = $ sth - > fetchrow_array ( ) ;
$ sth - > finish ( ) ;
return $ overlay_action ;
}
= head2 SetImportBatchOverlayAction
= over 4
SetImportBatchOverlayAction ( $ batch_id , $ new_overlay_action ) ;
= back
= cut
sub SetImportBatchOverlayAction {
my ( $ batch_id , $ new_overlay_action ) = @ _ ;
my $ dbh = C4::Context - > dbh ;
my $ sth = $ dbh - > prepare ( "UPDATE import_batches SET overlay_action = ? WHERE import_batch_id = ?" ) ;
$ sth - > execute ( $ new_overlay_action , $ batch_id ) ;
$ sth - > finish ( ) ;
}
= head2 GetImportRecordOverlayStatus
= over 4
my $ overlay_status = GetImportRecordOverlayStatus ( $ import_record_id ) ;
= back
= cut
sub GetImportRecordOverlayStatus {
my ( $ import_record_id ) = @ _ ;
my $ dbh = C4::Context - > dbh ;
my $ sth = $ dbh - > prepare ( "SELECT overlay_status FROM import_records WHERE import_record_id = ?" ) ;
$ sth - > execute ( $ import_record_id ) ;
my ( $ overlay_status ) = $ sth - > fetchrow_array ( ) ;
$ sth - > finish ( ) ;
return $ overlay_status ;
}
= head2 SetImportRecordOverlayStatus
= over 4
SetImportRecordOverlayStatus ( $ import_record_id , $ new_overlay_status ) ;
= back
= cut
sub SetImportRecordOverlayStatus {
my ( $ import_record_id , $ new_overlay_status ) = @ _ ;
my $ dbh = C4::Context - > dbh ;
my $ sth = $ dbh - > prepare ( "UPDATE import_records SET overlay_status = ? WHERE import_record_id = ?" ) ;
$ sth - > execute ( $ new_overlay_status , $ import_record_id ) ;
$ sth - > finish ( ) ;
}
= head2 SetImportRecordMatches
= over 4
SetImportRecordMatches ( $ import_record_id , @ matches ) ;
= back
= cut
sub SetImportRecordMatches {
my $ import_record_id = shift ;
my @ matches = @ _ ;
my $ dbh = C4::Context - > dbh ;
my $ delsth = $ dbh - > prepare ( "DELETE FROM import_record_matches WHERE import_record_id = ?" ) ;
$ delsth - > execute ( $ import_record_id ) ;
$ delsth - > finish ( ) ;
my $ sth = $ dbh - > prepare ( " INSERT INTO import_record_matches ( import_record_id , candidate_match_id , score )
VALUES ( ? , ? , ? ) " ) ;
foreach my $ match ( @ matches ) {
$ sth - > execute ( $ import_record_id , $ match - > { 'record_id' } , $ match - > { 'score' } ) ;
}
}
# internal functions
sub _create_import_record {