[ngModelOptions]="{standalone: true}" [(ngModel)]="runImmediately"/>
<label for="retrieve-immediately" class="form-check-label" i18n>Retrieve Results Immediately</label>
</div>
+ <div class="col-xs-3 pl-2" *ngIf="showExpAngOptions()">
+ <div class="form-check form-check-inline">
+ <input class="form-check-input" type="checkbox"
+ name="show-exp-ang-links" id="show-exp-ang-links"
+ (change)="toggleExpSearchLinks()" [ngModel]="showExpAngLinks()"/>
+ <label class="form-check-label" for="show-exp-ang-links" i18n>
+ Activate Experimental Links
+ </label>
+ </div>
+ </div>
</div>
</form>
</div>
import {PcrudService} from '@eg/core/pcrud.service';
import {StringComponent} from '@eg/share/string/string.component';
import {ToastService} from '@eg/share/toast/toast.service';
-import {AcqSearchTerm, AcqSearch} from './acq-search.service';
+import {AcqSearchService, AcqSearchTerm, AcqSearch} from './acq-search.service';
import {ServerStoreService} from '@eg/core/server-store.service';
@Component({
private store: ServerStoreService,
private idl: IdlService,
private toast: ToastService,
+ private acqSearch: AcqSearchService
) {}
ngOnInit() {
saveRunImmediately() {
return this.store.setItem(this.runImmediatelySetting, this.runImmediately);
}
+
+ showExpAngOptions(): boolean {
+ return this.acqSearch.angSelectionEnabled;
+ }
+
+ showExpAngLinks(): boolean {
+ return this.acqSearch.angSearchLinksEnabled;
+ }
+
+ toggleExpSearchLinks() {
+ this.acqSearch.angSearchLinksEnabled = !this.acqSearch.angSearchLinksEnabled;
+ this.store.setItem('ui.staff.angular_acq_search.enabled',
+ this.acqSearch.angSearchLinksEnabled);
+ }
}
import {PicklistCloneDialogComponent} from './picklist-clone-dialog.component';
import {PicklistDeleteDialogComponent} from './picklist-delete-dialog.component';
import {PicklistMergeDialogComponent} from './picklist-merge-dialog.component';
+import {AcqSearchService} from './acq-search.service';
@NgModule({
declarations: [
imports: [
StaffCommonModule,
AcqSearchRoutingModule
- ]
+ ],
+ providers: [AcqSearchService]
})
export class AcqSearchModule {
import {IdlObject} from '@eg/core/idl.service';
import {EventService} from '@eg/core/event.service';
import {AttrDefsService} from './attr-defs.service';
+import {ServerStoreService} from '@eg/core/server-store.service';
const baseIdlClass = {
lineitem: 'jub',
_conjunction = 'all';
firstRun = true;
+ angSelectionEnabled = false;
+ angSearchLinksEnabled = false;
+
constructor(
private net: NetService,
private evt: EventService,
private auth: AuthService,
private pcrud: PcrudService,
+ private serverStore: ServerStoreService,
private attrDefs: AttrDefsService
) {
this.firstRun = true;
};
return gridSource;
}
+
+ loadUiPrefs(): Promise<any> {
+ return this.serverStore.getItemBatch([
+ 'ui.staff.angular_acq_selection.enabled',
+ 'ui.staff.angular_acq_search.enabled'
+ ]).then(sets => {
+ this.angSelectionEnabled = sets['ui.staff.angular_acq_selection.enabled'];
+ this.angSearchLinksEnabled =
+ sets['ui.staff.angular_acq_search.enabled'] && this.angSelectionEnabled;
+ });
+ }
}
@Component({
selector: 'eg-invoice-results',
- templateUrl: 'invoice-results.component.html',
- providers: [AcqSearchService]
+ templateUrl: 'invoice-results.component.html'
})
export class InvoiceResultsComponent implements OnInit {
defaultSearchSetting="eg.acq.search.default.lineitems"></eg-acq-search-form>
<ng-template #idTmpl let-lineitem="row">
- <a *ngIf="lineitem.purchase_order()"
- routerLink="/staff/acq/po/{{lineitem.purchase_order().id()}}"
- fragment="{{lineitem.id()}}" target="_blank">
- {{lineitem.id()}}
- </a>
- <a *ngIf="lineitem.picklist() && !lineitem.purchase_order()"
- routerLink="/staff/acq/picklist/{{lineitem.picklist().id()}}"
- fragment="{{lineitem.id()}}" target="_blank">
- {{lineitem.id()}}
- </a>
+
+ <ng-container *ngIf="showExpAngLinks(); else legacyId">
+ <a *ngIf="lineitem.purchase_order()"
+ routerLink="/staff/acq/po/{{lineitem.purchase_order().id()}}"
+ fragment="{{lineitem.id()}}" target="_blank">
+ {{lineitem.id()}}
+ </a>
+ <a *ngIf="lineitem.picklist() && !lineitem.purchase_order()"
+ routerLink="/staff/acq/picklist/{{lineitem.picklist().id()}}"
+ fragment="{{lineitem.id()}}" target="_blank">
+ {{lineitem.id()}}
+ </a>
+ </ng-container>
+
+ <ng-template #legacyId>
+ <a *ngIf="lineitem.purchase_order()"
+ href="/eg/staff/acq/legacy/po/view/{{lineitem.purchase_order().id()}}?focus_li={{lineitem.id()}}"
+ target="_blank">
+ {{lineitem.id()}}
+ </a>
+ <a *ngIf="lineitem.picklist() && !lineitem.purchase_order()"
+ href="/eg/staff/acq/legacy/picklist/view/{{lineitem.picklist().id()}}?focus_li={{lineitem.id()}}"
+ target="_blank">
+ {{lineitem.id()}}
+ </a>
+ </ng-template>
</ng-template>
<ng-template #poTmpl let-lineitem="row">
- <a *ngIf="lineitem.purchase_order()"
- routerLink="/staff/acq/po/{{lineitem.purchase_order().id()}}"
- fragment="{{lineitem.id()}}" target="_blank">
- {{lineitem.purchase_order().name()}}
- </a>
+ <ng-container *ngIf="showExpAngLinks(); else legacyPo">
+ <a *ngIf="lineitem.purchase_order()"
+ routerLink="/staff/acq/po/{{lineitem.purchase_order().id()}}"
+ fragment="{{lineitem.id()}}" target="_blank">
+ {{lineitem.purchase_order().name()}}
+ </a>
+ </ng-container>
+ <ng-template #legacyPo>
+ <a *ngIf="lineitem.purchase_order()"
+ href="/eg/staff/acq/legacy/po/view/{{lineitem.purchase_order().id()}}?focus_li={{lineitem.id()}}"
+ target="_blank">
+ {{lineitem.purchase_order().name()}}
+ </a>
+ </ng-template>
</ng-template>
<ng-template #plTmpl let-lineitem="row">
- <a *ngIf="lineitem.picklist()"
- routerLink="/staff/acq/picklist/{{lineitem.picklist().id()}}"
- fragment="{{lineitem.id()}}" target="_blank">
- {{lineitem.picklist().name()}}
- </a>
+ <ng-container *ngIf="showExpAngLinks(); else legacyPl">
+ <a *ngIf="lineitem.picklist()"
+ routerLink="/staff/acq/picklist/{{lineitem.picklist().id()}}"
+ fragment="{{lineitem.id()}}" target="_blank">
+ {{lineitem.picklist().name()}}
+ </a>
+ </ng-container>
+
+ <ng-template #legacyPl>
+ <a *ngIf="lineitem.picklist()"
+ href="/eg/staff/acq/legacy/picklist/view/{{lineitem.picklist().id()}}?focus_li={{lineitem.id()}}"
+ target="_blank">
+ {{lineitem.picklist().name()}}
+ </a>
+ </ng-template>
</ng-template>
<ng-template #liAttrTmpl let-lineitem="row" let-col="col">
<li *ngIf="lineitem.eg_bib_id()">
<a routerLink="/staff/catalog/record/{{lineitem.eg_bib_id()}}"
target="_blank" i18n>Catalog</a></li>
- <li><a routerLink="/staff/acq/lineitem/{{lineitem.id()}}/worksheet"
- target="_blank" i18n>Worksheet</a></li>
+ <li>
+ <ng-container *ngIf="showExpAngLinks(); else legacyWs">
+ <a routerLink="/staff/acq/lineitem/{{lineitem.id()}}/worksheet"
+ target="_blank" i18n>Worksheet</a>
+ </ng-container>
+ <ng-template #legacyWs>
+ <a href="/eg/staff/acq/legacy/lineitem/worksheet/{{lineitem.id()}}"
+ target="_blank" i18n>Worksheet</a>
+ </ng-template>
+ </li>
+
<li *ngIf="lineitem.purchase_order()">
- <a routerLink="/staff/acq/po/{{lineitem.purchase_order().id()}}"
- target="_blank" i18n>Purchase Order</a></li>
+ <ng-container *ngIf="showExpAngLinks(); else legacyPo2">
+ <a routerLink="/staff/acq/po/{{lineitem.purchase_order().id()}}"
+ target="_blank" i18n>Purchase Order</a>
+ </ng-container>
+ <ng-template #legacyPo2>
+ <a href="/eg/staff/acq/legacy/po/view/{{lineitem.purchase_order().id()}}"
+ target="_blank" i18n>Purchase Order</a>
+ </ng-template>
+ </li>
<li><a href="/eg/staff/acq/requests/lineitem/{{lineitem.id()}}"
target="_blank" i18n>Requests</a></li>
<li>
<a routerLink="/staff/cat/vandelay/queue/bib/{{lineitem.queued_record().queue()}}"
target="_blank" i18n>Queue</a></li>
<li *ngIf="lineitem.picklist()">
- <a routerLink="/staff/acq/picklist/{{lineitem.picklist().id()}}"
- target="_blank" i18n>Selection List</a></li>
+ <ng-container *ngIf="showExpAngLinks(); else legacyPl2">
+ <a routerLink="/staff/acq/picklist/{{lineitem.picklist().id()}}"
+ target="_blank" i18n>Selection List</a>
+ </ng-container>
+ <ng-template #legacyPl2>
+ <a href="/eg/staff/acq/legacy/picklist/view/{{lineitem.picklist().id()}}"
+ target="_blank" i18n>Selection List</a>
+ </ng-template>
+ </li>
</ul>
</ng-template>
@Component({
selector: 'eg-lineitem-results',
- templateUrl: 'lineitem-results.component.html',
- providers: [AcqSearchService]
+ templateUrl: 'lineitem-results.component.html'
})
export class LineitemResultsComponent implements OnInit {
showRow(row: any) {
window.open('/eg/staff/acq/legacy/lineitem/worksheet/' + row.id(), '_blank');
}
+
+ showExpAngLinks(): boolean {
+ return this.acqSearch.angSearchLinksEnabled;
+ }
}
</eg-string>
<ng-template #nameTmpl let-selectionlist="row">
- <a routerLink="/staff/acq/picklist/{{selectionlist.id()}}" target="_blank">
- {{selectionlist.name()}}
- </a>
+ <ng-container *ngIf="showExpAngLinks(); else legacyLinks">
+ <a routerLink="/staff/acq/picklist/{{selectionlist.id()}}" target="_blank">
+ {{selectionlist.name()}}
+ </a>
+ </ng-container>
+ <ng-template #legacyLinks>
+ <a href="/eg/staff/acq/legacy/picklist/view/{{selectionlist.id()}}"
+ target="_blank">
+ {{selectionlist.name()}}
+ </a>
+ </ng-template>
</ng-template>
<eg-picklist-create-dialog #picklistCreateDialog>
@Component({
selector: 'eg-picklist-results',
- templateUrl: 'picklist-results.component.html',
- providers: [AcqSearchService]
+ templateUrl: 'picklist-results.component.html'
})
export class PicklistResultsComponent implements OnInit {
};
}
+ showExpAngOptions(): boolean {
+ return this.acqSearch.angSelectionEnabled;
+ }
+
+ showExpAngLinks(): boolean {
+ return this.acqSearch.angSearchLinksEnabled;
+ }
+
openCreateDialog() {
this.picklistCreateDialog.open().subscribe(
modified => {
defaultSearchSetting="eg.acq.search.default.purchaseorders"></eg-acq-search-form>
<ng-template #nameTmpl let-purchaseorder="row">
- <a href="/eg/staff/acq/legacy/po/view/{{purchaseorder.id()}}"
- target="_blank">
- {{purchaseorder.name()}}
- </a>
+ <ng-container *ngIf="showExpAngLinks(); else legacyPo">
+ <a routerLink="/staff/acq/po/{{purchaseorder.id()}}" target="_blank">
+ {{purchaseorder.name()}}
+ </a>
+ </ng-container>
+ <ng-template #legacyPo>
+ <a href="/eg/staff/acq/legacy/po/view/{{purchaseorder.id()}}"
+ target="_blank">
+ {{purchaseorder.name()}}
+ </a>
+ </ng-template>
</ng-template>
<ng-template #providerTmpl let-purchaseorder="row">
@Component({
selector: 'eg-purchase-order-results',
templateUrl: 'purchase-order-results.component.html',
- providers: [AcqSearchService]
})
export class PurchaseOrderResultsComponent implements OnInit {
this.purchaseOrderResultsGrid.reload();
});
}
+
+ showExpAngLinks(): boolean {
+ return this.acqSearch.angSearchLinksEnabled;
+ }
+
}
import {Router, Resolve, RouterStateSnapshot,
ActivatedRouteSnapshot} from '@angular/router';
import {AttrDefsService} from './attr-defs.service';
+import {AcqSearchService} from './acq-search.service';
@Injectable()
export class AttrDefsResolver implements Resolve<Promise<any[]>> {
constructor(
private router: Router,
private attrDefs: AttrDefsService,
+ private acqSearch: AcqSearchService
) {}
resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Promise<any[]> {
- return Promise.all([
- this.attrDefs.fetchAttrDefs()
- ]);
+ return this.attrDefs.fetchAttrDefs()
+ .then(_ => this.acqSearch.loadUiPrefs());
}
}
</div>
</div>
+ <div class="navbar-nav" *ngIf="showAngularAcq">
+ <div ngbDropdown class="nav-item dropdown">
+ <a ngbDropdownToggle i18n class="nav-link dropdown-toggle">
+ Acquisitions (Experimental)
+ </a>
+ <div class="dropdown-menu" ngbDropdownMenu>
+ <a class="dropdown-item"
+ routerLink="/staff/acq/po/create">
+ <span class="material-icons" aria-hidden="true">add_shopping_cart</span>
+ <span i18n>Create Purchase Order</span>
+ </a>
+ </div>
+ </div>
+ </div>
+
<div class="navbar-nav">
<div ngbDropdown class="nav-item dropdown">
<a ngbDropdownToggle i18n class="nav-link dropdown-toggle">
// When active, show a link to the traditional staff catalog
showTraditionalCatalog = true;
+ showAngularAcq: boolean;
curbsideEnabled: boolean;
@ViewChild('navOpChange', {static: false}) opChange: OpChangeComponent;
// Avoid attempts to fetch org settings if the user has not yet
// logged in (e.g. this is the login page).
if (this.user()) {
+ // Note these are all pre-cached by our resolver.
+ // Batching not required.
this.org.settings('ui.staff.traditional_catalog.enabled')
.then(settings => this.showTraditionalCatalog =
Boolean(settings['ui.staff.traditional_catalog.enabled']));
+
+ this.org.settings('ui.staff.angular_acq_selection.enabled')
+ .then(settings => this.showAngularAcq =
+ Boolean(settings['ui.staff.angular_acq_selection.enabled']));
+
this.org.settings('circ.curbside')
.then(settings => this.curbsideEnabled =
Boolean(settings['circ.curbside']));
'webstaff.format.dates',
'webstaff.format.date_and_time',
'ui.staff.max_recent_patrons',
+ 'circ.curbside', // navbar
+ 'ui.staff.angular_acq_selection.enabled', // navbar
'ui.staff.angular_catalog.enabled' // navbar
]).then(settings => {
// Avoid clobbering defaults
INSERT INTO config.workstation_setting_type (name, grp, datatype, label)
VALUES (
+ 'eg.grid.acq.lineitem.history', 'gui', 'object',
+ oils_i18n_gettext(
+ 'eg.grid.acq.lineitem.history',
+ 'Grid Config: Acq Lineitem History',
+ 'cwst', 'label'
+ )
+), (
+ 'eg.grid.acq.po.history', 'gui', 'object',
+ oils_i18n_gettext(
+ 'eg.grid.acq.po.history',
+ 'Grid Config: Acq PO History',
+ 'cwst', 'label'
+ )
+), (
+ 'eg.grid.acq.po.edi_messages', 'gui', 'object',
+ oils_i18n_gettext(
+ 'eg.grid.acq.po.edi_messages',
+ 'Grid Config: Acq PO EDI Messages',
+ 'cwst', 'label'
+ )
+), (
+ 'acq.lineitem.page_size', 'gui', 'integer',
+ oils_i18n_gettext(
+ 'acq.lineitem.page_size',
+ 'ACQ Lineitem List Page Size',
+ 'cwst', 'label'
+ )
+), (
+ 'ui.staff.angular_acq_search.enabled', 'gui', 'bool',
+ oils_i18n_gettext(
+ 'ui.staff.angular_acq_search.enabled',
+ 'Enable Experimental ACQ Selection/Purchase Search Interface Links',
+ 'cwst', 'label'
+ )
+);
+
+INSERT INTO config.workstation_setting_type (name, grp, datatype, label)
+VALUES (
'eg.cat.volcopy.defaults', 'cat', 'object',
oils_i18n_gettext(
'eg.cat.volcopy.defaults',
)
);
+INSERT INTO config.org_unit_setting_type (name, grp, datatype, label)
+VALUES (
+ 'ui.staff.angular_acq_selection.enabled', 'gui', 'bool',
+ oils_i18n_gettext(
+ 'ui.staff.angular_acq_selection.enabled',
+ 'Enable Experimental ACQ Selection/Purchase Interfaces',
+ 'cwst', 'label'
+ )
+);
+
INSERT into config.org_unit_setting_type
(name, grp, label, description, datatype)
VALUES (
)
);
+INSERT INTO config.print_template
+ (id, name, label, owner, active, locale, template)
+VALUES (
+ 4, 'lineitem_worksheet', 'Lineitem Worksheet', 1, TRUE, 'en-US',
+$TEMPLATE$
+[%-
+ USE money=format('%.2f');
+ SET li = template_data.lineitem;
+ SET title = '';
+ SET author = '';
+ FOREACH attr IN li.attributes;
+ IF attr.attr_type == 'lineitem_marc_attr_definition';
+ IF attr.attr_name == 'title';
+ title = attr.attr_value;
+ ELSIF attr.attr_name == 'author';
+ author = attr.attr_value;
+ END;
+ END;
+ END;
+-%]
+
+<div>Title: [% title.substr(0, 80) %][% IF title.length > 80 %]...[% END %]</div>
+<div>Author: [% author %]</div>
+<div>Item Count: [% li.lineitem_details.size %]</div>
+<div>Lineitem ID: [% li.id %]</div>
+<div>PO # : [% li.purchase_order%]</div>
+<div>Est. Price: [% money(li.estimated_unit_price) %]</div>
+
+$TEMPLATE$
+);
+
+INSERT INTO config.print_template
+ (id, name, label, owner, active, locale, template)
+VALUES (5, 'purchase_order', 'Purchase Order', 1, TRUE, 'en-US',
+$TEMPLATE$
+
+[%-
+ USE date;
+ USE String;
+ USE money=format('%.2f');
+ SET po = template_data.po;
+
+ # find a lineitem attribute by name and optional type
+ BLOCK get_li_attr;
+ FOR attr IN li.attributes;
+ IF attr.attr_name == attr_name;
+ IF !attr_type OR attr_type == attr.attr_type;
+ attr.attr_value;
+ LAST;
+ END;
+ END;
+ END;
+ END;
+
+ BLOCK get_li_order_attr_value;
+ FOR attr IN li.attributes;
+ IF attr.order_ident == 't';
+ attr.attr_value;
+ LAST;
+ END;
+ END;
+ END;
+-%]
+
+<table style="width:100%">
+ <thead>
+ <tr>
+ <th>PO#</th>
+ <th>Line#</th>
+ <th>ISBN / Item # / Charge Type</th>
+ <th>Title</th>
+ <th>Author</th>
+ <th>Pub Info</th>
+ <th>Quantity</th>
+ <th>Unit Price</th>
+ <th>Line Total</th>
+ </tr>
+ </thead>
+ <tbody>
+[%
+ SET subtotal = 0;
+ FOR li IN po.lineitems;
+
+ SET idval = '';
+ IF vendnum != '';
+ idval = PROCESS get_li_attr attr_name = 'vendor_num';
+ END;
+ IF !idval;
+ idval = PROCESS get_li_order_attr_value;
+ END;
+-%]
+ <tr>
+ <td>[% po.id %]</td>
+ <td>[% li.id %]</td>
+ <td>[% idval %]</td>
+ <td>[% PROCESS get_li_attr attr_name = 'title' %]</td>
+ <td>[% PROCESS get_li_attr attr_name = 'author' %]</td>
+ <td>
+ <div>
+ [% PROCESS get_li_attr attr_name = 'publisher' %],
+ [% PROCESS get_li_attr attr_name = 'pubdate' %]
+ </div>
+ <div>Edition: [% PROCESS get_li_attr attr_name = 'edition' %]</div>
+ </td>
+ [%-
+ SET count = li.lineitem_details.size;
+ SET price = li.estimated_unit_price;
+ SET itotal = (price * count);
+ %]
+ <td>[% count %]</td>
+ <td>[% money(price) %]</td>
+ <td>[% money(litotal) %]</td>
+ </tr>
+ [% END %]
+
+ </tbody>
+</table>
+
+$TEMPLATE$
+);
'ACQ Lineitem List Page Size',
'cwst', 'label'
)
+), (
+ 'ui.staff.angular_acq_search.enabled', 'gui', 'bool',
+ oils_i18n_gettext(
+ 'ui.staff.angular_acq_search.enabled',
+ 'Enable Experimental ACQ Selection/Purchase Search Interface Links',
+ 'cwst', 'label'
+ )
);
+INSERT INTO config.org_unit_setting_type (name, grp, datatype, label)
+VALUES (
+ 'ui.staff.angular_acq_selection.enabled', 'gui', 'bool',
+ oils_i18n_gettext(
+ 'ui.staff.angular_acq_selection.enabled',
+ 'Enable Experimental ACQ Selection/Purchase Interfaces',
+ 'cwst', 'label'
+ )
+);
+
+
INSERT INTO config.print_template
(id, name, label, owner, active, locale, template)
VALUES (
</ul>
</li>
+ <!-- acquisitions experimental -->
+ <li class="dropdown" uib-dropdown>
+ <a href uib-dropdown-toggle>[% l('Acquisitions (Experimental)') %]<b class="caret"
+ aria-hidden="true"></b>
+ </a>
+ <ul uib-dropdown-menu>
+ <li>
+ <a href="/eg2/staff/acq/po/create">
+ <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
+ [% l('Create Purchase Order') %]
+ </a>
+ </li>
+ </ul>
+ </li>
+
+
<!-- booking -->
<li class="dropdown" uib-dropdown>
<a href uib-dropdown-toggle>[% l('Booking') %]<b class="caret"
egCore.org.settings([
'ui.staff.max_recent_patrons',
'ui.staff.traditional_catalog.enabled',
+ 'ui.staff.angular_acq_selection.enabled',
'circ.curbside'
]).then(function(s) {
var val = s['ui.staff.max_recent_patrons'];
val = s['ui.staff.traditional_catalog.enabled'];
$scope.showTraditionalCatalog = (val !== false);
+ $scope.showAngularAcq =
+ s['ui.staff.angular_acq_selection.enabled'];
$scope.enableCurbside =
s['circ.curbside'];
}).then(function() {