DeliveryOrder um convert_invoice erweitert
[kivitendo-erp.git] / t / db_helper / convert_invoice.t
1 use Test::More tests => 29;
2
3 use strict;
4
5 use lib 't';
6 use utf8;
7
8 use Support::TestSetup;
9
10 use Carp;
11 use Data::Dumper;
12 use Support::TestSetup;
13 use Test::Exception;
14 use List::Util qw(max);
15
16 use SL::DB::Buchungsgruppe;
17 use SL::DB::Currency;
18 use SL::DB::Customer;
19 use SL::DB::Employee;
20 use SL::DB::Invoice;
21 use SL::DB::Order;
22 use SL::DB::DeliveryOrder;
23 use SL::DB::Part;
24 use SL::DB::Unit;
25 use SL::DB::TaxZone;
26
27 my ($customer, $currency_id, $buchungsgruppe, $employee, $vendor, $taxzone, $buchungsgruppe7, $tax, $tax7,
28     $unit, @parts);
29
30 sub clear_up {
31   foreach (qw(DeliveryOrderItem DeliveryOrder InvoiceItem Invoice Part Customer Vendor Employee Department PaymentTerm)) {
32     "SL::DB::Manager::${_}"->delete_all(all => 1);
33   }
34 };
35
36 sub reset_state {
37   my %params = @_;
38
39   clear_up();
40
41   $buchungsgruppe   = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 19%', %{ $params{buchungsgruppe} }) || croak "No accounting group 19\%";
42   $buchungsgruppe7  = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 7%', %{ $params{buchungsgruppe} })  || croak "No accounting group 7\%";
43   $taxzone          = SL::DB::Manager::TaxZone->find_by( description => 'Inland')                                           || croak "No taxzone";
44   $tax              = SL::DB::Manager::Tax->find_by(taxkey => 3, rate => 0.19, %{ $params{tax} })                           || croak "No tax for 19\%";
45   $tax7             = SL::DB::Manager::Tax->find_by(taxkey => 2, rate => 0.07)                                              || croak "No tax for 7\%";
46   $unit             = SL::DB::Manager::Unit->find_by(name => 'kg', %{ $params{unit} })                                      || croak "No unit";
47   $currency_id     = $::instance_conf->get_currency_id;
48
49   $customer     = SL::DB::Customer->new(
50     name        => '520484567dfaedc9e60fc',
51     currency_id => $currency_id,
52     taxzone_id  => $taxzone->id,
53     %{ $params{customer} }
54   )->save;
55
56   # some od.rnr real anonym data
57   my $employee_bk = SL::DB::Employee->new(
58                 'id' => 31915,
59                 'login' => 'barbuschka.kappes',
60                 'name' => 'Barbuschka Kappes',
61   )->save;
62
63   my $department_do = SL::DB::Department->new(
64                  'description' => 'Maisenhaus-Versand',
65                  'id' => 32149,
66                  'itime' => undef,
67                  'mtime' => undef
68   )->save;
69
70   my $payment_do = SL::DB::PaymentTerm->new(
71                  'description' => '14Tage 2%Skonto, 30Tage netto',
72                  'description_long' => "Innerhalb von 14 Tagen abzüglich 2 % Skonto, innerhalb von 30 Tagen rein netto.|Bei einer Zahlung bis zum <%skonto_date%> gewähren wir 2 % Skonto (EUR <%skonto_amount%>) entspricht EUR <%total_wo_skonto%>.Bei einer Zahlung bis zum <%netto_date%> ist der fällige Betrag in Höhe von <%total%> <%currency%> zu überweisen.",
73                  'id' => 11276,
74                  'itime' => undef,
75                  'mtime' => undef,
76                  'percent_skonto' => '0.02',
77                  'ranking' => undef,
78                  'sortkey' => 4,
79                  'terms_netto' => 30,
80                  'auto_calculation' => undef,
81                  'terms_skonto' => 14
82   )->save;
83
84   # two real parts
85   @parts = ();
86   push @parts, SL::DB::Part->new(
87                  'id' => 26321,
88                  'image' => '',
89                  'lastcost' => '49.95000',
90                  'listprice' => '0.00000',
91                  'onhand' => '5.00000',
92                  'partnumber' => 'v-519160549',
93                  #'partsgroup_id' => 111645,
94                  'rop' => '0',
95                  'sellprice' => '242.20000',
96                  #'warehouse_id' => 64702,
97                  'weight' => '0.79',
98                  description        => "Nussbaum, Gr.5, Unterfilz weinrot, genietet[[Aufschnittbreite: 11,0, Kernform: US]]\"" ,
99                  buchungsgruppen_id => $buchungsgruppe->id,
100                  unit               => $unit->name,
101                  id                 => 26321,
102   )->save;
103
104   push @parts, SL::DB::Part->new(
105                  'description' => "[[0640]]Flügel Hammerstiele bestehend aus:
106 70 Stielen Standard in Weißbuche und
107 20 Stielen Diskant abgekehlt in Weißbuche
108 mit Röllchen aus Synthetikleder,
109 Kapseln mit Yamaha Profil, Kerbenabstand 3,6 mm mit eingedrehten Abnickschrauben",
110                  'id' => 25505,
111                  'lastcost' => '153.00000',
112                  'listprice' => '0.00000',
113                  'onhand' => '9.00000',
114                  'partnumber' => 'v-120160086',
115                  # 'partsgroup_id' => 111639,
116                  'rop' => '0',
117                  'sellprice' => '344.30000',
118                  'weight' => '0.9',
119                   buchungsgruppen_id => $buchungsgruppe->id,
120                   unit               => $unit->name,
121   )->save;
122 }
123
124 sub new_delivery_order {
125   my %params  = @_;
126
127   return SL::DB::DeliveryOrder->new(
128    currency_id => $currency_id,
129    taxzone_id  => $taxzone->id,
130     %params,
131   )->save;
132 }
133
134 Support::TestSetup::login();
135
136 reset_state();
137
138 # we create L20199 with two items
139 my $do1 = new_delivery_order('department_id'    => 32149,
140                              'donumber'         => 'L20199',
141                              'employee_id'      => 31915,
142                              'intnotes'         => 'Achtung: Neue Lieferadresse ab 16.02.2015 in der Carl-von-Ossietzky-Str.32!   13.02.2015/MH
143
144                                             Steinway-Produkte (201...) immer plus 25% dazu rechnen / BK 13.02.2014',
145                               'ordnumber'       => 'A16399',
146                               'payment_id'      => 11276,
147                               'salesman_id'     => 31915,
148                               'shippingpoint'   => 'Maisenhaus',
149                               # 'shipto_id'     => 451463,
150                               'is_sales'        => 'true',
151                               'shipvia'         => 'DHL, Versand am 06.03.2015, 1 Paket  17,00 kg',
152                               'taxzone_id'      => 4,
153                               'closed'          => undef,
154                               # 'currency_id'   => 1,
155                               'cusordnumber'    => 'b84da',
156                               'customer_id'     => $customer->id,
157                               'id'              => 464003,
158 );
159
160 my $do1_item1 = SL::DB::DeliveryOrderItem->new('delivery_order_id' => 464003,
161                                                'description' => "Flügel Hammerkopf bestehend aus:
162                                                                  Bass/Diskant 26/65 Stück, Gesamtlänge 80/72, Bohrlänge 56/48
163                                                                  Nussbaum, Gr.5, Unterfilz weinrot, genietet[[Aufschnittbreite: 11,0, Kernform: US]]",
164                                                'discount' => '0.25',
165                                                'id' => 144736,
166                                                'lastcost' => '49.95000',
167                                                'longdescription' => '',
168                                                'marge_price_factor' => 1,
169                                                'mtime' => undef,
170                                                'ordnumber' => 'A16399',
171                                                'parts_id' => 26321,
172                                                'position' => 1,
173                                                'price_factor' => 1,
174                                                'qty' => '2.00000',
175                                                'sellprice' => '242.20000',
176                                                'transdate' => '06.03.2015',
177                                                'unit' => 'kg')->save;
178
179 my $do1_item2 = SL::DB::DeliveryOrderItem->new('delivery_order_id' => 464003,
180                  'description' => "[[0640]]Flügel Hammerstiele bestehend aus:
181 70 Stielen Standard in Weißbuche und
182 20 Stielen Diskant abgekehlt in Weißbuche
183 mit Röllchen aus Synthetikleder,
184 Kapseln mit Yamaha Profil, Kerbenabstand 3,6 mm mit eingedrehten Abnickschrauben",
185                  'discount' => '0.25',
186                  'id' => 144737,
187                  'itime' => undef,
188                  'lastcost' => '153.00000',
189                  'longdescription' => '',
190                  'marge_price_factor' => 1,
191                  'mtime' => undef,
192                  'ordnumber' => 'A16399',
193                  'parts_id' => 25505,
194                  'position' => 2,
195                  'price_factor' => 1,
196                  'price_factor_id' => undef,
197                  'pricegroup_id' => undef,
198                  'project_id' => undef,
199                  'qty' => '3.00000',
200                  'reqdate' => undef,
201                  'sellprice' => '344.30000',
202                  'serialnumber' => '',
203                  'transdate' => '06.03.2015',
204                  'unit' => 'kg')->save;
205
206 # TESTS
207
208
209 # test delivery order before any conversion
210 ok($do1->donumber eq "L20199", 'Delivery Order Number created');
211 ok((not $do1->closed) , 'Delivery Order is not closed');
212 ok($do1_item1->parts_id eq '26321', 'doi linked with part');
213 ok($do1_item1->qty == 2, 'qty check doi');
214 ok($do1_item2->position == 2, 'doi2 position check');
215 ok(2 ==  scalar@{ SL::DB::Manager::DeliveryOrderItem->get_all(where => [ delivery_order_id => $do1->id ]) }, 'two doi linked');
216
217
218 # convert this do to invoice
219 my $invoice = $do1->convert_to_invoice();
220
221 # test invoice afterwards
222
223 ok ($invoice->shipvia eq "DHL, Versand am 06.03.2015, 1 Paket  17,00 kg", "ship via check");
224 ok ($invoice->shippingpoint eq "Maisenhaus", "shipping point check");
225 ok ($invoice->ordnumber eq "A16399", "ordnumber check");
226 ok ($invoice->donumber eq "L20199", "donumber check");
227 ok(($do1->closed) , 'Delivery Order is closed after conversion');
228 ok (SL::DB::PaymentTerm->new(id => $invoice->{payment_id})->load->description eq "14Tage 2%Skonto, 30Tage netto", 'payment term description check');
229
230 # some test data from original client invoice console (!)
231 # my $invoice3 = SL::DB::Manager::Invoice->find_by( ordnumber => 'A16399' );
232 # which will fail due to PTC Calculation differs from GUI-Calculation, see issue: http://redmine.kivitendo-premium.de/issues/82
233 # pp $invoice3
234 # values from gui should be:
235 #ok($invoice->amount == 1354.20000, 'amount check');
236 #ok($invoice->marge_percent == 50.88666, 'marge percent check');
237 #ok($invoice->marge_total == 579.08000, 'marge total check');
238 #ok($invoice->netamount == 1137.98000, 'netamount check');
239
240
241 # the values change if one reloads the object
242 # without reloading we get this failures
243 #not ok 17 - amount check
244 #   Failed test 'amount check'
245 #   at t/db_helper/convert_invoice.t line 272.
246 #          got: '1354.17'
247 #     expected: '1354.17000'
248 #not ok 18 - marge percent check
249 #   Failed test 'marge percent check'
250 #   at t/db_helper/convert_invoice.t line 273.
251 #          got: '50.8857956342929'
252 #     expected: '50.88580'
253 #not ok 19 - marge total check
254 #   Failed test 'marge total check'
255 #   at t/db_helper/convert_invoice.t line 274.
256 #          got: '579.06'
257 #     expected: '579.06000'
258 #not ok 20 - netamount check
259 #   Failed test 'netamount check'
260 #   at t/db_helper/convert_invoice.t line 275.
261 #          got: '1137.96'
262 #     expected: '1137.96000'
263
264 $invoice->load;
265
266 ok($invoice->currency_id eq '1', 'currency_id');
267 ok($invoice->cusordnumber eq 'b84da', 'cusordnumber check');
268 ok(SL::DB::Department->new(id => $invoice->{department_id})->load->description eq "Maisenhaus-Versand", 'department description');
269 is($invoice->amount, '1354.17000', 'amount check');
270 is($invoice->marge_percent, '50.88580', 'marge percent check');
271 is($invoice->marge_total, '579.06000', 'marge total check');
272 is($invoice->netamount, '1137.96000', 'netamount check');
273
274 # some item checks
275 ok(@ {$invoice->items_sorted}[0]->parts_id eq '26321', 'invoiceitem 1 linked with part');
276 ok(2 ==  scalar@{ $invoice->invoiceitems }, 'two invoice items linked with invoice');
277 is(@ {$invoice->items_sorted}[0]->position, 1, "position 1 order correct");
278 is(@ {$invoice->items_sorted}[1]->position, 2, "position 2 order correct");
279 is(@ {$invoice->items_sorted}[0]->part->partnumber, 'v-519160549', "partnumber 1 correct");
280 is(@ {$invoice->items_sorted}[1]->part->partnumber, 'v-120160086', "partnumber 2 correct");
281 is(@ {$invoice->items_sorted}[0]->qty, '2.00000', "pos 1 qty");
282 is(@ {$invoice->items_sorted}[1]->qty, '3.00000', "pos 2 qty");
283 is(@ {$invoice->items_sorted}[0]->discount, 0.25, "pos 1 discount");
284 is(@ {$invoice->items_sorted}[1]->discount, 0.25, "pos 2 discount");
285
286 # more ideas: check onhand, lastcost (parsed lastcost)
287
288 clear_up();
289
290 1;