From 52c2e951b144c5d4a12944e1fc385081dd002fe8 Mon Sep 17 00:00:00 2001 From: Jonathan Druart <jonathan.druart@biblibre.com> Date: Fri, 10 Feb 2012 09:57:35 +0100 Subject: [PATCH 1/1] Bug 7154: Modification in borrower attributes * group some attributes for a more friendly display * allow a link between a borrower category and an attribute to display it only for the specified category * Attr classes filled with AV 'PA_CLASS' category (you have to create AV with a new category 'PA_CLASS' to fill class list) this patch add 2 fields in borrower_attribute_types : category_code class --- C4/Members/AttributeTypes.pm | 83 +++++++++- C4/Members/Attributes.pm | 4 +- admin/patron-attr-types.pl | 43 +++++- installer/data/mysql/kohastructure.sql | 2 + installer/data/mysql/updatedatabase.pl | 12 ++ .../prog/en/modules/admin/patron-attr-types.tt | 73 +++++++-- .../prog/en/modules/members/memberentrygen.tt | 170 ++++++++++++-------- .../prog/en/modules/members/moremember.tt | 43 ++++-- members/memberentry.pl | 23 +++- members/moremember.pl | 23 +++- 10 files changed, 365 insertions(+), 111 deletions(-) diff --git a/C4/Members/AttributeTypes.pm b/C4/Members/AttributeTypes.pm index e36557b..8c96e54 100644 --- a/C4/Members/AttributeTypes.pm +++ b/C4/Members/AttributeTypes.pm @@ -70,7 +70,7 @@ If $all_fields is true, then each hashref also contains the other fields from bo sub GetAttributeTypes { my ($all) = @_; - my $select = $all ? '*' : 'code, description'; + my $select = $all ? '*' : 'code, description, class'; my $dbh = C4::Context->dbh; my $sth = $dbh->prepare("SELECT $select FROM borrower_attribute_types ORDER by code"); $sth->execute(); @@ -120,6 +120,9 @@ sub new { $self->{'staff_searchable'} = 0; $self->{'display_checkout'} = 0; $self->{'authorised_value_category'} = ''; + $self->{'category_code'} = ''; + $self->{'category_description'} = ''; + $self->{'class'} = ''; bless $self, $class; return $self; @@ -140,11 +143,15 @@ sub fetch { my $self = {}; my $dbh = C4::Context->dbh(); - my $sth = $dbh->prepare_cached("SELECT * FROM borrower_attribute_types WHERE code = ?"); + my $sth = $dbh->prepare_cached(" + SELECT borrower_attribute_types.*, categories.description AS category_description + FROM borrower_attribute_types + LEFT JOIN categories ON borrower_attribute_types.category_code=categories.categorycode + WHERE code =?"); $sth->execute($code); my $row = $sth->fetchrow_hashref; $sth->finish(); - return undef unless defined $row; + return undef unless defined $row; $self->{'code'} = $row->{'code'}; $self->{'description'} = $row->{'description'}; @@ -155,6 +162,9 @@ sub fetch { $self->{'staff_searchable'} = $row->{'staff_searchable'}; $self->{'display_checkout'} = $row->{'display_checkout'}; $self->{'authorised_value_category'} = $row->{'authorised_value_category'}; + $self->{'category_code'} = $row->{'category_code'}; + $self->{'category_description'} = $row->{'category_description'}; + $self->{'class'} = $row->{'class'}; bless $self, $class; return $self; @@ -185,14 +195,16 @@ sub store { password_allowed = ?, staff_searchable = ?, authorised_value_category = ?, - display_checkout = ? + display_checkout = ?, + category_code = ?, + class = ? WHERE code = ?"); } else { $sth = $dbh->prepare_cached("INSERT INTO borrower_attribute_types (description, repeatable, unique_id, opac_display, password_allowed, - staff_searchable, authorised_value_category, display_checkout, code) + staff_searchable, authorised_value_category, display_checkout, category_code, class, code) VALUES (?, ?, ?, ?, ?, - ?, ?, ?, ?)"); + ?, ?, ?, ?, ?, ?)"); } $sth->bind_param(1, $self->{'description'}); $sth->bind_param(2, $self->{'repeatable'}); @@ -202,7 +214,9 @@ sub store { $sth->bind_param(6, $self->{'staff_searchable'}); $sth->bind_param(7, $self->{'authorised_value_category'}); $sth->bind_param(8, $self->{'display_checkout'}); - $sth->bind_param(9, $self->{'code'}); + $sth->bind_param(9, $self->{'category_code'} || undef); + $sth->bind_param(10, $self->{'class'}); + $sth->bind_param(11, $self->{'code'}); $sth->execute; } @@ -341,6 +355,61 @@ sub authorised_value_category { @_ ? $self->{'authorised_value_category'} = shift : $self->{'authorised_value_category'}; } +=head2 category_code + +=over 4 + +my $category_code = $attr_type->category_code(); +$attr_type->category_code($category_code); + +=back + +Accessor. + +=cut + +sub category_code { + my $self = shift; + @_ ? $self->{'category_code'} = shift : $self->{'category_code'}; +} + +=head2 category_description + +=over 4 + +my $category_description = $attr_type->category_description(); +$attr_type->category_description($category_description); + +=back + +Accessor. + +=cut + +sub category_description { + my $self = shift; + @_ ? $self->{'category_description'} = shift : $self->{'category_description'}; +} + +=head2 class + +=over 4 + +my $class = $attr_type->class(); +$attr_type->class($class); + +=back + +Accessor. + +=cut + +sub class { + my $self = shift; + @_ ? $self->{'class'} = shift : $self->{'class'}; +} + + =head2 delete $attr_type->delete(); diff --git a/C4/Members/Attributes.pm b/C4/Members/Attributes.pm index 33affa8..33d2407 100644 --- a/C4/Members/Attributes.pm +++ b/C4/Members/Attributes.pm @@ -72,7 +72,7 @@ sub GetBorrowerAttributes { my $opac_only = @_ ? shift : 0; my $dbh = C4::Context->dbh(); - my $query = "SELECT code, description, attribute, lib, password, display_checkout + my $query = "SELECT code, description, attribute, lib, password, display_checkout, category_code, class FROM borrower_attributes JOIN borrower_attribute_types USING (code) LEFT JOIN authorised_values ON (category = authorised_value_category AND attribute = authorised_value) @@ -90,6 +90,8 @@ sub GetBorrowerAttributes { value_description => $row->{'lib'}, password => $row->{'password'}, display_checkout => $row->{'display_checkout'}, + category_code => $row->{'category_code'}, + class => $row->{'class'}, } } return \@results; diff --git a/admin/patron-attr-types.pl b/admin/patron-attr-types.pl index 29a0d90..660a227 100755 --- a/admin/patron-attr-types.pl +++ b/admin/patron-attr-types.pl @@ -22,10 +22,13 @@ use strict; use warnings; use CGI; +use List::MoreUtils qw/uniq/; + use C4::Auth; use C4::Context; use C4::Output; use C4::Koha; +use C4::Members qw/GetBorrowercategoryList/; use C4::Members::AttributeTypes; my $script_name = "/cgi-bin/koha/admin/patron-attr-types.pl"; @@ -82,8 +85,10 @@ sub add_attribute_type_form { $template->param( attribute_type_form => 1, confirm_op => 'add_attribute_type_confirmed', + categories => GetBorrowercategoryList, ); authorised_value_category_list($template); + pa_classes($template); } sub error_add_attribute_type_form { @@ -110,6 +115,9 @@ sub error_add_attribute_type_form { $template->param(display_checkout_checked => 'checked="checked"'); } + $template->param( category_code => $input->param('category_code') ); + $template->param( class => $input->param('class') ); + $template->param( attribute_type_form => 1, confirm_op => 'add_attribute_type_confirmed', @@ -152,6 +160,8 @@ sub add_update_attribute_type { $attr_type->password_allowed($password_allowed); my $display_checkout = $input->param('display_checkout'); $attr_type->display_checkout($display_checkout); + $attr_type->category_code($input->param('category_code')); + $attr_type->class($input->param('class')); if ($op eq 'edit') { $template->param(edited_attribute_type => $attr_type->code()); @@ -209,6 +219,7 @@ sub edit_attribute_type_form { $template->param(code => $code); $template->param(description => $attr_type->description()); + $template->param(class => $attr_type->class()); if ($attr_type->repeatable()) { $template->param(repeatable_checked => 1); @@ -231,20 +242,41 @@ sub edit_attribute_type_form { $template->param(display_checkout_checked => 'checked="checked"'); } authorised_value_category_list($template, $attr_type->authorised_value_category()); + pa_classes( $template, $attr_type->class ); + + $template->param ( category_code => $attr_type->category_code ); + $template->param ( category_description => $attr_type->category_description ); $template->param( attribute_type_form => 1, edit_attribute_type => 1, confirm_op => 'edit_attribute_type_confirmed', + categories => GetBorrowercategoryList, ); } sub patron_attribute_type_list { my $template = shift; - + my @attr_types = C4::Members::AttributeTypes::GetAttributeTypes(); - $template->param(available_attribute_types => \@attr_types); + my @classes = uniq( map {$_->{class}} @attr_types ); + @classes = sort @classes; + + my @attributes_loop; + for my $class (@classes) { + my @items; + for my $attr (@attr_types) { + push @items, $attr if $attr->{class} eq $class + } + my $lib = GetAuthorisedValueByCode( 'PA_CLASS', $class ) || $class; + push @attributes_loop, { + class => $class, + items => \@items, + lib => $lib, + }; + } + $template->param(available_attribute_types => \@attributes_loop); $template->param(display_list => 1); } @@ -261,3 +293,10 @@ sub authorised_value_category_list { } $template->param(authorised_value_categories => \@list); } + +sub pa_classes { + my $template = shift; + my $selected = @_ ? shift : ''; + + $template->param(classes_val_loop => GetAuthorisedValues( 'PA_CLASS', $selected ) ); +} diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 288dc05..0b3fe28 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -286,6 +286,8 @@ CREATE TABLE `borrower_attribute_types` ( -- definitions for custom patron field `staff_searchable` tinyint(1) NOT NULL default 0, -- defines if this field is searchable via the patron search in the staff client (1 for yes, 0 for no) `authorised_value_category` varchar(10) default NULL, -- foreign key from authorised_values that links this custom field to an authorized value category `display_checkout` tinyint(1) NOT NULL default 0,-- defines if this field displays in checkout screens + `category_code` VARCHAR(1) NOT NULL DEFAULT '',-- defines a category for an attribute_type + `class` VARCHAR(255) NOT NULL DEFAULT '',-- defines a class for an attribute_type PRIMARY KEY (`code`), KEY `auth_val_cat_idx` (`authorised_value_category`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index 4f21435..ca2b8b8 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -4944,6 +4944,18 @@ if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { } + + + +$DBversion = "3.07.00.XXX"; +if (C4::Context->preference("Version") < TransformToNum($DBversion)) { + $dbh->do("ALTER TABLE borrower_attribute_types ADD COLUMN category_code VARCHAR(10) NULL DEFAULT NULL AFTER `display_checkout`"); + $dbh->do("ALTER TABLE borrower_attribute_types ADD COLUMN class VARCHAR(255) NOT NULL DEFAULT '' AFTER `category_code`"); + $dbh->do("ALTER TABLE borrower_attribute_types ADD CONSTRAINT category_code_fk FOREIGN KEY (category_code) REFERENCES categories(categorycode)"); + print "Upgrade to $DBversion done (New fields category_code and class in borrower_attribute_types table)\n"; + SetVersion($DBversion); +} + =head1 FUNCTIONS =head2 DropAllForeignKeys($table) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/patron-attr-types.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/patron-attr-types.tt index b8a8e3e..e1bacd1 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/patron-attr-types.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/patron-attr-types.tt @@ -186,6 +186,34 @@ function CheckAttributeTypeForm(f) { to be chosen from the authorized value list. However, an authorized value list is not enforced during batch patron import.</span> </li> + <li> + <label for="category">Category: </label> + <select name="category_code" id="category"> + <option value=""></option> + [% FOREACH cat IN categories %] + [% IF ( cat.categorycode == category_code ) %]<option value="[% cat.categorycode %]" selected="selected">[% cat.description %]</option>[% ELSE %]<option value="[% cat.categorycode %]">[% cat.description %]</option>[% END %] + [% END %] + </select> + <span>Please let blank if you want these attributs to be for all types of patron. Else, select one type.</span> + </li> + <li> + <label for="class">Class: </label> + <select name="class"> + <option value="" /> + [% FOREACH class IN classes_val_loop %] + [% IF ( class.selected ) %] + <option value="[% class.authorised_value %]" selected="selected"> + [% class.lib %] + </option> + [% ELSE %] + <option value="[% class.authorised_value %]" > + [% class.lib %] + </option> + [% END %] + [% END %] + </select> + <span>Group attributes types with a block title (based on Authorised values category 'PA_CLASS')</span> + </li> </ol> </fieldset> <fieldset class="action"> @@ -248,23 +276,36 @@ function CheckAttributeTypeForm(f) { <div class="dialog message">Could not delete patron attribute type "[% ERROR_delete_not_found %]" — it was already absent from the database.</div> [% END %] -[% IF ( available_attribute_types ) %]<table> - <tr> - <th>Code</th> - <th>Description</th> - <th>Actions</th> - </tr> - [% FOREACH available_attribute_type IN available_attribute_types %] - <tr> - <td>[% available_attribute_type.code |html %]</td> - <td>[% available_attribute_type.description %]</td> - <td> - <a href="[% available_attribute_type.script_name %]?op=edit_attribute_type&code=[% available_attribute_type.code |html %]">Edit</a> - <a href="[% available_attribute_type.script_name %]?op=delete_attribute_type&code=[% available_attribute_type.code |html %]">Delete</a> - </td> - </tr> +[% IF ( available_attribute_types ) %] + [% FOREACH attribute IN available_attribute_types %] + [% IF attribute.class %] + <h4>[% attribute.lib %]</h4> + [% END %] + <table class="patron_attributes_types"> + <thead> + <tr> + <th>Code</th> + <th>Description</th> + <th>Actions</th> + </tr> + </thead> + <tbody> + [% FOREACH item IN attribute.items %] + <tr> + <td>[% item.code |html %]</td> + <td>[% item.description %]</td> + <td> + <a href="[% item.script_name %]?op=edit_attribute_type&code=[% item.code |html %]">Edit</a> + <a href="[% item.script_name %]?op=delete_attribute_type&code=[% item.code |html %]">Delete</a> + </td> + </tr> + [% END %] + </tbody> + </table> [% END %] -</table>[% ELSE %]<p>There are no saved patron attribute types.</p>[% END %] +[% ELSE %] + <p>There are no saved patron attribute types.</p> +[% END %] <div class="pages">[% pagination_bar %]</div> diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt index 814bd55..901f8fa 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt @@ -23,6 +23,16 @@ document.form.state.value=RegExp.$3; document.form.country.value=RegExp.$4; }); + + [% IF categorycode %] + update_category_code( "[% categorycode %]" ); + [% ELSE %] + if ( $("#categorycode").length > 0 ){ + var category_code = $("#categorycode").find("option:selected").val(); + update_category_code( category_code ); + } + [% END %] + }); function clear_entry(node) { @@ -51,6 +61,26 @@ $("select#patron_attr_" + newId, clone).attr('value',''); original.parentNode.insertBefore(clone, original.nextSibling); } + + function update_category_code(category_code) { + if ( $(category_code).is("select") ) { + category_code = $("#categorycode").find("option:selected").val(); + } + var mytables = $(".attributes_table>tbody"); + + mytables.find("tr").each(function(){ + $(this).hide() + }); + + mytables.find("tr[data-category_code="+category_code+"]").each(function(){ + $(this).show(); + }); + mytables.find("tr[data-category_code='']").each(function(){ + $(this).show(); + }); + + } + var MSG_SEPARATOR = _("Separator must be / in field "); var MSG_INCORRECT_DAY = _("Invalid day entered in field "); var MSG_INCORRECT_MONTH = _("Invalid month entered in field "); @@ -999,25 +1029,25 @@ [% END %] <li> <label for="categorycode">Category: </label> - <select id="categorycode" name="categorycode"> + <select id="categorycode" name="categorycode" onchange="update_category_code(this);"> [% FOREACH typeloo IN typeloop %] - [% FOREACH categoryloo IN typeloo.categoryloop %] - [% IF ( loop.first ) %] - [% IF ( typeloo.typename_C ) %]<optgroup label="Child">[% END %] - [% IF ( typeloo.typename_A ) %]<optgroup label="Adult">[% END %] - [% IF ( typeloo.typename_S ) %]<optgroup label="Staff">[% END %] - [% IF ( typeloo.typename_I ) %]<optgroup label="Organization">[% END %] - [% IF ( typeloo.typename_P ) %]<optgroup label="Professional">[% END %] - [% IF ( typeloo.typename_X ) %]<optgroup label="Statistical">[% END %] - [% END %] - [% IF ( categoryloo.categorycodeselected ) %] - <option value="[% categoryloo.categorycode %]" selected="selected">[% categoryloo.categoryname %]</option> - [% ELSE %] -<option value="[% categoryloo.categorycode %]">[% categoryloo.categoryname %]</option> - [% END %] - [% IF ( loop.last ) %] - </optgroup> - [% END %] + [% FOREACH categoryloo IN typeloo.categoryloop %] + [% IF ( loop.first ) %] + [% IF ( typeloo.typename_C ) %]<optgroup label="Child" value="C">[% END %] + [% IF ( typeloo.typename_A ) %]<optgroup label="Adult" value="A">[% END %] + [% IF ( typeloo.typename_S ) %]<optgroup label="Staff" value="S">[% END %] + [% IF ( typeloo.typename_I ) %]<optgroup label="Organization" value="I">[% END %] + [% IF ( typeloo.typename_P ) %]<optgroup label="Professional" value="P">[% END %] + [% IF ( typeloo.typename_X ) %]<optgroup label="Statistical" value="X">[% END %] + [% END %] + [% IF ( categoryloo.categorycodeselected ) %] + <option value="[% categoryloo.categorycode %]" selected="selected" data-typename="[% typeloo.typename %]">[% categoryloo.categoryname %]</option> + [% ELSE %] + <option value="[% categoryloo.categorycode %]" data-typename="[% typeloo.typename %]">[% categoryloo.categoryname %]</option> + [% END %] + [% IF ( loop.last ) %] + </optgroup> + [% END %] [% END %] [% END %] </select> @@ -1352,55 +1382,67 @@ <fieldset class="rows" id="memberentry_patron_attributes"> <input type="hidden" name="setting_extended_patron_attributes" value="1" /> <legend>Additional attributes and identifiers</legend> - <table> - <tr> - <th>Type</th> - <th colspan="2">Value</th> - </tr> - [% FOREACH patron_attribute IN patron_attributes %] - <tr> - <td>[% patron_attribute.code %] ([% patron_attribute.description %]) - </td> - <td> - <input type="hidden" id="[% patron_attribute.form_id %]_code" name="[% patron_attribute.form_id %]_code" value="[% patron_attribute.code |html %]" /> - [% IF ( patron_attribute.use_dropdown ) %] - <select id="[% patron_attribute.form_id %]" name="[% patron_attribute.form_id %]"> - <option value="" /> - [% FOREACH auth_val_loo IN patron_attribute.auth_val_loop %] - [% IF ( auth_val_loo.selected ) %] - <option value="[% auth_val_loo.authorised_value %]" selected="selected"> - [% auth_val_loo.lib %] - </option> + [% FOREACH pa_loo IN patron_attributes %] + [% IF pa_loo.class %] + <h4>[% pa_loo.lib %]</h4> + <table id=aai_[% pa_loo.class %] class="attributes_table"> + [% ELSE %] + <table id="aai" class="attributes_table"> + [% END %] + <thead> + <tr> + <th>Type</th> + <th colspan="2">Value</th> + </tr> + </thead> + <tbody> + [% FOREACH patron_attribute IN pa_loo.items %] + <tr data-category_code="[% patron_attribute.category_code %]"> + <td> + [% patron_attribute.code %] ([% patron_attribute.description %]) + </td> + <td> + <input type="hidden" id="[% patron_attribute.form_id %]_code" name="[% patron_attribute.form_id %]_code" value="[% patron_attribute.code |html %]" /> + [% IF ( patron_attribute.use_dropdown ) %] + <select id="[% patron_attribute.form_id %]" name="[% patron_attribute.form_id %]"> + <option value="" /> + [% FOREACH auth_val_loo IN patron_attribute.auth_val_loop %] + [% IF ( auth_val_loo.selected ) %] + <option value="[% auth_val_loo.authorised_value %]" selected="selected"> + [% auth_val_loo.lib %] + </option> + [% ELSE %] + <option value="[% auth_val_loo.authorised_value %]" > + [% auth_val_loo.lib %] + </option> + [% END %] + [% END %] + </select> + [% ELSE %] + [% IF ( opduplicate ) %] + <input type="text" maxlength="64" value="[% patron_attribute.value %]" + id="[% patron_attribute.form_id %]" name="[% patron_attribute.form_id %]" onclick="this.value=''" /> [% ELSE %] - <option value="[% auth_val_loo.authorised_value %]" > - [% auth_val_loo.lib %] - </option> + <input type="text" maxlength="64" value="[% patron_attribute.value %]" + id="[% patron_attribute.form_id %]" name="[% patron_attribute.form_id %]" /> [% END %] [% END %] - </select> - [% ELSE %] - [% IF ( opduplicate ) %] - <input type="text" maxlength="64" value="[% patron_attribute.value %]" - id="[% patron_attribute.form_id %]" name="[% patron_attribute.form_id %]" onclick="this.value=''" /> - [% ELSE %] - <input type="text" maxlength="64" value="[% patron_attribute.value %]" - id="[% patron_attribute.form_id %]" name="[% patron_attribute.form_id %]" /> - [% END %] - [% END %] - [% IF ( patron_attribute.password_allowed ) %] - (Password: <input type="password" maxlength="64" value="[% patron_attribute.password %]" - id="[% patron_attribute.form_id %]_password" name="[% patron_attribute.form_id %]_password" />) - [% END %] - </td> - <td> - <a href="#" onclick="clear_entry(this); return false;">Clear</a> - [% IF ( patron_attribute.repeatable ) %] - <a href="#" onclick="clone_entry(this); return false;">New</a> - [% END %] - </td> - </tr> - [% END %] - </table> + [% IF ( patron_attribute.password_allowed ) %] + (Password: <input type="password" maxlength="64" value="[% patron_attribute.password %]" + id="[% patron_attribute.form_id %]_password" name="[% patron_attribute.form_id %]_password" />) + [% END %] + </td> + <td> + <a href="#" onclick="clear_entry(this); return false;">Clear</a> + [% IF ( patron_attribute.repeatable ) %] + <a href="#" onclick="clone_entry(this); return false;">New</a> + [% END %] + </td> + </tr> + [% END %] + </tbody> + </table> + [% END %] </fieldset> [% END %][% END %][% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt index bd19584..7c06298 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt @@ -285,22 +285,35 @@ function validate1(date) { [% UNLESS ( no_patron_attribute_types ) %] <div id="patron-extended-attributes" style="padding-top: 1em;"> <h3>Additional attributes and identifiers</h3> -<table> - <tr> - <th>Type</th> - <th>Value</th> - </tr> - [% FOREACH extendedattribute IN extendedattributes %] - <tr> - <td>[% extendedattribute.code %] ([% extendedattribute.description %])</td> - <td>[% extendedattribute.value %] - [% IF ( extendedattribute.value_description ) %] - ([% extendedattribute.value_description %]) - [% END %] - </td> - </tr> +[% FOREACH attribute IN attributes_loop %] + [% IF attribute.class %] + <h4>[% attribute.lib %]</h4> + <table id=aai_[% attribute.class %]> + [% ELSE %] + <table id="aai"> [% END %] -</table> + <thead> + <tr> + <th>Type</th> + <th>Description</th> + <th>Value</th> + </tr> + </thead> + <tbody> + [% FOREACH item IN attribute.items %] + <tr> + <td>[% item.code %]</td> + <td>[% item.description %]</td> + <td>[% item.value %] + [% IF ( item.value_description ) %] + ([% item.value_description %]) + [% END %] + </td> + </tr> + [% END %] + </tbody> + </table> +[% END %] </div> <div class="action"><a href="memberentry.pl?op=modify&borrowernumber=[% borrowernumber %]&step=4">Edit</a></div> [% END %] diff --git a/members/memberentry.pl b/members/memberentry.pl index d53f7f1..2d8cace 100755 --- a/members/memberentry.pl +++ b/members/memberentry.pl @@ -25,6 +25,7 @@ use warnings; # external modules use CGI; # use Digest::MD5 qw(md5_base64); +use List::MoreUtils qw/uniq/; # internal modules use C4::Auth; @@ -423,6 +424,9 @@ if ($op eq 'add'){ if ($op eq "modify") { $template->param( updtype => 'M',modify => 1 ); $template->param( step_1=>1, step_2=>1, step_3=>1, step_4=>1, step_5 => 1, step_6 => 1) unless $step; + if ( $step == 4 ) { + $template->param( categorycode => $borrower_data->{'categorycode'} ); + } } if ( $op eq "duplicate" ) { $template->param( updtype => 'I' ); @@ -764,6 +768,8 @@ sub patron_attributes_form { return; } my $attributes = C4::Members::Attributes::GetBorrowerAttributes($borrowernumber); + my @classes = uniq( map {$_->{class}} @$attributes ); + @classes = sort @classes; # map patron's attributes into a more convenient structure my %attr_hash = (); @@ -773,14 +779,17 @@ sub patron_attributes_form { my @attribute_loop = (); my $i = 0; + my %items_by_class; foreach my $type_code (map { $_->{code} } @types) { my $attr_type = C4::Members::AttributeTypes->fetch($type_code); my $entry = { + class => $attr_type->class(), code => $attr_type->code(), description => $attr_type->description(), repeatable => $attr_type->repeatable(), password_allowed => $attr_type->password_allowed(), category => $attr_type->authorised_value_category(), + category_code => $attr_type->category_code(), password => '', }; if (exists $attr_hash{$attr_type->code()}) { @@ -795,8 +804,7 @@ sub patron_attributes_form { } $i++; $newentry->{form_id} = "patron_attr_$i"; - #use Data::Dumper; die Dumper($entry) if $entry->{use_dropdown}; - push @attribute_loop, $newentry; + push @{$items_by_class{$attr_type->class()}}, $newentry; } } else { $i++; @@ -806,9 +814,18 @@ sub patron_attributes_form { $newentry->{auth_val_loop} = GetAuthorisedValues($attr_type->authorised_value_category()); } $newentry->{form_id} = "patron_attr_$i"; - push @attribute_loop, $newentry; + push @{$items_by_class{$attr_type->class()}}, $newentry; + } + } + while ( my ($class, @items) = each %items_by_class ) { + my $lib = GetAuthorisedValueByCode( 'PA_CLASS', $class ) || $class; + push @attribute_loop, { + class => $class, + items => @items, + lib => $lib, } } + $template->param(patron_attributes => \@attribute_loop); } diff --git a/members/moremember.pl b/members/moremember.pl index 5a988f9..b9d0c8f 100755 --- a/members/moremember.pl +++ b/members/moremember.pl @@ -251,7 +251,6 @@ my $issuecount = @{$issue}; my $relissuecount = @{$relissue}; my $roaddetails = &GetRoadTypeDetails( $data->{'streettype'} ); my $today = POSIX::strftime("%Y-%m-%d", localtime); # iso format -my @issuedata; my @borrowers_with_issues; my $overdues_exist = 0; my $totalprice = 0; @@ -431,11 +430,29 @@ my $branch=C4::Context->userenv->{'branch'}; $template->param(%$data); if (C4::Context->preference('ExtendedPatronAttributes')) { - my $attributes = GetBorrowerAttributes($borrowernumber); + my $attributes = C4::Members::Attributes::GetBorrowerAttributes($borrowernumber); + my @classes = uniq( map {$_->{class}} @$attributes ); + @classes = sort @classes; + + my @attributes_loop; + for my $class (@classes) { + my @items; + for my $attr (@$attributes) { + push @items, $attr if $attr->{class} eq $class + } + my $lib = GetAuthorisedValueByCode( 'PA_CLASS', $class ) || $class; + push @attributes_loop, { + class => $class, + items => \@items, + lib => $lib, + }; + } + $template->param( ExtendedPatronAttributes => 1, - extendedattributes => $attributes + attributes_loop => \@attributes_loop ); + my @types = C4::Members::AttributeTypes::GetAttributeTypes(); if (scalar(@types) == 0) { $template->param(no_patron_attribute_types => 1); -- 1.7.7.3