Provide exists/does-not-exist (NOT NULL and NULL) operators for acq search fields
authorMike Rylander <mrylander@gmail.com>
Tue, 21 Apr 2020 21:21:41 +0000 (17:21 -0400)
committerGalen Charlton <gmc@equinoxinitiative.org>
Fri, 24 Apr 2020 21:19:51 +0000 (17:19 -0400)
Signed-off-by: Mike Rylander <mrylander@gmail.com>
Signed-off-by: Galen Charlton <gmc@equinoxinitiative.org>
Open-ILS/src/eg2/src/app/staff/acq/search/acq-search-form.component.html
Open-ILS/src/eg2/src/app/staff/acq/search/acq-search.service.ts

index a039578..962a10c 100644 (file)
         <option i18n value="__gte" [hidden]="searchTermDatatypes[t.field] != 'timestamp' && !dateLikeSearchFields[t.field]">is on or AFTER</option>
         <option i18n value="__between" [hidden]="searchTermDatatypes[t.field] != 'timestamp'">is BETWEEN</option>
         <option i18n value="__age" [hidden]="searchTermDatatypes[t.field] != 'timestamp'">age (relative date)</option>
+        <option i18n value="__isnotnull">exists</option>
+        <option i18n value="__isnull">does NOT exist</option>
         <option i18n value="__in">matches a term from a file</option>
       </select>
     </div>
     <div class="col-lg-3">
-      <ng-container *ngIf="t.op == '__in'">
-        <eg-file-reader [(ngModel)]="t.value1" [ngModelOptions]="{standalone: true}"></eg-file-reader>
+      <ng-container *ngIf="t.op == '__in' || t.op == '__isnull' || t.op == '__isnotnull'">
+        <ng-container *ngIf="t.op == '__in'">
+          <eg-file-reader [(ngModel)]="t.value1" [ngModelOptions]="{standalone: true}"></eg-file-reader>
+        </ng-container>
       </ng-container>
-      <ng-container *ngIf="t.op !== '__in'">
+      <ng-container *ngIf="t.op !== '__in' && t.op !== '__isnull' && t.op !== '__isnotnull'">
        <div *ngIf="t.field.endsWith(':state') && (t.op === '' || t.op === '__not'); else notStateField">
          <eg-combobox *ngIf="t.op != '__fuzzy'"
           [asyncSupportsEmptyTermClick]="true"
index 88ac7ca..860c1d5 100644 (file)
@@ -147,13 +147,17 @@ export class AcqSearchService {
 
         // handle supplied search terms
         this._terms.forEach(term => {
-            if (term.value1 === '') {
+            if (term.value1 === '' && !(term.op === '__isnull' || term.op === '__isnotnull')) {
                 return;
             }
             const searchTerm: Object = {};
             const recType = term.field.split(':')[0];
             const searchField = term.field.split(':')[1];
-            if (term.op === '__between') {
+            if (term.op === '__isnull') {
+                searchTerm[searchField] = null;
+            } else if (term.op === '__isnotnull') {
+                searchTerm[searchField] = { '!=' : null };
+            } else if (term.op === '__between') {
                 searchTerm[searchField] = [term.value1, term.value2];
             } else {
                 searchTerm[searchField] = term.value1;