<div class="row">
<div class="ml-auto mr-3"><a i18n href="/eg/staff/acq/legacy/search/unified">Legacy Search Interface</a></div>
</div>
-<div class="row">
+<div class="row" *ngFor="let t of searchTerms">
<div class="col-lg-3">
- <select class="form-control" id="selected-search-term" [ngModelOptions]="{standalone: true}" [(ngModel)]="selectedSearchTerm">
+ <select class="form-control" id="selected-search-term" [ngModelOptions]="{standalone: true}" [(ngModel)]="t.field">
<option disabled="disabled" i18n>Select Search Field</option>
- <optgroup *ngFor="let g of hints" label="{{availableSearchTerms[g]['__label']}}">
- <option *ngFor="let o of availableSearchTerms[g]['__fields']" value="{{g}}:{{o}}">
- {{availableSearchTerms[g][o].label}}
+ <optgroup *ngFor="let g of hints" label="{{availableSearchFields[g]['__label']}}">
+ <option *ngFor="let o of availableSearchFields[g]['__fields']" value="{{g}}:{{o}}">
+ {{availableSearchFields[g][o].label}}
</option>
</optgroup>
</select>
</div>
- <div class="col-lg-3">
- <select class="form-control" id="selected-search-op" [ngModelOptions]="{standalone: true}" [(ngModel)]="selectedSearchOp">
+ <div class="col-lg-2">
+ <select class="form-control" id="selected-search-op" [ngModelOptions]="{standalone: true}" [(ngModel)]="t.op">
<option i18n value="">is</option>
<option i18n value="__not">is NOT</option>
- <option i18n value="__fuzzy" [disabled]="searchTermDatatypes[selectedSearchTerm] != 'text'">contains</option>
- <option i18n value="__not,__fuzzy" [disabled]="searchTermDatatypes[selectedSearchTerm] != 'text'">does NOT contain</option>
- <option i18n value="__lte" [disabled]="searchTermDatatypes[selectedSearchTerm] != 'timestamp'">is on or BEFORE</option>
- <option i18n value="__gte" [disabled]="searchTermDatatypes[selectedSearchTerm] != 'timestamp'">is on or AFTER</option>
+ <option i18n value="__fuzzy" [disabled]="searchTermDatatypes[t.field] != 'text'">contains</option>
+ <option i18n value="__not,__fuzzy" [disabled]="searchTermDatatypes[t.field] != 'text'">does NOT contain</option>
+ <option i18n value="__lte" [disabled]="searchTermDatatypes[t.field] != 'timestamp'">is on or BEFORE</option>
+ <option i18n value="__gte" [disabled]="searchTermDatatypes[t.field] != 'timestamp'">is on or AFTER</option>
<option i18n value="__in">matches a term from a file</option>
</select>
</div>
<div class="col-lg-3">
+ <input [(ngModel)]="t.value1" type="text" *ngIf="searchTermDatatypes[t.field] == 'text'" class="form-control" />
+ <input [(ngModel)]="t.value1" type="numeric" *ngIf="searchTermDatatypes[t.field] == 'money'" class="form-control" />
+ <eg-org-select *ngIf="searchTermDatatypes[t.field] == 'org_unit'"
+ (onChange)="setOrgUnitSearchValue($event, t)">
+ </eg-org-select>
</div>
</div>
<div class="row">
<div class="col-lg-2">
- <button class="form-control" i18n>Add Search Term</button>
+ <button class="form-control" (click)="addSearchTerm()" i18n>Add Search Term</button>
+ </div>
+ <div class="col-lg-2">
+ <button class="form-control btn-success" (click)="submitSearch()" i18n>Search</button>
</div>
</div>
<div class="row">
-import {Component, OnInit, AfterViewInit, ViewChild} from '@angular/core';
+import {Component, OnInit, AfterViewInit, ViewChild, ViewChildren, QueryList} from '@angular/core';
import {NgbTabset, NgbTabChangeEvent} from '@ng-bootstrap/ng-bootstrap';
import {Router, ActivatedRoute} from '@angular/router';
import {StaffCommonModule} from '@eg/staff/common.module';
import {IdlService, IdlObject} from '@eg/core/idl.service';
import {PcrudService} from '@eg/core/pcrud.service';
+import {AcqSearchTerm} from './acq-search.service';
import {LineitemResultsComponent} from './lineitem-results.component';
import {PurchaseOrderResultsComponent} from './purchase-order-results.component';
import {InvoiceResultsComponent} from './invoice-results.component';
export class AcqSearchComponent implements OnInit, AfterViewInit {
- selectedSearchTerm: String;
- selectedSearchOp: String;
-
hints = ['jub', 'acqpl', 'acqpo', 'acqinv', 'acqlid'];
- availableSearchTerms = {};
+ availableSearchFields = {};
searchTermDatatypes = {};
searchType = '';
validSearchTypes = ['lineitems', 'purchaseorders', 'invoices', 'selectionlists'];
defaultSearchType = 'lineitems';
+ searchTerms: AcqSearchTerm[] = [];
+
onTabChange: ($event: NgbTabChangeEvent) => void;
@ViewChild('acqSearchTabs', { static: true }) tabs: NgbTabset;
+ @ViewChildren(PurchaseOrderResultsComponent) poResults: QueryList<PurchaseOrderResultsComponent>;
constructor(
private router: Router,
ngOnInit() {
const self = this;
- this.selectedSearchTerm = '';
- this.selectedSearchOp = '';
const searchTypeParam = this.route.snapshot.paramMap.get('searchtype');
}
}
);
- self.availableSearchTerms[hint] = o;
+ self.availableSearchFields[hint] = o;
}
);
this.hints.push('acqlia');
- this.availableSearchTerms['acqlia'] = {'__label': this.idl.classes.acqlia.label, '__fields': []};
+ this.availableSearchFields['acqlia'] = {'__label': this.idl.classes.acqlia.label, '__fields': []};
this.pcrud.retrieveAll('acqliad', {'order_by': {'acqliad': 'id'}})
.subscribe(liad => {
- this.availableSearchTerms['acqlia']['__fields'].push('' + liad.id());
- this.availableSearchTerms['acqlia'][liad.id()] = {
+ this.availableSearchFields['acqlia']['__fields'].push('' + liad.id());
+ this.availableSearchFields['acqlia'][liad.id()] = {
label: liad.description(),
datatype: 'text'
};
this.searchTermDatatypes['acqlia:' + liad.id()] = 'text';
});
+ this.addSearchTerm();
}
ngAfterViewInit() {}
+ addSearchTerm() {
+ this.searchTerms.push({ field: '', op: '', value1: '', value2: '' });
+ }
+
+ setOrgUnitSearchValue(org: IdlObject, term: AcqSearchTerm) {
+ if (org == null) {
+ term.value1 = '';
+ } else {
+ term.value1 = org.id();
+ }
+ }
+
+ submitSearch() {
+ if (this.searchType === 'purchaseorders') {
+ this.poResults.forEach(poResult => poResult.doSearch(this.searchTerms));
+ }
+ }
+
}
'like': '__fuzzy',
};
+export interface AcqSearchTerm {
+ field: string;
+ op: string;
+ value1: string;
+ value2: string;
+}
+
@Injectable()
export class AcqSearchService {
+ _terms: AcqSearchTerm[] = [];
+
constructor(
private net: NetService,
private auth: AuthService
) {
}
+ setSearchTerms(terms: AcqSearchTerm[]) {
+ this._terms = terms;
+ }
+
generateAcqSearch(searchType, filters): any {
const baseSearch = JSON.parse(JSON.stringify(defaultSearch[searchType])); // deep copy
const coreRecType = Object.keys(defaultSearch[searchType])[0];
+ // handle supplied search terms
+ this._terms.forEach(term => {
+ const searchTerm: Object = {};
+ const searchField = term.field.split(':')[1];
+ searchTerm[searchField] = term.value1;
+ if (term.op !== '') {
+ searchTerm[term.op] = true;
+ }
+ baseSearch[coreRecType].push(searchTerm);
+ });
+
// handle grid filters
// note that date filters coming from the grid do not need
// to worry about __castdate because the grid filter supplies
import {AuthService} from '@eg/core/auth.service';
import {GridComponent} from '@eg/share/grid/grid.component';
import {GridDataSource} from '@eg/share/grid/grid';
-import {AcqSearchService} from './acq-search.service';
+import {AcqSearchService, AcqSearchTerm} from './acq-search.service';
@Component({
selector: 'eg-purchase-order-results',
this.gridSource = this.acqSearch.getAcqSearchDataSource('purchase_order');
}
+ doSearch(terms: AcqSearchTerm[]) {
+ this.acqSearch.setSearchTerms(terms);
+ this.purchaseOrderResultsGrid.reload();
+ }
}