10 use Support::TestSetup;
13 use SL::DB::Buchungsgruppe;
19 use SL::DB::DeliveryOrder;
23 my ($customer, $currency_id, $buchungsgruppe, $employee, $vendor);
24 my ($link, $links, $o1, $o2, $d, $i);
29 $params{$_} ||= {} for qw(buchungsgruppe unit customer part tax);
31 SL::DB::Manager::DeliveryOrder->delete_all(all => 1);
32 SL::DB::Manager::Order->delete_all(all => 1);
33 SL::DB::Manager::Invoice->delete_all(all => 1);
34 SL::DB::Manager::Customer->delete_all(all => 1);
35 SL::DB::Manager::Vendor->delete_all(all => 1);
37 $buchungsgruppe = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 19%', %{ $params{buchungsgruppe} }) || croak "No accounting group";
38 $employee = SL::DB::Manager::Employee->current || croak "No employee";
40 $currency_id = $::instance_conf->get_currency_id;
42 $customer = SL::DB::Customer->new(
43 name => 'Test Customer',
44 currency_id => $currency_id,
45 %{ $params{customer} }
48 $vendor = SL::DB::Vendor->new(
49 name => 'Test Vendor',
50 currency_id => $currency_id,
58 return SL::DB::Order->new(
59 customer_id => $customer->id,
60 currency_id => $currency_id,
61 employee_id => $employee->id,
62 salesman_id => $employee->id,
69 sub new_delivery_order {
72 return SL::DB::DeliveryOrder->new(
73 customer_id => $customer->id,
74 currency_id => $currency_id,
75 employee_id => $employee->id,
76 salesman_id => $employee->id,
85 return SL::DB::Invoice->new(
86 customer_id => $customer->id,
87 currency_id => $currency_id,
88 employee_id => $employee->id,
89 salesman_id => $employee->id,
90 gldate => DateTime->today_local->to_kivitendo,
98 Support::TestSetup::login();
106 $link = $o1->link_to_record($i);
109 is ref $link, 'SL::DB::RecordLink', 'link_to_record returns new link';
110 is $link->from_table, 'oe', 'from_table';
111 is $link->from_id, $o1->id, 'from_id';
112 is $link->to_table, 'ar', 'to_table';
113 is $link->to_id, $i->id, 'to_id';
116 $links = $o1->linked_records(direction => 'to', to => 'Invoice');
117 is $links->[0]->id, $i->id, 'direct retrieve 1';
119 $links = $o1->linked_records(direction => 'to', to => 'SL::DB::Invoice');
120 is $links->[0]->id, $i->id, 'direct retrieve 2 (with SL::DB::)';
122 $links = $o1->linked_records(direction => 'to', to => [ 'Invoice', 'Order' ]);
123 is $links->[0]->id, $i->id, 'direct retrieve 3 (array target)';
125 $links = $o1->linked_records(direction => 'both', both => 'Invoice');
126 is $links->[0]->id, $i->id, 'direct retrieve 4 (direction both)';
128 $links = $i->linked_records(direction => 'from', from => 'Order');
129 is $links->[0]->id, $o1->id, 'direct retrieve 4 (direction from)';
131 # what happens if we delete a linked record?
134 $links = $i->linked_records(direction => 'from', from => 'Order');
135 is @$links, 0, 'no dangling link after delete';
137 # can we distinguish between types?
138 $o1 = new_order(quotation => 1);
140 $o1->link_to_record($o2);
142 $links = $o2->linked_records(direction => 'from', from => 'Order', query => [ quotation => 1 ]);
143 is $links->[0]->id, $o1->id, 'query restricted retrieve 1';
145 $links = $o2->linked_records(direction => 'from', from => 'Order', query => [ quotation => 0 ]);
146 is @$links, 0, 'query restricted retrieve 2';
148 # try bidirectional linking
151 $o1->link_to_record($o2, bidirectional => 1);
153 $links = $o1->linked_records(direction => 'to', to => 'Order');
154 is $links->[0]->id, $o2->id, 'bidi 1';
155 $links = $o1->linked_records(direction => 'from', from => 'Order');
156 is $links->[0]->id, $o2->id, 'bidi 2';
157 $links = $o1->linked_records(direction => 'both', both => 'Order');
158 is $links->[0]->id, $o2->id, 'bidi 3';
160 # funky stuff with both
162 $d = new_delivery_order();
165 $o2->link_to_record($d);
166 $d->link_to_record($i);
169 $links = $d->linked_records(direction => 'both', to => 'Invoice', from => 'Order', sort_by => 'customer_id', sort_dir => 1);
170 is $links->[0]->id, $o2->id, 'both with different from/to 1';
171 is $links->[1]->id, $i->id, 'both with different from/to 2';
173 # what happens if we double link?
175 $o2->link_to_record($d);
177 $links = $o2->linked_records(direction => 'to', to => 'DeliveryOrder');
178 is @$links, 1, 'double link is only added once 1';
180 $d->link_to_record($o2, bidirectional => 1);
182 $links = $o2->linked_records(direction => 'to', to => 'DeliveryOrder');
183 is @$links, 1, 'double link is only added once 2';
185 # doc states that to/from ae optional. test that
186 $links = $o2->linked_records(direction => 'both');
187 is @$links, 2, 'links without from/to get all';
189 # doc says there will be special values set... lets see
190 $links = $o1->linked_records(direction => 'to', to => 'Order');
191 is $links->[0]->{_record_link_direction}, 'to', '_record_link_direction to';
192 is $links->[0]->{_record_link}->to_id, $o2->id, '_record_link to';
194 $links = $o1->linked_records(direction => 'from', from => 'Order');
195 is $links->[0]->{_record_link_direction}, 'from', '_record_link_direction from';
196 is $links->[0]->{_record_link}->to_id, $o1->id, '_record_link from';
198 # check if bidi returns an array of links
199 { local $TODO = 'does not work as advertised';
200 my @links = $d->link_to_record($o2, bidirectional => 1);
201 is @links, 2, 'bidi returns array of links in array context';
205 $links = $o2->linked_records(direction => 'to', to => 'Invoice', via => 'DeliveryOrder');
206 is $links->[0]->id, $i->id, 'simple case via links (string)';
208 $links = $o2->linked_records(direction => 'to', to => 'Invoice', via => [ 'DeliveryOrder' ]);
209 is $links->[0]->id, $i->id, 'simple case via links (arrayref)';
211 $links = $o1->linked_records(direction => 'to', to => 'Invoice', via => [ 'Order', 'DeliveryOrder' ]);
212 is $links->[0]->id, $i->id, 'simple case via links (2 hops)';
214 # multiple links in the same direction from one object
215 $o1->link_to_record($d);
216 $links = $o2->linked_records(direction => 'to', to => 'Invoice', via => 'DeliveryOrder');
217 is $links->[0]->id, $i->id, 'simple case via links (string)';
219 # at this point the structure is:
221 # o1 <--> o2 ---> d ---> i
225 # o1 must have 2 linked records now:
226 $links = $o1->linked_records(direction => 'to');
227 is @$links, 2, 'more than one link';
229 # as a special funny case, o1 via Order, Order will now yield o2, because it bounces back over itself
230 { local $TODO = 'no idea if this is desired';
231 $links = $o2->linked_records(direction => 'to', to => 'Order', via => [ 'Order', 'Order' ]);
232 is @$links, 2, 'via links with bidirectional hop over starting object';
235 # for sorting, get all don't bother with the links, we'll just take our records
236 my @records = ($o2, $i, $o1, $d);
238 $sorted = SL::DB::Helper::LinkedRecords->sort_linked_records('type', 1, @records);
239 is_deeply $sorted, [$o1, $o2, $d, $i], 'sorting by type';
240 $sorted = SL::DB::Helper::LinkedRecords->sort_linked_records('type', 0, @records);
241 is_deeply $sorted, [$i, $d, $o2, $o1], 'sorting by type desc';
248 $sorted = SL::DB::Helper::LinkedRecords->sort_linked_records('number', 1, @records);
249 is_deeply $sorted, [$d, $o1, $i, $o2], 'sorting by number';
250 $sorted = SL::DB::Helper::LinkedRecords->sort_linked_records('number', 0, @records);
251 is_deeply $sorted, [$o2, $i, $o1, $d], 'sorting by number desc';
253 # again with natural sorting
255 $o1->ordnumber("a3");
257 $o2->ordnumber("a10");
259 $sorted = SL::DB::Helper::LinkedRecords->sort_linked_records('number', 1, @records);
260 is_deeply $sorted, [$d, $o1, $i, $o2], 'sorting naturally by number';
261 $sorted = SL::DB::Helper::LinkedRecords->sort_linked_records('number', 0, @records);
262 is_deeply $sorted, [$o2, $i, $o1, $d], 'sorting naturally by number desc';
264 $o2->transdate(DateTime->new(year => 2010, month => 3, day => 1));
265 $i->transdate(DateTime->new(year => 2014, month => 3, day => 19));
266 $o1->transdate(DateTime->new(year => 2014, month => 5, day => 1));
267 $d->transdate(DateTime->new(year => 2014, month => 5, day => 2));
269 # transdate should be used before itime
270 $sorted = SL::DB::Helper::LinkedRecords->sort_linked_records('date', 1, @records);
271 is_deeply $sorted, [$o2, $i, $o1, $d], 'sorting by transdate';
272 $sorted = SL::DB::Helper::LinkedRecords->sort_linked_records('date', 0, @records);
273 is_deeply $sorted, [$d, $o1, $i, $o2], 'sorting by transdate desc';