commit 07b6482f47cf5a4f5854480cdec5116eff66db72
Author: Werner Hahn <wh@futureworldsearch.net>
Date:   Fri Sep 15 16:03:33 2017 +0200

    Shopmodul: Test für Shoporders

diff --git a/SL/Controller/ShopOrder.pm b/SL/Controller/ShopOrder.pm
index f066fe8f6..d95808269 100644
--- a/SL/Controller/ShopOrder.pm
+++ b/SL/Controller/ShopOrder.pm
@@ -106,9 +106,9 @@ sub action_transfer {
   my $customer = SL::DB::Manager::Customer->find_by(id => $::form->{customer});
   die "Can't find customer" unless $customer;
   my $employee = SL::DB::Manager::Employee->current;
+  die "Can't find employee" unless $employee;
 
   die "Can't load shop_order form form->import_id" unless $self->shop_order;
-
   my $order = $self->shop_order->convert_to_sales_order(customer => $customer, employee => $employee);
   $order->calculate_prices_and_taxes;
 
@@ -135,11 +135,10 @@ sub action_transfer {
 
       $self->shop_order->transferred(1);
       $self->shop_order->transfer_date(DateTime->now_local);
-      $self->shop_order->oe_transid($order->id);
       $self->shop_order->save;
       $self->shop_order->link_to_record($order);
-      $self->redirect_to(controller => "oe.pl", action => 'edit', type => 'sales_order', vc => 'customer', id => $order->id);
     }) || die $order->db->error;
+    $self->redirect_to(controller => "oe.pl", action => 'edit', type => 'sales_order', vc => 'customer', id => $order->id);
   }
 }
 
diff --git a/SL/Dev/ALL.pm b/SL/Dev/ALL.pm
index 32eaa41b3..b702b0f5b 100644
--- a/SL/Dev/ALL.pm
+++ b/SL/Dev/ALL.pm
@@ -12,7 +12,7 @@ use SL::Dev::Shop;
 
 sub import {
   no strict "refs";
-  for (qw(Part CustomerVendor Inventory Record Payment)) {
+  for (qw(Part CustomerVendor Inventory Record Payment Shop)) {
     Exporter::export_to_level("SL::Dev::$_", 1, @_);
   }
 }
diff --git a/SL/Dev/Shop.pm b/SL/Dev/Shop.pm
index ba380e65b..857a1c470 100644
--- a/SL/Dev/Shop.pm
+++ b/SL/Dev/Shop.pm
@@ -2,21 +2,23 @@ package SL::Dev::Shop;
 
 use strict;
 use base qw(Exporter);
-our @EXPORT = qw(create_shop create_shop_part create_shop_order);
+use Data::Dumper;
+our @EXPORT_OK = qw(new_shop new_shop_part new_shop_order);
+our %EXPORT_TAGS = (ALL => \@EXPORT_OK);
 
 use SL::DB::Shop;
 
-sub create_shop {
+sub new_shop {
   my (%params) = @_;
 
   my $shop = SL::DB::Shop->new(
-    description => 'testshop',
+    description => delete $params{description} || 'testshop',
     %params
   );
   return $shop;
 }
 
-sub create_shop_part {
+sub new_shop_part {
   my (%params) = @_;
 
   my $part = delete $params{part};
@@ -30,7 +32,7 @@ sub create_shop_part {
   return $shop_part;
 }
 
-sub create_shop_order {
+sub new_shop_order {
   my (%params) = @_;
 
   my $shop_order = SL::DB::ShopOrder->new(
diff --git a/SL/ShopConnector/Shopware.pm b/SL/ShopConnector/Shopware.pm
index abf4f0286..f52497a68 100644
--- a/SL/ShopConnector/Shopware.pm
+++ b/SL/ShopConnector/Shopware.pm
@@ -4,7 +4,7 @@ use strict;
 
 use parent qw(SL::ShopConnector::Base);
 
-use SL::DBUtils;
+
 use SL::JSON;
 use LWP::UserAgent;
 use LWP::Authen::Digest;
@@ -42,42 +42,12 @@ sub get_new_orders {
       my $data_json = $data->content;
       my $import    = SL::JSON::decode_json($data_json);
 
-      my $shop_order = $self->map_data_to_shoporder($import);
-
-      $shop_order->save;
-      $of ++;
-      my $id = $shop_order->id;
-
-      my @positions = sort { Sort::Naturally::ncmp($a->{"partnumber"}, $b->{"partnumber"}) } @{ $import->{data}->{details} };
-      my $position = 1;
-      foreach my $pos(@positions) {
-        my $price = $::form->round_amount($pos->{price},2);
-
-        my %pos_columns = ( description          => $pos->{articleName},
-                            partnumber           => $pos->{articleNumber},
-                            price                => $price,
-                            quantity             => $pos->{quantity},
-                            position             => $position,
-                            tax_rate             => $pos->{taxRate},
-                            shop_trans_id        => $pos->{articleId},
-                            shop_order_id        => $id,
-                            active_price_source  => $self->config->price_source,
-                          );
-        my $pos_insert = SL::DB::ShopOrderItem->new(%pos_columns);
-        $pos_insert->save;
-        $position++;
-      }
-      $shop_order->{positions} = $position-1;
-      my $customer = $shop_order->get_customer;
-      if(ref($customer)){
-        $shop_order->kivi_customer_id($customer->id);
-        $shop_order->save;
-      }
-
-      my $attributes->{last_order_number} = $ordnumber;
-      $self->config->assign_attributes( %{ $attributes } );
+      $self->import_data_to_shop_order($import);
+
+      $self->config->assign_attributes( last_order_number => $ordnumber);
       $self->config->save;
       $ordnumber++;
+      $of++;
     }
   }
   my $shop           = $self->config->description;
@@ -85,13 +55,52 @@ sub get_new_orders {
   return \%fetched_orders;
 }
 
+sub import_data_to_shop_order {
+  my ( $self, $import ) = @_;
+  my $shop_order = $self->map_data_to_shoporder($import);
+
+  $shop_order->save;
+  my $id = $shop_order->id;
+
+  my @positions = sort { Sort::Naturally::ncmp($a->{"partnumber"}, $b->{"partnumber"}) } @{ $import->{data}->{details} };
+  my $position = 1;
+  my $active_price_source = $self->config->price_source;
+  foreach my $pos(@positions) {
+    my $price = $::form->round_amount($pos->{price},2);
+    my %pos_columns = ( description          => $pos->{articleName},
+                        partnumber           => $pos->{articleNumber},
+                        price                => $price,
+                        quantity             => $pos->{quantity},
+                        position             => $position,
+                        tax_rate             => $pos->{taxRate},
+                        shop_trans_id        => $pos->{articleId},
+                        shop_order_id        => $id,
+                        active_price_source  => $active_price_source,
+                      );
+    my $pos_insert = SL::DB::ShopOrderItem->new(%pos_columns);
+    $pos_insert->save;
+    $position++;
+  }
+  $shop_order->{positions} = $position-1;
+
+  my $customer = $shop_order->get_customer;
+  if(ref($customer)){
+    $shop_order->kivi_customer_id($customer->id);
+    $shop_order->save;
+  }
+}
+
 sub map_data_to_shoporder {
   my ($self, $import) = @_;
+
   my $parser = DateTime::Format::Strptime->new( pattern   => '%Y-%m-%dT%H:%M:%S',
                                                   locale    => 'de_DE',
                                                   time_zone => 'local'
                                                 );
   my $orderdate = $parser->parse_datetime($import->{data}->{orderTime});
+
+  my $shop_id      = $self->config->id;
+  my $tax_included = $self->config->pricetype;
   # Mapping to table shoporders. See http://community.shopware.com/_detail_1690.html#GET_.28Liste.29
   my %columns = (
     amount                  => $import->{data}->{invoiceAmount},
@@ -152,11 +161,12 @@ sub map_data_to_shoporder {
     shop_customer_id        => $import->{data}->{customerId},
     shop_customer_number    => $import->{data}->{billing}->{number},
     shop_customer_comment   => $import->{data}->{customerComment},
-    shop_id                 => $self->config->id,
+    shop_id                 => $shop_id,
     shop_ordernumber        => $import->{data}->{number},
     shop_trans_id           => $import->{data}->{id},
-    tax_included            => $self->config->pricetype eq "brutto" ? 1 : 0,
+    tax_included            => $tax_included eq "brutto" ? 1 : 0,
   );
+
   my $shop_order = SL::DB::ShopOrder->new(%columns);
   return $shop_order;
 }
@@ -358,24 +368,32 @@ __END__
 
 =head1 NAME
 
-  SL::Shopconnecter::Shopware - connector for shopware 5
+SL::Shopconnecter::Shopware - connector for shopware 5
 
 =head1 SYNOPSIS
 
 
 =head1 DESCRIPTION
 
+=head1 METHODS
+
+=back 4
+
+=item C<import_data_to_shop_order>
+
+Creates on shoporder object from json
+
 =head1 TODO
 
-  Pricesrules, pricessources aren't fully implemented yet.
-  Payments aren't implemented( need to map payments from Shopware like invoice, paypal etc. to payments in kivitendo)
+Pricesrules, pricessources aren't fully implemented yet.
+Payments aren't implemented( need to map payments from Shopware like invoice, paypal etc. to payments in kivitendo)
 
 =head1 BUGS
 
-  None yet. :)
+None yet. :)
 
 =head1 AUTHOR
 
-  W. Hahn E<lt>wh@futureworldsearch.netE<gt>
+W. Hahn E<lt>wh@futureworldsearch.netE<gt>
 
 =cut
diff --git a/t/shop/shop_order.t b/t/shop/shop_order.t
index 15c0b27ed..e977b264b 100644
--- a/t/shop/shop_order.t
+++ b/t/shop/shop_order.t
@@ -9,6 +9,7 @@ use SL::Dev::ALL;
 use SL::DB::Shop;
 use SL::DB::ShopOrder;
 use SL::DB::ShopOrderItem;
+use SL::Controller::ShopOrder;
 use Data::Dumper;
 
 my ($shop, $shop_order, $shop_part, $part, $customer, $employee);
@@ -18,9 +19,9 @@ sub reset_state {
 
   clear_up();
 
-  $shop = SL::Dev::Shop::create_shop->save;
+  $shop = SL::Dev::Shop::new_shop->save;
   $part = SL::Dev::Part::new_part->save;
-  $shop_part = SL::Dev::Shop::create_shop_part(part => $part, shop => $shop)->save;
+  $shop_part = SL::Dev::Shop::new_shop_part(part => $part, shop => $shop)->save;
 
   $employee = SL::DB::Manager::Employee->current || croak "No employee";
 
@@ -32,13 +33,41 @@ sub reset_state {
   )->save;
 }
 
+sub save_shorcontroller_to_string {
+
+  my $output;
+  open(my $outputFH, '<', \$output) or die "OUTPUT";
+  my $oldFH = select $outputFH;
+  my $shor_controller = SL::Controller::ShopOrder->new;
+  $shor_controller->action_transfer;
+
+  select $oldFH;
+  close $outputFH;
+  return $output;
+}
+sub test_transfer {
+  my ( %params ) = @_;
+  $::form = Support::TestSetup->create_new_form;
+  $::form->{import_id} = $params{import_id};
+  $::form->{customer} =  $params{customer};
+  my $test_name = 'Test Controller Action Transfer';
+  save_shorcontroller_to_string();
+  my @links_record = RecordLinks->get_links( 'from_table' => 'shop_orders',
+                                            'from_id'    => $params{import_id},
+                                            'to_table'   => 'oe',
+                                          );
+  is($links_record[0]->{from_id}    , $params{import_id}, "record from id check");
+  is($links_record[0]->{from_table} , 'shop_orders'     , "record from table <shop_orders> check");
+  is($links_record[0]->{to_table}   , 'oe'              , "record to table <oe> check");
+}
+
 Support::TestSetup::login();
 
 reset_state();
 
 my $shop_trans_id = 1;
 
-my $shop_order = SL::Dev::Shop::create_shop_order(
+my $shop_order = SL::Dev::Shop::new_shop_order(
   shop              => $shop,
   shop_trans_id     => $shop_trans_id,
   amount            => 59.5,
@@ -98,6 +127,8 @@ is(ref($order), 'SL::DB::Order', 'order ok');
 is($order->amount,    59.5, 'order amount ok');
 is($order->netamount, 50,   'order netamount ok');
 
+test_transfer( import_id => $shop_order->id , customer => $customer->id );
+
 done_testing;
 
 clear_up();
diff --git a/t/shop/shopware.t b/t/shop/shopware.t
new file mode 100644
index 000000000..fc030a6b2
--- /dev/null
+++ b/t/shop/shopware.t
@@ -0,0 +1,84 @@
+use strict;
+use Test::More;
+
+use lib 't';
+use Support::TestSetup;
+use Carp;
+use Test::Exception;
+use SL::Dev::ALL;
+use SL::DB::Shop;
+use SL::DB::ShopOrder;
+use SL::DB::ShopOrderItem;
+use SL::Controller::ShopOrder;
+use SL::Shop;
+use Data::Dumper;
+use SL::JSON;
+use SL::ShopConnector::Shopware;
+my ($shop, $shopware, $shop_order, $shop_part, $part, $customer, $employee, $json_import);
+
+sub reset_state {
+  my %params = @_;
+
+  clear_up();
+
+  $shop = SL::Dev::Shop::new_shop( connector         => 'shopware',
+                                   last_order_number => 20000,
+                                   pricetype         => 'brutto',
+                                   price_source      => 'master_data',
+                                   taxzone_id        => 1,
+                                 );
+  $shopware = SL::Shop->new( config => $shop );
+  $part = SL::Dev::Part::new_part( partnumber   => 'SW10002',
+                                         description  => 'TITANIUM CARBON GS 12m cm',
+                                       );
+  $shop_part = SL::Dev::Shop::new_shop_part(part => $part, shop => $shop);
+
+  $employee = SL::DB::Manager::Employee->current || croak "No employee";
+
+  $customer = SL::Dev::CustomerVendor::new_customer(
+    name    => 'Evil Inc',
+    street  => 'Evil Street',
+    zipcode => '66666',
+    email   => 'evil@evilinc.com'
+  )->save;
+
+}
+
+sub get_json {
+  local $/;
+  my $file = "t/shop/json_ok.json";
+  my $json_text = do {
+    open(my $json_fh, "<:encoding(UTF-8)", $file)
+         or die("Can't open \"$file\": $!\n");
+    local $/;
+    <$json_fh>
+  };
+
+  return $json_text;
+}
+
+sub test_import {
+
+  my $json_import = get_json();
+  note('testing shoporder mapping json good');
+  my $import = SL::JSON::decode_json($json_import);
+  $shop_order = $shopware->connector->import_data_to_shop_order($import);
+  is($shop_order->shop_id , $shop->id  , "shop_id ok");
+}
+
+Support::TestSetup::login();
+
+reset_state();
+
+test_import();
+
+done_testing;
+
+clear_up();
+
+1;
+
+sub clear_up {
+  "SL::DB::Manager::${_}"->delete_all(all => 1) for qw(OrderItem Order);
+  "SL::DB::Manager::${_}"->delete_all(all => 1) for qw(ShopPart Part ShopOrderItem ShopOrder Shop Customer);
+}
