LP#1942220: implement item count and claim count LI filtering
authorGalen Charlton <gmc@equinoxOLI.org>
Tue, 14 Dec 2021 17:12:12 +0000 (12:12 -0500)
committerGalen Charlton <gmc@equinoxOLI.org>
Tue, 14 Dec 2021 17:12:12 +0000 (12:12 -0500)
Noting that this is being done client-side

Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
Open-ILS/src/eg2/src/app/staff/acq/lineitem/lineitem-list.component.html
Open-ILS/src/eg2/src/app/staff/acq/lineitem/lineitem-list.component.ts

index 842ef41..f93cfab 100644 (file)
             <option value="acqlia:isbn" i18n>ISBN</option>
             <option value="acqlia:issn" i18n>ISSN</option>
             <option value="acqlia:upc" i18n>UPC</option>
-<!-- TODO
             <option value="claim_count" i18n>Claim count</option>
             <option value="item_count" i18n>Item count</option>
--->
             <option value="estimated_unit_price" i18n>Estimated unit price</option>
           </select> 
           <label for="filter-operator-select" class="form-check-label mr-1 ml-1">using operator:</label>
             <option i18n value="__gte" [hidden]="searchTermDatatypes[filterField] != 'timestamp' && !dateLikeSearchFields[filterField]">is on or AFTER</option>
             <option i18n value="__between" [hidden]="searchTermDatatypes[filterField] != 'timestamp'">is BETWEEN</option>
             <option i18n value="__age" [hidden]="searchTermDatatypes[filterField] != 'timestamp'">age (relative date)</option>
+            <option i18n value="__gte" [hidden]="searchTermDatatypes[filterField] != 'number'">is greater than or equal</option>
+            <option i18n value="__lte" [hidden]="searchTermDatatypes[filterField] != 'number'">is less than or equal</option>
 <!-- TODO
             <option i18n value="__isnotnull" [hidden]="searchTermDatatypes[filterField] == 'id'">exists</option>
             <option i18n value="__isnull" [hidden]="searchTermDatatypes[filterField] == 'id'">does NOT exist</option>
index 5eb96c0..b37e856 100644 (file)
@@ -92,8 +92,8 @@ export class LineitemListComponent implements OnInit {
         'acqlia:isbn': 'text',
         'acqlia:issn': 'text',
         'acqlia:upc': 'text',
-        'claim_count': 'text',
-        'item_count': 'text',
+        'claim_count': 'number',
+        'item_count': 'number',
         'estimated_unit_price': 'money',
     };
     dateLikeSearchFields = {
@@ -301,6 +301,10 @@ export class LineitemListComponent implements OnInit {
         Object.assign(opts, SORT_ORDER_MAP[this.sortOrder]);
 
         let _doingClientSort = false;
+        if (this.filterField === 'item_count' ||
+            this.filterField === 'claim_count') {
+            opts['flesh_li_details'] = true;
+        }
         if (this.sortOrder === 'title_asc'      ||
             this.sortOrder === 'title_desc'     ||
             this.sortOrder === 'author_asc'     ||
@@ -314,9 +318,9 @@ export class LineitemListComponent implements OnInit {
             _doingClientSort = true;
             opts['flesh_attrs'] = true;
         } else {
-            // not doing a title sort, so we can rely on
-            // the server-side sort as is
-            opts['id_list'] = true;
+            if (!opts['flesh_li_details']) {
+                opts['id_list'] = true;
+            }
         }
 
         return this.net.request(
@@ -328,6 +332,50 @@ export class LineitemListComponent implements OnInit {
             null,
             opts
         ).toPromise().then(resp => {
+            let _mustDeflesh = false;
+            if (this.filterField === 'item_count') {
+                _mustDeflesh = true;
+                if (!isNaN(Number(this.filterValue))) {
+                    const num = Number(this.filterValue);
+                    resp = resp.filter(l => {
+                        if (this.filterOperator === '' && l.item_count() === num) {
+                            return true;
+                        } else if (this.filterOperator === '__not' && l.item_count() !== num) {
+                            return true;
+                        } else if (this.filterOperator === '__gte' && l.item_count() >= num) {
+                            return true;
+                        } else if (this.filterOperator === '__lte' && l.item_count() <= num) {
+                            return true;
+                        } else {
+                            return false;
+                        }
+                    });
+                }
+            } else if (this.filterField === 'claim_count') {
+                _mustDeflesh = true;
+                if (!isNaN(Number(this.filterValue))) {
+                    const num = Number(this.filterValue);
+                    resp.forEach(
+                        l => l['_claim_count'] = l.lineitem_details().reduce(
+                            (a, b) => (a ? a.claims().length : 0) + b.claims().length, 0
+                        )
+                    );
+                    resp = resp.filter(l => {
+                        if (this.filterOperator === '' && l['_claim_count'] === num) {
+                            return true;
+                        } else if (this.filterOperator === '__not' && l['_claim_count'] !== num) {
+                            return true;
+                        } else if (this.filterOperator === '__gte' && l['_claim_count'] >= num) {
+                            return true;
+                        } else if (this.filterOperator === '__lte' && l['_claim_count'] <= num) {
+                            return true;
+                        } else {
+                            return false;
+                        }
+                    });
+                    resp.forEach(l => delete l['_claim_count']);
+                }
+            }
             if (_doingClientSort) {
                 const sortOrder = this.sortOrder;
                 const liService = this.liService;
@@ -346,7 +394,11 @@ export class LineitemListComponent implements OnInit {
                 }
                 this.lineitemIds = resp.sort(_compareLIs).map(l => Number(l.id()));
             } else {
-                this.lineitemIds = resp.map(i => Number(i));
+                if (_mustDeflesh) {
+                    this.lineitemIds = resp.map(l => Number(l.id()));
+                } else {
+                    this.lineitemIds = resp.map(i => Number(i));
+                }
             }
             this.pager.resultCount = resp.length;
         });
@@ -358,6 +410,11 @@ export class LineitemListComponent implements OnInit {
         let filterOp = this.filterOperator;
         let filterVal = this.filterValue;
 
+        if (filterField === 'item_count' ||
+            filterField === 'claim_count') {
+            return;
+        }
+
         if (filterOp === 'like' && filterVal.length > 1) {
             if (filterVal[0] === '%' && filterVal[filterVal.length - 1] === '%') {
                 filterVal = filterVal.slice(1, filterVal.length - 1);