This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Evergreen ILS".
The branch, main has been updated
via 9abb6a32c73469df272cc6b0c36fda789366a76b (commit)
via 27e0a094eae3e117682c56c7edc8a0499bb20007 (commit)
via 6edbc0101e032efaba8f34e57d8099fb7843740a (commit)
from 4605e1f5e89e93f34a2e6471496424381f4448a1 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 9abb6a32c73469df272cc6b0c36fda789366a76b
Author: Steven Mayo <smayo(a)georgialibraries.org>
Date: Thu Jun 5 14:14:52 2025 -0400
lp2096916 Don't force part assignment if copy is unholdable
Allows saving without a part on a record with parts when the require
parts setting is enabled if the part isn't holdable. If the part becomes
holdable, the requiredness reactivates and you can't save until you
assign a part.
Also refactored so that all the logic tracking part requiredness is done
in volcopy.component instead of vol-edit. Passes 'should you be red' as
a map that gets updated by the function that checks if the warning on
the bottom of the screen should display.
Signed-off-by: Steven Mayo <smayo(a)georgialibraries.org>
Signed-off-by: Jane Sandberg <js7389(a)princeton.edu>
Signed-off-by: Ian Skelskey <ianskelskey(a)gmail.com>
Signed-off-by: Ruth Frasur Davis <redavis4974(a)gmail.com>
Signed-off-by: Shula Link <slink(a)gchrl.org>
Signed-off-by: Michele Morgan <mmorgan(a)noblenet.org>
diff --git a/Open-ILS/src/eg2/src/app/staff/cat/volcopy/vol-edit.component.html b/Open-ILS/src/eg2/src/app/staff/cat/volcopy/vol-edit.component.html
index 818b37f877..9dd551a22a 100644
--- a/Open-ILS/src/eg2/src/app/staff/cat/volcopy/vol-edit.component.html
+++ b/Open-ILS/src/eg2/src/app/staff/cat/volcopy/vol-edit.component.html
@@ -470,7 +470,7 @@
[moreClasses]="'vol-edit-validity-combobox'"
[smallFormControl]="true"
[allowFreeText]="true"
- [required]="copyRequiresParts(copyNode)"
+ [required]="itemRequirePartsMap[copyNode.target.id()]"
(onChange)="copyPartChanged(copyNode, $event)">
<eg-combobox-entry
*ngFor="let part of volcopy.bibParts[volNode.target.record()]"
diff --git a/Open-ILS/src/eg2/src/app/staff/cat/volcopy/vol-edit.component.ts b/Open-ILS/src/eg2/src/app/staff/cat/volcopy/vol-edit.component.ts
index ebb4bf5620..59371f4494 100644
--- a/Open-ILS/src/eg2/src/app/staff/cat/volcopy/vol-edit.component.ts
+++ b/Open-ILS/src/eg2/src/app/staff/cat/volcopy/vol-edit.component.ts
@@ -60,8 +60,8 @@ export class VolEditComponent implements OnInit {
// Set default for Call Number Label requirement
requireCNL = true;
- // For every org we are editing copies for, whether they require parts to be on copies if the record has parts
- requirePartsOrgMap : {[key: number]: boolean} = {};
+ // For every copy in the context, whether or not the copy will need a part
+ @Input() itemRequirePartsMap : {[key: number]: boolean} = {};
// When adding multiple vols via add-many popover.
addVolCount: number = null;
@@ -98,14 +98,6 @@ export class VolEditComponent implements OnInit {
this.volcopy.genBarcodesRequested.subscribe(() => this.generateBarcodes());
- // Check for each org if a part is required
- for (const orgId of this.context.getOwningLibIds()) {
- this.org.settings('circ.holds.ui_require_monographic_part_when_present', orgId)
- .then(settings => {
- this.requirePartsOrgMap[orgId] = Boolean(settings['circ.holds.ui_require_monographic_part_when_present']);
- });
- }
-
// Check to see if call number label is required
this.org.settings('cat.require_call_number_labels')
.then(settings => {
@@ -131,22 +123,6 @@ export class VolEditComponent implements OnInit {
return '';
}
- recordHasParts(bibId: number): boolean {
- return this.volcopy.bibParts[bibId] &&
- this.volcopy.bibParts[bibId].length > 0;
- }
-
- copyRequiresParts(node: HoldingsTreeNode) : boolean {
- if (['org', 'vol'].includes(node.nodeType)){
- throw new TypeError('Invalid HoldingsTreeNode type!');
- }
-
- const org = node.parentNode.target.owning_lib();
- const record = node.parentNode.target.record();
-
- return this.recordHasParts(record) && this.requirePartsOrgMap[org];
- }
-
// Column width (flex:x) for column by column number.
flexAt(column: number): number {
if (!this.displayColumn(this.flexColMap[column])) {
@@ -318,7 +294,6 @@ export class VolEditComponent implements OnInit {
copy.ischanged(true);
}
- this.emitSaveChange();
}
batchVolApply() {
@@ -632,8 +607,7 @@ export class VolEditComponent implements OnInit {
const badCopies = copies.filter(copy => {
if (copy._dupe_barcode ||
- (!copy.isnew() && !copy.barcode()) ||
- (this.copyRequiresParts(this.context.findOrCreateCopyNode(copy)) && (!copy.parts() || copy.parts().length === 0))
+ (!copy.isnew() && !copy.barcode())
) {
return true;
} else {
diff --git a/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.component.html b/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.component.html
index 34664bcbcc..3bad0d45c4 100644
--- a/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.component.html
+++ b/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.component.html
@@ -55,7 +55,7 @@
<h3 class="visually-hidden" i18n>Holdings</h3>
<div class="mt-2">
<eg-vol-edit [context]="context"
- (canSaveChange)="volsCanSaveChange($event)"></eg-vol-edit>
+ (canSaveChange)="volsCanSaveChange($event)" [itemRequirePartsMap]="itemRequirePartsMap"></eg-vol-edit>
</div>
<ng-container *ngIf="volcopy.defaults.values.unified_display">
<div class="mt-2">
@@ -101,7 +101,10 @@
<div class="row">
<p *ngIf="changesPendingForStatusBar" class="col-12 alert alert-warning text-center" i18n>Changes Pending</p>
<p *ngIf="barcodeNeeded()" class="col-12 alert alert-warning text-center" i18n>At least one barcoded item needed for current changes.</p>
- <p *ngIf="partNeeded()" class="col-12 alert alert-warning text-center" i18n>At least one item requires a part.</p>
+ <p *ngIf="partNeeded()" class="col-12 alert alert-warning text-center">
+ <ng-container *ngIf="missingPartsCount == 1" i18n>1 item requires a part.</ng-container>
+ <ng-container *ngIf="missingPartsCount > 1" i18n>{{missingPartsCount}} items require a part.</ng-container>
+ </p>
</div>
<div class="row">
<div class="col-lg-12 d-flex align-items-start volcopy-actions">
diff --git a/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.component.ts b/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.component.ts
index 0bd7dad1db..8cea09566a 100644
--- a/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.component.ts
+++ b/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.component.ts
@@ -80,6 +80,10 @@ export class VolCopyComponent implements OnInit {
// For every org we are editing copies for, whether they require parts to be on copies if the record has parts
orgRequiresParts : {[key: number]: boolean} = {};
+ // For every copy in the context, whether or not the copy needs to require a part
+ itemRequirePartsMap : {[key: number]: boolean} = {};
+ missingPartsCount: number = 0;
+
not_allowed_vols = [];
@ViewChild('pendingChangesDialog', {static: false})
@@ -805,26 +809,52 @@ export class VolCopyComponent implements OnInit {
return result;
}
- recordHasParts(bibId: number): boolean {
- return this.volcopy.bibParts[bibId] &&
- this.volcopy.bibParts[bibId].length > 0;
+
+ copyRequiresPart(copy : IdlObject) : boolean {
+ // Does the org setting require a part?
+ const copyNode = this.context.findOrCreateCopyNode(copy);
+ const org = copyNode.parentNode.target.owning_lib();
+ const record = copyNode.parentNode.target.record();
+
+ const settingEnabled = this.orgRequiresParts[org];
+ const recordHasParts = this.volcopy.bibParts[record] && this.volcopy.bibParts[record].length > 0;
+
+ const copyStatusHoldable = this.volcopy.copyStatuses[copyNode.target.status()].holdable() == "t"
+ const copyHoldableFlag = copyNode.target.holdable() == "t";
+ const copyShelvingLocationHoldable = copyNode.target.location().holdable() == "t";
+ const copyIsHoldable = copyStatusHoldable && copyHoldableFlag && copyShelvingLocationHoldable;
+
+ const copyRequiresPart = settingEnabled && recordHasParts && copyIsHoldable;
+
+ // Only update when changing in case that matters for performance. (binding propagation)
+ if (this.itemRequirePartsMap[copy.id()] != copyRequiresPart) {
+ this.itemRequirePartsMap[copy.id()] = copyRequiresPart;
+ }
+
+ return copyRequiresPart;
+
}
partNeeded() : boolean {
+ let needPart = false;
+ let missingCount = 0;
for (const copy of this.context.copyList()) {
- // Does the org setting require a part?
- const copyNode = this.context.findOrCreateCopyNode(copy);
- const org = copyNode.parentNode.target.owning_lib();
- const record = copyNode.parentNode.target.record();
+ let copyRequiresPart = this.copyRequiresPart(copy);
- const settingEnabled = this.orgRequiresParts[org];
- const recordHasParts = this.recordHasParts(record);
const copyHasParts = Boolean(copy.parts()?.length);
- if (settingEnabled && recordHasParts && !copyHasParts){
- return true;
+ const copyMissingPart = copyRequiresPart && !copyHasParts;
+ // Visit every copy instead of immediately returning true to update the validity of every copy, not just the first that fails
+ if (copyMissingPart) {
+ needPart = true;
+ missingCount++;
}
+
}
- return false;
+ // Silly conditional assignment to not overwhelm Angular change detection
+ if (missingCount != this.missingPartsCount) {
+ this.missingPartsCount = missingCount;
+ }
+ return needPart;
}
@HostListener('window:beforeunload', ['$event'])
commit 27e0a094eae3e117682c56c7edc8a0499bb20007
Author: Steven Mayo <smayo(a)georgialibraries.org>
Date: Thu Jun 5 09:08:43 2025 -0400
lp2096916 Prevent Save When Missing Required Part
Kinda duplicated the part logic in the vol-edit component into the
volcopy component. Added a message similar to missing barcodes to the
bottom of the page to show when missing a required part.
Signed-off-by: Steven Mayo <smayo(a)georgialibraries.org>
Signed-off-by: Jane Sandberg <js7389(a)princeton.edu>
Signed-off-by: Ian Skelskey <ianskelskey(a)gmail.com>
Signed-off-by: Ruth Frasur Davis <redavis4974(a)gmail.com>
Signed-off-by: Shula Link <slink(a)gchrl.org>
Signed-off-by: Michele Morgan <mmorgan(a)noblenet.org>
diff --git a/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.component.html b/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.component.html
index fd9d8a9dff..34664bcbcc 100644
--- a/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.component.html
+++ b/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.component.html
@@ -101,6 +101,7 @@
<div class="row">
<p *ngIf="changesPendingForStatusBar" class="col-12 alert alert-warning text-center" i18n>Changes Pending</p>
<p *ngIf="barcodeNeeded()" class="col-12 alert alert-warning text-center" i18n>At least one barcoded item needed for current changes.</p>
+ <p *ngIf="partNeeded()" class="col-12 alert alert-warning text-center" i18n>At least one item requires a part.</p>
</div>
<div class="row">
<div class="col-lg-12 d-flex align-items-start volcopy-actions">
diff --git a/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.component.ts b/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.component.ts
index 424a2a8317..0bd7dad1db 100644
--- a/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.component.ts
+++ b/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.component.ts
@@ -77,6 +77,9 @@ export class VolCopyComponent implements OnInit {
changesPendingForStatusBar = false;
routingAllowed = false;
+ // For every org we are editing copies for, whether they require parts to be on copies if the record has parts
+ orgRequiresParts : {[key: number]: boolean} = {};
+
not_allowed_vols = [];
@ViewChild('pendingChangesDialog', {static: false})
@@ -290,6 +293,18 @@ export class VolCopyComponent implements OnInit {
this.context.volNodes().map(n => n.target)))
.then(_ => this.context.sortHoldings())
.then(_ => this.context.setRecordId())
+ .then(_ => this.volcopy.fetchBibParts(this.context.getRecordIds()))
+ .then(_ => {
+ // Check for each org if a part is required
+ const orgSettingFetches = [];
+ for (const orgId of this.context.getOwningLibIds()) {
+ orgSettingFetches.push(this.org.settings('circ.holds.ui_require_monographic_part_when_present', orgId)
+ .then(settings => {
+ this.orgRequiresParts[orgId] = Boolean(settings['circ.holds.ui_require_monographic_part_when_present']);
+ }));
+ }
+ return Promise.all(orgSettingFetches);
+ })
.then(_ => {
// unified display has no 'attrs' tab
if (this.volcopy.defaults.values.unified_display
@@ -685,7 +700,7 @@ export class VolCopyComponent implements OnInit {
// return this.saveApi(volumes, true, close);
this.loading = false;
alert(evt);
- return Promise.reject();
+ return Promise.reject(evt);
}
this.broadcastChanges(volumes);
@@ -730,6 +745,7 @@ export class VolCopyComponent implements OnInit {
if (!this.volsCanSave) { return true; }
if (!this.attrsCanSave) { return true; }
if (this.barcodeNeeded()) { return true; }
+ if (this.partNeeded()) { return true; }
// This can happen regardless of whether we are modifying
// volumes vs. copies.
@@ -789,6 +805,28 @@ export class VolCopyComponent implements OnInit {
return result;
}
+ recordHasParts(bibId: number): boolean {
+ return this.volcopy.bibParts[bibId] &&
+ this.volcopy.bibParts[bibId].length > 0;
+ }
+
+ partNeeded() : boolean {
+ for (const copy of this.context.copyList()) {
+ // Does the org setting require a part?
+ const copyNode = this.context.findOrCreateCopyNode(copy);
+ const org = copyNode.parentNode.target.owning_lib();
+ const record = copyNode.parentNode.target.record();
+
+ const settingEnabled = this.orgRequiresParts[org];
+ const recordHasParts = this.recordHasParts(record);
+ const copyHasParts = Boolean(copy.parts()?.length);
+ if (settingEnabled && recordHasParts && !copyHasParts){
+ return true;
+ }
+ }
+ return false;
+ }
+
@HostListener('window:beforeunload', ['$event'])
canDeactivate($event?: Event): boolean | Promise<boolean> {
diff --git a/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.service.ts b/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.service.ts
index a973a15c25..9137acbe33 100644
--- a/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.service.ts
+++ b/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.service.ts
@@ -1,6 +1,6 @@
/* eslint-disable max-len, no-prototype-builtins */
import {Injectable, EventEmitter, OnDestroy} from '@angular/core';
-import {Subject, tap, takeUntil} from 'rxjs';
+import {Subject, tap, takeUntil, toArray, lastValueFrom, Observable, Subscription} from 'rxjs';
import {SafeUrl} from '@angular/platform-browser';
import {IdlService, IdlObject} from '@eg/core/idl.service';
import {NetService} from '@eg/core/net.service';
@@ -14,7 +14,6 @@ import {FileExportService} from '@eg/share/util/file-export.service';
import {ServerStoreService} from '@eg/core/server-store.service';
import {StoreService} from '@eg/core/store.service';
import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
-import { Observable, Subscription, lastValueFrom } from 'rxjs';
/* Managing volcopy data */
@@ -531,7 +530,7 @@ export class VolCopyService implements OnDestroy {
});
this.bibParts = finalBibParts;
}
- }))
+ }), toArray())
);
}
commit 6edbc0101e032efaba8f34e57d8099fb7843740a
Author: Steven Mayo <smayo(a)georgialibraries.org>
Date: Wed Feb 5 10:28:13 2025 -0500
LP2096916 Can Edit Items Without Assigning Required Part
Turns volcopy.fetchBibParts() into a promise so it is actually waited
for on init in vol-edit.component. Prevents incorrectly determining
there are no parts on every copy in context.
Release-note: Fix a bug in which the "Require Monographic Parts when Present"
library setting failed to apply when editing existing items.
Signed-off-by: Steven Mayo <smayo(a)georgialibraries.org>
Signed-off-by: Jane Sandberg <js7389(a)princeton.edu>
Signed-off-by: Ian Skelskey <ianskelskey(a)gmail.com>
Signed-off-by: Ruth Frasur Davis <redavis4974(a)gmail.com>
Signed-off-by: Shula Link <slink(a)gchrl.org>
Signed-off-by: Michele Morgan <mmorgan(a)noblenet.org>
diff --git a/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.service.ts b/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.service.ts
index 37ad90f17d..a973a15c25 100644
--- a/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.service.ts
+++ b/Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.service.ts
@@ -14,6 +14,7 @@ import {FileExportService} from '@eg/share/util/file-export.service';
import {ServerStoreService} from '@eg/core/server-store.service';
import {StoreService} from '@eg/core/store.service';
import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
+import { Observable, Subscription, lastValueFrom } from 'rxjs';
/* Managing volcopy data */
@@ -498,17 +499,17 @@ export class VolCopyService implements OnDestroy {
'eg.cat.volcopy.defaults', this.defaults);
}
- fetchBibParts(recordIds: number[]) {
+ fetchBibParts(recordIds: number[]) : Promise<any> {
if (recordIds.length === 0) { return; }
// All calls fetch updated data since we may be creating
// new mono parts during editing.
- this.pcrud.search('bmp',
+ return lastValueFrom( this.pcrud.search('bmp',
{record: recordIds, deleted: 'f'})
- .subscribe(
- { next: part => {
+ .pipe(tap({
+ next: part => {
const updatedBibParts = {...this.bibParts};
if (!updatedBibParts[part.record()]) {
updatedBibParts[part.record()] = [];
@@ -517,7 +518,9 @@ export class VolCopyService implements OnDestroy {
updatedBibParts[part.record()].push(part);
}
this.bibParts = updatedBibParts;
- }, error: (err: unknown) => {}, complete: () => {
+ },
+ error: (err: unknown) => {},
+ complete: () => {
const finalBibParts = {...this.bibParts};
recordIds.forEach(bibId => {
if (finalBibParts[bibId]) {
@@ -527,8 +530,9 @@ export class VolCopyService implements OnDestroy {
}
});
this.bibParts = finalBibParts;
- } }
- );
+ }
+ }))
+ );
}
-----------------------------------------------------------------------
Summary of changes:
.../app/staff/cat/volcopy/vol-edit.component.html | 2 +-
.../app/staff/cat/volcopy/vol-edit.component.ts | 32 +---------
.../app/staff/cat/volcopy/volcopy.component.html | 6 +-
.../src/app/staff/cat/volcopy/volcopy.component.ts | 70 +++++++++++++++++++++-
.../src/app/staff/cat/volcopy/volcopy.service.ts | 19 +++---
5 files changed, 89 insertions(+), 40 deletions(-)
hooks/post-receive
--
Evergreen ILS