3 # Copyright 2007 Liblime Ltd
5 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 2 of the License, or (at your option) any later
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License along with
17 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
18 # Suite 330, Boston, MA 02111-1307 USA
20 # Script to take some borrowers data in a known format and load it into Koha
24 # cardnumber,surname,firstname,title,othernames,initials,streetnumber,streettype,
25 # address line , address line 2, city, zipcode, email, phone, mobile, fax, work email, work phone,
26 # alternate streetnumber, alternate streettype, alternate address line 1, alternate city,
27 # alternate zipcode, alternate email, alternate phone, date of birth, branchcode,
28 # categorycode, enrollment date, expiry date, noaddress, lost, debarred, contact surname,
29 # contact firstname, contact title, borrower notes, contact relationship, ethnicity, ethnicity notes
30 # gender, username, opac note, contact note, password, sort one, sort two
32 # any fields except cardnumber can be blank but the number of fields must match
33 # dates should be in the format you have set up Koha to expect
34 # branchcode and categorycode need to be valid
39 use C4::Dates qw(format_date_in_iso);
42 use C4::Members::Attributes;
43 use C4::Members::AttributeTypes;
49 'cardnumber', 'surname', 'firstname', 'title',
50 'othernames', 'initials', 'streetnumber', 'streettype',
51 'address', 'address2', 'city', 'zipcode',
52 'email', 'phone', 'mobile', 'fax',
53 'emailpro', 'phonepro', 'B_streetnumber', 'B_streettype',
54 'B_address', 'B_city', 'B_zipcode', 'B_email',
55 'B_phone', 'dateofbirth', 'branchcode', 'categorycode',
56 'dateenrolled', 'dateexpiry', 'gonenoaddress', 'lost',
57 'debarred', 'contactname', 'contactfirstname', 'contacttitle',
58 'borrowernotes', 'relationship', 'ethnicity', 'ethnotes',
59 'sex', 'userid', 'opacnote', 'contactnote',
60 'password', 'sort1', 'sort2'
62 if (C4::Context->preference('ExtendedPatronAttributes')) {
63 push @columnkeys, 'patron_attributes';
68 my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
70 template_name => "tools/import_borrowers.tmpl",
74 flagsrequired => { tools => 'import_patrons' },
79 my $uploadborrowers = $input->param('uploadborrowers');
80 my $matchpoint = $input->param('matchpoint');
82 $matchpoint =~ s/^patron_attribute_//;
84 my $overwrite_cardnumber = $input->param('overwrite_cardnumber');
86 $template->param( SCRIPT_NAME => $ENV{'SCRIPT_NAME'} );
88 if (C4::Context->preference('ExtendedPatronAttributes')) {
89 $template->param(ExtendedPatronAttributes => 1);
92 if ( $uploadborrowers && length($uploadborrowers) > 0 ) {
93 my $csv = Text::CSV->new();
98 my $matchpoint_attr_type;
100 if (C4::Context->preference('ExtendedPatronAttributes')) {
101 $matchpoint_attr_type = C4::Members::AttributeTypes->fetch($matchpoint);
104 while ( my $borrowerline = <$uploadborrowers> ) {
105 my $status = $csv->parse($borrowerline);
106 my @columns = $csv->fields();
108 my $patron_attributes;
109 if ( @columns == @columnkeys ) {
110 @borrower{@columnkeys} = @columns;
112 if (C4::Context->preference('ExtendedPatronAttributes')) {
113 my $attr_str = $borrower{patron_attributes};
114 delete $borrower{patron_attributes};
115 my $ok = $csv->parse($attr_str);
116 my @list = $csv->fields();
117 # FIXME error handling
118 $patron_attributes = [ map { map { my @arr = split /:/, $_, 2; { code => $arr[0], value => $arr[1] } } $_ } @list ];
120 foreach (qw(dateofbirth dateenrolled dateexpiry)) {
121 my $tempdate = $borrower{$_} or next;
122 $borrower{$_} = format_date_in_iso($tempdate) || '';
125 if ($matchpoint eq 'cardnumber') {
126 my $member = GetMember( $borrower{'cardnumber'}, 'cardnumber' );
128 $borrowernumber = $member->{'borrowernumber'};
130 } elsif (C4::Context->preference('ExtendedPatronAttributes')) {
131 if (defined($matchpoint_attr_type)) {
132 foreach my $attr (@$patron_attributes) {
133 if ($attr->{code} eq $matchpoint and $attr->{value} ne '') {
134 my @borrowernumbers = $matchpoint_attr_type->get_patrons($attr->{value});
135 $borrowernumber = $borrowernumbers[0] if scalar(@borrowernumbers) == 1;
142 if ( $borrowernumber)
145 if ($overwrite_cardnumber) {
146 $borrower{'borrowernumber'} = $borrowernumber;
147 ModMember(%borrower);
148 if (C4::Context->preference('ExtendedPatronAttributes')) {
149 C4::Members::Attributes::SetBorrowerAttributes($borrower{'borrowernumber'}, $patron_attributes);
157 if ($borrowernumber = AddMember(%borrower)) {
158 if (C4::Context->preference('ExtendedPatronAttributes')) {
159 C4::Members::Attributes::SetBorrowerAttributes($borrowernumber, $patron_attributes);
163 $invalid++; # was just "$invalid", I assume incrementing was the point --atz
170 $template->param( 'uploadborrowers' => 1 );
172 'uploadborrowers' => 1,
173 'imported' => $imported,
174 'overwritten' => $overwritten,
175 'alreadyindb' => $alreadyindb,
176 'invalid' => $invalid,
177 'total' => $imported + $alreadyindb + $invalid + $overwritten,
181 if (C4::Context->preference('ExtendedPatronAttributes')) {
182 my @matchpoints = ();
183 my @attr_types = C4::Members::AttributeTypes::GetAttributeTypes();
184 foreach my $type (@attr_types) {
185 my $attr_type = C4::Members::AttributeTypes->fetch($type->{code});
186 if ($attr_type->unique_id()) {
187 push @matchpoints, { code => "patron_attribute_" . $attr_type->code(), description => $attr_type->description() };
190 $template->param(matchpoints => \@matchpoints);
194 output_html_with_http_headers $input, $cookie, $template->output;