diff --git a/code/web/RecordDrivers/GroupedWorkDriver.php b/code/web/RecordDrivers/GroupedWorkDriver.php index 3a0b11263d..7ed00684c3 100644 --- a/code/web/RecordDrivers/GroupedWorkDriver.php +++ b/code/web/RecordDrivers/GroupedWorkDriver.php @@ -3138,7 +3138,7 @@ private function getRawItemDataFromDB($uniqueItemIds) { $uniqueItemIdsString = implode(',', $uniqueItemIds); $scopeQuery = "SELECT grouped_work_record_items.id as groupedWorkItemId, available, holdable, inLibraryUseOnly, locationOwnedScopes, libraryOwnedScopes, groupedStatusTbl.status as groupedStatus, statusTbl.status as status, grouped_work_record_items.groupedWorkRecordId, grouped_work_record_items.groupedWorkVariationId, grouped_work_record_items.itemId, indexed_call_number.callNumber, indexed_shelf_location.shelfLocation, numCopies, isOrderItem, dateAdded, - indexed_location_code.locationCode, indexed_sub_location_code.subLocationCode, lastCheckInDate, isVirtual + indexed_location_code.locationCode, indexed_sub_location_code.subLocationCode, lastCheckInDate, isVirtual, groupedWorkRecordEdition.edition as 'edition' FROM grouped_work_record_items LEFT JOIN indexed_status as groupedStatusTbl on groupedStatusId = groupedStatusTbl.id LEFT JOIN indexed_status as statusTbl on statusId = statusTbl.id @@ -3146,6 +3146,10 @@ private function getRawItemDataFromDB($uniqueItemIds) { LEFT JOIN indexed_shelf_location ON shelfLocationId = indexed_shelf_location.id LEFT JOIN indexed_location_code on locationCodeId = indexed_location_code.id LEFT JOIN indexed_sub_location_code on subLocationCodeId = indexed_sub_location_code.id + LEFT JOIN ( + SELECT indexed_edition.edition, grouped_work_records.id, grouped_work_records.editionId from grouped_work_records + LEFT JOIN indexed_edition on grouped_work_records.editionId = indexed_edition.id + ) as groupedWorkRecordEdition on groupedWorkRecordId = groupedWorkRecordEdition.id where grouped_work_record_items.id IN ($uniqueItemIdsString)"; $results = $aspen_db->query($scopeQuery, PDO::FETCH_ASSOC); $scopedItems = $results->fetchAll(); diff --git a/code/web/interface/themes/responsive/GroupedWork/copyDetails.tpl b/code/web/interface/themes/responsive/GroupedWork/copyDetails.tpl index d18a11c6ba..7e356d7e3a 100644 --- a/code/web/interface/themes/responsive/GroupedWork/copyDetails.tpl +++ b/code/web/interface/themes/responsive/GroupedWork/copyDetails.tpl @@ -1,35 +1,99 @@ {strip} -
+ {if !empty($separateItemsByEditionInWhereIsIt) && $separateItemsByEditionInWhereIsIt == 1 && !empty($summaryList)} + + {else} + + {/if} {/strip} \ No newline at end of file diff --git a/code/web/interface/themes/responsive/css/main.css b/code/web/interface/themes/responsive/css/main.css index eaaf5699ba..f9f2000999 100644 --- a/code/web/interface/themes/responsive/css/main.css +++ b/code/web/interface/themes/responsive/css/main.css @@ -10382,6 +10382,9 @@ a.browse-thumbnail.active { .related_record_status.availableOther { color: #c62828; } +.itemSummaryTable tr.sectionHeader { + border-top: solid #505050 4px; +} .itemSummaryTable tr.available { font-weight: bold; } diff --git a/code/web/interface/themes/responsive/css/results-list.less b/code/web/interface/themes/responsive/css/results-list.less index 4d5ece28de..77716e2826 100644 --- a/code/web/interface/themes/responsive/css/results-list.less +++ b/code/web/interface/themes/responsive/css/results-list.less @@ -232,6 +232,9 @@ .related_record_status.availableOther{ color: #c62828; } +.itemSummaryTable tr.sectionHeader { + border-top: solid #505050 4px; +} .itemSummaryTable tr.available{ font-weight: bold; } diff --git a/code/web/release_notes/24.10.00.MD b/code/web/release_notes/24.10.00.MD index 31d480015b..2dabb46b28 100644 --- a/code/web/release_notes/24.10.00.MD +++ b/code/web/release_notes/24.10.00.MD @@ -107,8 +107,8 @@ - When the cron runs for the first time after a library enables cookieStorageConsent, users who have not opted in to localAnalyticsTracking will have their data cleared from the user_usage statistics tables. (*AB*) // chloe - PTFS-E -## Aspen Usage Data -- added usage graphs and raw data tables for the Axis360, Aspen API, and SideLoads usage dashboards, all of which include a CSV download feature. (*CZ*) +- Added a 'Show Editions in the Where is it popup' setting to Aspen Administration > Catalog/Grouped Works > Grouped Work Display > ... > Searching> Search Results, which groups copies in the 'Where is it?' popup by edition, displaying each edition's name and book cover thumbnail in the popup (visibility toggled on/off by 'Show Covers for Editions') (*CZ*)## Aspen Usage Data +- Added usage graphs and raw data tables for the Axis360, Aspen API, and SideLoads usage dashboards, all of which include a CSV download feature. (*CZ*) // pedro - PTFS-E // lucas - Theke diff --git a/code/web/services/GroupedWork/AJAX.php b/code/web/services/GroupedWork/AJAX.php index a7fafbd316..e65fe18f4c 100644 --- a/code/web/services/GroupedWork/AJAX.php +++ b/code/web/services/GroupedWork/AJAX.php @@ -1535,13 +1535,14 @@ function uploadCoverByURL() : array { } /** @noinspection PhpUnused */ - function getCopyDetails() : array { + function getCopyDetails(): array { global $interface; require_once ROOT_DIR . '/RecordDrivers/GroupedWorkDriver.php'; $id = $_REQUEST['id']; $recordDriver = new GroupedWorkDriver($id); $interface->assign('recordDriver', $recordDriver); + $separateItemsByEditionInWhereIsIt = $interface->getVariable('separateItemsByEditionInWhereIsIt'); $recordId = $_REQUEST['recordId']; $selectedFormat = urldecode($_REQUEST['format']); @@ -1555,33 +1556,77 @@ function getCopyDetails() : array { $interface->assign('itemSummaryId', $id); $interface->assign('relatedManifestation', $relatedManifestation); - if ($recordId != $id) { - $record = $recordDriver->getRelatedRecord($recordId); - $summary = null; - if ($record != null) { - foreach ($relatedManifestation->getVariations() as $variation) { - foreach ($variation->getRecords() as $recordWithVariation) { - if ($recordWithVariation->id == $recordId) { - $summary = $recordWithVariation->getItemSummary(); + // show the editions and group the copies at given locations by edition + if (!empty($separateItemsByEditionInWhereIsIt) && $separateItemsByEditionInWhereIsIt == 1) { + $summaryList = []; + if ($recordId != $id) { + $record = $recordDriver->getRelatedRecord($recordId); + $summary = null; + if ($record != null) { + foreach ($relatedManifestation->getVariations() as $variation) { + foreach ($variation->getRecords() as $recordWithVariation) { + if ($recordWithVariation->id == $recordId) { + $item = []; + $item['summary'] = $recordWithVariation->getItemSummary(); + $item['editionCoverUrl'] = $recordWithVariation->getBookcoverUrl('small'); + $item['edition'] = $recordWithVariation->edition; + array_push($summaryList, $item); + break; + } + } + if (!empty($summary)) { break; } } - if (!empty($summary)) { - break; + } else { + // if there is no recordId, then do not attempt to look for edition information, and only display summary information + foreach ($relatedManifestation->getVariations() as $variation) { + if ($recordId == $id . '_' . $variation->label) { + $summary = $variation->getItemSummary(); + break; + } } } } else { - foreach ($relatedManifestation->getVariations() as $variation) { - if ($recordId == $id . '_' . $variation->label) { - $summary = $variation->getItemSummary(); - break; - } + foreach ($recordDriver->getRelatedRecords() as $relatedRecord) { + $item = []; + $item['summary'] = $relatedRecord->getItemSummary(); + $item['editionCoverUrl'] = $relatedRecord->getBookcoverUrl('small'); + $item['edition'] = $relatedRecord->edition; + array_push($summaryList, $item); } } + $interface->assign('summaryList', $summaryList); } else { - $summary = $relatedManifestation->getItemSummary(); + // only group copies by location, irrespective of edition (default) + if ($recordId != $id) { + $record = $recordDriver->getRelatedRecord($recordId); + $summary = null; + if ($record != null) { + foreach ($relatedManifestation->getVariations() as $variation) { + foreach ($variation->getRecords() as $recordWithVariation) { + if ($recordWithVariation->id == $recordId) { + $summary = $recordWithVariation->getItemSummary(); + break; + } + } + if (!empty($summary)) { + break; + } + } + } else { + foreach ($relatedManifestation->getVariations() as $variation) { + if ($recordId == $id . '_' . $variation->label) { + $summary = $variation->getItemSummary(); + break; + } + } + } + } else { + $summary = $relatedManifestation->getItemSummary(); + } + $interface->assign('summary', $summary); } - $interface->assign('summary', $summary); $modalBody = $interface->fetch('GroupedWork/copyDetails.tpl'); return [ diff --git a/code/web/sys/DBMaintenance/version_updates/24.10.00.php b/code/web/sys/DBMaintenance/version_updates/24.10.00.php index 117fe3172d..d7722be316 100644 --- a/code/web/sys/DBMaintenance/version_updates/24.10.00.php +++ b/code/web/sys/DBMaintenance/version_updates/24.10.00.php @@ -167,6 +167,14 @@ function getUpdates24_10_00(): array { ], //chloe - PTFS-Europe + 'add_separate_items_by_edition_in_where_is_it' => [ + 'title' => 'Add Separate Items By Edition in Where is it', + 'description' => 'Add the separateItemsByEditionInWhereIsIt column to grouped_work_display_settings in order for the "Show Editions in the Where is it popup" setting to be added', + 'continueOnError' => true, + 'sql' => [ + 'ALTER TABLE grouped_work_display_settings ADD COLUMN separateItemsByEditionInWhereIsIt TINYINT(1) DEFAULT 0', + ], + ], // add_separate_items_by_edition_in_where_is_it //pedro - PTFS-Europe diff --git a/code/web/sys/Grouping/GroupedWorkDisplaySetting.php b/code/web/sys/Grouping/GroupedWorkDisplaySetting.php index 5593f80e02..cec570d4b8 100644 --- a/code/web/sys/Grouping/GroupedWorkDisplaySetting.php +++ b/code/web/sys/Grouping/GroupedWorkDisplaySetting.php @@ -31,6 +31,7 @@ class GroupedWorkDisplaySetting extends DataObject { public $alwaysFlagNewTitles; public $showRelatedRecordLabels; public $showEditionCovers; + public $separateItemsByEditionInWhereIsIt; //Contents of search public $includeOutOfSystemExternalLinks; @@ -266,6 +267,14 @@ static function getObjectStructure($context = ''): array { 'default' => true, 'hideInLists' => true, ], + 'separateItemsByEditionInWhereIsIt' => [ + 'property' => 'separateItemsByEditionInWhereIsIt', + 'type' => 'checkbox', + 'label' => 'Show Editions in the Where is it popup', + 'description' => 'Turn on to divide the Where is it popup table into edition sections so that edition information can be displayed. If Show Covers for Editions is toggled on, also include edition covers as thumbnails.', + 'default' => false, + 'hideInLists' => true + ] ], ], 'searchFacetsSection' => [ @@ -921,6 +930,7 @@ public static function getDefaultDisplaySettings() : GroupedWorkDisplaySetting { $defaultDisplaySettings->alwaysFlagNewTitles = false; $defaultDisplaySettings->showRelatedRecordLabels = true; $defaultDisplaySettings->showEditionCovers = true; + $defaultDisplaySettings->separateItemsByEditionInWhereIsIt = false; $defaultDisplaySettings->availabilityToggleLabelSuperScope = 'Entire Collection'; $defaultDisplaySettings->availabilityToggleLabelLocal = ''; $defaultDisplaySettings->availabilityToggleLabelAvailable = 'Available Now'; diff --git a/code/web/sys/Grouping/Item.php b/code/web/sys/Grouping/Item.php index ba33343575..4d59020370 100644 --- a/code/web/sys/Grouping/Item.php +++ b/code/web/sys/Grouping/Item.php @@ -25,6 +25,8 @@ class Grouping_Item { public $locallyOwned; /** @var bool */ public $holdable; + /** @var string */ + public $edition; /** * @var bool */ @@ -81,6 +83,7 @@ public function __construct($itemDetails, $scopingInfo, $searchLocation, $librar $this->isOrderItem = (bool)$itemDetails['isOrderItem']; $this->isEContent = $itemDetails['isEcontent']; $this->eContentSource = $itemDetails['eContentSource']; + $this->edition = $itemDetails['edition']; if ($this->isEContent && !empty($itemDetails['localUrl'])) { $this->_relatedUrls[] = [ 'source' => $itemDetails['eContentSource'], @@ -294,6 +297,7 @@ public function getSummary(): array { 'subLocation' => $this->subLocation, 'itemId' => $this->itemId, 'variationId' => $this->variationId, + 'edition' => $this->edition, 'actions' => $this->getActions(), ]; return $itemSummaryInfo; diff --git a/code/web/sys/Interface.php b/code/web/sys/Interface.php index 885de79b28..63cded7ab5 100644 --- a/code/web/sys/Interface.php +++ b/code/web/sys/Interface.php @@ -627,6 +627,7 @@ function loadDisplayOptions($fromBookCoverProcessing = false) { $this->assign('alwaysShowSearchResultsMainDetails', $groupedWorkDisplaySettings->alwaysShowSearchResultsMainDetails); $this->assign('showRelatedRecordLabels', $groupedWorkDisplaySettings->showRelatedRecordLabels); $this->assign('showEditionCovers', $groupedWorkDisplaySettings->showEditionCovers); + $this->assign('separateItemsByEditionInWhereIsIt', $groupedWorkDisplaySettings->separateItemsByEditionInWhereIsIt); $this->assign('showExpirationWarnings', $library->showExpirationWarnings); $this->assign('expiredMessage', $library->expiredMessage); $this->assign('expirationNearMessage', $library->expirationNearMessage); @@ -682,6 +683,7 @@ function loadDisplayOptions($fromBookCoverProcessing = false) { $this->assign('showStandardReviews', $groupedWorkDisplaySettings->showStandardReviews); $this->assign('showRelatedRecordLabels', $groupedWorkDisplaySettings->showRelatedRecordLabels); $this->assign('showEditionCovers', $groupedWorkDisplaySettings->showEditionCovers); + $this->assign('separateItemsByEditionInWhereIsIt', $groupedWorkDisplaySettings->separateItemsByEditionInWhereIsIt); } else { // library only $groupedWorkDisplaySettings = $library->getGroupedWorkDisplaySettings(); $this->assign('showFavorites', $library->showFavorites); @@ -697,6 +699,7 @@ function loadDisplayOptions($fromBookCoverProcessing = false) { $this->assign('showStandardReviews', $groupedWorkDisplaySettings->showStandardReviews); $this->assign('showRelatedRecordLabels', $groupedWorkDisplaySettings->showRelatedRecordLabels); $this->assign('showEditionCovers', $groupedWorkDisplaySettings->showEditionCovers); + $this->assign('separateItemsByEditionInWhereIsIt', $groupedWorkDisplaySettings->separateItemsByEditionInWhereIsIt); } if ($showStaffView == 2) { $showStaffView = UserAccount::isStaff();