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