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