From 9c2bf86fea950268afdba8647d339cec456c395e Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Mon, 4 Nov 2024 16:47:38 +0200 Subject: [PATCH 01/24] Paging for exporting transaction history until work processor is implemented --- local/languages/finna/en-gb.ini | 2 +- local/languages/finna/fi.ini | 2 +- local/languages/finna/sv.ini | 2 +- .../Finna/Controller/MyResearchController.php | 98 +++++++++---------- .../finna2/templates/checkouts/history.phtml | 21 +++- 5 files changed, 68 insertions(+), 57 deletions(-) diff --git a/local/languages/finna/en-gb.ini b/local/languages/finna/en-gb.ini index 6ee91623ff4..4ac27d2f4fc 100644 --- a/local/languages/finna/en-gb.ini +++ b/local/languages/finna/en-gb.ini @@ -599,7 +599,7 @@ list_order_saved = "Sort order saved" list-tags-info = "Add a new keyword" Loading = "Loading" Loan Details = "Loan Details" -loan_history_download = "Export all" +loan_history_download = "Export all in page" loan_history_download_csv = "Export CSV" loan_history_download_ods = "Export OpenOffice (ods)" loan_history_download_xlsx = "Export Excel (xlsx)" diff --git a/local/languages/finna/fi.ini b/local/languages/finna/fi.ini index 49457eb14fe..66e17185bfb 100644 --- a/local/languages/finna/fi.ini +++ b/local/languages/finna/fi.ini @@ -589,7 +589,7 @@ list_order_saved = "Järjestys tallennettu" list-tags-info = "Lisää uusi avainsana" Loading = "Ladataan" Loan Details = "Lainan tiedot" -loan_history_download = "Vie kaikki" +loan_history_download = "Vie kaikki sivulta" loan_history_download_csv = "Vie CSV" loan_history_download_ods = "Vie OpenOffice (ods)" loan_history_download_xlsx = "Vie Excel (xlsx)" diff --git a/local/languages/finna/sv.ini b/local/languages/finna/sv.ini index fd87e1c5ade..e3e84c7b4a9 100644 --- a/local/languages/finna/sv.ini +++ b/local/languages/finna/sv.ini @@ -587,7 +587,7 @@ list_order_saved = "Sortering sparad" list-tags-info = "Lägg till nytt nyckelord" Loading = "Laddar" Loan Details = "Information om lånet" -loan_history_download = "Exportera alla" +loan_history_download = "Exportera alla på sidan" loan_history_download_csv = "Exportera CSV" loan_history_download_ods = "Exportera OpenOffice (ods)" loan_history_download_xlsx = "Exportera Excel (xlsx)" diff --git a/module/Finna/src/Finna/Controller/MyResearchController.php b/module/Finna/src/Finna/Controller/MyResearchController.php index b5e9fa9fca0..9be2eb547c9 100644 --- a/module/Finna/src/Finna/Controller/MyResearchController.php +++ b/module/Finna/src/Finna/Controller/MyResearchController.php @@ -1356,8 +1356,10 @@ public function downloadLoanHistoryAction() throw new \Exception('Invalid parameters.'); } + $page = (int)$this->params()->fromQuery('page', 1); + $sort = $this->params()->fromQuery('sort', ''); $recordLoader = $this->serviceLocator->get(\VuFind\Record\Loader::class); - $page = 1; + $config = $this->getConfig(); try { $tmp = fopen('php://temp/maxmemory:' . (5 * 1024 * 1024), 'r+'); $header = [ @@ -1377,55 +1379,50 @@ public function downloadLoanHistoryAction() if ('xlsx' === $fileFormat) { Cell::setValueBinder(new AdvancedValueBinder()); } - do { - // Try to use large page size, but take ILS limits into account - $pageOptions = $this->getPaginationHelper() - ->getOptions($page, null, 1000, $functionConfig); - $result = $catalog - ->getMyTransactionHistory($patron, $pageOptions['ilsParams']); - - if (isset($result['success']) && !$result['success']) { - $this->flashMessenger()->addErrorMessage($result['status']); - return $this->redirect()->toRoute('checkouts-history'); - } + $pageOptions = $this->getPaginationHelper()->getOptions( + $page, + $sort, + $config->Catalog->historic_loan_page_size ?? 50, + $functionConfig + ); + $result = $catalog->getMyTransactionHistory($patron, $pageOptions['ilsParams']); - $ids = []; - foreach ($result['transactions'] as $current) { - $id = $current['id'] ?? ''; - $source = $current['source'] ?? DEFAULT_SEARCH_BACKEND; - $ids[] = compact('id', 'source'); - } - $records = $recordLoader->loadBatch($ids, true); - foreach ($result['transactions'] as $i => $current) { - $driver = $records[$i]; - $format = $driver->getFormats(); - $format = end($format); - $author = $driver->tryMethod('getNonPresenterAuthors'); - - $loan = []; - $loan[] = $current['title'] ?? $driver->getTitle() ?? ''; - $loan[] = $this->translate($format); - $loan[] = $author[0]['name'] ?? ''; - $loan[] = $current['publication_year'] ?? ''; - $loan[] = empty($current['institution_name']) - ? '' - : $this->translateWithPrefix('location_', $current['institution_name']); - $loan[] = empty($current['borrowingLocation']) - ? '' - : $this->translateWithPrefix('location_', $current['borrowingLocation']); - $loan[] = $current['checkoutDate'] ?? ''; - $loan[] = $current['returnDate'] ?? ''; - $loan[] = $current['dueDate'] ?? ''; - - $nextRow = $worksheet->getHighestRow() + 1; - $worksheet->fromArray($loan, null, 'A' . (string)$nextRow); - } + if (isset($result['success']) && !$result['success']) { + $this->flashMessenger()->addErrorMessage($result['status']); + return $this->redirect()->toRoute('checkouts-history'); + } - $pageEnd = $pageOptions['ilsPaging'] - ? ceil($result['count'] / $pageOptions['limit']) - : 1; - $page++; - } while ($page <= $pageEnd); + $ids = []; + foreach ($result['transactions'] as $current) { + $id = $current['id'] ?? ''; + $source = $current['source'] ?? DEFAULT_SEARCH_BACKEND; + $ids[] = compact('id', 'source'); + } + $records = $recordLoader->loadBatch($ids, true); + foreach ($result['transactions'] as $i => $current) { + $driver = $records[$i]; + $format = $driver->getFormats(); + $format = end($format); + $author = $driver->tryMethod('getNonPresenterAuthors'); + + $loan = []; + $loan[] = $current['title'] ?? $driver->getTitle() ?? ''; + $loan[] = $this->translate($format); + $loan[] = $author[0]['name'] ?? ''; + $loan[] = $current['publication_year'] ?? ''; + $loan[] = empty($current['institution_name']) + ? '' + : $this->translateWithPrefix('location_', $current['institution_name']); + $loan[] = empty($current['borrowingLocation']) + ? '' + : $this->translateWithPrefix('location_', $current['borrowingLocation']); + $loan[] = $current['checkoutDate'] ?? ''; + $loan[] = $current['returnDate'] ?? ''; + $loan[] = $current['dueDate'] ?? ''; + + $nextRow = $worksheet->getHighestRow() + 1; + $worksheet->fromArray($loan, null, 'A' . (string)$nextRow); + } if ('xlsx' === $fileFormat) { $worksheet->getStyle('G2:I' . $worksheet->getHighestRow()) ->getNumberFormat() @@ -1442,11 +1439,12 @@ public function downloadLoanHistoryAction() ); $writer = new $this->exportFormats[$fileFormat]['writer']($spreadsheet); $writer->save($tmp); - + $fileName = implode('-', ['finna-loan-history-page', $page, $sort,]); + $fileName = str_replace(' ', '-', $fileName) . '.' . $fileFormat; $response->getHeaders() ->addHeaderLine( 'Content-Disposition', - 'attachment; filename="finna-loan-history.' . $fileFormat . '"' + 'attachment; filename="' . $fileName . '"' ); rewind($tmp); diff --git a/themes/finna2/templates/checkouts/history.phtml b/themes/finna2/templates/checkouts/history.phtml index dbcd1c4137f..9057319546c 100644 --- a/themes/finna2/templates/checkouts/history.phtml +++ b/themes/finna2/templates/checkouts/history.phtml @@ -88,18 +88,31 @@ transactions)): ?> +
+ transEsc('loan_history_save')?> +
- + transEsc('loan_history_download')?>
From 0d6b1c25092f9257eb079a9c7ead9860e9dc3be3 Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Tue, 5 Nov 2024 13:41:04 +0200 Subject: [PATCH 04/24] QA --- .../Finna/src/Finna/Controller/MyResearchController.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/module/Finna/src/Finna/Controller/MyResearchController.php b/module/Finna/src/Finna/Controller/MyResearchController.php index 15920c1e164..456b8f12a2f 100644 --- a/module/Finna/src/Finna/Controller/MyResearchController.php +++ b/module/Finna/src/Finna/Controller/MyResearchController.php @@ -1352,6 +1352,7 @@ public function downloadLoanHistoryAction() $this->flashMessenger()->addErrorMessage('ils_action_unavailable'); return $this->redirect()->toRoute('checkouts-history'); } + $config = $this->getConfig(); $allowedFileFormats = ['csv', 'ods', 'xlsx']; if (!$this->formWasSubmitted('submitLoanHistoryRequest')) { $pageOptions = $this->getPaginationHelper()->getOptions( @@ -1360,7 +1361,7 @@ public function downloadLoanHistoryAction() $config->Catalog->historic_loan_page_size ?? 50, $functionConfig ); - // Get checked out item details: + // Get checked out item details: $result = $catalog->getMyTransactionHistory($patron, $pageOptions['ilsParams']); $paginator = $this->getPaginationHelper()->getPaginator( $pageOptions, @@ -1394,7 +1395,7 @@ public function downloadLoanHistoryAction() if (!in_array($fileFormat, $allowedFileFormats)) { throw new \Exception('Should be not here.'); } - + $startPage = (int)$requestCombined['startIndex']; $lastPage = (int)($requestCombined['lastIndex'] ?? $startPage); $alternativeLimit = $startPage + 9; @@ -1403,7 +1404,6 @@ public function downloadLoanHistoryAction() } $recordLoader = $this->serviceLocator->get(\VuFind\Record\Loader::class); - $config = $this->getConfig(); $tmp = fopen('php://temp/maxmemory:' . (5 * 1024 * 1024), 'r+'); $header = [ @@ -1417,7 +1417,7 @@ public function downloadLoanHistoryAction() $this->translate('Return Date'), $this->translate('Due Date'), ]; - + if ($file = $requestCombined['append_file']['tmp_name'] ?? null) { $fileFormatLimit = [ \PhpOffice\PhpSpreadsheet\IOFactory::READER_CSV, From 4cfe9cca6791e1ac18652cb147ad5fd8a759c76e Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Tue, 5 Nov 2024 15:46:30 +0200 Subject: [PATCH 05/24] Adjusted translations --- local/languages/finna/en-gb.ini | 2 +- local/languages/finna/sv.ini | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/local/languages/finna/en-gb.ini b/local/languages/finna/en-gb.ini index c9d0cf9525b..796fa9ff9e0 100644 --- a/local/languages/finna/en-gb.ini +++ b/local/languages/finna/en-gb.ini @@ -603,7 +603,7 @@ loan_history_download = "Download loan history" loan_history_download_csv = "CSV" loan_history_download_ods = "OpenOffice (ods)" loan_history_download_xlsx = "Excel (xlsx)" -loan_history_info = "Select starting page for downloading loan history. Download starts from the first page and 9 following pages." +loan_history_info = "Select first page for downloading loan history. Download starts from the first page and includes 9 following pages." loan_history_pages = "Pages available to download: %%total%%" loan_history_append_file = "Choose a file where to append loan history" loan_history_create_new_file = "Or create a new file" diff --git a/local/languages/finna/sv.ini b/local/languages/finna/sv.ini index 31d8dde5488..9fa438e9784 100644 --- a/local/languages/finna/sv.ini +++ b/local/languages/finna/sv.ini @@ -591,9 +591,9 @@ loan_history_download = "Ladda lånehistorik" loan_history_download_csv = "CSV" loan_history_download_ods = "OpenOffice (ods)" loan_history_download_xlsx = "Excel (xlsx)" -loan_history_info = "Välja första sidan att ladda lånehistorik. Laddning börjar från första sidan och innehåller nästa 9 sidorna." -loan_history_pages = "Sidorna tillgänglig för laddning: %%total%%" -loan_history_append_file = "Välj filen för att fortsätta nedladdningen" +loan_history_info = "Välja startsida för att ladda ner lånehistorik. Nedladdningen börjar från den första sidan och innehåller de följande 9 sidorna." +loan_history_pages = "Sidorna tillgängliga för nedladdning: %%total%%" +loan_history_append_file = "Välj en fil för att fortsätta nedladdningen" loan_history_create_new_file = "Eller skapa en ny fil" loan_history_purge = "Rensa historiken" loan_history_purge_prompt_html = "Är du säker på att du vill rensa din utlåningshistorik? Raderad historik kan inte återskapas." From 33616de2cfbf1041b034dd69b6fa979d309a6fc9 Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Fri, 15 Nov 2024 14:09:34 +0200 Subject: [PATCH 06/24] Adjustments to loan history downloading --- local/config/finna/config.ini.sample | 4 + local/languages/finna/en-gb.ini | 5 +- local/languages/finna/fi.ini | 5 +- local/languages/finna/sv.ini | 5 +- .../Finna/Controller/MyResearchController.php | 121 +++++++----------- .../templates/checkouts/downloadhistory.phtml | 59 +++++---- .../finna2/templates/checkouts/history.phtml | 2 +- 7 files changed, 90 insertions(+), 111 deletions(-) diff --git a/local/config/finna/config.ini.sample b/local/config/finna/config.ini.sample index 022fd5b5e79..180a0539b89 100644 --- a/local/config/finna/config.ini.sample +++ b/local/config/finna/config.ini.sample @@ -311,6 +311,10 @@ library_cards = true ; memory problems for users with a large number of historic loans). Default = 50 ;historic_loan_page_size = 50 +; Limit for how many historic transactions to fetch at most from ILS +; when downloading loan history +loan_history_download_batch_limit = 1000 + ; Whether to display the item barcode for each loan. Default is false. display_checked_out_item_barcode = true diff --git a/local/languages/finna/en-gb.ini b/local/languages/finna/en-gb.ini index 796fa9ff9e0..a8f2c5227d8 100644 --- a/local/languages/finna/en-gb.ini +++ b/local/languages/finna/en-gb.ini @@ -603,10 +603,9 @@ loan_history_download = "Download loan history" loan_history_download_csv = "CSV" loan_history_download_ods = "OpenOffice (ods)" loan_history_download_xlsx = "Excel (xlsx)" -loan_history_info = "Select first page for downloading loan history. Download starts from the first page and includes 9 following pages." +loan_history_info = "Pages downloaded at most %%total%%" loan_history_pages = "Pages available to download: %%total%%" -loan_history_append_file = "Choose a file where to append loan history" -loan_history_create_new_file = "Or create a new file" +loan_history_choose_file_format = "Choose file format" loan_history_purge = "Purge History" loan_history_purge_prompt_html = "Are you sure you will purge the loan history? Cleared loan history cannot be retrieved anymore." loan_history_purge_selected = "Purge Selected" diff --git a/local/languages/finna/fi.ini b/local/languages/finna/fi.ini index 2a0e6763341..cf169d2609e 100644 --- a/local/languages/finna/fi.ini +++ b/local/languages/finna/fi.ini @@ -593,10 +593,9 @@ loan_history_download = "Lataa lainaushistoria" loan_history_download_csv = "CSV" loan_history_download_ods = "OpenOffice (ods)" loan_history_download_xlsx = "Excel (xlsx)" -loan_history_info = "Valitse aloitussivu lainahistorian lataamiselle. Sivuja ladataan ensimmäinen valittu sivu ja 9 seuraavaa." +loan_history_info = "Sivuja ladataan korkeintaan %%total%%" loan_history_pages = "Sivuja ladattavana: %%total%%" -loan_history_append_file = "Valitse tiedosto, mihin lainahistoriaa jatketaan" -loan_history_create_new_file = "Tai luo uusi tiedosto" +loan_history_choose_file_format = "Valitse tiedostomuoto" loan_history_purge = "Tyhjennä historia" loan_history_purge_prompt_html = "Oletko varma, että haluat tyhjentää lainaushistoriasi? Tyhjennettyä historiaa ei saa takaisin." loan_history_purge_selected = "Poista valitut" diff --git a/local/languages/finna/sv.ini b/local/languages/finna/sv.ini index 9fa438e9784..e543beeb5c0 100644 --- a/local/languages/finna/sv.ini +++ b/local/languages/finna/sv.ini @@ -591,10 +591,9 @@ loan_history_download = "Ladda lånehistorik" loan_history_download_csv = "CSV" loan_history_download_ods = "OpenOffice (ods)" loan_history_download_xlsx = "Excel (xlsx)" -loan_history_info = "Välja startsida för att ladda ner lånehistorik. Nedladdningen börjar från den första sidan och innehåller de följande 9 sidorna." +loan_history_info = "Sidorna laddas högst %%total%%" loan_history_pages = "Sidorna tillgängliga för nedladdning: %%total%%" -loan_history_append_file = "Välj en fil för att fortsätta nedladdningen" -loan_history_create_new_file = "Eller skapa en ny fil" +loan_history_choose_file_format = "Välja filformat" loan_history_purge = "Rensa historiken" loan_history_purge_prompt_html = "Är du säker på att du vill rensa din utlåningshistorik? Raderad historik kan inte återskapas." loan_history_purge_selected = "Radera valda" diff --git a/module/Finna/src/Finna/Controller/MyResearchController.php b/module/Finna/src/Finna/Controller/MyResearchController.php index 456b8f12a2f..a003c471a6c 100644 --- a/module/Finna/src/Finna/Controller/MyResearchController.php +++ b/module/Finna/src/Finna/Controller/MyResearchController.php @@ -1352,111 +1352,61 @@ public function downloadLoanHistoryAction() $this->flashMessenger()->addErrorMessage('ils_action_unavailable'); return $this->redirect()->toRoute('checkouts-history'); } - $config = $this->getConfig(); + $allowedFileFormats = ['csv', 'ods', 'xlsx']; + $historyResult = $this->forwardTo('checkouts', 'history'); + if (!isset($historyResult->transactions)) { + return $historyResult; + } + $batchLimit = $this->getConfig()->Catalog->loan_history_download_batch_limit ?? 1000; + $pagesTotal = $historyResult->paginator ? $historyResult->paginator->count() : 1; + $pagesDownloadCounter = 1; + // Calculate how many times required to fetch from ILS to achieve the $batchLimit + if ($pagesTotal > 1) { + $pagesDownloadCounter = ceil($batchLimit / $historyResult->paginator->getItemCountPerPage()); + } if (!$this->formWasSubmitted('submitLoanHistoryRequest')) { - $pageOptions = $this->getPaginationHelper()->getOptions( - 1, - null, - $config->Catalog->historic_loan_page_size ?? 50, - $functionConfig - ); - // Get checked out item details: - $result = $catalog->getMyTransactionHistory($patron, $pageOptions['ilsParams']); - $paginator = $this->getPaginationHelper()->getPaginator( - $pageOptions, - $result['count'], - $result['transactions'] - ); $view = $this->createViewModel([ - 'paginator' => $paginator, 'fileFormats' => $allowedFileFormats, - 'params' => $pageOptions['ilsParams'], + 'params' => $historyResult->params, + 'pagesTotal' => $pagesTotal, + 'pagesDownloadCounter' => $pagesDownloadCounter, ]); $view->setTemplate('checkouts/downloadhistory.phtml'); return $view; } - $request = $this->getRequest(); if (!$request->isPost()) { throw new \Exception('Invalid method.'); } - $requestCombined = array_merge_recursive( - $request->getPost()->toArray(), - $request->getFiles()->toArray() - ); // Do CSRF check $csrf = $this->serviceLocator->get(\VuFind\Validator\CsrfInterface::class); - if (!$csrf->isValid($requestCombined['csrf'])) { + if (!$csrf->isValid($request->getPost('csrf'))) { throw new \VuFind\Exception\BadRequest('error_inconsistent_parameters'); } - $fileFormat = $requestCombined['history_file_format'] ?? ''; + $fileFormat = $request->getPost('history_file_format', ''); if (!in_array($fileFormat, $allowedFileFormats)) { - throw new \Exception('Should be not here.'); + throw new \Exception('Invalid format.'); } - $startPage = (int)$requestCombined['startIndex']; - $lastPage = (int)($requestCombined['lastIndex'] ?? $startPage); - $alternativeLimit = $startPage + 9; - if ($lastPage > $startPage + 9) { - $lastPage = $alternativeLimit; - } + $startPage = (int)$request->getPost('startPage', 1); + $lastPage = min($startPage + $pagesDownloadCounter, $pagesTotal); $recordLoader = $this->serviceLocator->get(\VuFind\Record\Loader::class); - $tmp = fopen('php://temp/maxmemory:' . (5 * 1024 * 1024), 'r+'); - $header = [ - $this->translate('Title'), - $this->translate('Format'), - $this->translate('Author'), - $this->translate('Publication Year'), - $this->translate('Institution'), - $this->translate('Borrowing Location'), - $this->translate('Checkout Date'), - $this->translate('Return Date'), - $this->translate('Due Date'), - ]; - - if ($file = $requestCombined['append_file']['tmp_name'] ?? null) { - $fileFormatLimit = [ - \PhpOffice\PhpSpreadsheet\IOFactory::READER_CSV, - \PhpOffice\PhpSpreadsheet\IOFactory::READER_ODS, - \PhpOffice\PhpSpreadsheet\IOFactory::READER_XLSX, - ]; - try { - $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file, 0, $fileFormatLimit); - } catch (\Exception $e) { - throw new \Exception('Invalid format'); - } - $worksheet = $spreadsheet->getActiveSheet(); - } else { - $spreadsheet = new Spreadsheet(); - $worksheet = $spreadsheet->getActiveSheet(); - $worksheet->fromArray($header); - } - if ('xlsx' === $fileFormat) { - Cell::setValueBinder(new AdvancedValueBinder()); - } $transactions = []; for ($i = $startPage; $i <= $lastPage; $i++) { - $pageOptions = $this->getPaginationHelper()->getOptions( - $i, - null, - $config->Catalog->historic_loan_page_size ?? 50, - $functionConfig - ); - $result = $catalog->getMyTransactionHistory($patron, $pageOptions['ilsParams']); + $result = $catalog->getMyTransactionHistory($patron, $historyResult->params); if (isset($result['success']) && !$result['success']) { $this->flashMessenger()->addErrorMessage($result['status']); return $this->redirect()->toRoute('checkouts-history'); } - $tempPaginator = $this->getPaginationHelper()->getPaginator( - $pageOptions, - $result['count'], - $result['transactions'] - ); + // Break if no transactions found + if (empty($result['transactions'])) { + break; + } $transactions = array_merge($transactions, $result['transactions']); } $ids = []; @@ -1466,6 +1416,27 @@ public function downloadLoanHistoryAction() $ids[] = compact('id', 'source'); } $records = $recordLoader->loadBatch($ids, true); + + $header = [ + $this->translate('Title'), + $this->translate('Format'), + $this->translate('Author'), + $this->translate('Publication Year'), + $this->translate('Institution'), + $this->translate('Borrowing Location'), + $this->translate('Checkout Date'), + $this->translate('Return Date'), + $this->translate('Due Date'), + ]; + + $spreadsheet = new Spreadsheet(); + $worksheet = $spreadsheet->getActiveSheet(); + $worksheet->fromArray($header); + + if ('xlsx' === $fileFormat) { + Cell::setValueBinder(new AdvancedValueBinder()); + } + foreach ($transactions as $i => $current) { $driver = $records[$i]; $format = $driver->getFormats(); diff --git a/themes/finna2/templates/checkouts/downloadhistory.phtml b/themes/finna2/templates/checkouts/downloadhistory.phtml index c2ac6442826..265a59aa4a0 100644 --- a/themes/finna2/templates/checkouts/downloadhistory.phtml +++ b/themes/finna2/templates/checkouts/downloadhistory.phtml @@ -1,26 +1,33 @@ -

transEsc('loan_history_download')?>

- - -
- transEsc('loan_history_info')?> -
- transEsc('loan_history_pages', ['%%total%%' => $this->paginator->count()])?> -
- - -
-
- - -
-
- - -
- - - + +headTitle($this->translate('loan_history_download')); + + // Set up breadcrumbs: + $this->layout()->breadcrumbs = '
  • ' . $this->transEsc('Your Account') . '
  • ' . $this->transEsc('Loan History') . '
  • '; +?> +context($this)->renderInContext('myresearch/menu.phtml', ['active' => 'historicLoans']); ?> + +
    +

    transEsc('loan_history_download')?>

    +
    + +
    + transEsc('loan_history_info', ['%%total%%' => $this->pagesDownloadCounter])?> +
    + transEsc('loan_history_pages', ['%%total%%' => $this->pagesTotal])?> +
    + + +
    +
    + + +
    + +
    +
    diff --git a/themes/finna2/templates/checkouts/history.phtml b/themes/finna2/templates/checkouts/history.phtml index 52b89293147..cfa22f2ead8 100644 --- a/themes/finna2/templates/checkouts/history.phtml +++ b/themes/finna2/templates/checkouts/history.phtml @@ -92,7 +92,7 @@ transEsc('loan_history_save')?>
    - transEsc('loan_history_download')?> + transEsc('loan_history_download')?>
    From 5573fca782ca6201675ef46a011a52c1c31d94cf Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Fri, 15 Nov 2024 14:13:54 +0200 Subject: [PATCH 07/24] Added comments to template --- themes/finna2/templates/checkouts/downloadhistory.phtml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/themes/finna2/templates/checkouts/downloadhistory.phtml b/themes/finna2/templates/checkouts/downloadhistory.phtml index 265a59aa4a0..d21ca6f40f3 100644 --- a/themes/finna2/templates/checkouts/downloadhistory.phtml +++ b/themes/finna2/templates/checkouts/downloadhistory.phtml @@ -1,4 +1,4 @@ - + headTitle($this->translate('loan_history_download')); @@ -31,3 +31,4 @@ + From a19346e6e6beb3283f2a9f10501c645b353e2e38 Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Mon, 13 Jan 2025 12:40:28 +0200 Subject: [PATCH 08/24] Adjusted to fetch file from ajax handler --- local/languages/finna/en-gb.ini | 1 + local/languages/finna/fi.ini | 1 + local/languages/finna/se.ini | 1 + local/languages/finna/sv.ini | 1 + module/Finna/config/module.config.php | 9 +- .../AbstractIlsAndUserActionFactory.php | 81 +++++ .../AjaxHandler/GetTransactionHistory.php | 284 ++++++++++++++++++ .../src/Finna/Controller/AjaxController.php | 53 ++++ .../Finna/Controller/MyResearchController.php | 176 +---------- .../Finna/src/Finna/ILS/Enum/ILSDefaults.php | 45 +++ module/VuFind/src/VuFind/ILS/Driver/Demo.php | 2 +- themes/finna2/js/finna-transaction-history.js | 116 +++++++ themes/finna2/js/finna.js | 1 + .../finna2/templates/checkouts/history.phtml | 19 +- .../layout/finna-js-translations.phtml | 3 +- themes/finna2/theme.config.php | 1 + 16 files changed, 612 insertions(+), 182 deletions(-) create mode 100644 module/Finna/src/Finna/AjaxHandler/AbstractIlsAndUserActionFactory.php create mode 100644 module/Finna/src/Finna/AjaxHandler/GetTransactionHistory.php create mode 100644 module/Finna/src/Finna/ILS/Enum/ILSDefaults.php create mode 100644 themes/finna2/js/finna-transaction-history.js diff --git a/local/languages/finna/en-gb.ini b/local/languages/finna/en-gb.ini index 9ac2f13fbfe..d0b5341a5bb 100644 --- a/local/languages/finna/en-gb.ini +++ b/local/languages/finna/en-gb.ini @@ -605,6 +605,7 @@ list-tags-info = "Add a new keyword" Loading = "Loading" Loan Details = "Loan Details" loan_history_download = "Download loan history" +loan_history_download_part = "Download loan history (part %%part%%)" loan_history_download_csv = "CSV" loan_history_download_ods = "OpenOffice (ods)" loan_history_download_xlsx = "Excel (xlsx)" diff --git a/local/languages/finna/fi.ini b/local/languages/finna/fi.ini index de5b379e818..ff8cd271b95 100644 --- a/local/languages/finna/fi.ini +++ b/local/languages/finna/fi.ini @@ -595,6 +595,7 @@ list-tags-info = "Lisää uusi avainsana" Loading = "Ladataan" Loan Details = "Lainan tiedot" loan_history_download = "Lataa lainaushistoria" +loan_history_download_part = "Lataa lainaushistoria (osa %%part%%)" loan_history_download_csv = "CSV" loan_history_download_ods = "OpenOffice (ods)" loan_history_download_xlsx = "Excel (xlsx)" diff --git a/local/languages/finna/se.ini b/local/languages/finna/se.ini index dc53354c603..ddba3b2b468 100644 --- a/local/languages/finna/se.ini +++ b/local/languages/finna/se.ini @@ -577,6 +577,7 @@ list-tags-info = "Lasit ođđa beassansáni" Loading = "Láddejuvvo" Loan Details = "Luoikama dieđut" loan_history_download = "Doalvvo visot" +loan_history_download_page = "Doalvvo visot (siidu %%page%%)" loan_history_download_csv = "Doalvvo CSV" loan_history_download_ods = "Doalvvo OpenOffice (ods)" loan_history_download_xlsx = "Doalvvo Excel (xlsx)" diff --git a/local/languages/finna/sv.ini b/local/languages/finna/sv.ini index 90a4f6742fb..d97d5c13c30 100644 --- a/local/languages/finna/sv.ini +++ b/local/languages/finna/sv.ini @@ -593,6 +593,7 @@ list-tags-info = "Lägg till nytt nyckelord" Loading = "Laddar" Loan Details = "Information om lånet" loan_history_download = "Ladda lånehistorik" +loan_history_download_page = "Ladda lånehistorik (del %%page%%)" loan_history_download_csv = "CSV" loan_history_download_ods = "OpenOffice (ods)" loan_history_download_xlsx = "Excel (xlsx)" diff --git a/module/Finna/config/module.config.php b/module/Finna/config/module.config.php index 3a0c5517534..d80bb9e9d7e 100644 --- a/module/Finna/config/module.config.php +++ b/module/Finna/config/module.config.php @@ -491,6 +491,8 @@ 'Finna\AjaxHandler\GetUserListFactory', 'Finna\AjaxHandler\GetUserLists' => 'Finna\AjaxHandler\GetUserListsFactory', + 'Finna\AjaxHandler\GetTransactionHistory' => + 'Finna\AjaxHandler\AbstractIlsAndUserActionFactory', 'Finna\AjaxHandler\ImportFavorites' => 'Finna\AjaxHandler\ImportFavoritesFactory', 'Finna\AjaxHandler\OnlinePaymentNotify' => @@ -528,6 +530,7 @@ 'getRecordData' => 'Finna\AjaxHandler\GetRecordData', 'getRecordDriverRelatedRecords' => 'Finna\AjaxHandler\GetRecordDriverRelatedRecords', 'getRecordInfoByAuthority' => 'Finna\AjaxHandler\GetRecordInfoByAuthority', + 'getTransactionHistory' => 'Finna\AjaxHandler\GetTransactionHistory', 'getSearchTabsRecommendations' => 'Finna\AjaxHandler\GetSearchTabsRecommendations', 'getSimilarRecords' => 'Finna\AjaxHandler\GetSimilarRecords', 'getUserList' => 'Finna\AjaxHandler\GetUserList', @@ -1084,7 +1087,10 @@ 'newLibraryCardPassword' => 'newPassword/[:id]', 'librarycards-displaybarcode' => 'displayBarcode/[:id]', ], - 'MyResearch' => ['sortList' => 'SortList/[:id]'], + 'MyResearch' => [ + 'sortList' => 'SortList/[:id]', + 'downloadLoanHistory' => 'DownloadLoanHistory/[:part]/[:format]', + ], 'ReservationList' => [ 'reservationlist-displaylists' => 'DisplayLists', 'reservationlist-displaylist' => 'DisplayList/[:id]', @@ -1102,7 +1108,6 @@ 'LibraryCards/ResetPassword', 'LocationService/Modal', 'MetaLib/Home', 'MetaLib/Search', 'MetaLib/Advanced', - 'MyResearch/DownloadLoanHistory', 'MyResearch/SaveCustomOrder', 'MyResearch/SaveHistoricLoans', 'OrganisationInfo/Home', 'PCI/Home', 'PCI/Search', 'PCI/Record', diff --git a/module/Finna/src/Finna/AjaxHandler/AbstractIlsAndUserActionFactory.php b/module/Finna/src/Finna/AjaxHandler/AbstractIlsAndUserActionFactory.php new file mode 100644 index 00000000000..d296a8e897e --- /dev/null +++ b/module/Finna/src/Finna/AjaxHandler/AbstractIlsAndUserActionFactory.php @@ -0,0 +1,81 @@ + + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ + +namespace Finna\AjaxHandler; + +use Laminas\ServiceManager\Exception\ServiceNotCreatedException; +use Laminas\ServiceManager\Exception\ServiceNotFoundException; +use Psr\Container\ContainerExceptionInterface as ContainerException; +use Psr\Container\ContainerInterface; + +/** + * Factory for AbstractIlsAndUserAction AJAX handlers. + * + * @category VuFind + * @package AJAX + * @author Demian Katz + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class AbstractIlsAndUserActionFactory implements \Laminas\ServiceManager\Factory\FactoryInterface +{ + /** + * Create an object + * + * @param ContainerInterface $container Service manager + * @param string $requestedName Service being created + * @param null|array $options Extra options (optional) + * + * @return object + * + * @throws ServiceNotFoundException if unable to resolve the service. + * @throws ServiceNotCreatedException if an exception is raised when + * creating a service. + * @throws ContainerException&\Throwable if any other error occurs + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function __invoke( + ContainerInterface $container, + $requestedName, + array $options = null + ) { + $config = $container->get(\VuFind\Config\PluginManager::class)->get('config'); + return new $requestedName( + $container->get(\VuFind\Session\Settings::class), + $container->get(\VuFind\ILS\Connection::class), + $container->get(\VuFind\Auth\ILSAuthenticator::class), + $container->get(\VuFind\Auth\Manager::class)->getUserObject(), + $container->get(\VuFind\Record\Loader::class), + $config->Catalog->loan_history_download_batch_limit ?? 1000, + $config->Catalog->historic_loan_page_size ?? 50, + ...($options ?: []) + ); + } +} diff --git a/module/Finna/src/Finna/AjaxHandler/GetTransactionHistory.php b/module/Finna/src/Finna/AjaxHandler/GetTransactionHistory.php new file mode 100644 index 00000000000..ff70113e766 --- /dev/null +++ b/module/Finna/src/Finna/AjaxHandler/GetTransactionHistory.php @@ -0,0 +1,284 @@ + + * @author Ere Maijala + * @author Konsta Raunio + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ + +namespace Finna\AjaxHandler; + +use Exception; +use Laminas\Mvc\Controller\Plugin\Params; +use PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder; +use PhpOffice\PhpSpreadsheet\Cell\Cell; +use PhpOffice\PhpSpreadsheet\Spreadsheet; +use PhpOffice\PhpSpreadsheet\Writer\Csv; +use PhpOffice\PhpSpreadsheet\Writer\Ods; +use PhpOffice\PhpSpreadsheet\Writer\Xlsx; +use VuFind\Auth\ILSAuthenticator; +use VuFind\Db\Entity\UserEntityInterface; +use VuFind\ILS\Connection; +use VuFind\ILS\PaginationHelper; +use VuFind\Session\Settings as SessionSettings; + +/** + * GetFeed AJAX handler + * + * @category VuFind + * @package AJAX + * @author Samuli Sillanpää + * @author Ere Maijala + * @author Konsta Raunio + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class GetTransactionHistory extends \VuFind\AjaxHandler\AbstractIlsAndUserAction +{ + protected $exportFormats = [ + 'xlsx' => [ + 'mediaType' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'writer' => Xlsx::class, + ], + 'ods' => [ + 'mediaType' => 'application/vnd.oasis.opendocument.spreadsheet', + 'writer' => Ods::class, + ], + 'csv' => [ + 'mediaType' => 'text/csv', + 'writer' => Csv::class, + ], + ]; + + /** + * Constructor + * + * @param SessionSettings $ss Session settings + * @param Connection $ils ILS connection + * @param ILSAuthenticator $ilsAuthenticator ILS authenticator + * @param ?UserEntityInterface $user Logged in user (or null) + * @param \VuFind\Record\Loader $recordLoader Record loader + * @param int $batchLimit Config specified default batch limit + * @param int $defaultPageSize Default page size set in config.ini + */ + public function __construct( + SessionSettings $ss, + Connection $ils, + ILSAuthenticator $ilsAuthenticator, + ?UserEntityInterface $user, + protected \VuFind\Record\Loader $recordLoader, + protected int $batchLimit = 1000, + protected int $defaultPageSize = 50 + ) { + parent::__construct($ss, $ils, $ilsAuthenticator, $user); + } + + /** + * Handle a request. + * + * @param Params $params Parameter helper from controller + * + * @return array [response data, HTTP status code] + */ + public function handleRequest(Params $params) + { + $this->disableSessionWrites(); // avoid session write timing bug + + $patron = $this->ilsAuthenticator->storedCatalogLogin(); + if (!$patron || !$this->user) { + return $this->formatResponse( + $this->translate('You must be logged in first'), + self::STATUS_HTTP_NEED_AUTH + ); + } + + $requestType = $params->fromQuery('type', 'status'); + // Check function config + $functionConfig = $this->ils->checkFunction( + 'getMyTransactionHistory', + $patron + ); + if (false === $functionConfig) { + return $this->formatResponse( + $this->translate('ils_action_unavailable'), + self::STATUS_HTTP_UNAVAILABLE + ); + } + $paginationHelper = new PaginationHelper(); + $pageOptions = $paginationHelper->getOptions( + 1, + null, + $this->defaultPageSize, + $functionConfig + ); + + // Get checked out item details: + $result = $this->ils->getMyTransactionHistory($patron, $pageOptions['ilsParams']); + if (!($result['success'] ?? true)) { + return $this->formatResponse( + $this->translate('An error has occurred'), + self::STATUS_HTTP_ERROR + ); + } + if ('status' === $requestType) { + // Get amount of items in a single page + return $this->formatResponse( + [ + 'parts' => ceil(($result['count'] ?? 1) / 1000), + ] + ); + } + if ('file' === $requestType) { + $paginator = $paginationHelper->getPaginator( + $pageOptions, + $result['count'], + $result['transactions'] + ); + // Get requested history part as a file to be downloaded + $part = $params->fromQuery('part', 1); + $fileFormat = $params->fromQuery('format', 'csv'); + $pageLimit = $paginator ? $paginator->getItemCountPerPage() : 50; + $pagesCount = $paginator ? $paginator->count() : 1; + return $this->getHistoryAsFile($patron, $part, $pageLimit, $pagesCount, $fileFormat); + } + return $this->formatResponse( + $this->translate('An error has occurred'), + self::STATUS_HTTP_ERROR + ); + } + + /** + * Create a file for transaction history + * + * @param array $patron Currently logged in users patron + * @param int $part Part of the transaction history to download + * @param int $limit Limit for how many transactions one fetch from ils fetches + * @param int $pagesCount Total amount of pages the user has in history + * @param string $fileFormat Format of the file to generate + * + * @return array [fileName => name of the file, mediaType => media type, filePointer => pointer for the resource] + */ + private function getHistoryAsFile( + array $patron, + int $part = 1, + int $limit = 50, + int $pagesCount = 1, + string $fileFormat = 'csv' + ): array { + // Calculate how many times required to fetch from ILS to achieve the $batchLimit + $pagesToFetch = 1; + $firstPageToFetch = 1; + $lastPageToFetch = 1; + if ($pagesCount > 1) { + $pagesToFetch = ceil($this->batchLimit / $limit); + $firstPageToFetch += ($pagesToFetch * ($part - 1)); + $lastPageToFetch += min(($pagesToFetch * $part), $pagesCount); + } + $tmp = fopen('php://temp/maxmemory:' . (5 * 1024 * 1024), 'r+'); + + $transactions = []; + for ($i = $firstPageToFetch; $i < $lastPageToFetch; $i++) { + $result = $this->ils->getMyTransactionHistory($patron, ['page' => $i, 'limit' => $limit]); + // Break if no transactions found + if (empty($result['transactions'])) { + break; + } + $transactions = [...$transactions, ...$result['transactions']]; + } + $ids = []; + foreach ($transactions as $current) { + $id = $current['id'] ?? ''; + $source = $current['source'] ?? DEFAULT_SEARCH_BACKEND; + $ids[] = compact('id', 'source'); + } + $records = $this->recordLoader->loadBatch($ids, true); + + $header = [ + $this->translate('Title'), + $this->translate('Format'), + $this->translate('Author'), + $this->translate('Publication Year'), + $this->translate('Institution'), + $this->translate('Borrowing Location'), + $this->translate('Checkout Date'), + $this->translate('Return Date'), + $this->translate('Due Date'), + ]; + + $spreadsheet = new Spreadsheet(); + $worksheet = $spreadsheet->getActiveSheet(); + $worksheet->fromArray($header); + + if ('xlsx' === $fileFormat) { + Cell::setValueBinder(new AdvancedValueBinder()); + } + + foreach ($transactions as $i => $current) { + $driver = $records[$i]; + $format = $driver->getFormats(); + $format = end($format); + $author = $driver->tryMethod('getNonPresenterAuthors'); + + $loan = []; + $loan[] = $current['title'] ?? $driver->getTitle() ?? ''; + $loan[] = $this->translate($format); + $loan[] = $author[0]['name'] ?? ''; + $loan[] = $current['publication_year'] ?? ''; + $loan[] = empty($current['institution_name']) + ? '' + : $this->translateWithPrefix('location_', $current['institution_name']); + $loan[] = empty($current['borrowingLocation']) + ? '' + : $this->translateWithPrefix('location_', $current['borrowingLocation']); + $loan[] = $current['checkoutDate'] ?? ''; + $loan[] = $current['returnDate'] ?? ''; + $loan[] = $current['dueDate'] ?? ''; + + $nextRow = $worksheet->getHighestRow() + 1; + $worksheet->fromArray($loan, null, 'A' . (string)$nextRow); + } + if ('xlsx' === $fileFormat) { + $worksheet->getStyle('G2:I' . $worksheet->getHighestRow()) + ->getNumberFormat() + ->setFormatCode('dd.mm.yyyy'); + foreach (['G', 'H', 'I'] as $col) { + $worksheet->getColumnDimension($col)->setAutoSize(true); + } + } + $writer = new $this->exportFormats[$fileFormat]['writer']($spreadsheet); + $writer->save($tmp); + $fileName = implode('-', ['finna-loan-history-pages', $firstPageToFetch, $lastPageToFetch - 1]); + $fileName .= ".$fileFormat"; + + rewind($tmp); + + return $this->formatResponse([ + 'fileName' => $fileName, + 'mediaType' => $this->exportFormats[$fileFormat]['mediaType'], + 'filePointer' => $tmp, + ], 200); + } +} diff --git a/module/Finna/src/Finna/Controller/AjaxController.php b/module/Finna/src/Finna/Controller/AjaxController.php index 378f21948b9..82ade0ebb1c 100644 --- a/module/Finna/src/Finna/Controller/AjaxController.php +++ b/module/Finna/src/Finna/Controller/AjaxController.php @@ -54,4 +54,57 @@ public function onlinePaymentNotifyAction() // Use text/html to avoid any output return $this->callAjaxMethod('onlinePaymentNotify', 'text/html'); } + + /** + * Format the content of the AJAX response based on the response type. + * + * @param string $type Content-type of output + * @param mixed $data The response data + * @param int $httpCode A custom HTTP Status Code + * + * @return string + * @throws \Exception + */ + protected function formatContent($type, $data, $httpCode) + { + if ($type !== 'file_type_content') { + return parent::formatContent($type, $data, $httpCode); + } + if ($httpCode === 200) { + return $this->getFileResponse($data); + } else { + return parent::formatContent('text/plain', $data, $httpCode); + } + } + + /** + * Get a file download + * + * @return \Laminas\Http\Response + */ + public function fileAction() + { + $method = $this->params()->fromQuery('method'); + if (!$method) { + return $this->getAjaxResponse('text/plain', ['error' => 'Parameter "method" missing'], 400); + } + return $this->callAjaxMethod($method, 'file_type_content'); + } + + /** + * Send output data and exit. + * + * @param mixed $data The response data + * + * @return \Laminas\Http\Response + * @throws \Exception + */ + protected function getFileResponse($data) + { + $response = $this->getResponse(); + $headers = $response->getHeaders(); + $headers->addHeaderLine('Content-type', $data['mediaType']); + $headers->addHeaderLine('Content-Disposition', 'attachment; filename="' . $data['fileName'] . '"'); + return stream_get_contents($data['filePointer']); + } } diff --git a/module/Finna/src/Finna/Controller/MyResearchController.php b/module/Finna/src/Finna/Controller/MyResearchController.php index a003c471a6c..4f2237926cf 100644 --- a/module/Finna/src/Finna/Controller/MyResearchController.php +++ b/module/Finna/src/Finna/Controller/MyResearchController.php @@ -40,12 +40,6 @@ use Finna\Db\Service\FinnaUserListServiceInterface; use Finna\Db\Service\FinnaUserServiceInterface; use Finna\Db\Service\UserListService as FinnaUserListService; -use PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder; -use PhpOffice\PhpSpreadsheet\Cell\Cell; -use PhpOffice\PhpSpreadsheet\Spreadsheet; -use PhpOffice\PhpSpreadsheet\Writer\Csv; -use PhpOffice\PhpSpreadsheet\Writer\Ods; -use PhpOffice\PhpSpreadsheet\Writer\Xlsx; use VuFind\Db\Entity\UserEntityInterface; use VuFind\Db\Service\SearchServiceInterface; use VuFind\Db\Service\UserListServiceInterface; @@ -83,21 +77,6 @@ class MyResearchController extends \VuFind\Controller\MyResearchController use FinnaPersonalInformationSupportTrait; use Feature\FinnaUserListTrait; - protected $exportFormats = [ - 'xlsx' => [ - 'mediaType' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'writer' => Xlsx::class, - ], - 'ods' => [ - 'mediaType' => 'application/vnd.oasis.opendocument.spreadsheet', - 'writer' => Ods::class, - ], - 'csv' => [ - 'mediaType' => 'text/csv', - 'writer' => Csv::class, - ], - ]; - /** * Catalog Login Action * @@ -1333,162 +1312,11 @@ public function importAction() /** * Download historic loans * - * @return mixed + * @return mixed + * @deprecated Use AjaxHandler/GetTransactionHistory */ public function downloadLoanHistoryAction() { - if (!is_array($patron = $this->catalogLogin())) { - return $patron; - } - $catalog = $this->getILS(); - - // Check function config - $functionConfig = $catalog->checkFunction( - 'getMyTransactionHistory', - $patron - ); - - if (false === $functionConfig) { - $this->flashMessenger()->addErrorMessage('ils_action_unavailable'); - return $this->redirect()->toRoute('checkouts-history'); - } - - $allowedFileFormats = ['csv', 'ods', 'xlsx']; - $historyResult = $this->forwardTo('checkouts', 'history'); - if (!isset($historyResult->transactions)) { - return $historyResult; - } - $batchLimit = $this->getConfig()->Catalog->loan_history_download_batch_limit ?? 1000; - $pagesTotal = $historyResult->paginator ? $historyResult->paginator->count() : 1; - $pagesDownloadCounter = 1; - // Calculate how many times required to fetch from ILS to achieve the $batchLimit - if ($pagesTotal > 1) { - $pagesDownloadCounter = ceil($batchLimit / $historyResult->paginator->getItemCountPerPage()); - } - if (!$this->formWasSubmitted('submitLoanHistoryRequest')) { - $view = $this->createViewModel([ - 'fileFormats' => $allowedFileFormats, - 'params' => $historyResult->params, - 'pagesTotal' => $pagesTotal, - 'pagesDownloadCounter' => $pagesDownloadCounter, - ]); - $view->setTemplate('checkouts/downloadhistory.phtml'); - return $view; - } - $request = $this->getRequest(); - if (!$request->isPost()) { - throw new \Exception('Invalid method.'); - } - - // Do CSRF check - $csrf = $this->serviceLocator->get(\VuFind\Validator\CsrfInterface::class); - if (!$csrf->isValid($request->getPost('csrf'))) { - throw new \VuFind\Exception\BadRequest('error_inconsistent_parameters'); - } - $fileFormat = $request->getPost('history_file_format', ''); - if (!in_array($fileFormat, $allowedFileFormats)) { - throw new \Exception('Invalid format.'); - } - - $startPage = (int)$request->getPost('startPage', 1); - $lastPage = min($startPage + $pagesDownloadCounter, $pagesTotal); - - $recordLoader = $this->serviceLocator->get(\VuFind\Record\Loader::class); - $tmp = fopen('php://temp/maxmemory:' . (5 * 1024 * 1024), 'r+'); - - $transactions = []; - for ($i = $startPage; $i <= $lastPage; $i++) { - $result = $catalog->getMyTransactionHistory($patron, $historyResult->params); - if (isset($result['success']) && !$result['success']) { - $this->flashMessenger()->addErrorMessage($result['status']); - return $this->redirect()->toRoute('checkouts-history'); - } - // Break if no transactions found - if (empty($result['transactions'])) { - break; - } - $transactions = array_merge($transactions, $result['transactions']); - } - $ids = []; - foreach ($transactions as $current) { - $id = $current['id'] ?? ''; - $source = $current['source'] ?? DEFAULT_SEARCH_BACKEND; - $ids[] = compact('id', 'source'); - } - $records = $recordLoader->loadBatch($ids, true); - - $header = [ - $this->translate('Title'), - $this->translate('Format'), - $this->translate('Author'), - $this->translate('Publication Year'), - $this->translate('Institution'), - $this->translate('Borrowing Location'), - $this->translate('Checkout Date'), - $this->translate('Return Date'), - $this->translate('Due Date'), - ]; - - $spreadsheet = new Spreadsheet(); - $worksheet = $spreadsheet->getActiveSheet(); - $worksheet->fromArray($header); - - if ('xlsx' === $fileFormat) { - Cell::setValueBinder(new AdvancedValueBinder()); - } - - foreach ($transactions as $i => $current) { - $driver = $records[$i]; - $format = $driver->getFormats(); - $format = end($format); - $author = $driver->tryMethod('getNonPresenterAuthors'); - - $loan = []; - $loan[] = $current['title'] ?? $driver->getTitle() ?? ''; - $loan[] = $this->translate($format); - $loan[] = $author[0]['name'] ?? ''; - $loan[] = $current['publication_year'] ?? ''; - $loan[] = empty($current['institution_name']) - ? '' - : $this->translateWithPrefix('location_', $current['institution_name']); - $loan[] = empty($current['borrowingLocation']) - ? '' - : $this->translateWithPrefix('location_', $current['borrowingLocation']); - $loan[] = $current['checkoutDate'] ?? ''; - $loan[] = $current['returnDate'] ?? ''; - $loan[] = $current['dueDate'] ?? ''; - - $nextRow = $worksheet->getHighestRow() + 1; - $worksheet->fromArray($loan, null, 'A' . (string)$nextRow); - } - if ('xlsx' === $fileFormat) { - $worksheet->getStyle('G2:I' . $worksheet->getHighestRow()) - ->getNumberFormat() - ->setFormatCode('dd.mm.yyyy'); - foreach (['G', 'H', 'I'] as $col) { - $worksheet->getColumnDimension($col)->setAutoSize(true); - } - } - $response = $this->getResponse(); - $response->getHeaders() - ->addHeaderLine( - 'Content-Type', - $this->exportFormats[$fileFormat]['mediaType'] - ); - $writer = new $this->exportFormats[$fileFormat]['writer']($spreadsheet); - $writer->save($tmp); - $fileName = implode('-', ['finna-loan-history-pages', $startPage, $lastPage]); - $fileName .= ".$fileFormat"; - $response->getHeaders() - ->addHeaderLine( - 'Content-Disposition', - 'attachment; filename="' . $fileName . '"' - ); - - rewind($tmp); - - $response->setContent(stream_get_contents($tmp)); - return $response; } /** diff --git a/module/Finna/src/Finna/ILS/Enum/ILSDefaults.php b/module/Finna/src/Finna/ILS/Enum/ILSDefaults.php new file mode 100644 index 00000000000..3ef73a2b986 --- /dev/null +++ b/module/Finna/src/Finna/ILS/Enum/ILSDefaults.php @@ -0,0 +1,45 @@ + + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Site + */ + +namespace Finna\ILS\Enum; + +/** + * Enum for representing default hardcoded values found in ILS specific methods. + * + * @category VuFind + * @package ILS_Drivers + * @author Ere Maijala + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Site + */ +enum ILSDefaults: int +{ + case TRANSACTION_LIMIT_20 = 20; + case TRANSACTION_LIMIT_50 = 50; +} diff --git a/module/VuFind/src/VuFind/ILS/Driver/Demo.php b/module/VuFind/src/VuFind/ILS/Driver/Demo.php index 8e413fa559c..400216d1cba 100644 --- a/module/VuFind/src/VuFind/ILS/Driver/Demo.php +++ b/module/VuFind/src/VuFind/ILS/Driver/Demo.php @@ -1384,7 +1384,7 @@ protected function getRandomHistoricTransactionList() $trans = rand() % 10 - 1 > 0 ? rand() % 15 : 0; $transList = []; - for ($i = 0; $i < $trans; $i++) { + for ($i = 0; $i < 10000; $i++) { // Checkout date $relative = rand() % 300; $checkoutDate = strtotime("now -$relative days"); diff --git a/themes/finna2/js/finna-transaction-history.js b/themes/finna2/js/finna-transaction-history.js new file mode 100644 index 00000000000..a1f37af5a4c --- /dev/null +++ b/themes/finna2/js/finna-transaction-history.js @@ -0,0 +1,116 @@ +/*global finna, VuFind */ +finna.transactionHistory = (function transactionHistory() { + + const historyButtonSelector = 'div.js-download-loan-history'; + + const toggleButtonSelector = 'button.js-history-toggle'; + + const fileFormatButtonSelector = 'button.js-history-file-format'; + + /** + * Calculates the current page for the button limited by the last possible page to be downloaded. + * @param {HTMLButtonElement} element Button element to be clicked to download history + * @returns {void} + */ + function setNextPage(element) { + let currentPart = +element.dataset.currentPart; + let lastPart = +element.dataset.lastPart; + if (currentPart < lastPart) { + currentPart++; + } + element.dataset.currentPart = currentPart; + } + + + /** + * Sets the buttons text content to match for the next page to be downloaded if clicked. + * @param {HTMLButtonElement} element Button element to be clicked to download history + * @returns {void} + */ + function syncButtonText(element) { + const toggleButton = element.querySelector(toggleButtonSelector); + const textContent = VuFind.translate('loan_history_download_part'); + toggleButton.textContent = `${textContent.replace('%%part%%', element.dataset.currentPart)} `; + toggleButton.append(VuFind.icon('show-more', {}, true)); + } + + /** + * Request part of a transaction history to download + * @param {HTMLElement} element Parent element for transaction history downloading + * @param {string} formatButton Clicked button containing format specific data + */ + function getTransactionHistoryPart(element, formatButton) + { + const part = element.dataset.currentPart; + const format = formatButton.dataset.format; + const searchParams = new URLSearchParams({method: "getTransactionHistory", part, format, type: "file"}); + let filename; + fetch (`${VuFind.path}/AJAX/FILE?${searchParams}`).then(response => { + if (!response.ok) { + throw new Error(''); + } + const header = response.headers.get('Content-Disposition'); + const parts = header.split(';'); + filename = parts[1].split('=')[1].replaceAll("\"", ""); + + return response.blob(); + }).then((blob) => { + var url = window.URL.createObjectURL(blob); + var a = document.createElement('a'); + a.href = url; + a.download = filename; + document.body.appendChild(a); // we need to append the element to the dom -> otherwise it will not work in firefox + a.click(); + a.remove(); + setNextPage(element); + syncButtonText(element); + }).catch((reason) => { + console.warn(reason); + }); + } + + /** + * Initializes a button to allow for loading loan history in chunks. + * @param {HTMLButtonElement} element Button element to be clicked to download history + * @returns {void} + */ + function initButton(element) { + fetch (`${VuFind.path}/AJAX/JSON?method=getTransactionHistory&type=status`) + .then(response => { + if (!response.ok) { + throw new Error(''); + } + return response.json(); + }).then(result => { + if (!result.data) { + element.style.display = 'none'; + return; + } + element.dataset.currentPart = 1; + if (result.data && result.data.parts) { + element.dataset.lastPart = result.data.parts; + syncButtonText(element); + const formatButtons = element.querySelectorAll(fileFormatButtonSelector); + formatButtons.forEach(formatButton => { + formatButton.addEventListener('click', (e) => { + e.preventDefault(); + getTransactionHistoryPart(element, formatButton); + }); + }); + } + }).catch(error => { + console.warn(error); + element.style.display = 'none'; + }); + } + + /** + * Initialize buttons to handle downloading transaction history + */ + function init() { + document.querySelectorAll(historyButtonSelector).forEach(el => { initButton(el); }); + } + return { + init: init + }; +})(); diff --git a/themes/finna2/js/finna.js b/themes/finna2/js/finna.js index 380dd3b7972..1f1ec23ff69 100644 --- a/themes/finna2/js/finna.js +++ b/themes/finna2/js/finna.js @@ -44,6 +44,7 @@ var finna = (function finnaModule() { 'mdEditable', 'a11y', 'finnaDatepicker', + 'transactionHistory', ]; $.each(modules, function initModule(ind, module) { diff --git a/themes/finna2/templates/checkouts/history.phtml b/themes/finna2/templates/checkouts/history.phtml index 74aadf89b29..8559776a297 100644 --- a/themes/finna2/templates/checkouts/history.phtml +++ b/themes/finna2/templates/checkouts/history.phtml @@ -89,10 +89,21 @@ transactions)): ?> -
    - transEsc('loan_history_download')?> +
    diff --git a/themes/finna2/templates/layout/finna-js-translations.phtml b/themes/finna2/templates/layout/finna-js-translations.phtml index d822f060a8f..0d67bada9dc 100644 --- a/themes/finna2/templates/layout/finna-js-translations.phtml +++ b/themes/finna2/templates/layout/finna-js-translations.phtml @@ -82,7 +82,8 @@ $this->jsTranslations()->addStrings( 'select_a11y_clear' => 'select_a11y_clear', 'datepicker_selected' => 'selected', - + 'loan_history_download' => 'loan_history_download', + 'loan_history_download_part' => 'loan_history_download_part', ] ); diff --git a/themes/finna2/theme.config.php b/themes/finna2/theme.config.php index 4aec817c867..0556c30238c 100644 --- a/themes/finna2/theme.config.php +++ b/themes/finna2/theme.config.php @@ -267,6 +267,7 @@ 'finna-select-a11y.js', 'finna-a11y.js', 'finna-datepicker.js', + 'finna-transaction-history.js', 'components/finna-bazaar-browse-bar.js', 'components/finna-md-editable.js', 'components/finna-tabs-nav.js', From c78eb632f8344d77246bb32308e1d6434e814d66 Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Mon, 13 Jan 2025 12:46:51 +0200 Subject: [PATCH 09/24] Removed unused files and translations --- local/languages/finna/en-gb.ini | 3 -- local/languages/finna/fi.ini | 3 -- local/languages/finna/sv.ini | 3 -- .../templates/checkouts/downloadhistory.phtml | 34 ------------------- 4 files changed, 43 deletions(-) delete mode 100644 themes/finna2/templates/checkouts/downloadhistory.phtml diff --git a/local/languages/finna/en-gb.ini b/local/languages/finna/en-gb.ini index d0b5341a5bb..3a6d9aff9b0 100644 --- a/local/languages/finna/en-gb.ini +++ b/local/languages/finna/en-gb.ini @@ -609,9 +609,6 @@ loan_history_download_part = "Download loan history (part %%part%%)" loan_history_download_csv = "CSV" loan_history_download_ods = "OpenOffice (ods)" loan_history_download_xlsx = "Excel (xlsx)" -loan_history_info = "Pages downloaded at most %%total%%" -loan_history_pages = "Pages available to download: %%total%%" -loan_history_choose_file_format = "Choose file format" loan_history_purge = "Purge History" loan_history_purge_prompt_html = "Are you sure you will purge the loan history? Cleared loan history cannot be retrieved anymore." loan_history_purge_selected = "Purge Selected" diff --git a/local/languages/finna/fi.ini b/local/languages/finna/fi.ini index ff8cd271b95..957ec056888 100644 --- a/local/languages/finna/fi.ini +++ b/local/languages/finna/fi.ini @@ -599,9 +599,6 @@ loan_history_download_part = "Lataa lainaushistoria (osa %%part%%)" loan_history_download_csv = "CSV" loan_history_download_ods = "OpenOffice (ods)" loan_history_download_xlsx = "Excel (xlsx)" -loan_history_info = "Sivuja ladataan korkeintaan %%total%%" -loan_history_pages = "Sivuja ladattavana: %%total%%" -loan_history_choose_file_format = "Valitse tiedostomuoto" loan_history_purge = "Tyhjennä historia" loan_history_purge_prompt_html = "Oletko varma, että haluat tyhjentää lainaushistoriasi? Tyhjennettyä historiaa ei saa takaisin." loan_history_purge_selected = "Poista valitut" diff --git a/local/languages/finna/sv.ini b/local/languages/finna/sv.ini index d97d5c13c30..46a9cdae6e3 100644 --- a/local/languages/finna/sv.ini +++ b/local/languages/finna/sv.ini @@ -597,9 +597,6 @@ loan_history_download_page = "Ladda lånehistorik (del %%page%%)" loan_history_download_csv = "CSV" loan_history_download_ods = "OpenOffice (ods)" loan_history_download_xlsx = "Excel (xlsx)" -loan_history_info = "Sidorna laddas högst %%total%%" -loan_history_pages = "Sidorna tillgängliga för nedladdning: %%total%%" -loan_history_choose_file_format = "Välja filformat" loan_history_purge = "Rensa historiken" loan_history_purge_prompt_html = "Är du säker på att du vill rensa din utlåningshistorik? Raderad historik kan inte återskapas." loan_history_purge_selected = "Radera valda" diff --git a/themes/finna2/templates/checkouts/downloadhistory.phtml b/themes/finna2/templates/checkouts/downloadhistory.phtml deleted file mode 100644 index d21ca6f40f3..00000000000 --- a/themes/finna2/templates/checkouts/downloadhistory.phtml +++ /dev/null @@ -1,34 +0,0 @@ - -headTitle($this->translate('loan_history_download')); - - // Set up breadcrumbs: - $this->layout()->breadcrumbs = '
  • ' . $this->transEsc('Your Account') . '
  • ' . $this->transEsc('Loan History') . '
  • '; -?> -context($this)->renderInContext('myresearch/menu.phtml', ['active' => 'historicLoans']); ?> - -
    -

    transEsc('loan_history_download')?>

    -
    - -
    - transEsc('loan_history_info', ['%%total%%' => $this->pagesDownloadCounter])?> -
    - transEsc('loan_history_pages', ['%%total%%' => $this->pagesTotal])?> -
    - - -
    -
    - - -
    - -
    -
    - From 4497c6ddeaf89b2d26db4572cc501f0d8340d2db Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Mon, 13 Jan 2025 12:51:09 +0200 Subject: [PATCH 10/24] Adjusted translation, reverted change to demo driver --- local/languages/finna/en-gb.ini | 2 +- local/languages/finna/fi.ini | 2 +- local/languages/finna/se.ini | 2 +- local/languages/finna/sv.ini | 2 +- module/VuFind/src/VuFind/ILS/Driver/Demo.php | 2 +- themes/finna2/js/finna-transaction-history.js | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/local/languages/finna/en-gb.ini b/local/languages/finna/en-gb.ini index 3a6d9aff9b0..1d3b2d0f1a2 100644 --- a/local/languages/finna/en-gb.ini +++ b/local/languages/finna/en-gb.ini @@ -605,7 +605,7 @@ list-tags-info = "Add a new keyword" Loading = "Loading" Loan Details = "Loan Details" loan_history_download = "Download loan history" -loan_history_download_part = "Download loan history (part %%part%%)" +loan_history_download_part = "Download loan history (part %%part%%/%%lastPart%%)" loan_history_download_csv = "CSV" loan_history_download_ods = "OpenOffice (ods)" loan_history_download_xlsx = "Excel (xlsx)" diff --git a/local/languages/finna/fi.ini b/local/languages/finna/fi.ini index 957ec056888..0010164d629 100644 --- a/local/languages/finna/fi.ini +++ b/local/languages/finna/fi.ini @@ -595,7 +595,7 @@ list-tags-info = "Lisää uusi avainsana" Loading = "Ladataan" Loan Details = "Lainan tiedot" loan_history_download = "Lataa lainaushistoria" -loan_history_download_part = "Lataa lainaushistoria (osa %%part%%)" +loan_history_download_part = "Lataa lainaushistoria (osa %%part%%/%%lastPart%%)" loan_history_download_csv = "CSV" loan_history_download_ods = "OpenOffice (ods)" loan_history_download_xlsx = "Excel (xlsx)" diff --git a/local/languages/finna/se.ini b/local/languages/finna/se.ini index ddba3b2b468..ddfe5902b6c 100644 --- a/local/languages/finna/se.ini +++ b/local/languages/finna/se.ini @@ -577,7 +577,7 @@ list-tags-info = "Lasit ođđa beassansáni" Loading = "Láddejuvvo" Loan Details = "Luoikama dieđut" loan_history_download = "Doalvvo visot" -loan_history_download_page = "Doalvvo visot (siidu %%page%%)" +loan_history_download_part = "Doalvvo visot (siidu %%part%%/%%lastPart%%)" loan_history_download_csv = "Doalvvo CSV" loan_history_download_ods = "Doalvvo OpenOffice (ods)" loan_history_download_xlsx = "Doalvvo Excel (xlsx)" diff --git a/local/languages/finna/sv.ini b/local/languages/finna/sv.ini index 46a9cdae6e3..5a1fa0b53ef 100644 --- a/local/languages/finna/sv.ini +++ b/local/languages/finna/sv.ini @@ -593,7 +593,7 @@ list-tags-info = "Lägg till nytt nyckelord" Loading = "Laddar" Loan Details = "Information om lånet" loan_history_download = "Ladda lånehistorik" -loan_history_download_page = "Ladda lånehistorik (del %%page%%)" +loan_history_download_part = "Ladda lånehistorik (del %%part%%/%%lastPart%%)" loan_history_download_csv = "CSV" loan_history_download_ods = "OpenOffice (ods)" loan_history_download_xlsx = "Excel (xlsx)" diff --git a/module/VuFind/src/VuFind/ILS/Driver/Demo.php b/module/VuFind/src/VuFind/ILS/Driver/Demo.php index 400216d1cba..8e413fa559c 100644 --- a/module/VuFind/src/VuFind/ILS/Driver/Demo.php +++ b/module/VuFind/src/VuFind/ILS/Driver/Demo.php @@ -1384,7 +1384,7 @@ protected function getRandomHistoricTransactionList() $trans = rand() % 10 - 1 > 0 ? rand() % 15 : 0; $transList = []; - for ($i = 0; $i < 10000; $i++) { + for ($i = 0; $i < $trans; $i++) { // Checkout date $relative = rand() % 300; $checkoutDate = strtotime("now -$relative days"); diff --git a/themes/finna2/js/finna-transaction-history.js b/themes/finna2/js/finna-transaction-history.js index a1f37af5a4c..212d961c8f6 100644 --- a/themes/finna2/js/finna-transaction-history.js +++ b/themes/finna2/js/finna-transaction-history.js @@ -30,7 +30,7 @@ finna.transactionHistory = (function transactionHistory() { function syncButtonText(element) { const toggleButton = element.querySelector(toggleButtonSelector); const textContent = VuFind.translate('loan_history_download_part'); - toggleButton.textContent = `${textContent.replace('%%part%%', element.dataset.currentPart)} `; + toggleButton.textContent = `${textContent.replace('%%part%%', element.dataset.currentPart).replace('%%lastPart%%', element.dataset.lastPart)} `; toggleButton.append(VuFind.icon('show-more', {}, true)); } From 81b632639991e1706700f0008ea66aa9341f5b95 Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Mon, 13 Jan 2025 12:54:04 +0200 Subject: [PATCH 11/24] Adjusted page numbers --- .../Finna/src/Finna/AjaxHandler/GetTransactionHistory.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/module/Finna/src/Finna/AjaxHandler/GetTransactionHistory.php b/module/Finna/src/Finna/AjaxHandler/GetTransactionHistory.php index ff70113e766..9fc0a95e58e 100644 --- a/module/Finna/src/Finna/AjaxHandler/GetTransactionHistory.php +++ b/module/Finna/src/Finna/AjaxHandler/GetTransactionHistory.php @@ -195,12 +195,12 @@ private function getHistoryAsFile( if ($pagesCount > 1) { $pagesToFetch = ceil($this->batchLimit / $limit); $firstPageToFetch += ($pagesToFetch * ($part - 1)); - $lastPageToFetch += min(($pagesToFetch * $part), $pagesCount); + $lastPageToFetch += min(($pagesToFetch * $part) - 1, $pagesCount); } $tmp = fopen('php://temp/maxmemory:' . (5 * 1024 * 1024), 'r+'); $transactions = []; - for ($i = $firstPageToFetch; $i < $lastPageToFetch; $i++) { + for ($i = $firstPageToFetch; $i <= $lastPageToFetch; $i++) { $result = $this->ils->getMyTransactionHistory($patron, ['page' => $i, 'limit' => $limit]); // Break if no transactions found if (empty($result['transactions'])) { @@ -270,7 +270,7 @@ private function getHistoryAsFile( } $writer = new $this->exportFormats[$fileFormat]['writer']($spreadsheet); $writer->save($tmp); - $fileName = implode('-', ['finna-loan-history-pages', $firstPageToFetch, $lastPageToFetch - 1]); + $fileName = implode('-', ['finna-loan-history-pages', $firstPageToFetch, $lastPageToFetch]); $fileName .= ".$fileFormat"; rewind($tmp); From 42c1d1854cef56bfbb47aa0e47c78e2d79683a5e Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Mon, 13 Jan 2025 12:57:29 +0200 Subject: [PATCH 12/24] Remove useless ilsdefaults --- module/Finna/config/module.config.php | 5 +-- .../Finna/src/Finna/ILS/Enum/ILSDefaults.php | 45 ------------------- .../finna2/templates/checkouts/history.phtml | 2 +- 3 files changed, 2 insertions(+), 50 deletions(-) delete mode 100644 module/Finna/src/Finna/ILS/Enum/ILSDefaults.php diff --git a/module/Finna/config/module.config.php b/module/Finna/config/module.config.php index d80bb9e9d7e..85cb04d22bd 100644 --- a/module/Finna/config/module.config.php +++ b/module/Finna/config/module.config.php @@ -1087,10 +1087,7 @@ 'newLibraryCardPassword' => 'newPassword/[:id]', 'librarycards-displaybarcode' => 'displayBarcode/[:id]', ], - 'MyResearch' => [ - 'sortList' => 'SortList/[:id]', - 'downloadLoanHistory' => 'DownloadLoanHistory/[:part]/[:format]', - ], + 'MyResearch' => ['sortList' => 'SortList/[:id]'], 'ReservationList' => [ 'reservationlist-displaylists' => 'DisplayLists', 'reservationlist-displaylist' => 'DisplayList/[:id]', diff --git a/module/Finna/src/Finna/ILS/Enum/ILSDefaults.php b/module/Finna/src/Finna/ILS/Enum/ILSDefaults.php deleted file mode 100644 index 3ef73a2b986..00000000000 --- a/module/Finna/src/Finna/ILS/Enum/ILSDefaults.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org Main Site - */ - -namespace Finna\ILS\Enum; - -/** - * Enum for representing default hardcoded values found in ILS specific methods. - * - * @category VuFind - * @package ILS_Drivers - * @author Ere Maijala - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org Main Site - */ -enum ILSDefaults: int -{ - case TRANSACTION_LIMIT_20 = 20; - case TRANSACTION_LIMIT_50 = 50; -} diff --git a/themes/finna2/templates/checkouts/history.phtml b/themes/finna2/templates/checkouts/history.phtml index 8559776a297..70f1e6990fe 100644 --- a/themes/finna2/templates/checkouts/history.phtml +++ b/themes/finna2/templates/checkouts/history.phtml @@ -89,7 +89,7 @@ transactions)): ?>
    - + { + finna.checkoutHistory.init(document.querySelector('div.js-download-loan-history')); + }); + JS; + +echo $this->inlineScript()->appendScript($js); +?> diff --git a/themes/finna2/theme.config.php b/themes/finna2/theme.config.php index 8b1b5482dbe..833608fbeab 100644 --- a/themes/finna2/theme.config.php +++ b/themes/finna2/theme.config.php @@ -267,7 +267,7 @@ 'finna-select-a11y.js', 'finna-a11y.js', 'finna-datepicker.js', - 'finna-transaction-history.js', + 'finna-checkout-history.js', 'finna-reservation-list.js', 'components/finna-bazaar-browse-bar.js', 'components/finna-md-editable.js', From 39061abedff96c4e7fc68e7cf91ce3b894b5377f Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Wed, 15 Jan 2025 19:39:55 +0200 Subject: [PATCH 16/24] Added comments --- .../Finna/src/Finna/AjaxHandler/GetCheckoutHistory.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/module/Finna/src/Finna/AjaxHandler/GetCheckoutHistory.php b/module/Finna/src/Finna/AjaxHandler/GetCheckoutHistory.php index ccdf290608e..a1766294f5d 100644 --- a/module/Finna/src/Finna/AjaxHandler/GetCheckoutHistory.php +++ b/module/Finna/src/Finna/AjaxHandler/GetCheckoutHistory.php @@ -47,8 +47,18 @@ */ class GetCheckoutHistory extends \VuFind\AjaxHandler\AbstractIlsAndUserAction { + /** + * Cache for patron + * + * @var array + */ protected array $cachedPatron = []; + /** + * Cache for function config. + * + * @var array + */ protected array $cachedFunctionConfig = []; /** From 9ba8d20d5af9be25c0261f47bd3f17f8fe04c7ef Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Wed, 15 Jan 2025 19:41:13 +0200 Subject: [PATCH 17/24] Removed unused parameter type --- themes/finna2/js/finna-checkout-history.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes/finna2/js/finna-checkout-history.js b/themes/finna2/js/finna-checkout-history.js index 2fe438a7f38..7f0c6c110b9 100644 --- a/themes/finna2/js/finna-checkout-history.js +++ b/themes/finna2/js/finna-checkout-history.js @@ -83,7 +83,7 @@ finna.checkoutHistory = (function checkoutHistory() { * @returns {void} */ function init(element) { - fetch (`${VuFind.path}/AJAX/JSON?method=getCheckoutHistory&type=status`) + fetch (`${VuFind.path}/AJAX/JSON?method=getCheckoutHistory`) .then(response => { if (!response.ok) { throw new Error(''); From 6ca8bb4a9169e2d94a8753c84def8d15e2bb3d3e Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Wed, 15 Jan 2025 19:42:52 +0200 Subject: [PATCH 18/24] Adjusted js comments --- themes/finna2/js/finna-checkout-history.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/themes/finna2/js/finna-checkout-history.js b/themes/finna2/js/finna-checkout-history.js index 7f0c6c110b9..86419ae5864 100644 --- a/themes/finna2/js/finna-checkout-history.js +++ b/themes/finna2/js/finna-checkout-history.js @@ -7,7 +7,7 @@ finna.checkoutHistory = (function checkoutHistory() { /** * Calculates the current page for the button limited by the last possible page to be downloaded. - * @param {HTMLButtonElement} element Button element to be clicked to download history + * @param {HTMLButtonElement} element Element containing toggleButton * @returns {void} */ function setNextPage(element) { @@ -18,7 +18,7 @@ finna.checkoutHistory = (function checkoutHistory() { /** * Sets the buttons text content to match for the next page to be downloaded if clicked. - * @param {HTMLButtonElement} element Button element to be clicked to download history + * @param {HTMLButtonElement} element Element containing toggleButton * @returns {void} */ function syncButtonText(element) { @@ -28,7 +28,6 @@ finna.checkoutHistory = (function checkoutHistory() { toggleButton.append(VuFind.icon('show-more', {}, true)); } - /** * Display a spinner inside toggle button * @param {HTMLElement} element Element containing toggleButton @@ -79,7 +78,7 @@ finna.checkoutHistory = (function checkoutHistory() { /** * Initializes an element containing format buttons to allow for loading checkout history in batches. - * @param {HTMLButtonElement} element Button element to be clicked to download history + * @param {HTMLButtonElement} element Element to be initialized * @returns {void} */ function init(element) { From 6931dbf417c8f6282ade1deaf783dddd06f84346 Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Thu, 16 Jan 2025 11:19:32 +0200 Subject: [PATCH 19/24] Removed test variable.. --- module/Finna/src/Finna/AjaxHandler/GetCheckoutHistory.php | 1 - 1 file changed, 1 deletion(-) diff --git a/module/Finna/src/Finna/AjaxHandler/GetCheckoutHistory.php b/module/Finna/src/Finna/AjaxHandler/GetCheckoutHistory.php index a1766294f5d..31950eb4994 100644 --- a/module/Finna/src/Finna/AjaxHandler/GetCheckoutHistory.php +++ b/module/Finna/src/Finna/AjaxHandler/GetCheckoutHistory.php @@ -142,7 +142,6 @@ public function getCheckoutHistoryResult(int $page = 1, ?int $limit = null): arr } return [ 'success' => true, - 'status' => 'wat', 'function_result' => $result, 'pageOptions' => $pageOptions, ]; From 1d742b51f28efbfa538e6fbedaed6a3ec233c642 Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Thu, 16 Jan 2025 12:08:16 +0200 Subject: [PATCH 20/24] Adjusted to calculate history properly --- .../Finna/AjaxHandler/GetCheckoutHistory.php | 33 ++++++++++++++++++- .../AjaxHandler/GetCheckoutHistoryFile.php | 22 ++++++------- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/module/Finna/src/Finna/AjaxHandler/GetCheckoutHistory.php b/module/Finna/src/Finna/AjaxHandler/GetCheckoutHistory.php index 31950eb4994..de365668fce 100644 --- a/module/Finna/src/Finna/AjaxHandler/GetCheckoutHistory.php +++ b/module/Finna/src/Finna/AjaxHandler/GetCheckoutHistory.php @@ -81,6 +81,9 @@ public function __construct( protected int $batchLimit = 1000, protected int $defaultPageSize = 50 ) { + if ($this->batchLimit < $defaultPageSize) { + $this->batchLimit = $defaultPageSize; + } parent::__construct($ss, $ils, $ilsAuthenticator, $user); } @@ -98,7 +101,35 @@ public function handleRequest(Params $params) if ($result['success'] === false) { return $this->formatResponse($result['message'], $result['status']); } - return $this->formatResponse(['parts' => ceil(($result['function_result']['count'] ?? 1) / $this->batchLimit)]); + $calculatedResults = $this->calculateLimitsFromResult($result); + return $this->formatResponse(['parts' => $calculatedResults['parts']]); + } + + /** + * Calculate limits used to fetch data from the results obtained from getCheckoutHistoryResult. + * + * @param array $result Checkout history result + * + * @return array + */ + public function calculateLimitsFromResult(array $result): array + { + $resultCount = $result['function_result']['count'] ?? 1; + $paginationHelper = new PaginationHelper(); + $paginator = $paginationHelper->getPaginator( + $result['pageOptions'], + $result['function_result']['count'], + $result['function_result']['transactions'] + ); + $pageLimit = $paginator ? $paginator->getItemCountPerPage() : $this->defaultPageSize; + $parts = $pageLimit > $this->batchLimit + ? floor($resultCount / $this->batchLimit) + : ceil($resultCount / $this->batchLimit); + return [ + 'pageLimit' => $paginator ? $paginator->getItemCountPerPage() : $this->defaultPageSize, + 'pageCount' => $paginator ? $paginator->count() : 1, + 'parts' => $parts, + ]; } /** diff --git a/module/Finna/src/Finna/AjaxHandler/GetCheckoutHistoryFile.php b/module/Finna/src/Finna/AjaxHandler/GetCheckoutHistoryFile.php index dc627458e14..57cc47f85e9 100644 --- a/module/Finna/src/Finna/AjaxHandler/GetCheckoutHistoryFile.php +++ b/module/Finna/src/Finna/AjaxHandler/GetCheckoutHistoryFile.php @@ -37,7 +37,6 @@ use PhpOffice\PhpSpreadsheet\Writer\Csv; use PhpOffice\PhpSpreadsheet\Writer\Ods; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; -use VuFind\ILS\PaginationHelper; /** * GetCheckoutHistoryFile AJAX handler @@ -92,18 +91,16 @@ public function handleRequest(Params $params) return $this->formatResponse($result['message'], $result['status']); } try { - $paginationHelper = new PaginationHelper(); - $paginator = $paginationHelper->getPaginator( - $result['pageOptions'], - $result['function_result']['count'], - $result['function_result']['transactions'] - ); // Get requested history part as a file to be downloaded $part = $params->fromQuery('part', 1); $fileFormat = $params->fromQuery('format', 'csv'); - $pageLimit = $paginator ? $paginator->getItemCountPerPage() : $this->defaultPageSize; - $pagesCount = $paginator ? $paginator->count() : 1; - return $this->getHistoryAsFile($part, $pageLimit, $pagesCount, $fileFormat); + $calculatedResults = $this->calculateLimitsFromResult($result); + return $this->getHistoryAsFile( + $part, + $calculatedResults['pageLimit'], + $calculatedResults['pageCount'], + $fileFormat + ); } catch (Exception $e) { return $this->formatResponse( $this->translate('An error has occurred'), @@ -213,7 +210,10 @@ private function getHistoryAsFile( } $writer = new $this->exportFormats[$fileFormat]['writer']($spreadsheet); $writer->save($tmp); - $fileName = implode('-', ['finna-loan-history-pages', $firstPageToFetch, $lastPageToFetch]); + $fileName = 'finna-loan-history-parts-' . $firstPageToFetch; + if ($firstPageToFetch !== $lastPageToFetch) { + $fileName .= '-' . $lastPageToFetch; + } $fileName .= ".$fileFormat"; rewind($tmp); From 6125ab80abf2f1eb23f42b987377212b90bbf456 Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Thu, 16 Jan 2025 14:34:42 +0200 Subject: [PATCH 21/24] Added test for GetCheckoutHistory --- .../Finna/AjaxHandler/GetCheckoutHistory.php | 5 +- .../AjaxHandler/GetCheckoutHistoryTest.php | 281 ++++++++++++++++++ 2 files changed, 284 insertions(+), 2 deletions(-) create mode 100644 module/Finna/tests/unit-tests/src/FinnaTest/AjaxHandler/GetCheckoutHistoryTest.php diff --git a/module/Finna/src/Finna/AjaxHandler/GetCheckoutHistory.php b/module/Finna/src/Finna/AjaxHandler/GetCheckoutHistory.php index de365668fce..340d5221578 100644 --- a/module/Finna/src/Finna/AjaxHandler/GetCheckoutHistory.php +++ b/module/Finna/src/Finna/AjaxHandler/GetCheckoutHistory.php @@ -148,10 +148,11 @@ public function getCheckoutHistoryResult(int $page = 1, ?int $limit = null): arr return compact('success', 'message', 'status'); }; if (!$this->cachedPatron) { - $this->cachedPatron = $this->ilsAuthenticator->storedCatalogLogin(); - if (!$this->user || !$this->cachedPatron) { + $patron = $this->ilsAuthenticator->storedCatalogLogin(); + if (!$this->user || !$patron) { return $getErrorMessage('You must be logged in first', self::STATUS_HTTP_NEED_AUTH); } + $this->cachedPatron = $patron; } // Check function config if (!$this->cachedFunctionConfig) { diff --git a/module/Finna/tests/unit-tests/src/FinnaTest/AjaxHandler/GetCheckoutHistoryTest.php b/module/Finna/tests/unit-tests/src/FinnaTest/AjaxHandler/GetCheckoutHistoryTest.php new file mode 100644 index 00000000000..63250741fab --- /dev/null +++ b/module/Finna/tests/unit-tests/src/FinnaTest/AjaxHandler/GetCheckoutHistoryTest.php @@ -0,0 +1,281 @@ + + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Page + */ + +namespace VuFindTest\AjaxHandler; + +use Finna\AjaxHandler\GetCheckoutHistory; +use Finna\AjaxHandler\GetCheckoutHistoryFactory; +use Laminas\Config\Config; +use VuFind\Auth\ILSAuthenticator; +use VuFind\Auth\Manager; +use VuFind\Db\Entity\UserEntityInterface; +use VuFind\ILS\Connection; + +/** + * GetCheckoutHistory test class. + * + * @category VuFind + * @package Tests + * @author Juha Luoma + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Page + */ +class GetCheckoutHistoryTest extends \VuFindTest\Unit\AjaxHandlerTestCase +{ + /** + * Set up a GetCheckoutHistory handler for testing. + * + * @param ?UserEntityInterface $user Return value for getUserObject() in auth manager + * @param Config $testConfig Default values for testing config settings + * + * @return GetCheckoutHistory + */ + protected function getHandler( + ?UserEntityInterface $user = null, + Config $testConfig = new Config([]) + ): GetCheckoutHistory { + // Set up auth manager with user: + $this->container->set(Manager::class, $this->getMockAuthManager($user)); + $mockConfigManager = $this->container->createMock(\VuFind\Config\PluginManager::class, ['get']); + $mockConfigManager->expects($this->once())->method('get')->with('config')->willReturn($testConfig); + $this->container->set(\VuFind\Config\PluginManager::class, $mockConfigManager); + // Build the handler: + $factory = new GetCheckoutHistoryFactory(); + return $factory($this->container, GetCheckoutHistory::class); + } + + /** + * Data provider for testSuccess + * + * @return array + */ + public static function getSuccessfulData(): array + { + return [ + 'batch limit is higher' => [ + 50, + 1000, + [ + 'success' => true, + 'transactions' => [[]], + 'count' => 10000, + ], + ['parts' => 10], + ], + 'batch limit is same' => [ + 50, + 50, + [ + 'success' => true, + 'transactions' => [[]], + 'count' => 10000, + ], + ['parts' => 200], + ], + 'batch limit is lower' => [ + 50, + 10, + [ + 'success' => true, + 'transactions' => [[]], + 'count' => 10000, + ], + ['parts' => 200], + ], + 'results lower than batch limit' => [ + 50, + 1000, + [ + 'success' => true, + 'transactions' => [[]], + 'count' => 21, + ], + ['parts' => 1], + ], + 'no history' => [ + 50, + 10, + [ + 'success' => true, + 'transactions' => [], + 'count' => 0, + ], + ['parts' => 0], + ], + ]; + } + + /** + * Data provider for testSuccess + * + * @return array + */ + public static function getFailuresData(): array + { + return [ + 'failure from getMyTransactions' => [ + 50, + 1000, + [ + 'success' => false, + 'transactions' => [[]], + 'count' => 10000, + ], + ['An error has occurred', 500], + ], + ]; + } + + /** + * Test successful response + * + * @param int $defaultPageSize Default page size to set in config + * @param int $batchLimit Default batch limit to set in config + * @param array $transactionResult Array containing success, transactions and count of all transactions + * @param array $expected What is the expected result + * + * @return void + * + * @dataProvider getSuccessfulData + */ + public function testSuccess(int $defaultPageSize, int $batchLimit, array $transactionResult, array $expected) + { + $this->assertEquals( + [$expected], + $this->runSuccessfulTest($defaultPageSize, $batchLimit, $transactionResult) + ); + } + + /** + * Test failures + * + * @param int $defaultPageSize Default page size to set in config + * @param int $batchLimit Default batch limit to set in config + * @param array $transactionResult Array containing success, transactions and count of all transactions + * @param array $expected What is the expected result + * + * @return void + * + * @dataProvider getFailuresData + */ + public function testFailures(int $defaultPageSize, int $batchLimit, array $transactionResult, array $expected) + { + $this->assertEquals( + $expected, + $this->runSuccessfulTest($defaultPageSize, $batchLimit, $transactionResult) + ); + } + + /** + * Test the AJAX handler's response when no one is logged in. + * + * @return void + */ + public function testLoggedOutUser(): void + { + $handler = $this->getHandler(); + $this->assertEquals( + ['You must be logged in first', 401], + $handler->handleRequest($this->getParamsHelper([])) + ); + } + + /** + * Generic support function for successful request tests. + * + * @param int $limit Default page limit + * @param int $batchLimit Default batch limit + * @param array $transactionResult Result from getMyTransactionHistory + * + * @return array + */ + protected function runSuccessfulTest($limit, $batchLimit, $transactionResult = []): array + { + /** + * Create a wrapper class for connection as it is little bit difficult to mock + */ + $wrapperClass = new class ($transactionResult) extends Connection { + /** + * Override constructor + * + * @param array $transactionResult Result from getMyTransactionHistory + * + * @return void + */ + public function __construct(protected array $transactionResult = []) + { + } + + /** + * Override checkFunction + * + * @param string $function Function to check + * @param ?array $params Params to use or null + * + * @return array + */ + public function checkFunction($function, $params = null) + { + return [ + 'max_results' => 50, + ]; + } + + /** + * GetMyTransactionHistory mock + * + * @param array $patron Mock patron array + * @param array $params Contains info about ils specified limits + * + * @return array + */ + public function getMyTransactionHistory($patron, $params): array + { + return $this->transactionResult ?: [ + 'success' => true, + 'transactions' => [[]], + 'count' => 10000, + ]; + } + }; + $ilsAuth = $this->container + ->createMock(ILSAuthenticator::class, ['storedCatalogLogin']); + $ilsAuth->expects($this->any())->method('storedCatalogLogin')->willReturn([3]); + $this->container->set(Connection::class, $wrapperClass); + $this->container->set(ILSAuthenticator::class, $ilsAuth); + $config = new Config([ + 'Catalog' => [ + 'historic_loan_page_size' => $limit, + 'loan_history_download_batch_limit' => $batchLimit, + ], + ]); + $handler = $this->getHandler($this->getMockUser(), $config); + return $handler->handleRequest($this->getParamsHelper([])); + } +} From c6a274ccea1db7221d3daeb1409b8502b796fdd4 Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Thu, 16 Jan 2025 15:40:16 +0200 Subject: [PATCH 22/24] small tuning to test --- .../AjaxHandler/GetCheckoutHistoryTest.php | 151 +++++++++++------- 1 file changed, 91 insertions(+), 60 deletions(-) diff --git a/module/Finna/tests/unit-tests/src/FinnaTest/AjaxHandler/GetCheckoutHistoryTest.php b/module/Finna/tests/unit-tests/src/FinnaTest/AjaxHandler/GetCheckoutHistoryTest.php index 63250741fab..1ee088faa7b 100644 --- a/module/Finna/tests/unit-tests/src/FinnaTest/AjaxHandler/GetCheckoutHistoryTest.php +++ b/module/Finna/tests/unit-tests/src/FinnaTest/AjaxHandler/GetCheckoutHistoryTest.php @@ -27,7 +27,7 @@ * @link https://vufind.org Main Page */ -namespace VuFindTest\AjaxHandler; +namespace FinnaTest\AjaxHandler; use Finna\AjaxHandler\GetCheckoutHistory; use Finna\AjaxHandler\GetCheckoutHistoryFactory; @@ -36,6 +36,7 @@ use VuFind\Auth\Manager; use VuFind\Db\Entity\UserEntityInterface; use VuFind\ILS\Connection; +use VuFind\ILS\PaginationHelper; /** * GetCheckoutHistory test class. @@ -78,56 +79,86 @@ protected function getHandler( public static function getSuccessfulData(): array { return [ - 'batch limit is higher' => [ - 50, - 1000, - [ - 'success' => true, - 'transactions' => [[]], - 'count' => 10000, - ], - ['parts' => 10], - ], - 'batch limit is same' => [ - 50, - 50, - [ - 'success' => true, - 'transactions' => [[]], - 'count' => 10000, - ], - ['parts' => 200], - ], - 'batch limit is lower' => [ - 50, - 10, - [ - 'success' => true, - 'transactions' => [[]], - 'count' => 10000, - ], - ['parts' => 200], - ], - 'results lower than batch limit' => [ - 50, - 1000, - [ - 'success' => true, - 'transactions' => [[]], - 'count' => 21, - ], - ['parts' => 1], - ], - 'no history' => [ - 50, - 10, - [ - 'success' => true, - 'transactions' => [], - 'count' => 0, - ], - ['parts' => 0], - ], + 'batch limit is higher' => [ + 50, + 1000, + [ + 'success' => true, + 'transactions' => [[]], + 'count' => 10000, + ], + ['parts' => 10], + ], + 'batch limit is same' => [ + 50, + 50, + [ + 'success' => true, + 'transactions' => [[]], + 'count' => 10000, + ], + ['parts' => 200], + ], + 'batch limit is lower' => [ + 50, + 10, + [ + 'success' => true, + 'transactions' => [[]], + 'count' => 10000, + ], + ['parts' => 200], + ], + 'results lower than batch limit' => [ + 50, + 1000, + [ + 'success' => true, + 'transactions' => [[]], + 'count' => 21, + ], + ['parts' => 1], + ], + 'no history' => [ + 50, + 10, + [ + 'success' => true, + 'transactions' => [], + 'count' => 0, + ], + ['parts' => 0], + ], + 'different default than usual' => [ + 15, + 1000, + [ + 'success' => true, + 'transactions' => [], + 'count' => 10000, + ], + ['parts' => 10], + ], + 'test with very small limits' => [ + 3, + 2, + [ + 'success' => true, + 'transactions' => [], + 'count' => 7, + ], + ['parts' => 3], + ], + 'test with nothing set as limits' => [ + 0, + 1000, + [ + 'success' => true, + 'transactions' => [], + 'count' => 10000, + ], + ['parts' => 10], + ], ]; } @@ -139,16 +170,16 @@ public static function getSuccessfulData(): array public static function getFailuresData(): array { return [ - 'failure from getMyTransactions' => [ - 50, - 1000, - [ - 'success' => false, - 'transactions' => [[]], - 'count' => 10000, + 'failure from getMyTransactions' => [ + 50, + 1000, + [ + 'success' => false, + 'transactions' => [[]], + 'count' => 10000, + ], + ['An error has occurred', 500], ], - ['An error has occurred', 500], - ], ]; } From dc5359c34435a88d5377aebca3f1789eee313226 Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Fri, 17 Jan 2025 09:40:16 +0200 Subject: [PATCH 23/24] Fix --- .../src/FinnaTest/AjaxHandler/GetCheckoutHistoryTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/module/Finna/tests/unit-tests/src/FinnaTest/AjaxHandler/GetCheckoutHistoryTest.php b/module/Finna/tests/unit-tests/src/FinnaTest/AjaxHandler/GetCheckoutHistoryTest.php index 1ee088faa7b..de83ce3bec3 100644 --- a/module/Finna/tests/unit-tests/src/FinnaTest/AjaxHandler/GetCheckoutHistoryTest.php +++ b/module/Finna/tests/unit-tests/src/FinnaTest/AjaxHandler/GetCheckoutHistoryTest.php @@ -36,7 +36,6 @@ use VuFind\Auth\Manager; use VuFind\Db\Entity\UserEntityInterface; use VuFind\ILS\Connection; -use VuFind\ILS\PaginationHelper; /** * GetCheckoutHistory test class. From 3c089fbbde1c9f0d4326e1b2c8b64e940debfbeb Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Mon, 10 Feb 2025 14:15:59 +0200 Subject: [PATCH 24/24] Added same padding for buttons as anchors had inside dropdown li --- themes/finna2/scss/global/dropdowns-bootstrap.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes/finna2/scss/global/dropdowns-bootstrap.scss b/themes/finna2/scss/global/dropdowns-bootstrap.scss index 1bebe83fd6e..48dbe4dd061 100644 --- a/themes/finna2/scss/global/dropdowns-bootstrap.scss +++ b/themes/finna2/scss/global/dropdowns-bootstrap.scss @@ -27,7 +27,7 @@ border-bottom: none; } - > li > a { + > li > a, > li > button { padding: 7px 15px; } }