Revision fd6900cc
Von Moritz Bunkus vor mehr als 17 Jahren hinzugefügt
SL/DN.pm | ||
---|---|---|
56 | 56 |
|
57 | 57 |
foreach my $ref (@{ $form->{DUNNING} }) { |
58 | 58 |
$ref->{fee} = $form->format_amount($myconfig, $ref->{fee}, 2); |
59 |
$ref->{interest} = $form->format_amount($myconfig, ($ref->{interest} * 100));
|
|
59 |
$ref->{interest_rate} = $form->format_amount($myconfig, ($ref->{interest_rate} * 100));
|
|
60 | 60 |
} |
61 | 61 |
|
62 | 62 |
$dbh->disconnect(); |
... | ... | |
76 | 76 |
|
77 | 77 |
for my $i (1 .. $form->{rowcount}) { |
78 | 78 |
$form->{"fee_$i"} = $form->parse_amount($myconfig, $form->{"fee_$i"}) * 1; |
79 |
$form->{"interest_$i"} = $form->parse_amount($myconfig, $form->{"interest_$i"}) / 100;
|
|
79 |
$form->{"interest_rate_$i"} = $form->parse_amount($myconfig, $form->{"interest_rate_$i"}) / 100;
|
|
80 | 80 |
|
81 | 81 |
if (($form->{"dunning_level_$i"} ne "") && |
82 | 82 |
($form->{"dunning_description_$i"} ne "")) { |
83 | 83 |
@values = (conv_i($form->{"dunning_level_$i"}), $form->{"dunning_description_$i"}, |
84 | 84 |
$form->{"email_subject_$i"}, $form->{"email_body_$i"}, |
85 |
$form->{"template_$i"}, $form->{"fee_$i"}, $form->{"interest_$i"}, |
|
85 |
$form->{"template_$i"}, $form->{"fee_$i"}, $form->{"interest_rate_$i"},
|
|
86 | 86 |
$form->{"active_$i"} ? 't' : 'f', $form->{"auto_$i"} ? 't' : 'f', $form->{"email_$i"} ? 't' : 'f', |
87 | 87 |
$form->{"email_attachment_$i"} ? 't' : 'f', conv_i($form->{"payment_terms_$i"}), conv_i($form->{"terms_$i"})); |
88 | 88 |
if ($form->{"id_$i"}) { |
... | ... | |
90 | 90 |
qq|UPDATE dunning_config SET |
91 | 91 |
dunning_level = ?, dunning_description = ?, |
92 | 92 |
email_subject = ?, email_body = ?, |
93 |
template = ?, fee = ?, interest = ?, |
|
93 |
template = ?, fee = ?, interest_rate = ?,
|
|
94 | 94 |
active = ?, auto = ?, email = ?, |
95 | 95 |
email_attachment = ?, payment_terms = ?, terms = ? |
96 | 96 |
WHERE id = ?|; |
... | ... | |
99 | 99 |
$query = |
100 | 100 |
qq|INSERT INTO dunning_config |
101 | 101 |
(dunning_level, dunning_description, email_subject, email_body, |
102 |
template, fee, interest, active, auto, email, |
|
102 |
template, fee, interest_rate, active, auto, email,
|
|
103 | 103 |
email_attachment, payment_terms, terms) |
104 | 104 |
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)|; |
105 | 105 |
} |
... | ... | |
129 | 129 |
|
130 | 130 |
my ($dunning_id) = selectrow_query($form, $dbh, qq|SELECT nextval('id')|); |
131 | 131 |
|
132 |
my $q_update_ar = qq|UPDATE ar SET dunning_config_id = ? WHERE id = ?|; |
|
133 |
my $h_update_ar = prepare_query($form, $dbh, $q_update_ar); |
|
134 |
|
|
135 |
my $q_insert_dunning = |
|
136 |
qq|INSERT INTO dunning (dunning_id, dunning_config_id, dunning_level, |
|
137 |
trans_id, fee, interest, transdate, duedate) |
|
138 |
VALUES (?, ?, |
|
139 |
(SELECT dunning_level FROM dunning_config WHERE id = ?), |
|
140 |
?, |
|
141 |
(SELECT SUM(fee) |
|
142 |
FROM dunning_config |
|
143 |
WHERE dunning_level <= (SELECT dunning_level FROM dunning_config WHERE id = ?)), |
|
144 |
(SELECT (amount - paid) * (current_date - transdate) FROM ar WHERE id = ?) |
|
145 |
* (SELECT interest_rate FROM dunning_config WHERE id = ?) |
|
146 |
/ 360, |
|
147 |
current_date, |
|
148 |
current_date + (SELECT payment_terms FROM dunning_config WHERE id = ?))|; |
|
149 |
my $h_insert_dunning = prepare_query($form, $dbh, $q_insert_dunning); |
|
150 |
|
|
151 |
my @invoice_ids; |
|
152 |
my ($next_dunning_config_id, $customer_id); |
|
153 |
my $send_email = 0; |
|
154 |
|
|
132 | 155 |
foreach my $row (@{ $rows }) { |
156 |
push @invoice_ids, $row->{invoice_id}; |
|
157 |
$next_dunning_config_id = $row->{next_dunning_config_id}; |
|
158 |
$customer_id = $row->{customer_id}; |
|
159 |
|
|
160 |
@values = ($row->{next_dunning_config_id}, $row->{invoice_id}); |
|
161 |
do_statement($form, $h_update_ar, $q_update_ar, @values); |
|
162 |
|
|
163 |
$send_email |= $row->{email}; |
|
133 | 164 |
|
134 |
$form->{"interest_$row"} = $form->parse_amount($myconfig,$form->{"interest_$row"}); |
|
135 |
$form->{"fee_$row"} = $form->parse_amount($myconfig,$form->{"fee_$row"}); |
|
136 |
$form->{send_email} = $form->{"email_$row"}; |
|
137 |
|
|
138 |
$query = qq|UPDATE ar SET dunning_config_id = ? WHERE id = ?|; |
|
139 |
@values = ($form->{"next_dunning_config_id_$row"}, |
|
140 |
$form->{"inv_id_$row"}); |
|
141 |
do_query($form, $dbh, $query, @values); |
|
142 |
|
|
143 |
$query = |
|
144 |
qq|INSERT INTO dunning (dunning_id, dunning_config_id, dunning_level, |
|
145 |
trans_id, fee, interest, transdate, duedate) |
|
146 |
VALUES (?, ?, (SELECT dunning_level FROM dunning_config WHERE id = ?), |
|
147 |
?, ?, ?, current_date, ?)|; |
|
148 |
@values = ($dunning_id, |
|
149 |
conv_i($form->{"next_dunning_config_id_$row"}), |
|
150 |
conv_i($form->{"next_dunning_config_id_$row"}), |
|
151 |
conv_i($form->{"inv_id_$row"}), $form->{"fee_$row"}, |
|
152 |
$form->{"interest_$row"}, |
|
153 |
conv_date($form->{"next_duedate_$row"})); |
|
154 |
do_query($form, $dbh, $query, @values); |
|
165 |
my $next_config_id = conv_i($row->{next_dunning_config_id}); |
|
166 |
my $invoice_id = conv_i($row->{invoice_id}); |
|
167 |
|
|
168 |
@values = ($dunning_id, $next_config_id, $next_config_id, |
|
169 |
$invoice_id, $next_config_id, $invoice_id, |
|
170 |
$next_config_id, $next_config_id); |
|
171 |
do_statement($form, $h_insert_dunning, $q_insert_dunning, @values); |
|
155 | 172 |
} |
156 | 173 |
|
174 |
$h_update_ar->finish(); |
|
175 |
$h_insert_dunning->finish(); |
|
176 |
|
|
157 | 177 |
my $query = |
158 |
qq|SELECT invnumber, ordnumber, customer_id, amount, netamount, |
|
159 |
ar.transdate, ar.duedate, paid, amount - paid AS open_amount, |
|
160 |
template AS formname, email_subject, email_body, email_attachment, |
|
161 |
da.fee, da.interest, da.transdate AS dunning_date, |
|
162 |
da.duedate AS dunning_duedate, |
|
163 |
c.name, c.street, c.zipcode, c.city, c.country, c.department_1, c.department_2 |
|
178 |
qq|SELECT |
|
179 |
ar.invnumber, ar.ordnumber, ar.amount, ar.netamount, |
|
180 |
ar.transdate, ar.duedate, ar.paid, ar.amount - ar.paid AS open_amount, |
|
181 |
da.fee, da.interest, da.transdate AS dunning_date, da.duedate AS dunning_duedate |
|
164 | 182 |
FROM ar |
165 |
LEFT JOIN dunning_config ON (dunning_config.id = ar.dunning_config_id) |
|
166 |
LEFT JOIN dunning da ON (ar.id = da.trans_id AND dunning_config.dunning_level = da.dunning_level) |
|
167 |
LEFT JOIN customer c ON (ar.customer_id = c.id) |
|
183 |
LEFT JOIN dunning_config cfg ON (cfg.id = ar.dunning_config_id) |
|
184 |
LEFT JOIN dunning da ON (ar.id = da.trans_id AND cfg.dunning_level = da.dunning_level) |
|
168 | 185 |
WHERE ar.id IN (| |
169 |
. join(", ", map("?", @{ $form->{"inv_ids"} })) . qq|)|;
|
|
186 |
. join(", ", map { "?" } @invoice_ids) . qq|)|;
|
|
170 | 187 |
|
171 |
my $sth = prepare_execute_query($form, $dbh, $query, @{ $form->{"inv_ids"} });
|
|
188 |
my $sth = prepare_execute_query($form, $dbh, $query, @invoice_ids);
|
|
172 | 189 |
my $first = 1; |
173 | 190 |
while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { |
174 | 191 |
if ($first) { |
175 | 192 |
map({ $form->{"dn_$_"} = []; } keys(%{$ref})); |
176 | 193 |
$first = 0; |
177 | 194 |
} |
195 |
|
|
196 |
$ref->{interest_rate} = $form->format_amount($myconfig, $ref->{interest_rate} * 100); |
|
178 | 197 |
map { $ref->{$_} = $form->format_amount($myconfig, $ref->{$_}, 2) } qw(amount netamount paid open_amount fee interest); |
179 |
map { $form->{$_} = $ref->{$_} } keys %$ref; |
|
180 |
#print(STDERR Dumper($ref)); |
|
181 | 198 |
map { push(@{ $form->{"dn_$_"} }, $ref->{$_})} keys %$ref; |
199 |
map { $form->{$_} = $ref->{$_} } keys %{ $ref }; |
|
182 | 200 |
} |
183 | 201 |
$sth->finish; |
184 | 202 |
|
185 |
IS->customer_details($myconfig,$form); |
|
186 |
#print(STDERR Dumper($form->{dn_invnumber})); |
|
187 |
$form->{templates} = "$myconfig->{templates}"; |
|
188 |
|
|
189 |
|
|
203 |
$query = |
|
204 |
qq|SELECT id AS customer_id, name, street, zipcode, city, country, department_1, department_2, email |
|
205 |
FROM customer |
|
206 |
WHERE id = ?|; |
|
207 |
$ref = selectfirst_hashref_query($form, $dbh, $query, $customer_id); |
|
208 |
map { $form->{$_} = $ref->{$_} } keys %{ $ref }; |
|
190 | 209 |
|
191 |
$form->{language} = $form->get_template_language(\%myconfig); |
|
210 |
$query = |
|
211 |
qq|SELECT |
|
212 |
cfg.interest_rate, cfg.template AS formname, |
|
213 |
cfg.email_subject, cfg.email_body, cfg.email_attachment, |
|
214 |
(SELECT fee |
|
215 |
FROM dunning |
|
216 |
WHERE dunning_id = ? |
|
217 |
LIMIT 1) |
|
218 |
AS fee, |
|
219 |
(SELECT SUM(interest) |
|
220 |
FROM dunning |
|
221 |
WHERE dunning_id = ?) |
|
222 |
AS total_interest, |
|
223 |
(SELECT SUM(amount) - SUM(paid) |
|
224 |
FROM ar |
|
225 |
WHERE id IN (| . join(", ", map { "?" } @invoice_ids) . qq|)) |
|
226 |
AS total_open_amount |
|
227 |
FROM dunning_config cfg |
|
228 |
WHERE id = ?|; |
|
229 |
$ref = selectfirst_hashref_query($form, $dbh, $query, $dunning_id, $dunning_id, @invoice_ids, $next_dunning_config_id); |
|
230 |
map { $form->{$_} = $ref->{$_} } keys %{ $ref }; |
|
231 |
|
|
232 |
$form->{interest_rate} = $form->format_amount($myconfig, $ref->{interest_rate} * 100); |
|
233 |
$form->{fee} = $form->format_amount($myconfig, $ref->{fee}, 2); |
|
234 |
$form->{total_interest} = $form->format_amount($myconfig, $form->round_amount($ref->{total_interest}, 2), 2); |
|
235 |
$form->{total_open_amount} = $form->format_amount($myconfig, $form->round_amount($ref->{total_open_amount}, 2), 2); |
|
236 |
$form->{total_amount} = $form->format_amount($myconfig, $form->round_amount($ref->{fee} + $ref->{total_interest} + $ref->{total_open_amount}, 2), 2); |
|
237 |
|
|
238 |
$form->{templates} = "$myconfig->{templates}"; |
|
239 |
$form->{language} = $form->get_template_language(\%myconfig); |
|
192 | 240 |
$form->{printer_code} = $form->get_printer_code(\%myconfig); |
193 | 241 |
|
194 | 242 |
if ($form->{language} ne "") { |
... | ... | |
215 | 263 |
$form->{"IN"} =~ s/html$/odt/; |
216 | 264 |
} |
217 | 265 |
|
218 |
if ($form->{"send_email"} && ($form->{email} ne "")) {
|
|
266 |
if ($send_email && ($form->{email} ne "")) {
|
|
219 | 267 |
$form->{media} = 'email'; |
220 | 268 |
} |
221 | 269 |
|
... | ... | |
259 | 307 |
# connect to database |
260 | 308 |
my $dbh = $form->dbconnect($myconfig); |
261 | 309 |
|
262 |
my $where = |
|
263 |
qq| WHERE (a.paid < a.amount) |
|
264 |
AND (a.duedate < current_date) |
|
265 |
AND (dnn.id = |
|
266 |
(SELECT id FROM dunning_config |
|
267 |
WHERE dunning_level > |
|
268 |
(SELECT |
|
269 |
CASE |
|
270 |
WHEN a.dunning_config_id IS NULL |
|
271 |
THEN 0 |
|
272 |
ELSE (SELECT dunning_level |
|
273 |
FROM dunning_config |
|
274 |
WHERE id = a.dunning_config_id |
|
275 |
ORDER BY dunning_level |
|
276 |
LIMIT 1) |
|
277 |
END |
|
278 |
FROM dunning_config LIMIT 1) |
|
279 |
LIMIT 1)) |; |
|
310 |
my $where; |
|
280 | 311 |
my @values; |
281 | 312 |
|
282 | 313 |
$form->{customer_id} = $1 if ($form->{customer} =~ /--(\d+)$/); |
... | ... | |
312 | 343 |
push(@values, $form->{minamount}); |
313 | 344 |
} |
314 | 345 |
|
315 |
$paymentdate = $form->{paymentuntil} ? $dbh->quote($form->{paymentuntil}) : |
|
316 |
"current_date"; |
|
317 |
|
|
318 | 346 |
$query = |
319 |
qq|SELECT a.id, a.ordnumber, a.transdate, a.invnumber, a.amount, |
|
347 |
qq|SELECT |
|
348 |
a.id, a.ordnumber, a.transdate, a.invnumber, a.amount, |
|
320 | 349 |
ct.name AS customername, a.customer_id, a.duedate, |
321 |
da.fee AS old_fee, dnn.active, dnn.email, dnn.fee + da.fee AS fee, |
|
322 |
dn.dunning_description, da.transdate AS dunning_date, da.duedate AS dunning_duedate, |
|
323 |
a.duedate + dnn.terms - current_date AS nextlevel, |
|
324 |
$paymentdate - a.duedate AS pastdue, dn.dunning_level, |
|
325 |
current_date + dnn.payment_terms AS next_duedate, |
|
326 |
dnn.dunning_description AS next_dunning_description, dnn.id AS next_dunning_config_id, |
|
327 |
dnn.interest AS interest_rate, dnn.terms |
|
328 |
FROM dunning_config dnn, ar a |
|
329 |
JOIN customer ct ON (a.customer_id = ct.id) |
|
330 |
LEFT JOIN dunning_config dn ON (dn.id = a.dunning_config_id) |
|
331 |
LEFT JOIN dunning da ON ((da.trans_id = a.id) AND (dn.dunning_level = da.dunning_level)) |
|
350 |
|
|
351 |
cfg.dunning_description, cfg.dunning_level, |
|
352 |
|
|
353 |
d.transdate AS dunning_date, d.duedate AS dunning_duedate, |
|
354 |
d.fee, d.interest, |
|
355 |
|
|
356 |
a.duedate + cfg.terms - current_date AS nextlevel, |
|
357 |
current_date - COALESCE(d.duedate, a.duedate) AS pastdue, |
|
358 |
current_date + cfg.payment_terms AS next_duedate, |
|
359 |
|
|
360 |
nextcfg.dunning_description AS next_dunning_description, |
|
361 |
nextcfg.id AS next_dunning_config_id, |
|
362 |
nextcfg.terms, nextcfg.active, nextcfg.email |
|
363 |
|
|
364 |
FROM ar a |
|
365 |
|
|
366 |
LEFT JOIN customer ct ON (a.customer_id = ct.id) |
|
367 |
LEFT JOIN dunning_config cfg ON (a.dunning_config_id = cfg.id) |
|
368 |
LEFT JOIN dunning_config nextcfg ON |
|
369 |
(nextcfg.id = |
|
370 |
(SELECT id |
|
371 |
FROM dunning_config |
|
372 |
WHERE dunning_level > |
|
373 |
COALESCE((SELECT dunning_level |
|
374 |
FROM dunning_config |
|
375 |
WHERE id = a.dunning_config_id |
|
376 |
ORDER BY dunning_level DESC |
|
377 |
LIMIT 1), |
|
378 |
0) |
|
379 |
LIMIT 1)) |
|
380 |
LEFT JOIN dunning d ON ((d.trans_id = a.id) AND (cfg.dunning_level = d.dunning_level)) |
|
381 |
|
|
382 |
WHERE (a.paid < a.amount) |
|
383 |
AND (a.duedate < current_date) |
|
384 |
|
|
332 | 385 |
$where |
333 |
ORDER BY a.id, transdate, duedate, name|; |
|
334 | 386 |
|
387 |
ORDER BY a.id, transdate, duedate, name|; |
|
335 | 388 |
my $sth = prepare_execute_query($form, $dbh, $query, @values); |
336 | 389 |
|
337 | 390 |
$form->{DUNNINGS} = []; |
338 | 391 |
|
339 | 392 |
while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { |
340 |
$ref->{interest} = ($ref->{amount} * $ref->{pastdue} * $ref->{interest_rate}) / 360; |
|
393 |
next if !$ref->{terms} || ($ref->{pastdue} < $ref->{terms}); |
|
394 |
|
|
341 | 395 |
$ref->{interest} = $form->round_amount($ref->{interest}, 2); |
342 |
map({ $ref->{$_} = $form->format_amount($myconfig, $ref->{$_}, 2)} qw(amount fee interest)); |
|
343 |
if ($ref->{pastdue} >= $ref->{terms}) { |
|
344 |
push(@{ $form->{DUNNINGS} }, $ref); |
|
345 |
} |
|
396 |
push(@{ $form->{DUNNINGS} }, $ref); |
|
346 | 397 |
} |
347 | 398 |
|
348 | 399 |
$sth->finish; |
... | ... | |
555 | 606 |
sub print_dunning { |
556 | 607 |
$main::lxdebug->enter_sub(); |
557 | 608 |
|
558 |
my ($self, $myconfig, $form, $dunning_id, $userspath,$spool, $sendmail) = @_; |
|
609 |
my ($self, $myconfig, $form, $dunning_id, $userspath, $spool, $sendmail) = @_;
|
|
559 | 610 |
# connect to database |
560 | 611 |
my $dbh = $form->dbconnect_noauto($myconfig); |
561 | 612 |
|
... | ... | |
582 | 633 |
} |
583 | 634 |
$sth->finish; |
584 | 635 |
|
585 |
IS->customer_details($myconfig,$form); |
|
636 |
$query = |
|
637 |
qq|SELECT id AS customer_id, name, street, zipcode, city, country, department_1, department_2, email |
|
638 |
FROM customer |
|
639 |
WHERE id = |
|
640 |
(SELECT customer_id |
|
641 |
FROM dunning d |
|
642 |
LEFT JOIN ar ON (d.trans_id = ar.id) |
|
643 |
WHERE d.id = ?)|; |
|
644 |
$ref = selectfirst_hashref_query($form, $dbh, $query, $dunning_id); |
|
645 |
map { $form->{$_} = $ref->{$_} } keys %{ $ref }; |
|
646 |
|
|
647 |
$query = |
|
648 |
qq|SELECT |
|
649 |
cfg.interest_rate, cfg.template AS formname, |
|
650 |
cfg.email_subject, cfg.email_body, cfg.email_attachment, |
|
651 |
d.fee, d.dunning_date, |
|
652 |
(SELECT SUM(interest) |
|
653 |
FROM dunning |
|
654 |
WHERE dunning_id = ?) |
|
655 |
AS total_interest, |
|
656 |
(SELECT SUM(amount) - SUM(paid) |
|
657 |
FROM ar |
|
658 |
WHERE id IN |
|
659 |
(SELECT trans_id |
|
660 |
FROM dunning |
|
661 |
WHERE dunning_id = ?)) |
|
662 |
AS total_open_amount |
|
663 |
FROM dunning d |
|
664 |
LEFT JOIN dunning_config cfg ON (d.dunning_config_id = cfg.id) |
|
665 |
WHERE d.dunning_id = ? |
|
666 |
LIMIT 1|; |
|
667 |
$ref = selectfirst_hashref_query($form, $dbh, $query, $dunning_id, $dunning_id, $dunning_id); |
|
668 |
map { $form->{$_} = $ref->{$_} } keys %{ $ref }; |
|
669 |
|
|
670 |
$form->{interest_rate} = $form->format_amount($myconfig, $ref->{interest_rate} * 100); |
|
671 |
$form->{fee} = $form->format_amount($myconfig, $ref->{fee}, 2); |
|
672 |
$form->{total_interest} = $form->format_amount($myconfig, $form->round_amount($ref->{total_interest}, 2), 2); |
|
673 |
$form->{total_open_amount} = $form->format_amount($myconfig, $form->round_amount($ref->{total_open_amount}, 2), 2); |
|
674 |
$form->{total_amount} = $form->format_amount($myconfig, $form->round_amount($ref->{fee} + $ref->{total_interest} + $ref->{total_open_amount}, 2), 2); |
|
675 |
|
|
676 |
|
|
586 | 677 |
$form->{templates} = "$myconfig->{templates}"; |
587 | 678 |
|
588 | 679 |
$form->{language} = $form->get_template_language(\%myconfig); |
Auch abrufbar als: Unified diff
Große Teile des Mahncodes neu geschrieben bzw. umgeschrieben. Mehrere Fehler behoben:
1. Rechnungen, die bereits gemahnt wurden, wurden zu früh erneut zur Mahnung angeboten, weil der Mahnzeitraum auf das ursprüngliche Fälligkeitsdatum der Rechnung bezogen wurde und nicht auf das Fälligkeitsdatum der vorhergehenden Mahnstufe.
2. Wurden gleichzeitig Mahnungen für mehrere Mahnstufen generiert, so wurden die falschen Vorlagen benutzt.
3. Die kummulierten Mahnkosten und die Zinsen wurden in der Liste der neu zu erstellenden Mahnungen falsch angezeigt.
Weiterhin wurde die Dokumentation für die Vorlagenvariablen um eine Sektion über Mahnungen erweitert.