Revision ba68038e
Von Kivitendo Admin vor fast 8 Jahren hinzugefügt
SL/DB/Helper/Payment.pm | ||
---|---|---|
29 | 29 |
my $is_sales = ref($self) eq 'SL::DB::Invoice'; |
30 | 30 |
my $mult = $is_sales ? 1 : -1; # multiplier for getting the right sign depending on ar/ap |
31 | 31 |
|
32 |
my $paid_amount = 0; # the amount that will be later added to $self->paid |
|
32 |
my $paid_amount = 0; # the amount that will be later added to $self->paid, should be in default currency
|
|
33 | 33 |
|
34 | 34 |
# default values if not set |
35 | 35 |
$params{payment_type} = 'without_skonto' unless $params{payment_type}; |
... | ... | |
38 | 38 |
# check for required parameters |
39 | 39 |
Common::check_params(\%params, qw(chart_id transdate)); |
40 | 40 |
|
41 |
my $transdate_obj = $::locale->parse_date_to_object($params{transdate}); |
|
41 |
my $transdate_obj; |
|
42 |
if (ref($params{transdate} eq 'DateTime')) { |
|
43 |
print "found transdate ref\n"; sleep 2; |
|
44 |
$transdate_obj = $params{transdate}; |
|
45 |
} else { |
|
46 |
$transdate_obj = $::locale->parse_date_to_object($params{transdate}); |
|
47 |
}; |
|
42 | 48 |
croak t8('Illegal date') unless ref $transdate_obj; |
43 | 49 |
|
44 | 50 |
# check for closed period |
... | ... | |
52 | 58 |
croak t8('Cannot post transaction above the maximum future booking date!') if $transdate_obj > DateTime->now->add( days => $::instance_conf->get_max_future_booking_interval ); |
53 | 59 |
}; |
54 | 60 |
|
61 |
# currency is either passed or use the invoice currency if it differs from the default currency |
|
62 |
my ($exchangerate,$currency); |
|
63 |
if ($params{currency} || $params{currency_id} || $self->currency_id != $::instance_conf->get_currency_id) { |
|
64 |
if ($params{currency} || $params{currency_id} ) { # currency was specified |
|
65 |
$currency = SL::DB::Manager::Currency->find_by(name => $params{currency}) || SL::DB::Manager::Currency->find_by(id => $params{currency_id}); |
|
66 |
} else { # use invoice currency |
|
67 |
$currency = SL::DB::Manager::Currency->find_by(id => $self->currency_id); |
|
68 |
}; |
|
69 |
die "no currency" unless $currency; |
|
70 |
if ($currency->id == $::instance_conf->get_currency_id) { |
|
71 |
$exchangerate = 1; |
|
72 |
} else { |
|
73 |
my $rate = SL::DB::Manager::Exchangerate->find_by(currency_id => $currency->id, |
|
74 |
transdate => $transdate_obj, |
|
75 |
); |
|
76 |
if ($rate) { |
|
77 |
$exchangerate = $is_sales ? $rate->buy : $rate->sell; |
|
78 |
} else { |
|
79 |
die "No exchange rate for " . $transdate_obj->to_kivitendo; |
|
80 |
}; |
|
81 |
}; |
|
82 |
} else { # no currency param given or currency is the same as default_currency |
|
83 |
$exchangerate = 1; |
|
84 |
}; |
|
85 |
|
|
55 | 86 |
# input checks: |
56 | 87 |
if ( $params{'payment_type'} eq 'without_skonto' ) { |
57 | 88 |
croak "invalid amount for payment_type 'without_skonto': $params{'amount'}\n" unless abs($params{'amount'}) > 0; |
... | ... | |
83 | 114 |
my $memo = $params{'memo'} || ''; |
84 | 115 |
my $source = $params{'source'} || ''; |
85 | 116 |
|
86 |
my $rounded_params_amount = _round( $params{amount} ); |
|
117 |
my $rounded_params_amount = _round( $params{amount} ); # / $exchangerate);
|
|
87 | 118 |
|
88 | 119 |
my $db = $self->db; |
89 | 120 |
$db->do_transaction(sub { |
... | ... | |
107 | 138 |
$pay_amount = $self->amount_less_skonto if $params{payment_type} eq 'with_skonto_pt'; |
108 | 139 |
|
109 | 140 |
# bank account and AR/AP |
110 |
$paid_amount += $pay_amount; |
|
141 |
$paid_amount += $pay_amount * $exchangerate; |
|
142 |
|
|
143 |
my $amount = (-1 * $pay_amount) * $mult; |
|
144 |
|
|
111 | 145 |
|
112 | 146 |
# total amount against bank, do we already know this by now? |
113 | 147 |
$new_acc_trans = SL::DB::AccTransaction->new(trans_id => $self->id, |
114 | 148 |
chart_id => $account_bank->id, |
115 | 149 |
chart_link => $account_bank->link, |
116 |
amount => (-1 * $pay_amount) * $mult,
|
|
150 |
amount => $amount,
|
|
117 | 151 |
transdate => $transdate_obj, |
118 | 152 |
source => $source, |
119 | 153 |
memo => $memo, |
120 | 154 |
taxkey => 0, |
121 | 155 |
tax_id => SL::DB::Manager::Tax->find_by(taxkey => 0)->id); |
122 | 156 |
$new_acc_trans->save; |
157 |
|
|
158 |
# deal with fxtransaction |
|
159 |
if ( $self->currency_id != $::instance_conf->get_currency_id ) { |
|
160 |
my $fxamount = _round($amount - ($amount * $exchangerate)); |
|
161 |
# print "amount: $amount, fxamount = $fxamount\n"; |
|
162 |
# print "amount - (amount * exchangerate) = " . $amount . " - (" . $amount . " - " . $exchangerate . ")\n"; |
|
163 |
$new_acc_trans = SL::DB::AccTransaction->new(trans_id => $self->id, |
|
164 |
chart_id => $account_bank->id, |
|
165 |
chart_link => $account_bank->link, |
|
166 |
amount => $fxamount * -1, |
|
167 |
transdate => $transdate_obj, |
|
168 |
source => $source, |
|
169 |
memo => $memo, |
|
170 |
taxkey => 0, |
|
171 |
fx_transaction => 1, |
|
172 |
tax_id => SL::DB::Manager::Tax->find_by(taxkey => 0)->id); |
|
173 |
$new_acc_trans->save; |
|
174 |
}; |
|
123 | 175 |
}; |
124 | 176 |
|
125 | 177 |
if ( $params{payment_type} eq 'difference_as_skonto' or $params{payment_type} eq 'with_skonto_pt' ) { |
... | ... | |
148 | 200 |
my $amount = -1 * $skonto_booking->{skonto_amount}; |
149 | 201 |
$new_acc_trans = SL::DB::AccTransaction->new(trans_id => $self->id, |
150 | 202 |
chart_id => $skonto_booking->{'chart_id'}, |
151 |
chart_link => SL::DB::Manager::Chart->find_by(id => $skonto_booking->{'chart_id'})->{'link'},
|
|
203 |
chart_link => SL::DB::Manager::Chart->find_by(id => $skonto_booking->{'chart_id'})->link,
|
|
152 | 204 |
amount => $amount * $mult, |
153 | 205 |
transdate => $transdate_obj, |
154 | 206 |
source => $params{source}, |
... | ... | |
159 | 211 |
$new_acc_trans->save; |
160 | 212 |
|
161 | 213 |
$reference_amount -= abs($amount); |
162 |
$paid_amount += -1 * $amount; |
|
214 |
$paid_amount += -1 * $amount * $exchangerate;
|
|
163 | 215 |
$skonto_amount_check -= $skonto_booking->{'skonto_amount'}; |
164 | 216 |
}; |
165 | 217 |
if ( $params{payment_type} eq 'difference_as_skonto' ) { |
... | ... | |
186 | 238 |
my $arap_booking= SL::DB::AccTransaction->new(trans_id => $self->id, |
187 | 239 |
chart_id => $reference_account->id, |
188 | 240 |
chart_link => $reference_account->link, |
189 |
amount => $arap_amount * $mult,
|
|
241 |
amount => _round($arap_amount * $mult * $exchangerate),
|
|
190 | 242 |
transdate => $transdate_obj, |
191 | 243 |
source => '', #$params{source}, |
192 | 244 |
taxkey => 0, |
193 | 245 |
tax_id => SL::DB::Manager::Tax->find_by(taxkey => 0)->id); |
194 | 246 |
$arap_booking->save; |
195 | 247 |
|
196 |
$self->paid($self->paid+$paid_amount) if $paid_amount;
|
|
248 |
$self->paid($self->paid + _round($paid_amount)) if $paid_amount;
|
|
197 | 249 |
$self->datepaid($transdate_obj); |
198 | 250 |
$self->save; |
199 | 251 |
|
... | ... | |
386 | 438 |
# my $transactions = $self->transactions; |
387 | 439 |
foreach my $transaction (@{ $self->transactions }) { |
388 | 440 |
# find all transactions with an AR_amount or AP_amount link |
389 |
my $tax = SL::DB::Manager::Tax->get_first( where => [taxkey => $transaction->{taxkey}]);
|
|
441 |
my $tax = SL::DB::Manager::Tax->get_first( where => [taxkey => $transaction->taxkey]);
|
|
390 | 442 |
croak "no tax for taxkey " . $transaction->{taxkey} unless ref $tax; |
391 | 443 |
|
392 |
$transaction->{chartlinks} = { map { $_ => 1 } split(m/:/, $transaction->{chart_link}) };
|
|
444 |
$transaction->{chartlinks} = { map { $_ => 1 } split(m/:/, $transaction->chart_link) };
|
|
393 | 445 |
if ( $is_sales && $transaction->{chartlinks}->{AR_amount} ) { |
394 | 446 |
$skonto_configured = 0 unless $tax->skonto_sales_chart_id; |
395 | 447 |
} elsif ( !$is_sales && $transaction->{chartlinks}->{AP_amount}) { |
... | ... | |
717 | 769 |
payment_type => 'with_skonto', |
718 | 770 |
); |
719 | 771 |
|
772 |
or in a certain currency: |
|
773 |
$ap->pay_invoice(chart_id => $bank->chart_id, |
|
774 |
amount => 500, |
|
775 |
currency => 'USD', |
|
776 |
transdate => DateTime->now->to_kivitendo, |
|
777 |
memo => 'foobar', |
|
778 |
source => 'barfoo', |
|
779 |
payment_type => 'with_skonto', |
|
780 |
); |
|
781 |
|
|
720 | 782 |
Allowed payment types are: |
721 | 783 |
without_skonto with_skonto_pt difference_as_skonto |
722 | 784 |
|
... | ... | |
768 | 830 |
|
769 | 831 |
Skonto doesn't/shouldn't apply if the invoice contains credited items. |
770 | 832 |
|
833 |
If no amount is given the whole open amout is paid. |
|
834 |
|
|
835 |
If neither currency or currency_id are given as params, the currency of the |
|
836 |
invoice is assumed to be the payment currency. |
|
837 |
|
|
771 | 838 |
=item C<reference_account> |
772 | 839 |
|
773 | 840 |
Returns a chart object which is the chart of the invoice with link AR or AP. |
Auch abrufbar als: Unified diff
Paymenthelper kann Fremdwährung mit Steuer inkl. und exkl.