epic-s6ts
[kivitendo-erp.git] / SL / IO.pm
1 package IO;
2
3 use List::Util qw(first);
4 use List::MoreUtils qw(any);
5
6 use SL::DBUtils;
7 use SL::DB;
8
9 use strict;
10
11 sub retrieve_partunits {
12   $main::lxdebug->enter_sub();
13
14   my $self     = shift;
15   my %params   = @_;
16
17   Common::check_params(\%params, qw(part_ids));
18
19   my $myconfig = \%main::myconfig;
20   my $form     = $main::form;
21
22   my $dbh      = $params{dbh} || $form->get_standard_dbh();
23
24   my $query    = qq|SELECT id, unit FROM parts WHERE id IN (| . join(', ', map { '?' } @{ $params{part_ids} }) . qq|)|;
25   my %units    = selectall_as_map($form, $dbh, $query, 'id', 'unit', @{ $params{part_ids} });
26
27   $main::lxdebug->leave_sub();
28
29   return %units;
30 }
31
32
33 sub set_datepaid {
34   $main::lxdebug->enter_sub();
35
36   my $self     = shift;
37   my %params   = @_;
38
39   Common::check_params(\%params, qw(id table));
40
41   my $myconfig = \%main::myconfig;
42   my $form     = $main::form;
43
44   SL::DB->client->with_transaction(sub {
45     my $dbh      = $params{dbh} || SL::DB->client->dbh;
46     my $id       = conv_i($params{id});
47     my $table    = (any { $_ eq $params{table} } qw(ar ap gl)) ? $params{table} : 'ar';
48
49     my ($curr_datepaid, $curr_paid) = selectfirst_array_query($form, $dbh, qq|SELECT datepaid, paid FROM $table WHERE id = ?|, $id);
50
51     my $query    = <<SQL;
52       SELECT MAX(at.transdate)
53       FROM acc_trans at
54       LEFT JOIN chart c ON (at.chart_id = c.id)
55       WHERE (at.trans_id = ?)
56         AND (c.link LIKE '%paid%')
57 SQL
58
59     my ($max_acc_trans_date) = selectfirst_array_query($form, $dbh, $query, $id);
60
61     if ($max_acc_trans_date && ($max_acc_trans_date ne $curr_datepaid)) {
62       # 1. Fall: Es gab mindestens eine Zahlung, und das Datum der Zahlung entspricht nicht
63       # dem vermerkten Zahlungsdatum.
64       do_query($form, $dbh, qq|UPDATE $table SET datepaid = ? WHERE id = ?|, $max_acc_trans_date, $id);
65
66     } elsif (!$max_acc_trans_date && ($curr_paid * 1)) {
67       # 2. Fall: Es gab keine Zahlung, aber paid ist nicht 0. Das ist z.B. der Fall, wenn
68       # die Funktion "als bezahlt buchen" verwendet oder wenn ein Beleg storniert wird.
69       # In diesem Fall das letzte Modifikationsdatum als Bezahldatum nehmen, oder aber das
70       # Erstelldatum, wenn keine Modifikation erfolgt ist (bei Stornos z.B.).
71       do_query($form, $dbh, qq|UPDATE $table SET datepaid = COALESCE(mtime::date, itime::date) WHERE id = ?|, $id);
72     }
73
74     1;
75   }) or do { die SL::DB->client->error };
76
77   $main::lxdebug->leave_sub();
78 }
79
80
81 1;