<eg-acq-add-copies-dialog #addCopiesDialog></eg-acq-add-copies-dialog>
<eg-acq-link-invoice-dialog #linkInvoiceDialog></eg-acq-link-invoice-dialog>
<eg-acq-claim-policy-dialog #claimPolicyDialog></eg-acq-claim-policy-dialog>
+<eg-acq-manage-claims-dialog #manageClaimsDialog></eg-acq-manage-claims-dialog>
<eg-acq-export-attributes-dialog #exportAttributesDialog></eg-acq-export-attributes-dialog>
<eg-lineitem-alert-dialog #confirmAlertsDialog></eg-lineitem-alert-dialog>
(click)="editHoldings(li)" i18n>Update Barcodes</button>
<button ngbDropdownItem [disabled]="!liHasRealCopies(li)"
(click)="jumpToHoldings(li)" i18n>Open Holdings View</button>
+ <button ngbDropdownItem [disabled]="!liHasRealCopies(li)"
+ (click)="manageClaims(li)" i18n>Claims ({{countClaims(li)}} existing)</button>
<a ngbDropdownItem routerLink="lineitem/{{li.id()}}/history"
queryParamsHandling="merge" i18n>View History</a>
</div>
import {LinkInvoiceDialogComponent} from './link-invoice-dialog.component';
import {ExportAttributesDialogComponent} from './export-attributes-dialog.component';
import {ClaimPolicyDialogComponent} from './claim-policy-dialog.component';
+import {ManageClaimsDialogComponent} from './manage-claims-dialog.component';
import {LineitemAlertDialogComponent} from './lineitem-alert-dialog.component';
const DELETABLE_STATES = [
@ViewChild('linkInvoiceDialog') linkInvoiceDialog: LinkInvoiceDialogComponent;
@ViewChild('exportAttributesDialog') exportAttributesDialog: ExportAttributesDialogComponent;
@ViewChild('claimPolicyDialog') claimPolicyDialog: ClaimPolicyDialogComponent;
+ @ViewChild('manageClaimsDialog') manageClaimsDialog: ManageClaimsDialogComponent;
@ViewChild('lineItemsUpdatedString', { static: false }) lineItemsUpdatedString: StringComponent;
@ViewChild('noActionableLIs', { static: true }) private noActionableLIs: AlertDialogComponent;
@ViewChild('selectorReadyConfirmDialog', { static: true }) selectorReadyConfirmDialog: ConfirmDialogComponent;
window.open('/eg2/staff/catalog/record/' + li.eg_bib_id() + '/holdings', '_blank');
}
+ manageClaims(li: IdlObject) {
+ this.manageClaimsDialog.li = li;
+ this.manageClaimsDialog.open().subscribe(result => {
+ if (result) {
+ delete this.liService.liCache[li.id()];
+ this.loadPageOfLis();
+ }
+ });
+ }
+
+ countClaims(li: IdlObject): number {
+ let total = 0;
+ li.lineitem_details().forEach(lid => total += lid.claims().length);
+ return total;
+ }
+
receiveSelected() {
this.markReceived(this.selectedIds());
}
import {LinkInvoiceDialogComponent} from './link-invoice-dialog.component';
import {ExportAttributesDialogComponent} from './export-attributes-dialog.component';
import {ClaimPolicyDialogComponent} from './claim-policy-dialog.component';
+import {ManageClaimsDialogComponent} from './manage-claims-dialog.component';
import {LineitemAlertDialogComponent} from './lineitem-alert-dialog.component';
import {MarcEditModule} from '@eg/staff/share/marc-edit/marc-edit.module';
import {AcqCommonModule} from '../acq-common.module';
LinkInvoiceDialogComponent,
ExportAttributesDialogComponent,
ClaimPolicyDialogComponent,
+ ManageClaimsDialogComponent,
LineitemAlertDialogComponent,
BriefRecordComponent,
CreateAssetsComponent,
LinkInvoiceDialogComponent,
ExportAttributesDialogComponent,
ClaimPolicyDialogComponent,
+ ManageClaimsDialogComponent,
LineitemAlertDialogComponent
],
imports: [
--- /dev/null
+<ng-template #dialogContent>
+ <form class="form-validated">
+ <div class="modal-header bg-info">
+ <h3 class="modal-title" i18n>Manage Claims</h3>
+ <button type="button" class="close"
+ i18n-aria-label aria-label="Close" (click)="close()">
+ <span aria-hidden="true">×</span>
+ </button>
+ </div>
+ <div class="modal-body">
+ <h4 i18n>Claims</h4>
+ <span i18n>Against line item {{liService.getFirstAttributeValue(li, 'title')}} ({{li.id()}})</span>
+ <ul>
+ <li *ngFor="let lid of lidsWithClaims" i18n>
+ {{lid.barcode()}} /
+ <ng-container *ngIf="lid.cancel_reason()">Cancelled ({{lid.cancel_reason().label()}})</ng-container>
+ <ng-container *ngIf="lid.recv_time() && !lid.cancel_reason()">Received {{lid.recv_time() | formatValue:'timestamp'}}</ng-container>
+ <ng-container *ngIf="!lid.recv_time() && !lid.cancel_reason()">Not received</ng-container>
+ <ul>
+ <li *ngFor="let claim of lid.claims()">
+ {{claim.type().code()}} <a href="javascript:;" (click)="printVoucher(lid.id())">Print Voucher</a>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ <hr>
+ <h4 i18n>Initiate New Claims</h4>
+ <div *ngFor="let lid of li.lineitem_details()" i18n>
+ <input type="checkbox" name="lidsToClaim" [(ngModel)]="lid._selected_for_claim">
+ {{lid.barcode()}} /
+ <ng-container *ngIf="lid.cancel_reason()">Cancelled ({{lid.cancel_reason().label()}})</ng-container>
+ <ng-container *ngIf="lid.recv_time() && !lid.cancel_reason()">Received {{lid.recv_time() | formatValue:'timestamp'}}</ng-container>
+ <ng-container *ngIf="!lid.recv_time() && !lid.cancel_reason()">Not received</ng-container>
+ </div>
+ <ng-container *ngIf="claimEventTypes.length > 0">
+ <label for="selectClaimEventTypes" i18n>Select Claim Action(s)</label>
+ <select class="form-control" multiple="true" [size]="claimEventTypes.length"
+ [(ngModel)]="selectedClaimEventTypes" [ngModelOptions]="{standalone: true}" id="selectClaimEventTypes">
+ <option *ngFor="let clet of claimEventTypes" [value]="clet.id()" i18n>
+ {{clet.code()}} ({{clet.org_unit().shortname()}}) <i>{{clet.description()}}</i>
+ <ng-container *ngIf="clet.library_initiated()"> [Library initiated]</ng-container>
+ </option>
+ </select>
+ </ng-container>
+ <label for="claimType" i18n>Claim Type</label>
+ <eg-combobox domId="claimType" name="claimType"
+ [asyncSupportsEmptyTermClick]="true"
+ idlClass="acqclt" [(ngModel)]="claimType" [ngModelOptions]="{standalone: true}"></eg-combobox>
+ <label for="note" i18n>Claim Note</label>
+ <input class="form-control" type="text" i18n-placeholder placeholder="Note" [(ngModel)]="note"
+ [ngModelOptions]="{standalone: true}" id="note">
+ </div>
+
+ <div class="modal-footer">
+ <button type="button" class="btn btn-success"
+ [disabled]="!canPerformClaim()"
+ (click)="claimItems()" i18n>Claim Selected</button>
+ <button type="button" class="btn btn-warning"
+ (click)="close()" i18n>Exit Dialog</button>
+ </div>
+ </form>
+</ng-template>
+
+<ng-template #printTemplate let-context>
+ <div>
+ <h1>Claim Voucher</h1>
+ <hr>
+ <span [innerHtml]="context.voucher"></span>
+ </div>
+</ng-template>
--- /dev/null
+import {Component, Input, ViewChild, TemplateRef} from '@angular/core';
+import {Observable} from 'rxjs';
+import {NgbModal, NgbModalOptions} from '@ng-bootstrap/ng-bootstrap';
+import {DialogComponent} from '@eg/share/dialog/dialog.component';
+import {IdlService, IdlObject} from '@eg/core/idl.service';
+import {NetService} from '@eg/core/net.service';
+import {PcrudService} from '@eg/core/pcrud.service';
+import {AuthService} from '@eg/core/auth.service';
+import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
+import {LineitemService} from '../lineitem/lineitem.service';
+import {PrintService} from '@eg/share/print/print.service';
+
+@Component({
+ selector: 'eg-acq-manage-claims-dialog',
+ templateUrl: './manage-claims-dialog.component.html'
+})
+
+export class ManageClaimsDialogComponent extends DialogComponent {
+ @Input() li: IdlObject;
+
+ @ViewChild('printTemplate', { static: true }) private printTemplate: TemplateRef<any>;
+
+ lidsWithClaims: IdlObject[] = [];
+
+ note = '';
+ claimEventTypes: number[] = [];
+ selectedClaimEventTypes: number[] = [];
+ claimType: ComboboxEntry;
+
+ constructor(
+ private modal: NgbModal,
+ private net: NetService,
+ private auth: AuthService,
+ private pcrud: PcrudService,
+ private printer: PrintService,
+ private liService: LineitemService
+ ) { super(modal); }
+
+ open(args?: NgbModalOptions): Observable<any> {
+ if (!args) {
+ args = {};
+ }
+
+ this.lidsWithClaims = this.getLidsWithClaims();
+ this.note = '';
+ this.claimEventTypes = [];
+ this.selectedClaimEventTypes = [];
+ this.getClaimEventTypes();
+
+ return super.open(args);
+ }
+
+ getLidsWithClaims(): IdlObject[] {
+ return this.li.lineitem_details().filter(x => x.claims().length > 0);
+ }
+
+ getClaimEventTypes() {
+ this.pcrud.retrieveAll('acqclet',
+ { 'order_by': {'acqclet': 'code'}, flesh: 1, flesh_fields: {acqclet: ['org_unit']} },
+ {}
+ ).subscribe(t => this.claimEventTypes.push(t));
+ }
+
+ canPerformClaim(): boolean {
+ if (!this.claimType) { return false; }
+ if (!this.claimType.id) { return false; }
+ const lidsToClaim = this.li.lineitem_details().filter(x => x._selected_for_claim);
+ if (lidsToClaim.length < 1) { return false; }
+ return true;
+ }
+
+ claimItems() {
+ if (!this.canPerformClaim()) { return; }
+ const lidsToClaim = this.li.lineitem_details()
+ .filter(x => x._selected_for_claim)
+ .map(x => x.id());
+ this.net.request(
+ 'open-ils.acq',
+ 'open-ils.acq.claim.lineitem_detail.atomic',
+ this.auth.token(),
+ lidsToClaim, null,
+ this.claimType.id,
+ this.note,
+ null,
+ this.selectedClaimEventTypes
+ ).subscribe(result => {
+ if (result && result.length) {
+ const voucher = result.map(x => x.template_output().data()).join('<hr>');
+ this.printer.print({
+ template: this.printTemplate,
+ contextData: { voucher: voucher },
+ printContext: 'default'
+ });
+ }
+ this.close(true);
+ });
+ }
+
+ printVoucher(lidId: number) {
+ this.net.request(
+ 'open-ils.acq',
+ 'open-ils.acq.claim.voucher.by_lineitem_detail',
+ this.auth.token(), lidId
+ ).subscribe(result => {
+ if (!result) { return; }
+ this.printer.print({
+ template: this.printTemplate,
+ contextData: { voucher: result.template_output().data() },
+ printContext: 'default'
+ });
+ });
+ }
+}