2 <div v-if="!initialized">{{ $__("Loading") }}</div>
3 <div v-else id="agreements_add">
4 <h2 v-if="agreement.agreement_id">
5 {{ $__("Edit agreement #%s").format(agreement.agreement_id) }}
7 <h2 v-else>{{ $__("New agreement") }}</h2>
9 <form @submit="onSubmit($event)">
10 <div class="page-section">
11 <fieldset class="rows">
14 <label class="required" for="agreement_name"
15 >{{ $__("Agreement name") }}:</label
19 v-model="agreement.name"
20 :placeholder="$__('Agreement name')"
23 <span class="required">{{
28 <label for="agreement_vendor_id"
29 >{{ $__("Vendor") }}:</label
32 id="agreement_vendor_id"
33 v-model="agreement.vendor_id"
35 :reduce="vendor => vendor.id"
40 <label for="agreement_description"
41 >{{ $__("Description") }}:
44 id="agreement_description"
45 v-model="agreement.description"
46 :placeholder="$__('Description')"
53 <label for="agreement_status"
54 >{{ $__("Status") }}:</label
58 v-model="agreement.status"
60 :reduce="av => av.authorised_value"
61 :options="av_agreement_statuses"
62 @option:selected="onStatusChanged"
63 :required="!agreement.status"
65 <template #search="{ attributes, events }">
67 :required="!agreement.status"
74 <span class="required">{{
79 <label for="agreement_closure_reason"
80 >{{ $__("Closure reason") }}:</label
83 id="agreement_closure_reason"
84 v-model="agreement.closure_reason"
86 :reduce="av => av.authorised_value"
87 :options="av_agreement_closure_reasons"
89 agreement.status == 'closed'
97 for="agreement_is_perpetual"
99 >{{ $__("Is perpetual") }}:</label
101 <label for="agreement_is_perpetual_yes">
105 id="agreement_is_perpetual_yes"
107 v-model="agreement.is_perpetual"
111 <label for="agreement_is_perpetual_no">
115 id="agreement_is_perpetual_no"
117 v-model="agreement.is_perpetual"
123 <label for="agreement_renewal_priority"
124 >{{ $__("Renewal priority") }}:</label
127 id="agreement_renewal_priority"
128 v-model="agreement.renewal_priority"
130 :reduce="av => av.authorised_value"
131 :options="av_agreement_renewal_priorities"
135 <label for="agreement_license_info"
136 >{{ $__("License info") }}:
139 id="agreement_license_info"
140 v-model="agreement.license_info"
141 placeholder="License info"
147 <AgreementPeriods :periods="agreement.periods" />
149 :user_type="$__('Agreement user')"
150 :user_roles="agreement.user_roles"
151 :av_user_roles="av_user_roles"
154 :agreement_licenses="agreement.agreement_licenses"
155 :av_agreement_license_statuses="
156 av_agreement_license_statuses
158 :av_agreement_license_location="
159 av_agreement_license_location
162 <AgreementRelationships
163 :agreement_id="agreement.agreement_id"
164 :relationships="agreement.agreement_relationships"
165 :av_agreement_relationships="av_agreement_relationships"
167 <Documents :documents="agreement.documents" />
168 <fieldset class="action">
169 <input type="submit" value="Submit" />
171 to="/cgi-bin/koha/erm/agreements"
174 >{{ $__("Cancel") }}</router-link
183 import { inject } from "vue"
184 import AgreementPeriods from "./AgreementPeriods.vue"
185 import UserRoles from "./UserRoles.vue"
186 import AgreementLicenses from "./AgreementLicenses.vue"
187 import AgreementRelationships from "./AgreementRelationships.vue"
188 import Documents from "./Documents.vue"
189 import { setMessage, setError, setWarning } from "../../messages"
190 import { fetchAgreement, checkError } from "../../fetch"
191 import { storeToRefs } from "pinia"
195 const vendorStore = inject("vendorStore")
196 const { vendors } = storeToRefs(vendorStore)
198 const AVStore = inject("AVStore")
200 av_agreement_statuses,
201 av_agreement_closure_reasons,
202 av_agreement_renewal_priorities,
204 av_agreement_license_statuses,
205 av_agreement_license_location,
206 av_agreement_relationships,
207 } = storeToRefs(AVStore)
211 av_agreement_statuses,
212 av_agreement_closure_reasons,
213 av_agreement_renewal_priorities,
215 av_agreement_license_statuses,
216 av_agreement_license_location,
217 av_agreement_relationships,
231 renewal_priority: "",
235 agreement_licenses: [],
236 agreement_relationships: [],
242 beforeRouteEnter(to, from, next) {
244 if (to.params.agreement_id) {
245 vm.agreement = vm.getAgreement(to.params.agreement_id)
247 vm.initialized = true
252 async getAgreement(agreement_id) {
253 const agreement = await fetchAgreement(agreement_id)
254 this.agreement = agreement
255 this.initialized = true
257 checkForm(agreement) {
260 let agreement_licenses = agreement.agreement_licenses
261 // Do not use al.license.name here! Its name is not the one linked with al.license_id
262 // At this point al.license is meaningless, form/template only modified al.license_id
263 const license_ids = agreement_licenses.map(al => al.license_id)
264 const duplicate_license_ids = license_ids.filter(
265 (id, i) => license_ids.indexOf(id) !== i
268 if (duplicate_license_ids.length) {
269 errors.push(this.$__("A license is used several times"))
272 const related_agreement_ids = agreement.agreement_relationships.map(
273 rs => rs.related_agreement_id
275 const duplicate_related_agreement_ids =
276 related_agreement_ids.filter(
277 (id, i) => related_agreement_ids.indexOf(id) !== i
280 if (duplicate_related_agreement_ids.length) {
283 "An agreement is used as relationship several times"
289 agreement_licenses.filter(al => al.status == "controlling")
292 errors.push(this.$__("Only one controlling license is allowed"))
296 agreement_licenses.filter(al => al.status == "controlling")
299 errors.push(this.$__("Only one controlling license is allowed"))
302 let documents_with_uploaded_files = agreement.documents.filter(
303 doc => typeof doc.file_content !== "undefined"
306 documents_with_uploaded_files.filter(
307 doc => atob(doc.file_content).length >= max_allowed_packet
311 this.$__("File size exceeds maximum allowed: %s MB").format(
312 (max_allowed_packet / (1024 * 1024)).toFixed(2)
316 errors.forEach(function (e) {
319 return !errors.length
324 //let agreement= Object.assign( {} ,this.agreement); // copy
325 let agreement = JSON.parse(JSON.stringify(this.agreement)) // copy
327 if (!this.checkForm(agreement)) {
331 let apiUrl = "/api/v1/erm/agreements"
334 if (agreement.agreement_id) {
336 apiUrl += "/" + agreement.agreement_id
338 delete agreement.agreement_id
339 delete agreement.vendor
340 agreement.is_perpetual = agreement.is_perpetual ? true : false
342 if (agreement.vendor_id == "") {
343 agreement.vendor_id = null
346 agreement.periods = agreement.periods.map(
347 ({ agreement_id, agreement_period_id, ...keepAttrs }) =>
351 agreement.user_roles = agreement.user_roles.map(
352 ({ patron, patron_str, ...keepAttrs }) => keepAttrs
355 agreement.agreement_licenses = agreement.agreement_licenses.map(
359 agreement_license_id,
364 agreement.agreement_relationships =
365 agreement.agreement_relationships.map(
366 ({ related_agreement, ...keepAttrs }) => keepAttrs
369 agreement.documents = agreement.documents.map(
370 ({ file_type, uploaded_on, ...keepAttrs }) => keepAttrs
373 delete agreement.agreement_packages
377 body: JSON.stringify(agreement),
379 "Content-Type": "application/json;charset=utf-8",
383 fetch(apiUrl, options)
384 .then(response => checkError(response, 1))
386 if (response.status == 200) {
387 this.$router.push("/cgi-bin/koha/erm/agreements")
388 setMessage(this.$__("Agreement updated"))
389 } else if (response.status == 201) {
390 this.$router.push("/cgi-bin/koha/erm/agreements")
391 setMessage(this.$__("Agreement created"))
393 setError(response.message || response.statusText)
401 if (e.authorised_value != "closed") {
402 this.agreement.closure_reason = ""
410 AgreementRelationships,
413 name: "AgreementsFormAdd",