View | Details | Raw Unified | Return to bug 11395
Collapse All | Expand All

(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/batch_record_modification.tt (+237 lines)
Line 0 Link Here
1
[% PROCESS 'authorities-search-results.inc' %]
2
[% INCLUDE 'doc-head-open.inc' %]
3
<title>Koha &rsaquo; Tools &rsaquo; Batch record modification</title>
4
[% INCLUDE 'doc-head-close.inc' %]
5
[% INCLUDE 'greybox.inc' %]
6
<link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" />
7
[% INCLUDE 'datatables.inc' %]
8
<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.checkboxes.min.js"></script>
9
<script type="text/javascript" src="[% themelang %]/js/background-job-progressbar.js"></script>
10
<script type="text/javascript">
11
//<![CDATA[
12
$(document).ready(function() {
13
  $("#selectall").click(function(e){
14
    e.preventDefault();
15
    $(".records").checkCheckboxes();
16
  });
17
  $("#clearall").click(function(e){
18
    e.preventDefault();
19
    $(".records").unCheckCheckboxes();
20
  });
21
  $("#selectall").click();
22
23
  $("table#biblios").dataTable($.extend(true, {}, dataTablesDefaults, {
24
    "aoColumnDefs": [
25
      { "aTargets": [ 0, 3 ], "bSortable": false, "bSearchable": false },
26
      { "aTargets": [ 1 ], "sType": "num-html" }
27
    ],
28
    "sDom": 't',
29
    "aaSorting": [],
30
    "bPaginate": false
31
  }));
32
33
  $("table#authorities").dataTable($.extend(true, {}, dataTablesDefaults, {
34
    "aoColumnDefs": [
35
      { "aTargets": [ 0, 3 ], "bSortable": false, "bSearchable": false },
36
      { "aTargets": [ 1 ], "sType": "num-html" }
37
    ],
38
    "sDom": 't',
39
    "aaSorting": [],
40
    "bPaginate": false
41
  }));
42
43
  $("#mainformsubmit").click(function(){
44
    return submitBackgroundJob(document.getElementById("process"));
45
  });
46
47
});
48
//]]>
49
</script>
50
</head>
51
<body id="tools_batch_record_modification" class="tools">
52
[% INCLUDE 'header.inc' %]
53
[% INCLUDE 'cat-search.inc' %]
54
55
<div id="breadcrumbs">
56
    <a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo;
57
    <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> &rsaquo;
58
    <a href="/cgi-bin/koha/tools/batch_record_modification.pl">Batch record modification</a>
59
</div>
60
61
<div id="doc3" class="yui-t2">
62
<div id="bd">
63
<div id="yui-main">
64
<div class="yui-b">
65
  <h1>Batch record modification</h1>
66
  [% FOREACH message IN messages %]
67
    [% IF message.type == 'success' %]
68
      <div class="dialog message">
69
    [% ELSIF message.type == 'warning' %]
70
      <div class="dialog alert">
71
    [% ELSIF message.type == 'error' %]
72
      <div class="dialog error" style="margin:auto;">
73
    [% END %]
74
                  <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% biblio.biblionumber %]">[% biblio.title %]</a></td>
75
    [% IF message.code == 'no_action_defined_for_the_template' %]
76
      The selected template (id=[% message.mmtid%]) does not exist or no action is defined.
77
    [% ELSIF message.code == 'biblio_not_exists' %]
78
      The biblionumber [% message.biblionumber %] does not exist in the database.
79
    [% ELSIF message.code == 'authority_not_exists' %]
80
      The authority id [% message.authid %] does not exist in the database.
81
    [% ELSIF message.code == 'biblio_not_modified' %]
82
      The biblio <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% message.biblionumber %]">[% message.biblionumber %]</a> has not been modified. An error occurred on modifying it.
83
    [% ELSIF message.code == 'authority_not_modified' %]
84
      The authority <a href="/cgi-bin/koha/authorities/detail.pl?authid=[% message.authid %]">[% message.authid %]</a> has not been modified. An error occurred on modifying it.
85
    [% ELSIF message.code == 'biblio_modified' %]
86
      The biblio <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% message.biblionumber %]">[% message.biblionumber %]</a> has successfully been modified.
87
    [% ELSIF message.code == 'authority_modified' %]
88
      The authority <a href="/cgi-bin/koha/authorities/detail.pl?authid=[% message.authid %]">[% message.authid %]</a> has successfully been modified.
89
    [% END %]
90
    [% IF message.error %]
91
      (The error was: [% message.error%], see the Koha logfile for more information).
92
    [% END %]
93
    </div>
94
  [% END %]
95
  [% IF view == 'form' %]
96
    <form method="post" enctype="multipart/form-data" action="/cgi-bin/koha/tools/batch_record_modification.pl">
97
      <fieldset class="rows">
98
        <legend>Record type</legend>
99
        <ol>
100
          <li><label for="biblio_type">Biblios: </label><input type="radio" name="recordtype" value="biblio" id="biblio_type" checked="checked" /></li>
101
          <li><label for="authority_type">Authorities: </label><input type="radio" name="recordtype" value="authority" id="authority_type" /></li>
102
        </ol>
103
      </fieldset>
104
      <fieldset class="rows">
105
        <legend>Use a file</legend>
106
        <ol>
107
          <li><label for="uploadfile">File: </label> <input type="file" id="uploadfile" name="uploadfile" /></li>
108
        </ol>
109
      </fieldset>
110
      <fieldset class="rows">
111
        <legend>Or enter a list of record numbers</legend>
112
        <ol>
113
          <li>
114
            <label for="recordnumber_list">Record number list (one per line): </label>
115
            <textarea rows="10" cols="30" id="recordnumber_list" name="recordnumber_list"></textarea>
116
          </li>
117
        </ol>
118
      </fieldset>
119
      <fieldset class="rows">
120
        <legend>Use MARC Modification Template:</legend>
121
        <ol>
122
          <li>
123
            <label for="marc_modification_template_id" class="required">Modify record using the following template: </label>
124
            <select name="marc_modification_template_id" id="marc_modification_template_id" required="required">
125
              <option value="">Select a template</option>
126
                [% FOREACH mmt IN MarcModificationTemplatesLoop %]
127
                  <option value="[% mmt.template_id %]">[% mmt.name %]</option>
128
                [% END %]
129
            </select>
130
          </li>
131
        </ol>
132
      </fieldset>
133
      <fieldset class="action">
134
        <input type="hidden" name="op" value="list" />
135
        <input type="submit" value="Continue" class="button" />
136
        <a class="cancel" href="/cgi-bin/koha/tools/tools-home.pl">Cancel</a>
137
      </fieldset>
138
    </form>
139
  [% ELSIF view == 'list' %]
140
    [% IF records %]
141
      [% IF recordtype == 'biblio' %]
142
        <div id="toolbar">
143
          <a id="selectall" href="#">Select All</a>
144
          | <a id="clearall" href="#">Clear All</a>
145
        </div>
146
        <form action="/cgi-bin/koha/tools/batch_record_modification.pl" method="post" id="process">
147
          <table id="biblios" class="records">
148
            <thead>
149
              <tr>
150
                <th></th>
151
                <th>Biblionumber</th>
152
                <th>Title</th>
153
                <th>Preview</th>
154
              </tr>
155
            </thead>
156
            <tbody>
157
              [% FOR biblio IN records %]
158
                <tr>
159
                  <td><input type="checkbox" name="record_id" value="[% biblio.biblionumber %]" data-items="[% biblio.itemnumbers.size %]" data-issues="[% biblio.issues_count %]" data-reserves="[% biblio.reserves.size %]" /></td>
160
                  <td>[% biblio.biblionumber %]</td>
161
                  <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% biblio.biblionumber %]">[% biblio.title %]</a></td>
162
                  <td><a href="/cgi-bin/koha/svc/records/preview?record_type=biblio&record_id=[% biblio.biblionumber %]&mmtid=[% mmtid %]" title="MARC preview" rel="gb_page_center[600,500]">Preview MARC</a>
163
164
                </tr>
165
              [% END %]
166
            </tbody>
167
          </table>
168
          <div class="note">Reminder: this action will modify all selected biblios!</div>
169
      [% ELSE %]
170
        <div id="toolbar">
171
          <a id="selectall" href="#">Select All</a>
172
          | <a id="clearall" href="#">Clear All</a>
173
        </div>
174
        <form action="/cgi-bin/koha/tools/batch_record_modification.pl" method="post" id="process">
175
          <table id="authorities" class="records">
176
            <thead>
177
              <tr>
178
                <th></th>
179
                <th>Authid</th>
180
                <th>Summary</th>
181
                <th>Preview</th>
182
              </tr>
183
            </thead>
184
            <tbody>
185
              [% FOR authority IN records %]
186
                <tr>
187
                  <td><input type="checkbox" name="record_id" value="[% authority.authid %]" data-usage="[% authority.count_usage %]" /></td>
188
                  <td><a href="/cgi-bin/koha/authorities/detail.pl?authid=[% authority.authid %]">[% authority.authid %]</a></td>
189
                  <td>[% PROCESS authresult summary=authority.summary %]</td>
190
                  <td><a href="/cgi-bin/koha/svc/records/preview?record_type=authority&record_id=[% authority.authid %]&mmtid=[% mmtid %]" title="MARC preview" rel="gb_page_center[600,500]">Preview MARC</a>
191
                </tr>
192
              [% END %]
193
            </tbody>
194
          </table>
195
          <div class="note">Reminder: this action will modify all selected authorities!</div>
196
      [% END %]
197
        <fieldset class="action">
198
          <input type="hidden" name="op" value="modify" />
199
          <input type="hidden" name="recordtype" value="[% recordtype %]" />
200
          <input type="button" id="mainformsubmit" value="Modify selected records" class="button" />
201
          <input type="hidden" name="runinbackground" id="runinbackground" value="" />
202
          <input type="hidden" name="completedJobID" id="completedJobID" value="" />
203
          <input type="hidden" name="marc_modification_template_id" value="[% mmtid %]" />
204
          <a class="cancel" href="/cgi-bin/koha/tools/batch_record_modification.pl">Cancel</a>
205
        </fieldset>
206
        <div id="jobpanel">
207
          <div id="jobstatus">Job progress: <div id="jobprogress"></div> <span id="jobprogresspercent">0</span>%</div>
208
          <div id="jobfailed"></div>
209
        </div>
210
      </form>
211
    [% ELSE %]
212
      There is no record ids defined.
213
    [% END %]
214
  [% ELSIF view == 'report' %]
215
    [% IF report.total_records == report.total_success %]
216
      All records have successfully been modified!
217
    [% ELSE %]
218
      [% report.total_success %] / [% report.total_records %] records have successfully been modified.
219
      Some errors occurred.
220
    [% END %]
221
    <p><a href="/cgi-bin/koha/tools/batch_record_modification.pl" title="New batch record modification">New batch record modification</a></p>
222
  [% ELSIF view == 'errors' %]
223
    [% FOR error IN errors %]
224
      [% IF error == 'no_template_defined' %]
225
        No MARC modification template is defined. You have <a href="/cgi-bin/koha/tools/marc_modification_templates.pl">to create</a> at least one template for using this tool.
226
      [% END %]
227
    [% END %]
228
  [% ELSE %]
229
    No action defined for the template.
230
  [% END %]
231
</div>
232
</div>
233
<div class="yui-b">
234
  [% INCLUDE 'tools-menu.inc' %]
235
</div>
236
</div>
237
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/tools/batch_record_modification.pl (-1 / +261 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# This file is part of Koha.
4
#
5
# Copyright 2013 BibLibre
6
#
7
# Koha is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as
9
# published by the Free Software Foundation; either version 3
10
# of the License, or (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General
18
# Public License along with Koha; if not, see
19
# <http://www.gnu.org/licenses>
20
21
use Modern::Perl;
22
23
use CGI;
24
use List::MoreUtils qw( uniq );
25
26
use C4::Auth qw( get_template_and_user );
27
use C4::Output qw( output_html_with_http_headers );
28
use C4::AuthoritiesMarc qw( BuildSummary GetAuthTypeCode ModAuthority );
29
use C4::BackgroundJob;
30
use C4::Biblio qw( GetMarcBiblio ModBiblio );
31
use C4::MarcModificationTemplates qw( GetModificationTemplateActions GetModificationTemplates ModifyRecordWithTemplate );
32
use Koha::Authority;
33
34
my $input = new CGI;
35
our $dbh = C4::Context->dbh;
36
my $op = $input->param('op') // q|form|;
37
my $recordtype = $input->param('recordtype') // 'biblio';
38
my $mmtid = $input->param('marc_modification_template_id');
39
40
my ( @messages );
41
42
my ( $template, $loggedinuser, $cookie ) = get_template_and_user({
43
        template_name => 'tools/batch_record_modification.tt',
44
        query => $input,
45
        type => "intranet",
46
        authnotrequired => 0,
47
        flagsrequired => { tools => 'biblio_batchmod' },
48
});
49
50
51
my $sessionID = $input->cookie("CGISESSID");
52
53
my $runinbackground = $input->param('runinbackground');
54
my $completedJobID = $input->param('completedJobID');
55
if ( $completedJobID ) {
56
    my $job = C4::BackgroundJob->fetch($sessionID, $completedJobID);
57
    my $report = $job->get('report');
58
    my $messages = $job->get('messages');
59
    $template->param(
60
        report => $report,
61
        messages => $messages,
62
        view => 'report',
63
    );
64
    output_html_with_http_headers $input, $cookie, $template->output;
65
    exit;
66
}
67
68
my @templates = GetModificationTemplates();
69
unless ( @templates ) {
70
    $op = 'error';
71
    $template->param(
72
        view => 'errors',
73
        errors => ['no_template_defined'],
74
    );
75
    output_html_with_http_headers $input, $cookie, $template->output;
76
}
77
78
if ( $mmtid ) {
79
    my @actions = GetModificationTemplateActions( $mmtid );
80
    unless ( @actions ) {
81
        $op = 'form';
82
        push @messages, {
83
            type => 'error',
84
            code => 'no_action_defined_for_the_template',
85
            mmtid => $mmtid,
86
        };
87
    }
88
}
89
90
if ( $op eq 'form' ) {
91
    # Display the form
92
    $template->param(
93
        view => 'form',
94
        MarcModificationTemplatesLoop => \@templates,
95
    );
96
} elsif ( $op eq 'list' ) {
97
    # List all records to process
98
    my ( @records, @record_ids );
99
    if ( my $bib_list = $input->param('bib_list') ) {
100
        # Come from the basket
101
        @record_ids = split /\//, $bib_list;
102
        $recordtype = 'biblio';
103
    } elsif ( my $uploadfile = $input->param('uploadfile') ) {
104
        # A file of id is given
105
        while ( my $content = <$uploadfile> ) {
106
            next unless $content;
107
            $content =~ s/[\r\n]*$//;
108
            push @record_ids, $content if $content;
109
        }
110
    } else {
111
        # The user enters manually the list of id
112
        push @record_ids, split( /\s\n/, $input->param('recordnumber_list') );
113
    }
114
115
    for my $record_id ( uniq @record_ids ) {
116
        if ( $recordtype eq 'biblio' ) {
117
            # Retrieve biblio information
118
            my $biblio = C4::Biblio::GetBiblio( $record_id );
119
            unless ( $biblio ) {
120
                push @messages, {
121
                    type => 'warning',
122
                    code => 'biblio_not_exists',
123
                    biblionumber => $record_id,
124
                };
125
                next;
126
            }
127
            push @records, $biblio;
128
        } else {
129
            # Retrieve authority information
130
            my $authority = Koha::Authority->get_from_authid( $record_id );
131
            unless ( $authority ) {
132
                push @messages, {
133
                    type => 'warning',
134
                    code => 'authority_not_exists',
135
                    authid => $record_id,
136
                };
137
                next;
138
            }
139
140
            push @records, {
141
                authid => $record_id,
142
                summary => C4::AuthoritiesMarc::BuildSummary( $authority->record, $record_id ),
143
            };
144
        }
145
    }
146
    $template->param(
147
        records => \@records,
148
        mmtid => $mmtid,
149
        view => 'list',
150
    );
151
} elsif ( $op eq 'modify' ) {
152
    # We want to modify selected records!
153
    my @record_ids = $input->param('record_id');
154
155
    my ( $job );
156
    if ( $runinbackground ) {
157
        my $job_size = scalar( @record_ids );
158
        $job = C4::BackgroundJob->new( $sessionID, "FIXME", $ENV{SCRIPT_NAME}, $job_size );
159
        my $job_id = $job->id;
160
        if (my $pid = fork) {
161
            $dbh->{InactiveDestroy}  = 1;
162
163
            my $reply = CGI->new("");
164
            print $reply->header(-type => 'text/html');
165
            print '{"jobID":"' . $job_id . '"}';
166
            exit 0;
167
        } elsif (defined $pid) {
168
            close STDOUT;
169
            close STDERR;
170
        } else {
171
            warn "fork failed while attempting to run $ENV{'SCRIPT_NAME'} as a background job";
172
            exit 0;
173
        }
174
    }
175
176
    my $report = {
177
        total_records => 0,
178
        total_success => 0,
179
    };
180
    my $progress = 0;
181
    $dbh->{RaiseError} = 1;
182
    RECORD_IDS: for my $record_id ( sort { $a <=> $b } @record_ids ) {
183
        $report->{total_records}++;
184
        next unless $record_id;
185
186
        if ( $recordtype eq 'biblio' ) {
187
            # Biblios
188
            my $biblionumber = $record_id;
189
190
            # Finally, modify the biblio
191
            my $error = eval {
192
                my $record = GetMarcBiblio( $biblionumber );
193
                ModifyRecordWithTemplate( $mmtid, $record );
194
                ModBiblio( $record, $biblionumber );
195
            };
196
            if ( $error and $error != 1 or $@ ) { # ModBiblio returns 1 if everything as gone well
197
                push @messages, {
198
                    type => 'error',
199
                    code => 'biblio_not_modified',
200
                    biblionumber => $biblionumber,
201
                    error => ($@ ? $@ : $error),
202
                };
203
            } else {
204
                push @messages, {
205
                    type => 'success',
206
                    code => 'biblio_modified',
207
                    biblionumber => $biblionumber,
208
                };
209
                $report->{total_success}++;
210
            }
211
        } else {
212
            # Authorities
213
            my $authid = $record_id;
214
            my $error = eval {
215
                my $authority = Koha::Authority->get_from_authid( $authid );
216
                my $record = $authority->record;
217
                ModifyRecordWithTemplate( $mmtid, $record );
218
                ModAuthority( $authid, $record, GetAuthTypeCode( $authid ) );
219
            };
220
            if ( $error and $error != $authid or $@ ) {
221
                push @messages, {
222
                    type => 'error',
223
                    code => 'authority_not_modified',
224
                    authid => $authid,
225
                    error => ($@ ? $@ : 0),
226
                };
227
            } else {
228
                push @messages, {
229
                    type => 'success',
230
                    code => 'authority_modified',
231
                    authid => $authid,
232
                };
233
                $report->{total_success}++;
234
            }
235
        }
236
237
        $job->set({
238
            view => 'report',
239
            report => $report,
240
            messages => \@messages,
241
        });
242
        $job->progress( ++$progress ) if $runinbackground;
243
    }
244
245
    if ($runinbackground) {
246
        $job->finish if defined $job;
247
    } else {
248
        $template->param(
249
            view => 'report',
250
            report => $report,
251
            messages => \@messages,
252
        );
253
    }
254
}
255
256
$template->param(
257
    messages => \@messages,
258
    recordtype => $recordtype,
259
);
260
261
output_html_with_http_headers $input, $cookie, $template->output;

Return to bug 11395