View | Details | Raw Unified | Return to bug 3050
Collapse All | Expand All

(-)a/C4/Auth.pm (-1 lines)
Lines 358-364 sub get_template_and_user { Link Here
358
            EnableBorrowerFiles         => C4::Context->preference('EnableBorrowerFiles'),
358
            EnableBorrowerFiles         => C4::Context->preference('EnableBorrowerFiles'),
359
            UseKohaPlugins              => C4::Context->preference('UseKohaPlugins'),
359
            UseKohaPlugins              => C4::Context->preference('UseKohaPlugins'),
360
            UseCourseReserves            => C4::Context->preference("UseCourseReserves"),
360
            UseCourseReserves            => C4::Context->preference("UseCourseReserves"),
361
            AcqEnableFiles              => C4::Context->preference('AcqEnableFiles'),
362
        );
361
        );
363
    }
362
    }
364
    else {
363
    else {
(-)a/Koha/Misc/Files.pm (-40 / +132 lines)
Lines 20-59 package Koha::Misc::Files; Link Here
20
# along with Koha; if not, see <http://www.gnu.org/licenses>.
20
# along with Koha; if not, see <http://www.gnu.org/licenses>.
21
21
22
use Modern::Perl;
22
use Modern::Perl;
23
use strict; ## not needed if Modern::Perl, but perlcritic complains..
24
use vars qw($VERSION);
23
use vars qw($VERSION);
25
$VERSION = '0.20';
24
$VERSION = '0.23';
26
25
27
use C4::Context;
26
use C4::Context;
28
use C4::Output;
27
use C4::Output;
29
use C4::Dates;
28
use C4::Dates;
30
use C4::Debug;
31
29
32
=head1 NAME
30
=head1 NAME
33
31
34
Koha::Misc::Files - module for managing miscellaneous files
32
Koha::Misc::Files - module for managing miscellaneous files associated
35
associated with records from arbitrary tables
33
with records from arbitrary tables
34
35
=head1 SYNOPSIS
36
37
use Koha::Misc::Files;
38
39
my $mf = Koha::Misc::Files->new( tabletag => $tablename,
40
    recordid => $recordnumber );
41
42
=head1 FUNCTIONS
43
44
=over
45
46
=item new()
47
48
my $mf = Koha::Misc::Files->new( tabletag => $tablename,
49
    recordid => $recordnumber );
50
51
Creates new Koha::Misc::Files object. Such object is essentially
52
a pair: in typical usage scenario, 'tabletag' parameter will be
53
a database table name, and 'recordid' an unique record ID number
54
from this table. However, this method does accept an arbitrary
55
string as 'tabletag', and an arbitrary integer as 'recordid'.
56
57
Particular Koha::Misc::Files object can have one or more file records
58
(actuall file contents + various file metadata) associated with it.
59
60
In case of an error (wrong parameter format) it returns undef.
36
61
37
=cut
62
=cut
38
63
39
sub new {
64
sub new {
40
    my ( $class, %args ) = @_;
65
    my ( $class, %args ) = @_;
41
66
42
    ( defined( $args{'tabletag'} ) && defined( $args{'recordid'} ) )
67
    my $recid = $args{'recordid'};
68
    my $tag   = $args{'tabletag'};
69
    ( defined($tag) && $tag ne '' && defined($recid) && $recid =~ /^\d+$/ )
43
      || return ();
70
      || return ();
71
44
    my $self = bless( {}, $class );
72
    my $self = bless( {}, $class );
45
73
46
    $self->{'table_tag'} = $args{'tabletag'};
74
    $self->{'table_tag'} = $tag;
47
    $self->{'record_id'} = $args{'recordid'};
75
    $self->{'record_id'} = '' . ( 0 + $recid );
48
76
49
    return $self;
77
    return $self;
50
}
78
}
51
79
52
=item GetFilesInfo()
80
=item GetFilesInfo()
53
81
54
    my $mf = Koha::Misc::Files->new( tabletag => $tablename,
82
my $files_descriptions = $mf->GetFilesInfo();
55
        recordid => $recordnumber);
83
56
    my $files_hashref = $mf->GetFilesInfo
84
This method returns a reference to an array of hashes
85
containing files metadata (file_id, file_name, file_type,
86
file_description, file_size, date_uploaded) for all file records
87
associated with given $mf object, or an empty arrayref if there are
88
no such records yet.
89
90
In case of an error it returns undef.
57
91
58
=cut
92
=cut
59
93
Lines 61-113 sub GetFilesInfo { Link Here
61
    my $self = shift;
95
    my $self = shift;
62
96
63
    my $dbh   = C4::Context->dbh;
97
    my $dbh   = C4::Context->dbh;
64
    my $query = "
98
    my $query = '
65
        SELECT
99
        SELECT
66
            file_id,
100
            file_id,
67
            file_name,
101
            file_name,
68
            file_type,
102
            file_type,
69
            file_description,
103
            file_description,
70
            date_uploaded
104
            date_uploaded,
105
            LENGTH(file_content) AS file_size
71
        FROM misc_files
106
        FROM misc_files
72
        WHERE table_tag = ? AND record_id = ?
107
        WHERE table_tag = ? AND record_id = ?
73
        ORDER BY file_name, date_uploaded
108
        ORDER BY file_name, date_uploaded
74
    ";
109
    ';
75
    my $sth = $dbh->prepare($query);
110
    my $sth = $dbh->prepare($query);
76
    $sth->execute( $self->{'table_tag'}, $self->{'record_id'} );
111
    $sth->execute( $self->{'table_tag'}, $self->{'record_id'} );
77
    return $sth->fetchall_arrayref( {} );
112
    return $sth->fetchall_arrayref( {} );
78
}
113
}
79
114
80
=item AddFile()
115
=item AddFile()
81
    my $mf = Koha::Misc::Files->new( tabletag => $tablename,
116
82
        recordid => $recordnumber);
117
$mf->AddFile( name => $filename, type => $mimetype,
83
    $mf->AddFile( name => $filename, type => $mimetype, description => $description, content => $content );
118
    description => $description, content => $content );
119
120
Adds a new file (we want to store for / associate with a given
121
object) to the database. Parameters 'name' and 'content' are mandatory.
122
Note: this method would (silently) fail if there is no 'name' given
123
or if the 'content' provided is empty.
124
84
=cut
125
=cut
85
126
86
sub AddFile {
127
sub AddFile {
87
    my ( $self, %args ) = @_;
128
    my ( $self, %args ) = @_;
88
129
89
    my $name        = $args{'name'};
130
    my $name        = $args{'name'};
90
    my $type        = $args{'type'};
131
    my $type        = $args{'type'} // '';
91
    my $description = $args{'description'};
132
    my $description = $args{'description'};
92
    my $content     = $args{'content'};
133
    my $content     = $args{'content'};
93
134
94
    return unless ( $name && $content );
135
    return unless ( defined($name) && $name ne '' && defined($content) && $content ne '' );
95
136
96
    my $dbh   = C4::Context->dbh;
137
    my $dbh   = C4::Context->dbh;
97
    my $query = "
138
    my $query = '
98
        INSERT INTO misc_files ( table_tag, record_id, file_name, file_type, file_description, file_content )
139
        INSERT INTO misc_files ( table_tag, record_id, file_name, file_type, file_description, file_content )
99
        VALUES ( ?,?,?,?,?,? )
140
        VALUES ( ?,?,?,?,?,? )
100
    ";
141
    ';
101
    my $sth = $dbh->prepare($query);
142
    my $sth = $dbh->prepare($query);
102
    $sth->execute( $self->{'table_tag'}, $self->{'record_id'}, $name, $type,
143
    $sth->execute( $self->{'table_tag'}, $self->{'record_id'}, $name, $type,
103
        $description, $content );
144
        $description, $content );
104
}
145
}
105
146
106
=item GetFile()
147
=item GetFile()
107
    my $mf = Koha::Misc::Files->new( tabletag => $tablename,
148
108
        recordid => $recordnumber);
149
my $file = $mf->GetFile( id => $file_id );
109
    ...
150
110
    my $file = $mf->GetFile( id => $file_id );
151
For an individual, specific file ID this method returns a hashref
152
containing all metadata (file_id, table_tag, record_id, file_name,
153
file_type, file_description, file_content, date_uploaded), plus
154
an actuall contents of a file (in 'file_content'). In typical usage
155
scenarios, for a given $mf object, specific file IDs have to be
156
obtained first by GetFilesInfo() call.
157
158
Returns undef in case when file ID specified as 'id' parameter was not
159
found in the database.
160
111
=cut
161
=cut
112
162
113
sub GetFile {
163
sub GetFile {
Lines 116-134 sub GetFile { Link Here
116
    my $file_id = $args{'id'};
166
    my $file_id = $args{'id'};
117
167
118
    my $dbh   = C4::Context->dbh;
168
    my $dbh   = C4::Context->dbh;
119
    my $query = "
169
    my $query = '
120
        SELECT * FROM misc_files WHERE file_id = ? AND table_tag = ? AND record_id = ?
170
        SELECT * FROM misc_files WHERE file_id = ? AND table_tag = ? AND record_id = ?
121
    ";
171
    ';
122
    my $sth = $dbh->prepare($query);
172
    my $sth = $dbh->prepare($query);
123
    $sth->execute( $file_id, $self->{'table_tag'}, $self->{'record_id'} );
173
    $sth->execute( $file_id, $self->{'table_tag'}, $self->{'record_id'} );
124
    return $sth->fetchrow_hashref();
174
    return $sth->fetchrow_hashref();
125
}
175
}
126
176
127
=item DelFile()
177
=item DelFile()
128
    my $mf = Koha::Misc::Files->new( tabletag => $tablename,
178
129
        recordid => $recordnumber);
179
$mf->DelFile( id => $file_id );
130
    ...
180
131
    $mf->DelFile( id => $file_id );
181
Deletes specific, individual file record (file contents and metadata)
182
from the database.
183
132
=cut
184
=cut
133
185
134
sub DelFile {
186
sub DelFile {
Lines 137-174 sub DelFile { Link Here
137
    my $file_id = $args{'id'};
189
    my $file_id = $args{'id'};
138
190
139
    my $dbh   = C4::Context->dbh;
191
    my $dbh   = C4::Context->dbh;
140
    my $query = "
192
    my $query = '
141
        DELETE FROM misc_files WHERE file_id = ? AND table_tag = ? AND record_id = ?
193
        DELETE FROM misc_files WHERE file_id = ? AND table_tag = ? AND record_id = ?
142
    ";
194
    ';
143
    my $sth = $dbh->prepare($query);
195
    my $sth = $dbh->prepare($query);
144
    $sth->execute( $file_id, $self->{'table_tag'}, $self->{'record_id'} );
196
    $sth->execute( $file_id, $self->{'table_tag'}, $self->{'record_id'} );
145
}
197
}
146
198
147
=item DelAllFiles()
199
=item DelAllFiles()
148
    my $mf = Koha::Misc::Files->new( tabletag => $tablename,
200
149
        recordid => $recordnumber);
201
$mf->DelAllFiles();
150
    $mf->DelAllFiles;
202
203
Deletes all file records associated with (stored for) a given $mf object.
204
151
=cut
205
=cut
152
206
153
sub DelAllFiles {
207
sub DelAllFiles {
154
    my ($self) = @_;
208
    my ($self) = @_;
155
209
156
    my $dbh   = C4::Context->dbh;
210
    my $dbh   = C4::Context->dbh;
157
    my $query = "
211
    my $query = '
158
        DELETE FROM misc_files WHERE table_tag = ? AND record_id = ?
212
        DELETE FROM misc_files WHERE table_tag = ? AND record_id = ?
159
    ";
213
    ';
160
    my $sth = $dbh->prepare($query);
214
    my $sth = $dbh->prepare($query);
161
    $sth->execute( $self->{'table_tag'}, $self->{'record_id'} );
215
    $sth->execute( $self->{'table_tag'}, $self->{'record_id'} );
162
}
216
}
163
217
218
=item MergeFileRecIds()
219
220
$mf->MergeFileRecIds(@ids_to_be_merged);
221
222
This method re-associates all individuall file records associated with
223
some "parent" records IDs (provided in @ids_to_be_merged) with the given
224
single $mf object (which would be treated as a "parent" destination).
225
226
This a helper method; typically it needs to be called only in cases when
227
some "parent" records are being merged in the (external) 'tablename'
228
table.
229
230
=cut
231
232
sub MergeFileRecIds {
233
    my ( $self, @ids_to_merge ) = @_;
234
235
    my $dst_recid = $self->{'record_id'};
236
    @ids_to_merge = map { ( $dst_recid == $_ ) ? () : ($_); } @ids_to_merge;
237
    @ids_to_merge > 0 || return ();
238
239
    my $dbh   = C4::Context->dbh;
240
    my $query = '
241
        UPDATE misc_files SET record_id = ?
242
        WHERE table_tag = ? AND record_id = ?
243
    ';
244
    my $sth = $dbh->prepare($query);
245
246
    for my $src_recid (@ids_to_merge) {
247
        $sth->execute( $dst_recid, $self->{'table_tag'}, $src_recid );
248
    }
249
}
250
164
1;
251
1;
252
165
__END__
253
__END__
166
254
167
=back
255
=back
168
256
257
=head1 SEE ALSO
258
259
Koha::Borrower::Files
260
169
=head1 AUTHOR
261
=head1 AUTHOR
170
262
171
Kyle M Hall <kyle.m.hall@gmail.com>
263
Kyle M Hall E<lt>kyle.m.hall@gmail.comE<gt>,
172
Jacek Ablewicz <ablewicz@gmail.com>
264
Jacek Ablewicz E<lt>ablewicz@gmail.comE<gt>
173
265
174
=cut
266
=cut
(-)a/acqui/invoice-files.pl (-23 / +12 lines)
Lines 27-47 Manage files associated with invoice Link Here
27
27
28
=cut
28
=cut
29
29
30
use strict;
30
use Modern::Perl;
31
use warnings;
32
31
33
use CGI;
32
use CGI;
34
use C4::Auth;
33
use C4::Auth;
35
use C4::Output;
34
use C4::Output;
36
use C4::Acquisition;
35
use C4::Acquisition;
37
use C4::Debug;
38
use Koha::DateUtils;
39
use Koha::Misc::Files;
36
use Koha::Misc::Files;
40
37
41
my $input = new CGI;
38
my $input = new CGI;
42
my ( $template, $loggedinuser, $cookie, $flags ) = get_template_and_user(
39
my ( $template, $loggedinuser, $cookie, $flags ) = get_template_and_user(
43
    {
40
    {
44
        template_name   => 'acqui/invoice-files.tmpl',
41
        template_name   => 'acqui/invoice-files.tt',
45
        query           => $input,
42
        query           => $input,
46
        type            => 'intranet',
43
        type            => 'intranet',
47
        authnotrequired => 0,
44
        authnotrequired => 0,
Lines 50-60 my ( $template, $loggedinuser, $cookie, $flags ) = get_template_and_user( Link Here
50
    }
47
    }
51
);
48
);
52
49
53
my $invoiceid = $input->param('invoiceid');
50
my $invoiceid = $input->param('invoiceid') // '';
54
my $op = $input->param('op') // '';
51
my $op = $input->param('op') // '';
52
my %errors;
55
53
56
$template->param( 'invoice_files' => 1 );
57
my $mf = Koha::Misc::Files->new( tabletag => 'aqinvoices', recordid => $invoiceid );
54
my $mf = Koha::Misc::Files->new( tabletag => 'aqinvoices', recordid => $invoiceid );
55
defined($mf) || do { $op = 'none'; $errors{'invalid_parameter'} = 1; };
58
56
59
if ( $op eq 'download' ) {
57
if ( $op eq 'download' ) {
60
    my $file_id = $input->param('file_id');
58
    my $file_id = $input->param('file_id');
Lines 62-72 if ( $op eq 'download' ) { Link Here
62
60
63
    my $fname = $file->{'file_name'};
61
    my $fname = $file->{'file_name'};
64
    my $ftype = $file->{'file_type'};
62
    my $ftype = $file->{'file_type'};
65
    if ($input->param('view') && ($ftype =~ /^image\//i || $fname =~ /\.pdf/i)) {
63
    if ($input->param('view') && ($ftype =~ m|^image/|i || $fname =~ /\.pdf/i)) {
66
        $fname =~ /\.pdf/i && do { $ftype='application/pdf'; };
64
        $fname =~ /\.pdf/i && do { $ftype='application/pdf'; };
67
        print $input->header(
65
        print $input->header(
68
            -type       => $ftype,
66
            -type       => $ftype,
69
            -charset    => 'utf-8',
67
            -charset    => 'utf-8'
70
        );
68
        );
71
    } else {
69
    } else {
72
        print $input->header(
70
        print $input->header(
Lines 86-92 else { Link Here
86
        booksellerid     => $details->{'booksellerid'},
84
        booksellerid     => $details->{'booksellerid'},
87
        datereceived     => $details->{'datereceived'},
85
        datereceived     => $details->{'datereceived'},
88
    );
86
    );
89
    my %errors;
90
87
91
    if ( $op eq 'upload' ) {
88
    if ( $op eq 'upload' ) {
92
        my $uploaded_file = $input->upload('uploadfile');
89
        my $uploaded_file = $input->upload('uploadfile');
Lines 96-118 else { Link Here
96
            my $mimetype = $input->uploadInfo($filename)->{'Content-Type'};
93
            my $mimetype = $input->uploadInfo($filename)->{'Content-Type'};
97
94
98
            $errors{'empty_upload'} = 1 if ( -z $uploaded_file );
95
            $errors{'empty_upload'} = 1 if ( -z $uploaded_file );
99
96
            unless (%errors) {
100
            if (%errors) {
97
                my $file_content = do { local $/; <$uploaded_file>; };
101
                $template->param( errors => %errors );
98
                if ($mimetype =~ /^application\/(force-download|unknown)$/i && $filename =~ /\.pdf$/i) {
102
            }
103
            else {
104
                my $file_content;
105
                while (<$uploaded_file>) {
106
                    $file_content .= $_;
107
                }
108
                if ($mimetype =~ /^application\/(force-download|unknown)$/i && $filename =~ /\.pdf$/) {
109
                    $mimetype = 'application/pdf';
99
                    $mimetype = 'application/pdf';
110
                }
100
                }
111
                $mf->AddFile(
101
                $mf->AddFile(
112
                    name    => $filename,
102
                    name    => $filename,
113
                    type    => $mimetype,
103
                    type    => $mimetype,
114
                    content => $file_content,
104
                    content => $file_content,
115
                    description => $input->param('description'),
105
                    description => $input->param('description')
116
                );
106
                );
117
            }
107
            }
118
        }
108
        }
Lines 124-132 else { Link Here
124
    }
114
    }
125
115
126
    $template->param(
116
    $template->param(
127
        files => $mf->GetFilesInfo(),
117
        files => (defined($mf)? $mf->GetFilesInfo(): undef),
128
        errors => \%errors
118
        errors => \%errors
129
    );
119
    );
130
131
    output_html_with_http_headers $input, $cookie, $template->output;
120
    output_html_with_http_headers $input, $cookie, $template->output;
132
}
121
}
(-)a/acqui/invoice.pl (-9 / +9 lines)
Lines 52-57 my ( $template, $loggedinuser, $cookie, $flags ) = get_template_and_user( Link Here
52
my $invoiceid = $input->param('invoiceid');
52
my $invoiceid = $input->param('invoiceid');
53
my $op        = $input->param('op');
53
my $op        = $input->param('op');
54
54
55
my $invoice_files;
56
if ( C4::Context->preference('AcqEnableFiles') ) {
57
    $invoice_files = Koha::Misc::Files->new(
58
        tabletag => 'aqinvoices', recordid => $invoiceid );
59
}
60
55
if ( $op && $op eq 'close' ) {
61
if ( $op && $op eq 'close' ) {
56
    CloseInvoice($invoiceid);
62
    CloseInvoice($invoiceid);
57
    my $referer = $input->param('referer');
63
    my $referer = $input->param('referer');
Lines 87-100 elsif ( $op && $op eq 'mod' ) { Link Here
87
    } elsif ($input->param('merge')) {
93
    } elsif ($input->param('merge')) {
88
        my @sources = $input->param('merge');
94
        my @sources = $input->param('merge');
89
        MergeInvoices($invoiceid, \@sources);
95
        MergeInvoices($invoiceid, \@sources);
96
        defined($invoice_files) && $invoice_files->MergeFileRecIds(@sources);
90
    }
97
    }
91
    $template->param( modified => 1 );
98
    $template->param( modified => 1 );
92
}
99
}
93
elsif ( $op && $op eq 'delete' ) {
100
elsif ( $op && $op eq 'delete' ) {
94
    DelInvoice($invoiceid);
101
    DelInvoice($invoiceid);
95
    C4::Context->preference('AcqEnableFiles')
102
    defined($invoice_files) && $invoice_files->DelAllFiles();
96
      && $invoiceid && Koha::Misc::Files->new(
97
        tabletag => 'aqinvoices', recordid => $invoiceid )->DelAllFiles();
98
    my $referer = $input->param('referer') || 'invoices.pl';
103
    my $referer = $input->param('referer') || 'invoices.pl';
99
    if ($referer) {
104
    if ($referer) {
100
        print $input->redirect($referer);
105
        print $input->redirect($referer);
Lines 213-224 $template->param( Link Here
213
    budgets_loop             => \@budgets_loop,
218
    budgets_loop             => \@budgets_loop,
214
);
219
);
215
220
216
{
221
defined( $invoice_files ) && $template->param( files => $invoice_files->GetFilesInfo() );
217
    C4::Context->preference('AcqEnableFiles') || last;
218
    my $mf = Koha::Misc::Files->new(
219
        tabletag => 'aqinvoices', recordid => $invoiceid );
220
    defined( $mf ) && $template->param( files => $mf->GetFilesInfo() );
221
}
222
222
223
sub get_infos {
223
sub get_infos {
224
    my $order      = shift;
224
    my $order      = shift;
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/invoice-files.tt (-60 / +74 lines)
Lines 4-9 Link Here
4
<title>Koha &rsaquo; Acquisitions &rsaquo; Invoice &rsaquo; Files</title>
4
<title>Koha &rsaquo; Acquisitions &rsaquo; Invoice &rsaquo; Files</title>
5
<link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" />
5
<link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" />
6
[% INCLUDE 'doc-head-close.inc' %]
6
[% INCLUDE 'doc-head-close.inc' %]
7
[% INCLUDE 'datatables.inc' %]
8
<script type="text/javascript">
9
//<![CDATA[
10
    $(document).ready(function() {
11
        $("#invoice_files_details_table").dataTable($.extend(true, {}, dataTablesDefaults, {
12
            "aoColumnDefs": [
13
                { "aTargets": [ -1, -2 ], "bSortable": false, "bSearchable": false },
14
                { "aTargets": [ 3 ], "sType": "natural" }
15
            ],
16
            bInfo: false,
17
            bPaginate: false,
18
            bFilter: false,
19
            sDom: "t"
20
        }));
21
    });
22
//]]>
23
</script>
7
</head>
24
</head>
8
<body>
25
<body>
9
[% INCLUDE 'header.inc' %]
26
[% INCLUDE 'header.inc' %]
Lines 16-82 Link Here
16
<div id="bd">
33
<div id="bd">
17
  <div id="yui-main">
34
  <div id="yui-main">
18
    <div class="yui-b">
35
    <div class="yui-b">
19
      <h1>Files for invoice: [% invoicenumber %]</h1>
36
      <h2>Files for invoice: [% invoicenumber | html %]</h2>
20
37
      <p><b>Vendor: </b><a href="/cgi-bin/koha/acqui/supplier.pl?booksellerid=[% booksellerid %]">[% suppliername %]</a></p>
21
      <p>Vendor: <a href="/cgi-bin/koha/acqui/supplier.pl?booksellerid=[% booksellerid %]">[% suppliername %]</a></p>
38
      <br />
22
39
      [% IF errors %]
23
                [% IF errors %]
40
        <div class="dialog alert">
24
                    <div class="dialog alert">
41
          [% IF errors.empty_upload %]The file you are attempting to upload has no contents.[% END %]
25
                        [% IF errors.empty_upload %]The file you are attempting to upload has no contents.[% END %]
42
          [% IF errors.no_file %]You did not select a file to upload.[% END %]
26
                        [% IF errors.no_file %]You did not select a file to upload.[% END %]
43
          [% IF errors.invalid_parameter %]Invalid or missing script parameter.[% END %]
27
                    </div>
44
        </div>
28
                [% END %]
45
      [% END %]
29
46
      [% IF files %]
30
                [% IF ( files ) %]
47
          <table id="invoice_files_details_table">
31
                <table>
48
              <thead>
32
                    <thead>
49
                  <tr>
33
                        <tr>
50
                      <th>Name</th>
34
                            <th>Name</th>
51
                      <th>Type</th>
35
                            <th>Type</th>
52
                      <th>Description</th>
36
                            <th>Description</th>
53
                      <th>Uploaded</th>
37
                            <th>Uploaded</th>
54
                      <th>Bytes</th>
38
                            <th>&nbsp;</th>
55
                      <th>&nbsp;</th>
39
                            <th>&nbsp;</th>
56
                      <th>&nbsp;</th>
40
                        </tr>
57
                  </tr>
41
                    </thead>
58
              </thead>
42
59
              <tbody>
43
                    <tbody>
60
                [% FOREACH f IN files %]
44
                        [% FOREACH f IN files %]
61
                  <tr>
45
                            <tr>
62
                      <td><a href="?invoiceid=[% invoiceid %]&amp;op=download&amp;view=1&amp;file_id=[% f.file_id %]">[% f.file_name | html %]</a></td>
46
                                 <td><a href="?invoiceid=[% invoiceid %]&amp;op=download&amp;view=1&amp;file_id=[% f.file_id %]">[% f.file_name %]</a></td>
63
                      <td>[% f.file_type | html %]</td>
47
                                 <td>[% f.file_type %]</td>
64
                      <td>[% f.file_description | html %]</td>
48
                                 <td>[% f.file_description %]</td>
65
                      <td><!-- [% f.date_uploaded %] -->[% f.date_uploaded | $KohaDates %]</td>
49
                                 <td>[% f.date_uploaded | $KohaDates %]</td>
66
                      <td>[% f.file_size %]</td>
50
                                 <td><a href="?invoiceid=[% invoiceid %]&amp;op=delete&amp;file_id=[% f.file_id %]">Delete</a></td>
67
                      <td><a href="?invoiceid=[% invoiceid %]&amp;op=delete&amp;file_id=[% f.file_id %]">Delete</a></td>
51
                                 <td><a href="?invoiceid=[% invoiceid %]&amp;op=download&amp;file_id=[% f.file_id %]">Download</a></td>
68
                      <td><a href="?invoiceid=[% invoiceid %]&amp;op=download&amp;file_id=[% f.file_id %]">Download</a></td>
52
                            </tr>
69
                  </tr>
53
                        [% END %]
54
                    </tbody>
55
                </table>
56
                [% ELSE %]
57
                <div class="dialog message">
58
                    <p>This invoice has no files attached.</p>
59
                </div>
60
                [% END %]
70
                [% END %]
61
71
              </tbody>
62
                <form method="post" action="/cgi-bin/koha/acqui/invoice-files.pl" enctype="multipart/form-data">
72
          </table>
63
                    <fieldset class="rows">
73
      [% ELSE %]
64
                        <legend>Upload New File</legend>
74
          <div class="dialog message">
65
                        <ol>
75
              <p>This invoice has no files attached.</p>
66
                        <li><input type="hidden" name="op" value="upload" />
76
          </div>
67
                        <input type="hidden" name="invoiceid" value="[% invoiceid %]" />
77
      [% END %]
68
                        <input type="hidden" name="MAX_FILE_SIZE" value="9000000" />
78
      [% IF invoiceid %]
69
79
          <br />
70
                        <label for="description">Description:</label>
80
          <form method="post" action="/cgi-bin/koha/acqui/invoice-files.pl" enctype="multipart/form-data">
71
                        <input name="description" id="description" type="text" /></li>
81
              <fieldset class="rows">
72
82
                  <legend>Upload New File</legend>
73
                        <li><label for="uploadfile">File:</label><input name="uploadfile" type="file" id="uploadfile" /></li>
83
                  <ol>
74
84
                      <li><input type="hidden" name="op" value="upload" />
75
                        </ol>
85
                      <input type="hidden" name="invoiceid" value="[% invoiceid %]" />
76
                        <fieldset class="action"><input name="upload" type="submit" id="upload" value="Upload File" /></fieldset>
86
                      <label for="description">Description:</label>
77
                    </fieldset>
87
                      <input name="description" id="description" type="text" /></li>
78
                </form>
88
                      <li><label for="uploadfile">File:</label><input name="uploadfile" type="file" id="uploadfile" /></li>
79
89
                  </ol>
90
                  <fieldset class="action"><input name="upload" type="submit" id="upload" value="Upload File" /></fieldset>
91
              </fieldset>
92
          </form>
93
      [% END %]
80
    </div>
94
    </div>
81
  </div>
95
  </div>
82
  <div class="yui-b">
96
  <div class="yui-b">
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/invoice.tt (-8 / +20 lines)
Lines 1-3 Link Here
1
[% USE Koha %]
1
[% USE KohaDates %]
2
[% USE KohaDates %]
2
3
3
[% INCLUDE 'doc-head-open.inc' %]
4
[% INCLUDE 'doc-head-open.inc' %]
Lines 15-20 Link Here
15
            bFilter: false,
16
            bFilter: false,
16
            sDom: "t"
17
            sDom: "t"
17
        }));
18
        }));
19
[% IF ( (Koha.Preference('AcqEnableFiles')) && files ) %]
20
        $("#invoice_files_table").dataTable($.extend(true, {}, dataTablesDefaults, {
21
            "aoColumnDefs": [
22
                { "aTargets": [ 3 ], "sType": "natural" }
23
            ],
24
            bInfo: false,
25
            bPaginate: false,
26
            bFilter: false,
27
            sDom: "t"
28
        }));
29
[% END %]
18
    });
30
    });
19
//]]>
31
//]]>
20
</script>
32
</script>
Lines 89-95 Link Here
89
      </form>
101
      </form>
90
      <p>
102
      <p>
91
          <a href="/cgi-bin/koha/acqui/parcel.pl?invoiceid=[% invoiceid %]">Go to receipt page</a>
103
          <a href="/cgi-bin/koha/acqui/parcel.pl?invoiceid=[% invoiceid %]">Go to receipt page</a>
92
          [% IF ( AcqEnableFiles ) %]| <a href="/cgi-bin/koha/acqui/invoice-files.pl?invoiceid=[% invoiceid %]">Manage invoice files</a>[% END %]
104
          [% IF Koha.Preference('AcqEnableFiles') %]| <a href="/cgi-bin/koha/acqui/invoice-files.pl?invoiceid=[% invoiceid %]">Manage invoice files</a>[% END %]
93
      </p>
105
      </p>
94
      <h2>Invoice details</h2>
106
      <h2>Invoice details</h2>
95
      [% IF orders_loop.size %]
107
      [% IF orders_loop.size %]
Lines 170-179 Link Here
170
        [% ELSE %]
182
        [% ELSE %]
171
            <div class="dialog message"><p>No orders yet</p></div>
183
            <div class="dialog message"><p>No orders yet</p></div>
172
        [% END %]
184
        [% END %]
173
        [% IF ( AcqEnableFiles && files ) %]
185
        [% IF ( (Koha.Preference('AcqEnableFiles')) && files ) %]
174
            <br>
186
            <br />
175
            <h2>Files attached to invoice</h2>
187
            <h2>Files attached to invoice</h2>
176
            <table>
188
            <table id="invoice_files_table">
177
                <thead>
189
                <thead>
178
                    <tr>
190
                    <tr>
179
                        <th>Name</th>
191
                        <th>Name</th>
Lines 185-194 Link Here
185
                <tbody>
197
                <tbody>
186
                [% FOREACH f IN files %]
198
                [% FOREACH f IN files %]
187
                    <tr>
199
                    <tr>
188
                         <td><a href="/cgi-bin/koha/acqui/invoice-files.pl?invoiceid=[% invoiceid %]&amp;op=download&amp;view=1&amp;file_id=[% f.file_id %]">[% f.file_name %]</a></td>
200
                         <td><a href="/cgi-bin/koha/acqui/invoice-files.pl?invoiceid=[% invoiceid %]&amp;op=download&amp;view=1&amp;file_id=[% f.file_id %]">[% f.file_name | html %]</a></td>
189
                         <td>[% f.file_type %]</td>
201
                         <td>[% f.file_type | html %]</td>
190
                         <td>[% f.file_description %]</td>
202
                         <td>[% f.file_description | html %]</td>
191
                         <td>[% f.date_uploaded | $KohaDates %]</td>
203
                         <td><!-- [% f.date_uploaded %] -->[% f.date_uploaded | $KohaDates %]</td>
192
                    </tr>
204
                    </tr>
193
                [% END %]
205
                [% END %]
194
                </tbody>
206
                </tbody>
(-)a/t/db_dependent/Koha_Misc_Files.t (-1 / +87 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# Unit tests for Koha::Misc::Files
4
# Author: Jacek Ablewicz, abl@biblos.pk.edu.pl
5
6
use Modern::Perl;
7
use C4::Context;
8
use Test::More tests => 27;
9
10
BEGIN {
11
    use_ok('Koha::Misc::Files');
12
}
13
14
my $dbh = C4::Context->dbh;
15
$dbh->{AutoCommit} = 0;
16
$dbh->{RaiseError} = 1;
17
18
## new() parameter handling check
19
is(Koha::Misc::Files->new(recordid => 12), undef, "new() param check test/1");
20
is(Koha::Misc::Files->new(recordid => 'aa123', tabletag => 'ttag_a'), undef, "new() param check test/2");
21
22
## create some test objects with arbitrary (tabletag, recordid) pairs
23
my $mf_a_123 = Koha::Misc::Files->new(recordid => '123', tabletag => 'tst_table_a');
24
my $mf_a_124 = Koha::Misc::Files->new(recordid => '124', tabletag => 'tst_table_a');
25
my $mf_b_221 = Koha::Misc::Files->new(recordid => '221', tabletag => 'tst_table_b');
26
is(ref($mf_a_123), "Koha::Misc::Files", "new() returned object type");
27
28
## GetFilesInfo() initial tests (dummy AddFile() / parameter handling checks)
29
is(ref($mf_a_123->GetFilesInfo()), 'ARRAY', "GetFilesInfo() return type");
30
is(scalar @{$mf_a_123->GetFilesInfo()}, 0, "GetFilesInfo() empty/non-empty result/1");
31
$mf_a_123->AddFile(name => '', type => 'text/plain', content => "aaabbcc");
32
is(scalar @{$mf_a_123->GetFilesInfo()}, 0, "GetFilesInfo() empty/non-empty result/2");
33
34
## AddFile(); add 5 sample file records for 3 test objects
35
$mf_a_123->AddFile(name => 'File_name_1.txt', type => 'text/plain',
36
  content => "file contents\n1111\n", description => "File #1 sample description");
37
$mf_a_123->AddFile(name => 'File_name_2.txt', type => 'text/plain',
38
  content => "file contents\n2222\n", description => "File #2 sample description");
39
$mf_a_124->AddFile(name => 'File_name_3.txt', content => "file contents\n3333\n", type => 'text/whatever');
40
$mf_a_124->AddFile(name => 'File_name_4.txt', content => "file contents\n4444\n");
41
$mf_b_221->AddFile(name => 'File_name_5.txt', content => "file contents\n5555\n");
42
43
## check GetFilesInfo() results for added files
44
my $files_a_123_infos = $mf_a_123->GetFilesInfo();
45
is(scalar @$files_a_123_infos, 2, "GetFilesInfo() result count/1");
46
is(scalar @{$mf_b_221->GetFilesInfo()}, 1, "GetFilesInfo() result count/2");
47
is(ref($files_a_123_infos->[0]), 'HASH', "GetFilesInfo() item file result type");
48
is($files_a_123_infos->[0]->{file_name}, 'File_name_1.txt', "GetFilesInfo() result check/1");
49
is($files_a_123_infos->[1]->{file_name}, 'File_name_2.txt', "GetFilesInfo() result check/2");
50
is($files_a_123_infos->[1]->{file_type}, 'text/plain', "GetFilesInfo() result check/3");
51
is($files_a_123_infos->[1]->{file_size}, 19, "GetFilesInfo() result check/4");
52
is($files_a_123_infos->[1]->{file_description}, 'File #2 sample description', "GetFilesInfo() result check/5");
53
54
## GetFile() result checks
55
is($mf_a_123->GetFile(), undef, "GetFile() result check/1");
56
is($mf_a_123->GetFile(id => 0), undef, "GetFile() result check/2");
57
58
my $a123_file_1 = $mf_a_123->GetFile(id => $files_a_123_infos->[0]->{file_id});
59
is(ref($a123_file_1), 'HASH', "GetFile() result check/3");
60
is($a123_file_1->{file_id}, $files_a_123_infos->[0]->{file_id}, "GetFile() result check/4");
61
is($a123_file_1->{file_content}, "file contents\n1111\n", "GetFile() result check/5");
62
63
## MergeFileRecIds() tests
64
$mf_a_123->MergeFileRecIds(123,221);
65
$files_a_123_infos = $mf_a_123->GetFilesInfo();
66
is(scalar @$files_a_123_infos, 2, "GetFilesInfo() result count after dummy MergeFileRecIds()");
67
$mf_a_123->MergeFileRecIds(124);
68
$files_a_123_infos = $mf_a_123->GetFilesInfo();
69
is(scalar @$files_a_123_infos, 4, "GetFilesInfo() result count after MergeFileRecIds()/1");
70
is(scalar @{$mf_a_124->GetFilesInfo()}, 0, "GetFilesInfo() result count after MergeFileRecIds()/2");
71
is($files_a_123_infos->[-1]->{file_name}, 'File_name_4.txt', "GetFilesInfo() result check after MergeFileRecIds()");
72
73
## DelFile() test
74
$mf_a_123->DelFile(id => $files_a_123_infos->[-1]->{file_id});
75
$files_a_123_infos = $mf_a_123->GetFilesInfo();
76
is(scalar @$files_a_123_infos, 3, "GetFilesInfo() result count after DelFile()");
77
78
## DelAllFiles() tests
79
$mf_a_123->DelAllFiles();
80
$files_a_123_infos = $mf_a_123->GetFilesInfo();
81
is(scalar @$files_a_123_infos, 0, "GetFilesInfo() result count after DelAllFiles()/1");
82
$mf_b_221->DelAllFiles();
83
is(scalar @{$mf_b_221->GetFilesInfo()}, 0, "GetFilesInfo() result count after DelAllFiles()/2");
84
85
$dbh->rollback;
86
87
1;

Return to bug 3050