Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 88bf1c88

Von Tamino Steinert vor 10 Monaten hinzugefügt

  • ID 88bf1c88d8953c6c8d709d8f0b48169a1fa0d423
  • Vorgänger 972b0c67
  • Nachfolger f00a8e2b

FIX: Verschiebe PDF-Export für VK-Rechnungen in neuen Controller ...

Rechteprüfung überarbeitet
Behebt #634 (redmine)

Unterschiede anzeigen:

SL/Controller/Invoice.pm
1
package SL::Controller::Invoice;
2

  
3
use strict;
4

  
5
use parent qw(SL::Controller::Base);
6

  
7
use Archive::Zip;
8
use Params::Validate qw(:all);
9

  
10
use SL::DB::File;
11
use SL::DB::Invoice;
12
use SL::DB::Employee;
13

  
14
use SL::Webdav;
15
use SL::File;
16
use SL::Locale::String qw(t8);
17
use SL::MoreCommon qw(listify);
18

  
19
__PACKAGE__->run_before('check_auth');
20

  
21
sub check_auth {
22
  my ($self) = validate_pos(@_, { isa => 'SL::Controller::Invoice' }, 1);
23

  
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);
27
  return 1;
28
}
29

  
30
sub has_rights_through_projects {
31
  my ($ids) = validate_pos(@_, {
32
    type => ARRAYREF,
33
  });
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
38
  my $query = <<SQL;
39
  SELECT count(id) FROM ar
40
  WHERE NOT EXISTS (
41
    SELECT * from employee_project_invoices WHERE project_id = ar.globalproject_id and employee_id = ?
42
  ) AND id IN ($id_placeholder)
43
SQL
44
  my ($no_access_count) = SL::DB->client->dbh->selectrow_array($query, undef, $current_employee->id, @{$ids});
45
  return !$no_access_count;
46
}
47

  
48
sub action_webdav_pdf_export {
49
  my ($self) = @_;
50
  my $ids  = $::form->{id};
51

  
52
  my $invoices = SL::DB::Manager::Invoice->get_all(where => [ id => $ids ]);
53

  
54
  my @file_names_and_file_paths;
55
  my @errors;
56
  foreach my $invoice (@{$invoices}) {
57
    my $record_type = $invoice->record_type;
58
    $record_type = 'general_ledger' if $record_type eq 'ar_transaction';
59
    $record_type = 'invoice'        if $record_type eq 'invoice_storno';
60
    my $webdav = SL::Webdav->new(
61
      type     => $record_type,
62
      number   => $invoice->record_number,
63
    );
64
    my @latest_object = $webdav->get_all_latest();
65
    unless (scalar @latest_object) {
66
      push @errors, t8(
67
        "No Dokument found for record '#1'. Please deselect it or create a document it.",
68
        $invoice->displayable_name()
69
      );
70
      next;
71
    }
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(),
75
    }
76
  }
77

  
78
  if (scalar @errors) {
79
    die join("\n", @errors);
80
  }
81
  $self->_create_and_send_zip(\@file_names_and_file_paths);
82
}
83

  
84
sub action_files_pdf_export {
85
  my ($self) = @_;
86

  
87
  my $ids  = $::form->{id};
88

  
89
  my $invoices = SL::DB::Manager::Invoice->get_all(where => [ id => $ids ]);
90

  
91
  my @file_names_and_file_paths;
92
  my @errors;
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',
101
      source      => 'created',
102
    );
103

  
104
    unless (scalar @file_objects) {
105
      push @errors, t8(
106
        "No Dokument found for record '#1'. Please deselect it or create a document it.",
107
        $invoice->displayable_name()
108
      );
109
      next;
110
    }
111
    foreach my $file_object (@file_objects) {
112
      eval {
113
        push @file_names_and_file_paths, {
114
          file_name => $file_object->file_name,
115
          file_path => $file_object->get_file(),
116
        };
117
      } or do {
118
        push @errors, $@,
119
      };
120
    }
121
  }
122

  
123
  if (scalar @errors) {
124
    die join("\n", @errors);
125
  }
126
  $self->_create_and_send_zip(\@file_names_and_file_paths);
127
}
128

  
129
sub _create_and_send_zip {
130
  my ($self, $file_names_and_file_paths) = validate_pos(@_,
131
    { isa => 'SL::Controller::Invoice' },
132
    {
133
      type => ARRAYREF,
134
      callbacks => {
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};
139
          }
140
          return 1;
141
        }
142
      }
143
    });
144

  
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});
149
  }
150
  $zip->writeToFileHandle($fh) == Archive::Zip::AZ_OK() or die 'error writing zip file';
151
  close($fh);
152

  
153
  $self->send_file(
154
    $zipfile,
155
    name => t8('pdf_records.zip'), unlink => 1,
156
    type => 'application/zip',
157
  );
158
}
159

  
160
1;
bin/mozilla/ar.pl
35 35
use POSIX qw(strftime);
36 36
use List::Util qw(sum first max);
37 37
use List::UtilsBy qw(sort_by);
38
use Archive::Zip;
39
use Params::Validate qw(:all);
40 38

  
41 39
use SL::AR;
42 40
use SL::Controller::Base;
......
49 47
use SL::DB::Currency;
50 48
use SL::DB::Default;
51 49
use SL::DB::Employee;
52
use SL::DB::Invoice;
53 50
use SL::DB::Manager::Invoice;
54 51
use SL::DB::InvoiceItem;
55 52
use SL::DB::RecordTemplate;
......
62 59
use SL::Presenter::Chart;
63 60
use SL::Presenter::ItemsList;
64 61
use SL::ReportGenerator;
65
use SL::File::Object;
66
use SL::DB::Manager::File;
67
use SL::File::Backend::Filesystem;
68
use SL::Webdav;
69
use SL::File::Backend::Webdav;
70 62

  
71 63
require "bin/mozilla/common.pl";
72 64
require "bin/mozilla/reportgenerator.pl";
......
1032 1024
        action => [ $::locale->text('PDF-Export') ],
1033 1025
        action => [
1034 1026
          t8('WebDAV'),
1035
          submit   => [ '#report_form', { action => 'webdav_pdf_export' } ],
1027
          submit   => [ '#report_form', { action => 'Invoice/webdav_pdf_export' } ],
1036 1028
          checks   => [ ['kivi.check_if_entries_selected', '[name="id[]"]'] ],
1037 1029
          disabled => !$webdav_enabled ? t8('WebDAV is not enabled.')
1038 1030
                                       : undef,
1039 1031
        ],
1040 1032
        action => [
1041 1033
          t8('Documents'),
1042
          submit   => [ '#report_form', { action => 'files_pdf_export' } ],
1034
          submit   => [ '#report_form', { action => 'Invoice/files_pdf_export' } ],
1043 1035
          checks   => [ ['kivi.check_if_entries_selected', '[name="id[]"]'] ],
1044 1036
          disabled => !$files_enabled ? t8('No File Management enabled.')
1045 1037
                                      : undef,
......
1656 1648
  $::request->layout->add_javascripts('kivi.Validator.js');
1657 1649
}
1658 1650

  
1659
sub _check_access_right_for_ids {
1660
  my ($ids) = @_;
1661
  $main::lxdebug->enter_sub();
1662

  
1663
  my $form = Form->new;
1664
  AR->ar_transactions(\%::myconfig, \%$form);
1665
  my %allowed_ids = ();
1666

  
1667
  my @allowed_ar_ids = map {$_->{id}} @{$form->{AR}};
1668
  foreach my $ar_id (@allowed_ar_ids) {
1669
    $allowed_ids{$ar_id} = 1 ;
1670
  }
1671
  foreach my $id (@$ids) {
1672
    unless ($allowed_ids{$id}) {
1673
      $::auth->deny_access();
1674
    }
1675
  }
1676

  
1677
  $main::lxdebug->leave_sub();
1678
}
1679

  
1680
sub webdav_pdf_export {
1681
  $main::lxdebug->enter_sub();
1682

  
1683
  my $form = $main::form;
1684
  my $ids  = $form->{id};
1685

  
1686
  _check_access_right_for_ids($ids);
1687

  
1688
  my $invoices = SL::DB::Manager::Invoice->get_all(where => [ id => $ids ]);
1689

  
1690
  my @file_names_and_file_paths;
1691
  my @errors;
1692
  foreach my $invoice (@{$invoices}) {
1693
    my $record_type = $invoice->record_type;
1694
    $record_type = 'general_ledger' if $record_type eq 'ar_transaction';
1695
    $record_type = 'invoice'        if $record_type eq 'invoice_storno';
1696
    my $webdav = SL::Webdav->new(
1697
      type     => $record_type,
1698
      number   => $invoice->record_number,
1699
    );
1700
    my @latest_object = $webdav->get_all_latest();
1701
    unless (scalar @latest_object) {
1702
      push @errors, t8(
1703
        "No Dokument found for record '#1'. Please deselect it or create a document it.",
1704
        $invoice->displayable_name()
1705
      );
1706
      next;
1707
    }
1708
    push @file_names_and_file_paths, {
1709
      file_name => $latest_object[0]->basename . "." . $latest_object[0]->extension,
1710
      file_path => $latest_object[0]->full_filedescriptor(),
1711
    }
1712
  }
1713

  
1714
  if (scalar @errors) {
1715
    die join("\n", @errors);
1716
  }
1717
  _create_and_send_zip(\@file_names_and_file_paths);
1718

  
1719
  $main::lxdebug->leave_sub();
1720
}
1721

  
1722
sub files_pdf_export {
1723
  $main::lxdebug->enter_sub();
1724

  
1725
  my $form = $main::form;
1726
  my $ids  = $form->{id};
1727

  
1728
  _check_access_right_for_ids($ids);
1729

  
1730
  my $invoices = SL::DB::Manager::Invoice->get_all(where => [ id => $ids ]);
1731

  
1732
  my @file_names_and_file_paths;
1733
  my @errors;
1734
  foreach my $invoice (@{$invoices}) {
1735
    my $record_type = $invoice->record_type;
1736
    $record_type = 'invoice' if $record_type eq 'ar_transaction';
1737
    $record_type = 'invoice' if $record_type eq 'invoice_storno';
1738
    my @file_entries = @{SL::DB::Manager::File->get_all(
1739
      where => [
1740
        object_type => $record_type,
1741
        object_id   => $invoice->id,
1742
        file_type   => 'document',
1743
        source      => 'created',
1744
      ],
1745
    )};
1746

  
1747
    unless (scalar @file_entries) {
1748
      push @errors, t8(
1749
        "No Dokument found for record '#1'. Please deselect it or create a document it.",
1750
        $invoice->displayable_name()
1751
      );
1752
      next;
1753
    }
1754
    foreach my $file_entry (@file_entries) {
1755
      my $file = SL::File::Object->new(
1756
        db_file => $file_entry,
1757
        id => $file_entry->id,
1758
        loaded => 1,
1759
      );
1760
      eval {
1761
        push @file_names_and_file_paths, {
1762
          file_name => $file->file_name,
1763
          file_path => $file->get_file(),
1764
        };
1765
      } or do {
1766
        push @errors, $@,
1767
      };
1768
    }
1769
  }
1770

  
1771
  if (scalar @errors) {
1772
    die join("\n", @errors);
1773
  }
1774
  _create_and_send_zip(\@file_names_and_file_paths);
1775

  
1776
  $main::lxdebug->leave_sub();
1777
}
1778

  
1779
sub _create_and_send_zip {
1780
  $main::lxdebug->enter_sub();
1781
  my ($file_names_and_file_paths) = validate_pos(@_, {
1782
      type => ARRAYREF,
1783
      callbacks => {
1784
        "has 'file_name' and 'file_path'" => sub {
1785
          foreach my $file_entry (@{$_[0]}) {
1786
            return 0 unless defined $file_entry->{file_name}
1787
                         && defined $file_entry->{file_path};
1788
          }
1789
          return 1;
1790
        }
1791
      }
1792
    });
1793

  
1794
  my ($fh, $zipfile) = File::Temp::tempfile();
1795
  my $zip = Archive::Zip->new();
1796
  foreach my $file (@{$file_names_and_file_paths}) {
1797
    $zip->addFile($file->{file_path}, $file->{file_name});
1798
  }
1799
  $zip->writeToFileHandle($fh) == Archive::Zip::AZ_OK() or die 'error writing zip file';
1800
  close($fh);
1801

  
1802
  my $controller = SL::Controller::Base->new;
1803

  
1804
  $controller->send_file(
1805
    $zipfile,
1806
    name => t8('pdf_records.zip'), unlink => 1,
1807
    type => 'application/zip',
1808
  );
1809

  
1810
  $main::lxdebug->leave_sub();
1811
}
1812

  
1813

  
1814 1651
1;
templates/design40_webpages/ar/ar_transactions_header.html
1
<form method="post" action="ar.pl" id="report_form">
1
<form method="post" action="controller.pl" id="report_form">
templates/webpages/ar/ar_transactions_header.html
1
<form method="post" action="ar.pl" id="report_form">
1
<form method="post" action="controller.pl" id="report_form">

Auch abrufbar als: Unified diff