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

(-)a/Koha/SearchEngine/Elasticsearch.pm (-1 / +1 lines)
Lines 302-308 sub reset_elasticsearch_mappings { Link Here
302
    while ( my ( $index_name, $fields ) = each %$indexes ) {
302
    while ( my ( $index_name, $fields ) = each %$indexes ) {
303
        while ( my ( $field_name, $data ) = each %$fields ) {
303
        while ( my ( $field_name, $data ) = each %$fields ) {
304
304
305
            my %sf_params = map { $_ => $data->{$_} } grep { exists $data->{$_} } qw/ type label weight staff_client opac facet_order /;
305
            my %sf_params = map { $_ => $data->{$_} } grep { exists $data->{$_} } qw/ type label weight staff_client opac facet_order mandatory/;
306
306
307
            # Set default values
307
            # Set default values
308
            $sf_params{staff_client} //= 1;
308
            $sf_params{staff_client} //= 1;
(-)a/admin/searchengine/elasticsearch/mappings.pl (-1 / +8 lines)
Lines 130-135 if ( $op eq 'edit' ) { Link Here
130
        my @facetable_fields = Koha::SearchEngine::Elasticsearch->get_facetable_fields();
130
        my @facetable_fields = Koha::SearchEngine::Elasticsearch->get_facetable_fields();
131
        my @facetable_field_names = map { $_->name } @facetable_fields;
131
        my @facetable_field_names = map { $_->name } @facetable_fields;
132
132
133
        my $mandatory_before = Koha::SearchFields->search({mandatory=>1})->count;
134
        my $mandatory_after  = 0;
135
        my %seen_fields;
133
        for my $i ( 0 .. scalar(@index_name) - 1 ) {
136
        for my $i ( 0 .. scalar(@index_name) - 1 ) {
134
            my $index_name          = $index_name[$i];
137
            my $index_name          = $index_name[$i];
135
            my $search_field_name   = $search_field_name[$i];
138
            my $search_field_name   = $search_field_name[$i];
Lines 141-146 if ( $op eq 'edit' ) { Link Here
141
            my $mapping_search      = $mapping_search[$i];
144
            my $mapping_search      = $mapping_search[$i];
142
145
143
            my $search_field = Koha::SearchFields->find({ name => $search_field_name }, { key => 'name' });
146
            my $search_field = Koha::SearchFields->find({ name => $search_field_name }, { key => 'name' });
147
            $mandatory_after++ if $search_field->mandatory && !defined $seen_fields{$search_field_name};
148
            $seen_fields{$search_field_name} = 1;
144
            # TODO Check mapping format
149
            # TODO Check mapping format
145
            my $marc_field = Koha::SearchMarcMaps->find_or_create({
150
            my $marc_field = Koha::SearchMarcMaps->find_or_create({
146
                index_name => $index_name,
151
                index_name => $index_name,
Lines 154-161 if ( $op eq 'edit' ) { Link Here
154
                search => $mapping_search
159
                search => $mapping_search
155
            });
160
            });
156
        }
161
        }
162
        push @messages, { type => 'error', code => 'missing_mandatory_fields' } if $mandatory_after < $mandatory_before;
157
    };
163
    };
158
    if ($@) {
164
    if ($@ || @messages) {
159
        push @messages, { type => 'error', code => 'error_on_update', message => $@, };
165
        push @messages, { type => 'error', code => 'error_on_update', message => $@, };
160
        $schema->storage->txn_rollback;
166
        $schema->storage->txn_rollback;
161
    } else {
167
    } else {
Lines 233-238 for my $index_name (@index_names) { Link Here
233
            search_field_name  => $name,
239
            search_field_name  => $name,
234
            search_field_label => $s->label,
240
            search_field_label => $s->label,
235
            search_field_type  => $s->type,
241
            search_field_type  => $s->type,
242
            search_field_mandatory  => $s->mandatory,
236
            marc_field         => $s->get_column('marc_field'),
243
            marc_field         => $s->get_column('marc_field'),
237
            sort               => $s->get_column('sort') // 'undef', # To avoid warnings "Use of uninitialized value in lc"
244
            sort               => $s->get_column('sort') // 'undef', # To avoid warnings "Use of uninitialized value in lc"
238
            suggestible        => $s->get_column('suggestible'),
245
            suggestible        => $s->get_column('suggestible'),
(-)a/admin/searchengine/elasticsearch/mappings.yaml (+2 lines)
Lines 2215-2220 biblios: Link Here
2215
        sort: 1
2215
        sort: 1
2216
        suggestible: ''
2216
        suggestible: ''
2217
    type: sum
2217
    type: sum
2218
    mandatory: 1
2218
  itemnumber:
2219
  itemnumber:
2219
    label: itemnumber
2220
    label: itemnumber
2220
    mappings:
2221
    mappings:
Lines 4197-4202 biblios: Link Here
4197
        sort: ~
4198
        sort: ~
4198
        suggestible: ''
4199
        suggestible: ''
4199
    type: string
4200
    type: string
4201
    mandatory: 1
4200
  title-abbreviated:
4202
  title-abbreviated:
4201
    label: title-abbreviated
4203
    label: title-abbreviated
4202
    mappings:
4204
    mappings:
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/searchengine/elasticsearch/mappings.tt (-107 / +151 lines)
Lines 29-35 Link Here
29
    $(document).ready(function() {
29
    $(document).ready(function() {
30
        $("#tabs").tabs();
30
        $("#tabs").tabs();
31
        $('.delete').click(function() {
31
        $('.delete').click(function() {
32
            $(this).parents('tr').remove();
32
            if( $(this).hasClass('mandatory') && $(".mandatory[data-field_name="+$(this).attr('data-field_name')+"]").length < 2 ){
33
                alert("This field is mandatory and must have at least one mapping");
34
                return;
35
            } else {
36
                $(this).parents('tr').remove();
37
            }
33
        });
38
        });
34
39
35
        $("table.mappings").tableDnD( {
40
        $("table.mappings").tableDnD( {
Lines 85-90 a.add, a.delete { Link Here
85
          [% tx("(search field {field_name} with mapping {marc_field}.)", { field_name = m.values.field_name, marc_field = m.values.marc_field }) | html %]
90
          [% tx("(search field {field_name} with mapping {marc_field}.)", { field_name = m.values.field_name, marc_field = m.values.marc_field }) | html %]
86
        [% CASE 'invalid_field_weight' %]
91
        [% CASE 'invalid_field_weight' %]
87
          [% tx("Invalid field weight '{weight}', must be a positive decimal number.", { weight = m.weight }) | html %]
92
          [% tx("Invalid field weight '{weight}', must be a positive decimal number.", { weight = m.weight }) | html %]
93
        [% CASE 'missing_mandatory_fields' %]
94
          [% t("You attempted to delete all mappings for a required index, you must leave at least one mapping") | $raw %]
88
        [% CASE 'error_on_update_es_mappings' %]
95
        [% CASE 'error_on_update_es_mappings' %]
89
          [% tx("An error occurred when updating Elasticsearch index mappings: {message}.", { message = m.message }) | html %]
96
          [% tx("An error occurred when updating Elasticsearch index mappings: {message}.", { message = m.message }) | html %]
90
        [% CASE 'reindex_required' %]
97
        [% CASE 'reindex_required' %]
Lines 172-223 a.add, a.delete { Link Here
172
                </thead>
179
                </thead>
173
                <tbody>
180
                <tbody>
174
                  [% FOREACH search_field IN all_search_fields %]
181
                  [% FOREACH search_field IN all_search_fields %]
182
                      [% IF search_field.mandatory %]
183
                          [% SET is_readonly = "readonly" %]
184
                      [% ELSE %]
185
                          [% SET is_readonly = "" %]
186
                      [% END %]
175
                    <tr>
187
                    <tr>
176
                      <td>
188
                      <td>
177
                        <input type="text" name="search_field_name" value="[% search_field.name | html %]" />
189
                        <input type="text" name="search_field_name" value="[% search_field.name | html %]" [% is_readonly %]/>
178
                      </td>
190
                      </td>
179
                      <td>
191
                      <td>
180
                        <input type="text" name="search_field_label" value="[% search_field.label | html %]" />
192
                        <input type="text" name="search_field_label" value="[% search_field.label | html %]" [% is_readonly %]/>
181
                      </td>
182
                      <td>
193
                      <td>
183
                        <select name="search_field_type">
194
                        [% IF is_readonly %]
184
                          <option value=""></option>
195
                            <input type="hidden" name="search_field_type" value="[% search_field.type | html %]" />
185
                          [% IF search_field.type == "string" %]
196
                            <select name="search_field_type" disabled>
186
                            <option value="string" selected="selected">String</option>
197
                        [% ELSE %]
187
                          [% ELSE %]
198
                            <select name="search_field_type">
188
                            <option value="string">String</option>
199
                              <option value=""></option>
189
                          [% END %]
200
                              [% IF search_field.type == "string" %]
190
                          [% IF search_field.type == "date" %]
201
                                <option value="string" selected="selected">String</option>
191
                            <option value="date" selected="selected">Date</option>
202
                              [% ELSE %]
192
                          [% ELSE %]
203
                                <option value="string">String</option>
193
                            <option value="date">Date</option>
204
                              [% END %]
194
                          [% END %]
205
                              [% IF search_field.type == "date" %]
195
                          [% IF search_field.type == "number" %]
206
                                <option value="date" selected="selected">Date</option>
196
                            <option value="number" selected="selected">Number</option>
207
                              [% ELSE %]
197
                          [% ELSE %]
208
                                <option value="date">Date</option>
198
                            <option value="number">Number</option>
209
                              [% END %]
199
                          [% END %]
210
                              [% IF search_field.type == "number" %]
200
                          [% IF search_field.type == "boolean" %]
211
                                <option value="number" selected="selected">Number</option>
201
                            <option value="boolean" selected="selected">Boolean</option>
212
                              [% ELSE %]
202
                          [% ELSE %]
213
                                <option value="number">Number</option>
203
                            <option value="boolean">Boolean</option>
214
                              [% END %]
204
                          [% END %]
215
                              [% IF search_field.type == "boolean" %]
205
                          [% IF search_field.type == "sum" %]
216
                                <option value="boolean" selected="selected">Boolean</option>
206
                            <option value="sum" selected="selected">Sum</option>
217
                              [% ELSE %]
207
                          [% ELSE %]
218
                                <option value="boolean">Boolean</option>
208
                            <option value="sum">Sum</option>
219
                              [% END %]
209
                          [% END %]
220
                              [% IF search_field.type == "sum" %]
210
                          [% IF search_field.type == "isbn" %]
221
                                <option value="sum" selected="selected">Sum</option>
211
                            <option value="isbn" selected="selected">ISBN</option>
222
                              [% ELSE %]
212
                          [% ELSE %]
223
                                <option value="sum">Sum</option>
213
                            <option value="isbn">ISBN</option>
224
                              [% END %]
214
                          [% END %]
225
                              [% IF search_field.type == "isbn" %]
215
                          [% IF search_field.type == "stdno" %]
226
                                <option value="isbn" selected="selected">ISBN</option>
216
                            <option value="stdno" selected="selected">Std. Number</option>
227
                              [% ELSE %]
217
                          [% ELSE %]
228
                                <option value="isbn">ISBN</option>
218
                            <option value="stdno">Std. Number</option>
229
                              [% END %]
219
                          [% END %]
230
                              [% IF search_field.type == "stdno" %]
220
                        </select>
231
                                <option value="stdno" selected="selected">Std. Number</option>
232
                              [% ELSE %]
233
                                <option value="stdno">Std. Number</option>
234
                              [% END %]
235
                            </select>
236
                        [% END %]
221
                      </td>
237
                      </td>
222
                      <td>
238
                      <td>
223
                        <select name="search_field_staff_client">
239
                        <select name="search_field_staff_client">
Lines 269-342 a.add, a.delete { Link Here
269
                      </thead>
285
                      </thead>
270
                      <tbody>
286
                      <tbody>
271
                        [% FOREACH mapping IN index.mappings %]
287
                        [% FOREACH mapping IN index.mappings %]
272
                          <tr>
288
                            [% IF mapping.search_field_mandatory && mapping.search_field_label != loop.next.search_field_label && mapping.search_field_label != loop.prev.search_field_label %]
273
                            <td>
289
                              <tr>
274
                              <input type="hidden" name="mapping_index_name" value="[% index.index_name | html %]" />
290
                                <td>
275
                              <input type="hidden" name="mapping_search_field_name" value="[% mapping.search_field_name | html %]">
291
                                  <input type="hidden" name="mapping_index_name" value="[% index.index_name | html %]" />
276
                              [% mapping.search_field_label | html %]
292
                                  <input type="hidden" name="mapping_search_field_name" value="[% mapping.search_field_name | html %]">
277
                            </td>
293
                                  [% mapping.search_field_label | html %]
278
                            <td>
294
                                </td>
279
                              <select name="mapping_sort">
295
                                <td>
280
                                [% IF mapping.sort == 'undef' %]
296
                                  <input type="hidden" name="mapping_sort" value="[% mapping.sort | html %]" readonly />[% IF mapping.sort == 'undef' %]Undef[% ELSE %][% mapping.sort | html %][% END %]
281
                                  <option value="undef" selected="selected">Undef</option>
297
                                </td>
282
                                [% ELSE %]
298
                                <td>
283
                                  <option value="undef">Undef</option>
299
                                  <input type="hidden" name="mapping_facet" value="[% mapping.facet | html %]" readonly />[% IF mapping.facet == 1 %]Yes[% ELSE %]No[% END %]
284
                                [% END %]
300
                                </td>
285
                                [% IF mapping.sort == 0 %]
301
                                <td>
286
                                  <option value="0" selected="selected">0</option>
302
                                  <input type="hidden" name="mapping_suggestible" value="[% mapping.suggestible | html %]" readonly />[% IF mapping.suggestible == 1 %]Yes[% ELSE %]No[% END %]
287
                                [% ELSE %]
303
                                </td>
288
                                  <option value="0">0</option>
304
                                <td>
289
                                [% END %]
305
                                  <input type="hidden" name="mapping_search" value="[% mapping.search | html %]" readonly />[% IF mapping.search == 1 %]Yes[% ELSE %]No[% END %]
290
                                [% IF  mapping.sort == 1 %]
306
                                </td>
291
                                  <option value="1" selected="selected">1</option>
307
                                <td>
292
                                [% ELSE %]
308
                                    <input name="mapping_marc_field" type="text" value="[% mapping.marc_field | html %]" />
293
                                  <option value="1">1</option>
309
                                </td>
294
                                [% END %]
310
                              </tr>
295
                              </select>
311
                            [% ELSE %]
296
                            </td>
312
                              <tr>
297
                            <td>
313
                                <td>
298
                              [% IF mapping.is_facetable %]
314
                                  <input type="hidden" name="mapping_index_name" value="[% index.index_name | html %]" />
299
                                <select name="mapping_facet">
315
                                  <input type="hidden" name="mapping_search_field_name" value="[% mapping.search_field_name | html %]">
300
                                  [% IF mapping.facet %]
316
                                  [% mapping.search_field_label | html %]
301
                                    <option value="0">No</option>
317
                                </td>
302
                                    <option value="1" selected="selected">Yes</option>
318
                                <td>
319
                                  <select name="mapping_sort">
320
                                    [% IF mapping.sort == 'undef' %]
321
                                      <option value="undef" selected="selected">Undef</option>
322
                                    [% ELSE %]
323
                                      <option value="undef">Undef</option>
324
                                    [% END %]
325
                                    [% IF mapping.sort == 0 %]
326
                                      <option value="0" selected="selected">0</option>
327
                                    [% ELSE %]
328
                                      <option value="0">0</option>
329
                                    [% END %]
330
                                    [% IF  mapping.sort == 1 %]
331
                                      <option value="1" selected="selected">1</option>
332
                                    [% ELSE %]
333
                                      <option value="1">1</option>
334
                                    [% END %]
335
                                  </select>
336
                                </td>
337
                                <td>
338
                                  [% IF mapping.is_facetable %]
339
                                    <select name="mapping_facet">
340
                                      [% IF mapping.facet %]
341
                                        <option value="0">No</option>
342
                                        <option value="1" selected="selected">Yes</option>
343
                                      [% ELSE %]
344
                                        <option value="0" selected="selected">No</option>
345
                                        <option value="1">Yes</option>
346
                                      [% END %]
347
                                    </select>
303
                                  [% ELSE %]
348
                                  [% ELSE %]
304
                                    <option value="0" selected="selected">No</option>
349
                                    <input type="hidden" name="mapping_facet" value="0" />
305
                                    <option value="1">Yes</option>
350
                                    No
306
                                  [% END %]
351
                                  [% END %]
307
                                </select>
352
                                </td>
308
                              [% ELSE %]
353
                                <td>
309
                                <input type="hidden" name="mapping_facet" value="0" />
354
                                  <select name="mapping_suggestible">
310
                                No
355
                                    [% IF mapping.suggestible %]
311
                              [% END %]
356
                                      <option value="0">No</option>
312
                            </td>
357
                                      <option value="1" selected="selected">Yes</option>
313
                            <td>
358
                                    [% ELSE %]
314
                              <select name="mapping_suggestible">
359
                                      <option value="0" selected="selected">No</option>
315
                                [% IF mapping.suggestible %]
360
                                      <option value="1">Yes</option>
316
                                  <option value="0">No</option>
361
                                    [% END %]
317
                                  <option value="1" selected="selected">Yes</option>
362
                                  </select>
318
                                [% ELSE %]
363
                                </td>
319
                                  <option value="0" selected="selected">No</option>
364
                                <td>
320
                                  <option value="1">Yes</option>
365
                                  <select name="mapping_search">
321
                                [% END %]
366
                                    [% IF mapping.search %]
322
                              </select>
367
                                      <option value="0">No</option>
323
                            </td>
368
                                      <option value="1" selected="selected">Yes</option>
324
                            <td>
369
                                    [% ELSE %]
325
                              <select name="mapping_search">
370
                                      <option value="0" selected="selected">No</option>
326
                                [% IF mapping.search %]
371
                                      <option value="1">Yes</option>
327
                                  <option value="0">No</option>
372
                                    [% END %]
328
                                  <option value="1" selected="selected">Yes</option>
373
                                  </select>
374
                                </td>
375
                                <td>
376
                                    <input name="mapping_marc_field" type="text" value="[% mapping.marc_field | html %]" />
377
                                </td>
378
                                [% IF mapping.search_field_mandatory %]
379
                                    <td><a class="btn btn-default btn-xs delete mandatory" data-field_name="[% mapping.search_field_name %]" style="cursor: pointer;"><i class="fa fa-trash"></i> Delete</a></td>
329
                                [% ELSE %]
380
                                [% ELSE %]
330
                                  <option value="0" selected="selected">No</option>
381
                                    <td><a class="btn btn-default btn-xs delete" style="cursor: pointer;"><i class="fa fa-trash"></i> Delete</a></td>
331
                                  <option value="1">Yes</option>
332
                                [% END %]
382
                                [% END %]
333
                              </select>
383
                              </tr>
334
                            </td>
384
                            [% END %]
335
                            <td>
336
                                <input name="mapping_marc_field" type="text" value="[% mapping.marc_field | html %]" />
337
                            </td>
338
                            <td><a class="btn btn-default btn-xs delete" style="cursor: pointer;"><i class="fa fa-trash"></i> Delete</a></td>
339
                          </tr>
340
                        [% END %]
385
                        [% END %]
341
                      </tbody>
386
                      </tbody>
342
                      <tfoot>
387
                      <tfoot>
343
- 

Return to bug 19482