From 69fe2ac300565b147d5dad791dc95de63ce4fa8c Mon Sep 17 00:00:00 2001 From: GregJohnStewart Date: Fri, 14 Nov 2025 23:03:01 -0500 Subject: [PATCH 01/66] Core - API - Added search query to search results --- .../interfaces/endpoints/MainFileObjectProvider.java | 3 ++- .../oqm/core/api/model/rest/search/SearchObject.java | 4 ++++ .../importExport/exporting/DatabaseExportService.java | 2 +- .../importExport/importing/importer/FileImporter.java | 3 ++- .../importing/importer/GenericFileImporter.java | 3 ++- .../core/api/service/mongo/MongoObjectService.java | 3 ++- .../core/api/service/mongo/TopLevelMongoService.java | 3 ++- .../core/api/service/mongo/file/MongoFileService.java | 7 +++++-- .../service/mongo/file/MongoHistoriedFileService.java | 3 ++- .../service/mongo/search/ItemAwareSearchResult.java | 6 ++++-- .../core/api/service/mongo/search/SearchResult.java | 11 ++++++++--- .../service/mongo/search/PagingCalculationsTest.java | 4 +++- 12 files changed, 37 insertions(+), 15 deletions(-) diff --git a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/interfaces/endpoints/MainFileObjectProvider.java b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/interfaces/endpoints/MainFileObjectProvider.java index 593ffa017d..c9d769d642 100644 --- a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/interfaces/endpoints/MainFileObjectProvider.java +++ b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/interfaces/endpoints/MainFileObjectProvider.java @@ -11,6 +11,7 @@ import org.bson.types.ObjectId; import tech.ebp.oqm.core.api.interfaces.endpoints.media.FileGet; import tech.ebp.oqm.core.api.model.object.FileMainObject; +import tech.ebp.oqm.core.api.model.object.MainObject; import tech.ebp.oqm.core.api.model.object.history.ObjectHistoryEvent; import tech.ebp.oqm.core.api.model.object.media.FileMetadata; import tech.ebp.oqm.core.api.model.rest.media.file.FileUploadBody; @@ -32,7 +33,7 @@ */ @Slf4j @NoArgsConstructor -public abstract class MainFileObjectProvider, G extends FileGet> extends ObjectProvider { +public abstract class MainFileObjectProvider, G extends MainObject & FileGet> extends ObjectProvider { @Getter diff --git a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/rest/search/SearchObject.java b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/rest/search/SearchObject.java index 8c0ff1dde1..76bfe6a0bd 100644 --- a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/rest/search/SearchObject.java +++ b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/rest/search/SearchObject.java @@ -1,5 +1,6 @@ package tech.ebp.oqm.core.api.model.rest.search; +import com.fasterxml.jackson.annotation.JsonIgnore; import jakarta.ws.rs.QueryParam; import lombok.Getter; import lombok.Setter; @@ -26,14 +27,17 @@ public class SearchObject { @QueryParam("sortBy") String sortField; @QueryParam("sortType") SortType sortType; + @JsonIgnore public Bson getSortBson(){ return SearchUtils.getSortBson(this.sortField, this.sortType); } + @JsonIgnore public PagingOptions getPagingOptions(){ return PagingOptions.from(this); } + @JsonIgnore public List getSearchFilters(){ return new ArrayList<>(); } diff --git a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/importExport/exporting/DatabaseExportService.java b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/importExport/exporting/DatabaseExportService.java index 3c709150bb..325bd691c2 100644 --- a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/importExport/exporting/DatabaseExportService.java +++ b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/importExport/exporting/DatabaseExportService.java @@ -121,7 +121,7 @@ private static > void recordReco log.info("Took {} to write all data for {}", sw, dataTypeName); } - private static , G extends FileGet> void recordRecords( + private static , G extends MainObject & FileGet> void recordRecords( String oqmDbIdOrName, File tempDir, MongoFileService fileService, diff --git a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/importExport/importing/importer/FileImporter.java b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/importExport/importing/importer/FileImporter.java index 9cd751c601..3cb79e54e5 100644 --- a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/importExport/importing/importer/FileImporter.java +++ b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/importExport/importing/importer/FileImporter.java @@ -6,6 +6,7 @@ import org.bson.types.ObjectId; import tech.ebp.oqm.core.api.interfaces.endpoints.media.FileGet; import tech.ebp.oqm.core.api.model.object.FileMainObject; +import tech.ebp.oqm.core.api.model.object.MainObject; import tech.ebp.oqm.core.api.model.object.interactingEntity.InteractingEntity; import tech.ebp.oqm.core.api.model.rest.media.file.FileUploadBody; import tech.ebp.oqm.core.api.model.rest.search.FileSearchObject; @@ -22,7 +23,7 @@ public abstract class FileImporter< T extends FileMainObject, U extends FileUploadBody, S extends FileSearchObject, - G extends FileGet, + G extends MainObject & FileGet, M extends MongoHistoriedFileService > extends Importer { diff --git a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/importExport/importing/importer/GenericFileImporter.java b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/importExport/importing/importer/GenericFileImporter.java index 85ceedef79..d71c8ff8fa 100644 --- a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/importExport/importing/importer/GenericFileImporter.java +++ b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/importExport/importing/importer/GenericFileImporter.java @@ -8,6 +8,7 @@ import org.bson.types.ObjectId; import tech.ebp.oqm.core.api.interfaces.endpoints.media.FileGet; import tech.ebp.oqm.core.api.model.object.FileMainObject; +import tech.ebp.oqm.core.api.model.object.MainObject; import tech.ebp.oqm.core.api.model.object.ObjectUtils; import tech.ebp.oqm.core.api.model.object.interactingEntity.InteractingEntity; import tech.ebp.oqm.core.api.model.object.media.FileMetadata; @@ -30,7 +31,7 @@ public class GenericFileImporter< T extends FileMainObject, U extends FileUploadBody, S extends FileSearchObject, - G extends FileGet + G extends MainObject & FileGet > extends FileImporter> { diff --git a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/MongoObjectService.java b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/MongoObjectService.java index b1c9ab51a6..8751f8d5ba 100644 --- a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/MongoObjectService.java +++ b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/MongoObjectService.java @@ -227,7 +227,8 @@ public SearchResult search(String oqmDbIdOrName, ClientSession cs, @NonNull S list, this.count(oqmDbIdOrName, filter), !filters.isEmpty(), - pagingOptions + pagingOptions, + searchObject ); } diff --git a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/TopLevelMongoService.java b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/TopLevelMongoService.java index 7a16815758..b59e4539c4 100644 --- a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/TopLevelMongoService.java +++ b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/TopLevelMongoService.java @@ -192,7 +192,8 @@ public SearchResult search(@NonNull S searchObject) { list, this.count(filter), !filters.isEmpty(), - pagingOptions + pagingOptions, + searchObject ); } diff --git a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/file/MongoFileService.java b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/file/MongoFileService.java index 4e2bf52212..8ba3d3489d 100644 --- a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/file/MongoFileService.java +++ b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/file/MongoFileService.java @@ -25,6 +25,7 @@ import tech.ebp.oqm.core.api.interfaces.endpoints.media.FileGet; import tech.ebp.oqm.core.api.model.collectionStats.CollectionStats; import tech.ebp.oqm.core.api.model.object.FileMainObject; +import tech.ebp.oqm.core.api.model.object.MainObject; import tech.ebp.oqm.core.api.model.object.media.FileHashes; import tech.ebp.oqm.core.api.model.object.media.FileMetadata; import tech.ebp.oqm.core.api.model.rest.management.CollectionClearResult; @@ -67,7 +68,8 @@ * @param */ @Slf4j -public abstract class MongoFileService, X extends CollectionStats, G extends FileGet> extends MongoDbAwareService { +public abstract class MongoFileService, X extends CollectionStats, G extends MainObject & FileGet> extends MongoDbAwareService { private Map gridBuckets = new HashMap<>(); @@ -201,7 +203,8 @@ public SearchResult search(String dbIdOrName, S search){ results, this.getFileObjectService().count(dbIdOrName, filter), !filters.isEmpty(), - search.getPagingOptions() + search.getPagingOptions(), + search ); } diff --git a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/file/MongoHistoriedFileService.java b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/file/MongoHistoriedFileService.java index 6583f9e645..2d20849907 100644 --- a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/file/MongoHistoriedFileService.java +++ b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/file/MongoHistoriedFileService.java @@ -12,6 +12,7 @@ import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.bson.types.ObjectId; +import tech.ebp.oqm.core.api.model.object.MainObject; import tech.ebp.oqm.core.api.service.mongo.media.FileObjectService; import tech.ebp.oqm.core.api.interfaces.endpoints.media.FileGet; import tech.ebp.oqm.core.api.model.collectionStats.CollectionStats; @@ -37,7 +38,7 @@ * @param The type of object stored. */ @Slf4j -public abstract class MongoHistoriedFileService, G extends FileGet> +public abstract class MongoHistoriedFileService, G extends MainObject & FileGet> extends MongoFileService { public static final String NULL_USER_EXCEPT_MESSAGE = "User must exist to perform action."; diff --git a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/search/ItemAwareSearchResult.java b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/search/ItemAwareSearchResult.java index 9e7aea93c3..76e4240ad6 100644 --- a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/search/ItemAwareSearchResult.java +++ b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/search/ItemAwareSearchResult.java @@ -1,6 +1,7 @@ package tech.ebp.oqm.core.api.service.mongo.search; import lombok.*; +import tech.ebp.oqm.core.api.model.object.MainObject; import tech.ebp.oqm.core.api.model.object.storage.items.InventoryItem; import java.util.List; @@ -10,7 +11,7 @@ @Data @AllArgsConstructor @NoArgsConstructor -public class ItemAwareSearchResult extends SearchResult { +public class ItemAwareSearchResult extends SearchResult { private InventoryItem inventoryItem; @@ -21,7 +22,8 @@ public ItemAwareSearchResult(InventoryItem inventoryItem, SearchResult search searchResult.getNumResultsForEntireQuery(), searchResult.isHadSearchQuery(), searchResult.getPagingOptions(), - searchResult.getPagingCalculations() + searchResult.getPagingCalculations(), + searchResult.getSearchObject() ); this.inventoryItem = inventoryItem; } diff --git a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/search/SearchResult.java b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/search/SearchResult.java index 81f28200ca..6feefdf6d4 100644 --- a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/search/SearchResult.java +++ b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/search/SearchResult.java @@ -3,13 +3,15 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import tech.ebp.oqm.core.api.model.object.MainObject; +import tech.ebp.oqm.core.api.model.rest.search.SearchObject; import java.util.List; @Data @AllArgsConstructor @NoArgsConstructor -public class SearchResult { +public class SearchResult { private List results; private long numResults; @@ -17,6 +19,7 @@ public class SearchResult { private boolean hadSearchQuery; private PagingOptions pagingOptions; private PagingCalculations pagingCalculations; + private SearchObject searchObject; public SearchResult(List results) { this( @@ -25,18 +28,20 @@ public SearchResult(List results) { results.size(), false, null, + null, null ); } - public SearchResult(List results, long numResultsForEntireQuery, boolean hadSearchQuery, PagingOptions pagingOptions) { + public SearchResult(List results, long numResultsForEntireQuery, boolean hadSearchQuery, PagingOptions pagingOptions, SearchObject searchObject) { this( results, results.size(), numResultsForEntireQuery, hadSearchQuery, pagingOptions, - new PagingCalculations(pagingOptions, numResultsForEntireQuery) + new PagingCalculations(pagingOptions, numResultsForEntireQuery), + searchObject ); } diff --git a/software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/search/PagingCalculationsTest.java b/software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/search/PagingCalculationsTest.java index 9a50edbafa..e27e5a3f36 100644 --- a/software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/search/PagingCalculationsTest.java +++ b/software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/search/PagingCalculationsTest.java @@ -8,6 +8,8 @@ import tech.ebp.oqm.core.api.service.mongo.search.PagingCalculations; import tech.ebp.oqm.core.api.service.mongo.search.PagingOptions; import tech.ebp.oqm.core.api.service.mongo.search.SearchResult; +import tech.ebp.oqm.core.api.testResources.data.TestMainObject; +import tech.ebp.oqm.core.api.testResources.data.TestMainObjectSearch; import java.util.Collections; import java.util.Iterator; @@ -91,7 +93,7 @@ public void testOnPage() { @Test public void testSearchConstructor() { PagingCalculations calculations = new PagingCalculations( - new SearchResult(Collections.emptyList(), 3, false, new PagingOptions(1, 2)) + new SearchResult(Collections.emptyList(), 3, false, new PagingOptions(1, 2), new TestMainObjectSearch()) ); assertEquals(3, calculations.getNumPages()); From 926e30651dd2d91a24cbf83522231aa3735e16e9 Mon Sep 17 00:00:00 2001 From: GregJohnStewart Date: Sat, 15 Nov 2025 00:46:07 -0500 Subject: [PATCH 02/66] Lib - Core API for Quarkus - Added new search param for inventory item --- .../runtime/restClient/searchObjects/InventoryItemSearch.java | 1 + 1 file changed, 1 insertion(+) diff --git a/software/libs/core-api-lib-quarkus/runtime/src/main/java/tech/ebp/oqm/lib/core/api/quarkus/runtime/restClient/searchObjects/InventoryItemSearch.java b/software/libs/core-api-lib-quarkus/runtime/src/main/java/tech/ebp/oqm/lib/core/api/quarkus/runtime/restClient/searchObjects/InventoryItemSearch.java index f2394b68d5..11307a39ef 100644 --- a/software/libs/core-api-lib-quarkus/runtime/src/main/java/tech/ebp/oqm/lib/core/api/quarkus/runtime/restClient/searchObjects/InventoryItemSearch.java +++ b/software/libs/core-api-lib-quarkus/runtime/src/main/java/tech/ebp/oqm/lib/core/api/quarkus/runtime/restClient/searchObjects/InventoryItemSearch.java @@ -16,6 +16,7 @@ @SuperBuilder(toBuilder = true) public class InventoryItemSearch extends SearchKeyAttObject { @QueryParam("name") String name; + @QueryParam("storageTypes") List storageTypes; @QueryParam("itemCategories") List categories; @QueryParam("inStorageBlock") List inStorageBlocks; @QueryParam("hasExpired") Boolean hasExpired; From 412956afb49a04d24bec7204b3d098a1c2fbea22 Mon Sep 17 00:00:00 2001 From: GregJohnStewart Date: Sat, 15 Nov 2025 00:47:15 -0500 Subject: [PATCH 03/66] Core - API - Work towards initial rework of printouts --- .../rest/search/InventoryItemSearch.java | 14 ++++++++++- .../api/service/mongo/MongoObjectService.java | 2 +- .../service/mongo/TopLevelMongoService.java | 2 +- .../service/mongo/file/MongoFileService.java | 2 +- .../mongo/search/PagingCalculations.java | 25 +++++++++++-------- .../service/mongo/search/SearchResult.java | 6 ++--- .../mongo/search/PagingCalculationsTest.java | 10 ++++---- .../mongo/search/PagingOptionsTest.java | 6 ++--- 8 files changed, 41 insertions(+), 26 deletions(-) diff --git a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/rest/search/InventoryItemSearch.java b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/rest/search/InventoryItemSearch.java index f7e29b4967..07f252b6b6 100644 --- a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/rest/search/InventoryItemSearch.java +++ b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/rest/search/InventoryItemSearch.java @@ -8,6 +8,7 @@ import org.bson.conversions.Bson; import org.bson.types.ObjectId; import tech.ebp.oqm.core.api.model.object.storage.items.InventoryItem; +import tech.ebp.oqm.core.api.model.object.storage.items.StorageType; import tech.ebp.oqm.core.api.service.mongo.search.SearchUtils; import java.util.ArrayList; @@ -20,6 +21,7 @@ @Setter public class InventoryItemSearch extends SearchKeyAttObject { @QueryParam("name") String name; + @QueryParam("storageTypes") List storageTypes; @QueryParam("itemCategories") List categories; @QueryParam("inStorageBlock") List inStorageBlocks; @QueryParam("hasExpired") Boolean hasExpired; @@ -41,7 +43,17 @@ public List getSearchFilters() { SearchUtils.getBasicSearchFilter("name", this.getName()) ); } - if (this.getCategories() != null && !this.categories.isEmpty()) { + if (this.getCategories() != null && !this.getStorageTypes().isEmpty()) { + List typeFilterList = new ArrayList<>(this.getStorageTypes().size()); + for (StorageType curType : this.getStorageTypes()) { + typeFilterList.add(eq( + "storageType", + curType + )); + } + filters.add(Filters.or(typeFilterList)); + } + if (this.getCategories() != null && !this.getCategories().isEmpty()) { List catsFilterList = new ArrayList<>(this.getCategories().size()); for (ObjectId curCategoryId : this.getCategories()) { catsFilterList.add(in( diff --git a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/MongoObjectService.java b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/MongoObjectService.java index 8751f8d5ba..13bc1702ec 100644 --- a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/MongoObjectService.java +++ b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/MongoObjectService.java @@ -225,7 +225,7 @@ public SearchResult search(String oqmDbIdOrName, ClientSession cs, @NonNull S return new SearchResult<>( list, - this.count(oqmDbIdOrName, filter), + (int) this.count(oqmDbIdOrName, filter), !filters.isEmpty(), pagingOptions, searchObject diff --git a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/TopLevelMongoService.java b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/TopLevelMongoService.java index b59e4539c4..332a3157e1 100644 --- a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/TopLevelMongoService.java +++ b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/TopLevelMongoService.java @@ -190,7 +190,7 @@ public SearchResult search(@NonNull S searchObject) { return new SearchResult<>( list, - this.count(filter), + (int) this.count(filter), !filters.isEmpty(), pagingOptions, searchObject diff --git a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/file/MongoFileService.java b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/file/MongoFileService.java index 8ba3d3489d..2d3fab33f8 100644 --- a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/file/MongoFileService.java +++ b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/file/MongoFileService.java @@ -201,7 +201,7 @@ public SearchResult search(String dbIdOrName, S search){ return new SearchResult<>( results, - this.getFileObjectService().count(dbIdOrName, filter), + (int) this.getFileObjectService().count(dbIdOrName, filter), !filters.isEmpty(), search.getPagingOptions(), search diff --git a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/search/PagingCalculations.java b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/search/PagingCalculations.java index 14ed627581..b0095f0db3 100644 --- a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/search/PagingCalculations.java +++ b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/search/PagingCalculations.java @@ -15,19 +15,21 @@ public class PagingCalculations { private boolean onFirstPage; private boolean onLastPage; - private long numPages; - private long lastPage; - private long curPage; - private long nextPage; - private long previousPage; - private long pageResultIndexStart; - private long pageResultIndexEnd; + private int numPages; + private int pageSize; + private int lastPage; + private int curPage; + private int nextPage; + private int previousPage; + private int pageResultIndexStart; + private int pageResultIndexEnd; - protected PagingCalculations(long curPageNum, long numPages, long startIndex, long endIndex) { + protected PagingCalculations(int curPageNum, int numPages, int pageSize, int startIndex, int endIndex) { this( curPageNum <= 1, curPageNum == numPages, numPages, + pageSize, numPages, curPageNum, (Math.min(curPageNum + 1, numPages)), @@ -37,12 +39,13 @@ protected PagingCalculations(long curPageNum, long numPages, long startIndex, lo ); } - public PagingCalculations(PagingOptions options, long numResults) { + public PagingCalculations(PagingOptions options, int numResults) { this( options.getPageNum(), - (long) Math.ceil((double) numResults / (double) options.getPageSize()), + (int) Math.ceil((double) numResults / (double) options.getPageSize()), + options.getPageSize(), options.getSkipVal(), - options.getSkipVal() + options.pageSize - 1 + options.getSkipVal() + options.getPageSize() - 1 ); } diff --git a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/search/SearchResult.java b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/search/SearchResult.java index 6feefdf6d4..5610a45e96 100644 --- a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/search/SearchResult.java +++ b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/search/SearchResult.java @@ -14,8 +14,8 @@ public class SearchResult { private List results; - private long numResults; - private long numResultsForEntireQuery; + private int numResults; + private int numResultsForEntireQuery; private boolean hadSearchQuery; private PagingOptions pagingOptions; private PagingCalculations pagingCalculations; @@ -33,7 +33,7 @@ public SearchResult(List results) { ); } - public SearchResult(List results, long numResultsForEntireQuery, boolean hadSearchQuery, PagingOptions pagingOptions, SearchObject searchObject) { + public SearchResult(List results, int numResultsForEntireQuery, boolean hadSearchQuery, PagingOptions pagingOptions, SearchObject searchObject) { this( results, results.size(), diff --git a/software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/search/PagingCalculationsTest.java b/software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/search/PagingCalculationsTest.java index e27e5a3f36..d6cebcb7ec 100644 --- a/software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/search/PagingCalculationsTest.java +++ b/software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/search/PagingCalculationsTest.java @@ -42,13 +42,13 @@ public static Stream getPageIteratorArgs() { @MethodSource("getConstructorArgs") public void testConstructor( PagingOptions options, - long numResults, + int numResults, boolean expectedOnFirstPage, boolean expectedOnLastPage, - long expectedNumPages, - long expectedCurPage, - long expectedNextPage, - long expectedPreviousPage + int expectedNumPages, + int expectedCurPage, + int expectedNextPage, + int expectedPreviousPage ) { PagingCalculations calculations = new PagingCalculations(options, numResults); diff --git a/software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/search/PagingOptionsTest.java b/software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/search/PagingOptionsTest.java index 5966584b63..aed153e456 100644 --- a/software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/search/PagingOptionsTest.java +++ b/software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/search/PagingOptionsTest.java @@ -32,9 +32,9 @@ public void testFromQueryParams( Integer pageSize, Integer pageNum, boolean expectedDoPaging, - long expectedPageSize, - long expectedPageNum, - long expectedSkipVal, + int expectedPageSize, + int expectedPageNum, + int expectedSkipVal, Class expectedE ) { if (expectedE == null) { From 61306c5147576f4797b77c21b47efcd62cefcf98 Mon Sep 17 00:00:00 2001 From: GregJohnStewart Date: Sat, 15 Nov 2025 00:47:53 -0500 Subject: [PATCH 04/66] Core - Base Station - work towards initial rework of printouts --- .../PrintoutDataSearchUtilService.java | 126 ++++++++++++++++ .../StorageBlockInventorySheetService.java | 8 +- .../amountListStoredTable.html | 0 .../bulkStoredTable.html} | 0 .../uniqueMultiStoredTable.html} | 0 .../itemTables/uniqueSingleStoredTable.html | 141 ++++++++++++++++++ .../storageBlockSection.qute.html | 16 ++ 7 files changed, 286 insertions(+), 5 deletions(-) create mode 100644 software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/PrintoutDataSearchUtilService.java rename software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/{ => itemTables}/amountListStoredTable.html (100%) rename software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/{amountSimpleStoredTable.html => itemTables/bulkStoredTable.html} (100%) rename software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/{trackedStoredTable.html => itemTables/uniqueMultiStoredTable.html} (100%) create mode 100644 software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/uniqueSingleStoredTable.html create mode 100644 software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/storageBlockSection.qute.html diff --git a/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/PrintoutDataSearchUtilService.java b/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/PrintoutDataSearchUtilService.java new file mode 100644 index 0000000000..48108a54e1 --- /dev/null +++ b/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/PrintoutDataSearchUtilService.java @@ -0,0 +1,126 @@ +package tech.ebp.oqm.core.baseStation.service.printout; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Named; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.function.TriFunction; +import org.eclipse.microprofile.rest.client.inject.RestClient; +import tech.ebp.oqm.lib.core.api.quarkus.runtime.restClient.OqmCoreApiClientService; +import tech.ebp.oqm.lib.core.api.quarkus.runtime.restClient.searchObjects.InventoryItemSearch; + +import javax.xml.transform.Result; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.function.BiFunction; + +@Slf4j +@Named("PrintoutDataUtilService") +@ApplicationScoped +public class PrintoutDataSearchUtilService { + + @RestClient + OqmCoreApiClientService client; + + public ObjectNode getItemsInBlock(String auth, String db, String blockId, String storageType) { + try { + return this.client.invItemSearch( + auth, + db, + InventoryItemSearch.builder() + .inStorageBlocks(List.of(blockId)) + .storageTypes(List.of(storageType)) + .build() + ).subscribeAsCompletionStage().get(); + } catch(InterruptedException|ExecutionException e) { + throw new RuntimeException("Failed to get inventory items from search.", e); + } + } + + public ObjectNode getItemsNextPage(String auth, String db, ObjectNode prevSearchResults){ + ObjectNode pagingCalculations = (ObjectNode) prevSearchResults.get("pagingCalculations"); + ObjectNode prevQuery = (ObjectNode) prevSearchResults.get("searchObject"); + + List storageBlocks = new ArrayList<>(); + for(JsonNode node : prevQuery.get("inStorageBlocks")){ + storageBlocks.add(node.asText()); + } + List types = new ArrayList<>(); + for(JsonNode node : prevQuery.get("storageTypes")){ + types.add(node.asText()); + } + + try { + return this.client.invItemSearch( + auth, + db, + InventoryItemSearch.builder() + .inStorageBlocks(storageBlocks) + .storageTypes(types) + .pageNum(pagingCalculations.get("curPage").asInt() + 1) + .pageSize(pagingCalculations.get("pageSize").asInt()) + .build() + ).subscribeAsCompletionStage().get(); + } catch(InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + } + + public Iterator getItemInBlockResultsIterator(String auth, String db, String blockId, String storageType){ + return new ResultsIterator( + auth, + db, + this.getItemsInBlock(auth, db, blockId, storageType), + this::getItemsNextPage + ); + } + + @AllArgsConstructor(access = AccessLevel.PRIVATE) + public static class ResultsIterator implements Iterator { + + @NonNull + private String auth; + @NonNull + private String db; + + @NonNull + private ObjectNode curResults; + @NonNull + private TriFunction operation; + private boolean first; + + public ResultsIterator( + String auth, + String db, + ObjectNode curResults, + TriFunction operation + ){ + this(auth, db, curResults, operation, false); + } + + @Override + public boolean hasNext() { + return this.curResults == null || this.curResults.get("pagingCalculations").get("onLastPage").asBoolean(); + } + + @Override + public ObjectNode next() { + if(first){ + first = false; + return curResults; + } + + this.curResults = this.operation.apply(this.auth, this.db, this.curResults); + + return curResults; + } + } + +} diff --git a/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/StorageBlockInventorySheetService.java b/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/StorageBlockInventorySheetService.java index a69c053aad..3a6af4296e 100644 --- a/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/StorageBlockInventorySheetService.java +++ b/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/StorageBlockInventorySheetService.java @@ -72,6 +72,7 @@ private TemplateInstance getHtmlInventorySheet( ObjectNode itemsInBlockSr, InventorySheetsOptions options ) { + //TODO:: update these Predicate simpleAmountFilter = new Predicate() { @Override public boolean test(ObjectNode inventoryItem) { @@ -90,9 +91,7 @@ public boolean test(ObjectNode inventoryItem) { return "TRACKED".equals(inventoryItem.get("storageType").asText()); } }; - - - + return this.setupBasicPrintoutData(this.inventorySheetTemplate) .data("simpleAmountFilter", simpleAmountFilter) .data("listAmountFilter", listAmountFilter) @@ -173,8 +172,7 @@ public File getPdfInventorySheet( doc.getDocumentInfo().setSubject("Inventory sheet for " + block.get("label").asText()); doc.getDocumentInfo().setTitle(block.get("labelText").asText() + " Inventory Sheet"); doc.getDocumentInfo().setKeywords("inventory, sheet, " + storageBlockId); - - + String html = this.getHtmlInventorySheet( block, storageBlockChildrenSr, diff --git a/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/amountListStoredTable.html b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/amountListStoredTable.html similarity index 100% rename from software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/amountListStoredTable.html rename to software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/amountListStoredTable.html diff --git a/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/amountSimpleStoredTable.html b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/bulkStoredTable.html similarity index 100% rename from software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/amountSimpleStoredTable.html rename to software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/bulkStoredTable.html diff --git a/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/trackedStoredTable.html b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/uniqueMultiStoredTable.html similarity index 100% rename from software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/trackedStoredTable.html rename to software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/uniqueMultiStoredTable.html diff --git a/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/uniqueSingleStoredTable.html b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/uniqueSingleStoredTable.html new file mode 100644 index 0000000000..ae8d716cbd --- /dev/null +++ b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/uniqueSingleStoredTable.html @@ -0,0 +1,141 @@ +{#if curItemList.length > 0} +
+

Tracked Items ({curItemList.length})

+ + + + {#if options.includeNumCol} + + {/if} + {#if options.includeImageCol} + + {/if} + + + + + + {#if options.includeConditionCol} + + + {/if} + + + + + {#for curItem in curItemList} + {#let curWrapper = curItem.get("storageMap").get(storageBlock.get("id").asText())} + {#for curTrackedStored in curWrapper.get("stored").elements()} + + {#if curTrackedStored_count == 1} + {#if options.includeNumCol} + + {/if} + {#if options.includeImageCol} + {#if ! curItem.get("imageIds").isEmpty()} + + {#else} + + {/if} + {/if} + + + + {/if} + + + + {#if options.includeConditionCol} + + + {/if} + + {! TODO:: optionally handle keywords, atts, barcode? !} + + + {/for} + {/let} + {/for} + + + + {#if options.includeNumCol} + + {/if} + {#if options.includeImageCol} + + {/if} + + + + + + {#if options.includeConditionCol} + + + {/if} + + + +
+ # + + Image + + Item + + Total + + Id + + Id Val + + Identifying Details + + Cond. + + Cond. Notes + + Exp.? +
+ {curItem_count} + + {#let curImage = imageService.get(curItem.get("imageIds").get(0))} + Image for item {curItem.get( + {/let} + + {curItem.get("name").asText()} + + {curItem.get("total").get("value").asDouble()}{curItem.get("total").get("unit").get("symbol").asText()} + + {curItem.get("trackedItemIdentifierName").asText()} + {curTrackedStored.get("identifier").asText()}{curTrackedStored.get("identifyingDetails").asText()}{curTrackedStored.get("condition").asDouble()}%{curTrackedStored.get("conditionNotes").asText()} + {#if curTrackedStored.get("expires").asBoolean() != null} + {curTrackedStored.get("notificationStatus").get("expired").asBoolean()} + {#else} + N/A + {/if} +
+ # + + Image + + Item + + Total + + Id + + Id Val + + Identifying Details + + Cond. + + Cond. Notes + + Exp.? +
+
+{/if} \ No newline at end of file diff --git a/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/storageBlockSection.qute.html b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/storageBlockSection.qute.html new file mode 100644 index 0000000000..2287114968 --- /dev/null +++ b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/storageBlockSection.qute.html @@ -0,0 +1,16 @@ + +
+

{sectionTitle.else(storageBlock.name)}

+

+ Location: {storageBlock.location} + Description: {storageBlock.description} +

+ + {!TODO:: get result for each type !} + + + + + + +
\ No newline at end of file From 283fb067ae72cf5ec9f48a60156bf91c5dab76a3 Mon Sep 17 00:00:00 2001 From: GregJohnStewart Date: Sun, 16 Nov 2025 01:09:21 -0500 Subject: [PATCH 05/66] Core - Base Station - Most of the way up to reworked bulk stored table for printouts --- .../interfaces/rest/Printouts.java | 2 + .../PrintoutDataSearchUtilService.java | 8 +- .../StorageBlockInventorySheetService.java | 93 +++------ .../storageBlockInventorySheet.html | 35 ++-- .../itemTables/amountListStoredTable.html | 13 ++ .../itemTables/bulkStoredTable.html | 181 ++++++++---------- .../itemTables/itemTable.qute.html | 25 +++ .../storageBlockSection.qute.html | 1 - 8 files changed, 167 insertions(+), 191 deletions(-) create mode 100644 software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/itemTable.qute.html diff --git a/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/interfaces/rest/Printouts.java b/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/interfaces/rest/Printouts.java index b5f2b1a377..4630cc3c08 100644 --- a/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/interfaces/rest/Printouts.java +++ b/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/interfaces/rest/Printouts.java @@ -1,5 +1,6 @@ package tech.ebp.oqm.core.baseStation.interfaces.rest; +import io.smallrye.common.annotation.Blocking; import jakarta.annotation.security.RolesAllowed; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.RequestScoped; @@ -43,6 +44,7 @@ public class Printouts extends ApiProvider { description = "Bad request given. Data given could not pass validation.", content = @Content(mediaType = "text/plain") ) + @Blocking @RolesAllowed(Roles.INVENTORY_VIEW) @Produces("application/pdf") public Response getSheetPdf( diff --git a/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/PrintoutDataSearchUtilService.java b/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/PrintoutDataSearchUtilService.java index 48108a54e1..aaf181c0a9 100644 --- a/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/PrintoutDataSearchUtilService.java +++ b/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/PrintoutDataSearchUtilService.java @@ -94,7 +94,7 @@ public static class ResultsIterator implements Iterator { private ObjectNode curResults; @NonNull private TriFunction operation; - private boolean first; + private boolean first = true; public ResultsIterator( String auth, @@ -102,7 +102,7 @@ public ResultsIterator( ObjectNode curResults, TriFunction operation ){ - this(auth, db, curResults, operation, false); + this(auth, db, curResults, operation, true); } @Override @@ -121,6 +121,10 @@ public ObjectNode next() { return curResults; } + + public boolean hasResults(){ + return !this.curResults.get("empty").asBoolean(); + } } } diff --git a/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/StorageBlockInventorySheetService.java b/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/StorageBlockInventorySheetService.java index 3a6af4296e..d5d6be3f30 100644 --- a/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/StorageBlockInventorySheetService.java +++ b/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/StorageBlockInventorySheetService.java @@ -38,25 +38,25 @@ @Slf4j @ApplicationScoped public class StorageBlockInventorySheetService extends PrintoutDataService { - + private static final DateTimeFormatter FILENAME_TIMESTAMP_FORMAT = DateTimeFormatter.ofPattern("MM-dd-yyyy_kk-mm"); - + private static final String EXPORT_TEMP_DIR_PREFIX = "oqm-sheets"; - + private static final ConverterProperties CONVERTER_PROPERTIES; - + static { CONVERTER_PROPERTIES = new ConverterProperties() - .setBaseUri(ConfigProvider.getConfig().getValue("runningInfo.baseUrl", String.class)); + .setBaseUri(ConfigProvider.getConfig().getValue("runningInfo.baseUrl", String.class)); } - + @RestClient OqmCoreApiClientService coreApiClientService; - + @Inject @Location("printouts/storageBlockInvSheet/storageBlockInventorySheet.html") Template inventorySheetTemplate; - + private File getTempPdfFile(String name) throws IOException { java.nio.file.Path tempDirPath = Files.createTempDirectory(EXPORT_TEMP_DIR_PREFIX); File tempDir = tempDirPath.toFile(); @@ -65,47 +65,23 @@ private File getTempPdfFile(String name) throws IOException { "oqm_storage_sheet_" + name + "_" + ZonedDateTime.now().format(FILENAME_TIMESTAMP_FORMAT) + ".pdf"; return new File(tempDir, exportFileName); } - + private TemplateInstance getHtmlInventorySheet( + String oqmApiToken, + String oqmDbIdOrName, ObjectNode storageBlock, - ObjectNode childrenSr, - ObjectNode itemsInBlockSr, InventorySheetsOptions options ) { - //TODO:: update these - Predicate simpleAmountFilter = new Predicate() { - @Override - public boolean test(ObjectNode inventoryItem) { - return "AMOUNT_SIMPLE".equals(inventoryItem.get("storageType").asText()); - } - }; - Predicate listAmountFilter = new Predicate() { - @Override - public boolean test(ObjectNode inventoryItem) { - return "AMOUNT_LIST".equals(inventoryItem.get("storageType").asText()); - } - }; - Predicate trackedFilter = new Predicate() { - @Override - public boolean test(ObjectNode inventoryItem) { - return "TRACKED".equals(inventoryItem.get("storageType").asText()); - } - }; - return this.setupBasicPrintoutData(this.inventorySheetTemplate) - .data("simpleAmountFilter", simpleAmountFilter) - .data("listAmountFilter", listAmountFilter) - .data("trackedFilter", trackedFilter) - .data("options", options) - .data("storageBlock", storageBlock) - .data("storageBlockChildrenSearchResults", childrenSr) - .data("searchResult", itemsInBlockSr) + .data("auth", oqmApiToken) + .data("db", oqmDbIdOrName) + .data("options", options) + .data("storageBlock", storageBlock) ; } - + /** - * https://kb.itextpdf.com/home/it7kb/ebooks/itext-7-converting-html-to-pdf-with-pdfhtml https://www.baeldung.com/java-pdf-creation - * https://www.baeldung.com/java-html-to-pdf + * https://kb.itextpdf.com/home/it7kb/ebooks/itext-7-converting-html-to-pdf-with-pdfhtml https://www.baeldung.com/java-pdf-creation https://www.baeldung.com/java-html-to-pdf * * @param entity * @param storageBlockId @@ -122,49 +98,34 @@ public File getPdfInventorySheet( InventorySheetsOptions options ) throws Throwable { log.info("Getting inventory sheet for block {} with options: {}", storageBlockId, options); - + ObjectNode block; - ObjectNode storageBlockChildrenSr; - ObjectNode itemsInBlockSr; { CompletableFuture blockGetFut = this.coreApiClientService.storageBlockGet(oqmApiToken, oqmDbIdOrName, storageBlockId) - .subscribeAsCompletionStage(); - CompletableFuture blockChildrenGetFut = this.coreApiClientService.storageBlockSearch( - oqmApiToken, oqmDbIdOrName, - StorageBlockSearch.builder().isChildOf(storageBlockId).build() - ) - .subscribeAsCompletionStage(); - CompletableFuture itemsInBlockGetFut = this.coreApiClientService.invItemSearch( - oqmApiToken, - oqmDbIdOrName, - InventoryItemSearch.builder().inStorageBlocks(List.of(storageBlockId)).build() - ).subscribeAsCompletionStage(); - + .subscribeAsCompletionStage(); try { block = blockGetFut.join(); - storageBlockChildrenSr = blockChildrenGetFut.join(); - itemsInBlockSr = itemsInBlockGetFut.join(); - } catch(CompletionException e){ + } catch(CompletionException e) { throw e.getCause(); } } - + File outputFile = getTempPdfFile(storageBlockId); - + try ( PdfWriter writer = new PdfWriter(outputFile); ) { PdfDocument doc = new PdfDocument(writer); - + { PageSize size = new PageSize(options.getPageSize().size); - + if (PageOrientation.LANDSCAPE.equals(options.getPageOrientation())) { size = size.rotate(); } doc.setDefaultPageSize(size); } - + doc.getDocumentInfo().addCreationDate(); doc.getDocumentInfo().setCreator("Open QuarterMaster Base Station"); doc.getDocumentInfo().setProducer("Open QuarterMaster Base Station"); @@ -174,9 +135,9 @@ public File getPdfInventorySheet( doc.getDocumentInfo().setKeywords("inventory, sheet, " + storageBlockId); String html = this.getHtmlInventorySheet( + oqmApiToken, + oqmDbIdOrName, block, - storageBlockChildrenSr, - itemsInBlockSr, options ).render(); log.debug("Html generated: {}", html); diff --git a/software/core/oqm-core-base-station/src/main/resources/templates/printouts/storageBlockInvSheet/storageBlockInventorySheet.html b/software/core/oqm-core-base-station/src/main/resources/templates/printouts/storageBlockInvSheet/storageBlockInventorySheet.html index dc1aa0a854..9ad847b4da 100644 --- a/software/core/oqm-core-base-station/src/main/resources/templates/printouts/storageBlockInvSheet/storageBlockInventorySheet.html +++ b/software/core/oqm-core-base-station/src/main/resources/templates/printouts/storageBlockInvSheet/storageBlockInventorySheet.html @@ -1,26 +1,25 @@ -{#include printouts/mainPrintoutTemplate} +{#include printouts/mainPrintoutTemplate generateDatetime=generateDatetime} {#title}{storageBlock.get("labelText").asText()} - Inventory sheet{/title} {#body}

{storageBlock.get("labelText").asText()} - Inventory sheet

- {#printouts/storageBlockTable storageBlockSr=storageBlockChildrenSearchResults options=options}{/printouts/storageBlockTable} -

Total Items: {searchResult.get("numResultsForEntireQuery").asText()}

- {#if searchResult.get("numResults").asInt() == 0} -

- No Items Stored -

- {#else} - {#let curItemList=cdi:JacksonHelpersService.getStreamFromJsonArr(searchResult.get("results")).filter(simpleAmountFilter).toArray()} - {#printouts/storageBlockInventorySheet/amountSimpleStoredTable curItemList=curItemList storageBlock=storageBlock options=options}{/printouts/storageBlockInventorySheet/amountSimpleStoredTable} - {/let} - {#let curItemList=cdi:JacksonHelpersService.getStreamFromJsonArr(searchResult.get("results")).filter(listAmountFilter).toArray()} - {#printouts/storageBlockInventorySheet/amountListStoredTable curItemList=curItemList storageBlock=storageBlock options=options}{/printouts/storageBlockInventorySheet/amountListStoredTable} - {/let} - {#let curItemList=cdi:JacksonHelpersService.getStreamFromJsonArr(searchResult.get("results")).filter(trackedFilter).toArray()} - {#printouts/storageBlockInventorySheet/trackedStoredTable curItemList=curItemList storageBlock=storageBlock options=options}{/printouts/storageBlockInventorySheet/trackedStoredTable} - {/let} - {/if} + {!

Total Items: {searchResult.get("numResultsForEntireQuery").asText()}

TODO!} + +

+ TODO:: table of contents +

+ + {#let bulkItemIt=cdi:PrintoutDataUtilService.getItemInBlockResultsIterator(auth, db, storageBlock.get("id").asText(), 'BULK') amtListItemIt=cdi:PrintoutDataUtilService.getItemInBlockResultsIterator(auth, db, storageBlock.get("id").asText(), 'AMOUNT_LIST') uniqueMultiItemIt=cdi:PrintoutDataUtilService.getItemInBlockResultsIterator(auth, db, storageBlock.get("id").asText(), 'UNIQUE_MULTI') uniqueSingleItemIt=cdi:PrintoutDataUtilService.getItemInBlockResultsIterator(auth, db, storageBlock.get("id").asText(), 'UNIQUE_SINGLE')} +
+

+ Items in Block +

+ + {#printouts/storageBlockInventorySheet/itemTables/bulkStoredTable itemSearchIt=bulkItemIt storageBlock=storageBlock options=options /} + +
+ {/let} {/body} {/include} \ No newline at end of file diff --git a/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/amountListStoredTable.html b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/amountListStoredTable.html index 7465f13f12..13a7ea7652 100644 --- a/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/amountListStoredTable.html +++ b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/amountListStoredTable.html @@ -1,3 +1,16 @@ +{#if itemSearchIt.hasResults()} + + +{/if} + + + + + + + + + {#if curItemList.length > 0}

List Amount Items ({curItemList.length})

diff --git a/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/bulkStoredTable.html b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/bulkStoredTable.html index d70c6f11b9..0d6ab3a3a9 100644 --- a/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/bulkStoredTable.html +++ b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/bulkStoredTable.html @@ -1,111 +1,84 @@ -{#if curItemList.length > 0} -
-

Simple Amount Items ({curItemList.length})

- - - - {#if options.includeNumCol} +{#if itemSearchIt.hasResults()} + {#printouts/storageBlockInventorySheet/itemTables/itemTable options=options itemSearchIt=itemSearchIt} + {#tableHeaderCells} + {#if options.includeNumCol} + + {/if} + {#if options.includeImageCol} + + {/if} - {/if} - {#if options.includeImageCol} - - {/if} - - - {#if options.includeConditionCol} + {#if options.includeConditionCol} + + + {/if} - {/if} - - - - - {#for curItem in curItemList} - {#let curWrapper = curItem.get("storageMap").get(storageBlock.get("id").asText())} - - {#if options.includeNumCol} - - {/if} - {#if options.includeImageCol} - {#if ! curItem.get("imageIds").isEmpty()} - + + + {#for curItem in curResult.get("results")} + + + + + {#let curWrapper = curItem.get("storageMap").get(storageBlock.get("id").asText())} + + {#if options.includeNumCol} + + {/if} + {#if options.includeImageCol} + {#if ! curItem.get("imageIds").isEmpty()} + + {#else} + + {/if} + {/if} + + + + {#if options.includeConditionCol} + + + {/if} + + + {! TODO:: optionally handle keywords, atts, barcode? !} + + {/let} - - {#else} - - {/if} - {/if} - - - - {#if options.includeConditionCol} - - - {/if} - - - {! TODO:: optionally handle keywords, atts, barcode? !} - - - {/let} - {/for} - - - - {#if options.includeNumCol} - - {/if} - {#if options.includeImageCol} - - {/if} - - - {#if options.includeConditionCol} - - - {/if} - - - -
+ # + + Image + - # + Item - Image - - Item - - Amount - - Cond. + Amount + Cond. + + Cond. Notes + - Cond. Notes + Exp.? - Exp.? -
- {curItem_count} - - {#let curImage = imageService.get(curItem.getImageIds().get(0))} - Image for item {curItem.getName()} + {/tableHeaderCells} + {#tableBodyRows} + {#for curResult in itemSearchIt} +
in outer loop: {curResult.get("empty").asText()}
in inner loop
+ {curItem_count} + + {#let curImage = imageService.get(curItem.getImageIds().get(0))} + Image for item {curItem.getName()} + {/let} + + {curItem.get("name").asText()} + {curWrapper.get("total").get("value").asInt()}{curWrapper.get("total").get("unit").get("symbol").asText()}{curWrapper.get("stored").get("condition").asInt()}%{curWrapper.get("stored").get("conditionNotes").asText()} + {#if curWrapper.get("stored").get("expires").asText() != null} + {curWrapper.get("stored").get("notificationStatus").get("expired").asBoolean()} + {/if} +
- {curItem.get("name").asText()} - {curWrapper.get("total").get("value").asInt()}{curWrapper.get("total").get("unit").get("symbol").asText()}{curWrapper.get("stored").get("condition").asInt()}%{curWrapper.get("stored").get("conditionNotes").asText()} - {#if curWrapper.get("stored").get("expires").asText() != null} - {curWrapper.get("stored").get("notificationStatus").get("expired").asBoolean()} - {/if} -
- # - - Image - - Item - - Amount - - Cond. - - Cond. Notes - - Exp.? -
-
-{/if} \ No newline at end of file + {/for} + {/for} + {/tableBodyRows} + {/printouts/storageBlockInventorySheet/itemTables/itemTable} +{/if} diff --git a/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/itemTable.qute.html b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/itemTable.qute.html new file mode 100644 index 0000000000..2656424b4b --- /dev/null +++ b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/itemTable.qute.html @@ -0,0 +1,25 @@ + +
+ + + {#if tableTitle??} + + + + {/if} + + {#insert tableHeaderCells}{/} + + + + {#insert tableBodyRows}{/} + + + + {#insert tableHeaderCells}{/} + + +
+ {tableTitle} +
+
\ No newline at end of file diff --git a/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/storageBlockSection.qute.html b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/storageBlockSection.qute.html index 2287114968..7129fc2450 100644 --- a/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/storageBlockSection.qute.html +++ b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/storageBlockSection.qute.html @@ -12,5 +12,4 @@

{sectionTitle.else(storageBlock.name)}

-
\ No newline at end of file From 331a305fca2937b9e935d61782fc4933cc00982d Mon Sep 17 00:00:00 2001 From: GregJohnStewart Date: Sun, 16 Nov 2025 22:19:27 -0500 Subject: [PATCH 06/66] Core - Base Station - Got bulk item table working for printouts --- .../service/JacksonHelpersService.java | 4 +- .../baseStation/service/QuteDebugService.java | 16 +++ .../PrintoutDataSearchUtilService.java | 54 +++++++-- .../storageBlockInventorySheet.html | 7 +- .../itemTables/bulkStoredTable.html | 104 ++++++++---------- .../itemTables/itemStdHeaderPost.qute.html | 1 + .../itemTables/itemStdHeaderPre.qute.html | 13 +++ .../itemTables/itemStdRowPost.qute.html | 1 + .../itemTables/itemStdRowPre.qute.html | 22 ++++ 9 files changed, 148 insertions(+), 74 deletions(-) create mode 100644 software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/QuteDebugService.java create mode 100644 software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/itemStdHeaderPost.qute.html create mode 100644 software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/itemStdHeaderPre.qute.html create mode 100644 software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/itemStdRowPost.qute.html create mode 100644 software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/itemStdRowPre.qute.html diff --git a/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/JacksonHelpersService.java b/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/JacksonHelpersService.java index fb341c0086..db4c412be8 100644 --- a/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/JacksonHelpersService.java +++ b/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/JacksonHelpersService.java @@ -1,6 +1,8 @@ package tech.ebp.oqm.core.baseStation.service; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Named; @@ -11,7 +13,7 @@ @Named("JacksonHelpersService") public class JacksonHelpersService { - public Stream getStreamFromJsonArr(ArrayNode jsonArr){ + public Stream getStreamFromJsonArr(ArrayNode jsonArr){ return StreamSupport.stream(jsonArr.spliterator(), false); } } diff --git a/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/QuteDebugService.java b/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/QuteDebugService.java new file mode 100644 index 0000000000..fd731b9a0b --- /dev/null +++ b/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/QuteDebugService.java @@ -0,0 +1,16 @@ +package tech.ebp.oqm.core.baseStation.service; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Named; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@ApplicationScoped +@Named("QDS") +public class QuteDebugService { + + public String debug(String message, Object... objects) { + log.debug(message, objects); + return ""; + } +} diff --git a/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/PrintoutDataSearchUtilService.java b/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/PrintoutDataSearchUtilService.java index aaf181c0a9..c8b7cc73ed 100644 --- a/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/PrintoutDataSearchUtilService.java +++ b/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/PrintoutDataSearchUtilService.java @@ -1,7 +1,6 @@ package tech.ebp.oqm.core.baseStation.service.printout; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Named; @@ -13,13 +12,12 @@ import org.eclipse.microprofile.rest.client.inject.RestClient; import tech.ebp.oqm.lib.core.api.quarkus.runtime.restClient.OqmCoreApiClientService; import tech.ebp.oqm.lib.core.api.quarkus.runtime.restClient.searchObjects.InventoryItemSearch; +import tech.ebp.oqm.lib.core.api.quarkus.runtime.restClient.searchObjects.StoredSearch; -import javax.xml.transform.Result; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.concurrent.ExecutionException; -import java.util.function.BiFunction; @Slf4j @Named("PrintoutDataUtilService") @@ -29,7 +27,8 @@ public class PrintoutDataSearchUtilService { @RestClient OqmCoreApiClientService client; - public ObjectNode getItemsInBlock(String auth, String db, String blockId, String storageType) { + public ObjectNode searchItemsInBlock(String auth, String db, String blockId, String storageType) { + log.debug("Getting {} items in block {}", storageType, blockId); try { return this.client.invItemSearch( auth, @@ -45,6 +44,7 @@ public ObjectNode getItemsInBlock(String auth, String db, String blockId, String } public ObjectNode getItemsNextPage(String auth, String db, ObjectNode prevSearchResults){ + log.debug("Getting next items in block"); ObjectNode pagingCalculations = (ObjectNode) prevSearchResults.get("pagingCalculations"); ObjectNode prevQuery = (ObjectNode) prevSearchResults.get("searchObject"); @@ -77,11 +77,32 @@ public Iterator getItemInBlockResultsIterator(String auth, String db return new ResultsIterator( auth, db, - this.getItemsInBlock(auth, db, blockId, storageType), + this.searchItemsInBlock(auth, db, blockId, storageType), this::getItemsNextPage ); } + public ObjectNode getSingleStoredInBlockPage(String auth, String db, String itemId, String blockId){ + ObjectNode results; + try { + results = (ObjectNode) this.client.invItemStoredInBlockSearch(auth, db, itemId, blockId, new StoredSearch()) + .subscribeAsCompletionStage() + .get(); + } catch(InterruptedException|ExecutionException e) { + throw new RuntimeException(e); + } + + int numResults = results.get("numResultsForEntireQuery").asInt(); + if(numResults == 0){ + return null; + } else if (numResults > 1) { + log.warn("Found more than one results for {} block in item {}", blockId, itemId); + return null; + } + + return (ObjectNode) results.get("results").get(0); + } + @AllArgsConstructor(access = AccessLevel.PRIVATE) public static class ResultsIterator implements Iterator { @@ -107,23 +128,34 @@ public ResultsIterator( @Override public boolean hasNext() { - return this.curResults == null || this.curResults.get("pagingCalculations").get("onLastPage").asBoolean(); + boolean onLastPage = this.curResults.get("pagingCalculations").get("onLastPage").asBoolean(); + boolean hasNext = this.first || !onLastPage; + + log.debug("Has next? {} / first: {} on last page: {}", hasNext, this.first, onLastPage); + + + return hasNext; } @Override public ObjectNode next() { - if(first){ - first = false; + if(this.first){ + log.info("Was at first result from search"); + + this.first = false; return curResults; } - + log.info("Getting next results from search"); this.curResults = this.operation.apply(this.auth, this.db, this.curResults); - return curResults; + return this.curResults; } public boolean hasResults(){ - return !this.curResults.get("empty").asBoolean(); + boolean hasResults = !this.curResults.get("empty").asBoolean(); + log.debug("Has results from search? {}", hasResults); + + return hasResults; } } diff --git a/software/core/oqm-core-base-station/src/main/resources/templates/printouts/storageBlockInvSheet/storageBlockInventorySheet.html b/software/core/oqm-core-base-station/src/main/resources/templates/printouts/storageBlockInvSheet/storageBlockInventorySheet.html index 9ad847b4da..f910401bd5 100644 --- a/software/core/oqm-core-base-station/src/main/resources/templates/printouts/storageBlockInvSheet/storageBlockInventorySheet.html +++ b/software/core/oqm-core-base-station/src/main/resources/templates/printouts/storageBlockInvSheet/storageBlockInventorySheet.html @@ -17,9 +17,12 @@

Items in Block

- {#printouts/storageBlockInventorySheet/itemTables/bulkStoredTable itemSearchIt=bulkItemIt storageBlock=storageBlock options=options /} + {#printouts/storageBlockInventorySheet/itemTables/bulkStoredTable auth=auth db=db itemSearchIt=bulkItemIt storageBlock=storageBlock options=options /} + {cdi:QDS.debug("done items in block")} {/let} + {cdi:QDS.debug("done items in block section")} {/body} -{/include} \ No newline at end of file +{/include} +{cdi:QDS.debug("done sheet")} \ No newline at end of file diff --git a/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/bulkStoredTable.html b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/bulkStoredTable.html index 0d6ab3a3a9..17a4ca46ae 100644 --- a/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/bulkStoredTable.html +++ b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/bulkStoredTable.html @@ -1,84 +1,68 @@ {#if itemSearchIt.hasResults()} - {#printouts/storageBlockInventorySheet/itemTables/itemTable options=options itemSearchIt=itemSearchIt} + {#printouts/storageBlockInventorySheet/itemTables/itemTable auth=auth db=db options=options itemSearchIt=itemSearchIt storageBlock=storageBlock} {#tableHeaderCells} - {#if options.includeNumCol} - - # - - {/if} - {#if options.includeImageCol} - - Image - - {/if} - - Item - + + {#printouts/storageBlockInventorySheet/itemTables/itemStdHeaderPre options=options /} Amount {#if options.includeConditionCol} - - Cond. - - - Cond. Notes - + + Cond. + + + Cond. Notes + {/if} Exp.? + + {#printouts/storageBlockInventorySheet/itemTables/itemStdHeaderPost options=options /} + {/tableHeaderCells} {#tableBodyRows} {#for curResult in itemSearchIt} - - in outer loop: {curResult.get("empty").asText()} - + {#let startIndex=curResult.get("pagingCalculations").get("pageResultIndexStart").asInt()} {#for curItem in curResult.get("results")} - - - in inner loop - - {#let curWrapper = curItem.get("storageMap").get(storageBlock.get("id").asText())} + {#let blockStats = curItem.get("stats").get("storageBlockStats").get(storageBlock.get("id").asText())} - {#if options.includeNumCol} - - {curItem_count} - - {/if} - {#if options.includeImageCol} - {#if ! curItem.get("imageIds").isEmpty()} - - {#let curImage = imageService.get(curItem.getImageIds().get(0))} - Image for item {curItem.getName()} - {/let} - - {#else} - - {/if} - {/if} - - {curItem.get("name").asText()} - - {curWrapper.get("total").get("value").asInt()}{curWrapper.get("total").get("unit").get("symbol").asText()} + {#printouts/storageBlockInventorySheet/itemTables/itemStdRowPre options=options item=curItem resultNo=(curItem_index + startIndex) /} + + {blockStats.get("total").get("value").asInt()}{blockStats.get("total").get("unit").get("symbol").asText()} - {#if options.includeConditionCol} - {curWrapper.get("stored").get("condition").asInt()}% - {curWrapper.get("stored").get("conditionNotes").asText()} - {/if} - - {#if curWrapper.get("stored").get("expires").asText() != null} - {curWrapper.get("stored").get("notificationStatus").get("expired").asBoolean()} + {#let stored=cdi:PrintoutDataUtilService.getSingleStoredInBlockPage(auth, db, curItem.get("id").asText(), storageBlock.get("id").asText())} + {#if options.includeConditionCol} + + {#if stored??} + {#if !stored.get("condition").isNull()} + {stored.get("condition").asText()}% + {/if} + {/if} + + + {#if stored??} + {#if !stored.get("conditionNotes").isNull()} + {stored.get("conditionNotes").asText()} + {/if} + {/if} + {/if} - + + {#if stored??} + {#if !stored.get("expires").isNull()} + {cdi:DateTimeService.formatForUi(stored.get("expires").asText())} + {/if} + {/if} + + + {/let} - {! TODO:: optionally handle keywords, atts, barcode? !} - + {#printouts/storageBlockInventorySheet/itemTables/itemStdRowPost options=options item=curItem /} {/let} {/for} {/for} {/tableBodyRows} {/printouts/storageBlockInventorySheet/itemTables/itemTable} -{/if} +{/if} \ No newline at end of file diff --git a/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/itemStdHeaderPost.qute.html b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/itemStdHeaderPost.qute.html new file mode 100644 index 0000000000..65c49b65f7 --- /dev/null +++ b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/itemStdHeaderPost.qute.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/itemStdHeaderPre.qute.html b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/itemStdHeaderPre.qute.html new file mode 100644 index 0000000000..4685d10316 --- /dev/null +++ b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/itemStdHeaderPre.qute.html @@ -0,0 +1,13 @@ +{#if options.includeNumCol} + + # + +{/if} +{#if options.includeImageCol} + + Image + +{/if} + + Item + \ No newline at end of file diff --git a/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/itemStdRowPost.qute.html b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/itemStdRowPost.qute.html new file mode 100644 index 0000000000..65c49b65f7 --- /dev/null +++ b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/itemStdRowPost.qute.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/itemStdRowPre.qute.html b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/itemStdRowPre.qute.html new file mode 100644 index 0000000000..4dab3373a0 --- /dev/null +++ b/software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/itemStdRowPre.qute.html @@ -0,0 +1,22 @@ +{#if options.includeNumCol} + + {resultNo} + +{/if} +{#if options.includeImageCol} + {#if ! item.get("imageIds").isEmpty()} + + {!TODO:: this !} + {!{#let curImage = imageService.get(item.getImageIds().get(0))}!} + {!Image for item {item.get(!} + {!{/let}!} + + {#else} + + {/if} +{/if} + + {item.get("name").asText()} + + From df40ab5bfb83ef3932fdfaec6c1ba46ed628f459 Mon Sep 17 00:00:00 2001 From: GregJohnStewart Date: Sun, 16 Nov 2025 22:20:06 -0500 Subject: [PATCH 07/66] Core - API - fixed storage block stats in new item --- .../storage/items/stored/stats/StatsWithTotalContaining.java | 4 +++- .../object/storage/items/stored/stats/StoredInBlockStats.java | 2 +- .../ebp/oqm/core/api/service/mongo/InventoryItemService.java | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/object/storage/items/stored/stats/StatsWithTotalContaining.java b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/object/storage/items/stored/stats/StatsWithTotalContaining.java index e4f1c6eddf..3c14f2d6fd 100644 --- a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/object/storage/items/stored/stats/StatsWithTotalContaining.java +++ b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/object/storage/items/stored/stats/StatsWithTotalContaining.java @@ -4,6 +4,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import lombok.NonNull; import lombok.ToString; import lombok.experimental.SuperBuilder; import tech.units.indriya.quantity.Quantities; @@ -23,6 +24,7 @@ public StatsWithTotalContaining(Unit unit){ this(); this.total = Quantities.getQuantity(0, unit); } - + +// @NonNull //TODO:: this private Quantity total; } diff --git a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/object/storage/items/stored/stats/StoredInBlockStats.java b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/object/storage/items/stored/stats/StoredInBlockStats.java index d1b24c8f3b..701ce213b7 100644 --- a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/object/storage/items/stored/stats/StoredInBlockStats.java +++ b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/object/storage/items/stored/stats/StoredInBlockStats.java @@ -19,7 +19,7 @@ public class StoredInBlockStats extends StatsWithTotalContaining { public StoredInBlockStats(Unit unit){ super(unit); } - + @lombok.Builder.Default private boolean hasStored = false; } diff --git a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/InventoryItemService.java b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/InventoryItemService.java index 5d7dc33d53..4f97134647 100644 --- a/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/InventoryItemService.java +++ b/software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/InventoryItemService.java @@ -160,6 +160,7 @@ public void ensureObjectValid(String oqmDbIdOrName, boolean newObject, Inventory throw new ValidationException("New unit not compatible with current unit."); } } else { + //TODO:: move to massage //if new item, and stats are null, set new stats. No stored should exist so this should be representative enough to start. Maybe generate stats? if (newOrChangedObject.getStats() == null) { newOrChangedObject.setStats( @@ -189,6 +190,7 @@ public InvItemCollectionStats getStats(String oqmDbIdOrName) { @Override @WithSpan public ObjectId add(String oqmDbIdOrName, ClientSession session, @NonNull @Valid InventoryItem item, InteractingEntity entity, HistoryDetail... details) { + //TODO:: move to massage item.setStats( //Build simple stats on the premise of not having any stored items ItemStoredStats.builder() .total((Quantities.getQuantity(0, item.getUnit()))) @@ -199,7 +201,7 @@ public ObjectId add(String oqmDbIdOrName, ClientSession session, @NonNull @Valid item.getStorageBlocks().stream() .collect(Collectors.toMap( Function.identity(), - (storageBlockId)->StoredInBlockStats.builder().build() + (storageBlockId)->new StoredInBlockStats(item.getUnit()) )) ) .build() From 9d13000c5edc512af69314ffaf44b66a212d4c3b Mon Sep 17 00:00:00 2001 From: GregJohnStewart Date: Tue, 18 Nov 2025 14:57:59 -0500 Subject: [PATCH 08/66] Core - Base Station - Iconography in printouts and work towards amount list tables --- .../PrintoutDataSearchUtilService.java | 23 +- .../printouts/mainPrintoutTemplate.html | 2 +- .../storageBlockInventorySheet.html | 11 +- .../itemTables/amountListStoredTable.html | 196 ++++++------------ .../itemTables/itemTable.qute.html | 2 +- .../itemTables/storedCells.qute.html | 3 + 6 files changed, 101 insertions(+), 136 deletions(-) create mode 100644 software/core/oqm-core-base-station/src/main/resources/templates/tags/printouts/storageBlockInventorySheet/itemTables/storedCells.qute.html diff --git a/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/PrintoutDataSearchUtilService.java b/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/PrintoutDataSearchUtilService.java index c8b7cc73ed..077d861da6 100644 --- a/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/PrintoutDataSearchUtilService.java +++ b/software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/printout/PrintoutDataSearchUtilService.java @@ -6,6 +6,7 @@ import jakarta.inject.Named; import lombok.AccessLevel; import lombok.AllArgsConstructor; +import lombok.Getter; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.function.TriFunction; @@ -73,7 +74,7 @@ public ObjectNode getItemsNextPage(String auth, String db, ObjectNode prevSearch } } - public Iterator getItemInBlockResultsIterator(String auth, String db, String blockId, String storageType){ + public ResultsIterator getItemInBlockResultsIterator(String auth, String db, String blockId, String storageType){ return new ResultsIterator( auth, db, @@ -103,6 +104,25 @@ public ObjectNode getSingleStoredInBlockPage(String auth, String db, String item return (ObjectNode) results.get("results").get(0); } + public ObjectNode searchStoredInBlock(String auth, String db, String itemId, String blockId){ + try { + return (ObjectNode) this.client.invItemStoredInBlockSearch(auth, db, itemId, blockId, new StoredSearch()) + .subscribeAsCompletionStage() + .get(); + } catch(InterruptedException|ExecutionException e) { + throw new RuntimeException(e); + } + } + + public ResultsIterator searchStoredInBlockResultsIterator(String auth, String db, String itemId, String blockId){ + return new ResultsIterator( + auth, + db, + this.searchStoredInBlock(auth, db, itemId, blockId), + this::getItemsNextPage + ); + } + @AllArgsConstructor(access = AccessLevel.PRIVATE) public static class ResultsIterator implements Iterator { @@ -111,6 +131,7 @@ public static class ResultsIterator implements Iterator { @NonNull private String db; + @Getter @NonNull private ObjectNode curResults; @NonNull diff --git a/software/core/oqm-core-base-station/src/main/resources/templates/printouts/mainPrintoutTemplate.html b/software/core/oqm-core-base-station/src/main/resources/templates/printouts/mainPrintoutTemplate.html index c9913161e9..daffabb0c4 100644 --- a/software/core/oqm-core-base-station/src/main/resources/templates/printouts/mainPrintoutTemplate.html +++ b/software/core/oqm-core-base-station/src/main/resources/templates/printouts/mainPrintoutTemplate.html @@ -10,7 +10,7 @@