1 package SL::Controller::Invoice;
5 use parent qw(SL::Controller::Base);
8 use Params::Validate qw(:all);
16 use SL::Locale::String qw(t8);
17 use SL::MoreCommon qw(listify);
19 __PACKAGE__->run_before('check_auth');
22 my ($self) = validate_pos(@_, { isa => 'SL::Controller::Invoice' }, 1);
24 return 1 if $::auth->assert('ar_transactions', 1); # may edit all invoices
25 my @ids = listify($::form->{id});
26 $::auth->assert() unless has_rights_through_projects(\@ids);
30 sub has_rights_through_projects {
31 my ($ids) = validate_pos(@_, {
34 return 0 unless scalar @{$ids}; # creating new invoices isn't allowed without invoice_edit
35 my $current_employee = SL::DB::Manager::Employee->current;
36 my $id_placeholder = join(', ', ('?') x @{$ids});
37 # Count of ids where the use has no access to
39 SELECT count(id) FROM ar
41 SELECT * from employee_project_invoices WHERE project_id = ar.globalproject_id and employee_id = ?
42 ) AND id IN ($id_placeholder)
44 my ($no_access_count) = SL::DB->client->dbh->selectrow_array($query, undef, $current_employee->id, @{$ids});
45 return !$no_access_count;
48 sub action_webdav_pdf_export {
50 my $ids = $::form->{id};
52 my $invoices = SL::DB::Manager::Invoice->get_all(where => [ id => $ids ]);
54 my @file_names_and_file_paths;
56 foreach my $invoice (@{$invoices}) {
57 my $record_type = $invoice->record_type;
58 $record_type = 'invoice' if $record_type eq 'ar_transaction';
59 $record_type = 'invoice' if $record_type eq 'invoice_storno';
60 my $webdav = SL::Webdav->new(
62 number => $invoice->record_number,
64 my @latest_object = $webdav->get_all_latest();
65 unless (scalar @latest_object) {
67 "No Dokument found for record '#1'. Please deselect it or create a document it.",
68 $invoice->displayable_name()
72 push @file_names_and_file_paths, {
73 file_name => $latest_object[0]->basename . "." . $latest_object[0]->extension,
74 file_path => $latest_object[0]->full_filedescriptor(),
79 die join("\n", @errors);
81 $self->_create_and_send_zip(\@file_names_and_file_paths);
84 sub action_files_pdf_export {
87 my $ids = $::form->{id};
89 my $invoices = SL::DB::Manager::Invoice->get_all(where => [ id => $ids ]);
91 my @file_names_and_file_paths;
93 foreach my $invoice (@{$invoices}) {
94 my $record_type = $invoice->record_type;
95 $record_type = 'invoice' if $record_type eq 'ar_transaction';
96 $record_type = 'invoice' if $record_type eq 'invoice_storno';
97 my @file_objects = SL::File->get_all(
98 object_type => $record_type,
99 object_id => $invoice->id,
100 file_type => 'document',
104 unless (scalar @file_objects) {
106 "No Dokument found for record '#1'. Please deselect it or create a document it.",
107 $invoice->displayable_name()
111 foreach my $file_object (@file_objects) {
113 push @file_names_and_file_paths, {
114 file_name => $file_object->file_name,
115 file_path => $file_object->get_file(),
123 if (scalar @errors) {
124 die join("\n", @errors);
126 $self->_create_and_send_zip(\@file_names_and_file_paths);
129 sub _create_and_send_zip {
130 my ($self, $file_names_and_file_paths) = validate_pos(@_,
131 { isa => 'SL::Controller::Invoice' },
135 "has 'file_name' and 'file_path'" => sub {
136 foreach my $file_entry (@{$_[0]}) {
137 return 0 unless defined $file_entry->{file_name}
138 && defined $file_entry->{file_path};
145 my ($fh, $zipfile) = File::Temp::tempfile();
146 my $zip = Archive::Zip->new();
147 foreach my $file (@{$file_names_and_file_paths}) {
148 $zip->addFile($file->{file_path}, $file->{file_name});
150 $zip->writeToFileHandle($fh) == Archive::Zip::AZ_OK() or die 'error writing zip file';
155 name => t8('pdf_records.zip'), unlink => 1,
156 type => 'application/zip',