]> wagnertech.de Git - mfinanz.git/blob - SL/DB/Manager/Chart.pm
Merge branch 'master' of http://wagnertech.de/git/mfinanz
[mfinanz.git] / SL / DB / Manager / Chart.pm
1 package SL::DB::Manager::Chart;
2
3 use strict;
4
5 use SL::DB::Helper::Manager;
6 use base qw(SL::DB::Helper::Manager);
7
8 use SL::DB::Helper::Sorted;
9 use SL::DB::Helper::Paginated;
10 use SL::DB::Helper::Filtered;
11 use SL::MoreCommon qw(listify);
12 use SL::DBUtils;
13
14 use Carp;
15 use DateTime;
16 use Data::Dumper;
17
18 sub object_class { 'SL::DB::Chart' }
19
20 __PACKAGE__->make_manager_methods;
21
22 __PACKAGE__->add_filter_specs(
23   type => sub {
24     my ($key, $value) = @_;
25     return __PACKAGE__->type_filter($value);
26   },
27   category => sub {
28     my ($key, $value) = @_;
29     return __PACKAGE__->category_filter($value);
30   },
31   selected_category => sub {
32     my ($key, $value) = @_;
33     return __PACKAGE__->selected_category_filter($value);
34   },
35   all => sub {
36     my ($key, $value) = @_;
37     return or => [ map { $_ => $value } qw(accno description) ]
38   },
39   booked => sub {
40     my ($key, $value) = @_;
41     return __PACKAGE__->booked_filter($value);
42   },
43   status => sub {
44     my ($key, $value) = @_;
45     return __PACKAGE__->invalid_filter($value);
46   },
47
48 );
49 sub invalid_filter {
50   my ($class, $status) = @_;
51
52   croak "Wrong call, need status invalid, all or valid, got:" . $status unless $status =~ m/invalid|all|valid/;
53
54   my @filter;
55
56   if ($status eq 'all') {
57      push @filter, ( id => [ \"SELECT id FROM chart" ] );
58   } elsif ($status eq 'valid') {
59      push @filter, ( id => [ \"SELECT id FROM chart WHERE NOT invalid" ] );
60   } elsif ($status eq 'invalid') {
61      push @filter, ( id => [ \"SELECT id FROM chart WHERE invalid" ] );
62   } else { die "Wrong state for invalid_filter"; }
63
64   return @filter;
65 }
66
67
68 sub booked_filter {
69   my ($class, $booked) = @_;
70
71   $booked //= 0;
72   my @filter;
73
74   if ( $booked ) {
75      push @filter, ( id => [ \"SELECT distinct chart_id FROM acc_trans" ] );
76   };
77
78   return @filter;
79 }
80
81 sub selected_category_filter {
82   my ($class, $selected_categories) = @_;
83
84   my @selected_categories = @$selected_categories;
85
86   # if no category is selected, there is no filter and thus all charts of all
87   # categories are displayed, which is what we want.
88
89   return (category => \@$selected_categories);
90 }
91
92 sub type_filter {
93   my ($class, $type) = @_;
94
95   # filter by link or several defined custom types
96   # special types:
97   # bank, guv, balance
98
99   return () unless $type;
100
101   if ('HASH' eq ref $type) {
102     # this is to make selection like type => { AR_paid => 1, AP_paid => 1 } work
103     $type = [ grep { $type->{$_} } keys %$type ];
104   }
105
106   my @types = grep { $_ } listify($type);
107   my @filter;
108
109   for my $type (@types) {
110     if ( $type eq 'bank' ) {
111      push @filter, ( id => [ \"SELECT chart_id FROM bank_accounts" ] );
112     } elsif ( $type eq 'guv' ) {
113      push @filter, ( category => [ 'I', 'E' ] );
114     } elsif ( $type eq 'balance' ) {
115      push @filter, ( category => [ 'A', 'Q', 'L' ] );
116     } else {
117       push @filter, $class->link_filter($type);
118     };
119   };
120
121   return @filter > 2 ? (or => \@filter) : @filter;
122 }
123
124 sub category_filter {
125   my ($class, $category) = @_;
126
127   return () unless $category;
128
129   # filter for chart_picker if a category filter was passed via params
130
131   if ( ref $category eq 'HASH' ) {
132     # this is to make a selection like category => { I => 1, E => 1 } work
133     $category = [ grep { $category->{$_} } keys %$category ];
134   }
135
136   my @categories = grep { $_ } listify($category);
137
138   return (category => \@categories);
139 }
140
141 sub link_filter {
142   my ($class, $link) = @_;
143
144   return (or => [ link => $link,
145                   link => { like => "${link}:\%"    },
146                   link => { like => "\%:${link}"    },
147                   link => { like => "\%:${link}:\%" } ]);
148 }
149
150 sub cache_taxkeys {
151   my ($self, %params) = @_;
152
153   my $date  = $params{date} || DateTime->today;
154   my $cache = $::request->cache('::SL::DB::Chart::get_active_taxkey')->{$date} //= {};
155
156   require SL::DB::TaxKey;
157   my $tks = SL::DB::Manager::TaxKey->get_all;
158   my %tks_by_id = map { $_->id => $_ } @$tks;
159
160   my $rows = selectall_hashref_query($::form, $::form->get_standard_dbh, <<"", $date);
161     SELECT DISTINCT ON (chart_id) chart_id, startdate, id
162     FROM taxkeys
163     WHERE startdate <= ?
164     ORDER BY chart_id, startdate DESC;
165
166   for (@$rows) {
167     $cache->{$_->{chart_id}} = $tks_by_id{$_->{id}};
168   }
169 }
170
171 sub _sort_spec {
172   (
173     default  => [ 'accno', 1 ],
174     # columns  => {
175     #   SIMPLE => 'ALL',
176     # },
177     nulls    => {},
178   );
179 }
180
181 1;
182
183 __END__
184
185 =pod
186
187 =encoding utf8
188
189 =head1 NAME
190
191 SL::DB::Manager::Chart - Manager class for the model for the C<chart> table
192
193 =head1 FUNCTIONS
194
195 =over 4
196
197 =item C<link_filter $link>
198
199 Returns a query builder filter that matches charts whose 'C<link>'
200 field contains C<$link>. Matching is done so that the exact value of
201 C<$link> matches but not if C<$link> is only a substring of a
202 match. Therefore C<$link = 'AR'> will match the column content 'C<AR>'
203 or 'C<AR_paid:AR>' but not 'C<AR_amount>'.
204
205 =back
206
207 =head1 BUGS
208
209 Nothing here yet.
210
211 =head1 AUTHOR
212
213 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
214
215 G. Richardson E<lt>information@kivitendo-premium.deE<gt>
216
217 =cut