36 |
36 |
|
37 |
37 |
use SL::Template;
|
38 |
38 |
use SL::IS;
|
|
39 |
use SL::Common;
|
|
40 |
use SL::DBUtils;
|
39 |
41 |
use Data::Dumper;
|
40 |
42 |
|
41 |
43 |
sub get_config {
|
... | ... | |
46 |
48 |
# connect to database
|
47 |
49 |
my $dbh = $form->dbconnect($myconfig);
|
48 |
50 |
|
49 |
|
my $query = qq|SELECT dn.*
|
50 |
|
FROM dunning_config dn
|
51 |
|
ORDER BY dn.dunning_level|;
|
|
51 |
my $query =
|
|
52 |
qq|SELECT * | .
|
|
53 |
qq|FROM dunning_config | .
|
|
54 |
qq|ORDER BY dunning_level|;
|
|
55 |
$form->{DUNNING} = selectall_hashref_query($form, $dbh, $query);
|
52 |
56 |
|
53 |
|
$sth = $dbh->prepare($query);
|
54 |
|
$sth->execute || $form->dberror($query);
|
55 |
|
|
56 |
|
while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
|
|
57 |
foreach my $ref (@{ $form->{DUNNING} }) {
|
57 |
58 |
$ref->{fee} = $form->format_amount($myconfig, $ref->{fee}, 2);
|
58 |
59 |
$ref->{interest} = $form->format_amount($myconfig, ($ref->{interest} * 100));
|
59 |
|
push @{ $form->{DUNNING} }, $ref;
|
60 |
60 |
}
|
61 |
61 |
|
62 |
|
$sth->finish;
|
63 |
|
$dbh->disconnect;
|
|
62 |
$dbh->disconnect();
|
64 |
63 |
|
65 |
64 |
$main::lxdebug->leave_sub();
|
66 |
65 |
}
|
67 |
66 |
|
68 |
|
|
69 |
67 |
sub save_config {
|
70 |
68 |
$main::lxdebug->enter_sub();
|
71 |
69 |
|
... | ... | |
74 |
72 |
# connect to database
|
75 |
73 |
my $dbh = $form->dbconnect_noauto($myconfig);
|
76 |
74 |
|
|
75 |
my ($query, @values);
|
|
76 |
|
77 |
77 |
for my $i (1 .. $form->{rowcount}) {
|
78 |
|
$form->{"active_$i"} *= 1;
|
79 |
|
$form->{"auto_$i"} *= 1;
|
80 |
|
$form->{"email_$i"} *= 1;
|
81 |
|
$form->{"terms_$i"} *= 1;
|
82 |
|
$form->{"payment_terms_$i"} *= 1;
|
83 |
|
$form->{"email_attachment_$i"} *= 1;
|
84 |
78 |
$form->{"fee_$i"} = $form->parse_amount($myconfig, $form->{"fee_$i"}) * 1;
|
85 |
|
$form->{"interest_$i"} = $form->parse_amount($myconfig, $form->{"interest_$i"})/100;
|
86 |
|
|
87 |
|
if (($form->{"dunning_level_$i"} ne "") && ($form->{"dunning_description_$i"} ne "")) {
|
|
79 |
$form->{"interest_$i"} = $form->parse_amount($myconfig, $form->{"interest_$i"}) / 100;
|
|
80 |
|
|
81 |
if (($form->{"dunning_level_$i"} ne "") &&
|
|
82 |
($form->{"dunning_description_$i"} ne "")) {
|
|
83 |
@values = (conv_i($form->{"dunning_level_$i"}), $form->{"dunning_description_$i"},
|
|
84 |
$form->{"email_subject_$i"}, $form->{"email_body_$i"},
|
|
85 |
$form->{"template_$i"}, $form->{"fee_$i"}, $form->{"interest_$i"},
|
|
86 |
$form->{"active_$i"} ? 't' : 'f', $form->{"auto_$i"} ? 't' : 'f', $form->{"email_$i"} ? 't' : 'f',
|
|
87 |
$form->{"email_attachment_$i"} ? 't' : 'f', conv_i($form->{"payment_terms_$i"}), conv_i($form->{"terms_$i"}));
|
88 |
88 |
if ($form->{"id_$i"}) {
|
89 |
|
my $query = qq|UPDATE dunning_config SET
|
90 |
|
dunning_level = | . $dbh->quote($form->{"dunning_level_$i"}) . qq|,
|
91 |
|
dunning_description = | . $dbh->quote($form->{"dunning_description_$i"}) . qq|,
|
92 |
|
email_subject = | . $dbh->quote($form->{"email_subject_$i"}) . qq|,
|
93 |
|
email_body = | . $dbh->quote($form->{"email_body_$i"}) . qq|,
|
94 |
|
template = | . $dbh->quote($form->{"template_$i"}) . qq|,
|
95 |
|
fee = '$form->{"fee_$i"}',
|
96 |
|
interest = '$form->{"interest_$i"}',
|
97 |
|
active = '$form->{"active_$i"}',
|
98 |
|
auto = '$form->{"auto_$i"}',
|
99 |
|
email = '$form->{"email_$i"}',
|
100 |
|
email_attachment = '$form->{"email_attachment_$i"}',
|
101 |
|
payment_terms = $form->{"payment_terms_$i"},
|
102 |
|
terms = $form->{"terms_$i"}
|
103 |
|
WHERE id=$form->{"id_$i"}|;
|
104 |
|
$dbh->do($query) || $form->dberror($query);
|
|
89 |
$query =
|
|
90 |
qq|UPDATE dunning_config SET
|
|
91 |
dunning_level = ?, dunning_description = ?,
|
|
92 |
email_subject = ?, email_body = ?,
|
|
93 |
template = ?, fee = ?, interest = ?,
|
|
94 |
active = ?, auto = ?, email = ?,
|
|
95 |
email_attachment = ?, payment_terms = ?, terms = ?
|
|
96 |
WHERE id = ?|;
|
|
97 |
push(@values, conv_i($form->{"id_$i"}));
|
105 |
98 |
} else {
|
106 |
|
my $query = qq|INSERT INTO dunning_config (dunning_level, dunning_description, email_subject, email_body, template, fee, interest, active, auto, email, email_attachment, terms, payment_terms) VALUES (| . $dbh->quote($form->{"dunning_level_$i"}) . qq|,| . $dbh->quote($form->{"dunning_description_$i"}) . qq|,| . $dbh->quote($form->{"email_subject_$i"}) . qq|,| . $dbh->quote($form->{"email_body_$i"}) . qq|,| . $dbh->quote($form->{"template_$i"}) . qq|,'$form->{"fee_$i"}','$form->{"interest_$i"}','$form->{"active_$i"}','$form->{"auto_$i"}','$form->{"email_$i"}','$form->{"email_attachment_$i"}',$form->{"terms_$i"},$form->{"payment_terms_$i"})|;
|
107 |
|
$dbh->do($query) || $form->dberror($query);
|
|
99 |
$query =
|
|
100 |
qq|INSERT INTO dunning_config
|
|
101 |
(dunning_level, dunning_description, email_subject, email_body,
|
|
102 |
template, fee, interest, active, auto, email,
|
|
103 |
email_attachment, payment_terms, terms)
|
|
104 |
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)|;
|
108 |
105 |
}
|
|
106 |
do_query($form, $dbh, $query, @values);
|
109 |
107 |
}
|
|
108 |
|
110 |
109 |
if (($form->{"dunning_description_$i"} eq "") && ($form->{"id_$i"})) {
|
111 |
|
my $query = qq|DELETE FROM dunning_config WHERE id=$form->{"id_$i"}|;
|
112 |
|
$dbh->do($query) || $form->dberror($query);
|
|
110 |
$query = qq|DELETE FROM dunning_config WHERE id = ?|;
|
|
111 |
do_query($form, $dbh, $query, $form->{"id_$i"});
|
113 |
112 |
}
|
114 |
113 |
}
|
115 |
114 |
|
... | ... | |
126 |
125 |
# connect to database
|
127 |
126 |
my $dbh = $form->dbconnect_noauto($myconfig);
|
128 |
127 |
|
129 |
|
foreach my $row (@{ $rows }) {
|
130 |
|
|
|
128 |
my ($query, @values);
|
|
129 |
|
|
130 |
foreach my $row (@{ $rows }) {
|
|
131 |
|
131 |
132 |
$form->{"interest_$row"} = $form->parse_amount($myconfig,$form->{"interest_$row"});
|
132 |
133 |
$form->{"fee_$row"} = $form->parse_amount($myconfig,$form->{"fee_$row"});
|
133 |
134 |
$form->{send_email} = $form->{"email_$row"};
|
134 |
|
|
135 |
|
my $query = qq| UPDATE ar set dunning_id = '$form->{"next_dunning_id_$row"}' WHERE id='$form->{"inv_id_$row"}'|;
|
136 |
|
$dbh->do($query) || $form->dberror($query);
|
137 |
|
my $query = qq| INSERT into dunning (dunning_id,dunning_level,trans_id,fee,interest,transdate,duedate) VALUES ($form->{"next_dunning_id_$row"},(select dunning_level from dunning_config WHERE id=$form->{"next_dunning_id_$row"}),$form->{"inv_id_$row"},'$form->{"fee_$row"}', '$form->{"interest_$row"}',current_date, |.$dbh->quote($form->{"next_duedate_$row"}) . qq|)|;
|
138 |
|
$dbh->do($query) || $form->dberror($query);
|
|
135 |
|
|
136 |
$query = qq|UPDATE ar SET dunning_id = ? WHERE id = ?|;
|
|
137 |
@values = ($form->{"next_dunning_id_$row"}, $form->{"inv_id_$row"});
|
|
138 |
do_query($form, $dbh, $query, @values);
|
|
139 |
$query =
|
|
140 |
qq|INSERT INTO dunning (dunning_id, dunning_level, trans_id, fee,
|
|
141 |
interest, transdate, duedate)
|
|
142 |
VALUES (?, (SELECT dunning_level FROM dunning_config WHERE id = ?),
|
|
143 |
?, ?, ?, current_date, ?)|;
|
|
144 |
@values = (conv_i($form->{"next_dunning_id_$row"}),
|
|
145 |
conv_i($form->{"next_dunning_id_$row"}),
|
|
146 |
conv_i($form->{"inv_id_$row"}), $form->{"fee_$row"},
|
|
147 |
$form->{"interest_$row"},
|
|
148 |
conv_date($form->{"next_duedate_$row"}));
|
|
149 |
do_query($form, $dbh, $query, @values);
|
139 |
150 |
}
|
140 |
151 |
|
141 |
|
my $query = qq| SELECT invnumber, ordnumber, customer_id, amount, netamount, ar.transdate, ar.duedate, paid, amount-paid AS open_amount, template AS formname, email_subject, email_body, email_attachment, da.fee, da.interest, da.transdate AS dunning_date, da.duedate AS dunning_duedate FROM ar LEFT JOIN dunning_config ON (dunning_config.id=ar.dunning_id) LEFT JOIN dunning da ON (ar.id=da.trans_id AND dunning_config.dunning_level=da.dunning_level) where ar.id IN $form->{inv_ids}|;
|
142 |
|
my $sth = $dbh->prepare($query);
|
143 |
|
$sth->execute || $form->dberror($query);
|
|
152 |
my $query =
|
|
153 |
qq|SELECT invnumber, ordnumber, customer_id, amount, netamount,
|
|
154 |
ar.transdate, ar.duedate, paid, amount - paid AS open_amount,
|
|
155 |
template AS formname, email_subject, email_body, email_attachment,
|
|
156 |
da.fee, da.interest, da.transdate AS dunning_date,
|
|
157 |
da.duedate AS dunning_duedate
|
|
158 |
FROM ar LEFT JOIN dunning_config ON (dunning_config.id = ar.dunning_id)
|
|
159 |
LEFT JOIN dunning da ON (ar.id = da.trans_id AND dunning_config.dunning_level = da.dunning_level)
|
|
160 |
WHERE ar.id IN (|
|
|
161 |
. join(", ", map("?", @{ $form->{"inv_ids"} })) . qq|)|;
|
|
162 |
|
|
163 |
my $sth = prepare_execute_query($form, $dbh, $query, @{ $form->{"inv_ids"} });
|
144 |
164 |
my $first = 1;
|
145 |
165 |
while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
|
146 |
166 |
if ($first) {
|
... | ... | |
150 |
170 |
map { $ref->{$_} = $form->format_amount($myconfig, $ref->{$_}, 2) } qw(amount netamount paid open_amount fee interest);
|
151 |
171 |
map { $form->{$_} = $ref->{$_} } keys %$ref;
|
152 |
172 |
#print(STDERR Dumper($ref));
|
153 |
|
map { push @{ $form->{"dn_$_"} }, $ref->{$_}} keys %$ref;
|
|
173 |
map { push(@{ $form->{"dn_$_"} }, $ref->{$_})} keys %$ref;
|
154 |
174 |
}
|
155 |
175 |
$sth->finish;
|
156 |
176 |
|
... | ... | |
206 |
226 |
$form->{OUT} = "$sendmail";
|
207 |
227 |
|
208 |
228 |
} else {
|
209 |
|
|
210 |
|
my $uid = rand() . time;
|
211 |
|
|
212 |
|
$uid .= $form->{login};
|
213 |
229 |
|
214 |
|
$uid = substr($uid, 2, 75);
|
215 |
|
$filename = $uid;
|
216 |
|
|
217 |
|
$filename .= '.pdf';
|
|
230 |
my $filename = Common::unique_id() . $form->{login} . ".pdf";
|
218 |
231 |
$form->{OUT} = ">$spool/$filename";
|
219 |
232 |
push(@{ $form->{DUNNING_PDFS} }, $filename);
|
220 |
233 |
$form->{keep_tmpfile} = 1;
|
221 |
234 |
}
|
222 |
|
|
|
235 |
|
223 |
236 |
$form->parse_template($myconfig, $userspath);
|
224 |
237 |
|
225 |
238 |
$dbh->commit;
|
... | ... | |
237 |
250 |
# connect to database
|
238 |
251 |
my $dbh = $form->dbconnect($myconfig);
|
239 |
252 |
|
240 |
|
$where = qq| WHERE 1=1 AND a.paid < a.amount AND a.duedate < current_date AND dnn.id = (select id from dunning_config WHERE dunning_level>(select case when a.dunning_id is null then 0 else (select dunning_level from dunning_config where id=a.dunning_id order by dunning_level limit 1 ) end from dunning_config limit 1) limit 1) |;
|
241 |
|
|
242 |
|
if ($form->{"$form->{vc}_id"}) {
|
243 |
|
$where .= qq| AND a.$form->{vc}_id = $form->{"$form->{vc}_id"}|;
|
244 |
|
} else {
|
245 |
|
if ($form->{ $form->{vc} }) {
|
246 |
|
$where .= " AND lower(ct.name) LIKE '$name'";
|
247 |
|
}
|
|
253 |
my $where =
|
|
254 |
qq| WHERE (a.paid < a.amount)
|
|
255 |
AND (a.duedate < current_date)
|
|
256 |
AND (dnn.id =
|
|
257 |
(SELECT id FROM dunning_config
|
|
258 |
WHERE dunning_level >
|
|
259 |
(SELECT
|
|
260 |
CASE
|
|
261 |
WHEN a.dunning_id IS NULL
|
|
262 |
THEN 0
|
|
263 |
ELSE (SELECT dunning_level FROM dunning_config WHERE id = a.dunning_id ORDER BY dunning_level LIMIT 1)
|
|
264 |
END
|
|
265 |
FROM dunning_config LIMIT 1)
|
|
266 |
LIMIT 1)) |;
|
|
267 |
my @values;
|
|
268 |
|
|
269 |
$form->{customer_id} = $1 if ($form->{customer} =~ /--(\d+)$/);
|
|
270 |
|
|
271 |
if ($form->{customer_id}) {
|
|
272 |
$where .= qq| AND (a.customer_id = ?)|;
|
|
273 |
push(@values, $form->{customer_id});
|
|
274 |
|
|
275 |
} elsif ($form->{customer}) {
|
|
276 |
$where .= qq| AND (ct.name ILIKE ?)|;
|
|
277 |
push(@values, '%' . $form->{customer} . '%');
|
248 |
278 |
}
|
249 |
279 |
|
250 |
|
my $sortorder = join ', ',
|
251 |
|
("a.id", $form->sort_columns(transdate, duedate, name));
|
252 |
|
$sortorder = $form->{sort} if $form->{sort};
|
253 |
|
|
254 |
|
$where .= " AND lower(ordnumber) LIKE '$form->{ordnumber}'" if $form->{ordnumber};
|
255 |
|
$where .= " AND lower(invnumber) LIKE '$form->{invnumber}'" if $form->{invnumber};
|
|
280 |
my %columns = (
|
|
281 |
"ordnumber" => "a.ordnumber",
|
|
282 |
"invnumber" => "a.invnumber",
|
|
283 |
"notes" => "a.notes",
|
|
284 |
);
|
|
285 |
foreach my $key (keys(%columns)) {
|
|
286 |
next unless ($form->{$key});
|
|
287 |
$where .= qq| AND $columns{$key} ILIKE ?|;
|
|
288 |
push(@values, '%' . $form->{$key} . '%');
|
|
289 |
}
|
256 |
290 |
|
|
291 |
if ($form->{dunning_level}) {
|
|
292 |
$where .= qq| AND a.dunning_id = ?|;
|
|
293 |
push(@values, conv_i($form->{dunning_level}));
|
|
294 |
}
|
257 |
295 |
|
258 |
296 |
$form->{minamount} = $form->parse_amount($myconfig,$form->{minamount});
|
259 |
|
$where .= " AND a.dunning_id='$form->{dunning_level}'"
|
260 |
|
if $form->{dunning_level};
|
261 |
|
$where .= " AND a.ordnumber ilike '%$form->{ordnumber}%'"
|
262 |
|
if $form->{ordnumber};
|
263 |
|
$where .= " AND a.invnumber ilike '%$form->{invnumber}%'"
|
264 |
|
if $form->{invnumber};
|
265 |
|
$where .= " AND a.notes ilike '%$form->{notes}%'"
|
266 |
|
if $form->{notes};
|
267 |
|
$where .= " AND ct.name ilike '%$form->{customer}%'"
|
268 |
|
if $form->{customer};
|
269 |
|
|
270 |
|
$where .= " AND a.amount-a.paid>'$form->{minamount}'"
|
271 |
|
if $form->{minamount};
|
272 |
|
|
273 |
|
$where .= " ORDER by $sortorder";
|
274 |
|
|
275 |
|
$paymentdate = ($form->{paymentuntil}) ? "'$form->{paymentuntil}'" : current_date;
|
276 |
|
|
277 |
|
$query = qq|SELECT a.id, a.ordnumber, a.transdate, a.invnumber,a.amount, ct.name AS customername, a.customer_id, a.duedate,da.fee AS old_fee,dnn.active,dnn.email, dnn.fee as fee, dn.dunning_description, da.transdate AS dunning_date, da.duedate AS dunning_duedate, a.duedate + dnn.terms - current_date AS nextlevel, $paymentdate - a.duedate AS pastdue, dn.dunning_level, current_date + dnn.payment_terms AS next_duedate, dnn.dunning_description AS next_dunning_description, dnn.id AS next_dunning_id, dnn.interest AS interest_rate, dnn.terms
|
278 |
|
FROM dunning_config dnn, ar a
|
279 |
|
JOIN customer ct ON (a.customer_id = ct.id)
|
280 |
|
LEFT JOIN dunning_config dn ON (dn.id = a.dunning_id)
|
281 |
|
LEFT JOIN dunning da ON (da.trans_id=a.id AND dn.dunning_level=da.dunning_level)
|
282 |
|
$where|;
|
283 |
|
|
284 |
|
my $sth = $dbh->prepare($query);
|
285 |
|
$sth->execute || $form->dberror($query);
|
|
297 |
if ($form->{minamount}) {
|
|
298 |
$where .= qq| AND ((a.amount - a.paid) > ?) |;
|
|
299 |
push(@values, $form->{minamount});
|
|
300 |
}
|
286 |
301 |
|
|
302 |
$paymentdate = $form->{paymentuntil} ? $dbh->quote($form->{paymentuntil}) :
|
|
303 |
"current_date";
|
|
304 |
|
|
305 |
$query =
|
|
306 |
qq|SELECT a.id, a.ordnumber, a.transdate, a.invnumber, a.amount,
|
|
307 |
ct.name AS customername, a.customer_id, a.duedate,
|
|
308 |
da.fee AS old_fee, dnn.active, dnn.email, dnn.fee + da.fee AS fee,
|
|
309 |
dn.dunning_description, da.transdate AS dunning_date, da.duedate AS dunning_duedate,
|
|
310 |
a.duedate + dnn.terms - current_date AS nextlevel,
|
|
311 |
$paymentdate - a.duedate AS pastdue, dn.dunning_level,
|
|
312 |
current_date + dnn.payment_terms AS next_duedate,
|
|
313 |
dnn.dunning_description AS next_dunning_description, dnn.id AS next_dunning_id,
|
|
314 |
dnn.interest AS interest_rate, dnn.terms
|
|
315 |
FROM dunning_config dnn, ar a
|
|
316 |
JOIN customer ct ON (a.customer_id = ct.id)
|
|
317 |
LEFT JOIN dunning_config dn ON (dn.id = a.dunning_id)
|
|
318 |
LEFT JOIN dunning da ON ((da.trans_id = a.id) AND (dn.dunning_level = da.dunning_level))
|
|
319 |
$where
|
|
320 |
ORDER BY a.id, transdate, duedate, name|;
|
|
321 |
|
|
322 |
my $sth = prepare_execute_query($form, $dbh, $query, @values);
|
|
323 |
|
|
324 |
$form->{DUNNINGS} = [];
|
287 |
325 |
|
288 |
326 |
while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
|
289 |
|
$ref->{fee} += $ref->{old_fee};
|
290 |
|
$ref->{interest} = ($ref->{amount} * $ref->{pastdue} * $ref->{interest_rate}) /360;
|
291 |
|
$ref->{interest} = $form->round_amount($ref->{interest},2);
|
292 |
|
map { $ref->{$_} = $form->format_amount($myconfig, $ref->{$_}, 2)} qw(amount fee interest);
|
|
327 |
$ref->{interest} = ($ref->{amount} * $ref->{pastdue} * $ref->{interest_rate}) / 360;
|
|
328 |
$ref->{interest} = $form->round_amount($ref->{interest}, 2);
|
|
329 |
map({ $ref->{$_} = $form->format_amount($myconfig, $ref->{$_}, 2)} qw(amount fee interest));
|
293 |
330 |
if ($ref->{pastdue} >= $ref->{terms}) {
|
294 |
|
push @{ $form->{DUNNINGS} }, $ref;
|
|
331 |
push(@{ $form->{DUNNINGS} }, $ref);
|
295 |
332 |
}
|
296 |
333 |
}
|
297 |
334 |
|
298 |
335 |
$sth->finish;
|
299 |
336 |
|
300 |
|
$query = qq|select id, dunning_description FROM dunning_config order by dunning_level|;
|
301 |
|
my $sth = $dbh->prepare($query);
|
302 |
|
$sth->execute || $form->dberror($query);
|
303 |
|
|
304 |
|
while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
|
305 |
|
push @{ $form->{DUNNING_CONFIG} }, $ref;
|
306 |
|
}
|
307 |
|
|
308 |
|
$sth->finish;
|
|
337 |
$query = qq|SELECT id, dunning_description FROM dunning_config ORDER BY dunning_level|;
|
|
338 |
$form->{DUNNING_CONFIG} = selectall_hashref_query($form, $dbh, $query);
|
309 |
339 |
|
310 |
340 |
$dbh->disconnect;
|
311 |
341 |
$main::lxdebug->leave_sub();
|
... | ... | |
320 |
350 |
# connect to database
|
321 |
351 |
my $dbh = $form->dbconnect($myconfig);
|
322 |
352 |
|
323 |
|
$where = qq| WHERE 1=1 AND da.trans_id=a.id|;
|
|
353 |
$where = qq| WHERE (da.trans_id = a.id)|;
|
324 |
354 |
|
325 |
|
if ($form->{"$form->{vc}_id"}) {
|
326 |
|
$where .= qq| AND a.$form->{vc}_id = $form->{"$form->{vc}_id"}|;
|
327 |
|
} else {
|
328 |
|
if ($form->{ $form->{vc} }) {
|
329 |
|
$where .= " AND lower(ct.name) LIKE '$name'";
|
330 |
|
}
|
331 |
|
}
|
|
355 |
my @values;
|
332 |
356 |
|
333 |
|
my $sortorder = join ', ',
|
334 |
|
("a.id", $form->sort_columns(transdate, duedate, name));
|
335 |
|
$sortorder = $form->{sort} if $form->{sort};
|
|
357 |
$form->{customer_id} = $1 if ($form->{customer} =~ /--(\d+)$/);
|
336 |
358 |
|
337 |
|
$where .= " AND lower(ordnumber) LIKE '$form->{ordnumber}'" if $form->{ordnumber};
|
338 |
|
$where .= " AND lower(invnumber) LIKE '$form->{invnumber}'" if $form->{invnumber};
|
|
359 |
if ($form->{customer_id}) {
|
|
360 |
$where .= qq| AND (a.customer_id = ?)|;
|
|
361 |
push(@values, $form->{customer_id});
|
339 |
362 |
|
|
363 |
} elsif ($form->{customer}) {
|
|
364 |
$where .= qq| AND (ct.name ILIKE ?)|;
|
|
365 |
push(@values, '%' . $form->{customer} . '%');
|
|
366 |
}
|
340 |
367 |
|
341 |
|
$form->{minamount} = $form->parse_amount($myconfig,$form->{minamount});
|
342 |
|
$where .= " AND a.dunning_id='$form->{dunning_level}'"
|
343 |
|
if $form->{dunning_level};
|
344 |
|
$where .= " AND a.ordnumber ilike '%$form->{ordnumber}%'"
|
345 |
|
if $form->{ordnumber};
|
346 |
|
$where .= " AND a.invnumber ilike '%$form->{invnumber}%'"
|
347 |
|
if $form->{invnumber};
|
348 |
|
$where .= " AND a.notes ilike '%$form->{notes}%'"
|
349 |
|
if $form->{notes};
|
350 |
|
$where .= " AND ct.name ilike '%$form->{customer}%'"
|
351 |
|
if $form->{customer};
|
352 |
|
$where .= " AND a.amount > a.paid AND da.dunning_id=a.dunning_id " unless ($form->{showold});
|
353 |
368 |
|
354 |
|
$where .= " AND a.transdate >='$form->{transdatefrom}' " if ($form->{transdatefrom});
|
355 |
|
$where .= " AND a.transdate <='$form->{transdateto}' " if ($form->{transdateto});
|
356 |
|
$where .= " AND da.transdate >='$form->{dunningfrom}' " if ($form->{dunningfrom});
|
357 |
|
$where .= " AND da.transdate <='$form->{dunningto}' " if ($form->{dunningto});
|
|
369 |
my %columns = (
|
|
370 |
"ordnumber" => "a.ordnumber",
|
|
371 |
"invnumber" => "a.invnumber",
|
|
372 |
"notes" => "a.notes",
|
|
373 |
);
|
|
374 |
foreach my $key (keys(%columns)) {
|
|
375 |
next unless ($form->{$key});
|
|
376 |
$where .= qq| AND $columns{$key} ILIKE ?|;
|
|
377 |
push(@values, '%' . $form->{$key} . '%');
|
|
378 |
}
|
358 |
379 |
|
359 |
|
$where .= " ORDER by $sortorder";
|
|
380 |
if ($form->{dunning_level}) {
|
|
381 |
$where .= qq| AND a.dunning_id = ?|;
|
|
382 |
push(@values, conv_i($form->{dunning_level}));
|
|
383 |
}
|
360 |
384 |
|
|
385 |
$form->{minamount} = $form->parse_amount($myconfig,$form->{minamount});
|
|
386 |
if ($form->{minamount}) {
|
|
387 |
$where .= qq| AND ((a.amount - a.paid) > ?) |;
|
|
388 |
push(@values, $form->{minamount});
|
|
389 |
}
|
361 |
390 |
|
362 |
|
$query = qq|SELECT a.id, a.ordnumber,a.invoice, a.transdate, a.invnumber,a.amount, ct.name AS customername, a.duedate,da.fee ,da.interest, dn.dunning_description, da.transdate AS dunning_date, da.duedate AS dunning_duedate, da.dunning_id
|
363 |
|
FROM ar a
|
364 |
|
JOIN customer ct ON (a.customer_id = ct.id),
|
365 |
|
dunning da LEFT JOIN dunning_config dn ON (da.dunning_id=dn.id)
|
366 |
|
$where|;
|
|
391 |
if (!$form->{showold}) {
|
|
392 |
$where .= qq| AND (a.amount > a.paid) AND (da.dunning_id = a.dunning_id) |;
|
|
393 |
}
|
367 |
394 |
|
368 |
|
my $sth = $dbh->prepare($query);
|
369 |
|
$sth->execute || $form->dberror($query);
|
|
395 |
if ($form->{transdatefrom}) {
|
|
396 |
$where .= qq| AND a.transdate >= ?|;
|
|
397 |
push(@values, $form->{transdatefrom});
|
|
398 |
}
|
|
399 |
if ($form->{transdateto}) {
|
|
400 |
$where .= qq| AND a.transdate <= ?|;
|
|
401 |
push(@values, $form->{transdateto});
|
|
402 |
}
|
|
403 |
if ($form->{dunningfrom}) {
|
|
404 |
$where .= qq| AND da.transdate >= ?|;
|
|
405 |
push(@values, $form->{dunningfrom});
|
|
406 |
}
|
|
407 |
if ($form->{dunningto}) {
|
|
408 |
$where .= qq| AND da.transdate >= ?|;
|
|
409 |
push(@values, $form->{dunningto});
|
|
410 |
}
|
370 |
411 |
|
|
412 |
$query =
|
|
413 |
qq|SELECT a.id, a.ordnumber, a.invoice, a.transdate, a.invnumber, a.amount,
|
|
414 |
ct.name AS customername, ct.id AS customer_id, a.duedate, da.fee,
|
|
415 |
da.interest, dn.dunning_description, da.transdate AS dunning_date, da.duedate AS dunning_duedate, da.dunning_id
|
|
416 |
FROM ar a
|
|
417 |
JOIN customer ct ON (a.customer_id = ct.id), dunning da
|
|
418 |
LEFT JOIN dunning_config dn ON (da.dunning_id = dn.id)
|
|
419 |
$where
|
|
420 |
ORDER BY name, a.id|;
|
371 |
421 |
|
372 |
|
while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
|
|
422 |
$form->{DUNNINGS} = selectall_hashref_query($form, $dbh, $query, @values);
|
373 |
423 |
|
|
424 |
foreach my $ref (@{ $form->{DUNNINGS} }) {
|
374 |
425 |
map { $ref->{$_} = $form->format_amount($myconfig, $ref->{$_}, 2)} qw(amount fee interest);
|
375 |
|
push @{ $form->{DUNNINGS} }, $ref;
|
376 |
426 |
}
|
377 |
427 |
|
378 |
|
$sth->finish;
|
379 |
|
|
380 |
|
|
381 |
|
|
382 |
428 |
$dbh->disconnect;
|
383 |
429 |
$main::lxdebug->leave_sub();
|
384 |
430 |
}
|
385 |
431 |
|
386 |
|
|
387 |
432 |
sub parse_strings {
|
388 |
433 |
|
389 |
434 |
$main::lxdebug->enter_sub();
|
... | ... | |
415 |
460 |
$form->cleanup();
|
416 |
461 |
$form->error("$form->{IN} : " . $template->get_error());
|
417 |
462 |
}
|
418 |
|
|
|
463 |
|
419 |
464 |
close(OUT);
|
420 |
465 |
my $result = "";
|
421 |
466 |
open(IN, $form->{tmpfile}) or $form->error($form->cleanup . "$form->{tmpfile} : $!");
|
... | ... | |
439 |
484 |
$main::lxdebug->enter_sub();
|
440 |
485 |
|
441 |
486 |
my ($self, $myconfig, $form, $userspath) = @_;
|
442 |
|
|
|
487 |
|
|
488 |
map({ $_ =~ s|.*/||g; } @{ $form->{DUNNING_PDFS} });
|
|
489 |
|
443 |
490 |
foreach my $file (@{ $form->{DUNNING_PDFS} }) {
|
444 |
491 |
$inputfiles .= " $userspath/$file ";
|
445 |
492 |
}
|
... | ... | |
449 |
496 |
foreach my $file (@{ $form->{DUNNING_PDFS} }) {
|
450 |
497 |
unlink("$userspath/$file");
|
451 |
498 |
}
|
452 |
|
$out="";
|
453 |
|
|
|
499 |
$out = "";
|
454 |
500 |
|
455 |
|
$form->{OUT} = $out;
|
|
501 |
$form->{OUT} = $out;
|
456 |
502 |
|
457 |
|
my $numbytes = (-s $outputfile);
|
458 |
|
open(IN, $outputfile)
|
459 |
|
or $form->error($self->cleanup . "$outputfile : $!");
|
|
503 |
my $numbytes = (-s $outputfile);
|
|
504 |
open(IN, $outputfile)
|
|
505 |
or $form->error($self->cleanup . "$outputfile : $!");
|
460 |
506 |
|
461 |
|
$form->{copies} = 1 unless $form->{media} eq 'printer';
|
|
507 |
$form->{copies} = 1 unless $form->{media} eq 'printer';
|
462 |
508 |
|
463 |
|
chdir("$self->{cwd}");
|
|
509 |
chdir("$self->{cwd}");
|
464 |
510 |
|
465 |
|
for my $i (1 .. $form->{copies}) {
|
466 |
|
if ($form->{OUT}) {
|
467 |
|
open(OUT, $form->{OUT})
|
468 |
|
or $form->error($form->cleanup . "$form->{OUT} : $!");
|
469 |
|
} else {
|
|
511 |
for my $i (1 .. $form->{copies}) {
|
|
512 |
if ($form->{OUT}) {
|
|
513 |
open(OUT, $form->{OUT})
|
|
514 |
or $form->error($form->cleanup . "$form->{OUT} : $!");
|
|
515 |
} else {
|
470 |
516 |
|
471 |
|
# launch application
|
472 |
|
print qq|Content-Type: Application/PDF
|
|
517 |
# launch application
|
|
518 |
print qq|Content-Type: Application/PDF
|
473 |
519 |
Content-Disposition: attachment; filename="$outputfile"
|
474 |
520 |
Content-Length: $numbytes
|
475 |
521 |
|
476 |
522 |
|;
|
477 |
523 |
|
478 |
|
open(OUT, ">-") or $form->error($form->cleanup . "$!: STDOUT");
|
|
524 |
open(OUT, ">-") or $form->error($form->cleanup . "$!: STDOUT");
|
479 |
525 |
|
480 |
|
}
|
|
526 |
}
|
481 |
527 |
|
482 |
|
while (<IN>) {
|
483 |
|
print OUT $_;
|
484 |
|
}
|
|
528 |
while (<IN>) {
|
|
529 |
print OUT $_;
|
|
530 |
}
|
485 |
531 |
|
486 |
|
close(OUT);
|
|
532 |
close(OUT);
|
487 |
533 |
|
488 |
|
seek IN, 0, 0;
|
489 |
|
}
|
|
534 |
seek(IN, 0, 0);
|
|
535 |
}
|
490 |
536 |
|
491 |
|
close(IN);
|
|
537 |
close(IN);
|
492 |
538 |
unlink("$userspath/$outputfile");
|
493 |
539 |
|
494 |
540 |
$main::lxdebug->leave_sub();
|
... | ... | |
497 |
543 |
sub print_dunning {
|
498 |
544 |
$main::lxdebug->enter_sub();
|
499 |
545 |
|
500 |
|
my ($self, $myconfig, $form, $dunning_id, $userspath,$spool, $sendmail) = @_;
|
|
546 |
my ($self, $myconfig, $form, $dunning_id, $customer_id, $userspath,$spool, $sendmail) = @_;
|
501 |
547 |
# connect to database
|
502 |
548 |
my $dbh = $form->dbconnect_noauto($myconfig);
|
503 |
549 |
|
504 |
|
|
505 |
|
my $query = qq| SELECT invnumber, ordnumber, customer_id, amount, netamount, ar.transdate, ar.duedate, paid, amount-paid AS open_amount, template AS formname, email_subject, email_body, email_attachment, da.fee, da.interest, da.transdate AS dunning_date, da.duedate AS dunning_duedate FROM ar LEFT JOIN dunning_config ON (dunning_config.id=ar.dunning_id) LEFT JOIN dunning da ON (ar.id=da.trans_id AND dunning_config.dunning_level=da.dunning_level) where ar.dunning_id=$dunning_id|;
|
506 |
|
my $sth = $dbh->prepare($query);
|
507 |
|
$sth->execute || $form->dberror($query);
|
|
550 |
my $query =
|
|
551 |
qq|SELECT invnumber, ordnumber, customer_id, amount, netamount,
|
|
552 |
ar.transdate, ar.duedate, paid, amount - paid AS open_amount,
|
|
553 |
template AS formname, email_subject, email_body, email_attachment,
|
|
554 |
da.fee, da.interest, da.transdate AS dunning_date, da.duedate AS dunning_duedate
|
|
555 |
FROM ar
|
|
556 |
LEFT JOIN dunning_config ON (dunning_config.id = ar.dunning_id)
|
|
557 |
LEFT JOIN dunning da ON ((ar.id = da.trans_id) AND (dunning_config.dunning_level = da.dunning_level))
|
|
558 |
WHERE (ar.dunning_id = ?) AND (customer_id = ?)|;
|
|
559 |
|
|
560 |
my $sth = prepare_execute_query($form, $dbh, $query, $dunning_id, $customer_id);
|
508 |
561 |
my $first = 1;
|
509 |
562 |
while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
|
510 |
563 |
if ($first) {
|
... | ... | |
513 |
566 |
}
|
514 |
567 |
map { $ref->{$_} = $form->format_amount($myconfig, $ref->{$_}, 2) } qw(amount netamount paid open_amount fee interest);
|
515 |
568 |
map { $form->{$_} = $ref->{$_} } keys %$ref;
|
516 |
|
#print(STDERR Dumper($ref));
|
517 |
569 |
map { push @{ $form->{"dn_$_"} }, $ref->{$_}} keys %$ref;
|
518 |
570 |
}
|
519 |
571 |
$sth->finish;
|
520 |
572 |
|
521 |
573 |
IS->customer_details($myconfig,$form);
|
522 |
|
#print(STDERR Dumper($form->{dn_invnumber}));
|
523 |
574 |
$form->{templates} = "$myconfig->{templates}";
|
524 |
575 |
|
525 |
|
|
526 |
|
|
527 |
576 |
$form->{language} = $form->get_template_language(\%myconfig);
|
528 |
577 |
$form->{printer_code} = $form->get_printer_code(\%myconfig);
|
529 |
578 |
|
... | ... | |
570 |
619 |
$form->{OUT} = "$sendmail";
|
571 |
620 |
|
572 |
621 |
} else {
|
573 |
|
|
574 |
|
my $uid = rand() . time;
|
575 |
|
|
576 |
|
$uid .= $form->{login};
|
577 |
622 |
|
578 |
|
$uid = substr($uid, 2, 75);
|
579 |
|
$filename = $uid;
|
|
623 |
my $filename = Common::unique_id() . $form->{login} . ".pdf";
|
580 |
624 |
|
581 |
|
$filename .= '.pdf';
|
582 |
|
$form->{OUT} = ">$spool/$filename";
|
583 |
625 |
push(@{ $form->{DUNNING_PDFS} }, $filename);
|
584 |
626 |
$form->{keep_tmpfile} = 1;
|
585 |
627 |
}
|
586 |
|
|
|
628 |
|
587 |
629 |
$form->parse_template($myconfig, $userspath);
|
588 |
630 |
|
589 |
631 |
$dbh->commit;
|
Vermeidung von SQL injection durch Verwendung von parametrisierten Queries. Zusätzlich die Optik beim Bericht über laufende Mahnungen verbessert. Fehler beseitigt, dass das erneute Ausdrucken von Mahnungen alle Mahnungen zusammengefasst hat, auch über Kundengrenzen hinaus.