Lines 12-24
Link Here
|
12 |
<div class="page-section bg-info" v-if="circRules.length"> |
12 |
<div class="page-section bg-info" v-if="circRules.length"> |
13 |
<h2>{{ $__("Trigger context") }}</h2> |
13 |
<h2>{{ $__("Trigger context") }}</h2> |
14 |
<TriggerContext :ruleInfo="ruleInfo" /> |
14 |
<TriggerContext :ruleInfo="ruleInfo" /> |
15 |
<h2>{{ $__("Existing rules") }}</h2> |
15 |
<h2 v-if="ruleInfo.numberOfTriggers > 0"> |
16 |
<p>{{ $__("Notice") }} {{ " " + newTriggerNumber - 1 }}</p> |
16 |
{{ $__("Existing rules") }} |
|
|
17 |
</h2> |
18 |
<p v-if="ruleInfo.numberOfTriggers > 0"> |
19 |
{{ $__("Notice") }} {{ " " + newTriggerNumber - 1 }} |
20 |
</p> |
17 |
<TriggersTable |
21 |
<TriggersTable |
|
|
22 |
v-if="ruleInfo.numberOfTriggers > 0" |
18 |
:circRules="circRules" |
23 |
:circRules="circRules" |
19 |
:triggerNumber="newTriggerNumber - 1" |
24 |
:triggerNumber="newTriggerNumber - 1" |
20 |
:modal="true" |
25 |
:modal="true" |
21 |
:ruleBeingEdited="ruleBeingEdited" |
26 |
:ruleBeingEdited="ruleBeingEdited" |
|
|
27 |
:triggerBeingEdited="triggerBeingEdited" |
22 |
:letters="letters" |
28 |
:letters="letters" |
23 |
/> |
29 |
/> |
24 |
</div> |
30 |
</div> |
Lines 30-36
Link Here
|
30 |
> |
36 |
> |
31 |
<v-select |
37 |
<v-select |
32 |
id="library_id" |
38 |
id="library_id" |
33 |
v-model="circRuleTrigger.library_id" |
39 |
v-model="newRule.library_id" |
34 |
label="name" |
40 |
label="name" |
35 |
:reduce="lib => lib.library_id" |
41 |
:reduce="lib => lib.library_id" |
36 |
:options="libraries" |
42 |
:options="libraries" |
Lines 39-45
Link Here
|
39 |
> |
45 |
> |
40 |
<template #search="{ attributes, events }"> |
46 |
<template #search="{ attributes, events }"> |
41 |
<input |
47 |
<input |
42 |
:required="!circRuleTrigger.library_id" |
48 |
:required="!newRule.library_id" |
43 |
class="vs__search" |
49 |
class="vs__search" |
44 |
v-bind="attributes" |
50 |
v-bind="attributes" |
45 |
v-on="events" |
51 |
v-on="events" |
Lines 54-60
Link Here
|
54 |
> |
60 |
> |
55 |
<v-select |
61 |
<v-select |
56 |
id="patron_category_id" |
62 |
id="patron_category_id" |
57 |
v-model="circRuleTrigger.patron_category_id" |
63 |
v-model="newRule.patron_category_id" |
58 |
label="name" |
64 |
label="name" |
59 |
:reduce="cat => cat.patron_category_id" |
65 |
:reduce="cat => cat.patron_category_id" |
60 |
:options="categories" |
66 |
:options="categories" |
Lines 63-71
Link Here
|
63 |
> |
69 |
> |
64 |
<template #search="{ attributes, events }"> |
70 |
<template #search="{ attributes, events }"> |
65 |
<input |
71 |
<input |
66 |
:required=" |
72 |
:required="!newRule.patron_category_id" |
67 |
!circRuleTrigger.patron_category_id |
|
|
68 |
" |
69 |
class="vs__search" |
73 |
class="vs__search" |
70 |
v-bind="attributes" |
74 |
v-bind="attributes" |
71 |
v-on="events" |
75 |
v-on="events" |
Lines 80-86
Link Here
|
80 |
> |
84 |
> |
81 |
<v-select |
85 |
<v-select |
82 |
id="item_type_id" |
86 |
id="item_type_id" |
83 |
v-model="circRuleTrigger.item_type_id" |
87 |
v-model="newRule.item_type_id" |
84 |
label="description" |
88 |
label="description" |
85 |
:reduce="type => type.item_type_id" |
89 |
:reduce="type => type.item_type_id" |
86 |
:options="itemTypes" |
90 |
:options="itemTypes" |
Lines 89-97
Link Here
|
89 |
> |
93 |
> |
90 |
<template #search="{ attributes, events }"> |
94 |
<template #search="{ attributes, events }"> |
91 |
<input |
95 |
<input |
92 |
:required=" |
96 |
:required="!newRule.item_type_id" |
93 |
!circRuleTrigger.item_type_id |
|
|
94 |
" |
95 |
class="vs__search" |
97 |
class="vs__search" |
96 |
v-bind="attributes" |
98 |
v-bind="attributes" |
97 |
v-on="events" |
99 |
v-on="events" |
Lines 106-113
Link Here
|
106 |
</label> |
108 |
</label> |
107 |
<input |
109 |
<input |
108 |
id="overdue_delay" |
110 |
id="overdue_delay" |
109 |
v-model="circRuleTrigger.delay" |
111 |
v-model="newRule.delay" |
110 |
type="number" |
112 |
type="number" |
|
|
113 |
:placeholder="fallbackRule.delay" |
114 |
:min="minDelay" |
111 |
/> |
115 |
/> |
112 |
</li> |
116 |
</li> |
113 |
<li> |
117 |
<li> |
Lines 116-122
Link Here
|
116 |
> |
120 |
> |
117 |
<v-select |
121 |
<v-select |
118 |
id="letter_code" |
122 |
id="letter_code" |
119 |
v-model="circRuleTrigger.notice" |
123 |
v-model="newRule.notice" |
120 |
label="name" |
124 |
label="name" |
121 |
:reduce="type => type.code" |
125 |
:reduce="type => type.code" |
122 |
:options="letters" |
126 |
:options="letters" |
Lines 126-142
Link Here
|
126 |
class="vs__search" |
130 |
class="vs__search" |
127 |
v-bind="attributes" |
131 |
v-bind="attributes" |
128 |
v-on="events" |
132 |
v-on="events" |
|
|
133 |
:placeholder=" |
134 |
letters.find( |
135 |
letter => |
136 |
letter.code === |
137 |
fallbackRule.notice |
138 |
)?.name || fallbackRule.notice |
139 |
" |
129 |
/> |
140 |
/> |
130 |
</template> |
141 |
</template> |
131 |
</v-select> |
142 |
</v-select> |
132 |
</li> |
143 |
</li> |
133 |
<li> |
144 |
<li |
|
|
145 |
v-if=" |
146 |
newRule.notice !== '' || |
147 |
((newRule.notice === null || |
148 |
newRule.notice === undefined) && |
149 |
fallbackRule.notice !== '') |
150 |
" |
151 |
> |
134 |
<label for="mtt" |
152 |
<label for="mtt" |
135 |
>{{ $__("Transport type(s)") }}:</label |
153 |
>{{ $__("Transport type(s)") }}:</label |
136 |
> |
154 |
> |
137 |
<v-select |
155 |
<v-select |
138 |
id="mtt" |
156 |
id="mtt" |
139 |
v-model="circRuleTrigger.mtt" |
157 |
v-model="newRule.mtt" |
140 |
label="name" |
158 |
label="name" |
141 |
:reduce="type => type.code" |
159 |
:reduce="type => type.code" |
142 |
:options="mtts" |
160 |
:options="mtts" |
Lines 147-152
Link Here
|
147 |
class="vs__search" |
165 |
class="vs__search" |
148 |
v-bind="attributes" |
166 |
v-bind="attributes" |
149 |
v-on="events" |
167 |
v-on="events" |
|
|
168 |
:placeholder=" |
169 |
newRule.mtt === null || |
170 |
newRule.mtt === undefined || |
171 |
newRule.mtt.length === 0 |
172 |
? fallbackRule.mtt |
173 |
: '' |
174 |
" |
150 |
/> |
175 |
/> |
151 |
</template> |
176 |
</template> |
152 |
</v-select> |
177 |
</v-select> |
Lines 155-168
Link Here
|
155 |
<label for="restricts" |
180 |
<label for="restricts" |
156 |
>{{ $__("Restricts checkouts") }}:</label |
181 |
>{{ $__("Restricts checkouts") }}:</label |
157 |
> |
182 |
> |
158 |
<input |
183 |
<div> |
159 |
type="checkbox" |
184 |
<input |
160 |
id="restricts" |
185 |
type="radio" |
161 |
:checked="false" |
186 |
id="restricts-yes" |
162 |
true-value="1" |
187 |
v-model="newRule.restrict" |
163 |
false-value="0" |
188 |
:value="1" |
164 |
v-model="circRuleTrigger.restrict" |
189 |
/> |
165 |
/> |
190 |
{{ $__("Yes") }} |
|
|
191 |
|
192 |
<input |
193 |
type="radio" |
194 |
id="restricts-no" |
195 |
v-model="newRule.restrict" |
196 |
:value="0" |
197 |
/> |
198 |
{{ $__("No") }} |
199 |
|
200 |
<input |
201 |
type="radio" |
202 |
id="restricts-fallback" |
203 |
v-model="newRule.restrict" |
204 |
:value="null" |
205 |
/> |
206 |
{{ $__("Fallback to default") }} |
207 |
<span v-if="fallbackRule.restricts !== null"> |
208 |
({{ |
209 |
fallbackRule.restricts === 1 |
210 |
? $__("Yes") |
211 |
: $__("No") |
212 |
}}) |
213 |
</span> |
214 |
</div> |
166 |
</li> |
215 |
</li> |
167 |
</ol> |
216 |
</ol> |
168 |
</fieldset> |
217 |
</fieldset> |
Lines 209-231
export default {
Link Here
|
209 |
categories: null, |
258 |
categories: null, |
210 |
itemTypes: null, |
259 |
itemTypes: null, |
211 |
circRules: [], |
260 |
circRules: [], |
212 |
circRuleTrigger: { |
261 |
newRule: { |
213 |
item_type_id: "*", |
262 |
item_type_id: "*", |
214 |
library_id: "*", |
263 |
library_id: "*", |
215 |
patron_category_id: "*", |
264 |
patron_category_id: "*", |
216 |
delay: null, |
265 |
delay: null, |
217 |
notice: null, |
266 |
notice: null, |
218 |
mtt: null, |
267 |
mtt: null, |
219 |
restrict: "0", |
268 |
restrict: null, |
220 |
}, |
269 |
}, |
221 |
effectiveRule: { |
270 |
fallbackRule: { |
222 |
item_type_id: "*", |
271 |
item_type_id: "*", |
223 |
library_id: "*", |
272 |
library_id: "*", |
224 |
patron_category_id: "*", |
273 |
patron_category_id: "*", |
225 |
delay: null, |
274 |
delay: null, |
226 |
notice: null, |
275 |
notice: null, |
227 |
mtt: null, |
276 |
mtt: null, |
228 |
restrict: "0", |
277 |
restrict: null, |
229 |
}, |
278 |
}, |
230 |
newTriggerNumber: 1, |
279 |
newTriggerNumber: 1, |
231 |
mtts: [ |
280 |
mtts: [ |
Lines 239-306
export default {
Link Here
|
239 |
fine: null, |
288 |
fine: null, |
240 |
chargeperiod: null, |
289 |
chargeperiod: null, |
241 |
lengthunit: null, |
290 |
lengthunit: null, |
|
|
291 |
numberOfTriggers: null, |
242 |
}, |
292 |
}, |
243 |
editMode: false, |
293 |
editMode: false, |
244 |
ruleBeingEdited: null, |
294 |
ruleBeingEdited: null, |
|
|
295 |
triggerBeingEdited: null, |
245 |
}; |
296 |
}; |
246 |
}, |
297 |
}, |
247 |
beforeRouteEnter(to, from, next) { |
298 |
beforeRouteEnter(to, from, next) { |
248 |
next(vm => { |
299 |
next(vm => { |
249 |
vm.getLibraries().then(() => |
300 |
vm.getLibraries().then(() => |
250 |
vm.getCategories().then(() => |
301 |
vm.getCategories().then(() => |
251 |
vm.getItemTypes().then(() => { |
302 |
vm.getItemTypes().then(() => |
252 |
const { query } = to; |
303 |
vm.getCircRules().then(() => { |
253 |
vm.checkForExistingRules(query).then( |
304 |
const { query } = to; |
254 |
() => (vm.initialized = true) |
305 |
vm.checkForExistingRules(query).then( |
255 |
); |
306 |
() => (vm.initialized = true) |
256 |
}) |
307 |
); |
|
|
308 |
}) |
309 |
) |
257 |
) |
310 |
) |
258 |
); |
311 |
); |
259 |
}); |
312 |
}); |
260 |
}, |
313 |
}, |
|
|
314 |
computed: { |
315 |
minDelay() { |
316 |
const lastRule = this.circRules[this.newTriggerNumber - 2]; |
317 |
return lastRule |
318 |
? parseInt( |
319 |
lastRule[`overdue_${this.newTriggerNumber - 1}_delay`] |
320 |
) + 1 |
321 |
: 0; |
322 |
}, |
323 |
}, |
261 |
methods: { |
324 |
methods: { |
262 |
async addCircRule(e) { |
325 |
async addCircRule(e) { |
263 |
e.preventDefault(); |
326 |
e.preventDefault(); |
264 |
|
327 |
|
265 |
const context = { |
328 |
const context = { |
266 |
library_id: this.circRuleTrigger.library_id || "*", |
329 |
library_id: this.newRule.library_id || "*", |
267 |
item_type_id: this.circRuleTrigger.item_type_id || "*", |
330 |
item_type_id: this.newRule.item_type_id || "*", |
268 |
patron_category_id: |
331 |
patron_category_id: this.newRule.patron_category_id || "*", |
269 |
this.circRuleTrigger.patron_category_id || "*", |
|
|
270 |
}; |
332 |
}; |
271 |
|
333 |
|
272 |
const delay = |
|
|
273 |
this.circRuleTrigger.delay === this.effectiveRule.delay |
274 |
? null |
275 |
: this.circRuleTrigger.delay; |
276 |
const notice = |
277 |
this.circRuleTrigger.notice === this.effectiveRule.notice |
278 |
? null |
279 |
: this.circRuleTrigger.notice; |
280 |
const restrict = |
281 |
this.circRuleTrigger.restrict === this.effectiveRule.restrict |
282 |
? null |
283 |
: this.circRuleTrigger.restrict; |
284 |
const mtt = |
285 |
this.circRuleTrigger.mtt.join(",") === |
286 |
this.effectiveRule.mtt.join(",") |
287 |
? null |
288 |
: this.circRuleTrigger.mtt.join(","); |
289 |
|
290 |
const circRule = { |
334 |
const circRule = { |
291 |
context, |
335 |
context, |
292 |
}; |
336 |
}; |
293 |
circRule[`overdue_${this.newTriggerNumber}_delay`] = delay; |
337 |
circRule[`overdue_${this.newTriggerNumber}_delay`] = |
294 |
circRule[`overdue_${this.newTriggerNumber}_notice`] = notice; |
338 |
this.newRule.delay; |
295 |
circRule[`overdue_${this.newTriggerNumber}_restrict`] = restrict; |
339 |
circRule[`overdue_${this.newTriggerNumber}_notice`] = |
296 |
circRule[`overdue_${this.newTriggerNumber}_mtt`] = mtt; |
340 |
this.newRule.notice; |
297 |
|
341 |
circRule[`overdue_${this.newTriggerNumber}_restrict`] = |
298 |
if (this.editMode) { |
342 |
this.newRule.restrict; |
299 |
Object.keys(circRule).forEach(key => { |
343 |
circRule[`overdue_${this.newTriggerNumber}_mtt`] = |
300 |
if (key === "context") return; |
344 |
this.newRule.mtt && this.newRule.mtt.length |
301 |
if (!circRule[key]) delete circRule[key]; |
345 |
? this.newRule.mtt.join(",") |
302 |
}); |
346 |
: null; |
303 |
} |
|
|
304 |
|
347 |
|
305 |
const client = APIClient.circRule; |
348 |
const client = APIClient.circRule; |
306 |
await client.circRules.update(circRule).then( |
349 |
await client.circRules.update(circRule).then( |
Lines 354-359
export default {
Link Here
|
354 |
error => {} |
397 |
error => {} |
355 |
); |
398 |
); |
356 |
}, |
399 |
}, |
|
|
400 |
async getCircRules() { |
401 |
const client = APIClient.circRule; |
402 |
await client.circRules.getAll({}, { effective: false }).then( |
403 |
rules => { |
404 |
const { rulesPerTrigger } = |
405 |
this.splitCircRulesByTriggerNumber(rules); |
406 |
this.circRules = rulesPerTrigger.length |
407 |
? rulesPerTrigger |
408 |
: rules; |
409 |
}, |
410 |
error => {} |
411 |
); |
412 |
}, |
357 |
async handleContextChange() { |
413 |
async handleContextChange() { |
358 |
await this.checkForExistingRules(); |
414 |
await this.checkForExistingRules(); |
359 |
}, |
415 |
}, |
Lines 362-456
export default {
Link Here
|
362 |
const editMode = routeParams && routeParams.triggerNumber; |
418 |
const editMode = routeParams && routeParams.triggerNumber; |
363 |
if (editMode) { |
419 |
if (editMode) { |
364 |
this.editMode = editMode; |
420 |
this.editMode = editMode; |
365 |
this.ruleBeingEdited = routeParams.triggerNumber; |
421 |
this.triggerBeingEdited = routeParams.triggerNumber; |
366 |
} |
422 |
} |
367 |
const library_id = |
423 |
const library_id = |
368 |
routeParams && routeParams.library_id |
424 |
routeParams && routeParams.library_id |
369 |
? routeParams.library_id |
425 |
? routeParams.library_id |
370 |
: this.circRuleTrigger.library_id || "*"; |
426 |
: this.newRule.library_id || "*"; |
371 |
const item_type_id = |
427 |
const item_type_id = |
372 |
routeParams && routeParams.item_type_id |
428 |
routeParams && routeParams.item_type_id |
373 |
? routeParams.item_type_id |
429 |
? routeParams.item_type_id |
374 |
: this.circRuleTrigger.item_type_id || "*"; |
430 |
: this.newRule.item_type_id || "*"; |
375 |
const patron_category_id = |
431 |
const patron_category_id = |
376 |
routeParams && routeParams.patron_category_id |
432 |
routeParams && routeParams.patron_category_id |
377 |
? routeParams.patron_category_id |
433 |
? routeParams.patron_category_id |
378 |
: this.circRuleTrigger.patron_category_id || "*"; |
434 |
: this.newRule.patron_category_id || "*"; |
379 |
const params = { |
435 |
const params = { |
380 |
library_id, |
436 |
library_id, |
381 |
item_type_id, |
437 |
item_type_id, |
382 |
patron_category_id, |
438 |
patron_category_id, |
383 |
}; |
439 |
}; |
384 |
|
440 |
|
|
|
441 |
// Fetch effective ruleset for context |
385 |
const client = APIClient.circRule; |
442 |
const client = APIClient.circRule; |
386 |
await client.circRules.getAll({}, params).then( |
443 |
await client.circRules.getAll({}, params).then( |
387 |
rules => { |
444 |
rules => { |
388 |
if (rules.length === 0) { |
445 |
this.ruleBeingEdited = rules[0]; |
389 |
this.newTriggerNumber = 1; |
446 |
this.ruleBeingEdited.context = params; |
390 |
} else { |
447 |
const regex = /overdue_(\d+)_delay/g; |
391 |
const { rulesPerTrigger } = |
448 |
const numberOfTriggers = Object.keys(rules[0]).filter( |
392 |
this.splitCircRulesByTriggerNumber(rules); |
449 |
key => regex.test(key) && rules[0][key] !== null |
393 |
this.circRules = rulesPerTrigger; |
450 |
).length; |
394 |
this.ruleInfo = { |
451 |
const splitRules = this.filterCircRulesByContext( |
395 |
issuelength: rules[0].issuelength, |
452 |
this.ruleBeingEdited |
396 |
decreaseloanholds: rules[0].decreaseloanholds, |
453 |
); |
397 |
fine: rules[0].fine, |
454 |
this.newTriggerNumber = editMode |
398 |
chargeperiod: rules[0].chargeperiod, |
455 |
? routeParams.triggerNumber |
399 |
lengthunit: rules[0].lengthunit, |
456 |
: numberOfTriggers + 1; |
400 |
}; |
457 |
this.assignTriggerValues( |
401 |
} |
458 |
splitRules, |
|
|
459 |
this.newTriggerNumber, |
460 |
params |
461 |
); |
462 |
|
463 |
this.ruleInfo = { |
464 |
issuelength: rules[0].issuelength, |
465 |
decreaseloanholds: rules[0].decreaseloanholds, |
466 |
fine: rules[0].fine, |
467 |
chargeperiod: rules[0].chargeperiod, |
468 |
lengthunit: rules[0].lengthunit, |
469 |
numberOfTriggers: numberOfTriggers, |
470 |
}; |
402 |
}, |
471 |
}, |
403 |
error => {} |
472 |
error => {} |
404 |
); |
473 |
); |
|
|
474 |
}, |
475 |
filterCircRulesByContext(effectiveRule) { |
476 |
const context = effectiveRule.context; |
405 |
|
477 |
|
406 |
params.effective = false; |
478 |
// Filter rules that match the context |
407 |
await client.circRules.getAll({}, params).then( |
479 |
let contextRules = this.circRules.filter(rule => { |
408 |
rules => { |
480 |
return Object.keys(context).every(key => { |
409 |
if (rules.length === 0) { |
481 |
return context[key] === rule.context[key]; |
410 |
this.newTriggerNumber = 1; |
482 |
}); |
|
|
483 |
}); |
411 |
|
484 |
|
412 |
this.assignTriggerValues( |
485 |
// Calculate the number of 'overdue_X_' triggers in the effectiveRule |
413 |
"circRuleTrigger", |
486 |
const regex = /overdue_(\d+)_delay/g; |
414 |
this.circRules, |
487 |
const numberOfTriggers = Object.keys(effectiveRule).filter( |
415 |
this.newTriggerNumber, |
488 |
key => regex.test(key) && effectiveRule[key] !== null |
416 |
params |
489 |
).length; |
417 |
); |
490 |
|
418 |
this.assignTriggerValues( |
491 |
// Ensure there is one contextRule per 'X' from 1 to numberOfTriggers |
419 |
"effectiveRule", |
492 |
for (let i = 1; i <= numberOfTriggers; i++) { |
420 |
this.circRules, |
493 |
// Check if there's already a rule for overdue_X_ in contextRules |
421 |
this.newTriggerNumber, |
494 |
const matchingRule = contextRules.find( |
422 |
params |
495 |
rule => rule[`overdue_${i}_delay`] !== undefined |
423 |
); |
496 |
); |
424 |
} else { |
497 |
|
425 |
const regex = /overdue_(\d+)_delay/g; |
498 |
if (!matchingRule) { |
426 |
const numberOfTriggers = Object.keys(rules[0]).filter( |
499 |
// Create a new rule with the same context and null overdue_X_* keys |
427 |
key => regex.test(key) && rules[0][key] !== null |
500 |
const placeholderRule = { |
428 |
).length; |
501 |
context: { ...context }, // Clone the context |
429 |
this.newTriggerNumber = editMode |
502 |
[`overdue_${i}_delay`]: null, |
430 |
? routeParams.triggerNumber |
503 |
[`overdue_${i}_notice`]: null, |
431 |
: numberOfTriggers + 1; |
504 |
[`overdue_${i}_mtt`]: null, |
432 |
const { rulesPerTrigger } = |
505 |
[`overdue_${i}_restrict`]: null, |
433 |
this.splitCircRulesByTriggerNumber(rules); |
506 |
}; |
434 |
const triggerToDisplay = editMode |
507 |
|
435 |
? routeParams.triggerNumber |
508 |
// Add the new rule to contextRules |
436 |
: numberOfTriggers; |
509 |
contextRules.push(placeholderRule); |
437 |
this.assignTriggerValues( |
510 |
} |
438 |
"circRuleTrigger", |
511 |
} |
439 |
rulesPerTrigger, |
512 |
|
440 |
triggerToDisplay |
513 |
// Sort contextRules by the 'X' value in 'overdue_X_delay' |
441 |
); |
514 |
contextRules.sort((a, b) => { |
442 |
this.assignTriggerValues( |
515 |
const getX = rule => { |
443 |
"effectiveRule", |
516 |
const match = Object.keys(rule).find(key => |
444 |
rulesPerTrigger, |
517 |
regex.test(key) |
445 |
triggerToDisplay |
518 |
); |
446 |
); |
519 |
return match ? parseInt(match.match(/\d+/)[0], 10) : 0; |
447 |
} |
520 |
}; |
448 |
}, |
521 |
|
449 |
error => {} |
522 |
return getX(a) - getX(b); |
450 |
); |
523 |
}); |
|
|
524 |
|
525 |
return contextRules; |
451 |
}, |
526 |
}, |
452 |
assignTriggerValues(prop, rules, triggerNumber, context = null) { |
527 |
findFallbackRule(currentContext, key) { |
453 |
this[prop] = { |
528 |
// Filter rules to only those with non-null values for the specified key and not the current context |
|
|
529 |
const relevantRules = this.circRules.filter(rule => { |
530 |
return ( |
531 |
Object.keys(currentContext).some( |
532 |
key => currentContext[key] !== rule.context[key] |
533 |
) && |
534 |
rule[key] !== null && |
535 |
rule[key] !== undefined |
536 |
); |
537 |
}); |
538 |
|
539 |
// Function to calculate specificity score |
540 |
const getSpecificityScore = ruleContext => { |
541 |
let score = 0; |
542 |
if ( |
543 |
ruleContext.library_id !== "*" && |
544 |
ruleContext.library_id === currentContext.library_id |
545 |
) |
546 |
score += 4; |
547 |
if ( |
548 |
ruleContext.patron_category_id !== "*" && |
549 |
ruleContext.patron_category_id === |
550 |
currentContext.patron_category_id |
551 |
) |
552 |
score += 2; |
553 |
if ( |
554 |
ruleContext.item_type_id !== "*" && |
555 |
ruleContext.item_type_id === currentContext.item_type_id |
556 |
) |
557 |
score += 1; |
558 |
return score; |
559 |
}; |
560 |
|
561 |
// Sort the rules based on specificity score, descending |
562 |
const sortedRules = relevantRules.sort((a, b) => { |
563 |
return ( |
564 |
getSpecificityScore(b.context) - |
565 |
getSpecificityScore(a.context) |
566 |
); |
567 |
}); |
568 |
|
569 |
// If no rule found, return null |
570 |
if (sortedRules.length === 0) { |
571 |
return null; |
572 |
} |
573 |
|
574 |
// Get the value from the most specific rule |
575 |
const bestRule = sortedRules[0]; |
576 |
return bestRule[key]; |
577 |
}, |
578 |
assignTriggerValues(rules, triggerNumber, context = null) { |
579 |
this.newRule = { |
454 |
item_type_id: context |
580 |
item_type_id: context |
455 |
? context.item_type_id |
581 |
? context.item_type_id |
456 |
: rules[triggerNumber - 1].context.item_type_id || "*", |
582 |
: rules[triggerNumber - 1].context.item_type_id || "*", |
Lines 461-481
export default {
Link Here
|
461 |
? context.patron_category_id |
587 |
? context.patron_category_id |
462 |
: rules[triggerNumber - 1].context.patron_category_id || |
588 |
: rules[triggerNumber - 1].context.patron_category_id || |
463 |
"*", |
589 |
"*", |
464 |
delay: rules[triggerNumber - 1][ |
590 |
delay: rules[triggerNumber - 1] |
|
|
591 |
? rules[triggerNumber - 1][`overdue_${triggerNumber}_delay`] |
592 |
: null, |
593 |
notice: rules[triggerNumber - 1] |
594 |
? rules[triggerNumber - 1][ |
595 |
`overdue_${triggerNumber}_notice` |
596 |
] |
597 |
: null, |
598 |
mtt: rules[triggerNumber - 1] |
599 |
? rules[triggerNumber - 1][`overdue_${triggerNumber}_mtt`] |
600 |
? rules[triggerNumber - 1][ |
601 |
`overdue_${triggerNumber}_mtt` |
602 |
].split(",") |
603 |
: [] |
604 |
: null, |
605 |
restrict: rules[triggerNumber - 1] |
606 |
? rules[triggerNumber - 1][ |
607 |
`overdue_${triggerNumber}_restrict` |
608 |
] |
609 |
: null, |
610 |
}; |
611 |
this.fallbackRule = { |
612 |
delay: this.findFallbackRule( |
613 |
context, |
465 |
`overdue_${triggerNumber}_delay` |
614 |
`overdue_${triggerNumber}_delay` |
466 |
], |
615 |
), |
467 |
notice: rules[triggerNumber - 1][ |
616 |
notice: this.findFallbackRule( |
|
|
617 |
context, |
468 |
`overdue_${triggerNumber}_notice` |
618 |
`overdue_${triggerNumber}_notice` |
469 |
], |
619 |
), |
470 |
mtt: rules[triggerNumber - 1][`overdue_${triggerNumber}_mtt`] |
620 |
mtt: this.findFallbackRule( |
471 |
? rules[triggerNumber - 1][ |
621 |
context, |
472 |
`overdue_${triggerNumber}_mtt` |
622 |
`overdue_${triggerNumber}_mtt` |
473 |
].split(",") |
623 |
), |
474 |
: [], |
624 |
restrict: this.findFallbackRule( |
475 |
restrict: |
625 |
context, |
476 |
rules[triggerNumber - 1][ |
626 |
`overdue_${triggerNumber}_restrict` |
477 |
`overdue_${triggerNumber}_restrict` |
627 |
), |
478 |
], |
|
|
479 |
}; |
628 |
}; |
480 |
}, |
629 |
}, |
481 |
}, |
630 |
}, |