import {OrgService} from '@eg/core/org.service';
import {NetService} from '@eg/core/net.service';
import {PatronService} from '@eg/staff/share/patron/patron.service';
-import {PatronContextService} from './patron.service';
-
-type FieldOptions = 'required' | 'suggested' | 'all';
+import {PatronContextService, EditorFieldOptions} from './patron.service';
@Component({
templateUrl: 'edit-toolbar.component.html',
})
export class EditToolbarComponent implements OnInit {
- showFields: FieldOptions = 'all';
-
- @Output() saveClicked: EventEmitter<void> = new EventEmitter<void>();
- @Output() saveCloneClicked: EventEmitter<void> = new EventEmitter<void>();
- @Output() printClicked: EventEmitter<void> = new EventEmitter<void>();
- @Output() showFieldsChanged:
- EventEmitter<FieldOptions> = new EventEmitter<FieldOptions>();
+ showFields: EditorFieldOptions = 'all';
constructor(
private org: OrgService,
private net: NetService,
- public patronService: PatronService,
+ private patronService: PatronService,
public context: PatronContextService
) {}
ngOnInit() {
}
- changeFields(field: FieldOptions) {
+ changeFields(field: EditorFieldOptions) {
this.showFields = field;
- this.showFieldsChanged.emit(field);
+ this.context.showFieldsChanged.emit(field);
}
}
import {AuthService} from '@eg/core/auth.service';
import {PcrudService} from '@eg/core/pcrud.service';
import {PatronService} from '@eg/staff/share/patron/patron.service';
-import {PatronContextService} from './patron.service';
+import {PatronContextService, EditorFieldOptions} from './patron.service';
import {ComboboxComponent, ComboboxEntry} from '@eg/share/combobox/combobox.component';
import {DateUtil} from '@eg/share/util/date';
import {ProfileSelectComponent} from '@eg/staff/share/patron/profile-select.component';
autoId = -1;
patron: IdlObject;
+ modifiedPatron: IdlObject;
changeHandlerNeeded = false;
nameTab = 'primary';
loading = false;
optInSettingTypes: {[name: string]: IdlObject} = {};
secondaryGroups: IdlObject[];
expireDate: Date;
+ visibleFields: EditorFieldOptions;
// All locations we have the specified permissions
permOrgs: {[name: string]: number[]};
) {}
ngOnInit() {
+
+ // Listen for edit-toolbar events
+ this.context.saveClicked.subscribe(_ => this.save());
+ this.context.saveCloneClicked.subscribe(_ => this.saveClone());
+ this.context.printClicked.subscribe(_ => this.printPatron());
+ this.context.showFieldsChanged.subscribe(f => this.visibleFields = f);
+
this.load();
}
cboxEntry = {
id: null,
freetext: true,
- label: map.stat_cat_entry()
+ label: map.stat_cat_entry(),
+ fm: map
};
stat.entries.unshift(cboxEntry);
patron.isnew(true);
patron.addresses([]);
patron.settings([]);
+ patron.waiver_entries([]);
const card = this.idl.create('ac');
card.isnew(true);
userStatCatChange(cat: IdlObject, entry: ComboboxEntry) {
// TODO: set dirty
- // 2-way binding at work, no need to set the value
+
+ let map = this.patron.stat_cat_entries()
+ .filter(m => m.stat_cat() === cat.id())[0];
+
+ if (map) {
+ if (entry) {
+ map.stat_cat_entry(entry.label);
+ map.ischanged(true);
+ map.isdeleted(false);
+ } else {
+ map.isdeleted(true);
+ }
+ } else {
+ map = this.idl.create('actscecm');
+ map.isnew(true);
+ map.stat_cat(cat.id());
+ map.stat_cat_entry(entry.label);
+ map.target_usr(this.patronId);
+ this.patron.stat_cat_entries().push(map);
+ }
}
userSettingChange(name: string, value: any) {
// TODO: set dirty
+ const obj = this.objectFromPath(path, index);
const value = this.getFieldValue(path, index, field);
+ obj.ischanged(true); // isnew() supersedes
console.debug(
`Modifying field path=${path || ''} field=${field} value=${value}`);
nonDeletedAddresses(): IdlObject[] {
return this.patron.addresses().filter(a => !a.isdeleted());
}
+
+ save(): Promise<any> {
+
+ // TODO clear unload prompt
+
+ this.loading = true;
+ return this.saveUser()
+ .then(_ => this.saveUserSettings())
+ .then(_ => this.postSaveRedirect())
+ }
+
+ postSaveRedirect() {
+ window.location.href = window.location.href;
+ }
+
+ saveClone() {
+ // TODO
+ }
+
+ // Resolves on success, rejects on error
+ saveUser(): Promise<IdlObject> {
+ this.modifiedPatron = null;
+
+ return this.net.request(
+ 'open-ils.actor',
+ 'open-ils.actor.patron.update',
+ this.auth.token(), this.patron
+ ).toPromise().then(result => {
+
+ if (result && result.classname) {
+ // Successful result returns the patron IdlObject.
+ return this.modifiedPatron = result;
+ }
+
+ const evt = this.evt.parse(result);
+
+ if (evt) {
+ console.error('Patron update failed with', evt);
+ if (evt.textcode === 'XACT_COLLISION') {
+ // TODO alert
+ }
+ }
+
+ alert('Patron update failed:' + result);
+
+ return Promise.reject('Save Failed');
+ });
+ }
+
+ // Resolves on success, rejects on error
+ saveUserSettings(): Promise<any> {
+
+ let settings: any = {};
+
+ if (this.patronId) {
+ // Update all user editor setting values for existing
+ // users regardless of whether a value changed.
+ settings = this.userSettings;
+
+ } else {
+
+ // Create settings for all non-null setting values for new patrons.
+ this.userSettings.forEach( (val, key) => {
+ if (val !== null) settings[key] = val;
+ });
+ }
+
+ if (Object.keys(settings).length == 0) { return Promise.resolve(); }
+
+ return this.net.request(
+ 'open-ils.actor',
+ 'open-ils.actor.patron.settings.update',
+ this.auth.token(), this.modifiedPatron.id(), settings
+ ).toPromise();
+ }
+
+ printPatron() {
+ // TODO
+ }
}
-import {Injectable} from '@angular/core';
+import {Injectable, EventEmitter} from '@angular/core';
import {IdlObject} from '@eg/core/idl.service';
import {NetService} from '@eg/core/net.service';
import {OrgService} from '@eg/core/org.service';
import {StoreService} from '@eg/core/store.service';
import {CircService, CircDisplayInfo} from '@eg/staff/share/circ/circ.service';
+export type EditorFieldOptions = 'required' | 'suggested' | 'all';
+
+
export interface BillGridEntry extends CircDisplayInfo {
xact: IdlObject; // mbt
billingLocation?: string;
// These should persist tab changes
checkouts: CircGridEntry[] = [];
+ // Emitted by the patron edit toolbar, which is kept as a
+ // separate component so it can be positioned differently.
+ // We just act as a go-between.
+ saveClicked: EventEmitter<void> = new EventEmitter<void>();
+ saveCloneClicked: EventEmitter<void> = new EventEmitter<void>();
+ printClicked: EventEmitter<void> = new EventEmitter<void>();
+ showFieldsChanged: EventEmitter<EditorFieldOptions> =
+ new EventEmitter<EditorFieldOptions>();
+
constructor(
private store: StoreService,
private net: NetService,