Koha/members/memberentry.pl
Paul Poulain 1fe3514c3c Bug 6328 fine in days does not work
Some code coming from BibLibre has been lost in the process of inclusion in
3.4. The result is that fine in days does not work at all (you can setup rules,
but it does nothing)

Step to reproduce:

- Koha > Admin > circ rules > set 1 day fine every day of overdue for default
  rule
- Issue a book return date last week
- check-in the book => no debarment is set

The following patch will fix all of those problems by :

* updating borrowers.debarred to a date field (instead of tinyint). It contains
  the limit of the debarment
* changing API of DebarMember and UpdateBorrowerDebarred to pass a date
* display debarrdate where applicable. Note that a debarrdate of 31/12/9999 is
  considered as unlimited and not displayed
* added a debarrcomment, usefull to explain why a patron is debarred (this is
  independant from debarrdate changes and can be used when placing an unlimited
  debarment too)

[2011-05-12] F. Demians. It works as described. And I can confirm this
functionality is impatiently awaited by French libraries since one year. Thanks
BibLibre for the good work and for contributing this code.

Bug 6328 Followup--update DB structure

Thanks Katrin.

Bug 6328: make comment a textbox / fix debar by notice trigger

Debarring by notice triggers was broken, because the new function
expects a date as second parameter.

The comment field in patron account details was a very long text field.
Patch changes it to be a textbox instead.

Bug 6328: Lift debarment leaves patron account

'Lift debarment' redirects to an empty circulation page.

BZ6328 follow-up 3

Fixes comment 23 from Fernando L. Canizo : when the patron was debarred and debar removed
he still could not check-out.

The changes in the IsMemberBlocked (that were on biblibre/master) were lost somewhere
The sub was still checking for old_issues instead of calling CheckBorrowerDebarred
to get a debardate if applicable

Note : this bug was appearing only is you had issuing rules defined for itemtype/categorycode/branch.
Seemed to work if you had only default rules. That's probably why it hadn't been spotted before

BZ6328 follow-up 4
Comments fron Zeno Tajoli: The patch is OK and I sign-off it. Two little changes done on
installer/data/mysql/kohastructure.sql and installer/data/mysql/updatedatabase.pl

Signed-off-by: koha <koha@kohabase.localdomain>
2011-11-25 14:00:47 +01:00

802 lines
31 KiB
Perl
Executable file

#!/usr/bin/perl
# Copyright 2006 SAN OUEST PROVENCE et Paul POULAIN
# Copyright 2010 BibLibre
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# pragma
use strict;
use warnings;
# external modules
use CGI;
# use Digest::MD5 qw(md5_base64);
# internal modules
use C4::Auth;
use C4::Context;
use C4::Output;
use C4::Members;
use C4::Members::Attributes;
use C4::Members::AttributeTypes;
use C4::Koha;
use C4::Dates qw/format_date format_date_in_iso/;
use C4::Input;
use C4::Log;
use C4::Letters;
use C4::Branch; # GetBranches
use C4::Form::MessagingPreferences;
use vars qw($debug);
BEGIN {
$debug = $ENV{DEBUG} || 0;
}
my $input = new CGI;
($debug) or $debug = $input->param('debug') || 0;
my %data;
my $dbh = C4::Context->dbh;
my ($template, $loggedinuser, $cookie)
= get_template_and_user({template_name => "members/memberentrygen.tmpl",
query => $input,
type => "intranet",
authnotrequired => 0,
flagsrequired => {borrowers => 1},
debug => ($debug) ? 1 : 0,
});
my $guarantorid = $input->param('guarantorid');
my $borrowernumber = $input->param('borrowernumber');
my $actionType = $input->param('actionType') || '';
my $modify = $input->param('modify');
my $delete = $input->param('delete');
my $op = $input->param('op');
my $destination = $input->param('destination');
my $cardnumber = $input->param('cardnumber');
my $check_member = $input->param('check_member');
my $nodouble = $input->param('nodouble');
my $duplicate = $input->param('duplicate');
$nodouble = 1 if ($op eq 'modify' or $op eq 'duplicate'); # FIXME hack to represent fact that if we're
# modifying an existing patron, it ipso facto
# isn't a duplicate. Marking FIXME because this
# script needs to be refactored.
my $select_city = $input->param('select_city');
my $nok = $input->param('nok');
my $guarantorinfo = $input->param('guarantorinfo');
my $step = $input->param('step') || 0;
my @errors;
my $default_city;
# $check_categorytype contains the value of duplicate borrowers category type to redirect in good template in step =2
my $check_categorytype=$input->param('check_categorytype');
# NOTE: Alert for ethnicity and ethnotes fields, they are invalid in all borrowers form
my $borrower_data;
my $NoUpdateLogin;
my $userenv = C4::Context->userenv;
$template->param("uppercasesurnames" => C4::Context->preference('uppercasesurnames'));
my $minpw = C4::Context->preference('minPasswordLength');
$template->param("minPasswordLength" => $minpw);
# function to designate mandatory fields (visually with css)
my $check_BorrowerMandatoryField=C4::Context->preference("BorrowerMandatoryField");
my @field_check=split(/\|/,$check_BorrowerMandatoryField);
foreach (@field_check) {
$template->param( "mandatory$_" => 1);
}
$template->param( "add" => 1 ) if ( $op eq 'add' );
$template->param( "duplicate" => 1 ) if ( $op eq 'duplicate' );
$template->param( "checked" => 1 ) if ( defined($nodouble) && $nodouble eq 1 );
( $borrower_data = GetMember( 'borrowernumber' => $borrowernumber ) ) if ( $op eq 'modify' or $op eq 'save' or $op eq 'duplicate' );
my $categorycode = $input->param('categorycode') || $borrower_data->{'categorycode'};
my $category_type = $input->param('category_type') || '';
if ($category_type){
$template->{VARS}->{'type_only'} = 1;
}
my $new_c_type = $category_type; #if we have input param, then we've already chosen the cat_type.
unless ($category_type or !($categorycode)){
my $borrowercategory = GetBorrowercategory($categorycode);
$category_type = $borrowercategory->{'category_type'};
my $category_name = $borrowercategory->{'description'};
$template->param("categoryname"=>$category_name);
}
$category_type="A" unless $category_type; # FIXME we should display a error message instead of a 500 error !
# if a add or modify is requested => check validity of data.
%data = %$borrower_data if ($borrower_data);
# initialize %newdata
my %newdata; # comes from $input->param()
if ( $op eq 'insert' || $op eq 'modify' || $op eq 'save' || $op eq 'duplicate' ) {
my @names = ( $borrower_data && $op ne 'save' ) ? keys %$borrower_data : $input->param();
foreach my $key (@names) {
if (defined $input->param($key)) {
$newdata{$key} = $input->param($key);
$newdata{$key} =~ s/\"/&quot;/g unless $key eq 'borrowernotes' or $key eq 'opacnote';
}
}
## Manipulate debarred
if ( $newdata{debarred} ) {
$newdata{debarred} = $newdata{datedebarred} ? $newdata{datedebarred} : "9999-12-31";
} elsif ( exists( $newdata{debarred} ) && !( $newdata{debarred} ) ) {
undef( $newdata{debarred} );
undef( $newdata{debarredcomment} );
} elsif ( exists( $newdata{debarredcomment} ) && $newdata{debarredcomment} eq "" ) {
undef( $newdata{debarredcomment} );
}
my $dateobject = C4::Dates->new();
my $syspref = $dateobject->regexp(); # same syspref format for all 3 dates
my $iso = $dateobject->regexp('iso'); #
foreach (qw(dateenrolled dateexpiry dateofbirth)) {
next unless exists $newdata{$_};
my $userdate = $newdata{$_} or next;
if ($userdate =~ /$syspref/) {
$newdata{$_} = format_date_in_iso($userdate); # if they match syspref format, then convert to ISO
} elsif ($userdate =~ /$iso/) {
warn "Date $_ ($userdate) is already in ISO format";
} else {
($userdate eq '0000-00-00') and warn "Data error: $_ is '0000-00-00'";
$template->param( "ERROR_$_" => 1 ); # else ERROR!
push(@errors,"ERROR_$_");
}
}
# check permission to modify login info.
if (ref($borrower_data) && ($borrower_data->{'category_type'} eq 'S') && ! (C4::Auth::haspermission($userenv->{'id'},{'staffaccess'=>1})) ) {
$NoUpdateLogin = 1;
}
}
# remove keys from %newdata that ModMember() doesn't like
{
my @keys_to_delete = (
qr/^BorrowerMandatoryField$/,
qr/^category_type$/,
qr/^check_member$/,
qr/^destination$/,
qr/^nodouble$/,
qr/^op$/,
qr/^save$/,
qr/^select_roadtype$/,
qr/^updtype$/,
qr/^SMSnumber$/,
qr/^setting_extended_patron_attributes$/,
qr/^setting_messaging_prefs$/,
qr/^digest$/,
qr/^modify$/,
qr/^step$/,
qr/^\d+$/,
qr/^\d+-DAYS/,
qr/^patron_attr_/,
);
for my $regexp (@keys_to_delete) {
for (keys %newdata) {
delete($newdata{$_}) if /$regexp/;
}
}
}
#############test for member being unique #############
if ( ( $op eq 'insert' ) and !$nodouble ) {
my $category_type_send;
if ( $category_type eq 'I' ) {
$category_type_send = $category_type;
}
my $check_category; # recover the category code of the doublon suspect borrowers
# ($result,$categorycode) = checkuniquemember($collectivity,$surname,$firstname,$dateofbirth)
( $check_member, $check_category ) = checkuniquemember(
$category_type_send,
( $newdata{surname} ? $newdata{surname} : $data{surname} ),
( $newdata{firstname} ? $newdata{firstname} : $data{firstname} ),
( $newdata{dateofbirth} ? $newdata{dateofbirth} : $data{dateofbirth} )
);
if ( !$check_member ) {
$nodouble = 1;
}
# recover the category type if the borrowers is a doublon
if ($check_category) {
my $tmpborrowercategory = GetBorrowercategory($check_category);
$check_categorytype = $tmpborrowercategory->{'category_type'};
}
}
#recover all data from guarantor address phone ,fax...
if ( $guarantorid and ( $category_type eq 'C' || $category_type eq 'P' )) {
if (my $guarantordata=GetMember(borrowernumber => $guarantorid)) {
$guarantorinfo=$guarantordata->{'surname'}." , ".$guarantordata->{'firstname'};
$newdata{'contactfirstname'}= $guarantordata->{'firstname'};
$newdata{'contactname'} = $guarantordata->{'surname'};
$newdata{'contacttitle'} = $guarantordata->{'title'};
if ( $op eq 'add' ) {
foreach (qw(streetnumber address streettype address2
zipcode country city state phone phonepro mobile fax email emailpro branchcode
B_streetnumber B_streettype B_address B_address2
B_city B_state B_zipcode B_country B_email B_phone)) {
$newdata{$_} = $guarantordata->{$_};
}
}
}
}
###############test to take the right zipcode, country and city name ##############
# set only if parameter was passed from the form
$newdata{'city'} = $input->param('city') if defined($input->param('city'));
$newdata{'zipcode'} = $input->param('zipcode') if defined($input->param('zipcode'));
$newdata{'country'} = $input->param('country') if defined($input->param('country'));
#builds default userid
if ( (defined $newdata{'userid'}) && ($newdata{'userid'} eq '')){
$newdata{'userid'} = Generate_Userid($borrowernumber, $newdata{'firstname'}, $newdata{'surname'});
}
$debug and warn join "\t", map {"$_: $newdata{$_}"} qw(dateofbirth dateenrolled dateexpiry);
my $extended_patron_attributes = ();
if ($op eq 'save' || $op eq 'insert'){
# If the cardnumber is blank, treat it as null.
$newdata{'cardnumber'} = undef if $newdata{'cardnumber'} =~ /^\s*$/;
if (checkcardnumber($newdata{cardnumber},$newdata{borrowernumber})){
push @errors, 'ERROR_cardnumber';
}
my $dateofbirthmandatory = (scalar grep {$_ eq "dateofbirth"} @field_check) ? 1 : 0;
if ($newdata{dateofbirth} && $dateofbirthmandatory) {
my $age = GetAge($newdata{dateofbirth});
my $borrowercategory=GetBorrowercategory($newdata{'categorycode'});
my ($low,$high) = ($borrowercategory->{'dateofbirthrequired'}, $borrowercategory->{'upperagelimit'});
if (($high && ($age > $high)) or ($age < $low)) {
push @errors, 'ERROR_age_limitations';
$template->param('ERROR_age_limitations' => "$low to $high");
}
}
if($newdata{surname} && C4::Context->preference('uppercasesurnames')) {
$newdata{'surname'} = uc($newdata{'surname'});
}
if (C4::Context->preference("IndependantBranches")) {
if ($userenv && $userenv->{flags} % 2 != 1){
$debug and print STDERR " $newdata{'branchcode'} : ".$userenv->{flags}.":".$userenv->{branch};
unless (!$newdata{'branchcode'} || $userenv->{branch} eq $newdata{'branchcode'}){
push @errors, "ERROR_branch";
}
}
}
# Check if the userid is unique
unless (Check_Userid($newdata{'userid'},$borrowernumber)) {
push @errors, "ERROR_login_exist";
}
my $password = $input->param('password');
push @errors, "ERROR_short_password" if( $password && $minpw && $password ne '****' && (length($password) < $minpw) );
if (C4::Context->preference('ExtendedPatronAttributes')) {
$extended_patron_attributes = parse_extended_patron_attributes($input);
foreach my $attr (@$extended_patron_attributes) {
unless (C4::Members::Attributes::CheckUniqueness($attr->{code}, $attr->{value}, $borrowernumber)) {
push @errors, "ERROR_extended_unique_id_failed";
$template->param(ERROR_extended_unique_id_failed => "$attr->{code}/$attr->{value}");
}
}
}
}
if ( ($op eq 'modify' || $op eq 'insert' || $op eq 'save'|| $op eq 'duplicate') and ($step == 0 or $step == 3 )){
unless ($newdata{'dateexpiry'}){
my $arg2 = $newdata{'dateenrolled'} || C4::Dates->today('iso');
$newdata{'dateexpiry'} = GetExpiryDate($newdata{'categorycode'},$arg2);
}
}
if ( ( defined $input->param('SMSnumber') ) && ( $input->param('SMSnumber') ne $newdata{'mobile'} ) ) {
$newdata{smsalertnumber} = $input->param('SMSnumber');
}
### Error checks should happen before this line.
$nok = $nok || scalar(@errors);
if ((!$nok) and $nodouble and ($op eq 'insert' or $op eq 'save')){
$debug and warn "$op dates: " . join "\t", map {"$_: $newdata{$_}"} qw(dateofbirth dateenrolled dateexpiry);
if ($op eq 'insert'){
# we know it's not a duplicate borrowernumber or there would already be an error
$borrowernumber = &AddMember(%newdata);
$newdata{'borrowernumber'} = $borrowernumber;
# If 'AutoEmailOpacUser' syspref is on, email user their account details from the 'notice' that matches the user's branchcode.
if ( C4::Context->preference("AutoEmailOpacUser") == 1 && $newdata{'userid'} && $newdata{'password'}) {
#look for defined primary email address, if blank - attempt to use borr.email and borr.emailpro instead
my $emailaddr;
if (C4::Context->preference("AutoEmailPrimaryAddress") ne 'OFF' &&
$newdata{C4::Context->preference("AutoEmailPrimaryAddress")} =~ /\w\@\w/ ) {
$emailaddr = $newdata{C4::Context->preference("AutoEmailPrimaryAddress")}
}
elsif ($newdata{email} =~ /\w\@\w/) {
$emailaddr = $newdata{email}
}
elsif ($newdata{emailpro} =~ /\w\@\w/) {
$emailaddr = $newdata{emailpro}
}
elsif ($newdata{B_email} =~ /\w\@\w/) {
$emailaddr = $newdata{B_email}
}
# if we manage to find a valid email address, send notice
if ($emailaddr) {
$newdata{emailaddr} = $emailaddr;
my $letter = getletter ('members', "ACCTDETAILS:$newdata{'branchcode'}") ;
# if $branch notice fails, then email a default notice instead.
$letter = getletter ('members', "ACCTDETAILS") if !$letter;
SendAlerts ( 'members' , \%newdata , $letter ) if $letter
}
}
if ($data{'organisations'}){
# need to add the members organisations
my @orgs=split(/\|/,$data{'organisations'});
add_member_orgs($borrowernumber,\@orgs);
}
if (C4::Context->preference('ExtendedPatronAttributes') and $input->param('setting_extended_patron_attributes')) {
C4::Members::Attributes::SetBorrowerAttributes($borrowernumber, $extended_patron_attributes);
}
if (C4::Context->preference('EnhancedMessagingPreferences') and $input->param('setting_messaging_prefs')) {
C4::Form::MessagingPreferences::handle_form_action($input, { borrowernumber => $borrowernumber }, $template, 1, $newdata{'categorycode'});
}
} elsif ($op eq 'save'){
if ($NoUpdateLogin) {
delete $newdata{'password'};
delete $newdata{'userid'};
}
&ModMember(%newdata) unless scalar(keys %newdata) <= 1; # bug 4508 - avoid crash if we're not
# updating any columns in the borrowers table,
# which can happen if we're only editing the
# patron attributes or messaging preferences sections
if (C4::Context->preference('ExtendedPatronAttributes') and $input->param('setting_extended_patron_attributes')) {
C4::Members::Attributes::SetBorrowerAttributes($borrowernumber, $extended_patron_attributes);
}
if (C4::Context->preference('EnhancedMessagingPreferences') and $input->param('setting_messaging_prefs')) {
C4::Form::MessagingPreferences::handle_form_action($input, { borrowernumber => $borrowernumber }, $template);
}
}
print scalar ($destination eq "circ") ?
$input->redirect("/cgi-bin/koha/circ/circulation.pl?borrowernumber=$borrowernumber") :
$input->redirect("/cgi-bin/koha/members/moremember.pl?borrowernumber=$borrowernumber") ;
exit; # You can only send 1 redirect! After that, content or other headers don't matter.
}
if ($delete){
print $input->redirect("/cgi-bin/koha/deletemem.pl?member=$borrowernumber");
exit; # same as above
}
if ($nok or !$nodouble){
$op="add" if ($op eq "insert");
$op="modify" if ($op eq "save");
%data=%newdata;
$template->param( updtype => ($op eq 'add' ?'I':'M')); # used to check for $op eq "insert"... but we just changed $op!
unless ($step){
$template->param( step_1 => 1,step_2 => 1,step_3 => 1, step_4 => 1, step_5 => 1, step_6 => 1);
}
}
if (C4::Context->preference("IndependantBranches")) {
my $userenv = C4::Context->userenv;
if ($userenv->{flags} % 2 != 1 && $data{'branchcode'}){
unless ($userenv->{branch} eq $data{'branchcode'}){
print $input->redirect("/cgi-bin/koha/members/members-home.pl");
exit;
}
}
}
if ($op eq 'add'){
$template->param( updtype => 'I', step_1=>1, step_2=>1, step_3=>1, step_4=>1, step_5 => 1, step_6 => 1);
}
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 ( $op eq "duplicate" ) {
$template->param( updtype => 'I' );
$template->param( step_1 => 1, step_2 => 1, step_3 => 1, step_4 => 1, step_5 => 1, step_6 => 1 ) unless $step;
}
$data{'cardnumber'}=fixup_cardnumber($data{'cardnumber'}) if $op eq 'add';
if(!defined($data{'sex'})){
$template->param( none => 1);
} elsif($data{'sex'} eq 'F'){
$template->param( female => 1);
} elsif ($data{'sex'} eq 'M'){
$template->param( male => 1);
} else {
$template->param( none => 1);
}
##Now all the data to modify a member.
my ($categories,$labels)=ethnicitycategories();
my $ethnicitycategoriescount=$#{$categories};
my $ethcatpopup;
if ($ethnicitycategoriescount>=0) {
$ethcatpopup = CGI::popup_menu(-name=>'ethnicity',
-id => 'ethnicity',
-tabindex=>'',
-values=>$categories,
-default=>$data{'ethnicity'},
-labels=>$labels);
$template->param(ethcatpopup => $ethcatpopup); # bad style, has to be fixed
}
my @typeloop;
my $no_categories = 1;
my $no_add;
foreach (qw(C A S P I X)) {
my $action="WHERE category_type=?";
($categories,$labels)=GetborCatFromCatType($_,$action);
if(scalar(@$categories) > 0){ $no_categories = 0; }
my @categoryloop;
foreach my $cat (@$categories){
push @categoryloop,{'categorycode' => $cat,
'categoryname' => $labels->{$cat},
'categorycodeselected' => ((defined($borrower_data->{'categorycode'}) &&
$cat eq $borrower_data->{'categorycode'})
|| (defined($categorycode) && $cat eq $categorycode)),
};
}
my %typehash;
$typehash{'typename'}=$_;
my $typedescription = "typename_".$typehash{'typename'};
$typehash{'categoryloop'}=\@categoryloop;
push @typeloop,{'typename' => $_,
$typedescription => 1,
'categoryloop' => \@categoryloop};
}
$template->param('typeloop' => \@typeloop,
no_categories => $no_categories);
if($no_categories){ $no_add = 1; }
# test in city
if ( $guarantorid ) {
$select_city = getidcity($data{city});
}
($default_city=$select_city) if ($step eq 0);
if (!defined($select_city) or $select_city eq '' ){
$default_city = &getidcity($data{'city'});
}
my $city_arrayref = GetCities();
if (@{$city_arrayref} ) {
$template->param( city_cgipopup => 1);
if ($default_city) { # flag the current or default val
for my $city ( @{$city_arrayref} ) {
if ($default_city == $city->{cityid}) {
$city->{selected} = 1;
last;
}
}
}
}
my $default_roadtype;
$default_roadtype=$data{'streettype'} ;
my($roadtypeid,$road_type)=GetRoadTypes();
$template->param( road_cgipopup => 1) if ($roadtypeid );
my $roadpopup = CGI::popup_menu(-name=>'streettype',
-id => 'streettype',
-values=>$roadtypeid,
-labels=>$road_type,
-override => 1,
-default=>$default_roadtype
);
my $default_borrowertitle;
$default_borrowertitle=$data{'title'} ;
my($borrowertitle)=GetTitles();
$template->param( title_cgipopup => 1) if ($borrowertitle);
my $borrotitlepopup = CGI::popup_menu(-name=>'title',
-id => 'btitle',
-values=>$borrowertitle,
-override => 1,
-default=>$default_borrowertitle
);
my @relationships = split /,|\|/, C4::Context->preference('borrowerRelationship');
my @relshipdata;
while (@relationships) {
my $relship = shift @relationships || '';
my %row = ('relationship' => $relship);
if (defined($data{'relationship'}) and $data{'relationship'} eq $relship) {
$row{'selected'}=' selected';
} else {
$row{'selected'}='';
}
push(@relshipdata, \%row);
}
my %flags = ( 'gonenoaddress' => ['gonenoaddress' ],
'lost' => ['lost']);
my @flagdata;
foreach (keys(%flags)) {
my $key = $_;
my %row = ('key' => $key,
'name' => $flags{$key}[0]);
if ($data{$key}) {
$row{'yes'}=' checked';
$row{'no'}='';
}
else {
$row{'yes'}='';
$row{'no'}=' checked';
}
push @flagdata,\%row;
}
#get Branches
my @branches;
my @select_branch;
my %select_branches;
my $onlymine=(C4::Context->preference('IndependantBranches') &&
C4::Context->userenv &&
C4::Context->userenv->{flags} % 2 !=1 &&
C4::Context->userenv->{branch}?1:0);
my $branches=GetBranches($onlymine);
my $default;
my $CGIbranch;
for my $branch (sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} } keys %$branches) {
push @select_branch,$branch;
$select_branches{$branch} = $branches->{$branch}->{'branchname'};
$default = C4::Context->userenv->{'branch'} if (C4::Context->userenv && C4::Context->userenv->{'branch'});
}
if(scalar(@select_branch) > 0){
# --------------------------------------------------------------------------------------------------------
#in modify mod :default value from $CGIbranch comes from borrowers table
#in add mod: default value come from branches table (ip correspendence)
if (defined ($data{'branchcode'}) and ( $op eq 'modify' || ( $op eq 'add' && $category_type eq 'C' ) )) {
$default = $data{'branchcode'};
}
$CGIbranch = CGI::scrolling_list(-id => 'branchcode',
-name => 'branchcode',
-values => \@select_branch,
-labels => \%select_branches,
-size => 1,
-override => 1,
-multiple =>0,
-default => $default,
);
}
if(!$CGIbranch){
$no_add = 1;
$template->param(no_branches => 1);
}
if($no_categories){
$no_add = 1;
$template->param(no_categories => 1);
}
$template->param(no_add => $no_add);
my $CGIorganisations;
my $member_of_institution;
if (C4::Context->preference("memberofinstitution")){
my $organisations=get_institutions();
my @orgs;
my %org_labels;
foreach my $organisation (keys %$organisations) {
push @orgs,$organisation;
$org_labels{$organisation}=$organisations->{$organisation}->{'surname'};
}
$member_of_institution=1;
$CGIorganisations = CGI::scrolling_list( -id => 'organisations',
-name => 'organisations',
-labels => \%org_labels,
-values => \@orgs,
-size => 5,
-multiple => 'true'
);
}
# --------------------------------------------------------------------------------------------------------
my $CGIsort = buildCGIsort("Bsort1","sort1",$data{'sort1'});
if ($CGIsort) {
$template->param(CGIsort1 => $CGIsort);
}
$template->param( sort1 => $data{'sort1'}); # shouldn't this be in an "else" statement like the 2nd one?
$CGIsort = buildCGIsort("Bsort2","sort2",$data{'sort2'});
if ($CGIsort) {
$template->param(CGIsort2 => $CGIsort);
} else {
$template->param( sort2 => $data{'sort2'});
}
if ($nok) {
foreach my $error (@errors) {
$template->param($error) || $template->param( $error => 1);
}
$template->param(nok => 1);
}
#Formatting data for display
if (!defined($data{'dateenrolled'}) or $data{'dateenrolled'} eq ''){
$data{'dateenrolled'}=C4::Dates->today('iso');
}
if ( $op eq 'duplicate' ) {
$data{'dateenrolled'} = C4::Dates->today('iso');
$data{'dateexpiry'} = GetExpiryDate( $data{'categorycode'}, $data{'dateenrolled'} );
}
if (C4::Context->preference('uppercasesurnames')) {
$data{'surname'} =uc($data{'surname'} );
$data{'contactname'}=uc($data{'contactname'});
}
$data{debarred} = C4::Overdues::CheckBorrowerDebarred($borrowernumber);
$data{datedebarred} = $data{debarred} if ( $data{debarred} ne "9999-12-31" );
foreach (qw(dateenrolled dateexpiry dateofbirth datedebarred)) {
$data{$_} = format_date($data{$_}); # back to syspref for display
$template->param( $_ => $data{$_});
}
if (C4::Context->preference('ExtendedPatronAttributes')) {
$template->param(ExtendedPatronAttributes => 1);
patron_attributes_form($template, $borrowernumber);
}
if (C4::Context->preference('EnhancedMessagingPreferences')) {
if ($op eq 'add') {
C4::Form::MessagingPreferences::set_form_values({ categorycode => $categorycode }, $template);
} else {
C4::Form::MessagingPreferences::set_form_values({ borrowernumber => $borrowernumber }, $template);
}
$template->param(SMSSendDriver => C4::Context->preference("SMSSendDriver"));
$template->param(SMSnumber => defined $data{'smsalertnumber'} ? $data{'smsalertnumber'} : $data{'mobile'});
}
$template->param( "showguarantor" => ($category_type=~/A|I|S|X/) ? 0 : 1); # associate with step to know where you are
$debug and warn "memberentry step: $step";
$template->param(%data);
$template->param( "step_$step" => 1) if $step; # associate with step to know where u are
$template->param( step => $step ) if $step; # associate with step to know where u are
$template->param( debug => $debug ) if $debug;
$template->param(
BorrowerMandatoryField => C4::Context->preference("BorrowerMandatoryField"),#field to test with javascript
category_type => $category_type,#to know the category type of the borrower
DHTMLcalendar_dateformat => C4::Dates->DHTMLcalendar(),
select_city => $select_city,
"$category_type" => 1,# associate with step to know where u are
destination => $destination,#to know wher u come from and wher u must go in redirect
check_member => $check_member,#to know if the borrower already exist(=>1) or not (=>0)
"op$op" => 1);
$template->param(CGIbranch=>$CGIbranch) if ($CGIbranch);
$template->param(
nodouble => $nodouble,
borrowernumber => $borrowernumber, #register number
guarantorid => ($borrower_data->{'guarantorid'} || $guarantorid),
ethcatpopup => $ethcatpopup,
relshiploop => \@relshipdata,
city_loop => $city_arrayref,
roadpopup => $roadpopup,
borrotitlepopup => $borrotitlepopup,
guarantorinfo => $guarantorinfo,
flagloop => \@flagdata,
dateformat => C4::Dates->new()->visual(),
C4::Context->preference('dateformat') => 1,
check_categorytype =>$check_categorytype,#to recover the category type with checkcategorytype function
category_type =>$category_type,
modify => $modify,
nok => $nok,#flag to konw if an error
memberofinstution => $member_of_institution,
CGIorganisations => $CGIorganisations,
NoUpdateLogin => $NoUpdateLogin
);
if(defined($data{'flags'})){
$template->param(flags=>$data{'flags'});
}
if(defined($data{'contacttitle'})){
$template->param("contacttitle_" . $data{'contacttitle'} => "SELECTED");
}
output_html_with_http_headers $input, $cookie, $template->output;
sub parse_extended_patron_attributes {
my ($input) = @_;
my @patron_attr = grep { /^patron_attr_\d+$/ } $input->param();
my @attr = ();
my %dups = ();
foreach my $key (@patron_attr) {
my $value = $input->param($key);
next unless defined($value) and $value ne '';
my $password = $input->param("${key}_password");
my $code = $input->param("${key}_code");
next if exists $dups{$code}->{$value};
$dups{$code}->{$value} = 1;
push @attr, { code => $code, value => $value, password => $password };
}
return \@attr;
}
sub patron_attributes_form {
my $template = shift;
my $borrowernumber = shift;
my @types = C4::Members::AttributeTypes::GetAttributeTypes();
if (scalar(@types) == 0) {
$template->param(no_patron_attribute_types => 1);
return;
}
my $attributes = C4::Members::Attributes::GetBorrowerAttributes($borrowernumber);
# map patron's attributes into a more convenient structure
my %attr_hash = ();
foreach my $attr (@$attributes) {
push @{ $attr_hash{$attr->{code}} }, $attr;
}
my @attribute_loop = ();
my $i = 0;
foreach my $type_code (map { $_->{code} } @types) {
my $attr_type = C4::Members::AttributeTypes->fetch($type_code);
my $entry = {
code => $attr_type->code(),
description => $attr_type->description(),
repeatable => $attr_type->repeatable(),
password_allowed => $attr_type->password_allowed(),
category => $attr_type->authorised_value_category(),
password => '',
};
if (exists $attr_hash{$attr_type->code()}) {
foreach my $attr (@{ $attr_hash{$attr_type->code()} }) {
my $newentry = { map { $_ => $entry->{$_} } %$entry };
$newentry->{value} = $attr->{value};
$newentry->{password} = $attr->{password};
$newentry->{use_dropdown} = 0;
if ($attr_type->authorised_value_category()) {
$newentry->{use_dropdown} = 1;
$newentry->{auth_val_loop} = GetAuthorisedValues($attr_type->authorised_value_category(), $attr->{value});
}
$i++;
$newentry->{form_id} = "patron_attr_$i";
#use Data::Dumper; die Dumper($entry) if $entry->{use_dropdown};
push @attribute_loop, $newentry;
}
} else {
$i++;
my $newentry = { map { $_ => $entry->{$_} } %$entry };
if ($attr_type->authorised_value_category()) {
$newentry->{use_dropdown} = 1;
$newentry->{auth_val_loop} = GetAuthorisedValues($attr_type->authorised_value_category());
}
$newentry->{form_id} = "patron_attr_$i";
push @attribute_loop, $newentry;
}
}
$template->param(patron_attributes => \@attribute_loop);
}
# Local Variables:
# tab-width: 8
# End: