Bug 41749: Display patron consents on staff patron detail page

Adds a read-only "Consents" section to the staff patron detail page
showing the patron's consent status for GDPR (when PrivacyPolicyConsent
is enabled) and any plugin-defined consent types.

Each consent displays with visual status indicators:
- Green checkmark with timestamp when consent was given
- Red X with timestamp when consent was refused
- Gray "Not specified" when no consent recorded

Test plan:
1. Enable PrivacyPolicyConsent system preference
2. As patron in OPAC: give/refuse consent at "Your consents"
3. As staff: view patron detail page
4. Verify "Consents" section shows correct status and timestamp
5. Test with no consent recorded (should show "Not specified")
6. If available, test with plugin-defined consent types

Signed-off-by: David Nind <david@davidnind.com>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This commit is contained in:
Martin Renvoize 2026-02-02 11:58:32 +00:00 committed by Lucas Gass
parent cc68988bce
commit 971e2ead4b
No known key found for this signature in database
GPG Key ID: 60B447398B0D36CA
2 changed files with 55 additions and 0 deletions

View File

@ -592,6 +592,41 @@
</div>
[%# /div#patron-library-details %]
[% IF consents.size %]
<div id="patron-consents" class="patroninfo-section">
<div class="patroninfo-heading">
<h3>Consents</h3>
</div>
<div class="rows">
<ol>
[% FOREACH consent IN consents %]
<li>
<span class="label">
[% IF consent.type == 'GDPR_PROCESSING' %]
Privacy policy consent:
[% ELSIF consent.title.title.${lang} %]
[% consent.title.title.${lang} | html %]:
[% ELSIF consent.title.title.en %]
[% consent.title.title.en | html %]:
[% ELSE %]
[% consent.type | html %]:
[% END %]
</span>
[% IF consent.given_on %]
<span class="text-success"> <i class="fa fa-check"></i> Given on [% consent.given_on | $KohaDates with_hours => 1 %] </span>
[% ELSIF consent.refused_on %]
<span class="text-danger"> <i class="fa fa-times"></i> Refused on [% consent.refused_on | $KohaDates with_hours => 1 %] </span>
[% ELSE %]
<span class="text-muted">Not specified</span>
[% END %]
</li>
[% END %]
</ol>
</div>
</div>
[%# /div#patron-consents %]
[% END %]
<div id="patron-alternate-address" class="patroninfo-section">
[% IF ( patron.B_phone || patron.B_email || patron.contactnote || patron.B_address || patron.B_address2 || patron.B_city || patron.B_zipcode || patron.B_country ) %]
<div class="patroninfo-heading">

View File

@ -41,6 +41,7 @@ use Koha::Patron::Messages;
use Koha::CsvProfiles;
use Koha::Holds;
use Koha::Patrons;
use Koha::Patron::Consents;
use Koha::Patron::Files;
use Koha::Token;
use Koha::Checkouts;
@ -316,4 +317,23 @@ if ( C4::Context->preference('UseRecalls') ) {
);
}
# Fetch available consent types and patron's consents
my $consent_types = Koha::Patron::Consents->available_types;
if ( keys %$consent_types ) {
my @consents_data;
for my $type ( sort keys %$consent_types ) {
my $consent = $patron->consent($type);
push @consents_data, {
type => $type,
title => $consent_types->{$type},
given_on => $consent->given_on,
refused_on => $consent->refused_on,
};
}
$template->param(
consents => \@consents_data,
consent_types => $consent_types,
);
}
output_html_with_http_headers $input, $cookie, $template->output;