From d5df686c003e3ebddfd44960454c8e491bff63ee Mon Sep 17 00:00:00 2001 From: Galen Charlton Date: Tue, 7 Dec 2021 11:56:25 -0500 Subject: [PATCH] LP#1942220: extend the active LI sort order to PO printing Note that this reimplements the sorting client-side. Signed-off-by: Galen Charlton --- .../eg2/src/app/staff/acq/po/print.component.ts | 78 ++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/Open-ILS/src/eg2/src/app/staff/acq/po/print.component.ts b/Open-ILS/src/eg2/src/app/staff/acq/po/print.component.ts index beadb5d99e..bbcfbd8240 100644 --- a/Open-ILS/src/eg2/src/app/staff/acq/po/print.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/acq/po/print.component.ts @@ -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 { + 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 { return this.printer.compileRemoteTemplate({ -- 2.11.0