LP#1942220: extend the active LI sort order to PO printing
authorGalen Charlton <gmc@equinoxOLI.org>
Tue, 7 Dec 2021 16:56:25 +0000 (11:56 -0500)
committerBill Erickson <berickxx@gmail.com>
Wed, 21 Sep 2022 15:29:34 +0000 (11:29 -0400)
Note that this reimplements the sorting client-side.

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

index beadb5d..bbcfbd8 100644 (file)
@@ -5,6 +5,7 @@ import {ActivatedRoute, ParamMap} from '@angular/router';
 import {IdlObject} from '@eg/core/idl.service';
 import {NetService} from '@eg/core/net.service';
 import {AuthService} from '@eg/core/auth.service';
+import {ServerStoreService} from '@eg/core/server-store.service';
 import {PcrudService} from '@eg/core/pcrud.service';
 import {IdlService} from '@eg/core/idl.service';
 import {OrgService} from '@eg/core/org.service';
@@ -12,6 +13,25 @@ import {PrintService} from '@eg/share/print/print.service';
 import {BroadcastService} from '@eg/share/util/broadcast.service';
 import {PoService} from './po.service';
 
+const DEFAULT_SORT_ORDER = 'li_id_asc';
+const SORT_ORDERS = [
+    'li_id_asc',
+    'li_id_desc',
+    'title_asc',
+    'title_desc',
+    'author_asc',
+    'author_desc',
+    'publisher_asc',
+    'publisher_desc',
+    'order_ident_asc',
+    'order_ident_desc'
+];
+const ORDER_IDENT_ATTRS = [
+    'isbn',
+    'issn',
+    'upc'
+];
+
 @Component({
   templateUrl: 'print.component.html'
 })
@@ -30,6 +50,7 @@ export class PrintComponent implements OnInit, AfterViewInit {
         private org: OrgService,
         private net: NetService,
         private auth: AuthService,
+        private store: ServerStoreService,
         private pcrud: PcrudService,
         private poService: PoService,
         private broadcaster: BroadcastService,
@@ -68,10 +89,67 @@ export class PrintComponent implements OnInit, AfterViewInit {
             }
         })
         .then(po => this.po = po)
+        .then(_ => this.sortLineItems())
         .then(_ => this.populatePreview())
         .then(_ => this.initDone = true);
     }
 
+    _getLISortKey(li: IdlObject, field: string): any {
+        let vals = [];
+        switch (field) {
+            case 'li_id':
+                return li.id();
+                break;
+            case 'title':
+                vals = li.attributes().filter(x => x.attr_name() === 'title');
+                return vals.length ? vals[0].attr_value() : null;
+                break;
+            case 'author':
+                vals = li.attributes().filter(x => x.attr_name() === 'author');
+                return vals.length ? vals[0].attr_value() : null;
+                break;
+            case 'publisher':
+                vals = li.attributes().filter(x => x.attr_name() === 'publisher');
+                return vals.length ? vals[0].attr_value() : null;
+                break;
+            case 'order_ident':
+                vals = li.attributes().filter(x => ORDER_IDENT_ATTRS.includes(x.attr_name()));
+                return vals.length ? vals[0].attr_value() : null;
+                break;
+            default:
+                return li.id();
+        }
+    }
+
+    sortLineItems(): Promise<any> {
+        return this.store.getItem('acq.lineitem.sort_order').then(sortOrder => {
+            if (!sortOrder || !SORT_ORDERS.includes(sortOrder)) {
+                sortOrder = DEFAULT_SORT_ORDER;
+            }
+            const _getLISortKey = this._getLISortKey;
+            function nullableCompare(a_val: any, b_val: any): number {
+                return   a_val === b_val ?  0 :
+                         a_val === null  ?  1 :
+                         b_val === null  ? -1 :
+                         a_val > b_val   ?  1 :
+                         a_val < b_val   ? -1 : 0;
+            }
+            function _compareLIs(a, b) {
+                const direction = sortOrder.match(/_asc$/) ? 'asc' : 'desc';
+                const field = sortOrder.replace(/_asc|_desc$/, '');
+                const a_val = _getLISortKey(a, field);
+                const b_val = _getLISortKey(b, field);
+
+                if (direction === 'asc') {
+                    return  nullableCompare(a_val, b_val);
+                } else {
+                    return -nullableCompare(a_val, b_val);
+                }
+            }
+            this.po.lineitems().sort(_compareLIs);
+        });
+    }
+
     populatePreview(): Promise<any> {
 
         return this.printer.compileRemoteTemplate({