Revision 07b6482f
Von Werner Hahn vor etwa 7 Jahren hinzugefügt
SL/Controller/ShopOrder.pm | ||
---|---|---|
106 | 106 |
my $customer = SL::DB::Manager::Customer->find_by(id => $::form->{customer}); |
107 | 107 |
die "Can't find customer" unless $customer; |
108 | 108 |
my $employee = SL::DB::Manager::Employee->current; |
109 |
die "Can't find employee" unless $employee; |
|
109 | 110 |
|
110 | 111 |
die "Can't load shop_order form form->import_id" unless $self->shop_order; |
111 |
|
|
112 | 112 |
my $order = $self->shop_order->convert_to_sales_order(customer => $customer, employee => $employee); |
113 | 113 |
$order->calculate_prices_and_taxes; |
114 | 114 |
|
... | ... | |
135 | 135 |
|
136 | 136 |
$self->shop_order->transferred(1); |
137 | 137 |
$self->shop_order->transfer_date(DateTime->now_local); |
138 |
$self->shop_order->oe_transid($order->id); |
|
139 | 138 |
$self->shop_order->save; |
140 | 139 |
$self->shop_order->link_to_record($order); |
141 |
$self->redirect_to(controller => "oe.pl", action => 'edit', type => 'sales_order', vc => 'customer', id => $order->id); |
|
142 | 140 |
}) || die $order->db->error; |
141 |
$self->redirect_to(controller => "oe.pl", action => 'edit', type => 'sales_order', vc => 'customer', id => $order->id); |
|
143 | 142 |
} |
144 | 143 |
} |
145 | 144 |
|
SL/Dev/ALL.pm | ||
---|---|---|
12 | 12 |
|
13 | 13 |
sub import { |
14 | 14 |
no strict "refs"; |
15 |
for (qw(Part CustomerVendor Inventory Record Payment)) { |
|
15 |
for (qw(Part CustomerVendor Inventory Record Payment Shop)) {
|
|
16 | 16 |
Exporter::export_to_level("SL::Dev::$_", 1, @_); |
17 | 17 |
} |
18 | 18 |
} |
SL/Dev/Shop.pm | ||
---|---|---|
2 | 2 |
|
3 | 3 |
use strict; |
4 | 4 |
use base qw(Exporter); |
5 |
our @EXPORT = qw(create_shop create_shop_part create_shop_order); |
|
5 |
use Data::Dumper; |
|
6 |
our @EXPORT_OK = qw(new_shop new_shop_part new_shop_order); |
|
7 |
our %EXPORT_TAGS = (ALL => \@EXPORT_OK); |
|
6 | 8 |
|
7 | 9 |
use SL::DB::Shop; |
8 | 10 |
|
9 |
sub create_shop {
|
|
11 |
sub new_shop {
|
|
10 | 12 |
my (%params) = @_; |
11 | 13 |
|
12 | 14 |
my $shop = SL::DB::Shop->new( |
13 |
description => 'testshop', |
|
15 |
description => delete $params{description} || 'testshop',
|
|
14 | 16 |
%params |
15 | 17 |
); |
16 | 18 |
return $shop; |
17 | 19 |
} |
18 | 20 |
|
19 |
sub create_shop_part {
|
|
21 |
sub new_shop_part {
|
|
20 | 22 |
my (%params) = @_; |
21 | 23 |
|
22 | 24 |
my $part = delete $params{part}; |
... | ... | |
30 | 32 |
return $shop_part; |
31 | 33 |
} |
32 | 34 |
|
33 |
sub create_shop_order {
|
|
35 |
sub new_shop_order {
|
|
34 | 36 |
my (%params) = @_; |
35 | 37 |
|
36 | 38 |
my $shop_order = SL::DB::ShopOrder->new( |
SL/ShopConnector/Shopware.pm | ||
---|---|---|
4 | 4 |
|
5 | 5 |
use parent qw(SL::ShopConnector::Base); |
6 | 6 |
|
7 |
use SL::DBUtils; |
|
7 |
|
|
8 | 8 |
use SL::JSON; |
9 | 9 |
use LWP::UserAgent; |
10 | 10 |
use LWP::Authen::Digest; |
... | ... | |
42 | 42 |
my $data_json = $data->content; |
43 | 43 |
my $import = SL::JSON::decode_json($data_json); |
44 | 44 |
|
45 |
my $shop_order = $self->map_data_to_shoporder($import); |
|
46 |
|
|
47 |
$shop_order->save; |
|
48 |
$of ++; |
|
49 |
my $id = $shop_order->id; |
|
50 |
|
|
51 |
my @positions = sort { Sort::Naturally::ncmp($a->{"partnumber"}, $b->{"partnumber"}) } @{ $import->{data}->{details} }; |
|
52 |
my $position = 1; |
|
53 |
foreach my $pos(@positions) { |
|
54 |
my $price = $::form->round_amount($pos->{price},2); |
|
55 |
|
|
56 |
my %pos_columns = ( description => $pos->{articleName}, |
|
57 |
partnumber => $pos->{articleNumber}, |
|
58 |
price => $price, |
|
59 |
quantity => $pos->{quantity}, |
|
60 |
position => $position, |
|
61 |
tax_rate => $pos->{taxRate}, |
|
62 |
shop_trans_id => $pos->{articleId}, |
|
63 |
shop_order_id => $id, |
|
64 |
active_price_source => $self->config->price_source, |
|
65 |
); |
|
66 |
my $pos_insert = SL::DB::ShopOrderItem->new(%pos_columns); |
|
67 |
$pos_insert->save; |
|
68 |
$position++; |
|
69 |
} |
|
70 |
$shop_order->{positions} = $position-1; |
|
71 |
my $customer = $shop_order->get_customer; |
|
72 |
if(ref($customer)){ |
|
73 |
$shop_order->kivi_customer_id($customer->id); |
|
74 |
$shop_order->save; |
|
75 |
} |
|
76 |
|
|
77 |
my $attributes->{last_order_number} = $ordnumber; |
|
78 |
$self->config->assign_attributes( %{ $attributes } ); |
|
45 |
$self->import_data_to_shop_order($import); |
|
46 |
|
|
47 |
$self->config->assign_attributes( last_order_number => $ordnumber); |
|
79 | 48 |
$self->config->save; |
80 | 49 |
$ordnumber++; |
50 |
$of++; |
|
81 | 51 |
} |
82 | 52 |
} |
83 | 53 |
my $shop = $self->config->description; |
... | ... | |
85 | 55 |
return \%fetched_orders; |
86 | 56 |
} |
87 | 57 |
|
58 |
sub import_data_to_shop_order { |
|
59 |
my ( $self, $import ) = @_; |
|
60 |
my $shop_order = $self->map_data_to_shoporder($import); |
|
61 |
|
|
62 |
$shop_order->save; |
|
63 |
my $id = $shop_order->id; |
|
64 |
|
|
65 |
my @positions = sort { Sort::Naturally::ncmp($a->{"partnumber"}, $b->{"partnumber"}) } @{ $import->{data}->{details} }; |
|
66 |
my $position = 1; |
|
67 |
my $active_price_source = $self->config->price_source; |
|
68 |
foreach my $pos(@positions) { |
|
69 |
my $price = $::form->round_amount($pos->{price},2); |
|
70 |
my %pos_columns = ( description => $pos->{articleName}, |
|
71 |
partnumber => $pos->{articleNumber}, |
|
72 |
price => $price, |
|
73 |
quantity => $pos->{quantity}, |
|
74 |
position => $position, |
|
75 |
tax_rate => $pos->{taxRate}, |
|
76 |
shop_trans_id => $pos->{articleId}, |
|
77 |
shop_order_id => $id, |
|
78 |
active_price_source => $active_price_source, |
|
79 |
); |
|
80 |
my $pos_insert = SL::DB::ShopOrderItem->new(%pos_columns); |
|
81 |
$pos_insert->save; |
|
82 |
$position++; |
|
83 |
} |
|
84 |
$shop_order->{positions} = $position-1; |
|
85 |
|
|
86 |
my $customer = $shop_order->get_customer; |
|
87 |
if(ref($customer)){ |
|
88 |
$shop_order->kivi_customer_id($customer->id); |
|
89 |
$shop_order->save; |
|
90 |
} |
|
91 |
} |
|
92 |
|
|
88 | 93 |
sub map_data_to_shoporder { |
89 | 94 |
my ($self, $import) = @_; |
95 |
|
|
90 | 96 |
my $parser = DateTime::Format::Strptime->new( pattern => '%Y-%m-%dT%H:%M:%S', |
91 | 97 |
locale => 'de_DE', |
92 | 98 |
time_zone => 'local' |
93 | 99 |
); |
94 | 100 |
my $orderdate = $parser->parse_datetime($import->{data}->{orderTime}); |
101 |
|
|
102 |
my $shop_id = $self->config->id; |
|
103 |
my $tax_included = $self->config->pricetype; |
|
95 | 104 |
# Mapping to table shoporders. See http://community.shopware.com/_detail_1690.html#GET_.28Liste.29 |
96 | 105 |
my %columns = ( |
97 | 106 |
amount => $import->{data}->{invoiceAmount}, |
... | ... | |
152 | 161 |
shop_customer_id => $import->{data}->{customerId}, |
153 | 162 |
shop_customer_number => $import->{data}->{billing}->{number}, |
154 | 163 |
shop_customer_comment => $import->{data}->{customerComment}, |
155 |
shop_id => $self->config->id,
|
|
164 |
shop_id => $shop_id,
|
|
156 | 165 |
shop_ordernumber => $import->{data}->{number}, |
157 | 166 |
shop_trans_id => $import->{data}->{id}, |
158 |
tax_included => $self->config->pricetype eq "brutto" ? 1 : 0,
|
|
167 |
tax_included => $tax_included eq "brutto" ? 1 : 0,
|
|
159 | 168 |
); |
169 |
|
|
160 | 170 |
my $shop_order = SL::DB::ShopOrder->new(%columns); |
161 | 171 |
return $shop_order; |
162 | 172 |
} |
... | ... | |
358 | 368 |
|
359 | 369 |
=head1 NAME |
360 | 370 |
|
361 |
SL::Shopconnecter::Shopware - connector for shopware 5
|
|
371 |
SL::Shopconnecter::Shopware - connector for shopware 5 |
|
362 | 372 |
|
363 | 373 |
=head1 SYNOPSIS |
364 | 374 |
|
365 | 375 |
|
366 | 376 |
=head1 DESCRIPTION |
367 | 377 |
|
378 |
=head1 METHODS |
|
379 |
|
|
380 |
=back 4 |
|
381 |
|
|
382 |
=item C<import_data_to_shop_order> |
|
383 |
|
|
384 |
Creates on shoporder object from json |
|
385 |
|
|
368 | 386 |
=head1 TODO |
369 | 387 |
|
370 |
Pricesrules, pricessources aren't fully implemented yet.
|
|
371 |
Payments aren't implemented( need to map payments from Shopware like invoice, paypal etc. to payments in kivitendo)
|
|
388 |
Pricesrules, pricessources aren't fully implemented yet. |
|
389 |
Payments aren't implemented( need to map payments from Shopware like invoice, paypal etc. to payments in kivitendo) |
|
372 | 390 |
|
373 | 391 |
=head1 BUGS |
374 | 392 |
|
375 |
None yet. :)
|
|
393 |
None yet. :) |
|
376 | 394 |
|
377 | 395 |
=head1 AUTHOR |
378 | 396 |
|
379 |
W. Hahn E<lt>wh@futureworldsearch.netE<gt>
|
|
397 |
W. Hahn E<lt>wh@futureworldsearch.netE<gt> |
|
380 | 398 |
|
381 | 399 |
=cut |
t/shop/shop_order.t | ||
---|---|---|
9 | 9 |
use SL::DB::Shop; |
10 | 10 |
use SL::DB::ShopOrder; |
11 | 11 |
use SL::DB::ShopOrderItem; |
12 |
use SL::Controller::ShopOrder; |
|
12 | 13 |
use Data::Dumper; |
13 | 14 |
|
14 | 15 |
my ($shop, $shop_order, $shop_part, $part, $customer, $employee); |
... | ... | |
18 | 19 |
|
19 | 20 |
clear_up(); |
20 | 21 |
|
21 |
$shop = SL::Dev::Shop::create_shop->save;
|
|
22 |
$shop = SL::Dev::Shop::new_shop->save;
|
|
22 | 23 |
$part = SL::Dev::Part::new_part->save; |
23 |
$shop_part = SL::Dev::Shop::create_shop_part(part => $part, shop => $shop)->save;
|
|
24 |
$shop_part = SL::Dev::Shop::new_shop_part(part => $part, shop => $shop)->save;
|
|
24 | 25 |
|
25 | 26 |
$employee = SL::DB::Manager::Employee->current || croak "No employee"; |
26 | 27 |
|
... | ... | |
32 | 33 |
)->save; |
33 | 34 |
} |
34 | 35 |
|
36 |
sub save_shorcontroller_to_string { |
|
37 |
|
|
38 |
my $output; |
|
39 |
open(my $outputFH, '<', \$output) or die "OUTPUT"; |
|
40 |
my $oldFH = select $outputFH; |
|
41 |
my $shor_controller = SL::Controller::ShopOrder->new; |
|
42 |
$shor_controller->action_transfer; |
|
43 |
|
|
44 |
select $oldFH; |
|
45 |
close $outputFH; |
|
46 |
return $output; |
|
47 |
} |
|
48 |
sub test_transfer { |
|
49 |
my ( %params ) = @_; |
|
50 |
$::form = Support::TestSetup->create_new_form; |
|
51 |
$::form->{import_id} = $params{import_id}; |
|
52 |
$::form->{customer} = $params{customer}; |
|
53 |
my $test_name = 'Test Controller Action Transfer'; |
|
54 |
save_shorcontroller_to_string(); |
|
55 |
my @links_record = RecordLinks->get_links( 'from_table' => 'shop_orders', |
|
56 |
'from_id' => $params{import_id}, |
|
57 |
'to_table' => 'oe', |
|
58 |
); |
|
59 |
is($links_record[0]->{from_id} , $params{import_id}, "record from id check"); |
|
60 |
is($links_record[0]->{from_table} , 'shop_orders' , "record from table <shop_orders> check"); |
|
61 |
is($links_record[0]->{to_table} , 'oe' , "record to table <oe> check"); |
|
62 |
} |
|
63 |
|
|
35 | 64 |
Support::TestSetup::login(); |
36 | 65 |
|
37 | 66 |
reset_state(); |
38 | 67 |
|
39 | 68 |
my $shop_trans_id = 1; |
40 | 69 |
|
41 |
my $shop_order = SL::Dev::Shop::create_shop_order(
|
|
70 |
my $shop_order = SL::Dev::Shop::new_shop_order(
|
|
42 | 71 |
shop => $shop, |
43 | 72 |
shop_trans_id => $shop_trans_id, |
44 | 73 |
amount => 59.5, |
... | ... | |
98 | 127 |
is($order->amount, 59.5, 'order amount ok'); |
99 | 128 |
is($order->netamount, 50, 'order netamount ok'); |
100 | 129 |
|
130 |
test_transfer( import_id => $shop_order->id , customer => $customer->id ); |
|
131 |
|
|
101 | 132 |
done_testing; |
102 | 133 |
|
103 | 134 |
clear_up(); |
t/shop/shopware.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 SL::Dev::ALL; |
|
9 |
use SL::DB::Shop; |
|
10 |
use SL::DB::ShopOrder; |
|
11 |
use SL::DB::ShopOrderItem; |
|
12 |
use SL::Controller::ShopOrder; |
|
13 |
use SL::Shop; |
|
14 |
use Data::Dumper; |
|
15 |
use SL::JSON; |
|
16 |
use SL::ShopConnector::Shopware; |
|
17 |
my ($shop, $shopware, $shop_order, $shop_part, $part, $customer, $employee, $json_import); |
|
18 |
|
|
19 |
sub reset_state { |
|
20 |
my %params = @_; |
|
21 |
|
|
22 |
clear_up(); |
|
23 |
|
|
24 |
$shop = SL::Dev::Shop::new_shop( connector => 'shopware', |
|
25 |
last_order_number => 20000, |
|
26 |
pricetype => 'brutto', |
|
27 |
price_source => 'master_data', |
|
28 |
taxzone_id => 1, |
|
29 |
); |
|
30 |
$shopware = SL::Shop->new( config => $shop ); |
|
31 |
$part = SL::Dev::Part::new_part( partnumber => 'SW10002', |
|
32 |
description => 'TITANIUM CARBON GS 12m cm', |
|
33 |
); |
|
34 |
$shop_part = SL::Dev::Shop::new_shop_part(part => $part, shop => $shop); |
|
35 |
|
|
36 |
$employee = SL::DB::Manager::Employee->current || croak "No employee"; |
|
37 |
|
|
38 |
$customer = SL::Dev::CustomerVendor::new_customer( |
|
39 |
name => 'Evil Inc', |
|
40 |
street => 'Evil Street', |
|
41 |
zipcode => '66666', |
|
42 |
email => 'evil@evilinc.com' |
|
43 |
)->save; |
|
44 |
|
|
45 |
} |
|
46 |
|
|
47 |
sub get_json { |
|
48 |
local $/; |
|
49 |
my $file = "t/shop/json_ok.json"; |
|
50 |
my $json_text = do { |
|
51 |
open(my $json_fh, "<:encoding(UTF-8)", $file) |
|
52 |
or die("Can't open \"$file\": $!\n"); |
|
53 |
local $/; |
|
54 |
<$json_fh> |
|
55 |
}; |
|
56 |
|
|
57 |
return $json_text; |
|
58 |
} |
|
59 |
|
|
60 |
sub test_import { |
|
61 |
|
|
62 |
my $json_import = get_json(); |
|
63 |
note('testing shoporder mapping json good'); |
|
64 |
my $import = SL::JSON::decode_json($json_import); |
|
65 |
$shop_order = $shopware->connector->import_data_to_shop_order($import); |
|
66 |
is($shop_order->shop_id , $shop->id , "shop_id ok"); |
|
67 |
} |
|
68 |
|
|
69 |
Support::TestSetup::login(); |
|
70 |
|
|
71 |
reset_state(); |
|
72 |
|
|
73 |
test_import(); |
|
74 |
|
|
75 |
done_testing; |
|
76 |
|
|
77 |
clear_up(); |
|
78 |
|
|
79 |
1; |
|
80 |
|
|
81 |
sub clear_up { |
|
82 |
"SL::DB::Manager::${_}"->delete_all(all => 1) for qw(OrderItem Order); |
|
83 |
"SL::DB::Manager::${_}"->delete_all(all => 1) for qw(ShopPart Part ShopOrderItem ShopOrder Shop Customer); |
|
84 |
} |
Auch abrufbar als: Unified diff
Shopmodul: Test für Shoporders