From: Galen Charlton Date: Mon, 29 Nov 2021 16:11:02 +0000 (-0500) Subject: LP#1942220: more Angularization of the Acquisitions staff interfaces X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=8e062cc8ffb3264b926047bca2a5cbd9df1ee6d8;p=working%2FEvergreen.git LP#1942220: more Angularization of the Acquisitions staff interfaces This patch extends on the work done for bugs 1929741 and 1929749 to finish converting the following interfaces to Angular: - Selection Lists - Load MARC Order Records - Purchase Orders - Create Purchase Order Note: this project was often referred to as "Angular acquisitions sprint 4" Mike Rylander made some contributions to this patch. Sponsored-by: Evergreen Community Development Initiative Signed-off-by: Galen Charlton Signed-off-by: Ruth Frasur Signed-off-by: Bill Erickson --- diff --git a/Open-ILS/src/eg2/src/app/staff/acq/acq-common.module.ts b/Open-ILS/src/eg2/src/app/staff/acq/acq-common.module.ts new file mode 100644 index 0000000000..7a32edacbe --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/acq/acq-common.module.ts @@ -0,0 +1,19 @@ +import {NgModule} from '@angular/core'; +import {StaffCommonModule} from '@eg/staff/common.module'; +import {UploadComponent} from './picklist/upload.component'; + +@NgModule({ + declarations: [ + UploadComponent + ], + exports: [ + UploadComponent + ], + imports: [ + StaffCommonModule + ], + providers: [] +}) + +export class AcqCommonModule { +} diff --git a/Open-ILS/src/eg2/src/app/staff/acq/lineitem/add-copies-dialog.component.html b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/add-copies-dialog.component.html new file mode 100644 index 0000000000..29d1b3eed1 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/add-copies-dialog.component.html @@ -0,0 +1,26 @@ + +
+ + + +
+
+ diff --git a/Open-ILS/src/eg2/src/app/staff/acq/lineitem/add-copies-dialog.component.ts b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/add-copies-dialog.component.ts new file mode 100644 index 0000000000..6f2237c625 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/add-copies-dialog.component.ts @@ -0,0 +1,18 @@ +import {Component, Input, ViewChild, TemplateRef, OnInit} from '@angular/core'; +import {NgbModal} from '@ng-bootstrap/ng-bootstrap'; +import {DialogComponent} from '@eg/share/dialog/dialog.component'; +import {IdlService, IdlObject} from '@eg/core/idl.service'; +import {ComboboxEntry} from '@eg/share/combobox/combobox.component'; + +@Component({ + selector: 'eg-acq-add-copies-dialog', + templateUrl: './add-copies-dialog.component.html' +}) + +export class AddCopiesDialogComponent extends DialogComponent { + @Input() ids: number[]; + lineitemWithCopies: IdlObject; + constructor(private modal: NgbModal) { super(modal); } +} + + diff --git a/Open-ILS/src/eg2/src/app/staff/acq/lineitem/add-to-po-dialog.component.html b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/add-to-po-dialog.component.html new file mode 100644 index 0000000000..9567e2e7b0 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/add-to-po-dialog.component.html @@ -0,0 +1,32 @@ + +
+ + + +
+
+ diff --git a/Open-ILS/src/eg2/src/app/staff/acq/lineitem/add-to-po-dialog.component.ts b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/add-to-po-dialog.component.ts new file mode 100644 index 0000000000..5e8739d682 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/add-to-po-dialog.component.ts @@ -0,0 +1,18 @@ +import {Component, Input, ViewChild, TemplateRef, OnInit} from '@angular/core'; +import {NgbModal} from '@ng-bootstrap/ng-bootstrap'; +import {DialogComponent} from '@eg/share/dialog/dialog.component'; +import {IdlService, IdlObject} from '@eg/core/idl.service'; +import {ComboboxEntry} from '@eg/share/combobox/combobox.component'; + +@Component({ + selector: 'eg-acq-add-to-po-dialog', + templateUrl: './add-to-po-dialog.component.html' +}) + +export class AddToPoDialogComponent extends DialogComponent { + @Input() ids: number[]; + po: ComboboxEntry; + constructor(private modal: NgbModal) { super(modal); } +} + + diff --git a/Open-ILS/src/eg2/src/app/staff/acq/lineitem/batch-copies.component.html b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/batch-copies.component.html index 8a5bb4d132..a654c87bc8 100644 --- a/Open-ILS/src/eg2/src/app/staff/acq/lineitem/batch-copies.component.html +++ b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/batch-copies.component.html @@ -1,10 +1,6 @@ - - - - + + @@ -12,14 +8,15 @@
Owning Branch
-
Copy Location
+
Shelving Location
Collection Code
Fund
Circ Modifier
-
Callnumber
+
Callnumber
- Barcode + Barcode
+
Receiver
@@ -35,6 +32,7 @@
@@ -47,10 +45,13 @@
diff --git a/Open-ILS/src/eg2/src/app/staff/acq/lineitem/batch-copies.component.ts b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/batch-copies.component.ts index 5adb6e3f00..f312b43eca 100644 --- a/Open-ILS/src/eg2/src/app/staff/acq/lineitem/batch-copies.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/batch-copies.component.ts @@ -8,8 +8,8 @@ import {AuthService} from '@eg/core/auth.service'; import {LineitemService} from './lineitem.service'; import {ComboboxEntry} from '@eg/share/combobox/combobox.component'; import {LineitemCopyAttrsComponent} from './copy-attrs.component'; -import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component'; import {CancelDialogComponent} from './cancel-dialog.component'; +import {LineitemAlertDialogComponent} from './lineitem-alert-dialog.component'; const BATCH_FIELDS = [ 'owning_lib', @@ -28,12 +28,18 @@ const BATCH_FIELDS = [ export class LineitemBatchCopiesComponent implements OnInit { @Input() lineitem: IdlObject; + @Input() batchAdd = false; - @ViewChild('confirmAlertsDialog') confirmAlertsDialog: ConfirmDialogComponent; + @Output() becameDirty = new EventEmitter(); + + @ViewChild('confirmAlertsDialog') confirmAlertsDialog: LineitemAlertDialogComponent; @ViewChild('cancelDialog') cancelDialog: CancelDialogComponent; // Current alert that needs confirming alertText: IdlObject; + liId: number; + liTitle: string; + alertComment: string; constructor( private evt: EventService, @@ -43,7 +49,14 @@ export class LineitemBatchCopiesComponent implements OnInit { private liService: LineitemService ) {} - ngOnInit() {} + ngOnInit() { + if (!this.lineitem) { + this.lineitem = this.idl.create('jub'); + const copy = this.idl.create('acqlid'); + copy.isnew(true); + this.lineitem.lineitem_details([copy]); + } + } // Propagate values from the batch edit bar into the indivudual LID's batchApplyAttrs(copyTemplate: IdlObject) { @@ -53,6 +66,7 @@ export class LineitemBatchCopiesComponent implements OnInit { this.lineitem.lineitem_details().forEach(copy => { copy[field](val); copy.ischanged(true); // isnew() takes precedence + this.becameDirty.emit(true); }); }); } @@ -66,6 +80,7 @@ export class LineitemBatchCopiesComponent implements OnInit { } else { // Requires a Save Changes action. copy.isdeleted(true); + this.becameDirty.emit(true); } } @@ -94,7 +109,7 @@ export class LineitemBatchCopiesComponent implements OnInit { } receiveCopy(copy: IdlObject) { - this.checkLiAlerts().then(ok => { + this.liService.checkLiAlerts([this.lineitem], this.confirmAlertsDialog).then(ok => { this.net.request( 'open-ils.acq', 'open-ils.acq.lineitem_detail.receive', @@ -111,29 +126,6 @@ export class LineitemBatchCopiesComponent implements OnInit { ).subscribe(ok => this.handleActionResponse(ok)); } - checkLiAlerts(): Promise { - - let promise = Promise.resolve(true); - - const notes = this.lineitem.lineitem_notes().filter(note => - note.alert_text() && !this.liService.alertAcks[note.id()]); - - if (notes.length === 0) { return promise; } - - notes.forEach(n => { - promise = promise.then(_ => { - this.alertText = n.alert_text(); - return this.confirmAlertsDialog.open().toPromise().then(ok => { - if (!ok) { return Promise.reject(); } - this.liService.alertAcks[n.id()] = true; - return true; - }); - }); - }); - - return promise; - } - hasEditableCopies(): boolean { if (this.lineitem) { const copies = this.lineitem.lineitem_details(); diff --git a/Open-ILS/src/eg2/src/app/staff/acq/lineitem/batch-update-copies-dialog.component.html b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/batch-update-copies-dialog.component.html new file mode 100644 index 0000000000..72e71b122b --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/batch-update-copies-dialog.component.html @@ -0,0 +1,70 @@ + +
+
Owning Branch
+
Shelving Location
+
Collection Code
+
Fund
+
Circ Modifier
+
+
+
+ + +
+ + + +
+
+ diff --git a/Open-ILS/src/eg2/src/app/staff/acq/lineitem/batch-update-copies-dialog.component.ts b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/batch-update-copies-dialog.component.ts new file mode 100644 index 0000000000..0ca7575463 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/batch-update-copies-dialog.component.ts @@ -0,0 +1,91 @@ +import {Component, Input} from '@angular/core'; +import {Observable} from 'rxjs'; +import {NgbModal, NgbModalOptions} from '@ng-bootstrap/ng-bootstrap'; +import {DialogComponent} from '@eg/share/dialog/dialog.component'; +import {IdlObject} from '@eg/core/idl.service'; +import {OrgService} from '@eg/core/org.service'; +import {AuthService} from '@eg/core/auth.service'; +import {ComboboxEntry} from '@eg/share/combobox/combobox.component'; +import {LineitemCopyAttrsComponent} from './copy-attrs.component'; + +@Component({ + selector: 'eg-acq-batch-update-copies-dialog', + templateUrl: './batch-update-copies-dialog.component.html' +}) + +export class BatchUpdateCopiesDialogComponent extends DialogComponent { + + @Input() ids: number[]; + + copyCount = ''; + selectedFormula: ComboboxEntry; + formulaFilter = {owner: []}; + templateCopy: IdlObject; + + constructor( + private modal: NgbModal, + private org: OrgService, + private auth: AuthService + ) { + super(modal); + } + + open(args?: NgbModalOptions): Observable { + if (!args) { + args = {}; + } + + this.copyCount = ''; + this.selectedFormula = null; + this.formulaFilter.owner = + this.org.fullPath(this.auth.user().ws_ou(), true); + + return super.open(args); + } + + canApply(): boolean { + if (!this.templateCopy) { return false; } + + const _copyCount = parseInt(this.copyCount, 10); + if ((_copyCount && _copyCount > 0) || + this.selectedFormula?.id || + this.templateCopy.owning_lib() || + this.templateCopy.location() || + this.templateCopy.collection_code() || + this.templateCopy.fund() || + this.templateCopy.circ_modifier()) { + return true; + } else { + return false; + } + } + + compileBatchChange(): any { + const changes = { + _dist_formula: this.selectedFormula?.id + }; + const _copyCount = parseInt(this.copyCount, 10); + if (_copyCount && _copyCount > 0) { + changes['item_count'] = _copyCount; + } + if (this.templateCopy.owning_lib()) { + changes['owning_lib'] = this.templateCopy.owning_lib(); + } + if (this.templateCopy.location()) { + changes['location'] = this.templateCopy.location(); + } + if (this.templateCopy.collection_code()) { + changes['collection_code'] = this.templateCopy.collection_code(); + } + if (this.templateCopy.fund()) { + changes['fund'] = this.templateCopy.fund(); + } + if (this.templateCopy.circ_modifier()) { + changes['circ_modifier'] = this.templateCopy.owning_lib(); + } + return changes; + } + +} + + diff --git a/Open-ILS/src/eg2/src/app/staff/acq/lineitem/bib-finder-dialog.component.css b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/bib-finder-dialog.component.css new file mode 100644 index 0000000000..56fc5d395e --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/bib-finder-dialog.component.css @@ -0,0 +1,3 @@ +.bib-finder-results-row:nth-child(even) { + background-color: rgba(0,0,0,.03); +} diff --git a/Open-ILS/src/eg2/src/app/staff/acq/lineitem/bib-finder-dialog.component.html b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/bib-finder-dialog.component.html new file mode 100644 index 0000000000..5adebb5b0a --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/bib-finder-dialog.component.html @@ -0,0 +1,57 @@ + +
+ + + +
+
+ diff --git a/Open-ILS/src/eg2/src/app/staff/acq/lineitem/bib-finder-dialog.component.ts b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/bib-finder-dialog.component.ts new file mode 100644 index 0000000000..630400d8e7 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/bib-finder-dialog.component.ts @@ -0,0 +1,107 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import {Observable} from 'rxjs'; +import {map} from 'rxjs/operators'; +import {NgbModal, NgbModalOptions} from '@ng-bootstrap/ng-bootstrap'; +import {DialogComponent} from '@eg/share/dialog/dialog.component'; +import {NetService} from '@eg/core/net.service'; +import {EgEvent, EventService} from '@eg/core/event.service'; +import {IdlService, IdlObject} from '@eg/core/idl.service'; +import {ComboboxEntry} from '@eg/share/combobox/combobox.component'; +import {LineitemService} from './lineitem.service'; +import {BibRecordService, BibRecordSummary} from '@eg/share/catalog/bib-record.service'; + +@Component({ + selector: 'eg-acq-bib-finder-dialog', + styleUrls: ['./bib-finder-dialog.component.css'], + templateUrl: './bib-finder-dialog.component.html' +}) + +export class BibFinderDialogComponent extends DialogComponent { + @Input() liId: number; + + queryString: string; + lineitem: IdlObject; + results: BibRecordSummary[] = []; + doingSearch = false; + bibToDisplay: number; + + constructor( + private modal: NgbModal, + private net: NetService, + private evt: EventService, + private bib: BibRecordService, + private liService: LineitemService + ) { + super(modal); + } + + open(args?: NgbModalOptions): Observable { + if (!args) { + args = {}; + } + + this.queryString = ''; + this.results.length = 0; + this.doingSearch = false; + this.bibToDisplay = null; + this.liService.getFleshedLineitems([this.liId], {fromCache: true}).subscribe(liStruct => { + this.lineitem = liStruct.lineitem; + this.queryString = this._buildDefaultQuery(this.lineitem); + }); + return super.open(args); + } + + _buildDefaultQuery(li: IdlObject): string { + let query = ''; + ['title', 'author'].forEach(field => { + const attr = this.liService.getFirstAttributeValue(li, field); + if (attr.length) { + query += field + ':' + attr + ' '; + } + }); + ['isbn', 'issn', 'upc'].forEach(field => { + const attr = this.liService.getFirstAttributeValue(li, field); + if (attr.length) { + query += 'identifier|' + field + ':' + attr + ' '; + } + }); + return query; + } + + submitSearch() { + this.results.length = 0; + this.bibToDisplay = null; + this.doingSearch = true; + this.net.request( + 'open-ils.search', + 'open-ils.search.biblio.multiclass.query.staff', + {limit: 15}, this.queryString, 1 + ).subscribe(response => { + const evt = this.evt.parse(response); + if (evt) { + this.doingSearch = false; + return; + } + const ids = response.ids.map(x => x[0]); + if (ids.length < 1) { + this.doingSearch = false; + return; + } + const bibSummaries: {[id: number]: BibRecordSummary} = {}; + this.bib.getBibSummaries(ids).subscribe( + summary => bibSummaries[summary.id] = summary, + err => {}, + () => { + this.doingSearch = false; + ids.forEach(id => { + if (bibSummaries[id]) { + this.results.push(bibSummaries[id]); + } + }); + } + ); + }); + } +} + + diff --git a/Open-ILS/src/eg2/src/app/staff/acq/lineitem/brief-record.component.ts b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/brief-record.component.ts index fa82cec9ad..3d5912e310 100644 --- a/Open-ILS/src/eg2/src/app/staff/acq/lineitem/brief-record.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/brief-record.component.ts @@ -79,7 +79,11 @@ export class BriefRecordComponent implements OnInit { // Append fields to the document dfNode.setAttribute('tag', '' + tags[0]); - dfNode.setAttribute('ind1', ' '); + if (attr.code() === 'upc') { + dfNode.setAttribute('ind1', '1'); + } else { + dfNode.setAttribute('ind1', ' '); + } dfNode.setAttribute('ind2', ' '); sfNode.setAttribute('code', '' + subfields[0]); const tNode = doc.createTextNode(value); diff --git a/Open-ILS/src/eg2/src/app/staff/acq/lineitem/cancel-dialog.component.html b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/cancel-dialog.component.html index 23ae488701..a8e7dd1a6a 100644 --- a/Open-ILS/src/eg2/src/app/staff/acq/lineitem/cancel-dialog.component.html +++ b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/cancel-dialog.component.html @@ -1,15 +1,23 @@