marei: tl2019 compat
[kivitendo-erp.git] / SL / Dev / Payment.pm
1 package SL::Dev::Payment;
2
3 use strict;
4 use base qw(Exporter);
5 our @EXPORT_OK = qw(create_payment_terms create_bank_account create_bank_transaction create_sepa_export create_sepa_export_item);
6 our %EXPORT_TAGS = (ALL => \@EXPORT_OK);
7
8 use SL::DB::PaymentTerm;
9 use SL::DB::BankAccount;
10 use SL::DB::Chart;
11 use DateTime;
12
13 sub create_payment_terms {
14   my (%params) = @_;
15
16   my $payment_terms =  SL::DB::PaymentTerm->new(
17     description      => 'payment',
18     description_long => 'payment',
19     terms_netto      => '30',
20     terms_skonto     => '5',
21     percent_skonto   => '0.05',
22     auto_calculation => 1,
23   );
24   $payment_terms->assign_attributes(%params) if %params;
25   $payment_terms->save;
26 }
27
28 sub create_bank_account {
29   my (%params) = @_;
30   my $bank_account = SL::DB::BankAccount->new(
31     iban           => 'DE12500105170648489890',
32     account_number => '0648489890',
33     bank           => 'Testbank',
34     chart_id       => delete $params{chart_id} // $::instance_conf->get_ar_paid_accno_id,
35     name           => 'Test bank account',
36     bic            => 'BANK1234',
37     bank_code      => '50010517'
38   );
39   $bank_account->assign_attributes(%params) if %params;
40   $bank_account->save;
41 }
42
43 sub create_sepa_export {
44   my (%params) = @_;
45   my $sepa_export = SL::DB::SepaExport->new(
46     closed       => 0,
47     employee_id  => $params{employee_id} // SL::DB::Manager::Employee->current->id,
48     executed     => 0,
49     vc           => 'customer',
50   );
51   $sepa_export->assign_attributes(%params) if %params;
52   $sepa_export->save;
53 }
54
55 sub create_sepa_export_item {
56   my (%params) = @_;
57   my $sepa_exportitem = SL::DB::SepaExportItem->new(
58     chart_id     => delete $params{chart_id} // $::instance_conf->get_ar_paid_accno_id,
59     payment_type => 'without_skonto',
60     our_bic      => 'BANK1234',
61     our_iban     => 'DE12500105170648489890',
62   );
63   $sepa_exportitem->assign_attributes(%params) if %params;
64   $sepa_exportitem->save;
65 }
66
67 sub create_bank_transaction {
68  my (%params) = @_;
69
70  my $record = delete $params{record};
71  die "bank_transactions can only be created for invoices" unless ref($record) eq 'SL::DB::Invoice' or ref($record) eq 'SL::DB::PurchaseInvoice';
72
73  my $multiplier = $record->is_sales ? 1 : -1;
74  my $amount = (delete $params{amount} || $record->amount) * $multiplier;
75
76  my $bank_chart;
77  if ( $params{bank_chart_id} ) {
78    $bank_chart = SL::DB::Manager::Chart->find_by(id => delete $params{bank_chart_id}) or die "Can't find bank chart";
79  } elsif ( $::instance_conf->get_ar_paid_accno_id ) {
80    $bank_chart   = SL::DB::Manager::Chart->find_by(id => $::instance_conf->get_ar_paid_accno_id);
81  } else {
82    $bank_chart = SL::DB::Manager::Chart->find_by(description => 'Bank') or die "Can't find bank chart";
83  }
84  my $bank_account = SL::DB::Manager::BankAccount->find_by( chart_id => $bank_chart->id );
85  die "bank account missing" unless $bank_account;
86
87  my $bt = SL::DB::BankTransaction->new(
88    local_bank_account_id => $bank_account->id,
89    remote_bank_code      => $record->customervendor->bank_code,
90    remote_account_number => $record->customervendor->account_number,
91    transdate             => DateTime->today,
92    valutadate            => DateTime->today,
93    amount                => $amount,
94    currency              => $record->currency->id,
95    remote_name           => $record->customervendor->depositor,
96    purpose               => $record->invnumber
97  );
98  $bt->assign_attributes(%params) if %params;
99  $bt->save;
100 }
101
102 1;
103
104 __END__
105
106 =head1 NAME
107
108 SL::Dev::Payment - create objects for payment-related testing, with minimal defaults
109
110 =head1 FUNCTIONS
111
112 =head2 C<create_payment_terms %PARAMS>
113
114 Create payment terms.
115
116 Minimal example with default values (30days, 5% skonto within 5 days):
117   my $payment_terms = SL::Dev::Payment::create_payment_terms;
118
119 =head2 C<create_bank_account %PARAMS>
120
121 Required params: chart_id
122
123 Example:
124   my $bank_account = SL::Dev::Payment::create_bank_account(chart_id => SL::DB::Manager::Chart->find_by(description => 'Bank')->id);
125
126 =head2 C<create_bank_transaction %PARAMS>
127
128 Create a bank transaction that matches an existing invoice record, e.g. to be able to
129 test the point system.
130
131 Required params: record  (an SL::DB::Invoice or SL::DB::PurchaseInvoice object)
132
133 Optional params: bank_chart_id : the chart id of a configured bank account
134                  amount        : the amount of the bank transaction
135
136 If no bank_chart_id is given, it tries to find a chart via defaults
137 (ar_paid_accno_id) or by searching for the chart named "Bank". The chart must
138 be connected to an existing BankAccount.
139
140 Param amount should always be relative to the absolute amount of the invoice, i.e. use positive
141 values for sales and purchases.
142
143 Example:
144   my $payment_terms = SL::Dev::Payment::create_payment_terms;
145   my $bank_chart    = SL::DB::Manager::Chart->find_by(description => 'Bank');
146   my $bank_account  = SL::Dev::Payment::create_bank_account(chart_id => $bank_chart->id);
147   my $customer      = SL::Dev::CustomerVendor::create_customer(iban           => 'DE12500105170648489890',
148                                                                bank_code      => 'abc',
149                                                                account_number => '44444',
150                                                                bank           => 'Testbank',
151                                                                bic            => 'foobar',
152                                                                depositor      => 'Name')->save;
153   my $sales_invoice = SL::Dev::Record::create_sales_invoice(customer      => $customer,
154                                                             payment_terms => $payment_terms,
155                                                            );
156   my $bt            = SL::Dev::Payment::create_bank_transaction(record        => $sales_invoice,
157                                                                 amount        => $sales_invoice->amount_less_skonto,
158                                                                 transdate     => DateTime->today->add(days => 10),
159                                                                 bank_chart_id => $bank_chart->id
160                                                                );
161   my ($agreement, $rule_matches) = $bt->get_agreement_with_invoice($sales_invoice);
162   # 14, 'remote_account_number(3) skonto_exact_amount(5) cust_vend_number_in_purpose(1) depositor_matches(2) payment_within_30_days(1) datebonus14(2)'
163
164 To create a payment for 3 invoices that were all paid together, all with skonto:
165   my $ar1 = SL::DB::Manager::Invoice->find_by(invnumber=>'20');
166   my $ar2 = SL::DB::Manager::Invoice->find_by(invnumber=>'21');
167   my $ar3 = SL::DB::Manager::Invoice->find_by(invnumber=>'22');
168   SL::Dev::Payment::create_bank_transaction(record  => $ar1
169                                             amount  => ($ar1->amount_less_skonto + $ar2->amount_less_skonto + $ar2->amount_less_skonto),
170                                             purpose => 'Rechnungen 20, 21, 22',
171                                            );
172
173 =head1 TODO
174
175 Nothing here yet.
176
177 =head1 BUGS
178
179 Nothing here yet.
180
181 =head1 AUTHOR
182
183 G. Richardson E<lt>grichardson@kivitendo-premium.deE<gt>
184
185 =cut