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

(-)a/Koha/SearchEngine/Elasticsearch.pm (-1 / +1 lines)
Lines 284-290 sub reset_elasticsearch_mappings { Link Here
284
284
285
    while ( my ( $index_name, $fields ) = each %$indexes ) {
285
    while ( my ( $index_name, $fields ) = each %$indexes ) {
286
        while ( my ( $field_name, $data ) = each %$fields ) {
286
        while ( my ( $field_name, $data ) = each %$fields ) {
287
            my %sf_params = map { $_ => $data->{$_} } grep { exists $data->{$_} } qw/ type label weight facet_order /;
287
            my %sf_params = map { $_ => $data->{$_} } grep { exists $data->{$_} } qw/ type label weight facet_order mandatory /;
288
            $sf_params{name} = $field_name;
288
            $sf_params{name} = $field_name;
289
289
290
            my $search_field = Koha::SearchFields->find_or_create( \%sf_params, { key => 'name' } );
290
            my $search_field = Koha::SearchFields->find_or_create( \%sf_params, { key => 'name' } );
(-)a/admin/searchengine/elasticsearch/mappings.pl (-1 / +8 lines)
Lines 116-121 if ( $op eq 'edit' ) { Link Here
116
        my @facetable_fields = Koha::SearchEngine::Elasticsearch->get_facetable_fields();
116
        my @facetable_fields = Koha::SearchEngine::Elasticsearch->get_facetable_fields();
117
        my @facetable_field_names = map { $_->name } @facetable_fields;
117
        my @facetable_field_names = map { $_->name } @facetable_fields;
118
118
119
        my $mandatory_before = Koha::SearchFields->search({mandatory=>1})->count;
120
        my $mandatory_after  = 0;
121
        my %seen_fields;
119
        for my $i ( 0 .. scalar(@index_name) - 1 ) {
122
        for my $i ( 0 .. scalar(@index_name) - 1 ) {
120
            my $index_name          = $index_name[$i];
123
            my $index_name          = $index_name[$i];
121
            my $search_field_name  = $search_field_name[$i];
124
            my $search_field_name  = $search_field_name[$i];
Lines 127-139 if ( $op eq 'edit' ) { Link Here
127
            $mapping_facet = ( grep {/^$search_field_name$/} @facetable_field_names ) ? $mapping_facet : 0;
130
            $mapping_facet = ( grep {/^$search_field_name$/} @facetable_field_names ) ? $mapping_facet : 0;
128
131
129
            my $search_field = Koha::SearchFields->find({ name => $search_field_name }, { key => 'name' });
132
            my $search_field = Koha::SearchFields->find({ name => $search_field_name }, { key => 'name' });
133
            $mandatory_after++ if $search_field->mandatory && !defined $seen_fields{$search_field_name};
134
            $seen_fields{$search_field_name} = 1;
130
            # TODO Check mapping format
135
            # TODO Check mapping format
131
            my $marc_field = Koha::SearchMarcMaps->find_or_create({ index_name => $index_name, marc_type => $marc_type, marc_field => $mapping_marc_field });
136
            my $marc_field = Koha::SearchMarcMaps->find_or_create({ index_name => $index_name, marc_type => $marc_type, marc_field => $mapping_marc_field });
132
            $search_field->add_to_search_marc_maps($marc_field, { facet => $mapping_facet, suggestible => $mapping_suggestible, sort => $mapping_sort } );
137
            $search_field->add_to_search_marc_maps($marc_field, { facet => $mapping_facet, suggestible => $mapping_suggestible, sort => $mapping_sort } );
133
138
134
        }
139
        }
140
        push @messages, { type => 'error', code => 'missing_mandatory_fields' } if $mandatory_after < $mandatory_before;
135
    };
141
    };
136
    if ($@) {
142
    if ($@ || @messages) {
137
        push @messages, { type => 'error', code => 'error_on_update', message => $@, };
143
        push @messages, { type => 'error', code => 'error_on_update', message => $@, };
138
        $schema->storage->txn_rollback;
144
        $schema->storage->txn_rollback;
139
    } else {
145
    } else {
Lines 196-201 for my $index_name (@index_names) { Link Here
196
          { search_field_name  => $name,
202
          { search_field_name  => $name,
197
            search_field_label => $s->label,
203
            search_field_label => $s->label,
198
            search_field_type  => $s->type,
204
            search_field_type  => $s->type,
205
            search_field_mandatory  => $s->mandatory,
199
            marc_field         => $s->get_column('marc_field'),
206
            marc_field         => $s->get_column('marc_field'),
200
            sort               => $s->get_column('sort') // 'undef', # To avoid warnings "Use of uninitialized value in lc"
207
            sort               => $s->get_column('sort') // 'undef', # To avoid warnings "Use of uninitialized value in lc"
201
            suggestible        => $s->get_column('suggestible'),
208
            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 (-95 / +137 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 165-214 a.add, a.delete { Link Here
165
                </thead>
172
                </thead>
166
                <tbody>
173
                <tbody>
167
                  [% FOREACH search_field IN all_search_fields %]
174
                  [% FOREACH search_field IN all_search_fields %]
175
                      [% IF search_field.mandatory %]
176
                          [% SET is_readonly = "readonly" %]
177
                      [% ELSE %]
178
                          [% SET is_readonly = "" %]
179
                      [% END %]
168
                    <tr>
180
                    <tr>
169
                      <td>
181
                      <td>
170
                        <input type="text" name="search_field_name" value="[% search_field.name | html %]" />
182
                        <input type="text" name="search_field_name" value="[% search_field.name | html %]" [% is_readonly %]/>
171
                      </td>
183
                      </td>
172
                      <td><input type="text" name="search_field_label" value="[% search_field.label | html %]" />
184
                      <td><input type="text" name="search_field_label" value="[% search_field.label | html %]" [% is_readonly %]/>
173
                      <td>
185
                      <td>
174
                        <select name="search_field_type">
186
                        [% IF is_readonly %]
175
                          <option value=""></option>
187
                            <input type="hidden" name="search_field_type" value="[% search_field.type | html %]" />
176
                          [% IF search_field.type == "string" %]
188
                            <select name="search_field_type" disabled>
177
                            <option value="string" selected="selected">String</option>
189
                        [% ELSE %]
178
                          [% ELSE %]
190
                            <select name="search_field_type">
179
                            <option value="string">String</option>
191
                              <option value=""></option>
180
                          [% END %]
192
                              [% IF search_field.type == "string" %]
181
                          [% IF search_field.type == "date" %]
193
                                <option value="string" selected="selected">String</option>
182
                            <option value="date" selected="selected">Date</option>
194
                              [% ELSE %]
183
                          [% ELSE %]
195
                                <option value="string">String</option>
184
                            <option value="date">Date</option>
196
                              [% END %]
185
                          [% END %]
197
                              [% IF search_field.type == "date" %]
186
                          [% IF search_field.type == "number" %]
198
                                <option value="date" selected="selected">Date</option>
187
                            <option value="number" selected="selected">Number</option>
199
                              [% ELSE %]
188
                          [% ELSE %]
200
                                <option value="date">Date</option>
189
                            <option value="number">Number</option>
201
                              [% END %]
190
                          [% END %]
202
                              [% IF search_field.type == "number" %]
191
                          [% IF search_field.type == "boolean" %]
203
                                <option value="number" selected="selected">Number</option>
192
                            <option value="boolean" selected="selected">Boolean</option>
204
                              [% ELSE %]
193
                          [% ELSE %]
205
                                <option value="number">Number</option>
194
                            <option value="boolean">Boolean</option>
206
                              [% END %]
195
                          [% END %]
207
                              [% IF search_field.type == "boolean" %]
196
                          [% IF search_field.type == "sum" %]
208
                                <option value="boolean" selected="selected">Boolean</option>
197
                            <option value="sum" selected="selected">Sum</option>
209
                              [% ELSE %]
198
                          [% ELSE %]
210
                                <option value="boolean">Boolean</option>
199
                            <option value="sum">Sum</option>
211
                              [% END %]
200
                          [% END %]
212
                              [% IF search_field.type == "sum" %]
201
                          [% IF search_field.type == "isbn" %]
213
                                <option value="sum" selected="selected">Sum</option>
202
                            <option value="isbn" selected="selected">ISBN</option>
214
                              [% ELSE %]
203
                          [% ELSE %]
215
                                <option value="sum">Sum</option>
204
                            <option value="isbn">ISBN</option>
216
                              [% END %]
205
                          [% END %]
217
                              [% IF search_field.type == "isbn" %]
206
                          [% IF search_field.type == "stdno" %]
218
                                <option value="isbn" selected="selected">ISBN</option>
207
                            <option value="stdno" selected="selected">Std. Number</option>
219
                              [% ELSE %]
208
                          [% ELSE %]
220
                                <option value="isbn">ISBN</option>
209
                            <option value="stdno">Std. Number</option>
221
                              [% END %]
210
                          [% END %]
222
                              [% IF search_field.type == "stdno" %]
211
                        </select>
223
                                <option value="stdno" selected="selected">Std. Number</option>
224
                              [% ELSE %]
225
                                <option value="stdno">Std. Number</option>
226
                              [% END %]
227
                            </select>
228
                        [% END %]
212
                      </td>
229
                      </td>
213
                      <td>
230
                      <td>
214
                      [% IF search_field.mapped_biblios %]
231
                      [% IF search_field.mapped_biblios %]
Lines 237-299 a.add, a.delete { Link Here
237
                      </thead>
254
                      </thead>
238
                      <tbody>
255
                      <tbody>
239
                        [% FOREACH mapping IN index.mappings %]
256
                        [% FOREACH mapping IN index.mappings %]
240
                          <tr>
257
                            [% IF mapping.search_field_mandatory && mapping.search_field_label != loop.next.search_field_label && mapping.search_field_label != loop.prev.search_field_label %]
241
                            <td>
258
                              <tr>
242
                              <input type="hidden" name="mapping_index_name" value="[% index.index_name | html %]" />
259
                                <td>
243
                              <input type="hidden" name="mapping_search_field_name" value="[% mapping.search_field_name | html %]">
260
                                  <input type="hidden" name="mapping_index_name" value="[% index.index_name | html %]" />
244
                              [% mapping.search_field_label | html %]
261
                                  <input type="hidden" name="mapping_search_field_name" value="[% mapping.search_field_name | html %]">
245
                            </td>
262
                                  [% mapping.search_field_label | html %]
246
                            <td>
263
                                </td>
247
                              <select name="mapping_sort">
264
                                <td>
248
                                [% IF mapping.sort == 'undef' %]
265
                                  <input type="hidden" name="mapping_sort" value="[% mapping.sort | html %]" readonly />[% IF mapping.sort == 'undef' %]Undef[% ELSE %][% mapping.sort | html %][% END %]
249
                                  <option value="undef" selected="selected">Undef</option>
266
                                </td>
250
                                [% ELSE %]
267
                                <td>
251
                                  <option value="undef">Undef</option>
268
                                  <input type="hidden" name="mapping_facet" value="[% mapping.facet | html %]" readonly />[% IF mapping.facet == 1 %]Yes[% ELSE %]No[% END %]
252
                                [% END %]
269
                                </td>
253
                                [% IF mapping.sort == 0 %]
270
                                <td>
254
                                  <option value="0" selected="selected">0</option>
271
                                  <input type="hidden" name="mapping_suggestible" value="[% mapping.suggestible | html %]" readonly />[% IF mapping.suggestible == 1 %]Yes[% ELSE %]No[% END %]
255
                                [% ELSE %]
272
                                </td>
256
                                  <option value="0">0</option>
273
                                <td>
257
                                [% END %]
274
                                    <input name="mapping_marc_field" type="text" value="[% mapping.marc_field | html %]" />
258
                                [% IF  mapping.sort == 1 %]
275
                                </td>
259
                                  <option value="1" selected="selected">1</option>
276
                              </tr>
260
                                [% ELSE %]
277
                            [% ELSE %]
261
                                  <option value="1">1</option>
278
                              <tr>
262
                                [% END %]
279
                                <td>
263
                              </select>
280
                                  <input type="hidden" name="mapping_index_name" value="[% index.index_name | html %]" />
264
                            </td>
281
                                  <input type="hidden" name="mapping_search_field_name" value="[% mapping.search_field_name | html %]">
265
                            <td>
282
                                  [% mapping.search_field_label | html %]
266
                              [% IF mapping.is_facetable %]
283
                                </td>
267
                                <select name="mapping_facet">
284
                                <td>
268
                                  [% IF mapping.facet %]
285
                                  <select name="mapping_sort">
269
                                    <option value="0">No</option>
286
                                    [% IF mapping.sort == 'undef' %]
270
                                    <option value="1" selected="selected">Yes</option>
287
                                      <option value="undef" selected="selected">Undef</option>
288
                                    [% ELSE %]
289
                                      <option value="undef">Undef</option>
290
                                    [% END %]
291
                                    [% IF mapping.sort == 0 %]
292
                                      <option value="0" selected="selected">0</option>
293
                                    [% ELSE %]
294
                                      <option value="0">0</option>
295
                                    [% END %]
296
                                    [% IF  mapping.sort == 1 %]
297
                                      <option value="1" selected="selected">1</option>
298
                                    [% ELSE %]
299
                                      <option value="1">1</option>
300
                                    [% END %]
301
                                  </select>
302
                                </td>
303
                                <td>
304
                                  [% IF mapping.is_facetable %]
305
                                    <select name="mapping_facet">
306
                                      [% IF mapping.facet %]
307
                                        <option value="0">No</option>
308
                                        <option value="1" selected="selected">Yes</option>
309
                                      [% ELSE %]
310
                                        <option value="0" selected="selected">No</option>
311
                                        <option value="1">Yes</option>
312
                                      [% END %]
313
                                    </select>
271
                                  [% ELSE %]
314
                                  [% ELSE %]
272
                                    <option value="0" selected="selected">No</option>
315
                                    <input type="hidden" name="mapping_facet" value="0" />
273
                                    <option value="1">Yes</option>
316
                                    No
274
                                  [% END %]
317
                                  [% END %]
275
                                </select>
318
                                </td>
276
                              [% ELSE %]
319
                                <td>
277
                                <input type="hidden" name="mapping_facet" value="0" />
320
                                  <select name="mapping_suggestible">
278
                                No
321
                                    [% IF mapping.suggestible %]
279
                              [% END %]
322
                                      <option value="0">No</option>
280
                            </td>
323
                                      <option value="1" selected="selected">Yes</option>
281
                            <td>
324
                                    [% ELSE %]
282
                              <select name="mapping_suggestible">
325
                                      <option value="0" selected="selected">No</option>
283
                                [% IF mapping.suggestible %]
326
                                      <option value="1">Yes</option>
284
                                  <option value="0">No</option>
327
                                    [% END %]
285
                                  <option value="1" selected="selected">Yes</option>
328
                                  </select>
329
                                </td>
330
                                <td>
331
                                    <input name="mapping_marc_field" type="text" value="[% mapping.marc_field | html %]" />
332
                                </td>
333
                                [% IF mapping.search_field_mandatory %]
334
                                    <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>
286
                                [% ELSE %]
335
                                [% ELSE %]
287
                                  <option value="0" selected="selected">No</option>
336
                                    <td><a class="btn btn-default btn-xs delete" style="cursor: pointer;"><i class="fa fa-trash"></i> Delete</a></td>
288
                                  <option value="1">Yes</option>
289
                                [% END %]
337
                                [% END %]
290
                              </select>
338
                              </tr>
291
                            </td>
339
                            [% END %]
292
                            <td>
293
                                <input name="mapping_marc_field" type="text" value="[% mapping.marc_field | html %]" />
294
                            </td>
295
                            <td><a class="btn btn-default btn-xs delete" style="cursor: pointer;"><i class="fa fa-trash"></i> Delete</a></td>
296
                          </tr>
297
                        [% END %]
340
                        [% END %]
298
                      </tbody>
341
                      </tbody>
299
                      <tfoot>
342
                      <tfoot>
300
- 

Return to bug 19482