The ILL Vue app currently reads ILLModule and ILLPartnerCode through the system preferences service. That service requires parameters/manage_sysprefs, so a staff user with ILL permissions but without system preference administration permissions cannot load the ILL module.
Add an ILL-specific /ill/config REST endpoint protected by the ill permission, and switch the ILL Vue app to load its configuration from that endpoint. This follows the module-specific configuration endpoint pattern introduced by bug 33606 for the same manage_sysprefs problem in the ERM Vue app.
Security/compatibility considerations: the endpoint returns only allow-listed, non-secret ILL configuration values needed by the ILL Vue app. It does not expose the generic system preferences API, and /api/v1/sysprefs remains restricted to parameters/manage_sysprefs.
Regression test coverage: the new API test verifies that a staff user with the ill permission can read /ill/config, that a staff user without the ill permission cannot read it, and that the same ILL-only user still cannot access /api/v1/sysprefs.
Test plan:
1. prove -I. -It/lib t/db_dependent/api/v1/ill_config.t
2. prove -I. -It/lib t/db_dependent/api/v1/ill_users.t
Signed-off-by: David Nind <david@davidnind.com>
Amended-by: Jonathan Druart
chmod +x t/db_dependent/api/v1/ill_config.t
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Built-in validation checks weren't functioning because the variable
required.sex was not getting set. Ensure that variable gets set, and
remove manual validation code that is no longer needed.
Signed-off-by: Emily Lamancusa <emily.lamancusa@montgomerycountymd.gov>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Solves this bug and enhances the user experiance by replacing the old radio buttons with a less-confusing dropdown menu.
Test plan:
1. Open the setting "PatronSelfRegistrationBorrowerMandatoryField", find Gender(sex) and mark it as not required.
2. Go to the self registration form. No 'Required' label under gender.
3. Go back to the setting "PatronSelfRegistrationBorrowerMandatoryField", find Gender(sex) and mark it as required.
4. Go to the self registration form. The 'Required' label is there.
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Emily Lamancusa <emily.lamancusa@montgomerycountymd.gov>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Test plan:
1. Set SuspendHoldsIntranet to "Don't allow"
2. Place a hold for a patron
3. Open the patron holds table
4. Confirm the Suspend button is visible in the Suspend column
5. Apply the patch
6. Reload the patron holds table
7. Confirm the Suspend button is no longer visible
8. Set SuspendHoldsIntranet to "Allow"
9. Reload the patron holds table
10. Confirm the Suspend button is visible again
Signed-off-by: Anneli Österman <anneli.osterman@koha-suomi.fi>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Typo in edit SQL when authorised values category is wrong : 'op=edit_formid='
Test plan:
1) Create a new authorised values category WRONG
2) Create a new SQL report with : SELECT * FROM biblio WHERE title LIKE <<val|WRONG>>
3) Save the report
4) Delete authorised values category WRONG
5) Run the SQL report
6) You see message 'The authorized value category (WRONG) you selected does not exist.'
7) Click on 'Edit SQL'
=> You comme back to editing the correct SQL report
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
If "Show/Hide filters" link is clicked, the "Manage bundle" buttons do not longer work.
Test plan:
Edit a record, set leader 7=collection
In the holding list click "Manage bundle"
Click "Show filters"
Click one of the "Manage bundle" button
=> Without this patch nothing happens
=> With this patch applied the table displays the nested table with the
bundle details
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Anni <anni.maki-mantila@turku.fi>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
The pending bookings page lists items that have not been collected yet,
but the status filter added when the server-side active pre-filter was
removed included 'issued' bookings, so bookings reappeared on the list
after the item had been checked out.
- restrict the status filter to 'new'
Test plan:
1. Place a booking starting today and open Circulation > Bookings to
collect; the booking is listed
2. Check the item out to the booking patron; reload the list and
confirm the booking is gone
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
The rewrite of js/tables/bookings.js in this patchset builds on
AdditionalFilters, which is provided by js/additional-filters.js. The
patron details page loads that asset but the circulation page did not,
so the bookings tab on circ/circulation.pl died with 'AdditionalFilters
is not defined' and the table never initialised.
Test plan:
1) Check out to a patron with bookings and open the Bookings tab on
the checkout page; confirm the table renders and no JS error is
logged in the console
Sponsored-by: Westminster City Council <https://www.westminster.gov.uk/>
Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
The bookings REST controller previously applied filter_by_active (status IN
'new','issued') as a server-side pre-filter. Removing that pre-filter means
callers that relied on it must now supply an explicit status filter.
- pendingbookings.tt: add status filter to additional_filters so the
pending-bookings-to-collect page still shows only new+issued bookings
- place_booking.js: correct status values from the obsolete 'pending','active'
(never valid in the schema) to the correct 'new','issued'
Test plan:
1. Navigate to Circulation > Bookings to collect.
- Confirm only bookings with status "New" or "Issued" are listed.
- Complete a booking (check out then return the item) and confirm it
disappears from the list.
2. On any biblio with multiple bookings, open the Place booking modal.
- Create overlapping bookings where one is completed or cancelled.
- Confirm the modal does not treat completed/cancelled bookings as active
conflicts when checking availability.
Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Sponsored-by: Westminster City Council <https://www.westminster.gov.uk/>
Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Implements a 4-state booking lifecycle: new → issued (on checkout) →
completed (on return), plus cancelled at any point.
Backend changes:
- AddIssue sets booking status to 'issued' (was incorrectly 'completed')
- AddReturn transitions 'issued' → 'completed' via booking_id on the issue
- filter_by_active updated to status-based: status IN ('new', 'issued');
previously it filtered by date range — active/inactive now reflect booking
lifecycle rather than the current date relative to start/end dates
- _is_final_status_transition reverted to only skip clash detection for
terminal statuses 'cancelled' and 'completed'; 'issued' is active and does
not bypass clash detection
- GET /api/v1/bookings no longer pre-filters to active bookings server-side;
callers must supply an explicit status filter if they need active-only
Display changes:
- Patron bookings tab: replaces the date-based expired/active toggle with
per-status filters (completed, cancelled) using the AdditionalFilters
framework; active bookings (new/issued) are shown by default
- Biblio bookings list: same status-based filters; removes the date-based
expired filter that was still present
- Status column is always visible on both views (was previously hidden on
the patron tab unless expired bookings were shown)
- Status badges: new=bg-success, issued=bg-info, completed/cancelled=bg-secondary
- Timeline isActive check corrected to ['new','issued']
- patron-detail-tabs.inc: rename expired_bookings_count → closed_bookings_count
to reflect status-based (not date-based) counting
- Filter button colour fixed to use $link-color so both views are consistent
Test plan:
1. Enable the EnableBookings system preference.
2. Create a biblio with at least one bookable item.
3. Place a booking for a patron via the biblio's Bookings tab.
- The booking should appear with status badge "New" (green).
4. Check out the booked item to that patron (Circulation → Check out).
- Reload the Bookings tab; the booking should now show "Issued" (blue).
5. Return the item (Circulation → Check in).
- Reload the Bookings tab; the booking should now show "Completed" (grey).
6. Place a second booking and cancel it from the Bookings tab Actions menu.
- The booking should show "Cancelled" (grey), with the reason if provided.
7. On the biblio Bookings tab:
- Completed and cancelled bookings are hidden by default.
- Clicking "Include completed" shows completed bookings.
- Clicking "Include cancelled" shows cancelled bookings.
- Both can be toggled independently.
- The Status column is always visible.
8. Navigate to the patron's detail page → Bookings tab.
- Active bookings (new/issued) are shown by default.
- Completed and cancelled can be toggled independently using the same
filter buttons.
- The Status column is always visible.
9. Confirm via the REST API that GET /api/v1/bookings (no filters) returns
bookings of all statuses, not just active ones.
Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Sponsored-by: Westminster City Council <https://www.westminster.gov.uk/>
Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
To test:
1. Set ReservesControlBranch is set to 'item's home library'
2. Set the deafult 'Holds and bookings policies by item type' for the itype BK to allow holds from patrons from any library, but pickup at CPL only
3. Have a bib owned by another library ( I used MPL ), and bib owned by CPL. Both are the item type BK, and each has one item on the bib.
4. Place a hold for a patron on bib A for pickup at MPL
5. Move the hold to bib B
6. Note that the hold moves successfully, and is still set for pickup at MPL
7. Login and try to trigger the hold, nothing happens
8. APPLY PATCH, restart_all
9. Try spets 3 - 6 again. This time on step 6 you should see a message that the hold cannot be moved.
Signed-off-by: Eric Phetteplace <phette23@gmail.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Builds on the panel-detection logic by having dateChanged report which
panel it opens, so onChange can adjust that panel's "To date" picker
directly without waiting on the slide animations to settle.
- dateChanged returns "showHoliday" when editing, "newHoliday" when adding
- onChange maps that to datecancelrange/dateofrange, in place of the
setTimeout and the :visible check
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
When you are editing holidays "To date" inputs calendar doesn't follow the
"From date" date. Instead calendar offers you today's date/month and
you must click calendar forward to the right date/month. This patch
adds check to determine if user is adding new holiday or editing
existing one and adjusts the code to disable past dates counting from
selected "From date" in both cases.
To test:
1. Navigate to calendar tool (Tools->Calendar).
2. Add new holiday and select "To date" for it.
=> Note that you are unable to select dates past from "From date".
3. Edit existing holiday and select "To date" for it.
=> Note that "To date" input calendar allows selecting dates past
"From date".
=> If you chosed holiday from incoming month, note that "To date"
calendar still opens up to this month.
4. Apply this patch, restart services if needed.
5. Edit existing holiday again.
=> Note that now "To date" inputs calendar works the same way as
it is working when your adding a new holiday.
Sponsored-by: Koha-Suomi Oy
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Test plan:
1) Install another language
2) Navigate to a vendor record
3) The group names should translate correctly and display in the split screen view
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
INSERT INTO action_logs (timestamp, user, module, action, object, info, interface) VALUES
(NOW(), 5, 'CIRCULATION', 'ISSUE', 5,
'{"issue":1,"branchcode":"CPL","itemnumber":1,"confirmations":["TOO_MANY"],"forced":["DEBT"]}', 'intranet'),
(NOW(), 5, 'CIRCULATION', 'RETURN', 5,
'1', 'intranet'),
(NOW(), 5, 'HOLDS', 'CREATE', 7,
'{"hold":7,"biblionumber":1,"itemnumber":1,"confirmations":["HIGHHOLDS"],"forced":["HOLD_POLICY_OVERRIDE"]}', 'intranet');
Test plan:
1) Without the patch applied, run the populate SQL above against the kohadev database.
2) Go to Tools > Log viewer
3) Under Modules, select only Circulation - leave the date range empty and click Submit.
4) Observe the ISSUE row's Info column shows the raw JSON payload as plain text, and the RETURN row shows the bare itemnumber "1" as plain text - neither is a clickable link to the item.
5) Go back, select only the Holds module, click Submit, and observe the CREATE row's Info column likewise shows raw JSON with no hold/item links.
6) Apply the patch.
7) Run yarn build && restart_all, then hard refresh the browser.
8) Repeat step 3.
9) Confirm the ISSUE row's Info column now shows a link reading "Item <barcode> CPL" (e.g. Item 3999900000001 CPL) - the branchcode comes from the JSON payload - and clicking it opens the item page. Override information is also displayed correctly
10) Confirm the RETURN row's Info column now shows a link reading "Item <barcode>" (no branchcode) opening the same item's detail page - verifying the bare-itemnumber payload path.
11) Repeat step 5. Confirm the CREATE row now shows "Hold 7 on biblio 1" linking to reserve/request.pl?biblionumber=1, followed by " - Item 1" linking to the item detail page. Override information is also displayed correctly
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
The log viewer results table uses "Return" for "Check-in" actions.
See the terminology list:
https://wiki.koha-community.org/wiki/Terminology#C
Test plan:
1. Check out an item to a patron, then check it back in again.
2. Go to the log view (Tools > Additional tools > Log viewer).
3. Click "Submit".
4. Note that the action column for the results shows "Return".
5. Apply the patch.
6. Refresh the log viewer page.
6. Note that the action column now correctly shows "Check-in".
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Replace direct $.post() to /api/v1/items/{id}/bundled_items with
ItemAPIClient.bundled_items.add(), which uses http-client.js and
automatically includes the CSRF token header.
The caller passes return_response: true because it needs access to
the raw response status code and body for fine-grained error handling
(different user-facing messages for 409/already_bundled, 409/checked_out,
409/reserved, 404/not_found, 400/failed_nesting). http-client.js
default behavior throws a plain Error on non-2xx responses, losing
the status code and error_code fields the UI needs.
Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Replace direct $.post('/api/v1/return_claims', ...) with the new
ClaimAPIClient, which uses http-client.js and automatically includes
the CSRF token header.
Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Replace direct $.post() and $.ajax() calls to /api/v1/bookings with
the new BookingAPIClient, which uses http-client.js and automatically
includes the CSRF token header.
Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Test plan:
1) Enable ILLModule
2) Ensure at least 2 ILL requests exist
3) Go to <staff_url>/cgi-bin/koha/ill/home
4) Confirm the most recent ILL request (highest ID) shows first
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Checkboxes must be disabled on the detail page as we cannot submit the
changes.
Test plan:
1 - Edit a patron, set a value for advance notices, do not check any transports
2 - View the details for the patron:
http://localhost:8081/cgi-bin/koha/members/moremember.pl?borrowernumber=5
3 - Note the checkboxes are disabled
QA: The logic is a bit weird as messaging_form_inactive is not set if the
pref is off, but the table is not displayed in this case.
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
To test:
1. Edit or create a framework that does not require the 008.
2. Make or edit a record in that framework without a 008.
3. Turn on EnableAdvancedCatalogingEditor, and make sure you are using the advanced editor.
4. Go to the record from step 2 and click "Edit as new (duplicate)"
5. The record won't load in the advanced editor.
6. APPLY PATCH
7. Try again, this time the record should load when using "Edit as new (duplicate)".
Signed-off-by: Roman Dolny <roman.dolny@jezuici.pl>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
If stateSave is turned on and one of the option has a value with _id set
to an Integer, toLowerCase is not available and a JS error is raised:
Uncaught (in promise) TypeError: this._id.toLowerCase is not a function
Test plan:
1.) Admin - table settings: cgi-bin/koha/admin/columns_settings.pl#eholdings|packages
Activate checkbox "Save search state on page change"
2.) Go to ERM : cgi-bin/koha/erm/eholdings/local/packages
And create two packages:
- One package with My Vendor assigned.
- One package without a vendor.
3.) Filter the package results list by My Vendor. --> List is filtered to one package
4.) Leave the page, for example by navigating to Agreements.
Return to the Packages list and you will see the issue (See also attached Screenshot)
=> Without the patch
The package results list becomes unresponsive / hangs after returning to the page.
=> With the patch
The package results list should load and display the filtered results correctly.
Signed-off-by: Michaela Sieber <michaela.sieber@kit.edu>
Signed-off-by: Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Adds a new system preference to control whether the real-time
holds queue processes only unallocated holds (faster, additive)
or rebuilds the entire queue for the affected biblio (current
behavior, more thorough).
Default is off (preserving current behavior).
Test plan:
1. Apply patch
2. Run:
$ ktd --shell
k$ perl installer/data/mysql/updatedatabase.pl
=> SUCCESS: New preference added
3. Verify RealTimeHoldsQueueUnallocated appears in
Administration > System preferences > Circulation
4. Sign off :-D
Signed-off-by: Alex Carver [Acerock7] <alex@rcls.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
The two-phase cashup workflow added a 'Cashup selected registers' modal
whose form's op hidden input had an empty value, populated at runtime by
JavaScript. xt/find-missing-op-in-forms.t parses templates statically and
flagged the empty op value as not starting with 'cud-' (see bug 34478).
Set a sensible default of 'cud-cashup_start'; the JS click handlers still
overwrite the value before submission, so behaviour is unchanged.
Test plan:
1. prove xt/find-missing-op-in-forms.t => now passes
Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
The cashup summary modal include uses the \$raw filter on
Koha.CSPNonce, but never declared [% USE raw %]. The QA template
tester (which processes templates through a fresh Template::Toolkit
instance) reports "valid_template: filter not found" because the
\$raw plugin is not loaded.
Add [% USE raw %] at the top of the include, matching the convention
used by other includes that emit nonce attributes (e.g.
includes/str/cataloging_additem.inc).
Test plan:
1. Run qa-test-tools against the bug branch -- cashup_summary.inc
passes valid_template.
2. Open the cashup summary modal -- the <style> tag still receives
a CSP nonce and the embedded styles render correctly.
Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
The cashup summary modal labelled the per-payment-type cash row "Cash
removed from register", but the value came from the session
transactions (with CASHUP_SURPLUS/DEFICIT lines excluded), so it
represented the *expected* cash, not the amount actually counted at
cashup. When a deficit or surplus existed, the reconciliation row
appeared as the difference between two figures the user could not
both see.
Render two rows when surplus_total or deficit_total is set on a
completed cashup: "Expected cash total" (from total_grouped) and
"Cash removed from register" (from cash_register_actions.amount,
already exposed as data.amount). The reconciliation row below now
visibly equals the difference. Balanced cashups and the in-progress
preview keep the original single-row display, and the negative-cashup
branch flips the labels to "Expected cash to add to register" /
"Cash added to register".
Test plan:
1. Configure a cash register and record a few cash payments.
2. Trigger a cashup, enter the exact expected amount; open the
summary modal -- a single "Cash removed from register" row is
shown matching the expected total.
3. Repeat with an amount lower than expected -- "Expected cash
total" and "Cash removed from register" both appear, and the
"Cashup deficit" row is the difference.
4. Repeat with an amount higher than expected -- the actual row
exceeds the expected row and "Cashup surplus" matches the gap.
Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
A cashup is the process of removing cash from the till to send it
to the bank, so labelling the headline cash line "Cash added to
register" was confusing. Re-word it to "Cash removed from register"
in the typical case and "Cash added to register" in the edge case
where the cashier has had to top up the till to cover refunds.
While doing this, align the sign convention of total_grouped with
that of the overall total field on the summary: positive means cash
collected (i.e. removed from the register at cashup time), negative
means cash had to be added back into the register. Previously
total_grouped used the raw accounting sign (credits negative, debits
positive), so a typical $2 cash session would display "Total: 2.00"
and "Cash added to register: -2.00", which was internally
inconsistent. The conditions on the cash and other-payment-type rows
in cashup_modal.js are swapped to match the new convention.
Test plan:
1. Apply the patch and rebuild JS (yarn js:build) inside KTD.
2. As a staff user with permission to manage cash registers, take
payments via several payment types (some cash, some not).
3. Trigger a cashup and view the cashup summary modal.
4. Confirm the "Total" line and the per-payment-type lines all
display as positive amounts in the typical "money was collected"
scenario, with the cash row labelled "Cash removed from
register".
5. Issue some refunds large enough to exceed cash collected, then
cash up again.
6. Confirm the cash row is labelled "Cash added to register" with a
negative amount and the per-non-cash-type rows are labelled
"{type} to add" where applicable.
7. Run prove t/db_dependent/Koha/Cash/Register/Cashup.t and prove
t/db_dependent/Koha/Cash/Register.t inside KTD; both should
pass.
Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This patch resolves three QA findings on the cashup reconciliation
work:
* Add a CSP nonce to the inline <style> block in cashup_summary.inc
so it is not flagged by the forbidden_patterns check.
* Document the private _get_session_end method on
Koha::Cash::Register::Cashup so pod_coverage passes.
* Mock CashupReconciliationNoteRequired to 0 in
t/db_dependent/Koha/Cash/Register/Cashup.t so the test does not
depend on the site preference value (it previously failed when
the syspref was set to "Require" because surpluses and deficits
are created without a reconciliation note in this test).
Test plan:
1. Apply the patch.
2. Set CashupReconciliationNoteRequired to "Require".
3. Run prove t/db_dependent/Koha/Cash/Register/Cashup.t -- it should
pass.
4. Set CashupReconciliationNoteRequired to "Don't require" and
re-run -- it should still pass.
5. Run koha-qa.pl on the bug branch -- pod_coverage on
Koha/Cash/Register/Cashup.pm and forbidden_patterns on
cashup_summary.inc should now pass.
Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This patch adds configuration options for cashup reconciliation and
enhances the user interface with preview functionality and improved
interaction patterns.
Configuration Options:
1. CashupReconciliationNoteRequired (System Preference):
- Optional validation requiring reconciliation notes when discrepancies exist
- Ensures documentation of surplus/deficit causes when needed
- Can be disabled for less stringent workflows
- Applied at cashup completion time
2. CashupReconciliationNoteAuthorisedValue (System Preference):
- Allows use of authorized value dropdown for reconciliation notes
- Provides standardized note options (e.g., "Till count error", "Cash removed")
- Falls back to free text textarea when not configured
- Improves consistency and reporting capabilities
UI Enhancements:
1. Cashup Summary Preview:
- Preview cashup summary for in-progress cashups
- Shows current transaction totals before completion
- Clearly indicates preview vs. final summary status
- Helps staff verify amounts before committing
2. Improved User Experience:
- Conditional note fields based on configuration
- Authorized value dropdowns when configured
- Clear validation messages
- Responsive UI updates
Backend changes:
- Enhanced Koha::REST::V1::CashRegisters::Cashups with preview support
- Database atomicupdate script for system preferences
- Validation logic for required notes
Frontend changes:
- Preview modal functionality in cashup_modal.js
- Conditional rendering of note input fields
- Authorized value dropdown integration
- Enhanced summary display logic
Test plan:
1. Apply patches and run database update
2. Configure CashupReconciliationNoteRequired:
- Enable preference
- Perform cashup with discrepancy without note - should fail
- Add note and retry - should succeed
- Disable preference - verify note optional
3. Configure CashupReconciliationNoteAuthorisedValue:
- Create AV category (e.g., CASHUP_NOTE) with values
- Set preference to category name
- Verify dropdown appears in cashup modal
- Clear preference - verify textarea shown
4. Test cashup preview:
- Start cashup on register
- Click "Preview cashup summary"
- Verify current totals displayed
- Add transaction and re-preview - verify updated
- Complete cashup - verify final summary
Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This patch implements an optional two-phase cashup workflow for point
of sale operations, along with improved error handling and validation.
Two-Phase Cashup Workflow:
- Staff can initiate cashup (CASHUP_START) and complete later
- Prevents new transactions on registers with cashups in progress
- Tracks cashup sessions with start/end timestamps
- Supports both quick cashup (immediate) and staged cashup workflows
- Updates batch cashup workflow operations across multiple registers
Error Handling & Validation:
- Centralized exception handling for cashup operations
- Clear validation messages for missing parameters
- Prevents cashup when no cash transactions exist
- Improved handling of zero/negative amounts
- Informative error messages for user guidance
Negative Amount Support:
- Supports negative cashup amounts for cashup deficits
- Automatic detection when actual cash is less than expected amount
- Creates appropriate CASHUP_DEFICIT records
- UI handles both positive and negative reconciliation amounts
- Updated calculations and display logic throughout
Modal Refactoring:
- Eliminates code duplication between register.tt and registers.tt
- Centralized cashup modal functionality in cashup_modals.js
- Shared confirm_cashup.inc and trigger_cashup.inc templates
- Consistent user experience across all cashup workflows
- Improved maintainability and code organization
Backend changes (Koha::Cash::Register):
- start_cashup(): Creates CASHUP_START action to begin session
- cashup_in_progress(): Detects active cashup sessions
- add_cashup(): Enhanced with two-phase completion support
- outstanding_accountlines(): Respects cashup session boundaries
Frontend changes:
- Interactive modals for starting and completing cashups
- Real-time calculation displays
- Support for reconciliation with actual amounts
- Batch operations UI for multiple registers
- Responsive error messaging and validation feedback
Test plan:
1. Apply patches and restart services
2. Run prove t/db_dependent/Koha/Cash/Register.t
3. Run prove t/db_dependent/Koha/Cash/Register/Cashup.t
4. Test single register workflows:
- Start cashup, add transactions, verify blocked
- Complete cashup with reconciliation amounts
- Test with positive, negative, and zero amounts
5. Test multi-register workflows:
- Select multiple registers on registers page
- Perform batch cashup operations
- Verify each register processes correctly
6. Test error conditions:
- Attempt cashup with no transactions
- Attempt cashup with invalid amounts
- Verify clear error messages displayed
Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This patch removes a redundant "onchange" event attribute from the
framework selection dropdown. This event is already registered in the JS
block.
The patch also does a little bit of cleanup to the JS: Combining two
<script> tags which don't need to be separate and moving a function
outside of the $(document).ready block.
To test, apply the patch and search for a bibliographic record in the
catalog.
- From the detail page, click the "Labeled MARC" tag in the sidebar (you
may need to enable the "viewLabeledMARC" preference).
- Try changing the "With framework" selection. The page should reload
with the selected framework.
Sponsored-by: Athens County Public Libraries
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
When one tries to transfer an item that could fill a pending hold
to a library that is not the holds pickup library, Koha gives only
a option to transfer item to pickup library. This patch adds
new option to ignore hold and transfer item to the library user
selected in transfer tool.
To test:
1. Log into Library A.
2. Find or create a biblio with 1 holdable item at Library A.
3. Place a hold for the biblio with pickup at Library B.
4. Navigate to Circulation > Transfers.
5. Attempt to transfer item to Library C.
=> Note that Koha only allows to transfer item to Library B,
cancel hold and attempt transfer or return to the transfer tool.
6. Apply this patch.
7. Attempt to transfer item again.
=> Note that there is now an option to ignore the hold and transfer
item to Library C.
=> When option to transfer item to the Library C is selected, confirm
that Koha tells that transfer was made to Library C and a new transfer
was made to database.
Sponsored-by: Koha-Suomi Oy
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
The early-exit added for the CurbsidePickup syspref check left
policy/curbside_pickups unset, but intranet-bottom.inc's jsinclude
still referenced them unconditionally, causing a client-side
TypeError on every render of the disabled state. Guard the whole
jsinclude block with disabled_for_branch.
Also distinguish the two reasons the page can be disabled: the
CurbsidePickup syspref being off globally vs. this branch simply
not having an enabled curbside pickup policy configured. The
message and link now point staff to the correct admin page for
each case, instead of always suggesting the syspref (which may
already be on).
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This patch solves the following issues:
* Template flow issue: the template called STOP which prevented the
WRAPPER to complete and affected how things were rendered.
* Redirect to 404 if feature disabled. This is common practice in other
modules. The fact things can be executed even with the feature
disabled is not ok (syspref).
* Shortcircuit earlier. Similar to the above, if the feature is
disabled for the current branch, no DB queries and stuff should take
place. Notice the lack of checks actually makes the controller perform
the actions. It is just that it is not displayed afterwards!
To test:
1. Enable the `CurbsidePickup` syspref.
2. 'Activate' the `CircSidebar` syspref.
3. Be on a branch that doesn't have them enabled
4. Go to Circulation > Check in
=> SUCCESS: A nice left-hand sidebar is displayed with access to
Circulation actions
5. Click on 'Curbside pickups'
=> FAIL: The sidebar doesn't display. boo!
6. Apply this patch
7. Restart plack
$ ktd --shell
$ koha-plack --restart kohadev
8. Repeat 4
=> SUCCESS: It renders much better!
9. Sign off :-D
Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This splits remaining JS into a block with and without TT interpolation. Auto tidy
Small changes on add_to_map() call:
To test:
a) go to Administration -> Shar eyour usage statistics
b) in dev console check Koha.prefs.UsageStatsGeolocation is [] when no coordinates are set
c) add some coordinates to main library (first Geolocation input field) and others
d) check that Main and other libraries are drwan on the map when reentering usage statistics page
e) No console errors should be shown
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
In order to tidy all the script tags of the .tt files we isolate the
interpolation of Template::Toolkit variables in a separate script tag.
This patch focuses on the administration module.
The 2 main changes are in the following files:
* aqplan.tt
"0" should be correctly formatted
* categories.tt
trivial change about table settings
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This removes all TT interpolations from the build_dropdown function and moves it to the non TT script block.
To test:
a) create several private or public lists via /cgi-bin/koha/virtualshelves/shelves.pl
b) either the number of private or public list should be > 10 to
c) add some items to a list
d) on this lists content site click 'Add to' to open drop down menu
e) the menu should offer up to 10 private or 10 public list options and a [ more lists ] option
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>