Consolidation and extended test runs
[kivitendo-erp.git] / t / controllers / financial_overview / sales_orders.t
1 package DateTime;
2
3 use SL::Helper::DateTime;
4
5 no warnings 'redefine';
6
7 sub now_local {
8   return shift->new(time_zone => $::locale->get_local_time_zone, year => 2014, month => 3, day => 15, hour => 12, minute => 23, second => 34);
9 }
10
11 sub today_local {
12   return shift->now_local->truncate(to => 'day');
13 }
14
15 package main;
16
17 use Test::More tests => 49;
18
19 use lib 't';
20 use strict;
21 use utf8;
22
23 use Carp;
24 use Support::TestSetup;
25
26 use_ok 'SL::BackgroundJob::CreatePeriodicInvoices';
27 use_ok 'SL::Controller::FinancialOverview';
28 use_ok 'SL::DB::Chart';
29 use_ok 'SL::DB::Customer';
30 use_ok 'SL::DB::Default';
31 use_ok 'SL::DB::Invoice';
32 use_ok 'SL::DB::Order';
33 use_ok 'SL::DB::Part';
34 use_ok 'SL::DB::TaxZone';
35
36 Support::TestSetup::login();
37
38 our ($ar_chart, $buchungsgruppe, $ctrl, $currency_id, $customer, $employee, $order, $part, $tax_zone, $unit, @invoices);
39
40 sub clear_up {
41   "SL::DB::Manager::${_}"->delete_all(all => 1) for qw(InvoiceItem Invoice OrderItem Order Customer Part);
42 };
43
44 sub init_common_state {
45   if ($::lx_office_conf{system}->{default_manager} eq "swiss") {
46     $ar_chart       = SL::DB::Manager::Chart->find_by(accno => '3200')                        || croak "No AR chart";
47     $buchungsgruppe = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 8%')  || croak "No accounting group";
48     $currency_id    = SL::DB::Default->get->currency_id;
49     $employee       = SL::DB::Manager::Employee->current                                      || croak "No employee";
50     $tax_zone       = SL::DB::Manager::TaxZone->find_by( description => 'Schweiz')            || croak "No taxzone";
51     $unit           = SL::DB::Manager::Unit->find_by(name => 'pauschal')                      || croak "No unit";
52   } else {
53     $ar_chart       = SL::DB::Manager::Chart->find_by(accno => '1400')                        || croak "No AR chart";
54     $buchungsgruppe = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 19%') || croak "No accounting group";
55     $currency_id    = SL::DB::Default->get->currency_id;
56     $employee       = SL::DB::Manager::Employee->current                                      || croak "No employee";
57     $tax_zone       = SL::DB::Manager::TaxZone->find_by( description => 'Inland')             || croak "No taxzone";
58     $unit           = SL::DB::Manager::Unit->find_by(name => 'psch')                          || croak "No unit";
59   }
60 }
61
62 sub create_sales_order {
63   my %params = @_;
64
65   $params{$_} ||= {} for qw(customer part tax order orderitem);
66
67   # Clean up: remove invoices, orders, parts and customers
68   clear_up();
69
70   $customer     = SL::DB::Customer->new(
71     name        => 'Test Customer',
72     currency_id => $currency_id,
73     taxzone_id  => $tax_zone->id,
74     %{ $params{customer} }
75   )->save;
76
77   $part = SL::DB::Part->new(
78     partnumber         => 'T4254',
79     description        => 'Fourty-two fifty-four',
80     lastcost           => 222.22,
81     sellprice          => 333.33,
82     buchungsgruppen_id => $buchungsgruppe->id,
83     unit               => $unit->name,
84     %{ $params{part} }
85   )->save;
86   $part->load;
87
88   $order                     = SL::DB::Order->new(
89     customer_id              => $customer->id,
90     currency_id              => $currency_id,
91     taxzone_id               => $tax_zone->id,
92     transaction_description  => '<%period_start_date%>',
93     transdate                => DateTime->from_kivitendo('01.03.2014'),
94     orderitems               => [
95       { parts_id             => $part->id,
96         description          => $part->description,
97         lastcost             => $part->lastcost,
98         sellprice            => $part->sellprice,
99         qty                  => 1,
100         unit                 => $unit->name,
101         %{ $params{orderitem} },
102       },
103     ],
104     periodic_invoices_config => $params{periodic_invoices_config} ? {
105       active                 => 1,
106       ar_chart_id            => $ar_chart->id,
107       %{ $params{periodic_invoices_config} },
108     } : undef,
109     %{ $params{order} },
110   );
111
112   $order->calculate_prices_and_taxes;
113
114   ok($order->save(cascade => 1));
115
116   $::form         = Form->new('');
117   $::form->{year} = 2014;
118   $ctrl           = SL::Controller::FinancialOverview->new;
119
120   $ctrl->get_objects;
121   $ctrl->calculate_one_time_data;
122   $ctrl->calculate_periodic_invoices;
123 }
124
125 init_common_state();
126
127 # ----------------------------------------------------------------------
128 # An order without periodic invoices:
129 create_sales_order();
130
131 is_deeply($ctrl->data->{$_}, { months => [ (0) x 12 ], quarters => [ 0, 0, 0, 0 ], year => 0 }, "no periodic invoices, data for $_")
132   for qw(purchase_invoices purchase_orders requests_for_quotation sales_invoices sales_quotations);
133
134 is_deeply($ctrl->data->{$_}, { months => [ 0, 0, 333.33, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], quarters => [ 333.33, 0, 0, 0 ], year => 333.33 }, "no periodic invoices, data for $_")
135   for qw(sales_orders sales_orders_per_inv);
136
137 # ----------------------------------------------------------------------
138 # order_value_periodicity=y, periodicity=q
139 create_sales_order(
140   periodic_invoices_config  => {
141     periodicity             => 'm',
142     order_value_periodicity => 'y',
143     start_date              => DateTime->from_kivitendo('01.05.2014'),
144   });
145
146 is_deeply($ctrl->data->{$_}, { months => [ (0) x 12 ], quarters => [ 0, 0, 0, 0 ], year => 0 }, "periodic conf p=m ovp=y, no invoices, data for $_")
147   for qw(purchase_invoices purchase_orders requests_for_quotation sales_invoices sales_quotations);
148
149 is_deeply($ctrl->data->{sales_orders},
150           { months => [ 0, 0, 0, 0, 27.7775, 27.7775, 27.7775, 27.7775, 27.7775, 27.7775, 27.7775, 27.7775 ], quarters => [ 0, 55.555, 83.3325, 83.3325 ], year => 222.22 },
151           "periodic conf p=m ovp=y, no invoices, data for sales_orders");
152 is_deeply($ctrl->data->{sales_orders_per_inv},
153           { months => [ 0, 0, 333.33, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], quarters => [ 333.33, 0, 0, 0 ], year => 333.33 },
154           "periodic conf p=m ovp=y, no invoices, data for sales_orders_per_inv");
155
156 # ----------------------------------------------------------------------
157 # order_value_periodicity=y, periodicity=q, starting in previous year
158 create_sales_order(
159   order                     => {
160     transdate               => DateTime->from_kivitendo('01.03.2013'),
161   },
162   periodic_invoices_config  => {
163     periodicity             => 'q',
164     order_value_periodicity => 'y',
165     start_date              => DateTime->from_kivitendo('01.05.2013'),
166   });
167
168 is_deeply($ctrl->data->{$_}, { months => [ (0) x 12 ], quarters => [ 0, 0, 0, 0 ], year => 0 }, "periodic conf p=q ovp=y, no invoices, starting previous year, data for $_")
169   for qw(purchase_invoices purchase_orders requests_for_quotation sales_invoices sales_quotations);
170
171 is_deeply($ctrl->data->{sales_orders},
172           { months => [ 0, 83.3325, 0, 0, 83.3325, 0, 0, 83.3325, 0, 0, 83.3325, 0 ], quarters => [ 83.3325, 83.3325, 83.3325, 83.3325 ], year => 333.33 },
173           "periodic conf p=q ovp=y, no invoices, starting previous year, data for sales_orders");
174 is_deeply($ctrl->data->{sales_orders_per_inv},
175           { months => [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], quarters => [ 0, 0, 0, 0 ], year => 0 },
176           "periodic conf p=q ovp=y, no invoices, starting previous year, data for sales_orders_per_inv");
177
178 # ----------------------------------------------------------------------
179 # order_value_periodicity=y, periodicity=q, starting in previous year, ending middle of year
180 create_sales_order(
181   order                     => {
182     transdate               => DateTime->from_kivitendo('01.03.2013'),
183   },
184   periodic_invoices_config  => {
185     periodicity             => 'q',
186     order_value_periodicity => 'y',
187     start_date              => DateTime->from_kivitendo('01.05.2013'),
188     end_date                => DateTime->from_kivitendo('01.09.2014'),
189     terminated              => 1,
190   });
191
192 is_deeply($ctrl->data->{$_}, { months => [ (0) x 12 ], quarters => [ 0, 0, 0, 0 ], year => 0 }, "periodic conf p=q ovp=y, no invoices, starting previous year, ending middle of year, data for $_")
193   for qw(purchase_invoices purchase_orders requests_for_quotation sales_invoices sales_quotations);
194
195 is_deeply($ctrl->data->{sales_orders},
196           { months => [ 0, 83.3325, 0, 0, 83.3325, 0, 0, 83.3325, 0, 0, 0, 0 ], quarters => [ 83.3325, 83.3325, 83.3325, 0 ], year => 249.9975 },
197           "periodic conf p=q ovp=y, no invoices, starting previous year, ending middle of year, data for sales_orders");
198 is_deeply($ctrl->data->{sales_orders_per_inv},
199           { months => [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], quarters => [ 0, 0, 0, 0 ], year => 0 },
200           "periodic conf p=q ovp=y, no invoices, starting previous year, ending middle of year, data for sales_orders_per_inv");
201
202 # ----------------------------------------------------------------------
203 # order_value_periodicity=y, periodicity=q, starting and ending before current
204 create_sales_order(
205   order                     => {
206     transdate               => DateTime->from_kivitendo('01.03.2012'),
207   },
208   periodic_invoices_config  => {
209     periodicity             => 'q',
210     order_value_periodicity => 'y',
211     start_date              => DateTime->from_kivitendo('01.05.2012'),
212     end_date                => DateTime->from_kivitendo('01.09.2013'),
213     terminated              => 1,
214   });
215
216 is_deeply($ctrl->data->{$_}, { months => [ (0) x 12 ], quarters => [ 0, 0, 0, 0 ], year => 0 }, "periodic conf p=q ovp=y, no invoices, starting and ending before current year, data for $_")
217   for qw(purchase_invoices purchase_orders requests_for_quotation sales_invoices sales_orders sales_orders_per_inv sales_quotations);
218
219 clear_up();
220
221 done_testing();