Listenpreis in Belegen u. Ausdruck richtig formatieren und nicht mehr parsen.
[kivitendo-erp.git] / SL / FU.pm
1 # Follow-Ups
2
3 package FU;
4
5 use List::Util qw(first);
6
7 use SL::Common;
8 use SL::DBUtils;
9 use SL::Notes;
10
11 use strict;
12
13 sub save {
14   $main::lxdebug->enter_sub();
15
16   my $self     = shift;
17   my %params   = @_;
18
19   my $myconfig = \%main::myconfig;
20   my $form     = $main::form;
21
22   my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
23   my ($query, @values);
24
25   if (!$params{id}) {
26     ($params{id}) = selectrow_query($form, $dbh, qq|SELECT nextval('follow_up_id')|);
27
28     $query = qq|INSERT INTO follow_ups (created_by, done, note_id, follow_up_date, created_for_user, id)
29                 VALUES ((SELECT id FROM employee WHERE login = ?), ?, ?, ?, ?, ?)|;
30
31     push @values, $::myconfig{login};
32
33   } else {
34     $query = qq|UPDATE follow_ups SET done = ?, note_id = ?, follow_up_date = ?, created_for_user = ? WHERE id = ?|;
35   }
36
37   $params{note_id} = Notes->save('id'           => $params{note_id},
38                                  'trans_id'     => $params{id},
39                                  'trans_module' => 'fu',
40                                  'subject'      => $params{subject},
41                                  'body'         => $params{body},
42                                  'dbh'          => $dbh,);
43
44   $params{done} = 1 if (!defined $params{done});
45
46   do_query($form, $dbh, $query, @values, $params{done} ? 't' : 'f', conv_i($params{note_id}), $params{follow_up_date}, conv_i($params{created_for_user}), conv_i($params{id}));
47
48   do_query($form, $dbh, qq|DELETE FROM follow_up_links WHERE follow_up_id = ?|, conv_i($params{id}));
49
50   $query = qq|INSERT INTO follow_up_links (follow_up_id, trans_id, trans_type, trans_info) VALUES (?, ?, ?, ?)|;
51   my $sth   = prepare_query($form, $dbh, $query);
52
53   foreach my $link (@{ $params{LINKS} }) {
54     do_statement($form, $sth, $query, conv_i($params{id}), conv_i($link->{trans_id}), $link->{trans_type}, $link->{trans_info});
55   }
56
57   $sth->finish();
58
59   $dbh->commit() unless ($params{dbh});
60
61   $main::lxdebug->leave_sub();
62 }
63
64 sub finish {
65   $main::lxdebug->enter_sub();
66
67   my $self     = shift;
68   my %params   = @_;
69
70   Common::check_params(\%params, 'id');
71
72   my $myconfig = \%main::myconfig;
73   my $form     = $main::form;
74
75   my $dbh      = $form->get_standard_dbh($myconfig);
76
77   do_query($form, $dbh, qq|UPDATE follow_ups SET done = TRUE WHERE id = ?|, conv_i($params{id}));
78
79   $dbh->commit();
80
81   $main::lxdebug->leave_sub();
82 }
83
84 sub delete {
85   $main::lxdebug->enter_sub();
86
87   my $self     = shift;
88   my %params   = @_;
89
90   Common::check_params(\%params, 'id');
91
92   my $myconfig = \%main::myconfig;
93   my $form     = $main::form;
94
95   my $dbh      = $form->get_standard_dbh($myconfig);
96
97   my $id       = conv_i($params{id});
98
99   do_query($form, $dbh, qq|DELETE FROM follow_up_links WHERE follow_up_id = ?|,                         $id);
100   do_query($form, $dbh, qq|DELETE FROM follow_ups      WHERE id = ?|,                                   $id);
101   do_query($form, $dbh, qq|DELETE FROM notes           WHERE (trans_id = ?) AND (trans_module = 'fu')|, $id);
102
103   $dbh->commit();
104
105   $main::lxdebug->leave_sub();
106 }
107
108 sub retrieve {
109   $main::lxdebug->enter_sub();
110
111   my $self     = shift;
112   my %params   = @_;
113
114   Common::check_params(\%params, 'id');
115
116   my $myconfig = \%main::myconfig;
117   my $form     = $main::form;
118
119   my $dbh      = $form->get_standard_dbh($myconfig);
120   my ($query, @values);
121
122   my ($employee_id) = selectrow_query($form, $dbh, qq|SELECT id FROM employee WHERE login = ?|, $::myconfig{login});
123   $query            = qq|SELECT fu.*, n.subject, n.body, n.created_by
124                          FROM follow_ups fu
125                          LEFT JOIN notes n ON (fu.note_id = n.id)
126                          WHERE (fu.id = ?)
127                            AND (   (fu.created_by = ?) OR (fu.created_for_user = ?)
128                                 OR (fu.created_by IN (SELECT DISTINCT what FROM follow_up_access WHERE who = ?)))|;
129   my $ref           = selectfirst_hashref_query($form, $dbh, $query, conv_i($params{id}), $employee_id, $employee_id, $employee_id);
130
131   if (!$ref) {
132     $main::lxdebug->leave_sub();
133     return undef;
134   }
135
136   $ref->{LINKS} = $self->retrieve_links(%{ $ref });
137
138   $main::lxdebug->leave_sub();
139
140   return $ref;
141 }
142
143 sub retrieve_links {
144   $main::lxdebug->enter_sub();
145
146   my $self     = shift;
147   my %params   = @_;
148
149   Common::check_params(\%params, qw(id));
150
151   my $myconfig = \%main::myconfig;
152   my $form     = $main::form;
153
154   my $dbh      = $form->get_standard_dbh($myconfig);
155
156   my $query    = qq|SELECT ful.trans_id, ful.trans_type, ful.trans_info, fu.note_id
157                     FROM follow_up_links ful
158                     LEFT JOIN follow_ups fu ON (ful.follow_up_id = fu.id)
159                     WHERE ful.follow_up_id = ?
160                     ORDER BY ful.itime|;
161
162   my $links    = selectall_hashref_query($form, $dbh, $query, conv_i($params{id}));
163
164   foreach my $link_ref (@{ $links }) {
165     my $link_details = FU->link_details(%{ $link_ref });
166     map { $link_ref->{$_} = $link_details->{$_} } keys %{ $link_details} if ($link_details);
167   }
168
169   $main::lxdebug->leave_sub();
170
171   return $links;
172 }
173
174 sub follow_ups {
175   $main::lxdebug->enter_sub();
176
177   my $self     = shift;
178   my %params   = @_;
179
180   my $myconfig = \%main::myconfig;
181   my $form     = $main::form;
182
183   my $dbh      = $form->get_standard_dbh($myconfig);
184   my ($query, $where, $where_user);
185
186   my ($employee_id) = selectrow_query($form, $dbh, qq|SELECT id FROM employee WHERE login = ?|, $::myconfig{login});
187   my @values        = ();
188   my @values_user   = ();
189
190   if ($params{trans_id}) {
191     $where .= qq| AND EXISTS (SELECT * FROM follow_up_links ful
192                               WHERE (ful.follow_up_id = fu.id) AND (ful.trans_id = ?))|;
193     push @values, conv_i($params{trans_id});
194   }
195
196   if ($params{due_only}) {
197     $where .= qq| AND (fu.follow_up_date <= current_date)|;
198   }
199
200   if ($params{done} ne $params{not_done}) {
201     my $not  = $params{not_done} ? 'NOT' : '';
202     $where  .= qq| AND $not COALESCE(fu.done, FALSE)|;
203   }
204
205   if ($params{not_id}) {
206     $where .= qq| AND (fu.id <> ?)|;
207     push @values, conv_i($params{not_id});
208   }
209
210   foreach my $item (qw(subject body)) {
211     next unless ($params{$item});
212     $where .= qq| AND (n.${item} ILIKE ?)|;
213     push @values, '%' . $params{$item} . '%';
214   }
215
216   if ($params{reference}) {
217     $where .= qq| AND EXISTS (SELECT ful.follow_up_id
218                               FROM follow_up_links ful
219                               WHERE (ful.follow_up_id = fu.id)
220                                 AND (ful.trans_info ILIKE ?)
221                               LIMIT 1)|;
222     push @values, '%' . $params{reference} . '%';
223   }
224
225   if ($params{follow_up_date_from}) {
226     $where .= qq| AND (fu.follow_up_date >= ?)|;
227     push @values, conv_date($params{follow_up_date_from});
228   }
229   if ($params{follow_up_date_to}) {
230     $where .= qq| AND (fu.follow_up_date <= ?)|;
231     push @values, conv_date($params{follow_up_date_to});
232   }
233
234   if ($params{itime_from}) {
235     $where .= qq| AND (date_trunc('DAY', fu.itime) >= ?)|;
236     push @values, conv_date($params{itime_from});
237   }
238   if ($params{itime_to}) {
239     $where .= qq| AND (date_trunc('DAY', fu.itime) <= ?)|;
240     push @values, conv_date($params{itime_to});
241   }
242
243   if ($params{all_users}) {
244     $where_user = qq|OR (fu.created_by IN (SELECT DISTINCT what FROM follow_up_access WHERE who = ?))|;
245     push @values_user, $employee_id;
246   }
247
248   my $order_by = '';
249
250   if ($form->{sort} ne 'title') {
251     my %sort_columns = (
252       'follow_up_date' => [ qw(fu.follow_up_date fu.id) ],
253       'created_on'     => [ qw(created_on fu.id) ],
254       'subject'        => [ qw(lower(n.subject)) ],
255       );
256
257     my $sortdir = !defined $form->{sortdir} ? 'ASC' : $form->{sortdir} ? 'ASC' : 'DESC';
258     my $sortkey = $sort_columns{$form->{sort}} ? $form->{sort} : 'follow_up_date';
259     $order_by   = 'ORDER BY ' . join(', ', map { "$_ $sortdir" } @{ $sort_columns{$sortkey} });
260   }
261
262   $query  = qq|SELECT fu.*, n.subject, n.body, n.created_by,
263                  fu.follow_up_date <= current_date AS due,
264                  fu.itime::DATE                    AS created_on,
265                  COALESCE(eby.name,  eby.login)    AS created_by_name,
266                  COALESCE(efor.name, efor.login)   AS created_for_user_name
267                FROM follow_ups fu
268                LEFT JOIN notes    n    ON (fu.note_id          = n.id)
269                LEFT JOIN employee eby  ON (n.created_by        = eby.id)
270                LEFT JOIN employee efor ON (fu.created_for_user = efor.id)
271                WHERE ((fu.created_by = ?) OR (fu.created_for_user = ?)
272                       $where_user)
273                  $where
274                $order_by|;
275
276   my $follow_ups = selectall_hashref_query($form, $dbh, $query, $employee_id, $employee_id, @values_user, @values);
277
278   if (!scalar @{ $follow_ups }) {
279     $main::lxdebug->leave_sub();
280     return $follow_ups;
281   }
282
283   foreach my $fu (@{ $follow_ups }) {
284     $fu->{LINKS} = $self->retrieve_links(%{ $fu });
285   }
286
287   if ($form->{sort} eq 'title') {
288     my $dir_factor = !defined $form->{sortdir} ? 1 : $form->{sortdir} ? 1 : -1;
289     $follow_ups    = [ map  { $_->[1] }
290                        sort { ($a->[0] cmp $b->[0]) * $dir_factor }
291                        map  { my $fu = $follow_ups->[$_]; [ @{ $fu->{LINKS} } ? lc($fu->{LINKS}->[0]->{title}) : '', $fu ] }
292                        (0 .. scalar(@{ $follow_ups }) - 1) ];
293   }
294
295   $main::lxdebug->leave_sub();
296
297   return $follow_ups;
298 }
299
300 sub link_details {
301   $main::lxdebug->enter_sub();
302
303   my $self     = shift;
304   my %params   = @_;
305
306   Common::check_params(\%params, qw(trans_id trans_type));
307
308   my $myconfig = \%main::myconfig;
309   my $form     = $main::form;
310   my $locale   = $main::locale;
311
312   my $q_id     = $form->quote($params{trans_id});
313   my $link;
314
315   if ($params{trans_type} eq 'customer') {
316     $link = {
317       'url'   => 'controller.pl?action=CustomerVendor/edit&db=customer&id=' . $form->quote($params{trans_id}) . '&note_id=' . $form->quote($params{note_id}),
318       'title' => $locale->text('Customer') . " '$params{trans_info}'",
319     };
320
321   } elsif ($params{trans_type} eq 'vendor') {
322     $link = {
323       'url'   => 'controller.pl?action=CustomerVendor/edit&db=vendor&id=' . $params{trans_id} . '&note_id=' . $form->quote($params{note_id}),
324       'title' => $locale->text('Vendor') . " '$params{trans_info}'",
325     };
326
327   } elsif ($params{trans_type} eq 'sales_quotation') {
328     $link = {
329       'url'   => 'oe.pl?action=edit&type=sales_quotation&id=' . $params{trans_id},
330       'title' => $locale->text('Sales quotation') . " $params{trans_info}",
331     };
332
333   } elsif ($params{trans_type} eq 'sales_delivery_order') {
334
335     $link = {
336       'url'   => 'do.pl?action=edit&type=sales_delivery_order&id=' . $params{trans_id} . '&edit_note_id=' . $form->quote($params{note_id}),
337       'title' => $locale->text('Sales delivery order') .' '. $params{trans_info},
338     };
339
340   } elsif ($params{trans_type} eq 'purchase_delivery_order') {
341
342     $link = {
343       'url'   => 'do.pl?action=edit&type=purchase_delivery_order&id=' . $params{trans_id} . '&edit_note_id=' . $form->quote($params{note_id}),
344       'title' => $locale->text('Purchase delivery order') .' '. $params{trans_info},
345     };
346
347   } elsif ($params{trans_type} eq 'sales_order') {
348     $link = {
349       'url'   => 'oe.pl?action=edit&type=sales_order&id=' . $params{trans_id},
350       'title' => $locale->text('Sales Order') . " $params{trans_info}",
351     };
352
353   } elsif ($params{trans_type} eq 'sales_invoice') {
354     $link = {
355       'url'   => 'is.pl?action=edit&type=invoice&id=' . $params{trans_id},
356       'title' => $locale->text('Sales Invoice') . " $params{trans_info}",
357     };
358
359   } elsif ($params{trans_type} eq 'credit_note') {
360     $link = {
361       'url'   => 'is.pl?action=edit&type=credit_note&id=' . $params{trans_id},
362       'title' => $locale->text('Credit Note') . " $params{trans_info}",
363     };
364
365   } elsif ($params{trans_type} eq 'dunning') {
366     $link = {
367       'url'   => 'dn.pl?action=print_dunning&format=pdf&media=screen&dunning_id=' . $params{trans_id},
368       'title' => $locale->text('Dunning') . " $params{trans_info}",
369     };
370
371   } elsif ($params{trans_type} eq 'request_quotation') {
372     $link = {
373       'url'   => 'oe.pl?action=edit&type=request_quotation&id=' . $params{trans_id},
374       'title' => $locale->text('Request quotation') . " $params{trans_info}",
375     };
376
377   } elsif ($params{trans_type} eq 'purchase_order') {
378     $link = {
379       'url'   => 'oe.pl?action=edit&type=purchase_order&id=' . $params{trans_id},
380       'title' => $locale->text('Purchase Order') . " $params{trans_info}",
381     };
382
383   } elsif ($params{trans_type} eq 'vendor_invoice') {
384     $link = {
385       'url'   => 'ir.pl?action=edit&type=invoice&id=' . $params{trans_id},
386       'title' => $locale->text('Vendor Invoice') . " $params{trans_info}",
387     };
388
389   } elsif ($params{trans_type} eq 'ar_transaction') {
390     $link = {
391       'url'   => 'ar.pl?action=edit&id=' . $params{trans_id},
392       'title' => $locale->text('AR Transaction') . " $params{trans_info}",
393     };
394
395   } elsif ($params{trans_type} eq 'ap_transaction') {
396     $link = {
397       'url'   => 'ap.pl?action=edit&id=' . $params{trans_id},
398       'title' => $locale->text('AP Transaction') . " $params{trans_info}",
399     };
400
401   } elsif ($params{trans_type} eq 'gl_transaction') {
402     $link = {
403       'url'   => 'gl.pl?action=edit&id=' . $params{trans_id},
404       'title' => $locale->text('GL Transaction') . " $params{trans_info}",
405     };
406
407   }
408
409   $main::lxdebug->leave_sub();
410
411   return $link || { };
412 }
413
414 sub save_access_rights {
415   $main::lxdebug->enter_sub();
416
417   my $self     = shift;
418   my %params   = @_;
419
420   Common::check_params(\%params, 'access');
421
422   my $myconfig = \%main::myconfig;
423   my $form     = $main::form;
424
425   my $dbh      = $form->get_standard_dbh($myconfig);
426
427   my ($id)     = selectrow_query($form, $dbh, qq|SELECT id FROM employee WHERE login = ?|, $::myconfig{login});
428
429   do_query($form, $dbh, qq|DELETE FROM follow_up_access WHERE what = ?|, $id);
430
431   my $query    = qq|INSERT INTO follow_up_access (who, what) VALUES (?, ?)|;
432   my $sth      = prepare_query($form, $dbh, $query);
433
434   while (my ($who, $access_allowed) = each %{ $params{access} }) {
435     next unless ($access_allowed);
436
437     do_statement($form, $sth, $query, conv_i($who), $id);
438   }
439
440   $sth->finish();
441
442   $dbh->commit();
443
444   $main::lxdebug->leave_sub();
445 }
446
447 sub retrieve_access_rights {
448   $main::lxdebug->enter_sub();
449
450   my $self     = shift;
451   my %params   = @_;
452
453   my $myconfig = \%main::myconfig;
454   my $form     = $main::form;
455
456   my $dbh      = $form->get_standard_dbh($myconfig);
457
458   my $sth      = prepare_execute_query($form, $dbh, qq|SELECT who FROM follow_up_access WHERE what = (SELECT id FROM employee WHERE login = ?)|, $::myconfig{login});
459   my $access   = {};
460
461   while (my $ref = $sth->fetchrow_hashref()) {
462     $access->{$ref->{who}} = 1;
463   }
464
465   $sth->finish();
466
467   $main::lxdebug->leave_sub();
468
469   return $access;
470 }
471
472 1;