<div class="mt-1 pt-1 border-top">
<div class="batch-copy-row"
- *ngFor="let copy of lineitem.lineitem_details(); let idx = index">
+ *ngFor="let copy of copies(); let idx = index">
<eg-lineitem-copy-attrs
(receiveRequested)="receiveCopy($event)"
(unReceiveRequested)="unReceiveCopy($event)"
}
return false;
}
+
+ copies(): IdlObject[] {
+ return this.lineitem.lineitem_details().filter(c => !c.isdeleted());
+ }
}
import {NetService} from '@eg/core/net.service';
import {PcrudService} from '@eg/core/pcrud.service';
import {AuthService} from '@eg/core/auth.service';
+import {LineitemService} from './lineitem.service';
const MARC_NS = 'http://www.loc.gov/MARC21/slim';
private idl: IdlService,
private auth: AuthService,
private net: NetService,
- private pcrud: PcrudService
+ private pcrud: PcrudService,
+ private liService: LineitemService
) { }
ngOnInit() {
this.net.request('open-ils.acq',
'open-ils.acq.lineitem.create', this.auth.token(), li
).toPromise().then(_ => {
+ this.liService.activateStateChange.emit();
this.router.navigate(['../'], {
relativeTo: this.route,
queryParamsHandling: 'merge'
<label class="ml-3" for='distrib-formula-cbox' i18n>Distribution Formulas</label>
<span class="ml-3">
<eg-combobox idlClass="acqdf" [idlQueryAnd]="formulaFilter"
+ [asyncSupportsEmptyTermClick]="true"
#distribFormCbox domId="distrib-formula-cbox">
</eg-combobox>
</span>
import {NetService} from '@eg/core/net.service';
import {PcrudService} from '@eg/core/pcrud.service';
import {AuthService} from '@eg/core/auth.service';
-import {LineitemService} from './lineitem.service';
+import {LineitemService, FleshCacheParams} from './lineitem.service';
import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
import {ItemLocationService} from '@eg/share/item-location-select/item-location-select.service';
this.liService.getLiAttrDefs();
}
- load(): Promise<any> {
+ load(params?: FleshCacheParams): Promise<any> {
this.lineitem = null;
this.copyCount = 1;
- return this.liService.getFleshedLineitems(
- [this.lineitemId], {toCache: true, fromCache: true})
+
+ if (!params) {
+ params = {toCache: true, fromCache: true};
+ }
+
+ return this.liService.getFleshedLineitems([this.lineitemId], params)
.pipe(tap(liStruct => this.lineitem = liStruct.lineitem)).toPromise()
.then(_ => {
this.liLocked =
this.progressValue++;
},
err => {},
- () => this.load().then(_ => {
+ () => this.load({toCache: true}).then(_ => {
this.liService.activateStateChange.emit(this.lineitem.id());
this.saving = false;
})
<div class="flex-2 p-1 pr-2 pl-2">
<ng-container *ngIf="!batchMode">
<ng-container *ngIf="disposition() == 'pre-order'">
- <button *ngIf="!copy.isdeleted()"
+ <button
class="btn btn-outline-danger material-icon-button"
(click)="deleteRequested.emit(copy)" title="Delete Item" i18n-title>
<span class="material-icons">delete</span>
</button>
- <button *ngIf="copy.isdeleted()"
- class="btn btn-outline-info material-icon-button"
- (click)="copy.isdeleted(false)" title="Un-Delete Item" i18n-title>
- <span class="material-icons">restore_page</span>
- </button>
</ng-container>
<ng-container *ngIf="disposition() == 'on-order'">
<a href="javascript:;" (click)="receiveRequested.emit(copy)" i18n>Mark Received</a>
<span *ngIf="liHasAlerts(li)" class="text-danger material-icons"
title="Has Alerts" i18n-title>flag</span>
</a>
- <span class="ml-1 mr-1" i18n> | </span>
- <a class="label-with-material-icon"
- routerLink="lineitem/{{li.id()}}/worksheet/">
- <span class="material-icons small mr-1">create</span>
- <span i18n>Worksheet</span>
- </a>
- <span class="ml-1 mr-1" i18n> | </span>
- <a class="label-with-material-icon"
- [queryParams]="{f: 'jub:id', val1: li.id()}"
- routerLink="/staff/acq/search/invoices">
- <span class="material-icons small mr-1">list</span>
- <span i18n>Invoice(s)</span>
- </a>
<ng-container *ngIf="li.eg_bib_id()">
<span class="ml-1 mr-1" i18n> | </span>
<a class="label-with-material-icon mr-2"
</a>
</ng-container>
- <ng-container *ngIf="!poId && li.purchase_order()">
- <span class="ml-1 mr-1" i18n> | </span>
- <a class="label-with-material-icon"
- title="Purchase Order" i18n-title
- routerLink="/staff/acq/po/{{li.purchase_order().id()}}">
- <span class="material-icons small mr-1">center_focus_weak</span>
- <span i18n>{{li.purchase_order().id()}}</span>
- </a>
- </ng-container>
+ <!-- TODO link to catalog -->
+
+ <span class="ml-1 mr-1" i18n> | </span>
+ <a class="label-with-material-icon"
+ routerLink="lineitem/{{li.id()}}/worksheet/">
+ <span class="material-icons small mr-1">create</span>
+ <span i18n>Worksheet</span>
+ </a>
<ng-container *ngIf="!picklistId && li.picklist() && li.picklist().name()">
<span class="ml-1 mr-1" i18n> | </span>
<a class="label-with-material-icon"
<span i18n>{{li.picklist().name()}}</span>
</a>
</ng-container>
+ <ng-container *ngIf="!poId && li.purchase_order()">
+ <span class="ml-1 mr-1" i18n> | </span>
+ <a class="label-with-material-icon"
+ title="Purchase Order" i18n-title
+ routerLink="/staff/acq/po/{{li.purchase_order().id()}}">
+ <span class="material-icons small mr-1">center_focus_weak</span>
+ <span i18n>{{li.purchase_order().id()}}</span>
+ </a>
+ </ng-container>
+
+ <!-- TODO patron requests -->
+
+ <span class="ml-1 mr-1" i18n> | </span>
+ <a class="label-with-material-icon"
+ [queryParams]="{f: 'jub:id', val1: li.id()}"
+ routerLink="/staff/acq/search/invoices">
+ <span class="material-icons small mr-1">list</span>
+ <span i18n>Invoice(s)</span>
+ </a>
+
+ <!-- TODO: claim policy -->
+
<ng-container *ngIf="li.provider()">
<span class="ml-1 mr-1" i18n> | </span>
<a class="label-with-material-icon"
<span i18n>{{li.provider().name()}}</span>
</a>
</ng-container>
+
+ <!-- TODO import queue -->
+
</div>
</div>
</div>
const DELETABLE_STATES = [
'new', 'selector-ready', 'order-ready', 'approved', 'pending-order'
-]
+];
@Component({
templateUrl: 'lineitem-list.component.html',
} else {
this.pageOfLineitems.push(li);
}
+
+ // Remove any 'new' lineitem details which may have been added
+ // and left unsaved on the copies page
+ li.lineitem_details(li.lineitem_details().filter(d => !d.isnew()));
}
// First matching attr
[key: string]: any; // Perl Acq::BatchManager
}
-interface FleshedLineitemParams {
+export interface FleshCacheParams {
// Flesh data beyond the default.
fleshMore?: any;
) {}
getFleshedLineitems(ids: number[],
- params: FleshedLineitemParams = {}): Observable<BatchLineitemStruct> {
+ params: FleshCacheParams = {}): Observable<BatchLineitemStruct> {
if (params.fromCache) {
const fromCache = this.getLineitemsFromCache(ids);
*ngFor="let charge of po().po_items()">
<div class="flex-2 p-2">
<eg-combobox idlClass="aiit" [selectedId]="charge.inv_item_type()"
+ [asyncSupportsEmptyTermClick]="true"
(onChange)="charge.inv_item_type($event ? $event.id : null)"
i18n-placeholder placeholder="Charge Type..."
[required]="true" [readOnly]="!charge.isnew()"></eg-combobox>
import {NetService} from '@eg/core/net.service';
import {AuthService} from '@eg/core/auth.service';
import {PcrudService} from '@eg/core/pcrud.service';
+import {LineitemService, FleshCacheParams} from '@eg/staff/acq/lineitem/lineitem.service';
@Injectable()
export class PoService {
private auth: AuthService
) {}
- getFleshedPo(id: number, fleshMore?: any, noCache?: boolean): Promise<IdlObject> {
+ getFleshedPo(id: number, params: FleshCacheParams = {}): Promise<IdlObject> {
- if (!noCache) {
+ if (params.fromCache) {
if (this.currentPo && id === this.currentPo.id()) {
// Set poService.currentPo = null to bypass the cache
return Promise.resolve(this.currentPo);
flesh_po_items: true,
flesh_price_summary: true,
flesh_lineitem_count: true
- }, fleshMore || {});
+ }, params.fleshMore || {});
return this.net.request(
'open-ils.acq',
const evt = this.evt.parse(po);
if (evt) { return Promise.reject(evt + ''); }
- if (!noCache) { this.currentPo = po; }
+ if (params.toCache) { this.currentPo = po; }
this.poRetrieved.emit(po);
return po;
this.po = null;
this.poService.getFleshedPo(this.poId, {
- flesh_provider_addresses: true,
- flesh_lineitems: true,
- flesh_lineitem_attrs: true,
- flesh_lineitem_notes: true,
- flesh_lineitem_details: true,
- clear_marc: true,
- flesh_notes: true
- }, true)
+ fleshMore: {
+ flesh_provider_addresses: true,
+ flesh_lineitems: true,
+ flesh_lineitem_attrs: true,
+ flesh_lineitem_notes: true,
+ flesh_lineitem_details: true,
+ clear_marc: true,
+ flesh_notes: true
+ }
+ })
.then(po => this.po = po)
.then(_ => this.populatePreview())
.then(_ => this.initDone = true);
</ng-template>
<ng-template #noCopies>
<ng-container
- *ngIf="evt.textcode == 'ACQ_LINEITEM_NO_COPIES'; else otherBlock">
+ *ngIf="evt.textcode == 'ACQ_LINEITEM_NO_COPIES'; else noOwner">
<span i18n>One or more lineitems have no items attached.</span>
</ng-container>
</ng-template>
+ <ng-template #noOwner>
+ <ng-container
+ *ngIf="evt.textcode == 'ACQ_COPY_NO_OWNING_LIB'; else otherBlock">
+ <span i18n>One or more items have no owning lib.</span>
+ </ng-container>
+ </ng-template>
<ng-template #otherBlock>
<span i18n>{{evt.textcode}} : {{evt.desc}}</span>
</ng-template>
// Re-check for activation blocks if the LI service tells us
// something significant happened.
this.liService.activateStateChange
+ .pipe(tap(_ => this.poService.getFleshedPo(this.poId, {toCache: true})))
.subscribe(_ => this.setCanActivate());
}
load(): Promise<any> {
if (!this.poId) { return Promise.resolve(); }
- return this.poService.getFleshedPo(this.poId)
+ return this.poService.getFleshedPo(this.poId, {fromCache: true, toCache: true})
.then(po => {
// EDI message count
}
]);
+ if (!$lid->owning_lib) {
+ # It's OK to create copies with no owning lib, but activating
+ # an order with such copies creates problems.
+ $mgr->editor->event(OpenILS::Event->new('ACQ_COPY_NO_OWNING_LIB', payload => $li->id));
+ $mgr->editor->rollback;
+ return 0;
+ }
+
create_lineitem_detail_debit($mgr, $li, $lid, $dry_run) or return 0;
}