</div>
</ng-template>
-<ng-container
- *ngTemplateOutlet="copyAttrsHeader;context:{
- moreCss:'mt-3 bg-light border border-secondary',
- hideBarcode: true
- }">
+<ng-container *ngIf="hasEditableCopies()">
+ <ng-container
+ *ngTemplateOutlet="copyAttrsHeader;context:{
+ moreCss:'mt-3 bg-light border border-secondary',
+ hideBarcode: true
+ }">
+ </ng-container>
+
+ <div class="pt-2 bg-light border border-secondary border-top-0 rounded-bottom">
+ <eg-lineitem-copy-attrs (batchApplyRequested)="batchApplyAttrs($event)"
+ [batchMode]="true"> </eg-lineitem-copy-attrs>
+ </div>
</ng-container>
-<div class="pt-2 bg-light border border-secondary border-top-0 rounded-bottom">
- <eg-lineitem-copy-attrs (batchApplyRequested)="batchApplyAttrs($event)"
- [batchMode]="true"> </eg-lineitem-copy-attrs>
-</div>
-
<hr/>
<ng-container *ngTemplateOutlet="copyAttrsHeader"> </ng-container>
return promise;
}
+
+ hasEditableCopies(): boolean {
+ if (this.lineitem) {
+ const copies = this.lineitem.lineitem_details();
+ if (copies && copies.length > 0) {
+ for (let idx = 0; idx < copies.length; idx++) { // early break
+ if (this.liService.copyDisposition(
+ this.lineitem, copies[idx]) === 'pre-order') {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
}
// are not required to go fetch them en masse / en duplicato.
fetchFormulaValues(): Promise<any> {
- const funds = this.formulaValues.fund ?
- Object.keys(this.formulaValues.fund) : [];
-
- const mods = this.formulaValues.circ_modifier ?
- Object.keys(this.formulaValues.circ_modifier) : [];
-
- const locs = this.formulaValues.location ?
- Object.keys(this.formulaValues.location) : [];
-
- let promise = Promise.resolve();
-
- if (funds.length > 0) {
- promise = promise.then(_ => {
- return this.pcrud.search('acqf', {id: funds})
- .pipe(tap(fund => {
- this.liService.fundCache[fund.id()] = fund;
- this.liService.batchOptionWanted.emit(
- {fund: {id: fund.id(), label: fund.code(), fm: fund}});
- })).toPromise();
- });
+ let funds = [];
+ if (this.formulaValues.fund) {
+ funds = Object.keys(this.formulaValues.fund).map(id => Number(id));
}
- if (mods.length > 0) {
- promise = promise.then(_ => {
- return this.pcrud.search('ccm', {code: mods})
- .pipe(tap(mod => {
- this.liService.circModCache[mod.code()] = mod;
- this.liService.batchOptionWanted.emit({circ_modifier:
- {id: mod.code(), label: mod.code(), fm: mod}});
- })).toPromise();
- });
+ let locs = [];
+ if (this.formulaValues.location) {
+ locs = Object.keys(this.formulaValues.location).map(id => Number(id));
}
- if (locs.length > 0) {
- promise = promise.then(_ => {
- return this.pcrud.search('acpl', {id: locs})
- .pipe(tap(loc => {
- this.loc.locationCache[loc.id()] = loc;
- this.liService.batchOptionWanted.emit({location:
- {id: loc.id(), label: loc.name(), fm: loc}});
- })).toPromise();
- });
- }
+ const mods = this.formulaValues.circ_modifier ?
+ Object.keys(this.formulaValues.circ_modifier) : [];
- return promise;
+ return this.liService.fetchFunds(funds)
+ .then(_ => this.liService.fetchLocations(locs))
+ .then(_ => this.liService.fetchCircMods(mods));
}
// Apply a formula entry to a single copy.
import {IdlObject, IdlService} from '@eg/core/idl.service';
import {NetService} from '@eg/core/net.service';
import {AuthService} from '@eg/core/auth.service';
-import {LineitemService} from './lineitem.service';
+import {LineitemService, COPY_ORDER_DISPOSITION} from './lineitem.service';
import {ComboboxComponent, ComboboxEntry} from '@eg/share/combobox/combobox.component';
import {ItemLocationService} from '@eg/share/item-location-select/item-location-select.service';
import {ItemLocationSelectComponent} from '@eg/share/item-location-select/item-location-select.component';
return false;
}
- disposition(): 'canceled' | 'delayed' | 'received' | 'on-order' | 'pre-order' {
- if (!this.copy || !this.lineitem) {
- return null;
- } else if (this.copy.cancel_reason()) {
- if (this.copy.cancel_reason().keep_debits() === 't') {
- return 'delayed';
- } else {
- return 'canceled';
- }
- } else if (this.copy.recv_time()) {
- return 'received';
- } else if (this.lineitem.state() === 'on-order') {
- return 'on-order';
- } else { return 'pre-order'; }
+ disposition(): COPY_ORDER_DISPOSITION {
+ return this.liService.copyDisposition(this.lineitem, this.copy);
}
}
import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
import {ItemLocationService} from '@eg/share/item-location-select/item-location-select.service';
+const COPY_ORDER_DISPOSITIONS:
+ 'canceled' | 'delayed' | 'received' | 'on-order' | 'pre-order' = null;
+export type COPY_ORDER_DISPOSITION = typeof COPY_ORDER_DISPOSITIONS;
+
export interface BatchLineitemStruct {
id: number;
lineitem: IdlObject;
const lids = li.lineitem_details().filter(copy =>
(copy.isnew() || copy.ischanged() || copy.isdeleted()));
- return this.net.request(
- 'open-ils.acq',
- 'open-ils.acq.lineitem_detail.cud.batch', this.auth.token(), lids);
+ return from(
+
+ // Ensure we have the updated fund/loc/mod values before
+ // sending the copies off to be updated and then re-drawn.
+ this.fetchFunds(lids.map(lid => lid.fund()))
+ .then(_ => this.fetchLocations(lids.map(lid => lid.location())))
+ .then(_ => this.fetchCircMods(lids.map(lid => lid.circ_modifier())))
+
+ ).pipe(switchMap(_ =>
+ this.net.request(
+ 'open-ils.acq',
+ 'open-ils.acq.lineitem_detail.cud.batch',
+ this.auth.token(), lids
+ )
+ ));
}
updateLineitems(lis: IdlObject[]): Observable<BatchLineitemUpdateStruct> {
return obs;
}
+
+
+ // Methods to fetch copy-related data, add it to our local cache,
+ // and announce that new values are available for comboboxes.
+ fetchFunds(fundIds: number[]): Promise<any> {
+ fundIds = fundIds.filter(id => id && !(id in this.fundCache));
+ if (fundIds.length === 0) { return Promise.resolve(); }
+
+ return this.pcrud.search('acqf', {id: fundIds})
+ .pipe(tap(fund => {
+ this.fundCache[fund.id()] = fund;
+ this.batchOptionWanted.emit(
+ {fund: {id: fund.id(), label: fund.code(), fm: fund}});
+ })).toPromise();
+ }
+
+ fetchCircMods(circMods: string[]): Promise<any> {
+ circMods = circMods
+ .filter(code => code && !(code in this.circModCache));
+
+ if (circMods.length === 0) { return Promise.resolve(); }
+
+ return this.pcrud.search('ccm', {code: circMods})
+ .pipe(tap(mod => {
+ this.circModCache[mod.code()] = mod;
+ this.batchOptionWanted.emit({circ_modifier:
+ {id: mod.code(), label: mod.code(), fm: mod}});
+ })).toPromise();
+ }
+
+ fetchLocations(locIds: number[]): Promise<any> {
+ locIds = locIds.filter(id => id && !(id in this.loc.locationCache));
+ if (locIds.length === 0) { return Promise.resolve(); }
+
+ return this.pcrud.search('acpl', {id: locIds})
+ .pipe(tap(loc => {
+ this.loc.locationCache[loc.id()] = loc;
+ this.batchOptionWanted.emit({location:
+ {id: loc.id(), label: loc.name(), fm: loc}});
+ })).toPromise();
+ }
+
+ // Order disposition of a single lineitem detail
+ copyDisposition(lineitem: IdlObject, copy: IdlObject): COPY_ORDER_DISPOSITION {
+ if (!copy || !lineitem) {
+ return null;
+ } else if (copy.cancel_reason()) {
+ if (copy.cancel_reason().keep_debits() === 't') {
+ return 'delayed';
+ } else {
+ return 'canceled';
+ }
+ } else if (copy.recv_time()) {
+ return 'received';
+ } else if (lineitem.state() === 'on-order') {
+ return 'on-order';
+ } else { return 'pre-order'; }
+ }
}