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

(-)a/Koha/AdditionalField.pm (+1 lines)
Lines 60-65 sub to_api { Link Here
60
        'aqbasket'            => 'basket',
60
        'aqbasket'            => 'basket',
61
        'aqinvoices'          => 'invoice',
61
        'aqinvoices'          => 'invoice',
62
        'erm_licenses'        => 'license',
62
        'erm_licenses'        => 'license',
63
        'erm_agreements'      => 'agreement',
63
        'aqorders'            => 'order',
64
        'aqorders'            => 'order',
64
    };
65
    };
65
66
(-)a/Koha/ERM/Agreement.pm (-1 / +1 lines)
Lines 25-31 use Koha::DateUtils qw( dt_from_string ); Link Here
25
use Koha::Exceptions;
25
use Koha::Exceptions;
26
use Koha::Acquisition::Bookseller;
26
use Koha::Acquisition::Bookseller;
27
27
28
use base qw(Koha::Object);
28
use base qw(Koha::Object::Mixin::AdditionalFields Koha::Object);
29
29
30
use Koha::ERM::Agreement::Periods;
30
use Koha::ERM::Agreement::Periods;
31
use Koha::ERM::Agreement::Licenses;
31
use Koha::ERM::Agreement::Licenses;
(-)a/Koha/ERM/Agreements.pm (-1 / +1 lines)
Lines 24-30 use Koha::DateUtils qw( dt_from_string ); Link Here
24
use Koha::ERM::Agreement;
24
use Koha::ERM::Agreement;
25
use Koha::ERM::Agreement::Periods;
25
use Koha::ERM::Agreement::Periods;
26
26
27
use base qw(Koha::Objects);
27
use base qw(Koha::Objects::Mixin::AdditionalFields Koha::Objects);
28
28
29
=head1 NAME
29
=head1 NAME
30
30
(-)a/Koha/REST/V1/ERM/Agreements.pm (+8 lines)
Lines 97-102 sub add { Link Here
97
                my $agreement_licenses = delete $body->{agreement_licenses} // [];
97
                my $agreement_licenses = delete $body->{agreement_licenses} // [];
98
                my $agreement_relationships = delete $body->{agreement_relationships} // [];
98
                my $agreement_relationships = delete $body->{agreement_relationships} // [];
99
                my $documents = delete $body->{documents} // [];
99
                my $documents = delete $body->{documents} // [];
100
                my $extended_attributes = delete $body->{extended_attributes} // [];
100
101
101
                my $agreement = Koha::ERM::Agreement->new_from_api($body)->store;
102
                my $agreement = Koha::ERM::Agreement->new_from_api($body)->store;
102
                $agreement->periods($periods);
103
                $agreement->periods($periods);
Lines 105-110 sub add { Link Here
105
                $agreement->agreement_relationships($agreement_relationships);
106
                $agreement->agreement_relationships($agreement_relationships);
106
                $agreement->documents($documents);
107
                $agreement->documents($documents);
107
108
109
                my @extended_attributes = map { {'id' => $_->{field_id}, 'value' => $_->{value}} } @{$extended_attributes};
110
                $agreement->extended_attributes( \@extended_attributes );
111
108
                $c->res->headers->location($c->req->url->to_string . '/' . $agreement->agreement_id);
112
                $c->res->headers->location($c->req->url->to_string . '/' . $agreement->agreement_id);
109
                return $c->render(
113
                return $c->render(
110
                    status  => 201,
114
                    status  => 201,
Lines 181-186 sub update { Link Here
181
                my $agreement_licenses = delete $body->{agreement_licenses} // [];
185
                my $agreement_licenses = delete $body->{agreement_licenses} // [];
182
                my $agreement_relationships = delete $body->{agreement_relationships} // [];
186
                my $agreement_relationships = delete $body->{agreement_relationships} // [];
183
                my $documents = delete $body->{documents} // [];
187
                my $documents = delete $body->{documents} // [];
188
                my $extended_attributes = delete $body->{extended_attributes} // [];
184
189
185
                $agreement->set_from_api($body)->store;
190
                $agreement->set_from_api($body)->store;
186
                $agreement->periods($periods);
191
                $agreement->periods($periods);
Lines 189-194 sub update { Link Here
189
                $agreement->agreement_relationships($agreement_relationships);
194
                $agreement->agreement_relationships($agreement_relationships);
190
                $agreement->documents($documents);
195
                $agreement->documents($documents);
191
196
197
                my @extended_attributes = map { {'id' => $_->{field_id}, 'value' => $_->{value}} } @{$extended_attributes};
198
                $agreement->extended_attributes( \@extended_attributes );
199
192
                $c->res->headers->location($c->req->url->to_string . '/' . $agreement->agreement_id);
200
                $c->res->headers->location($c->req->url->to_string . '/' . $agreement->agreement_id);
193
                return $c->render(
201
                return $c->render(
194
                    status  => 200,
202
                    status  => 200,
(-)a/Koha/REST/V1/ExtendedAttributeTypes.pm (-6 / +7 lines)
Lines 46-57 sub list { Link Here
46
46
47
    # FIXME: Maybe not the best place for this mapping
47
    # FIXME: Maybe not the best place for this mapping
48
    my $resource_to_table = {
48
    my $resource_to_table = {
49
        basket  => 'aqbasket',
49
        basket    => 'aqbasket',
50
        credit  => 'accountlines:credit',
50
        credit    => 'accountlines:credit',
51
        debit   => 'accountlines:debit',
51
        debit     => 'accountlines:debit',
52
        invoice => 'aqinvoices',
52
        invoice   => 'aqinvoices',
53
        license => 'erm_licenses',
53
        license   => 'erm_licenses',
54
        order   => 'aqorders',
54
        agreement => 'erm_agreements',
55
        order     => 'aqorders',
55
    };
56
    };
56
57
57
    return try {
58
    return try {
(-)a/Koha/Schema/Result/ErmAgreement.pm (+32 lines)
Lines 281-286 __PACKAGE__->add_columns( Link Here
281
    '+is_perpetual' => { is_boolean => 1 }
281
    '+is_perpetual' => { is_boolean => 1 }
282
);
282
);
283
283
284
__PACKAGE__->has_many(
285
    "additional_field_values",
286
    "Koha::Schema::Result::AdditionalFieldValue",
287
    sub {
288
        my ($args) = @_;
289
290
        return {
291
            "$args->{foreign_alias}.record_id" => { -ident => "$args->{self_alias}.agreement_id" },
292
293
            "$args->{foreign_alias}.field_id" =>
294
                { -in => \'(SELECT id FROM additional_fields WHERE tablename="erm_agreements")' },
295
        };
296
    },
297
    { cascade_copy => 0, cascade_delete => 0 },
298
);
299
300
__PACKAGE__->has_many(
301
    "extended_attributes",
302
    "Koha::Schema::Result::AdditionalFieldValue",
303
    sub {
304
        my ($args) = @_;
305
306
        return {
307
            "$args->{foreign_alias}.record_id" => { -ident => "$args->{self_alias}.agreement_id" },
308
309
            "$args->{foreign_alias}.field_id" =>
310
                { -in => \'(SELECT id FROM additional_fields WHERE tablename="erm_agreements")' },
311
        };
312
    },
313
    { cascade_copy => 0, cascade_delete => 0 },
314
);
315
284
sub koha_object_class {
316
sub koha_object_class {
285
    'Koha::ERM::Agreement';
317
    'Koha::ERM::Agreement';
286
}
318
}
(-)a/api/v1/swagger/definitions/erm_agreement.yaml (+10 lines)
Lines 69-74 properties: Link Here
69
    type:
69
    type:
70
      - object
70
      - object
71
      - "null"
71
      - "null"
72
  extended_attributes:
73
    description: Related additional field values
74
    type:
75
      - array
76
    items:
77
      $ref: extended_attribute_value.yaml
78
  _strings:
79
    type:
80
      - object
81
      - "null"
72
82
73
additionalProperties: false
83
additionalProperties: false
74
required:
84
required:
(-)a/api/v1/swagger/paths/erm_agreements.yaml (+6 lines)
Lines 69-74 Link Here
69
          enum:
69
          enum:
70
            - user_roles
70
            - user_roles
71
            - vendor
71
            - vendor
72
            - extended_attributes
73
            - +strings
72
        collectionFormat: csv
74
        collectionFormat: csv
73
      - $ref: "../swagger.yaml#/parameters/match"
75
      - $ref: "../swagger.yaml#/parameters/match"
74
      - $ref: "../swagger.yaml#/parameters/order_by"
76
      - $ref: "../swagger.yaml#/parameters/order_by"
Lines 198-203 Link Here
198
            - agreement_packages.package
200
            - agreement_packages.package
199
            - documents
201
            - documents
200
            - vendor
202
            - vendor
203
            - extended_attributes
204
            - +strings
201
        collectionFormat: csv
205
        collectionFormat: csv
202
    responses:
206
    responses:
203
      200:
207
      200:
Lines 265-270 Link Here
265
            - agreement_licenses
269
            - agreement_licenses
266
            - agreement_relationships
270
            - agreement_relationships
267
            - documents
271
            - documents
272
            - extended_attributes
273
            - +strings
268
        collectionFormat: csv
274
        collectionFormat: csv
269
    responses:
275
    responses:
270
      200:
276
      200:
(-)a/api/v1/swagger/paths/extended_attribute_types.yaml (+1 lines)
Lines 19-24 Link Here
19
          - debit
19
          - debit
20
          - invoice
20
          - invoice
21
          - license
21
          - license
22
          - agreement
22
          - order
23
          - order
23
          - subscription
24
          - subscription
24
      - $ref: "../swagger.yaml#/parameters/match"
25
      - $ref: "../swagger.yaml#/parameters/match"
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/additional-fields.tt (-2 / +3 lines)
Lines 23-29 Link Here
23
</head>
23
</head>
24
24
25
[% marcfield_tables = ['subscription', 'aqorders'] %]
25
[% marcfield_tables = ['subscription', 'aqorders'] %]
26
[% searchable_tables = ['subscription', 'aqbasket', 'aqinvoices', 'erm_licenses'] %]
26
[% searchable_tables = ['subscription', 'aqbasket', 'aqinvoices', 'erm_licenses', 'erm_agreements'] %]
27
[% show_marcfield = marcfield_tables.grep('^' _ tablename _ '$').size ? 1 : 0 %]
27
[% show_marcfield = marcfield_tables.grep('^' _ tablename _ '$').size ? 1 : 0 %]
28
[% show_searchable = searchable_tables.grep('^' _ tablename _ '$').size ? 1 : 0 %]
28
[% show_searchable = searchable_tables.grep('^' _ tablename _ '$').size ? 1 : 0 %]
29
29
Lines 136-142 Link Here
136
                    [% WRAPPER table_option value="accountlines:debit" %]Account lines (debit)[% END %]
136
                    [% WRAPPER table_option value="accountlines:debit" %]Account lines (debit)[% END %]
137
                [% END %]
137
                [% END %]
138
                [% IF CAN_user_erm %]
138
                [% IF CAN_user_erm %]
139
                    [% WRAPPER table_option value="erm_licenses" %]ERM licenses[% END %]
139
                    [% WRAPPER table_option value="erm_licenses" %]ERM Licenses[% END %]
140
                    [% WRAPPER table_option value="erm_agreements" %]ERM Agreements[% END %]
140
                [% END %]
141
                [% END %]
141
            </ul>
142
            </ul>
142
            [% ELSE %]
143
            [% ELSE %]
(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsFormAdd.vue (+12 lines)
Lines 132-137 Link Here
132
                        </li>
132
                        </li>
133
                    </ol>
133
                    </ol>
134
                </fieldset>
134
                </fieldset>
135
                <AdditionalFieldsEntry
136
                    resource_type="agreement"
137
                    :additional_field_values="agreement.extended_attributes"
138
                    @additional-fields-changed="additionalFieldsChanged"
139
                />
135
                <AgreementPeriods :periods="agreement.periods" />
140
                <AgreementPeriods :periods="agreement.periods" />
136
                <UserRoles
141
                <UserRoles
137
                    :user_type="$__('Agreement user %s')"
142
                    :user_type="$__('Agreement user %s')"
Lines 174-179 import UserRoles from "./UserRoles.vue" Link Here
174
import AgreementLicenses from "./AgreementLicenses.vue"
179
import AgreementLicenses from "./AgreementLicenses.vue"
175
import AgreementRelationships from "./AgreementRelationships.vue"
180
import AgreementRelationships from "./AgreementRelationships.vue"
176
import Documents from "./Documents.vue"
181
import Documents from "./Documents.vue"
182
import AdditionalFieldsEntry from "../AdditionalFieldsEntry.vue"
177
import ButtonSubmit from "../ButtonSubmit.vue"
183
import ButtonSubmit from "../ButtonSubmit.vue"
178
import FormSelectVendors from "../FormSelectVendors.vue"
184
import FormSelectVendors from "../FormSelectVendors.vue"
179
import { setMessage, setError, setWarning } from "../../messages"
185
import { setMessage, setError, setWarning } from "../../messages"
Lines 221-226 export default { Link Here
221
                agreement_licenses: [],
227
                agreement_licenses: [],
222
                agreement_relationships: [],
228
                agreement_relationships: [],
223
                documents: [],
229
                documents: [],
230
                extended_attributes: [],
224
            },
231
            },
225
            initialized: false,
232
            initialized: false,
226
        }
233
        }
Lines 329-334 export default { Link Here
329
336
330
            delete agreement.agreement_id
337
            delete agreement.agreement_id
331
            delete agreement.vendor
338
            delete agreement.vendor
339
            delete agreement._strings
332
            agreement.is_perpetual = agreement.is_perpetual ? true : false
340
            agreement.is_perpetual = agreement.is_perpetual ? true : false
333
341
334
            if (agreement.vendor_id == "") {
342
            if (agreement.vendor_id == "") {
Lines 388-393 export default { Link Here
388
                this.agreement.closure_reason = ""
396
                this.agreement.closure_reason = ""
389
            }
397
            }
390
        },
398
        },
399
        additionalFieldsChanged(additionalFieldValues) {
400
            this.agreement.extended_attributes = additionalFieldValues
401
        },
391
    },
402
    },
392
    components: {
403
    components: {
393
        AgreementPeriods,
404
        AgreementPeriods,
Lines 397-402 export default { Link Here
397
        Documents,
408
        Documents,
398
        ButtonSubmit,
409
        ButtonSubmit,
399
        FormSelectVendors,
410
        FormSelectVendors,
411
        AdditionalFieldsEntry,
400
    },
412
    },
401
    name: "AgreementsFormAdd",
413
    name: "AgreementsFormAdd",
402
}
414
}
(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsList.vue (-2 / +49 lines)
Lines 43-48 Link Here
43
            <KohaTable
43
            <KohaTable
44
                ref="table"
44
                ref="table"
45
                v-bind="tableOptions"
45
                v-bind="tableOptions"
46
                :searchable_additional_fields="searchable_additional_fields"
47
                :searchable_av_options="searchable_av_options"
46
                @show="doShow"
48
                @show="doShow"
47
                @edit="doEdit"
49
                @edit="doEdit"
48
                @delete="doDelete"
50
                @delete="doDelete"
Lines 109-117 export default { Link Here
109
            fp_config: flatpickr_defaults,
111
            fp_config: flatpickr_defaults,
110
            agreement_count: 0,
112
            agreement_count: 0,
111
            initialized: false,
113
            initialized: false,
114
            searchable_additional_fields: [],
115
            searchable_av_options: [],
112
            tableOptions: {
116
            tableOptions: {
113
                columns: this.getTableColumns(),
117
                columns: this.getTableColumns(),
114
                options: { embed: "user_roles,vendor" },
118
                options: { embed: "user_roles,vendor,extended_attributes,+strings" },
115
                url: () => this.table_url(),
119
                url: () => this.table_url(),
116
                table_settings: this.agreement_table_settings,
120
                table_settings: this.agreement_table_settings,
117
                add_filters: true,
121
                add_filters: true,
Lines 161-167 export default { Link Here
161
    },
165
    },
162
    beforeRouteEnter(to, from, next) {
166
    beforeRouteEnter(to, from, next) {
163
        next(vm => {
167
        next(vm => {
164
            vm.getAgreementCount().then(() => (vm.initialized = true))
168
            vm.getAgreementCount().then(() =>
169
                vm
170
                    .getSearchableAdditionalFields()
171
                    .then(() =>
172
                        vm
173
                            .getSearchableAVOptions()
174
                            .then(() => (vm.initialized = true))
175
                    )
176
            )
165
        })
177
        })
166
    },
178
    },
167
    methods: {
179
    methods: {
Lines 173-178 export default { Link Here
173
                },
185
                },
174
                error => {}
186
                error => {}
175
            )
187
            )
188
        },
189
	    async getSearchableAdditionalFields() {
190
            const client = APIClient.additional_fields
191
            await client.additional_fields.getAll("agreement").then(
192
                searchable_additional_fields => {
193
                    this.searchable_additional_fields =
194
                        searchable_additional_fields.filter(
195
                            field => field.searchable
196
                        )
197
                },
198
                error => {}
199
            )
200
        },
201
        async getSearchableAVOptions() {
202
            const client_av = APIClient.authorised_values
203
            let av_cat_array = this.searchable_additional_fields
204
                .filter(field => field.authorised_value_category_name)
205
                .map(field => field.authorised_value_category_name)
206
207
            await client_av.values
208
                .getCategoriesWithValues([
209
                    ...new Set(av_cat_array.map(av_cat => '"' + av_cat + '"')),
210
                ]) // unique
211
                .then(av_categories => {
212
                    av_cat_array.forEach(av_cat => {
213
                        let av_match = av_categories.find(
214
                            element => element.category_name == av_cat
215
                        )
216
                        this.searchable_av_options[av_cat] =
217
                            av_match.authorised_values.map(av => ({
218
                                value: av.value,
219
                                label: av.description,
220
                            }))
221
                    })
222
                })
176
        },
223
        },
177
        doShow: function ({ agreement_id }, dt, event) {
224
        doShow: function ({ agreement_id }, dt, event) {
178
            event.preventDefault()
225
            event.preventDefault()
(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsShow.vue (-1 / +10 lines)
Lines 322-327 Link Here
322
                    </li>
322
                    </li>
323
                </ol>
323
                </ol>
324
            </fieldset>
324
            </fieldset>
325
            <AdditionalFieldsDisplay
326
                resource_type="agreement"
327
                :additional_field_values="
328
                    agreement._strings.additional_field_values
329
                "
330
            />
325
            <fieldset class="action">
331
            <fieldset class="action">
326
                <router-link
332
                <router-link
327
                    :to="{ name: 'AgreementsList' }"
333
                    :to="{ name: 'AgreementsList' }"
Lines 339-344 import { inject } from "vue" Link Here
339
import { APIClient } from "../../fetch/api-client.js"
345
import { APIClient } from "../../fetch/api-client.js"
340
import Toolbar from "../Toolbar.vue"
346
import Toolbar from "../Toolbar.vue"
341
import ToolbarButton from "../ToolbarButton.vue"
347
import ToolbarButton from "../ToolbarButton.vue"
348
import AdditionalFieldsDisplay from "../AdditionalFieldsDisplay.vue"
342
349
343
export default {
350
export default {
344
    setup() {
351
    setup() {
Lines 373-378 export default { Link Here
373
                license_info: "",
380
                license_info: "",
374
                periods: [],
381
                periods: [],
375
                user_roles: [],
382
                user_roles: [],
383
                extended_attributes: [],
384
                _strings: [],
376
                agreement_packages: [],
385
                agreement_packages: [],
377
            },
386
            },
378
            initialized: false,
387
            initialized: false,
Lines 425-431 export default { Link Here
425
            )
434
            )
426
        },
435
        },
427
    },
436
    },
428
    components: { Toolbar, ToolbarButton },
437
    components: { Toolbar, ToolbarButton, AdditionalFieldsDisplay },
429
    name: "AgreementsShow",
438
    name: "AgreementsShow",
430
}
439
}
431
</script>
440
</script>
(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/erm-api-client.js (-1 / +1 lines)
Lines 23-29 export class ERMAPIClient extends HttpClient { Link Here
23
                    endpoint: "agreements/" + id,
23
                    endpoint: "agreements/" + id,
24
                    headers: {
24
                    headers: {
25
                        "x-koha-embed":
25
                        "x-koha-embed":
26
                            "periods,user_roles,user_roles.patron,agreement_licenses,agreement_licenses.license,agreement_relationships,agreement_relationships.related_agreement,documents,agreement_packages,agreement_packages.package,vendor",
26
                            "periods,user_roles,user_roles.patron,agreement_licenses,agreement_licenses.license,agreement_relationships,agreement_relationships.related_agreement,documents,agreement_packages,agreement_packages.package,vendor,extended_attributes,+strings",
27
                    },
27
                    },
28
                }),
28
                }),
29
            getAll: (query, params) =>
29
            getAll: (query, params) =>
(-)a/t/cypress/integration/AdditionalFields_spec.ts (-1 / +568 lines)
Lines 83-88 function get_licenses_additional_fields() { Link Here
83
    ];
83
    ];
84
}
84
}
85
85
86
function get_no_additional_fields_agreement() {
87
    return {
88
        agreement_id: 1,
89
        name: "agreement 1",
90
        description: "my first agreement",
91
        agreement_licenses: [],
92
        agreement_packages: [],
93
        agreement_relationships: [],
94
        closure_reason: "",
95
        is_perpetual: false,
96
        license_info: "",
97
        periods: [],
98
        renewal_priority: "",
99
        status: "active",
100
        user_roles: [],
101
        vendor_id: 1,
102
        vendor: [cy.get_vendors_to_relate()[0]],
103
        documents: [
104
            {
105
                agreement_id: 1,
106
                file_description: "file description",
107
                file_name: "file.json",
108
                notes: "file notes",
109
                physical_location: "file physical location",
110
                uri: "file uri",
111
                uploaded_on: "2022-10-27T11:57:02+00:00",
112
            },
113
        ],
114
        extended_attributes: [],
115
        _strings: {
116
            "additional_field_values": []
117
        },
118
    };
119
}
120
function get_agreement() {
121
    return {
122
        agreement_id: 1,
123
        name: "agreement 1",
124
        description: "my first agreement",
125
        agreement_licenses: [],
126
        agreement_packages: [],
127
        agreement_relationships: [],
128
        closure_reason: "",
129
        is_perpetual: false,
130
        license_info: "",
131
        periods: [],
132
        renewal_priority: "",
133
        status: "active",
134
        user_roles: [],
135
        vendor_id: 1,
136
        vendor: [cy.get_vendors_to_relate()[0]],
137
        documents: [
138
            {
139
                agreement_id: 1,
140
                file_description: "file description",
141
                file_name: "file.json",
142
                notes: "file notes",
143
                physical_location: "file physical location",
144
                uri: "file uri",
145
                uploaded_on: "2022-10-27T11:57:02+00:00",
146
            },
147
        ],
148
        extended_attributes: [
149
            {
150
                field_id: 1,
151
                id: "1",
152
                record_id: "1",
153
                value: "REF",
154
            },
155
            {
156
                field_id: 1,
157
                id: "2",
158
                record_id: "1",
159
                value: "NFIC",
160
            },
161
            {
162
                field_id: 2,
163
                id: "3",
164
                record_id: "1",
165
                value: "some text",
166
            },
167
            {
168
                field_id: 3,
169
                id: "4",
170
                record_id: "1",
171
                value: "some repeatable text",
172
            },
173
            {
174
                field_id: 4,
175
                id: "5",
176
                record_id: "1",
177
                value: "AF",
178
            },
179
        ],
180
        _strings: {
181
            additional_field_values: [
182
                {
183
                    field_id: 1,
184
                    field_label: "AV Repeatable",
185
                    type: "av",
186
                    value_str: "Reference, Non-fiction",
187
                },
188
                {
189
                    field_id: 2,
190
                    field_label: "Text non-repeatable",
191
                    type: "text",
192
                    value_str: "some text",
193
                },
194
                {
195
                    field_id: 3,
196
                    field_label: "Text repeatable",
197
                    type: "text",
198
                    value_str: "some repeatable text",
199
                },
200
                {
201
                    field_id: 4,
202
                    field_label: "AV Searchable",
203
                    type: "av",
204
                    value_str: "Afghanistan",
205
                },
206
            ],
207
        },
208
    };
209
}
210
211
function get_agreements_additional_fields() {
212
    return [
213
        {
214
            authorised_value_category_name: "CCODE",
215
            extended_attribute_type_id: 1,
216
            marcfield: "",
217
            marcfield_mode: "get",
218
            name: "AV Repeatable",
219
            repeatable: true,
220
            searchable: true,
221
            resource_type: "agreement",
222
        },
223
        {
224
            authorised_value_category_name: null,
225
            extended_attribute_type_id: 2,
226
            marcfield: "",
227
            marcfield_mode: "get",
228
            name: "Text non-repeatable",
229
            repeatable: false,
230
            searchable: false,
231
            resource_type: "agreement",
232
        },
233
        {
234
            authorised_value_category_name: null,
235
            extended_attribute_type_id: 3,
236
            marcfield: "",
237
            marcfield_mode: "get",
238
            name: "Text repeatable",
239
            repeatable: true,
240
            searchable: false,
241
            resource_type: "agreement",
242
        },
243
        {
244
            authorised_value_category_name: "COUNTRY",
245
            extended_attribute_type_id: 4,
246
            marcfield: "",
247
            marcfield_mode: "get",
248
            name: "AV Searchable",
249
            repeatable: false,
250
            searchable: true,
251
            resource_type: "agreement",
252
        },
253
    ];
254
}
255
86
function get_av_cats() {
256
function get_av_cats() {
87
    return [
257
    return [
88
        {
258
        {
Lines 167-172 describe("Additional Fields operations", () => { Link Here
167
        );
337
        );
168
    });
338
    });
169
339
340
    //
341
    // for licenses
342
    //
343
170
    it("Additional Fields display - Table (licenses)", () => {
344
    it("Additional Fields display - Table (licenses)", () => {
171
        let license = cy.get_license();
345
        let license = cy.get_license();
172
        let licenses = [license];
346
        let licenses = [license];
Lines 555-558 describe("Additional Fields operations", () => { Link Here
555
            "#licenses_add form #additional_fields label[for='additional_field_3']"
729
            "#licenses_add form #additional_fields label[for='additional_field_3']"
556
        ).should("have.length", 2);
730
        ).should("have.length", 2);
557
    });
731
    });
732
733
    //
734
    // for agreements
735
    //
736
737
    it("Additional Fields display - Table (agreements)", () => {
738
        let agreement = get_agreement();
739
        let agreements = [agreement];
740
        let agreement_additional_fields = get_agreements_additional_fields();
741
        let av_cats = get_av_cats();
742
743
        cy.intercept("GET", "/api/v1/extended_attribute_types*", {
744
            body: agreement_additional_fields,
745
            statusCode: 200,
746
        });
747
748
        cy.intercept("GET", "/api/v1/erm/agreements*", {
749
            statusCode: 200,
750
            body: agreements,
751
            headers: {
752
                "X-Base-Total-Count": "1",
753
                "X-Total-Count": "1",
754
            },
755
        });
756
        cy.intercept("GET", "/api/v1/erm/agreements/*", agreement);
757
        cy.visit("/cgi-bin/koha/erm/agreements");
758
        cy.get("#agreements_list").contains("Showing 1 to 1 of 1 entries");
759
760
        cy.get("#agreements_list table tbody tr:first").contains(
761
            get_description_from_av_value(
762
                av_cats,
763
                agreement.extended_attributes[4]
764
            )
765
        );
766
        cy.get("#agreements_list table tbody tr:first").contains(
767
            get_description_from_av_value(
768
                av_cats,
769
                agreement.extended_attributes[0]
770
            ) +
771
                ", " +
772
                get_description_from_av_value(
773
                    av_cats,
774
                    agreement.extended_attributes[1]
775
                )
776
        );
777
    });
778
779
    it("Additional Fields display - Show (agreements)", () => {
780
        let empty_agreement = get_no_additional_fields_agreement();
781
        let agreement = get_agreement();
782
        let agreements = [agreement];
783
        let vendors = cy.get_vendors_to_relate();
784
        let agreement_additional_fields = get_agreements_additional_fields();
785
        let av_cats = get_av_cats();
786
787
        // Click the 'Edit' button from the list
788
        cy.intercept("GET", "/api/v1/erm/agreements*", {
789
            statusCode: 200,
790
            body: agreements,
791
            headers: {
792
                "X-Base-Total-Count": "1",
793
                "X-Total-Count": "1",
794
            },
795
        });
796
        cy.intercept("GET", "/api/v1/erm/agreements/*", empty_agreement).as(
797
            "get-empty-agreement"
798
        );
799
800
        //Intercept vendors request
801
        cy.intercept("GET", "/api/v1/acquisitions/vendors*", {
802
            statusCode: 200,
803
            body: vendors,
804
        });
805
        cy.intercept("GET", "/api/v1/extended_attribute_types*", {
806
            body: [],
807
            statusCode: 200,
808
        }).as("empty-additional-fields");
809
810
        //Empty additional fields, should not display
811
        cy.visit("/cgi-bin/koha/erm/agreements");
812
        cy.get("#agreements_list table tbody tr:first td:first a").click();
813
        cy.wait("@get-empty-agreement");
814
        cy.get("#agreements_show #additional_fields").should("not.exist");
815
816
        cy.intercept("GET", "/api/v1/extended_attribute_types*", {
817
            body: agreement_additional_fields,
818
            statusCode: 200,
819
        }).as("existing-additional-fields");
820
821
        cy.intercept(
822
            {
823
                pathname: "/api/v1/authorised_value_categories",
824
                query: {
825
                    q: '{"me.category_name":["CCODE", "COUNTRY"]}',
826
                },
827
            },
828
            {
829
                body: av_cats,
830
                statusCode: 200,
831
            }
832
        ).as("avcategories");
833
834
        cy.intercept("GET", "/api/v1/erm/agreements/*", agreement).as(
835
            "get-agreement"
836
        );
837
838
        // There are additional fields, fieldset should exist
839
        cy.visit("/cgi-bin/koha/erm/agreements");
840
        cy.get("#agreements_list table tbody tr:first td:first a").click();
841
        cy.wait("@get-agreement");
842
        cy.get("#agreements_show #additional_fields").should("exist");
843
844
        // All fields are presented correctly
845
        cy.get(
846
            "#agreements_show #additional_fields label[for='additional_field_1']"
847
        ).contains(agreement_additional_fields[0].name);
848
        cy.get(
849
            "#agreements_show #additional_fields label[for='additional_field_1']"
850
        )
851
            .parent()
852
            .children("span")
853
            .contains(
854
                get_description_from_av_value(
855
                    av_cats,
856
                    agreement.extended_attributes[0]
857
                ) +
858
                    ", " +
859
                    get_description_from_av_value(
860
                        av_cats,
861
                        agreement.extended_attributes[1]
862
                    )
863
            );
864
865
        cy.get(
866
            "#agreements_show #additional_fields label[for='additional_field_2']"
867
        ).contains(agreement_additional_fields[1].name);
868
        cy.get(
869
            "#agreements_show #additional_fields label[for='additional_field_2']"
870
        )
871
            .parent()
872
            .children("span")
873
            .contains(agreement.extended_attributes[2].value);
874
875
        cy.get(
876
            "#agreements_show #additional_fields label[for='additional_field_3']"
877
        ).contains(agreement_additional_fields[2].name);
878
        cy.get(
879
            "#agreements_show #additional_fields label[for='additional_field_3']"
880
        )
881
            .parent()
882
            .children("span")
883
            .contains(agreement.extended_attributes[3].value);
884
885
        cy.get(
886
            "#agreements_show #additional_fields label[for='additional_field_4']"
887
        ).contains(agreement_additional_fields[3].name);
888
        cy.get(
889
            "#agreements_show #additional_fields label[for='additional_field_4']"
890
        )
891
            .parent()
892
            .children("span")
893
            .contains(
894
                get_description_from_av_value(
895
                    av_cats,
896
                    agreement.extended_attributes[4]
897
                )
898
            );
899
    });
900
901
    it("Additional Fields entry - Add (agreements)", () => {
902
        let vendors = cy.get_vendors_to_relate();
903
        let agreement_additional_fields = get_licenses_additional_fields();
904
        let av_cats = get_av_cats();
905
906
        //Intercept vendors request
907
        cy.intercept("GET", "/api/v1/acquisitions/vendors*", {
908
            statusCode: 200,
909
            body: vendors,
910
        });
911
        cy.intercept("GET", "/api/v1/extended_attribute_types*", {
912
            body: [],
913
            statusCode: 200,
914
        }).as("empty-additional-fields");
915
916
        // No additional fields, fieldset should not exist
917
        cy.visit("/cgi-bin/koha/erm/agreements/add");
918
        cy.get("#agreements_add form #additional_fields").should("not.exist");
919
920
        cy.intercept("GET", "/api/v1/extended_attribute_types*", {
921
            body: agreement_additional_fields,
922
            statusCode: 200,
923
        }).as("existing-additional-fields");
924
925
        cy.intercept(
926
            {
927
                pathname: "/api/v1/authorised_value_categories",
928
                query: {
929
                    q: '{"me.category_name":["CCODE", "COUNTRY"]}',
930
                },
931
            },
932
            {
933
                body: av_cats,
934
                statusCode: 200,
935
            }
936
        ).as("avcategories");
937
        // There are additional fields, fieldset should exist
938
        cy.visit("/cgi-bin/koha/erm/agreements/add");
939
        cy.get("#agreements_add form #additional_fields").should("exist");
940
941
        // All additional fields should be listed
942
        cy.get(
943
            "#agreements_add form #additional_fields label[for='additional_field_1']"
944
        ).contains(agreement_additional_fields[0].name);
945
        cy.get(
946
            "#agreements_add form #additional_fields label[for='additional_field_2']"
947
        ).contains(agreement_additional_fields[1].name);
948
        cy.get(
949
            "#agreements_add form #additional_fields label[for='additional_field_3']"
950
        ).contains(agreement_additional_fields[2].name);
951
        cy.get(
952
            "#agreements_add form #additional_fields label[for='additional_field_4']"
953
        ).contains(agreement_additional_fields[3].name);
954
955
        cy.get("#additional_fields #additional_field_1 .vs__selected").should(
956
            "not.exist"
957
        ); //new agreement, no pre-selected value
958
959
        // Pick one value
960
        cy.get("#additional_fields #additional_field_1 .vs__search").click();
961
        cy.get(
962
            "#additional_fields #additional_field_1 #vs5__option-0"
963
        ).contains(av_cats[0].authorised_values[0].description);
964
        cy.get("#additional_fields #additional_field_1 #vs5__option-0").click();
965
        cy.get("#additional_fields #additional_field_1 .vs__selected").contains(
966
            av_cats[0].authorised_values[0].description
967
        );
968
        cy.get("#additional_fields #additional_field_1 .vs__selected").should(
969
            "have.length",
970
            1
971
        );
972
973
        // Pick a second value for the same repeatable AV field
974
        cy.get("#additional_fields #additional_field_1 .vs__search").click();
975
        cy.get(
976
            "#additional_fields #additional_field_1 #vs5__option-1"
977
        ).contains(av_cats[0].authorised_values[1].description);
978
        cy.get("#additional_fields #additional_field_1 #vs5__option-1").click();
979
        cy.get("#additional_fields #additional_field_1 .vs__selected").contains(
980
            av_cats[0].authorised_values[1].description
981
        );
982
        cy.get("#additional_fields #additional_field_1 .vs__selected").should(
983
            "have.length",
984
            2
985
        );
986
987
        // Attempt to pick the same value again - should not be possible
988
        cy.get("#additional_fields #additional_field_1 .vs__search").click();
989
        cy.get(
990
            "#additional_fields #additional_field_1 #vs5__option-1"
991
        ).contains(av_cats[0].authorised_values[1].description);
992
        cy.get("#additional_fields #additional_field_1 #vs5__option-1").click();
993
        cy.get("#additional_fields #additional_field_1 .vs__selected").should(
994
            "have.length",
995
            2
996
        );
997
998
        // Remove the second selected value
999
        cy.get(
1000
            "#additional_fields #additional_field_1 .vs__selected button[title='Deselect " +
1001
                av_cats[0].authorised_values[1].description +
1002
                "'"
1003
        ).click();
1004
        cy.get("#additional_fields #additional_field_1 .vs__selected").should(
1005
            "have.length",
1006
            1
1007
        );
1008
        cy.get("#additional_fields #additional_field_1 .vs__selected").contains(
1009
            av_cats[0].authorised_values[0].description
1010
        );
1011
    });
1012
1013
    it("Additional Fields entry - Edit (agreements)", () => {
1014
        let agreement = get_agreement();
1015
        let agreements = [agreement];
1016
        let vendors = cy.get_vendors_to_relate();
1017
        let agreement_additional_fields = get_agreements_additional_fields();
1018
        let av_cats = get_av_cats();
1019
1020
        // Click the 'Edit' button from the list
1021
        cy.intercept("GET", "/api/v1/erm/agreements*", {
1022
            statusCode: 200,
1023
            body: agreements,
1024
            headers: {
1025
                "X-Base-Total-Count": "1",
1026
                "X-Total-Count": "1",
1027
            },
1028
        });
1029
        cy.intercept("GET", "/api/v1/erm/agreements/*", agreement).as(
1030
            "get-agreement"
1031
        );
1032
1033
        //Intercept vendors request
1034
        cy.intercept("GET", "/api/v1/acquisitions/vendors*", {
1035
            statusCode: 200,
1036
            body: vendors,
1037
        });
1038
1039
        cy.intercept("GET", "/api/v1/extended_attribute_types*", {
1040
            body: agreement_additional_fields,
1041
            statusCode: 200,
1042
        }).as("existing-additional-fields");
1043
1044
        cy.intercept(
1045
            {
1046
                pathname: "/api/v1/authorised_value_categories",
1047
                query: {
1048
                    q: '{"me.category_name":["CCODE", "COUNTRY"]}',
1049
                },
1050
            },
1051
            {
1052
                body: av_cats,
1053
                statusCode: 200,
1054
            }
1055
        ).as("avcategories");
1056
1057
        cy.visit("/cgi-bin/koha/erm/agreements");
1058
        cy.get("#agreements_list table tbody tr:first").contains("Edit").click();
1059
        cy.wait("@get-agreement");
1060
        cy.wait(500); // Cypress is too fast! Vue hasn't populated the form yet!
1061
1062
        // All additional fields should be pre-populated
1063
        cy.get("#additional_fields #additional_field_1 .vs__selected").contains(
1064
            get_description_from_av_value(
1065
                av_cats,
1066
                agreement.extended_attributes[0]
1067
            )
1068
        );
1069
        cy.get("#additional_fields #additional_field_1 .vs__selected").contains(
1070
            get_description_from_av_value(
1071
                av_cats,
1072
                agreement.extended_attributes[1]
1073
            )
1074
        );
1075
1076
        cy.get(
1077
            "#agreements_add form #additional_fields label[for='additional_field_2']"
1078
        )
1079
            .parent()
1080
            .children("input")
1081
            .should("have.value", agreement.extended_attributes[2].value);
1082
1083
        cy.get(
1084
            "#agreements_add form #additional_fields label[for='additional_field_3']"
1085
        )
1086
            .parent()
1087
            .children("input")
1088
            .should("have.value", agreement.extended_attributes[3].value);
1089
1090
        cy.get("#additional_fields #additional_field_4 .vs__selected").contains(
1091
            get_description_from_av_value(
1092
                av_cats,
1093
                agreement.extended_attributes[4]
1094
            )
1095
        );
1096
1097
        // Clear text field works
1098
        cy.get(
1099
            "#agreements_add form #additional_fields label[for='additional_field_2']"
1100
        )
1101
            .parent()
1102
            .children(".clear_attribute")
1103
            .click();
1104
        cy.get(
1105
            "#agreements_add form #additional_fields label[for='additional_field_2']"
1106
        )
1107
            .parent()
1108
            .children("input")
1109
            .should("have.value", "");
1110
1111
        // "+New" text field works
1112
        cy.get(
1113
            "#agreements_add form #additional_fields label[for='additional_field_3']"
1114
        ).should("have.length", 1);
1115
        cy.get(
1116
            "#agreements_add form #additional_fields label[for='additional_field_3']"
1117
        )
1118
            .parent()
1119
            .children(".clone_attribute")
1120
            .click();
1121
        cy.get(
1122
            "#agreements_add form #additional_fields label[for='additional_field_3']"
1123
        ).should("have.length", 2);
1124
    });
1125
558
});
1126
});
559
- 

Return to bug 37576