Bug 25898: Prohibit indirect object notation
[koha.git] / misc / maintenance / UNIMARC_sync_date_created_with_marc_biblio.pl
blob5e0cd37fcc4974375e6529bb8fb78113ac88780b
1 #!/usr/bin/perl
3 # This script should be used only with UNIMARC flavour
4 # It is designed to report some missing information from biblio
5 # table into marc data
7 use strict;
8 use warnings;
10 BEGIN {
11 use FindBin;
12 eval { require "$FindBin::Bin/../kohalib.pl" };
15 use Koha::Script;
16 use C4::Biblio;
17 use Getopt::Long;
19 sub _read_marc_code {
20 my $input = shift;
21 my ( $field, $subfield );
22 if ( $input =~ /^(\d{3})$/ ) {
23 $field = $1;
25 elsif ( $input =~ /^(\d{3})(\w)$/ ) {
26 $field = $1;
27 $subfield = $2;
29 return ( $field, $subfield );
32 my ( $run, $help, $verbose, $where, $date_created_marc, $date_modified_marc );
33 GetOptions(
34 'help|h' => \$help,
35 'verbose|v' => \$verbose,
36 'run' => \$run,
37 'where:s' => \$where,
38 'date-created-marc|c:s' => \$date_created_marc,
39 'date-modified-marc|m:s' => \$date_modified_marc,
41 my $debug = $ENV{DEBUG};
42 $verbose = 1 if $debug;
44 # display help ?
45 if ($help) {
46 print_usage();
47 exit 0;
50 $verbose and print "================================\n";
52 # date created MARC field/subfield
53 $date_created_marc = '099c' unless $date_created_marc;
54 my ( $c_field, $c_subfield ) = _read_marc_code($date_created_marc);
55 die "date-created-marc '$date_created_marc' is not correct." unless $c_field;
56 die "date-created-marc field is greated that 009, it should have a subfield."
57 if ( $c_field > 9 && !defined $c_subfield );
58 die "date-created-marc field is lower that 010, it should not have a subfield."
59 if ( $c_field < 10 && defined $c_subfield );
60 if ($verbose) {
61 print "Date created on $c_field";
62 print $c_subfield if defined $c_subfield; # use of defined to allow 0
63 print "\n";
66 # date last modified MARC field/subfield
67 $date_modified_marc = '099d' unless $date_modified_marc;
68 my ( $m_field, $m_subfield ) = _read_marc_code($date_modified_marc);
69 die "date-modified-marc '$date_modified_marc' is not correct." unless $m_field;
70 die "date-modified-marc field is greated that 009, it should have a subfield."
71 if ( $m_field > 9 && !defined $m_subfield );
72 die "date-modified-marc field is lower that 010, it should not have a subfield."
73 if ( $m_field < 10 && defined $m_subfield );
74 die
75 "When date-created-marc and date-modified-marc are on same field, they should have distinct subfields"
76 if ( $c_field eq $m_field )
77 && ( !defined $c_subfield
78 || !defined $m_subfield
79 || $c_subfield eq $m_subfield );
80 if ($verbose) {
81 print "Date last modified on $m_field";
82 print $m_subfield if defined $m_subfield; # use of defined to allow 0
83 print "\n";
86 my $dbh;
87 my $sth_prepared;
89 sub updateMarc {
90 my $id = shift;
91 my $biblio = GetMarcBiblio({ biblionumber => $id });
93 unless ($biblio) {
94 $debug and warn '[ERROR] GetMarcBiblio did not return any biblio.';
95 return;
98 my $c_marc_field = $biblio->field($c_field);
99 my $m_marc_field = $biblio->field($m_field);
101 my $c_marc_value;
102 if ($c_marc_field) {
103 $c_marc_value =
104 defined $c_subfield
105 ? $c_marc_field->subfield($c_subfield)
106 : $c_marc_field->data();
108 $c_marc_value = '' unless defined $c_marc_value;
110 my $m_marc_value;
111 if ($m_marc_field) {
112 $m_marc_value =
113 defined $m_subfield
114 ? $m_marc_field->subfield($m_subfield)
115 : $m_marc_field->data();
117 $m_marc_value ||= '';
119 $sth_prepared = $dbh->prepare(
121 SELECT
122 DATE_FORMAT(datecreated,'%Y-%m-%d') AS datecreatediso,
123 DATE_FORMAT(timestamp,'%Y-%m-%d') AS datemodifiediso,
124 frameworkcode
125 FROM biblio
126 WHERE biblionumber = ?
128 ) unless $sth_prepared;
129 $sth_prepared->execute($id);
130 my $bibliorow = $sth_prepared->fetchrow_hashref;
131 my $frameworkcode = $bibliorow->{'frameworkcode'};
132 my $c_db_value = $bibliorow->{'datecreatediso'} || '';
133 my $m_db_value = $bibliorow->{'datemodifiediso'} || '';
135 # do nothing if already sync
136 return if ( $c_marc_value eq $c_db_value && $m_marc_value eq $m_db_value );
138 # do apply to database ?
139 return 1 unless $run;
141 # update MARC record
143 # date created field
144 unless ($c_marc_field) {
145 if ( defined $c_subfield ) {
146 $biblio->add_fields(
147 MARC::Field->new(
148 $c_field, ' ', ' ', $c_subfield => $c_db_value
152 else {
153 $biblio->add_fields( MARC::Field->new( $c_field, $c_db_value ) );
155 $debug and warn "[WARN] $c_field did not exist.";
156 $c_marc_field = $biblio->field($c_field);
158 # when on same field
159 if ( $m_field eq $c_field ) {
160 $m_marc_field = $c_marc_field;
163 else {
164 if ( defined $c_subfield ) {
165 $c_marc_field->update( $c_subfield, $c_db_value );
167 else {
168 $c_marc_field->update($c_db_value);
172 # date last modified field
173 unless ($m_marc_field) {
174 if ( defined $m_subfield ) {
175 $biblio->add_fields(
176 MARC::Field->new(
177 $m_field, ' ', ' ', $m_subfield => $m_db_value
181 else {
182 $biblio->add_fields( MARC::Field->new( $m_field, $m_db_value ) );
185 $debug and warn "[WARN] $m_field did not exist.";
186 $m_marc_field = $biblio->field($m_field);
188 else {
189 if ( defined $m_subfield ) {
190 $m_marc_field->update( $m_subfield, $m_db_value );
192 else {
193 $m_marc_field->update($m_db_value);
197 # apply to databse
198 if ( &ModBiblio( $biblio, $id, $frameworkcode ) ) {
199 return 1;
202 $debug and warn '[ERROR] ModBiblio failed.';
203 return;
206 sub process {
208 $dbh = C4::Context->dbh;
209 my $mod_count = 0;
211 my $query = q{
212 SELECT biblionumber
213 FROM biblio
214 JOIN biblioitems USING (biblionumber)
216 $query .= qq{ WHERE $where} if $where;
217 my $sth = $dbh->prepare($query);
218 $sth->execute();
220 $verbose and print "Number of concerned biblios: " . $sth->rows . "\n";
222 while ( my $biblios = $sth->fetchrow_hashref ) {
223 $verbose and print 'Bib ' . $biblios->{'biblionumber'} . ':';
224 my $ret = updateMarc( $biblios->{'biblionumber'} );
225 if ($ret) {
226 $verbose and print 'modified';
227 $mod_count++;
229 $verbose and print "\n";
232 $verbose and print "Number of modified biblios: " . $mod_count . "\n";
235 if ( lc( C4::Context->preference('marcflavour') ) eq "unimarc" ) {
236 $verbose
237 and !$run
238 and print "*** Not in run mode, modifications will not be applyed ***\n";
240 $verbose and print "================================\n";
241 process();
243 else {
244 print
245 "This script is UNIMARC only and should be used only on UNIMARC databases\n";
248 sub print_usage {
249 print <<_USAGE_;
250 Synchronizes date created and date last modified from biblio table to MARC data.
251 Does not update biblio if dates are already synchronized.
252 UNIMARC specific.
254 Parameters:
255 --help or -h show this message
256 --verbose or -v verbose logging
257 --run run the command else modifications will not be applied to database
258 --where (optional) use this to limit execution to some biblios :
259 write a SQL where clause using biblio and/or biblioitems fields
260 --date-created-marc or c (optional) date created MARC field and optional subfield,
261 099c by default
262 --date-modified-marc or m (optional) date last modified MARC field and optional subfield,
263 099d by default
264 _USAGE_