Revision dba850b0
Von Kivitendo Admin vor mehr als 8 Jahren hinzugefügt
t/shop/shop.t | ||
---|---|---|
1 |
use strict; |
|
2 |
use Test::More; |
|
3 |
|
|
4 |
use lib 't'; |
|
5 |
use Support::TestSetup; |
|
6 |
use Carp; |
|
7 |
use Test::Exception; |
|
8 |
use Data::Dumper; |
|
9 |
use SL::DB::Shop; |
|
10 |
use SL::DB::Part; |
|
11 |
use SL::DB::Order; |
|
12 |
use SL::DB::OrderItem; |
|
13 |
use SL::DB::ShopPart; |
|
14 |
use SL::DB::Pricegroup; |
|
15 |
use SL::DB::Price; |
|
16 |
use SL::DB::ShopOrderItem; |
|
17 |
use SL::DB::ShopOrder; |
|
18 |
use SL::Shop; |
|
19 |
use SL::ShopConnector::ALL; |
|
20 |
use Rose::DB::Object::Helpers qw(clone_and_reset); |
|
21 |
use List::Util qw(sum); |
|
22 |
use DateTime; |
|
23 |
|
|
24 |
# use SL::DBUtils; |
|
25 |
|
|
26 |
use utf8; |
|
27 |
|
|
28 |
Support::TestSetup::login(); |
|
29 |
|
|
30 |
clear_up(); |
|
31 |
|
|
32 |
my $VERBOSE = 0; |
|
33 |
my $DEBUG = 0; |
|
34 |
|
|
35 |
# initialise data: |
|
36 |
my $pricegroup_a = SL::DB::Pricegroup->new(pricegroup => "typ a")->save; |
|
37 |
my $pricegroup_b = SL::DB::Pricegroup->new(pricegroup => "typ b")->save; |
|
38 |
my $pricegroup_c = SL::DB::Pricegroup->new(pricegroup => "typ c")->save; |
|
39 |
|
|
40 |
# all parts and shop_parts will be updated with roughly this mtime due to trigger |
|
41 |
my $reference_time = DateTime->now; |
|
42 |
|
|
43 |
# all parts are created a day earlier |
|
44 |
my $part_itime = $reference_time->clone->subtract(days => 1); |
|
45 |
|
|
46 |
my $buchungsgruppe = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 19%'); |
|
47 |
my $unit = SL::DB::Manager::Unit->find_by(name => 'Stck'); |
|
48 |
my $part = SL::DB::Part->new( |
|
49 |
partnumber => 'T4254', |
|
50 |
description => 'Fourty-two fifty-four', |
|
51 |
lastcost => 1.93, |
|
52 |
sellprice => 2.34, |
|
53 |
buchungsgruppen_id => $buchungsgruppe->id, |
|
54 |
unit => $unit->name, |
|
55 |
shop => 1, |
|
56 |
itime => $part_itime, |
|
57 |
)->save; |
|
58 |
|
|
59 |
my $part2 = $part->clone_and_reset; |
|
60 |
$part2->description("part 2"); |
|
61 |
$part2->save; |
|
62 |
|
|
63 |
my $baseprice1 = "12.34"; |
|
64 |
my $baseprice2 = "3.33"; |
|
65 |
foreach my $pg ( $pricegroup_a, $pricegroup_b, $pricegroup_c ) { |
|
66 |
SL::DB::Price->new( parts_id => $part->id, pricegroup => $pg, price => $baseprice1)->save; |
|
67 |
SL::DB::Price->new( parts_id => $part2->id, pricegroup => $pg, price => $baseprice2)->save; |
|
68 |
$baseprice1 += 1; |
|
69 |
$baseprice2 += 1; |
|
70 |
}; |
|
71 |
# foreach my $p ( $part, $part2 ) { |
|
72 |
# foreach ( $p->prices ) { |
|
73 |
# printf("%s: %s ( %s ) \n", $_->pricegroup->pricegroup, $_->price, $p->displayable_name); |
|
74 |
# }; |
|
75 |
# }; |
|
76 |
|
|
77 |
|
|
78 |
my $employee = SL::DB::Manager::Employee->current; |
|
79 |
my $taxzone = SL::DB::Manager::TaxZone->find_by( description => 'Inland') || croak "No taxzone"; |
|
80 |
my $currency_id = $::instance_conf->get_currency_id; |
|
81 |
my $customer = SL::DB::Customer->new( |
|
82 |
name => 'Flintstone', |
|
83 |
currency_id => $currency_id, |
|
84 |
taxzone_id => $taxzone->id, |
|
85 |
email => 'fred@flintstone.org', |
|
86 |
zipcode => '12345', |
|
87 |
)->save; |
|
88 |
|
|
89 |
my @pricesources = qw(sellprice lastcost listprice); |
|
90 |
push(@pricesources, map { $_->id } @{ SL::DB::Manager::Pricegroup->get_all }); |
|
91 |
|
|
92 |
my $config1 = SL::DB::Shop->new( description => 'TestShop', |
|
93 |
connector => 'xtcommerce', |
|
94 |
pricetype => 'netto', |
|
95 |
url => 'http://localhost', |
|
96 |
port => '3000', |
|
97 |
login => 'foo', |
|
98 |
password => 'bar', |
|
99 |
obsolete => 0, |
|
100 |
)->save; |
|
101 |
my $config2 = SL::DB::Shop->new( description => 'TestShop 2', |
|
102 |
connector => 'xtcommerce', |
|
103 |
pricetype => 'brutto', |
|
104 |
url => 'http://localhost', |
|
105 |
port => '3000', |
|
106 |
login => 'foo', |
|
107 |
password => 'bar', |
|
108 |
obsolete => 0, |
|
109 |
)->save; |
|
110 |
|
|
111 |
my $shop = SL::Shop->new( config => $config1 ); |
|
112 |
my $shop2 = SL::Shop->new( config => $config2 ); |
|
113 |
my $result = $shop->connector->get_order('1'); |
|
114 |
my $new_orders = $shop->connector->get_new_orders; |
|
115 |
|
|
116 |
# printf("order %s has amount %s\n", $result->{ordnumber}, $result->{amount}); |
|
117 |
|
|
118 |
is( $config1->connector, 'xtcommerce', 'created shop object'); |
|
119 |
is( $shop->config->connector, 'xtcommerce', 'created SL::Shop'); |
|
120 |
is( $result->{amount}, '12.34' , 'fetched amount for order 1234'); |
|
121 |
is( $shop->connector->url, "http://localhost:3000", 'connector url'); |
|
122 |
is( scalar keys %{ $new_orders } , 2, '2 new orders'); |
|
123 |
|
|
124 |
my $active_shops = SL::DB::Manager::Shop->get_all(query => [ obsolete => 0 ]); |
|
125 |
foreach my $shop_config ( @{ $active_shops } ) { |
|
126 |
my $shop = SL::Shop->new( config => $shop_config ); |
|
127 |
my $new_orders = $shop->connector->get_new_orders; |
|
128 |
# printf("Shop \"%s\" has %s new orders\n", $shop->config->description, scalar keys %{ $new_orders }); |
|
129 |
}; |
|
130 |
|
|
131 |
# create some orders for shop $shop |
|
132 |
my %shop_customer_fred = ( customer_firstname => 'Fred', |
|
133 |
customer_lastname => 'Flintstone', |
|
134 |
customer_email => 'fred@flintstones.org', |
|
135 |
customer_zipcode => '12345', |
|
136 |
); |
|
137 |
my %shop_customer_barney = ( customer_firstname => 'Barney', |
|
138 |
customer_lastname => 'Rubble', |
|
139 |
customer_email => 'b.rubble@boulder.org', |
|
140 |
customer_zipcode => '12345', |
|
141 |
); |
|
142 |
|
|
143 |
# create ShopOrders, 9 Freds and 1 Barney |
|
144 |
foreach my $i ( 1 .. 10 ) { |
|
145 |
my $so = SL::DB::ShopOrder->new( shop_ordernumber => $i, |
|
146 |
shop_trans_id => $i, |
|
147 |
shop_customer_number => 15, |
|
148 |
host => $shop->config->description, |
|
149 |
order_date => DateTime->today_local, |
|
150 |
$i == 5 ? %shop_customer_barney : %shop_customer_fred, |
|
151 |
); |
|
152 |
my $soi = SL::DB::ShopOrderItem->new( partnumber => $part->partnumber, |
|
153 |
price => (12.34 + $i), |
|
154 |
quantity => '2', |
|
155 |
shop_trans_id => $i, |
|
156 |
description => $part->description, |
|
157 |
); |
|
158 |
$so->add_shop_order_items($soi); |
|
159 |
$so->amount( $soi->price * $soi->quantity ); |
|
160 |
$so->save; |
|
161 |
}; |
|
162 |
|
|
163 |
my $shoporder = SL::DB::Manager::ShopOrder->get_first(); |
|
164 |
|
|
165 |
my $order = $shoporder->convert_to_sales_order(customer => $customer, employee => $employee); |
|
166 |
$order->save; |
|
167 |
is( $order->amount, $shoporder->amount, 'Shoporder and converted oe have same amount'); |
|
168 |
|
|
169 |
my $dt2 = $reference_time->clone->add(hours => 1); #->add(years => 1); |
|
170 |
|
|
171 |
my $s1p1 = SL::DB::ShopPart->new( part => $part, |
|
172 |
shop => $config1, |
|
173 |
shop_description => 'marketing speak for part 1 in shop 1', |
|
174 |
last_update => $reference_time, |
|
175 |
active => 1, |
|
176 |
itime => $part_itime, |
|
177 |
)->save; |
|
178 |
|
|
179 |
my $s1p2 = SL::DB::ShopPart->new( part => $part2, |
|
180 |
shop => $config1, |
|
181 |
shop_description => 'marketing speak for part 2 in shop 1', |
|
182 |
itime => $part_itime, |
|
183 |
)->save; |
|
184 |
|
|
185 |
my $s2p1 = SL::DB::ShopPart->new( part => $part, |
|
186 |
shop => $config2, |
|
187 |
last_update => $dt2, |
|
188 |
shop_description => 'marketing speak for part 1 shop 2', |
|
189 |
itime => $part_itime, |
|
190 |
)->save; |
|
191 |
|
|
192 |
my $number_of_active_shops = $part->find_shop_parts( { active => 1 } ); |
|
193 |
# my $number_of_active_shops = $part->find_shop_parts( { shop_id => $config1->id, active => 1 } ); |
|
194 |
is( scalar @{ $number_of_active_shops } , 1, 'part 1 is active in 1 shop'); |
|
195 |
|
|
196 |
is( scalar @{ $part2->find_shop_parts( { active => 1 } ) }, 0, 'part2 isn\'t active in any shop'); |
|
197 |
|
|
198 |
my $shop_parts = $part->shop_parts; |
|
199 |
is( scalar @{ $part->shop_parts } , 2, 'part 1 appears in 2 shops'); |
|
200 |
|
|
201 |
is( scalar @{ $shop->config->shop_parts } , 2, 'shop 1 has 2 parts'); |
|
202 |
|
|
203 |
my $active_shop_parts = $shop->config->find_shop_parts( { active => 1 } ); |
|
204 |
is( scalar @{ $active_shop_parts } , 1, 'shop 1 has 1 active part'); |
|
205 |
|
|
206 |
is( scalar @{ $shop2->config->shop_parts } , 1, 'shop 2 has 1 part'); |
|
207 |
|
|
208 |
$active_shop_parts = $shop2->config->find_shop_parts( { active => 1 } ); |
|
209 |
is( scalar @{ $active_shop_parts } , 0, 'shop 2 has no active parts'); |
|
210 |
|
|
211 |
# debug_on(); |
|
212 |
# set part1 active in shop2 |
|
213 |
# because of constraint there can only be one match |
|
214 |
my ($shop_part) = $part->find_shop_parts( { shop_id => $shop2->config->id } ); |
|
215 |
$shop_part->active(1); |
|
216 |
$shop_part->save(changes_only =>1); |
|
217 |
$shop_part->load; |
|
218 |
|
|
219 |
diag("activated part " . $shop_part->part->displayable_name . " in shop " . $shop_part->shop->description); |
|
220 |
# print "shop_part was last changed: " . $shop_part->mtime . "\n"; |
|
221 |
|
|
222 |
$active_shop_parts = $shop2->config->find_shop_parts( { active => 1 } ); |
|
223 |
is( scalar @{ $active_shop_parts } , 1, 'shop 2 now has 1 active part'); |
|
224 |
|
|
225 |
# debug_on(); |
|
226 |
# 1 hour after first part: only s1p1 |
|
227 |
my $dt_now = $reference_time->clone->subtract(hours => 1); #->add(years => 1); |
|
228 |
my $updatable_parts = $shop->updatable_parts($dt_now); |
|
229 |
diag("parts to be updated at " . $dt_now . " :"); |
|
230 |
foreach ( @{$updatable_parts} ) { |
|
231 |
diag(sprintf(" %s: %s\n", $_->shop->description, $_->part->displayable_name)); |
|
232 |
# print ". last update: " . $dt_now . "\n"; |
|
233 |
# print " part itime : " . $_->part->itime . "\n"; |
|
234 |
# print " part mtime : " . $_->part->mtime . "\n"; |
|
235 |
# print " shop_part itime: " . $_->itime . "\n"; |
|
236 |
# print " shop_part mtime: " . $_->mtime . "\n"; |
|
237 |
}; |
|
238 |
# 3 hours after first part: s1p1 and s2p1 |
|
239 |
$dt_now = $reference_time->clone->add(hours => 3); #->add(years => 1); |
|
240 |
$updatable_parts = $shop->updatable_parts($dt_now); |
|
241 |
diag("parts to be updated at " . $dt_now . " :"); |
|
242 |
foreach ( @{$updatable_parts} ) { |
|
243 |
diag(sprintf(" %s: %s\n", $_->shop->description, $_->part->displayable_name)); |
|
244 |
# print " last update: " . $dt_now . "\n"; |
|
245 |
# print " part itime : " . $_->part->itime . "\n"; |
|
246 |
# print " part mtime : " . $_->part->mtime . "\n"; |
|
247 |
# print " shop_part itime: " . $_->itime . "\n"; |
|
248 |
# print " shop_part mtime: " . $_->mtime . "\n"; |
|
249 |
}; |
|
250 |
# debug_off(); |
|
251 |
|
|
252 |
done_testing; |
|
253 |
|
|
254 |
# disable final clear_up while developing |
|
255 |
# done_testing(21); |
|
256 |
# clear_up(); |
|
257 |
|
|
258 |
sub clear_up { |
|
259 |
# remove all transactions after test has run |
|
260 |
SL::DB::Manager::Price->delete_all ( all => 1) ; |
|
261 |
SL::DB::Manager::Pricegroup->delete_all ( all => 1) ; |
|
262 |
SL::DB::Manager::OrderItem->delete_all ( all => 1) ; |
|
263 |
SL::DB::Manager::Order->delete_all ( all => 1) ; |
|
264 |
SL::DB::Manager::ShopPart->delete_all ( all => 1) ; |
|
265 |
SL::DB::Manager::Part->delete_all ( all => 1) ; |
|
266 |
SL::DB::Manager::ShopOrderItem->delete_all ( all => 1) ; |
|
267 |
SL::DB::Manager::ShopOrder->delete_all ( all => 1) ; |
|
268 |
SL::DB::Manager::Customer->delete_all ( all => 1) ; |
|
269 |
SL::DB::Manager::Shop->delete_all ( all => 1) ; |
|
270 |
}; |
|
271 |
|
|
272 |
sub debug_on { |
|
273 |
return unless $DEBUG; |
|
274 |
$Rose::DB::Object::Debug = 1; |
|
275 |
$Rose::DB::Object::Manager::Debug = 1; |
|
276 |
}; |
|
277 |
sub debug_off { |
|
278 |
$Rose::DB::Object::Debug = 0; |
|
279 |
$Rose::DB::Object::Manager::Debug = 0; |
|
280 |
}; |
|
281 |
|
|
282 |
1; |
Auch abrufbar als: Unified diff
Shop - Testcase