Bug 13757: OPAC changes
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io> Signed-off-by: Nick Clemens <nick@bywatersolutions.com> Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org> Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
This commit is contained in:
parent
1fa5660dbc
commit
0a40e0c60f
2 changed files with 201 additions and 28 deletions
|
@ -1,7 +1,9 @@
|
|||
[% USE AuthorisedValues %]
|
||||
[% USE Categories %]
|
||||
[% USE Koha %]
|
||||
[% USE Branches %]
|
||||
[% USE KohaDates %]
|
||||
[% USE Math %]
|
||||
[% SET userupdateview = 1 %]
|
||||
|
||||
[% INCLUDE 'doc-head-open.inc' %]
|
||||
|
@ -114,6 +116,9 @@
|
|||
</ol>
|
||||
</fieldset>
|
||||
[% END %]
|
||||
[% IF ( extended_unique_id_failed_code ) %]
|
||||
<div class="alert" id="extended_unique_id_failed"><a href="#patron-attr-start-[% extended_unique_id_failed_code %]">[% extended_unique_id_failed_description %]</a> value <i>[% extended_unique_id_failed_value %]</i> is already in use.</div>
|
||||
[% END %]
|
||||
|
||||
<form method="post" action="/cgi-bin/koha/opac-memberentry.pl" id="memberentry-form">
|
||||
|
||||
|
@ -885,7 +890,73 @@
|
|||
</fieldset>
|
||||
[% END %]
|
||||
|
||||
[% UNLESS action == 'edit' %]
|
||||
[% IF ( Koha.Preference('ExtendedPatronAttributes') && patron_attribute_classes.size && !Koha.Preference('PatronSelfRegistrationVerifyByEmail') ) %]
|
||||
[% FOREACH pa_class IN patron_attribute_classes %]
|
||||
[% IF pa_class.class %]
|
||||
<fieldset id="aai_[% pa_loo.class %]" class="rows patron-attributes">
|
||||
<legend>[% pa_loo.lib %]</legend>
|
||||
[% ELSE %]
|
||||
<fieldset class="rows patron-attributes">
|
||||
<legend>Additional information</legend>
|
||||
[% END %]
|
||||
<ol class="attributes_table">
|
||||
[% FOREACH pa IN pa_class.items %]
|
||||
[% FOREACH pa_value IN pa.values %]
|
||||
[% IF loop.first %]<a name="patron-attr-start-[% pa.type.code %]"></a>[% END %]
|
||||
[% form_id = 'patron-attr-' _ Math.int( Math.rand(1000000) ) %]
|
||||
<li data-category_code="[% pa.type.category_code %]">
|
||||
<label for="[% form_id %]">[% pa.type.description %]: </label>
|
||||
[% IF pa.type.opac_editable %]
|
||||
<input type="hidden" name="patron_attribute_code" value="[% pa.type.code |html %]" />
|
||||
[% IF ( pa.type.authorised_value_category ) %]
|
||||
<select id="[% form_id %]" name="patron_attribute_value">
|
||||
<option value=""></option>
|
||||
[% FOREACH auth_val IN AuthorisedValues.Get( pa.type.authorised_value_category, pa_value.value || '', 1 ) %]
|
||||
[% IF ( auth_val.selected ) %]
|
||||
<option value="[% auth_val.authorised_value %]" selected="selected">
|
||||
[%# Yes, lib; GetAuthorisedValues takes care of intelligently setting this from lib_opac %]
|
||||
[% auth_val.lib %]
|
||||
</option>
|
||||
[% ELSE %]
|
||||
<option value="[% auth_val.authorised_value %]" >
|
||||
[% auth_val.lib %]
|
||||
</option>
|
||||
[% END %]
|
||||
[% END %]
|
||||
</select>
|
||||
[% ELSE %]
|
||||
<textarea rows="2" cols="30" id="[% form_id %]" name="patron_attribute_value">[% pa_value.value %]</textarea>
|
||||
[% END %]
|
||||
<a href="#" class="clear-attribute">Clear</a>
|
||||
[% IF ( pa.type.repeatable ) %]
|
||||
<a href="#" class="clone-attribute">New</a>
|
||||
[% END %]
|
||||
[% IF ( pa.type.password_allowed ) %]
|
||||
</li><li><label for="[% form_id %]_password">Password:</label>
|
||||
<input type="password" maxlength="64" value="[% pa_value.password %]" id="[% form_id %]_password" name="patron_attribute_password" />
|
||||
[% ELSE %]
|
||||
[%# To keep the form inputs lined up in the POST %]
|
||||
<input type="hidden" name="patron_attribute_password" value="" />
|
||||
[% END %]
|
||||
[% ELSE %]
|
||||
[% IF ( pa.type.authorised_value_category ) %]
|
||||
[% AuthorisedValues.GetByCode( pa.type.authorised_value, pa_value.value, 1 ) %]
|
||||
[% ELSE %]
|
||||
[% pa_value.value | html_line_break %]
|
||||
[% END %]
|
||||
[% IF ( pa_value.password ) %]
|
||||
(Password: *******)
|
||||
[% END %]
|
||||
[% END %]
|
||||
</li>
|
||||
[% END %]
|
||||
[% END %]
|
||||
</ol>
|
||||
</fieldset>
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
||||
[% UNLESS action == 'edit' %]
|
||||
<fieldset class="rows" id="memberentry_captcha">
|
||||
<ol>
|
||||
|
||||
|
@ -901,24 +972,6 @@
|
|||
</fieldset>
|
||||
[% END %]
|
||||
|
||||
[% IF ( borrower.ExtendedPatronAttributes ) %]
|
||||
<fieldset class="rows">
|
||||
<legend>Additional information</legend>
|
||||
<ol>
|
||||
[% FOREACH patron_attribute IN borrower.patron_attributes %]
|
||||
<li>
|
||||
<label>[% patron_attribute.description %]:</label>
|
||||
[% IF ( patron_attribute.value_description ) %]
|
||||
[% patron_attribute.value_description %]
|
||||
[% ELSE %]
|
||||
[% patron_attribute.value |html_line_break %]
|
||||
[% END %]
|
||||
</li>
|
||||
[% END %]
|
||||
</ol>
|
||||
</fieldset>
|
||||
[% END %]
|
||||
|
||||
[% IF action == 'edit' %]
|
||||
[% IF OPACPatronDetails %]
|
||||
<fieldset class="action">
|
||||
|
@ -1006,6 +1059,24 @@
|
|||
});
|
||||
});
|
||||
[% END %]
|
||||
|
||||
$(".patron-attributes").on( 'click', '.clear-attribute', function() {
|
||||
$(this).parent()
|
||||
.find('textarea').attr('value', '').end()
|
||||
.find('select').attr('value', '').end();
|
||||
|
||||
return false;
|
||||
} );
|
||||
|
||||
$(".patron-attributes").on( 'click', '.clone-attribute', function() {
|
||||
var clone = $(this).parent().clone().insertAfter( $(this).parent() );
|
||||
|
||||
var newId = 50 + parseInt(Math.random() * 100000);
|
||||
$('input[type!="hidden"],select,textarea', clone).attr('id', 'patron-attr-' + newId).attr('value', '');
|
||||
$("label", clone).attr('for', 'patron-attr-' + newId).attr('value', '');
|
||||
|
||||
return false;
|
||||
} );
|
||||
});
|
||||
|
||||
$(".cleardate").on("click", function(){
|
||||
|
|
|
@ -20,6 +20,7 @@ use Modern::Perl;
|
|||
use CGI qw ( -utf8 );
|
||||
use Digest::MD5 qw( md5_base64 md5_hex );
|
||||
use Encode qw( encode );
|
||||
use List::MoreUtils qw( each_array uniq );
|
||||
use String::Random qw( random_string );
|
||||
|
||||
use C4::Auth;
|
||||
|
@ -86,6 +87,21 @@ $template->param(
|
|||
OPACPatronDetails => C4::Context->preference('OPACPatronDetails'),
|
||||
);
|
||||
|
||||
my $attributes = ParsePatronAttributes($cgi);
|
||||
my $conflicting_attribute = 0;
|
||||
|
||||
foreach my $attr (@$attributes) {
|
||||
unless ( C4::Members::Attributes::CheckUniqueness($attr->{code}, $attr->{value}, $borrowernumber) ) {
|
||||
my $attr_info = C4::Members::AttributeTypes->fetch($attr->{code});
|
||||
$template->param(
|
||||
extended_unique_id_failed_code => $attr->{code},
|
||||
extended_unique_id_failed_value => $attr->{value},
|
||||
extended_unique_id_failed_description => $attr_info->description()
|
||||
);
|
||||
$conflicting_attribute = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $action eq 'create' ) {
|
||||
|
||||
my %borrower = ParseCgiForBorrower($cgi);
|
||||
|
@ -102,7 +118,7 @@ if ( $action eq 'create' ) {
|
|||
$cardnumber_error_code = checkcardnumber( $borrower{cardnumber}, $borrower{borrowernumber} );
|
||||
}
|
||||
|
||||
if ( @empty_mandatory_fields || @$invalidformfields || $cardnumber_error_code ) {
|
||||
if ( @empty_mandatory_fields || @$invalidformfields || $cardnumber_error_code || $conflicting_attribute ) {
|
||||
if ( $cardnumber_error_code == 1 ) {
|
||||
$template->param( cardnumber_already_exists => 1 );
|
||||
} elsif ( $cardnumber_error_code == 2 ) {
|
||||
|
@ -114,6 +130,7 @@ if ( $action eq 'create' ) {
|
|||
invalid_form_fields => $invalidformfields,
|
||||
borrower => \%borrower
|
||||
);
|
||||
$template->param( patron_attribute_classes => GeneratePatronAttributesForm( undef, $attributes ) );
|
||||
}
|
||||
elsif (
|
||||
md5_base64( uc( $cgi->param('captcha') ) ) ne $cgi->param('captcha_digest') )
|
||||
|
@ -122,6 +139,7 @@ if ( $action eq 'create' ) {
|
|||
failed_captcha => 1,
|
||||
borrower => \%borrower
|
||||
);
|
||||
$template->param( patron_attribute_classes => GeneratePatronAttributesForm( undef, $attributes ) );
|
||||
}
|
||||
else {
|
||||
if (
|
||||
|
@ -182,6 +200,7 @@ if ( $action eq 'create' ) {
|
|||
C4::Context->preference('OpacPasswordChange') );
|
||||
|
||||
my ( $borrowernumber, $password ) = AddMember_Opac(%borrower);
|
||||
C4::Members::Attributes::SetBorrowerAttributes( $borrowernumber, $attributes );
|
||||
C4::Form::MessagingPreferences::handle_form_action($cgi, { borrowernumber => $borrowernumber }, $template, 1, C4::Context->preference('PatronSelfRegistrationDefaultCategory') ) if $borrowernumber && C4::Context->preference('EnhancedMessagingPreferences');
|
||||
|
||||
$template->param( password_cleartext => $password );
|
||||
|
@ -225,6 +244,7 @@ elsif ( $action eq 'update' ) {
|
|||
secret => md5_base64( Encode::encode( 'UTF-8', C4::Context->config('pass') ) ),
|
||||
}),
|
||||
);
|
||||
$template->param( patron_attribute_classes => GeneratePatronAttributesForm( undef, $attributes ) );
|
||||
|
||||
$template->param( action => 'edit' );
|
||||
}
|
||||
|
@ -272,14 +292,6 @@ elsif ( $action eq 'update' ) {
|
|||
elsif ( $action eq 'edit' ) { #Display logged in borrower's data
|
||||
my $borrower = GetMember( borrowernumber => $borrowernumber );
|
||||
|
||||
if (C4::Context->preference('ExtendedPatronAttributes')) {
|
||||
my $attributes = C4::Members::Attributes::GetBorrowerAttributes($borrowernumber, 'opac');
|
||||
if (scalar(@$attributes) > 0) {
|
||||
$borrower->{ExtendedPatronAttributes} = 1;
|
||||
$borrower->{patron_attributes} = $attributes;
|
||||
}
|
||||
}
|
||||
|
||||
$template->param(
|
||||
borrower => $borrower,
|
||||
guarantor => scalar Koha::Patrons->find($borrowernumber)->guarantor(),
|
||||
|
@ -295,6 +307,9 @@ elsif ( $action eq 'edit' ) { #Display logged in borrower's data
|
|||
$template->param( display_patron_image => 1 ) if $patron_image;
|
||||
}
|
||||
|
||||
$template->param( patron_attribute_classes => GeneratePatronAttributesForm( $borrower ) );
|
||||
} else {
|
||||
$template->param( patron_attribute_classes => GeneratePatronAttributesForm() );
|
||||
}
|
||||
|
||||
my $captcha = random_string("CCCCC");
|
||||
|
@ -448,3 +463,90 @@ sub DelEmptyFields {
|
|||
|
||||
return %borrower;
|
||||
}
|
||||
|
||||
sub GeneratePatronAttributesForm {
|
||||
my ( $borrower, $entered_attributes ) = @_;
|
||||
|
||||
# Get all attribute types and the values for this patron (if applicable)
|
||||
my @types = C4::Members::AttributeTypes::GetAttributeTypes();
|
||||
|
||||
if (scalar(@types) == 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
my %attr_values = ();
|
||||
|
||||
if ( $borrower ) {
|
||||
my $attributes = C4::Members::Attributes::GetBorrowerAttributes($borrowernumber);
|
||||
|
||||
# Remap the patron's attributes into a hash of arrayrefs per attribute (depends on
|
||||
# autovivification)
|
||||
foreach my $attr (@$attributes) {
|
||||
push @{ $attr_values{ $attr->{code} } }, $attr;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $entered_attributes ) {
|
||||
foreach my $attr (@$entered_attributes) {
|
||||
push @{ $attr_values{ $attr->{code} } }, $attr;
|
||||
}
|
||||
}
|
||||
|
||||
# Find all existing classes
|
||||
my @classes = uniq( map { $_->{class} } @types );
|
||||
@classes = sort @classes;
|
||||
my %items_by_class;
|
||||
|
||||
foreach my $attr_type_desc (@types) {
|
||||
my $attr_type = C4::Members::AttributeTypes->fetch( $attr_type_desc->{code} );
|
||||
# Make sure this attribute should be displayed in the OPAC
|
||||
next unless ( $attr_type->opac_display() );
|
||||
# Then, make sure it either has values or is editable
|
||||
next unless ( $attr_values{ $attr_type->code() } || $attr_type->opac_editable() );
|
||||
|
||||
push @{ $items_by_class{ $attr_type->class() } }, {
|
||||
type => $attr_type,
|
||||
# If editable, make sure there's at least one empty entry, to make the template's job easier
|
||||
values => $attr_values{ $attr_type->code() } || [{}]
|
||||
};
|
||||
}
|
||||
|
||||
# Finally, build a list of containing classes
|
||||
my @class_loop;
|
||||
foreach my $class (@classes) {
|
||||
next unless ( $items_by_class{$class} );
|
||||
|
||||
my $av = Koha::AuthorisedValues->search({ category => 'PA_CLASS', authorised_value => $class });
|
||||
my $lib = $av->count ? $av->next->opac_description : $class;
|
||||
|
||||
push @class_loop, {
|
||||
class => $class,
|
||||
items => $items_by_class{$class},
|
||||
lib => $lib,
|
||||
};
|
||||
}
|
||||
|
||||
return \@class_loop;
|
||||
}
|
||||
|
||||
sub ParsePatronAttributes {
|
||||
my ( $cgi ) = @_;
|
||||
|
||||
my @codes = $cgi->param('patron_attribute_code');
|
||||
my @values = $cgi->param('patron_attribute_value');
|
||||
my @passwords = $cgi->param('patron_attribute_password');
|
||||
|
||||
my $ea = each_array( @codes, @values, @passwords );
|
||||
my @attributes;
|
||||
my %dups = ();
|
||||
|
||||
while ( my ( $code, $value, $password ) = $ea->() ) {
|
||||
next unless defined($value) and $value ne '';
|
||||
next if exists $dups{$code}->{$value};
|
||||
$dups{$code}->{$value} = 1;
|
||||
|
||||
push @attributes, { code => $code, value => $value, password => $password };
|
||||
}
|
||||
|
||||
return \@attributes;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue