[Patches] [PATCH] Bug 7154: Modification in borrower attributes
koha-patchbot at kohaaloha.com
koha-patchbot at kohaaloha.com
Sat Dec 3 14:16:20 NZDT 2011
From: Jonathan Druart <jonathan.druart at biblibre.com>
Date: Fri, 2 Dec 2011 16:09:50 +0100
Subject: [PATCH] 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
this patch add 2 fields in borrower_attribute_types :
category_type
class
---
C4/Members/AttributeTypes.pm | 55 ++++++++++++-
C4/Members/Attributes.pm | 4 +-
admin/patron-attr-types.pl | 9 ++
installer/data/mysql/kohastructure.sql | 1 +
installer/data/mysql/updatedatabase.pl | 7 ++
.../prog/en/modules/admin/patron-attr-types.tt | 62 +++++++++++----
.../prog/en/modules/members/memberentrygen.tt | 84 ++++++++++++++------
.../prog/en/modules/members/moremember.tt | 43 +++++++----
members/memberentry.pl | 5 +
members/moremember.pl | 19 ++++-
10 files changed, 223 insertions(+), 66 deletions(-)
diff --git a/C4/Members/AttributeTypes.pm b/C4/Members/AttributeTypes.pm
index e36557b..6a6b16d 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,8 @@ sub new {
$self->{'staff_searchable'} = 0;
$self->{'display_checkout'} = 0;
$self->{'authorised_value_category'} = '';
+ $self->{'category_type'} = '';
+ $self->{'class'} = '';
bless $self, $class;
return $self;
@@ -155,6 +157,8 @@ sub fetch {
$self->{'staff_searchable'} = $row->{'staff_searchable'};
$self->{'display_checkout'} = $row->{'display_checkout'};
$self->{'authorised_value_category'} = $row->{'authorised_value_category'};
+ $self->{'category_type'} = $row->{'category_type'};
+ $self->{'class'} = $row->{'class'};
bless $self, $class;
return $self;
@@ -185,14 +189,16 @@ sub store {
password_allowed = ?,
staff_searchable = ?,
authorised_value_category = ?,
- display_checkout = ?
+ display_checkout = ?,
+ category_type = ?,
+ 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_type, class, code)
VALUES (?, ?, ?, ?, ?,
- ?, ?, ?, ?)");
+ ?, ?, ?, ?, ?, ?)");
}
$sth->bind_param(1, $self->{'description'});
$sth->bind_param(2, $self->{'repeatable'});
@@ -202,7 +208,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_type'});
+ $sth->bind_param(10, $self->{'class'});
+ $sth->bind_param(11, $self->{'code'});
$sth->execute;
}
@@ -341,6 +349,43 @@ sub authorised_value_category {
@_ ? $self->{'authorised_value_category'} = shift : $self->{'authorised_value_category'};
}
+=head2 category_type
+
+=over 4
+
+my $category_type = $attr_type->category_type();
+$attr_type->category_type($category_type);
+
+=back
+
+Accessor.
+
+=cut
+
+sub category_type {
+ my $self = shift;
+ @_ ? $self->{'category_type'} = shift : $self->{'category_type'};
+}
+
+=head2 class
+
+=over 4
+
+my $category_type = $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 4ae5600..137b11e 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_type, 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_type => $row->{'category_type'},
+ class => $row->{'class'},
}
}
return \@results;
diff --git a/admin/patron-attr-types.pl b/admin/patron-attr-types.pl
index 29a0d90..377159b 100755
--- a/admin/patron-attr-types.pl
+++ b/admin/patron-attr-types.pl
@@ -110,6 +110,9 @@ sub error_add_attribute_type_form {
$template->param(display_checkout_checked => 'checked="checked"');
}
+ $template->param( category_type => $input->param('category_type') );
+ $template->param( class => $input->param('class') );
+
$template->param(
attribute_type_form => 1,
confirm_op => 'add_attribute_type_confirmed',
@@ -152,6 +155,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_type($input->param('category_type'));
+ $attr_type->class($input->param('class'));
if ($op eq 'edit') {
$template->param(edited_attribute_type => $attr_type->code());
@@ -209,6 +214,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);
@@ -232,6 +238,9 @@ sub edit_attribute_type_form {
}
authorised_value_category_list($template, $attr_type->authorised_value_category());
+ $template->param ( category_type => $attr_type->category_type );
+ $template->param ( class => $attr_type->class );
+
$template->param(
attribute_type_form => 1,
edit_attribute_type => 1,
diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql
index 452173d..f4db550 100644
--- a/installer/data/mysql/kohastructure.sql
+++ b/installer/data/mysql/kohastructure.sql
@@ -286,6 +286,7 @@ 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_type` VARCHAR(1) NOT NULL DEFAULT '',-- defines a category 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 9ae0060..6728330 100755
--- a/installer/data/mysql/updatedatabase.pl
+++ b/installer/data/mysql/updatedatabase.pl
@@ -4571,6 +4571,13 @@ if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
SetVersion($DBversion);
}
+$DBversion = "3.06.00.XXX";
+if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
+ $dbh->do("ALTER TABLE borrower_attribute_types ADD COLUMN category_type VARCHAR(1) NOT NULL DEFAULT '' AFTER `display_checkout`");
+ $dbh->do("ALTER TABLE borrower_attribute_types ADD COLUMN class VARCHAR(255) NOT NULL DEFAULT '' AFTER `category_type`");
+ print "Upgrade to $DBversion done (New fields category_type and class in borrower_attribute_types table)\n";
+ SetVersion($DBversion);
+}
=head1 FUNCTIONS
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..4d32646 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,24 @@ 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_type">Category type: </label>
+ <select name="category_type" id="category_type">
+ <option value=""></option>
+ [% IF category_type == 'A' %]<option value="A" selected="selected">Adult</option>[% ELSE %]<option value="A">Adult</option>[% END %]
+ [% IF category_type == 'C' %]<option value="C" selected="selected">Child</option>[% ELSE %]<option value="C">Child</option>[% END %]
+ [% IF category_type == 'S' %]<option value="S" selected="selected">Staff</option>[% ELSE %]<option value="S">Staff</option>[% END %]
+ [% IF category_type == 'I' %]<option value="I" selected="selected">Organization</option>[% ELSE %]<option value="I">Organization</option>[% END %]
+ [% IF category_type == 'P' %]<option value="P" selected="selected">Professional</option>[% ELSE %]<option value="P">Professional</option>[% END %]
+ [% IF category_type == 'X' %]<option value="X" selected="selected">Statistical</option>[% ELSE %]<option value="X">Statistical</option>[% 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>
+ <input type="text" id="class" name="class" size="20" value="[% class | html %]"/>
+ <span>Group attributes types with a block title</span>
+ </li>
</ol>
</fieldset>
<fieldset class="action">
@@ -248,23 +266,33 @@ 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>
- [% END %]
-</table>[% ELSE %]<p>There are no saved patron attribute types.</p>[% END %]
+[% IF ( available_attribute_types ) %]
+ <table id="patron_attributes_types">
+ <thead>
+ <tr>
+ <th>Class</th>
+ <th>Code</th>
+ <th>Description</th>
+ <th>Actions</th>
+ </tr>
+ </thead>
+ <tbody>
+ [% FOREACH available_attribute_type IN available_attribute_types %]
+ <tr>
+ <td>[% available_attribute_type.class |html %]</td>
+ <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>
+ [% END %]
+ </tbody>
+ </table>
+[% 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 b9371b6..9c31271 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 category_type %]
+ update_category_code( "[% category_type %]" );
+ [% ELSE %]
+ if ( $("#categorycode").length > 0 ){
+ var category_type = $("#categorycode").find("option:selected").attr("data-typename");
+ update_category_code( category_type );
+ }
+ [% END %]
+
});
function clear_entry(node) {
@@ -51,6 +61,23 @@
$("select#patron_attr_" + newId, clone).attr('value','');
original.parentNode.insertBefore(clone, original.nextSibling);
}
+
+ function update_category_code(category_type) {
+ var mytable = $("#attributes_table>tbody");
+
+ mytable.find("tr").each(function(){
+ $(this).hide()
+ });
+
+ mytable.find("tr[data-category_type="+category_type+"]").each(function(){
+ $(this).show();
+ });
+ mytable.find("tr[data-category_type='']").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 ");
@@ -890,25 +917,25 @@
</li>
<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 ( categoryloo.typename_C ) %]<optgroup label="Child">[% END %]
- [% IF ( categoryloo.typename_A ) %]<optgroup label="Adult">[% END %]
- [% IF ( categoryloo.typename_S ) %]<optgroup label="Staff">[% END %]
- [% IF ( categoryloo.typename_I ) %]<optgroup label="Organization">[% END %]
- [% IF ( categoryloo.typename_P ) %]<optgroup label="Professional">[% END %]
- [% IF ( categoryloo.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 ( categoryloo.typename_C ) %]<optgroup label="Child" value="C">[% END %]
+ [% IF ( categoryloo.typename_A ) %]<optgroup label="Adult" value="A">[% END %]
+ [% IF ( categoryloo.typename_S ) %]<optgroup label="Staff" value="S">[% END %]
+ [% IF ( categoryloo.typename_I ) %]<optgroup label="Organization" value="I">[% END %]
+ [% IF ( categoryloo.typename_P ) %]<optgroup label="Professional" value="P">[% END %]
+ [% IF ( categoryloo.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>
@@ -1180,14 +1207,20 @@
<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>
+ <table id="attributes_table">
+ <thead>
+ <tr>
+ <th>Class</th>
+ <th>Type</th>
+ <th colspan="2">Value</th>
+ </tr>
+ </thead>
+ <tbody>
[% FOREACH patron_attribute IN patron_attributes %]
- <tr>
- <td>[% patron_attribute.code %] ([% patron_attribute.description %])
+ <tr data-category_type="[% patron_attribute.category_type %]">
+ <td>[% patron_attribute.class %]</td>
+ <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 %]" />
@@ -1228,6 +1261,7 @@
</td>
</tr>
[% END %]
+ </tbody>
</table>
</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 454032c..439689f 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.class %]</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 d169dbd..0997888 100755
--- a/members/memberentry.pl
+++ b/members/memberentry.pl
@@ -407,6 +407,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( category_type => $borrower_data->{'categorycode'} );
+ }
}
if ( $op eq "duplicate" ) {
$template->param( updtype => 'I' );
@@ -760,11 +763,13 @@ sub patron_attributes_form {
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_type => $attr_type->category_type(),
password => '',
};
if (exists $attr_hash{$attr_type->code()}) {
diff --git a/members/moremember.pl b/members/moremember.pl
index 6e5407c..e48538e 100755
--- a/members/moremember.pl
+++ b/members/moremember.pl
@@ -252,7 +252,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;
@@ -432,11 +431,25 @@ 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 );
+ my @attributes_loop;
+ for my $class (@classes) {
+ my @items;
+ for my $attr (@$attributes) {
+ push @items, $attr if $attr->{class} eq $class
+ }
+ push @attributes_loop, {
+ class => $class,
+ items => \@items
+ };
+ }
+
$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
More information about the Patches
mailing list