commit e66c12b7e3ce2719f30d316255c116a62542b4a5
Author: Werner Hahn <wh@futureworldsearch.net>
Date:   Fri Sep 8 11:53:34 2017 +0200

    Shopmodul: Bilder hochladen geht jetzt
    Bestellungen überarbeitet, Teile aus dem ShowareConnector ausgelagert, da diese allgemeingültig auch für andere Connectoren sind
    Typo

diff --git a/SL/Controller/Shop.pm b/SL/Controller/Shop.pm
index e54fbfdb3..6f4cfb649 100644
--- a/SL/Controller/Shop.pm
+++ b/SL/Controller/Shop.pm
@@ -38,13 +38,12 @@ sub action_edit {
 
   my $is_new = !$self->shop->id;
   $self->_setup_form_action_bar;
-  $self->render('shops/form', title       => ($is_new ? t8('Add shop') : t8('Edit shop')));
+  $self->render('shops/form', title => ($is_new ? t8('Add shop') : t8('Edit shop')));
 }
 
 sub action_save {
   my ($self) = @_;
 
-  my $is_new = !$self->shop->id;
   $self->create_or_update;
 }
 
@@ -54,7 +53,7 @@ sub action_delete {
   if ( eval { $self->shop->delete; 1; } ) {
     flash_later('info',  $::locale->text('The shop has been deleted.'));
   } else {
-    flash_later('error', $::locale->text('The shop has been used and cannot be deleted.'));
+    flash_later('error', $::locale->text('The shop is in use and cannot be deleted.'));
   };
   $self->redirect_to(action => 'list');
 }
@@ -63,10 +62,10 @@ sub action_reorder {
   my ($self) = @_;
 
   SL::DB::Shop->reorder_list(@{ $::form->{shop_id} || [] });
-  $self->render(\'', { type => 'json' });
+  $self->render(\'', { type => 'json' }); # ' emacs happy again
 }
 
-sub action_check_connectivity {
+sub check_connectivity {
   my ($self) = @_;
 
   my $ok = 0;
@@ -75,10 +74,10 @@ sub action_check_connectivity {
   my $version = $shop->connector->get_version;
   $ok       = $version->{success};
 
-  if($ok) {
-    flash_later('ok', t8('The connection to the webshop is success. Version: #1 -- Revision: #2', $version->{data}->{version}, $version->{data}->{revision}));
+  if ($ok) {
+    flash_later('ok', t8('The connection to the webshop was successful. Version: #1 -- Revision: #2', $version->{data}->{version}, $version->{data}->{revision}));
     return;
-  }else{
+  } else {
     return $version;
   }
 }
@@ -88,8 +87,7 @@ sub check_auth {
 }
 
 sub init_shop {
-  SL::DB::Manager::Shop->find_by_or_create(id => $::form->{id} || 0)
-                              ->assign_attributes(%{ $::form->{shop} });
+  SL::DB::Manager::Shop->find_by_or_create(id => $::form->{id} || 0)->assign_attributes(%{ $::form->{shop} });
 }
 
 #
@@ -98,6 +96,7 @@ sub init_shop {
 
 sub create_or_update {
   my ($self) = @_;
+
   my $is_new = !$self->shop->id;
 
   my @errors = $self->shop->validate;
@@ -108,7 +107,7 @@ sub create_or_update {
     return;
   }
 
-  my $version = $self->action_check_connectivity();
+  my $version = $self->check_connectivity();
   if ($version) {
     flash('error', t8('The connection to the webshop is not success. Message: #1 -- URL: #2 -- Datatype: #3', $version->{message}, $version->{data}->{version}, $version->{data}->{revision}));
     $self->load_types();
@@ -129,31 +128,31 @@ sub load_types {
   require SL::ShopConnector::ALL;
   $self->connectors(SL::ShopConnector::ALL->connectors);
 
-  $self->price_types( [ { id => "brutto", name => t8('brutto')}, { id => "netto", name => t8('netto') } ] );
+  $self->price_types( [ { id => "brutto", name => t8('brutto') },
+                        { id => "netto",  name => t8('netto')  } ] );
 
-  $self->protocols( [ { id => "http", name => t8('http') }, { id => "https", name => t8('https') } ] );
+  $self->protocols(   [ { id => "http",  name => t8('http') },
+                        { id => "https", name => t8('https') } ] );
 
   my $pricesources;
-  push( @{ $pricesources } , { id => "master_data/sellprice", name => t8("Master Data")." - ".t8("Sellprice") },
-                             { id => "master_data/listprice", name => t8("Master Data")." - ".t8("Listprice") },
-                             { id => "master_data/lastcost",  name => t8("Master Data")." - ".t8("Lastcost") }
-                             );
+  push(@{ $pricesources } , { id => "master_data/sellprice", name => t8("Master Data") . " - " . t8("Sellprice") },
+                            { id => "master_data/listprice", name => t8("Master Data") . " - " . t8("Listprice") },
+                            { id => "master_data/lastcost",  name => t8("Master Data") . " - " . t8("Lastcost")  });
   my $pricegroups = SL::DB::Manager::Pricegroup->get_all;
   foreach my $pg ( @$pricegroups ) {
-    push( @{ $pricesources } , { id => "pricegroup/".$pg->id, name => t8("Pricegroup") . " - " . $pg->pricegroup} );
+    push( @{ $pricesources } , { id => "pricegroup/" . $pg->id, name => t8("Pricegroup") . " - " . $pg->pricegroup} );
   };
 
-  $self->price_sources( $pricesources );
+  $self->price_sources($pricesources);
 
   #Buchungsgruppen for calculate the tax for an article
   my $taxkey_ids;
   my $taxzones = SL::DB::Manager::TaxZone->get_all_sorted();
 
-  foreach my $tz( @$taxzones ) {
-    push( @{ $taxkey_ids }, { id => $tz->id, name => $tz->description } );
+  foreach my $tz (@$taxzones) {
+    push  @{ $taxkey_ids }, { id => $tz->id, name => $tz->description };
   }
   $self->taxzone_id( $taxkey_ids );
-
 };
 
 sub _setup_form_action_bar {
@@ -171,11 +170,11 @@ sub _setup_form_action_bar {
           t8('Delete'),
           submit => [ '#form', { action => "Shop/delete" } ],
         ],
-        ],
-        action => [
-          t8('Cancel'),
-          submit => [ '#form', { action => "Shop/list" } ],
-        ],
+      ],
+      action => [
+        t8('Cancel'),
+        submit => [ '#form', { action => "Shop/list" } ],
+      ],
     );
   }
 }
@@ -185,12 +184,12 @@ sub _setup_list_action_bar {
 
   for my $bar ($::request->layout->get('actionbar')) {
     $bar->add(
-        link => [
-          t8('Add'),
-          link => $self->url_for(action => 'edit'),
-        ],
-    );
-  }
+      link => [
+        t8('Add'),
+        link => $self->url_for(action => 'edit'),
+      ],
+    )
+  };
 }
 
 1;
diff --git a/SL/Controller/ShopOrder.pm b/SL/Controller/ShopOrder.pm
index fd255fa11..3c12fb058 100644
--- a/SL/Controller/ShopOrder.pm
+++ b/SL/Controller/ShopOrder.pm
@@ -32,9 +32,11 @@ sub action_get_orders {
   foreach my $shop_config ( @{ $active_shops } ) {
     my $shop = SL::Shop->new( config => $shop_config );
     my $new_orders = $shop->connector->get_new_orders;
-    push @{ $orders_fetched },@{ $new_orders };
+#    push @{ $orders_fetched },@{ $new_orders };
   };
-  flash_later('info', t8('#1 shoporders has been fetched', scalar(@{$orders_fetched})-1));
+  $main::lxdebug->dump(0, 'WH:OF ',$orders_fetched);
+
+#  flash('info', t8('#1 shoporders has been fetched', scalar(@{$orders_fetched})-1));
   $self->action_list;
 }
 
@@ -68,32 +70,10 @@ sub action_list {
 sub action_show {
   my ( $self ) = @_;
   my $id = $::form->{id} || {};
-  my $shop_order = SL::DB::Manager::ShopOrder->find_by( id => $id , with_objects => ['kivi_customer'] );
+  my $shop_order = SL::DB::ShopOrder->new( id => $id )->load( with => ['kivi_customer'] );
   die "can't find shoporder with id $id" unless $shop_order;
 
-  # Only Customers which are not found will be applied
-  my $name = $shop_order->billing_lastname ne '' ? "%" . $shop_order->billing_firstname . "%" . $shop_order->billing_lastname . "%" : '';
-  my $lastname = $shop_order->billing_lastname ne '' ? "%" . $shop_order->billing_lastname . "%" : '';
-  my $company = $shop_order->billing_company ne '' ? "%" . $shop_order->billing_company . "%" : '';
-  my $street = $shop_order->billing_street ne '' ?  $shop_order->billing_street : '';
-  # Fuzzysearch for street to find e.g. "Dorfstrasse - Dorfstr. - Dorfstraße"
-  my $dbh = $::form->get_standard_dbh();
-  my $fs_query = "SELECT id FROM customer WHERE ( ( (    name ILIKE ?
-                                                      OR name ILIKE ?
-                                                    )
-                                                    AND zipcode ILIKE ?
-                                                  )
-                                                  OR ( street % ?
-                                                       AND zipcode ILIKE ?
-                                                     )
-                                                  OR email ILIKE ?
-                                                )";
-  my @values = ($lastname, $company, $shop_order->billing_zipcode, $street, $shop_order->billing_zipcode, $shop_order->billing_email);
-  my @c_ids = selectall_array_query($::form, $dbh, $fs_query, @values);
-
-  my $proposals = SL::DB::Manager::Customer->get_all(
-       query => [ id => [ @c_ids ], ],
-  );
+  my $proposals = $shop_order->check_for_existing_customers;
 
   $self->render('shop_order/show',
                 title       => t8('Shoporder'),
@@ -128,7 +108,7 @@ sub action_transfer {
   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);
-
+  ## price_tax_calculator
   if ($order->{error}){
     flash_later('error',@{$order->{errors}});
   $self->redirect_to(controller => "ShopOrder", action => 'show', id => $self->shop_order->id);
diff --git a/SL/DB/ShopOrder.pm b/SL/DB/ShopOrder.pm
index 4fef95688..bf0cca5a2 100644
--- a/SL/DB/ShopOrder.pm
+++ b/SL/DB/ShopOrder.pm
@@ -140,6 +140,60 @@ SQL
   return $customers;
 }
 
+#auslagern in eigene subroutine, da auch für andere connectoren genutzt werden muss
+sub get_customer{
+  my ($self, %params) = @_;
+
+  my $customer_proposals = $self->check_for_existing_customers;
+  my $name = $self->billing_firstname . " " . $self->billing_lastname;
+my $customer;
+  if(!scalar(@{$customer_proposals})){
+    my %address = ( 'name'                  => $name,
+                    'department_1'          => $self->billing_company,
+                    'department_2'          => $self->billing_department,
+                    'street'                => $self->billing_street,
+                    'zipcode'               => $self->billing_zipcode,
+                    'city'                  => $self->billing_city,
+                    'email'                 => $self->billing_email,
+                    'country'               => $self->billing_country,
+                    'greeting'              => $self->billing_greeting,
+                    'fax'                   => $self->billing_fax,
+                    'phone'                 => $self->billing_phone,
+                    'ustid'                 => $self->billing_vat,
+                    'taxincluded_checked'   => $self->config->pricetype eq "brutto" ? 1 : 0,
+                    'taxincluded'           => $self->config->pricetype eq "brutto" ? 1 : 0,
+                    'pricegroup_id'         => (split '\/',$self->config->price_source)[0] eq "pricegroup" ?  (split '\/',$self->config->price_source)[1] : undef,
+                    'taxzone_id'            => $self->config->taxzone_id,
+                    'currency'              => $::instance_conf->get_currency_id,
+                    #'payment_id'            => 7345,# TODO hardcoded
+                  );
+    $customer = SL::DB::Customer->new(%address);
+
+    $customer->save;
+    my $snumbers = "customernumber_" . $customer->customernumber;
+    SL::DB::History->new(
+                      trans_id    => $customer->id,
+                      snumbers    => $snumbers,
+                      employee_id => SL::DB::Manager::Employee->current->id,
+                      addition    => 'SAVED',
+                      what_done   => 'Shopimport',
+                    )->save();
+
+  }elsif(scalar(@{$customer_proposals}) == 1){
+    # hier überprüfen ob Kundendaten wirklich übereinstimmen auc auf ungültig überprüfen
+    $customer = $customer_proposals->[0];
+  }else{
+    # hier überprüfen ob Kundendaten wirklich übereinstimmen und ob es nur einen datensatz gibt auc auf ungültig überprüfen
+    $customer = SL::DB::Manager::Customer->find_by( name    => $name,
+                                                       street  => $self->billing_street,
+                                                       zipcode => $self->billing_zipcode,
+                                                       email   => $self->billing_email,
+                                                     );
+
+  }
+  return \$customer;
+}
+## EOF AUslagern
 sub compare_to {
   my ($self, $other) = @_;
 
diff --git a/SL/Shop.pm b/SL/Shop.pm
index 576795605..c19708610 100644
--- a/SL/Shop.pm
+++ b/SL/Shop.pm
@@ -7,6 +7,7 @@ use SL::ShopConnector::ALL;
 use SL::DB::Part;
 
 # __PACKAGE__->run_before('check_auth');
+# bb: warum auskommentiert - kann dann wohl weg, oder?
 
 use Rose::Object::MakeMethods::Generic (
   'scalar'                => [ qw(config) ],
diff --git a/SL/ShopConnector/Base.pm b/SL/ShopConnector/Base.pm
index 83cf117a5..1479d9923 100644
--- a/SL/ShopConnector/Base.pm
+++ b/SL/ShopConnector/Base.pm
@@ -7,17 +7,18 @@ use Rose::Object::MakeMethods::Generic (
   scalar => [ qw(config) ],
 );
 
-sub get_order { die 'get_order needs to be implemented' }
+sub get_order      { die 'get_order needs to be implemented' }
 
 sub get_new_orders { die 'get_order needs to be implemented' }
 
-sub update_part { die 'update_part needs to be implemented' }
+sub update_part    { die 'update_part needs to be implemented' }
 
-sub get_article { die 'get_article needs to be implemented' }
+sub get_article    { die 'get_article needs to be implemented' }
 
 sub get_categories { die 'get_order needs to be implemented' }
 
-sub get_version { die 'get_order needs to be implemented' }
+sub get_version    { die 'get_order needs to be implemented' }
+
 1;
 
 __END__
diff --git a/SL/ShopConnector/Shopware.pm b/SL/ShopConnector/Shopware.pm
index 000c5b63c..dad8584d5 100644
--- a/SL/ShopConnector/Shopware.pm
+++ b/SL/ShopConnector/Shopware.pm
@@ -11,6 +11,7 @@ use LWP::Authen::Digest;
 use SL::DB::ShopOrder;
 use SL::DB::ShopOrderItem;
 use SL::DB::History;
+use DateTime::Format::Strptime;
 use SL::DB::File;
 use Data::Dumper;
 use Sort::Naturally ();
@@ -23,89 +24,42 @@ use Rose::Object::MakeMethods::Generic (
   'scalar --get_set_init' => [ qw(connector url) ],
 );
 
+sub get_order_max {
+  my ($self) = @_;
+  my %params = ( sort  => { property  => 'number',
+                            direction => 'DESC',
+                          },
+               );
+  my $url       = $self->url;
+  my $data      = $self->connector->get($url . "api/orders?limit=1", %params);
+  my $data_json = $data->content;
+  $main::lxdebug->dump(0, 'WH:MAX1 ', $data->content);
+
+  my $import    = SL::JSON::decode_json($data_json);
+  $main::lxdebug->dump(0, 'WH:MAX ', $import->{data});
+  $main::lxdebug->dump(0, 'WH:MAX3 ', $import->{data}->{number});
+
+}
+
 sub get_new_orders {
   my ($self, $id) = @_;
 
   my $url       = $self->url;
   my $ordnumber = $self->config->last_order_number + 1;
   my $otf       = $self->config->orders_to_fetch;
-
-  my $i;
-  for ($i=1;$i<=$otf;$i++) {
+  my $of        = 0;
+  $self->get_order_max;
+  for(1 .. $otf) {
 
     my $data      = $self->connector->get($url . "api/orders/$ordnumber?useNumberAsId=true");
     my $data_json = $data->content;
     my $import    = SL::JSON::decode_json($data_json);
+
     if ($import->{success}){
+      my $shop_order = $self->map_data_to_shoporder($import);
 
-      # Mapping to table shoporders. See http://community.shopware.com/_detail_1690.html#GET_.28Liste.29
-      my %columns = (
-        amount                  => $import->{data}->{invoiceAmount},
-        billing_city            => $import->{data}->{billing}->{city},
-        billing_company         => $import->{data}->{billing}->{company},
-        billing_country         => $import->{data}->{billing}->{country}->{name},
-        billing_department      => $import->{data}->{billing}->{department},
-        billing_email           => $import->{data}->{customer}->{email},
-        billing_fax             => $import->{data}->{billing}->{fax},
-        billing_firstname       => $import->{data}->{billing}->{firstName},
-        #billing_greeting        => ($import->{data}->{billing}->{salutation} eq 'mr' ? 'Herr' : 'Frau'),
-        billing_lastname        => $import->{data}->{billing}->{lastName},
-        billing_phone           => $import->{data}->{billing}->{phone},
-        billing_street          => $import->{data}->{billing}->{street},
-        billing_vat             => $import->{data}->{billing}->{vatId},
-        billing_zipcode         => $import->{data}->{billing}->{zipCode},
-        customer_city           => $import->{data}->{billing}->{city},
-        customer_company        => $import->{data}->{billing}->{company},
-        customer_country        => $import->{data}->{billing}->{country}->{name},
-        customer_department     => $import->{data}->{billing}->{department},
-        customer_email          => $import->{data}->{customer}->{email},
-        customer_fax            => $import->{data}->{billing}->{fax},
-        customer_firstname      => $import->{data}->{billing}->{firstName},
-        #customer_greeting       => ($import->{data}->{billing}->{salutation} eq 'mr' ? 'Herr' : 'Frau'),
-        customer_lastname       => $import->{data}->{billing}->{lastName},
-        customer_phone          => $import->{data}->{billing}->{phone},
-        customer_street         => $import->{data}->{billing}->{street},
-        customer_vat            => $import->{data}->{billing}->{vatId},
-        customer_zipcode        => $import->{data}->{billing}->{zipCode},
-        customer_newsletter     => $import->{data}->{customer}->{newsletter},
-        delivery_city           => $import->{data}->{shipping}->{city},
-        delivery_company        => $import->{data}->{shipping}->{company},
-        delivery_country        => $import->{data}->{shipping}->{country}->{name},
-        delivery_department     => $import->{data}->{shipping}->{department},
-        delivery_email          => "",
-        delivery_fax            => $import->{data}->{shipping}->{fax},
-        delivery_firstname      => $import->{data}->{shipping}->{firstName},
-        #delivery_greeting       => ($import->{data}->{shipping}->{salutation} eq 'mr' ? 'Herr' : 'Frau'),
-        delivery_lastname       => $import->{data}->{shipping}->{lastName},
-        delivery_phone          => $import->{data}->{shipping}->{phone},
-        delivery_street         => $import->{data}->{shipping}->{street},
-        delivery_vat            => $import->{data}->{shipping}->{vatId},
-        delivery_zipcode        => $import->{data}->{shipping}->{zipCode},
-        host                    => $import->{data}->{shop}->{hosts},
-        netamount               => $import->{data}->{invoiceAmountNet},
-        order_date              => $import->{data}->{orderTime},
-        payment_description     => $import->{data}->{payment}->{description},
-        payment_id              => $import->{data}->{paymentId},
-        remote_ip               => $import->{data}->{remoteAddress},
-        sepa_account_holder     => $import->{data}->{paymentIntances}->{accountHolder},
-        sepa_bic                => $import->{data}->{paymentIntances}->{bic},
-        sepa_iban               => $import->{data}->{paymentIntances}->{iban},
-        shipping_costs          => $import->{data}->{invoiceShipping},
-        shipping_costs_net      => $import->{data}->{invoiceShippingNet},
-        shop_c_billing_id       => $import->{data}->{billing}->{customerId},
-        shop_c_billing_number   => $import->{data}->{billing}->{number},
-        shop_c_delivery_id      => $import->{data}->{shipping}->{id},
-        shop_customer_id        => $import->{data}->{customerId},
-        shop_customer_number    => $import->{data}->{billing}->{number},
-        shop_customer_comment   => $import->{data}->{customerComment},
-        shop_data               => "",
-        shop_id                 => $self->config->id,
-        shop_ordernumber        => $import->{data}->{number},
-        shop_trans_id           => $import->{data}->{id},
-        tax_included            => $self->config->pricetype eq "brutto" ? 1 : 0,
-      );
-      my $shop_order = SL::DB::ShopOrder->new(%columns);
       $shop_order->save;
+      $of ++;
       my $id = $shop_order->id;
 
       my @positions = sort { Sort::Naturally::ncmp($a->{"partnumber"}, $b->{"partnumber"}) } @{ $import->{data}->{details} };
@@ -128,90 +82,10 @@ sub get_new_orders {
         $position++;
       }
       $shop_order->{positions} = $position-1;
-
-      # Only Customers which are not found will be applied
-      my $name = $shop_order->billing_lastname ne '' ? $shop_order->billing_firstname . " " . $shop_order->billing_lastname : '';
-      my $lastname = $shop_order->billing_lastname ne '' ? "%" . $shop_order->billing_lastname . "%" : '';
-      my $company  = $shop_order->billing_company ne '' ? "%" . $shop_order->billing_company . "%" : '';
-      my $street   = $shop_order->billing_street ne '' ?  $shop_order->billing_street : '';
-      # Fuzzysearch for street to find e.g. "Dorfstrasse - Dorfstr. - Dorfstraße"
-      my $dbh      = $::form->get_standard_dbh();
-      my $fs_query = "SELECT id FROM customer WHERE ( ( (    name ILIKE ?
-                                                          OR name ILIKE ?
-                                                        )
-                                                        AND zipcode ILIKE ?
-                                                      )
-                                                      OR ( street % ?
-                                                           AND zipcode ILIKE ?
-                                                         )
-                                                      OR email ILIKE ?
-                                                    )";
-      my @values = ($lastname, $company, $shop_order->billing_zipcode, $street, $shop_order->billing_zipcode, $shop_order->billing_email);
-      my @c_ids  = selectall_array_query($::form, $dbh, $fs_query, @values);
-
-      if(!scalar(@c_ids)){
-
-        my %address = ( 'name'                  => $shop_order->billing_firstname . " " . $shop_order->billing_lastname,
-                        'department_1'          => $shop_order->billing_company,
-                        'department_2'          => $shop_order->billing_department,
-                        'street'                => $shop_order->billing_street,
-                        'zipcode'               => $shop_order->billing_zipcode,
-                        'city'                  => $shop_order->billing_city,
-                        'email'                 => $shop_order->billing_email,
-                        'country'               => $shop_order->billing_country,
-                        'greeting'              => $shop_order->billing_greeting,
-                        'contact'               => ($shop_order->billing_greeting eq "Herr" ? "Sehr geehrter Herr $lastname" : "Sehr geehrte Frau $lastname"),
-                        'fax'                   => $shop_order->billing_fax,
-                        'phone'                 => $shop_order->billing_phone,
-                        'ustid'                 => $shop_order->billing_vat,
-                        'taxincluded_checked'   => $self->config->pricetype eq "brutto" ? 1 : 0,
-                        'taxincluded'           => $self->config->pricetype eq "brutto" ? 1 : 0,
-                        'pricegroup_id'         => (split '\/',$self->config->price_source)[0] eq "pricegroup" ?  (split '\/',$self->config->price_source)[1] : undef,
-                        'taxzone_id'            => $self->config->taxzone_id,
-                        'currency'              => 1,   # TODO hardcoded
-                        #'payment_id'            => 7345,# TODO hardcoded
-                      );
-        my $customer = SL::DB::Customer->new(%address);
-
-        $customer->save;
-        my $snumbers = "customernumber_" . $customer->customernumber;
-        SL::DB::History->new(
-                          trans_id    => $customer->id,
-                          snumbers    => $snumbers,
-                          employee_id => SL::DB::Manager::Employee->current->id,
-                          addition    => 'SAVED',
-                          what_done   => 'Shopimport',
-                        )->save();
-        $shop_order->{kivi_customer_id} = $customer->id;
+      my $customer = $shop_order->get_customer;
+      if(ref($customer) eq "SL::DB::Customer"){
+        $shop_order->kivi_customer_id($customer->id);
         $shop_order->save;
-
-      }elsif(scalar(@c_ids) == 1){
-        my $customer = SL::DB::Manager::Customer->get_first( query => [
-                                                                  id      => $c_ids[0],
-                                                                  email   => $shop_order->billing_email,
-                                                                  street  => $shop_order->billing_street,
-                                                                  zipcode => $shop_order->billing_zipcode,
-                                                                  city    => $shop_order->billing_city,
-                                                                  name    => $name,
-                                                                ]);
-
-        if(ref $customer){
-          $shop_order->{kivi_customer_id} = $customer->id;
-          $shop_order->save;
-        }
-      }else{
-        my $customer = SL::DB::Manager::Customer->get_first( query => [   #or => [id      => \@c_ids ],
-                                                                        name    => $name,
-                                                                        street  => $shop_order->billing_street,
-                                                                        zipcode => $shop_order->billing_zipcode,
-                                                                        email   => $shop_order->billing_email,
-                                                                      ]
-                                                           );
-
-        if(ref $customer){
-          $shop_order->{kivi_customer_id} = $customer->id;
-          $shop_order->save;
-        }
       }
 
       my $attributes->{last_order_number} = $ordnumber;
@@ -221,9 +95,85 @@ sub get_new_orders {
     }
   }
   my $shop           = $self->config->description;
-  my @fetched_orders = ($shop,$i);
-  return \@fetched_orders;
-};
+  my %fetched_orders = (shop_id => $self->config->id, number_of_orders => $of);
+  return \%fetched_orders;
+}
+
+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});
+  # Mapping to table shoporders. See http://community.shopware.com/_detail_1690.html#GET_.28Liste.29
+  my %columns = (
+    amount                  => $import->{data}->{invoiceAmount},
+    billing_city            => $import->{data}->{billing}->{city},
+    billing_company         => $import->{data}->{billing}->{company},
+    billing_country         => $import->{data}->{billing}->{country}->{name},
+    billing_department      => $import->{data}->{billing}->{department},
+    billing_email           => $import->{data}->{customer}->{email},
+    billing_fax             => $import->{data}->{billing}->{fax},
+    billing_firstname       => $import->{data}->{billing}->{firstName},
+    #billing_greeting        => ($import->{data}->{billing}->{salutation} eq 'mr' ? 'Herr' : 'Frau'),
+    billing_lastname        => $import->{data}->{billing}->{lastName},
+    billing_phone           => $import->{data}->{billing}->{phone},
+    billing_street          => $import->{data}->{billing}->{street},
+    billing_vat             => $import->{data}->{billing}->{vatId},
+    billing_zipcode         => $import->{data}->{billing}->{zipCode},
+    customer_city           => $import->{data}->{billing}->{city},
+    customer_company        => $import->{data}->{billing}->{company},
+    customer_country        => $import->{data}->{billing}->{country}->{name},
+    customer_department     => $import->{data}->{billing}->{department},
+    customer_email          => $import->{data}->{customer}->{email},
+    customer_fax            => $import->{data}->{billing}->{fax},
+    customer_firstname      => $import->{data}->{billing}->{firstName},
+    #customer_greeting       => ($import->{data}->{billing}->{salutation} eq 'mr' ? 'Herr' : 'Frau'),
+    customer_lastname       => $import->{data}->{billing}->{lastName},
+    customer_phone          => $import->{data}->{billing}->{phone},
+    customer_street         => $import->{data}->{billing}->{street},
+    customer_vat            => $import->{data}->{billing}->{vatId},
+    customer_zipcode        => $import->{data}->{billing}->{zipCode},
+    customer_newsletter     => $import->{data}->{customer}->{newsletter},
+    delivery_city           => $import->{data}->{shipping}->{city},
+    delivery_company        => $import->{data}->{shipping}->{company},
+    delivery_country        => $import->{data}->{shipping}->{country}->{name},
+    delivery_department     => $import->{data}->{shipping}->{department},
+    delivery_email          => "",
+    delivery_fax            => $import->{data}->{shipping}->{fax},
+    delivery_firstname      => $import->{data}->{shipping}->{firstName},
+    #delivery_greeting       => ($import->{data}->{shipping}->{salutation} eq 'mr' ? 'Herr' : 'Frau'),
+    delivery_lastname       => $import->{data}->{shipping}->{lastName},
+    delivery_phone          => $import->{data}->{shipping}->{phone},
+    delivery_street         => $import->{data}->{shipping}->{street},
+    delivery_vat            => $import->{data}->{shipping}->{vatId},
+    delivery_zipcode        => $import->{data}->{shipping}->{zipCode},
+    host                    => $import->{data}->{shop}->{hosts},
+    netamount               => $import->{data}->{invoiceAmountNet},
+    order_date              => $orderdate,
+    payment_description     => $import->{data}->{payment}->{description},
+    payment_id              => $import->{data}->{paymentId},
+    remote_ip               => $import->{data}->{remoteAddress},
+    sepa_account_holder     => $import->{data}->{paymentIntances}->{accountHolder},
+    sepa_bic                => $import->{data}->{paymentIntances}->{bic},
+    sepa_iban               => $import->{data}->{paymentIntances}->{iban},
+    shipping_costs          => $import->{data}->{invoiceShipping},
+    shipping_costs_net      => $import->{data}->{invoiceShippingNet},
+    shop_c_billing_id       => $import->{data}->{billing}->{customerId},
+    shop_c_billing_number   => $import->{data}->{billing}->{number},
+    shop_c_delivery_id      => $import->{data}->{shipping}->{id},
+    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_ordernumber        => $import->{data}->{number},
+    shop_trans_id           => $import->{data}->{id},
+    tax_included            => $self->config->pricetype eq "brutto" ? 1 : 0,
+  );
+  my $shop_order = SL::DB::ShopOrder->new(%columns);
+  return $shop_order;
+}
 
 sub get_categories {
   my ($self) = @_;
@@ -257,7 +207,7 @@ sub get_version {
     return SL::JSON::decode_json($data_json);
   }else{
     my %return = ( success => 0,
-                   data  => { version => $url . ": " . $status_line, revision => $type },
+                   data    => { version => $url . ": " . $status_line, revision => $type },
                    message => "Server not found or wrong data type",
                 );
     return \%return;
@@ -291,11 +241,9 @@ sub update_part {
   my @upload_img = ();
   foreach my $img (@{ $images }) {
     my $file               = SL::File->get(id => $img->file->id );
-    my $file_path          = $file->get_file;
     my ($path, $extension) = (split /\./, $file->file_name);
     my $content            = File::Slurp::read_file($file->get_file);
-
-    my $temp ={ ( link        => 'data:' . $file->mime_type . ';base64,' . MIME::Base64::encode($content),
+    my $temp ={ ( link        => 'data:' . $file->mime_type . ';base64,' . MIME::Base64::encode($content, ""), #$content, # MIME::Base64::encode($content),
                   description => $img->file->title,
                   position    => $img->position,
                   extension   => $extension,
@@ -315,6 +263,7 @@ sub update_part {
 #  }
 
   # get the right price
+  # TODO In extra Helper??
   my ( $price_src_str, $price_src_id ) = split(/\//,$shop_part->active_price_source);
   require SL::DB::Part;
   my $price;
@@ -401,6 +350,7 @@ sub update_part {
 
   my $dataString = SL::JSON::to_json(\%shop_data);
   $dataString    = encode_utf8($dataString);
+
   my $upload_content;
   my $upload;
   if($import->{success}){
@@ -454,6 +404,7 @@ sub init_connector {
   );
 
   return $ua;
+
 }
 
 1;
diff --git a/doc/dokumentation.xml b/doc/dokumentation.xml
index 1244963de..17cf19ab5 100644
--- a/doc/dokumentation.xml
+++ b/doc/dokumentation.xml
@@ -143,8 +143,9 @@
         <title>Benötigte Perl-Pakete installieren</title>
 
         <para>Zum Betrieb von kivitendo werden zwingend ein Webserver (meist
-        Apache) und ein Datenbankserver (PostgreSQL) in einer aktuellen Version
-        (s.a. Liste der unterstützten Betriebssysteme) benötigt.</para>
+        Apache) und ein Datenbankserver (PostgreSQL) in einer aktuellen
+        Version (s.a. Liste der unterstützten Betriebssysteme)
+        benötigt.</para>
 
         <para>Zusätzlich benötigt kivitendo einige Perl-Pakete, die nicht
         Bestandteil einer Standard-Perl-Installation sind. Um zu überprüfen,
@@ -303,7 +304,7 @@
             <para><literal>Text::Iconv</literal></para>
           </listitem>
 
-           <listitem>
+          <listitem>
             <para><literal>Text::Unidecode</literal></para>
           </listitem>
 
@@ -319,8 +320,9 @@
             <para><literal>YAML</literal></para>
           </listitem>
         </itemizedlist>
-        <para>Seit Version größer v3.5.0 sind die folgenden Pakete hinzugekommen:
-        <literal>Text::Unidecode</literal></para>
+
+        <para>Seit Version größer v3.5.0 sind die folgenden Pakete
+        hinzugekommen: <literal>Text::Unidecode</literal></para>
 
         <para>Seit Version v3.4.0 sind die folgenden Pakete hinzugekommen:
         <literal>Algorithm::CheckDigits</literal><literal>PBKDF2::Tiny</literal></para>
@@ -428,6 +430,7 @@ cpan HTML::Restrict</programlisting>
           <programlisting>cpan Rose::Db::Object</programlisting>
         </sect3>
       </sect2>
+
       <sect2>
         <title>Andere Pakete installieren</title>
 
@@ -448,7 +451,6 @@ cpan HTML::Restrict</programlisting>
 
         <para>OpenSuSE: <programlisting>zypper install poppler-tools</programlisting></para>
       </sect2>
-
     </sect1>
 
     <sect1 id="Manuelle-Installation-des-Programmpaketes"
@@ -512,10 +514,9 @@ tar xvzf kivitendo-erp-3.4.1.tgz</programlisting>
 git clone https://github.com/kivitendo/kivitendo-erp.git
 cd kivitendo-erp/
 git checkout `git tag -l | egrep -ve "(beta|rc)" | tail -1`</programlisting>
-        Erläuterung: Der Befehl wechselt zur letzten Stable-Version (git tag -l listet
-       alle Tags auf, das egrep schmeisst alle Einträge mit beta oder rc raus und
-       das tail gibt davon den obersten Treffer zurück).
-
+        Erläuterung: Der Befehl wechselt zur letzten Stable-Version (git tag
+        -l listet alle Tags auf, das egrep schmeisst alle Einträge mit beta
+        oder rc raus und das tail gibt davon den obersten Treffer zurück).
         Sehr sinnvoll ist es, direkt im Anschluss einen eigenen Branch zu
         erzeugen, um bspw. seine eigenen Druckvorlagen-Anpassungen damit zu
         verwalten. Hierfür reicht ein simples <programlisting>  git checkout -b meine_eigenen_änderungen</programlisting>
@@ -523,9 +524,8 @@ git checkout `git tag -l | egrep -ve "(beta|rc)" | tail -1`</programlisting>
         url="http://www-cs-students.stanford.edu/~blynn/gitmagic/index.html">
         Git Magic</ulink>).</para>
 
-<para>
-        Ein beispielhafter Workflow für Druckvorlagen-Anpassungen von 3.4.1 nach 3.5:
-        <programlisting>
+        <para>Ein beispielhafter Workflow für Druckvorlagen-Anpassungen von
+        3.4.1 nach 3.5: <programlisting>
 $ git clone https://github.com/kivitendo/kivitendo-erp.git
 $ cd kivitendo-erp/
 $ git checkout release-3.4.1     # das ist der aktuelle release, den wir wollen
@@ -682,29 +682,40 @@ password =
 [system]
 default_manager = german</programlisting>
 
-		<para>Für kivitendo Installationen in der Schweiz sollte hier <varname>german</varname>
-		durch <varname>swiss</varname> ersetzt werden.</para>
-		<para>Die Einstellung <varname>default_manager = swiss</varname> bewirkt:</para>
-		<itemizedlist>
-            <listitem>
-              <para>Beim Erstellen einer neuen Datenbank in der kivitendo Administration
-              werden automatisch die Standard-Werte für die Schweiz voreingestellt:
-              Währung CHF, 5er-Rundung, Schweizer KMU-Kontenplan, Sollversteuerung,
-              Aufwandsmethode, Bilanzierung (die Werte können aber manuell angepasst werden).</para>
-			</listitem>
-			<listitem>
-				<para>Einstellen der Standardkonten für Rundungserträge und -aufwendungen
-			(unter Mandantenkonfiguration → Standardkonten veränderbar)</para>
-			</listitem>
-			<listitem>
-				<para>das verwendete Zahlenformat wird auf <varname>1'000.00</varname> eingestellt
-				 (unter Programm → Benutzereinstellungen veränderbar)</para>
-			</listitem>
-			<listitem>
-				<para>DATEV-Automatik und UStVA werden nicht angezeigt, Erfolgsrechnung
-				ersetzt GUV ( unter Mandantenkonfiguration → Features veränderbar)</para>
-			</listitem>
-		</itemizedlist>
+        <para>Für kivitendo Installationen in der Schweiz sollte hier
+        <varname>german</varname> durch <varname>swiss</varname> ersetzt
+        werden.</para>
+
+        <para>Die Einstellung <varname>default_manager = swiss</varname>
+        bewirkt:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>Beim Erstellen einer neuen Datenbank in der kivitendo
+            Administration werden automatisch die Standard-Werte für die
+            Schweiz voreingestellt: Währung CHF, 5er-Rundung, Schweizer
+            KMU-Kontenplan, Sollversteuerung, Aufwandsmethode, Bilanzierung
+            (die Werte können aber manuell angepasst werden).</para>
+          </listitem>
+
+          <listitem>
+            <para>Einstellen der Standardkonten für Rundungserträge und
+            -aufwendungen (unter Mandantenkonfiguration → Standardkonten
+            veränderbar)</para>
+          </listitem>
+
+          <listitem>
+            <para>das verwendete Zahlenformat wird auf
+            <varname>1'000.00</varname> eingestellt (unter Programm →
+            Benutzereinstellungen veränderbar)</para>
+          </listitem>
+
+          <listitem>
+            <para>DATEV-Automatik und UStVA werden nicht angezeigt,
+            Erfolgsrechnung ersetzt GUV ( unter Mandantenkonfiguration →
+            Features veränderbar)</para>
+          </listitem>
+        </itemizedlist>
 
         <para>Nutzt man wiederkehrende Rechnungen, kann man unter
         <varname>[periodic_invoices]</varname> den Login eines Benutzers
@@ -1038,7 +1049,6 @@ Require all denied
             <programlisting>
   Order Deny,Allow
   Deny from All </programlisting>
-
           </warning>
 
           <para>Seit mod_fcgid-Version 2.3.6 gelten sehr kleine Grenzen für
@@ -1098,8 +1108,8 @@ Alias       /url/for/kivitendo-erp-fcgid/          /path/to/kivitendo-erp/</prog
         Konfigurationsmöglichkeiten sprengen allerdings den Rahmen dieser
         Anleitung, hier ein Hinweis auf einen entsprechenden <ulink
         url="http://redmine.kivitendo-premium.de/boards/1/topics/142">Foreneintrag
-        (Stand Sept. 2015)</ulink> und einen aktuellen (Stand Mai 2017)
-        <ulink url="https://mozilla.github.io/server-side-tls/ssl-config-generator/">
+        (Stand Sept. 2015)</ulink> und einen aktuellen (Stand Mai 2017) <ulink
+        url="https://mozilla.github.io/server-side-tls/ssl-config-generator/">
         SSL-Konfigurations-Generator</ulink>.</para>
       </sect2>
     </sect1>
@@ -1121,12 +1131,12 @@ Alias       /url/for/kivitendo-erp-fcgid/          /path/to/kivitendo-erp/</prog
       Servers integriert werden muss, damit er automatisch gestartet wird.
       Dies kann kivitendo nicht für Sie erledigen.</para>
 
-      <para>Da der Taskserver als Perlscript läuft, wird Arbeitsspeicher,
-      der einmal benötigt wurde, nicht mehr an das Betriebssystem zurückgegeben,
+      <para>Da der Taskserver als Perlscript läuft, wird Arbeitsspeicher, der
+      einmal benötigt wurde, nicht mehr an das Betriebssystem zurückgegeben,
       solange der Taskserver läuft. Dies kann dazu führen, dass ein länger
       laufender Taskserver mit der Zeit immer mehr Arbeitsspeicher für sich
-      beansprucht. Es ist deshalb sinnvoll, dass der Taskserver in regelmässigen
-      Abständen neu gestartet wird.</para>
+      beansprucht. Es ist deshalb sinnvoll, dass der Taskserver in
+      regelmässigen Abständen neu gestartet wird.</para>
 
       <sect2 id="Konfiguration-des-Task-Servers">
         <title>Verfügbare und notwendige Konfigurationsoptionen</title>
@@ -1191,8 +1201,8 @@ Alias       /url/for/kivitendo-erp-fcgid/          /path/to/kivitendo-erp/</prog
         anstelle eines symbolischen Links verwendet werden können.</para>
 
         <sect3>
-          <title>SystemV-basierende Systeme (z.B. ältere Debian, ältere OpenSUSE,
-          ältere Fedora)</title>
+          <title>SystemV-basierende Systeme (z.B. ältere Debian, ältere
+          OpenSUSE, ältere Fedora)</title>
 
           <para>Kopieren Sie die Datei
           <filename>scripts/boot/system-v/kivitendo-task-server</filename>
@@ -1241,18 +1251,23 @@ insserv kivitendo-task-server</programlisting>
           <title>systemd-basierende Systeme (z.B. neure openSUSE, neuere
           Fedora, neuere Ubuntu und neuere Debians)</title>
 
-          <para>Kopieren Sie die Datei <filename>scripts/boot/systemd/kivitendo-task-server.service</filename> nach
-          <filename>/etc/systemd/system/</filename>. Passen Sie in der kopierten Datei den Pfad zum Task-Server an (Zeilen
-          <literal>ExecStart=....</literal> und <literal>ExecStop=...</literal>).</para>
+          <para>Kopieren Sie die Datei
+          <filename>scripts/boot/systemd/kivitendo-task-server.service</filename>
+          nach <filename>/etc/systemd/system/</filename>. Passen Sie in der
+          kopierten Datei den Pfad zum Task-Server an (Zeilen
+          <literal>ExecStart=....</literal> und
+          <literal>ExecStop=...</literal>).</para>
 
-          <para>Machen Sie anschließend das Script systemd bekannt, und binden Sie es in den Boot-Prozess ein. Dazu führen Sie die folgenden
-          Befehl aus:</para>
+          <para>Machen Sie anschließend das Script systemd bekannt, und binden
+          Sie es in den Boot-Prozess ein. Dazu führen Sie die folgenden Befehl
+          aus:</para>
 
           <programlisting>systemctl daemon-reload
 systemctl enable kivitendo-task-server.service</programlisting>
 
-          <para>Wenn Sie den Task-Server jetzt sofort starten möchten, anstatt den Server neu zu starten, so können Sie das mit dem
-          folgenden Befehl tun:</para>
+          <para>Wenn Sie den Task-Server jetzt sofort starten möchten, anstatt
+          den Server neu zu starten, so können Sie das mit dem folgenden
+          Befehl tun:</para>
 
           <programlisting>systemctl start kivitendo-task-server.service</programlisting>
         </sect3>
@@ -2234,14 +2249,14 @@ systemctl enable kivitendo-task-server.service</programlisting>
         und nicht nur Teile davon, da dies sonst oft zu einer odt-Datei führt,
         die vom Parser nicht korrekt gelesen werden kann.</para>
 
-        <para>Mahnungen können unter folgenden Einschränkungen mit den odt-Vorlagen
-        im Vorlagensatz rev-odt erzeugt werden:</para>
+        <para>Mahnungen können unter folgenden Einschränkungen mit den
+        odt-Vorlagen im Vorlagensatz rev-odt erzeugt werden:</para>
 
         <itemizedlist>
           <listitem>
             <para>als Druckoption steht nur 'PDF(OpenDocument/OASIS)' zur
-            Verfügung, das heisst, die Mahnungen werden als PDF-Datei ausgegeben.
-            </para>
+            Verfügung, das heisst, die Mahnungen werden als PDF-Datei
+            ausgegeben.</para>
           </listitem>
 
           <listitem>
@@ -2254,10 +2269,10 @@ systemctl enable kivitendo-task-server.service</programlisting>
         <para>Mehrere Mahnungen für eine Kundin / einen Kunden werden zu einer
         PDF-Datei zusammengefasst</para>
 
-        <para>Die Vorlagen zahlungserinnerung.odt sowie mahnung.odt sind für das
-        Erstellen einer Zahlungserinnerung bzw. Mahnung selbst vorgesehen, die
-        Vorlage mahnung_invoice.odt für das Erstellen einer Rechnung über die
-        verrechneten Mahngebühren und Verzugszinsen.</para>
+        <para>Die Vorlagen zahlungserinnerung.odt sowie mahnung.odt sind für
+        das Erstellen einer Zahlungserinnerung bzw. Mahnung selbst vorgesehen,
+        die Vorlage mahnung_invoice.odt für das Erstellen einer Rechnung über
+        die verrechneten Mahngebühren und Verzugszinsen.</para>
 
         <para>Zur Zeit gibt es in kivitendo noch keine Möglichkeit,
         odt-Vorlagen bei Briefen und Pflichtenheften einzusetzen.
@@ -2358,9 +2373,9 @@ systemctl enable kivitendo-task-server.service</programlisting>
       <title>OpenDocument-Vorlagen</title>
 
       <para>kivitendo unterstützt die Verwendung von Vorlagen im
-      OpenDocument-Format, wie es LibreOffice oder OpenOffice (ab Version 2) erzeugen.
-      kivitendo kann dabei sowohl neue OpenDocument-Dokumente als auch aus
-      diesen direkt PDF-Dateien erzeugen. Um die Unterstützung von
+      OpenDocument-Format, wie es LibreOffice oder OpenOffice (ab Version 2)
+      erzeugen. kivitendo kann dabei sowohl neue OpenDocument-Dokumente als
+      auch aus diesen direkt PDF-Dateien erzeugen. Um die Unterstützung von
       OpenDocument-Vorlagen zu aktivieren muss in der Datei
       <filename>config/kivitendo.conf</filename> die Variable
       <literal>opendocument</literal> im Abschnitt
@@ -2369,42 +2384,47 @@ systemctl enable kivitendo-task-server.service</programlisting>
 
       <para>Während die Erzeugung von reinen OpenDocument-Dateien keinerlei
       weitere Software benötigt, wird zur Umwandlung dieser Dateien in PDF
-      LibreOffice oder OpenOffice benötigt. Soll dieses Feature genutzt werden, so muss
-      neben LibreOffice oder OpenOffice auch der “X virtual frame buffer”
-      (xvfb) installiert werden. Bei Debian ist er im Paket “xvfb” enthalten.
-      Andere Distributionen enthalten ihn in anderen Paketen.</para>
+      LibreOffice oder OpenOffice benötigt. Soll dieses Feature genutzt
+      werden, so muss neben LibreOffice oder OpenOffice auch der “X virtual
+      frame buffer” (xvfb) installiert werden. Bei Debian ist er im Paket
+      “xvfb” enthalten. Andere Distributionen enthalten ihn in anderen
+      Paketen.</para>
 
       <para>Nach der Installation müssen in der Datei
       <filename>config/kivitendo.conf</filename> im Abschnitt
-      <literal>applications</literal> zwei weitere Variablen
-      angepasst werden:</para>
-      <para><literal>openofficeorg_writer</literal> muss den
-      vollständigen Pfad zu LibreOffice oder OpenOffice enthalten.
-      Dabei dürfen keine Anführungszeichen eingesetzt werden.</para>
+      <literal>applications</literal> zwei weitere Variablen angepasst
+      werden:</para>
+
+      <para><literal>openofficeorg_writer</literal> muss den vollständigen
+      Pfad zu LibreOffice oder OpenOffice enthalten. Dabei dürfen keine
+      Anführungszeichen eingesetzt werden.</para>
+
       <para>Beispiel für Debian oder Ubuntu:</para>
+
       <programlisting>openofficeorg_writer = /usr/bin/libreoffice</programlisting>
+
       <para><literal>xvfb</literal> muss den Pfad zum “X virtual frame buffer”
       enthalten.</para>
 
       <para>Zusätzlich gibt es zwei verschiedene Arten, wie kivitendo mit
-      LibreOffice bzw. OpenOffice kommuniziert. Die erste Variante, die benutzt
-      wird, wenn die Variable <literal>$openofficeorg_daemon</literal> gesetzt
-      ist, startet ein LibreOffice oder OpenOffice, das auch nach der Umwandlung
-      des Dokumentes gestartet bleibt. Bei weiteren Umwandlungen wird dann diese
-      laufende Instanz benutzt. Der Vorteil ist, dass die Zeit zur Umwandlung
-      deutlich reduziert wird, weil nicht für jedes Dokument ein LibreOffice bzw.
-      OpenOffice gestartet werden muss. Der Nachteil ist, dass diese Methode
-      Python und die Python-UNO-Bindings benötigt, die Bestandteil von LibreOffice
-      bzw. OpenOffice sind.</para>
+      LibreOffice bzw. OpenOffice kommuniziert. Die erste Variante, die
+      benutzt wird, wenn die Variable <literal>$openofficeorg_daemon</literal>
+      gesetzt ist, startet ein LibreOffice oder OpenOffice, das auch nach der
+      Umwandlung des Dokumentes gestartet bleibt. Bei weiteren Umwandlungen
+      wird dann diese laufende Instanz benutzt. Der Vorteil ist, dass die Zeit
+      zur Umwandlung deutlich reduziert wird, weil nicht für jedes Dokument
+      ein LibreOffice bzw. OpenOffice gestartet werden muss. Der Nachteil ist,
+      dass diese Methode Python und die Python-UNO-Bindings benötigt, die
+      Bestandteil von LibreOffice bzw. OpenOffice sind.</para>
 
       <note>
         <para>Für die Verbindung zu LibreOffice bzw. OpenOffice wird
         normalerweise der Python-Interpreter
-        <filename>/usr/bin/python</filename> benutzt.
-        Sollte dies nicht der richtige sein, so kann man mit zwei
-        Konfigurationsvariablen entscheiden, welcher Python-Interpreter
-        genutzt wird. Mit der Option <literal>python_uno</literal> aus dem
-        Abschnitt <literal>applications</literal> wird der Interpreter selber
+        <filename>/usr/bin/python</filename> benutzt. Sollte dies nicht der
+        richtige sein, so kann man mit zwei Konfigurationsvariablen
+        entscheiden, welcher Python-Interpreter genutzt wird. Mit der Option
+        <literal>python_uno</literal> aus dem Abschnitt
+        <literal>applications</literal> wird der Interpreter selber
         festgelegt; sie steht standardmäßig auf dem eben erwähnten Wert
         <literal>/usr/bin/python</literal>.</para>
 
@@ -2421,27 +2441,26 @@ systemctl enable kivitendo-task-server.service</programlisting>
       </note>
 
       <para>Ist <literal>$openofficeorg_daemon</literal> nicht gesetzt, so
-      wird für jedes Dokument LibreOffice bzw. OpenOffice neu gestartet
-      und die Konvertierung mit Hilfe eines Makros durchgeführt. Dieses
-      Makro muss in der Dokumentenvorlage enthalten sein und
+      wird für jedes Dokument LibreOffice bzw. OpenOffice neu gestartet und
+      die Konvertierung mit Hilfe eines Makros durchgeführt. Dieses Makro muss
+      in der Dokumentenvorlage enthalten sein und
       “Standard.Conversion.ConvertSelfToPDF()” heißen. Die Beispielvorlage
-      ‘<literal>templates/print/rev-odt/invoice.odt</literal>’
-      enthält ein solches Makro, das in jeder anderen Dokumentenvorlage
-      ebenfalls enthalten sein muss.</para>
+      ‘<literal>templates/print/rev-odt/invoice.odt</literal>’ enthält ein
+      solches Makro, das in jeder anderen Dokumentenvorlage ebenfalls
+      enthalten sein muss.</para>
 
-      <para>Als letztes muss herausgefunden werden, welchen Namen
-      OpenOffice bzw. LibreOffice dem Verzeichnis mit den Benutzereinstellungen
-      gibt. Unter Debian ist dies momentan
-      <literal>~/.config/libreoffice</literal>. kivitendo verwendet das
-      Verzeichnis <literal>users/.openoffice.org2</literal>.
-      Eventuell muss dieses Verzeichnis umbenannt werden.</para>
+      <para>Als letztes muss herausgefunden werden, welchen Namen OpenOffice
+      bzw. LibreOffice dem Verzeichnis mit den Benutzereinstellungen gibt.
+      Unter Debian ist dies momentan <literal>~/.config/libreoffice</literal>.
+      kivitendo verwendet das Verzeichnis
+      <literal>users/.openoffice.org2</literal>. Eventuell muss dieses
+      Verzeichnis umbenannt werden.</para>
 
       <para>Dieses Verzeichnis, wie auch das komplette
       <literal>users</literal>-Verzeichnis, muss vom Webserver beschreibbar
       sein. Dieses wurde bereits erledigt (siehe <xref
-      linkend="Manuelle-Installation-des-Programmpaketes"/>), kann aber
-      erneut überprüft werden, wenn die Konvertierung nach PDF
-      fehlschlägt.</para>
+      linkend="Manuelle-Installation-des-Programmpaketes"/>), kann aber erneut
+      überprüft werden, wenn die Konvertierung nach PDF fehlschlägt.</para>
 
       <sect2>
         <title>OpenDocument (odt) Druckvorlagen mit Makros</title>
@@ -2482,22 +2501,21 @@ systemctl enable kivitendo-task-server.service</programlisting>
             </listitem>
 
             <listitem>
-              <para>Druckerbeschreibung → aussagekräftiger Text: wird in
-              der Auftrags- bzw. Rechnungsmaske als Auswahl angezeigt (z.B.
-              mit Einzahlungsschein Bank xy)</para>
+              <para>Druckerbeschreibung → aussagekräftiger Text: wird in der
+              Auftrags- bzw. Rechnungsmaske als Auswahl angezeigt (z.B. mit
+              Einzahlungsschein Bank xy)</para>
             </listitem>
 
             <listitem>
-              <para>Druckbefehl → beliebiger Text (hat für das Erzeugen
-              von Aufträgen oder Rechnungen als odt-Datei keine Bedeutung,
-              darf aber nicht leer sein)</para>
+              <para>Druckbefehl → beliebiger Text (hat für das Erzeugen von
+              Aufträgen oder Rechnungen als odt-Datei keine Bedeutung, darf
+              aber nicht leer sein)</para>
             </listitem>
 
             <listitem>
-              <para>Vorlagenkürzel → besr bzw. selbst gewähltes
-              Vorlagensuffix (muss genau der Zeichenfolge entsprechen, die
-              zwischen "invoice_" bzw. "sales_order_" und ".odt"
-              steht.)</para>
+              <para>Vorlagenkürzel → besr bzw. selbst gewähltes Vorlagensuffix
+              (muss genau der Zeichenfolge entsprechen, die zwischen
+              "invoice_" bzw. "sales_order_" und ".odt" steht.)</para>
             </listitem>
 
             <listitem>
@@ -2516,8 +2534,7 @@ systemctl enable kivitendo-task-server.service</programlisting>
 
           <itemizedlist>
             <listitem>
-              <para>Programm → Benutzereinstellungen →
-              Druckoptionen</para>
+              <para>Programm → Benutzereinstellungen → Druckoptionen</para>
             </listitem>
 
             <listitem>
@@ -2529,8 +2546,8 @@ systemctl enable kivitendo-task-server.service</programlisting>
             </listitem>
 
             <listitem>
-              <para>Standarddrucker → gewünschte Druckerbeschreibung
-              auswählen (z.B. mit Einzahlungsschein Bank xy)</para>
+              <para>Standarddrucker → gewünschte Druckerbeschreibung auswählen
+              (z.B. mit Einzahlungsschein Bank xy)</para>
             </listitem>
 
             <listitem>
@@ -2606,8 +2623,8 @@ systemctl enable kivitendo-task-server.service</programlisting>
                   </listitem>
 
                   <listitem>
-					<para>DDDEND: muss am Ende der Zeile vorhanden sein</para>
-				  </listitem>
+                    <para>DDDEND: muss am Ende der Zeile vorhanden sein</para>
+                  </listitem>
                 </itemizedlist></para>
             </listitem>
 
@@ -2655,8 +2672,7 @@ systemctl enable kivitendo-task-server.service</programlisting>
 
           <itemizedlist>
             <listitem>
-              <para>Extras → Optionen → Sicherheit →
-              Makrosicherheit</para>
+              <para>Extras → Optionen → Sicherheit → Makrosicherheit</para>
             </listitem>
 
             <listitem>
@@ -2668,8 +2684,8 @@ systemctl enable kivitendo-task-server.service</programlisting>
 
             <listitem>
               <para>Beim Öffnen einer odt-Rechnung oder eines odt-Auftrags bei
-              der entsprechenden Nachfrage "Makros ausführen" auswählen.
-              </para>
+              der entsprechenden Nachfrage "Makros ausführen"
+              auswählen.</para>
 
               <para><emphasis role="bold">Wichtig</emphasis>: die Makros sind
               so eingestellt, dass sie beim Öffnen der Vorlagen selbst nicht
@@ -2688,42 +2704,42 @@ systemctl enable kivitendo-task-server.service</programlisting>
       <sect2 id="booking.dates">
         <title>Datum bei Buchungen</title>
 
-        <para>Seit der Version 3.5 werden für Buchungen in kivitendo einheitlich
-        folgende Bezeichnungen verwendet:</para>
+        <para>Seit der Version 3.5 werden für Buchungen in kivitendo
+        einheitlich folgende Bezeichnungen verwendet:</para>
 
         <itemizedlist>
           <listitem>
-            <para><option>Erfassungsdatum</option> (en: <option>Entry Date</option>,
-            code: <option>Gldate</option>)</para>
+            <para><option>Erfassungsdatum</option> (en: <option>Entry
+            Date</option>, code: <option>Gldate</option>)</para>
 
-            <para>bezeichnet das Datum, an dem die Buchung in kivitendo erfasst wurde.
-            </para>
+            <para>bezeichnet das Datum, an dem die Buchung in kivitendo
+            erfasst wurde.</para>
           </listitem>
 
           <listitem>
-            <para><option>Buchungsdatum</option> (en: <option>Booking Date</option>,
-            code: <option>Transdate</option>)</para>
+            <para><option>Buchungsdatum</option> (en: <option>Booking
+            Date</option>, code: <option>Transdate</option>)</para>
 
-            <para>bezeichnet das buchhaltungstechnisch für eine Buchung relevante
-            Datum</para>
+            <para>bezeichnet das buchhaltungstechnisch für eine Buchung
+            relevante Datum</para>
 
             <para>Das <option>Rechnungsdatum</option> bei Verkaufs- und
             Einkaufsrechnungen entspricht dem Buchungsdatum. Das heisst, in
             Berichten wie dem Buchungsjournal, in denen eine Spalte
-            <option>Buchungsdatum</option> angezeigt werden kann, erscheint hier
-            im Fall von Rechnungen das Rechnungsdatum.</para>
+            <option>Buchungsdatum</option> angezeigt werden kann, erscheint
+            hier im Fall von Rechnungen das Rechnungsdatum.</para>
           </listitem>
 
           <listitem>
-            <para>Bezieht sich ein verbuchter Beleg auf einen Zeitpunkt, der nicht mit
-            dem Buchungsdatum übereinstimmt, so kann dieses Datum momentan in kivitendo
-            nur unter Bemerkungen erfasst werden.</para>
+            <para>Bezieht sich ein verbuchter Beleg auf einen Zeitpunkt, der
+            nicht mit dem Buchungsdatum übereinstimmt, so kann dieses Datum
+            momentan in kivitendo nur unter Bemerkungen erfasst werden.</para>
 
-            <para>Möglicherweise wird für solche Fälle in einer späteren Version von
-            kivitendo ein dritter Datumswert für Buchungen erstellt. (Beispiel:
-            Einkaufsbeleg stammt aus einem früheren Jahr, das bereits
-            buchhaltungstechnisch abgeschlossen wurde, und muss deshalb später
-            verbucht werden.)</para>
+            <para>Möglicherweise wird für solche Fälle in einer späteren
+            Version von kivitendo ein dritter Datumswert für Buchungen
+            erstellt. (Beispiel: Einkaufsbeleg stammt aus einem früheren Jahr,
+            das bereits buchhaltungstechnisch abgeschlossen wurde, und muss
+            deshalb später verbucht werden.)</para>
           </listitem>
         </itemizedlist>
       </sect2>
@@ -2814,21 +2830,23 @@ systemctl enable kivitendo-task-server.service</programlisting>
         eingestellt werden.</para>
 
         <para>Für die Schweiz sind folgende Einstellungen üblich:
-		<itemizedlist>
+        <itemizedlist>
             <listitem>
-				<para>Sollversteuerung</para>
+              <para>Sollversteuerung</para>
             </listitem>
+
             <listitem>
-				<para>Aufwandsmethode</para>
-			</listitem>
-			<listitem>
-				<para>Bilanzierung</para>
-			</listitem>
-		</itemizedlist>
-		Diese Einstellungen werden automatisch beim Erstellen einer neuen
-		Datenbank vorausgewählt, wenn in <filename>config/kivitendo.conf</filename> unter
-		<varname>[system]</varname> <literal>default_manager = swiss</literal> eingestellt ist.
-        </para>
+              <para>Aufwandsmethode</para>
+            </listitem>
+
+            <listitem>
+              <para>Bilanzierung</para>
+            </listitem>
+          </itemizedlist> Diese Einstellungen werden automatisch beim
+        Erstellen einer neuen Datenbank vorausgewählt, wenn in
+        <filename>config/kivitendo.conf</filename> unter
+        <varname>[system]</varname> <literal>default_manager = swiss</literal>
+        eingestellt ist.</para>
 
         <para>Beim Upgrade bestehender Mandanten wird eur ausgelesen und die
         Variablen werden so gesetzt, daß sich an der Funktionalität nichts
@@ -2907,9 +2925,8 @@ systemctl enable kivitendo-task-server.service</programlisting>
 
         <para>Die folgenden Schritte sind notwendig, um das Konto manuell
         anzulegen und zu konfigurieren. Zuerst wird in
-        <guimenu>System</guimenu> →
-        <guisubmenu>Kontenübersicht</guisubmenu> → <guimenuitem>Konto
-        erfassen</guimenuitem> das Konto angelegt.</para>
+        <guimenu>System</guimenu> → <guisubmenu>Kontenübersicht</guisubmenu> →
+        <guimenuitem>Konto erfassen</guimenuitem> das Konto angelegt.</para>
 
         <screenshot>
           <screeninfo>Konto 3804 erfassen</screeninfo>
@@ -2940,9 +2957,8 @@ systemctl enable kivitendo-task-server.service</programlisting>
 
         <para>Als Drittes wird ein neuer Eintrag mit Steuerschlüssel 13 für
         Konto 3804 (19%) angelegt. Dazu unter <guimenu>System</guimenu> →
-        <guisubmenu>Steuern</guisubmenu> →
-        <guimenuitem>Erfassen</guimenuitem> auswählen und die Werte aus dem
-        Screenshot übernehmen.</para>
+        <guisubmenu>Steuern</guisubmenu> → <guimenuitem>Erfassen</guimenuitem>
+        auswählen und die Werte aus dem Screenshot übernehmen.</para>
 
         <screenshot>
           <screeninfo>Steuerschlüssel 13 für 3804 (19%) anlegen</screeninfo>
@@ -3045,88 +3061,102 @@ systemctl enable kivitendo-task-server.service</programlisting>
     </sect1>
 
     <sect1 id="config.erfolgsrechnung">
-	  <title>Erfolgsrechnung</title>
-
-	  <para>Seit der Version 3.4.1 existiert in kivitendo der Bericht <emphasis role="bold">
-	  Erfolgsrechnung</emphasis>.</para>
-
-	  <para>Die Erfolgsrechnung kann in der Mandantenkonfiguration unter Features
-	  an- oder abgeschaltet werden. Mit der Einstellung <varname>default_manager = swiss
-	  </varname> in der <filename>config/kivitendo.conf</filename> wird beim neu Erstellen
-	  einer Datenbank automatisch die Anzeige der Erfolgsrechnung im Menü <guimenu>Berichte
-	  </guimenu> ausgewählt und ersetzt dort die GUV.</para>
-
-	  <para>Im Gegensatz zur GUV werden bei der Erfolgsrechnung sämtliche Aufwands- und
-	  Erlöskonten einzeln aufgelistet (analog zur Bilanz), sortiert nach ERTRAG und AUFWAND.</para>
-
-	  <para>Bei den Konteneinstellungen muss bei jedem Konto, das in der Erfolgsrechnung
-	  erscheinen soll, unter <varname>Sonstige Einstellungen/Erfolgsrechnung</varname>
-	  entweder <literal>01.Ertrag</literal> oder <literal>06.Aufwand</literal>  ausgewählt
-	  werden.</para>
-
-	  <para>Wird bei einem Erlöskonto <literal>06.Aufwand</literal> ausgewählt,
-	  so wird dieses Konto als Aufwandsminderung unter AUFWAND aufgelistet.</para>
-
-	  <para>Wird bei einem Aufwandskonto <literal>01.Ertrag</literal> ausgewählt,
-	  so wird dieses Konto als Ertragsminderung unter ERTRAG aufgelistet.</para>
-
-	  <para>Soll bei einer bereits bestehenden Buchhaltung in Zukunft zusätzlich
-	  die Erfolgsrechnung als Bericht verwendet werden, so müssen die Einstellungen
-	  zu allen Erlös- und Aufwandskonten unter <varname>Sonstige
-	  Einstellungen/Erfolgsrechnung</varname> überprüft und allenfalls neu gesetzt werden.</para>
+      <title>Erfolgsrechnung</title>
+
+      <para>Seit der Version 3.4.1 existiert in kivitendo der Bericht
+      <emphasis role="bold"> Erfolgsrechnung</emphasis>.</para>
+
+      <para>Die Erfolgsrechnung kann in der Mandantenkonfiguration unter
+      Features an- oder abgeschaltet werden. Mit der Einstellung
+      <varname>default_manager = swiss </varname> in der
+      <filename>config/kivitendo.conf</filename> wird beim neu Erstellen einer
+      Datenbank automatisch die Anzeige der Erfolgsrechnung im Menü
+      <guimenu>Berichte </guimenu> ausgewählt und ersetzt dort die GUV.</para>
+
+      <para>Im Gegensatz zur GUV werden bei der Erfolgsrechnung sämtliche
+      Aufwands- und Erlöskonten einzeln aufgelistet (analog zur Bilanz),
+      sortiert nach ERTRAG und AUFWAND.</para>
+
+      <para>Bei den Konteneinstellungen muss bei jedem Konto, das in der
+      Erfolgsrechnung erscheinen soll, unter <varname>Sonstige
+      Einstellungen/Erfolgsrechnung</varname> entweder
+      <literal>01.Ertrag</literal> oder <literal>06.Aufwand</literal>
+      ausgewählt werden.</para>
+
+      <para>Wird bei einem Erlöskonto <literal>06.Aufwand</literal>
+      ausgewählt, so wird dieses Konto als Aufwandsminderung unter AUFWAND
+      aufgelistet.</para>
+
+      <para>Wird bei einem Aufwandskonto <literal>01.Ertrag</literal>
+      ausgewählt, so wird dieses Konto als Ertragsminderung unter ERTRAG
+      aufgelistet.</para>
+
+      <para>Soll bei einer bereits bestehenden Buchhaltung in Zukunft
+      zusätzlich die Erfolgsrechnung als Bericht verwendet werden, so müssen
+      die Einstellungen zu allen Erlös- und Aufwandskonten unter
+      <varname>Sonstige Einstellungen/Erfolgsrechnung</varname> überprüft und
+      allenfalls neu gesetzt werden.</para>
     </sect1>
 
     <sect1 id="config.rounding">
-	  <title>Rundung in Verkaufsbelegen</title>
+      <title>Rundung in Verkaufsbelegen</title>
 
-	  <para>In der Schweiz hat die kleinste aktuell benutzte Münze den Wert von 5 Rappen (0.05 CHF).</para>
+      <para>In der Schweiz hat die kleinste aktuell benutzte Münze den Wert
+      von 5 Rappen (0.05 CHF).</para>
 
-	  <para>Auch wenn im elektronischen Zahlungsverkehr Beträge mit einer Genauigkeit
-	  von 0.01 CHF verwendet werden können, ist es trotzdem nach wie vor üblich,
-	  Rechnungen mit auf 0.05 CHF gerundeten Beträgen auszustellen.</para>
+      <para>Auch wenn im elektronischen Zahlungsverkehr Beträge mit einer
+      Genauigkeit von 0.01 CHF verwendet werden können, ist es trotzdem nach
+      wie vor üblich, Rechnungen mit auf 0.05 CHF gerundeten Beträgen
+      auszustellen.</para>
 
-	  <para>In kivitendo kann seit der Version 3.4.1 die Einstellung für eine solche
-	  Rundung pro Mandant / Datenbank festgelegt werden.</para>
+      <para>In kivitendo kann seit der Version 3.4.1 die Einstellung für eine
+      solche Rundung pro Mandant / Datenbank festgelegt werden.</para>
 
-	  <para>Die Einstellung wird beim Erstellen der Datenbank bei <literal>Genauigkeit</literal>
-	  festgelegt. Sie kann anschliessend über das Webinterface von kivitendo nicht mehr
-	  verändert werden.</para>
+      <para>Die Einstellung wird beim Erstellen der Datenbank bei
+      <literal>Genauigkeit</literal> festgelegt. Sie kann anschliessend über
+      das Webinterface von kivitendo nicht mehr verändert werden.</para>
 
-	  <para>Abhängig vom Wert für <varname>default_manager</varname> in
-	  <filename>config/kivitendo.conf</filename> werden dabei folgende
-	  Werte voreingestellt:</para>
-	  <itemizedlist>
+      <para>Abhängig vom Wert für <varname>default_manager</varname> in
+      <filename>config/kivitendo.conf</filename> werden dabei folgende Werte
+      voreingestellt:</para>
+
+      <itemizedlist>
         <listitem>
           <para>0.05 (default_manager = swiss)</para>
         </listitem>
+
         <listitem>
           <para>0.01 (default_manager = german)</para>
         </listitem>
       </itemizedlist>
+
       <para>Der Wert wird in der Datenbank in der Tabelle <varname>defaults
       </varname>in der Spalte <varname>precision</varname> gespeichert.</para>
 
       <para>In allen Verkaufsangeboten, Verkaufsaufträgen, Verkaufsrechnungen
-      und Verkaufsgutschriften wird der Endbetrag inkl. MWST gerundet,
-      wenn dieser nicht der eingestellten Genauigkeit entspricht.</para>
+      und Verkaufsgutschriften wird der Endbetrag inkl. MWST gerundet, wenn
+      dieser nicht der eingestellten Genauigkeit entspricht.</para>
 
       <para>Beim Buchen einer Verkaufsrechnung wird der Rundungsbetrag
       automatisch auf die in der Mandantenkonfiguration festgelegten
-      Standardkonten für Rundungserträge bzw. Rundungsaufwendungen gebucht.</para>
+      Standardkonten für Rundungserträge bzw. Rundungsaufwendungen
+      gebucht.</para>
 
-      <para>(Die berechnete MWST wird durch den Rundungsbetrag nicht mehr verändert.)</para>
+      <para>(Die berechnete MWST wird durch den Rundungsbetrag nicht mehr
+      verändert.)</para>
 
       <para>Die in den Druckvorlagen zur Verfügung stehenden Variablen
       <varname>quototal</varname>, <varname>ordtotal</varname> bzw.
       <varname>invtotal</varname> enthalten den gerundeten Betrag.</para>
 
-      <para><emphasis role="bold">Achtung:</emphasis> Werden Verkaufsbelege
-      in anderen Währungen als der Standardwährung erstellt, so muss in
-      kivitendo ab Version 3.4.1 die Genauigkeit 0.01 verwendet werden.</para>
-      <para>Das heisst, Firmen in der Schweiz, die teilweise Verkaufsrechnungen
-      in Euro oder anderen Währungen erstellen wollen, müssen beim Erstellen
-      der Datenbank als Genauigkeit 0.01 wählen und können zur Zeit die
-      5er Rundung noch nicht nutzen.</para>
+      <para><emphasis role="bold">Achtung:</emphasis> Werden Verkaufsbelege in
+      anderen Währungen als der Standardwährung erstellt, so muss in kivitendo
+      ab Version 3.4.1 die Genauigkeit 0.01 verwendet werden.</para>
+
+      <para>Das heisst, Firmen in der Schweiz, die teilweise
+      Verkaufsrechnungen in Euro oder anderen Währungen erstellen wollen,
+      müssen beim Erstellen der Datenbank als Genauigkeit 0.01 wählen und
+      können zur Zeit die 5er Rundung noch nicht nutzen.</para>
     </sect1>
 
     <sect1 id="config.client">
@@ -3642,8 +3672,8 @@ systemctl enable kivitendo-task-server.service</programlisting>
         linkend="dokumentenvorlagen-und-variablen.tag-style"/>).</para>
 
         <para>kivitendo unterstützt LaTeX-, HTML- und OpenDocument-Vorlagen.
-        Sofern es nicht ausdrücklich eingeschränkt wird, gilt das im
-        Folgenden gesagte für alle Vorlagenarten.</para>
+        Sofern es nicht ausdrücklich eingeschränkt wird, gilt das im Folgenden
+        gesagte für alle Vorlagenarten.</para>
 
         <para>Insgesamt sind technisch gesehen eine ganze Menge mehr Variablen
         verfügbar als hier aufgelistet werden. Die meisten davon können
@@ -4937,8 +4967,8 @@ systemctl enable kivitendo-task-server.service</programlisting>
               <term><varname>rounding</varname></term>
 
               <listitem>
-                <para>Betrag, um den <varname>invtotal</varname> gerundet wurde
-                (kann positiv oder negativ sein)</para>
+                <para>Betrag, um den <varname>invtotal</varname> gerundet
+                wurde (kann positiv oder negativ sein)</para>
               </listitem>
             </varlistentry>
 
@@ -5415,18 +5445,21 @@ systemctl enable kivitendo-task-server.service</programlisting>
         <sect3 id="dokumentenvorlagen-und-variablen.dunning-allgemein">
           <title>Allgemeine Variablen in Mahnungen</title>
 
-          <para>Die Variablen des Bearbeiters, bzw. Verkäufers stehen wie gewohnt als
-          <varname>employee_...</varname> bzw. <varname>salesman_...</varname> zur Verfügung.
-          Werden mehrere Rechnungen in einer Mahnung zusammengefasst, so werden
-          die Metadaten (Bearbeiter, Abteilung, etc) der ersten angemahnten Rechnung
-          im Ausdruck genommen.</para>
-          <para>Die Adressdaten des Kunden stehen als Variablen <varname>name</varname>,
-          <varname>street</varname>, <varname>zipcode</varname>,
-          <varname>city</varname>, <varname>country</varname>,
-          <varname>department_1</varname>, <varname>department_2</varname>,
-          und <varname>email</varname> zur Verfügung. Der Ansprechpartner <varname>cp_...</varname>
-          steht auch zu Verfügung, wird allerdings auch nur von der ersten angemahnten Rechnung (s.o.)
-          genommen.</para>
+          <para>Die Variablen des Bearbeiters, bzw. Verkäufers stehen wie
+          gewohnt als <varname>employee_...</varname> bzw.
+          <varname>salesman_...</varname> zur Verfügung. Werden mehrere
+          Rechnungen in einer Mahnung zusammengefasst, so werden die Metadaten
+          (Bearbeiter, Abteilung, etc) der ersten angemahnten Rechnung im
+          Ausdruck genommen.</para>
+
+          <para>Die Adressdaten des Kunden stehen als Variablen
+          <varname>name</varname>, <varname>street</varname>,
+          <varname>zipcode</varname>, <varname>city</varname>,
+          <varname>country</varname>, <varname>department_1</varname>,
+          <varname>department_2</varname>, und <varname>email</varname> zur
+          Verfügung. Der Ansprechpartner <varname>cp_...</varname> steht auch
+          zu Verfügung, wird allerdings auch nur von der ersten angemahnten
+          Rechnung (s.o.) genommen.</para>
 
           <para>Weitere Variablen beinhalten:</para>
 
@@ -6284,18 +6317,19 @@ Beschreibung: &lt;%description%&gt;
     </sect1>
 
     <sect1 id="features.warehouse">
-
-
       <title>Mandantenkonfiguration Lager</title>
 
-      <para>
-       Die Lagerverwaltung in kivitendo funktioniert standardmässig wie folgt: Wird ein Lager mit einem Lagerplatz angelegt, so gibt es die
-       Möglichkeit hier über den Menüpunkt Lager entsprechende Warenbewegungen durchzuführen.  Ferner kann jede Position eines Lieferscheins
-       ein-, bzw. ausgelagert werden (Einkauf-, bzw. Verkauf). Es können beliebig viele Lager mit beliebig vielen Lagerplätzen abgebildet
-       werden. Die Lagerbewegungen über einen Lieferschein erfolgt durch Anklicken jeder Einzelposition und das Auswählen dieser Position zu
-       einem Lager mit Lagerplatz. Dieses Verfahren lässt sich schrittweise vereinfachen, je nachdem wie die Einstellungen in der
-       Mandatenkonfiguration gesetzt werden.
-      </para>
+      <para>Die Lagerverwaltung in kivitendo funktioniert standardmässig wie
+      folgt: Wird ein Lager mit einem Lagerplatz angelegt, so gibt es die
+      Möglichkeit hier über den Menüpunkt Lager entsprechende Warenbewegungen
+      durchzuführen. Ferner kann jede Position eines Lieferscheins ein-, bzw.
+      ausgelagert werden (Einkauf-, bzw. Verkauf). Es können beliebig viele
+      Lager mit beliebig vielen Lagerplätzen abgebildet werden. Die
+      Lagerbewegungen über einen Lieferschein erfolgt durch Anklicken jeder
+      Einzelposition und das Auswählen dieser Position zu einem Lager mit
+      Lagerplatz. Dieses Verfahren lässt sich schrittweise vereinfachen, je
+      nachdem wie die Einstellungen in der Mandatenkonfiguration gesetzt
+      werden.</para>
 
       <itemizedlist>
         <listitem>
@@ -6315,9 +6349,7 @@ Beschreibung: &lt;%description%&gt;
         </listitem>
       </itemizedlist>
 
-      <para>
-       Zusätzliche Funktionshinweise:
-      </para>
+      <para>Zusätzliche Funktionshinweise:</para>
 
       <itemizedlist>
         <listitem>
@@ -6334,48 +6366,47 @@ Beschreibung: &lt;%description%&gt;
           verwendet.</para>
         </listitem>
       </itemizedlist>
-
-
     </sect1>
 
     <sect1 id="features.swiss-charts-of-accounts">
-	  <title>Schweizer Kontenpläne</title>
-
-	  <para>Seit der Version 3.5 stehen in kivitendo 3 Kontenpläne für
-	  den Einsatz in der Schweiz zur Verfügung, einer für Firmen und
-	  Organisationen, die nicht mehrwertsteuerpflichtig sind, einer
-	  für Firmen, die mehrwertsteuerpflichtig sind und einer speziell
-          für Vereine.</para>
-
-	  <para>Die Kontenpläne orientieren sich am in der Schweiz üblicherweise
-	  verwendeten KMU-Kontenrahmen und sind mit der Revision des Schweizerischen
-	  Obligationenrechts (OR) vom 1.1.2013 kompatibel, insbesondere
-	  <literal>Art.957a Abs.2</literal>.</para>
-
-          <para>Beim Vereinskontenplan sind standardmässig nur die Konten 1100
-          (Debitoren CHF) und 1101 (Debitoren EUR) als Buchungskonten im Verkauf
-          sowie die Konten 2000 (Kreditoren CHF) und 2001 (Kreditoren EUR) als
-          Buchungskonten im Einkauf vorgesehen. Weitere Konten können bei Bedarf
-          in den Konto-Detaileinstellungen als Einkaufs- oder Verkaufskonten
-          konfiguriert werden.</para>
-
-	  <para>Die Möglichkeit, Saldosteuersätze zu verwenden ist in der aktuellen
-	  Version von kivitendo noch nicht integriert.</para>
-
-	  <para>Trotzdem können auch Firmen, die per Saldosteuersatz mit der
-	  Eidgenössischen Steuerverwaltung abrechnen, kivitendo bereits nutzen.
-	  Dazu wird der Kontenplan mit MWST ausgewählt. Anschliessend müssen
-	  alle Aufwandskonten editiert werden und dort der Steuersatz auf 0%
-	  gesetzt werden.</para>
-
-	  <para>So werden bei Kreditorenbuchungen keine Vorsteuern verbucht.</para>
-
-          <para>Bezugssteuern für aus dem Ausland bezogene Dienstleistungen müssen
-          manuell verbucht werden.</para>
-
-	  <para>Wünsche für Anpassungen an den Schweizer Kontenplänen sowie
-	  Vorschläge für weitere (z.B. branchenspezifische) Kontenpläne
-	  bitte an <literal>empfang@revamp-it.ch</literal> senden.</para>
+      <title>Schweizer Kontenpläne</title>
+
+      <para>Seit der Version 3.5 stehen in kivitendo 3 Kontenpläne für den
+      Einsatz in der Schweiz zur Verfügung, einer für Firmen und
+      Organisationen, die nicht mehrwertsteuerpflichtig sind, einer für
+      Firmen, die mehrwertsteuerpflichtig sind und einer speziell für
+      Vereine.</para>
+
+      <para>Die Kontenpläne orientieren sich am in der Schweiz üblicherweise
+      verwendeten KMU-Kontenrahmen und sind mit der Revision des
+      Schweizerischen Obligationenrechts (OR) vom 1.1.2013 kompatibel,
+      insbesondere <literal>Art.957a Abs.2</literal>.</para>
+
+      <para>Beim Vereinskontenplan sind standardmässig nur die Konten 1100
+      (Debitoren CHF) und 1101 (Debitoren EUR) als Buchungskonten im Verkauf
+      sowie die Konten 2000 (Kreditoren CHF) und 2001 (Kreditoren EUR) als
+      Buchungskonten im Einkauf vorgesehen. Weitere Konten können bei Bedarf
+      in den Konto-Detaileinstellungen als Einkaufs- oder Verkaufskonten
+      konfiguriert werden.</para>
+
+      <para>Die Möglichkeit, Saldosteuersätze zu verwenden ist in der
+      aktuellen Version von kivitendo noch nicht integriert.</para>
+
+      <para>Trotzdem können auch Firmen, die per Saldosteuersatz mit der
+      Eidgenössischen Steuerverwaltung abrechnen, kivitendo bereits nutzen.
+      Dazu wird der Kontenplan mit MWST ausgewählt. Anschliessend müssen alle
+      Aufwandskonten editiert werden und dort der Steuersatz auf 0% gesetzt
+      werden.</para>
+
+      <para>So werden bei Kreditorenbuchungen keine Vorsteuern
+      verbucht.</para>
+
+      <para>Bezugssteuern für aus dem Ausland bezogene Dienstleistungen müssen
+      manuell verbucht werden.</para>
+
+      <para>Wünsche für Anpassungen an den Schweizer Kontenplänen sowie
+      Vorschläge für weitere (z.B. branchenspezifische) Kontenpläne bitte an
+      <literal>empfang@revamp-it.ch</literal> senden.</para>
     </sect1>
 
     <sect1 id="features.part_classification">
@@ -6498,23 +6529,31 @@ Beschreibung: &lt;%description%&gt;
         verschiedenen Typs verwaltet. Dies können</para>
         <orderedlist>
           <listitem>
-            <para>aus ERP-Daten per LaTeX Template erzeugte PDF-Dokumente,</para>
+            <para>aus ERP-Daten per LaTeX Template erzeugte
+            PDF-Dokumente,</para>
           </listitem>
+
           <listitem>
-            <para>zu bestimmten ERP-Daten gehörende Anhangdateien unterschiedlichen Formats,</para>
+            <para>zu bestimmten ERP-Daten gehörende Anhangdateien
+            unterschiedlichen Formats,</para>
           </listitem>
+
           <listitem>
             <para>per Scanner eingelesene PDF-Dateien,</para>
           </listitem>
+
           <listitem>
             <para>per E-Mail empfangene Dateianhänge unterschiedlichen Formats,</para>
           </listitem>
+
           <listitem>
             <para>sowie speziel für Artikel hochgeladene Bilder sein.</para>
           </listitem>
         </orderedlist>
+
         <screenshot>
           <screeninfo>Übersicht</screeninfo>
+
           <mediaobject>
             <imageobject>
               <imagedata contentwidth="600" fileref="images/DMS-Overview.png"/>
@@ -6526,21 +6565,28 @@ Beschreibung: &lt;%description%&gt;
       <sect2>
         <title>Struktur</title>
 
-      <para>Über eine vom Speichermedium unabhängige Zwischenschicht werden die Dateien und ihre Versionen in der Datenbank verwaltet. Darunter können verschiedene Implementierungen (Backends) gleichzeitig existieren:
-      </para>
+        <para>Über eine vom Speichermedium unabhängige Zwischenschicht werden
+        die Dateien und ihre Versionen in der Datenbank verwaltet. Darunter
+        können verschiedene Implementierungen (Backends) gleichzeitig
+        existieren:</para>
+
         <itemizedlist>
           <listitem>
             <para>Dateisystem</para>
           </listitem>
+
           <listitem>
             <para>WebDAV</para>
           </listitem>
+
           <listitem>
             <para>Schnittstelle zu externen Dokumenten-Management-Systemen</para>
           </listitem>
+
           <listitem>
             <para>andere Datenbank</para>
           </listitem>
+
           <listitem>
             <para>etc ...</para>
           </listitem>
@@ -6553,11 +6599,13 @@ Beschreibung: &lt;%description%&gt;
             <para>"document": Das sind entweder generierte, eingescannte oder hochgeladene PDF-Dateien,
                   die zu bestimmten ERP-Daten (ERP-Objekte, wie z.B. Rechnung, Lieferschein) gehören.</para>
           </listitem>
+
           <listitem>
             <para>"attachment": zusätzlich hochgeladene Dokumente, die an bestimmte ERP-Objekte angehängt werden,
             z.B. technische Zeichnungen, Aufmaße. Diese können auch für Artikel,
             Lieferanten und Kunden hinterlegt sein.</para>
           </listitem>
+
           <listitem>
             <para>"image": Bilder für Artikel. Diese können auch verkleinert in einer Vorschau (Thumbnail)
             angezeigt werden.</para>
@@ -6570,12 +6618,15 @@ Beschreibung: &lt;%description%&gt;
           <listitem>
             <para> "created": vom System erzeugte Dokumente"</para>
           </listitem>
+
           <listitem>
             <para> "uploaded": hochgeladene Dokumente</para>
           </listitem>
+
           <listitem>
             <para> "email": vom Mail-System empfangene Dateien</para>
           </listitem>
+
           <listitem>
             <para> "scanner[1]": von einem oder mehreren Scannern erzeugte Dateien. Existieren mehrere Scanner,
             so sind diese durch unterschiedliche Quellennamen zu definieren.</para>
@@ -6594,9 +6645,10 @@ Beschreibung: &lt;%description%&gt;
         Reiter "Dokumente" und "Dateianhänge".</para>
         <screenshot>
           <screeninfo>Reiter "Dateianhänge"</screeninfo>
+
           <mediaobject>
             <imageobject>
-              <imagedata scale="50" fileref="images/DMS-Anhaenge.png"/>
+              <imagedata fileref="images/DMS-Anhaenge.png" scale="50"/>
             </imageobject>
           </mediaobject>
         </screenshot>
@@ -6606,20 +6658,25 @@ Beschreibung: &lt;%description%&gt;
         ob er die Datei umbenennen will, falls es eine neue Datei sein soll.</para>
         <screenshot>
           <screeninfo>Reiter "Dateianhänge"</screeninfo>
+
           <mediaobject>
             <imageobject>
-              <imagedata width="100" contentwidth="40" fileref="images/DMS-Anhaenge-hochladen.png"/>
+              <imagedata contentwidth="40"
+                         fileref="images/DMS-Anhaenge-hochladen.png"
+                         width="100"/>
             </imageobject>
           </mediaobject>
         </screenshot>
+
         <para>Es können mehrere Dateien gleichzeitig hochgeladen werden,
         solange in Summe die maximale Größe nicht überschritten wird
         (siehe <xref linkend="file_management.clientconfig"/>).</para>
         <screenshot>
           <screeninfo>Reiter "Dokumente"</screeninfo>
+
           <mediaobject>
             <imageobject>
-              <imagedata  width="500" fileref="images/DMS-Dokumente.png"/>
+              <imagedata fileref="images/DMS-Dokumente.png" width="500"/>
             </imageobject>
           </mediaobject>
         </screenshot>
@@ -6630,15 +6687,21 @@ Beschreibung: &lt;%description%&gt;
         Einkaufsrechnungen sichtbar:</para>
         <screenshot>
           <screeninfo>Reiter "Dokumente"</screeninfo>
+
           <mediaobject>
             <imageobject>
-              <imagedata  contentwidth="600" fileref="images/DMS-Dokumente-Scanner.png"/>
+              <imagedata contentwidth="600"
+                         fileref="images/DMS-Dokumente-Scanner.png"/>
             </imageobject>
           </mediaobject>
         </screenshot>
-        <para>Statt des Löschens wird hier die Datei zurück zur Quelle verschoben. Somit kann die Datei anschließend
-        an ein anderes ERP-Objekt angehängt werden.</para>
-        <para>Derzeit sind "Titel" und "Beschreibung" noch nicht genutzt. Sie sind bisher nur bei Bildern relevant.</para>
+
+        <para>Statt des Löschens wird hier die Datei zurück zur Quelle
+        verschoben. Somit kann die Datei anschließend an ein anderes
+        ERP-Objekt angehängt werden.</para>
+
+        <para>Derzeit sind "Titel" und "Beschreibung" noch nicht genutzt. Sie
+        sind bisher nur bei Bildern relevant.</para>
       </sect2>
 
       <sect2>
@@ -6680,7 +6743,9 @@ Beschreibung: &lt;%description%&gt;
         </para>
         </sect4>
         </sect3>
-        <sect3 id="file_management.dbconfig" xreflabel="Datenbank-Konfigurierung">
+
+        <sect3 id="file_management.dbconfig"
+               xreflabel="Datenbank-Konfigurierung">
           <title>Datenbank-Konfigurierung</title>
           <para>Die zusätzlichen Quellen für "email" oder ein oder mehrere Scanner sind derzeit vom Administrator
           direkt in der Datenbanktabelle "user_preferences" einzurichten. Die "value" ist im JSON-Format
@@ -6698,17 +6763,58 @@ Beschreibung: &lt;%description%&gt;
           <para>Es ist daran gedacht, statt dem Default-Eintrag später für bestimmte Benutzer ('login') bestimmte Quellen zuzulassen.
           Dies wird nach Bedarf implementiert.</para>
         </sect3>
-        <sect3 id="file_management.kiviconfig" xreflabel="kivitendo-Konfigurationsdatei">
+
+        <sect3 id="file_management.kiviconfig"
+               xreflabel="kivitendo-Konfigurationsdatei">
           <title>kivitendo-Konfigurationsdatei</title>
-          <para>Dort ist im Abschnitt [paths] der relative oder absolute Pfad zum Dokumentenwurzelverzeichnis einzutragen.
-          Dieser muss für den Webserver schreib- und lesbar sein, jedoch nicht ausführbar.</para>
+
+          <para>Dort ist im Abschnitt [paths] der relative oder absolute Pfad
+          zum Dokumentenwurzelverzeichnis einzutragen. Dieser muss für den
+          Webserver schreib- und lesbar sein, jedoch nicht ausführbar.</para>
+
           <programlisting>
 [paths]
 document_path = /var/local/kivi_documents
           </programlisting>
           <para>Unter diesem Wurzelverzeichnis wird pro Mandant automatisch ein Unterverzeichnis mit der ID des Mandanten angelegt.</para>
         </sect3>
-     </sect2>
+      </sect2>
+    </sect1>
+
+    <sect1>
+      <title>Webshop-Api</title>
+
+      <para>Das Shopmodul bietet die Möglichkeit Onlineshopartikel und
+      Onlineshopbestellungen zu verwalten und zu bearbeiten. </para>
+
+      <para>Es ist Multishopfähig, d.h. Artikel können mehreren oder
+      unterschiedlichen Shops zugeordnet werden. Bestellungen können aus
+      mehreren Shops geholt werden.</para>
+
+      <para>Zur Zeit bietet das Modul nur einen Connector zur REST-Api von
+      Shopware. Weitere Connectoren können dazu programmiert und eingerichtet
+      werden.</para>
+
+      <sect2>
+        <title>Installationvorraussetzungen</title>
+
+        <para>In der Datenbank <literal>template1</literal> muss die
+        Unterstützung für die trigram-Extension eingerichet werden. Melden Sie
+        sich dafür als Benutzer “postgres” an der Datenbank an:
+        <programlisting>su - postgres
+psql template1</programlisting></para>
+
+        <para>führen Sie die folgenden Kommandos aus:</para>
+
+        <programlisting>CREATE EXTENSION IF NOT EXISTS pg_trgm;
+\q</programlisting>
+      </sect2>
+
+      <sect2>
+        <title>Konfiguration</title>
+
+        <para/>
+      </sect2>
     </sect1>
   </chapter>
 
@@ -6992,7 +7098,8 @@ document_path = /var/local/kivi_documents
             </listitem>
 
             <listitem>
-              <para>Enthält unter anderem Datumsformat dateformat und Nummernformat numberformat</para>
+              <para>Enthält unter anderem Datumsformat dateformat und
+              Nummernformat numberformat</para>
             </listitem>
 
             <listitem>
@@ -7981,12 +8088,14 @@ $self-&gt;{more_texts} = {
           </listitem>
 
           <listitem>
-            <para><literal>Sys::CPU</literal> (Debian-Panetname: <literal>libsys-cpu-perl</literal>; Fedora und openSUSE: nicht
+            <para><literal>Sys::CPU</literal> (Debian-Panetname:
+            <literal>libsys-cpu-perl</literal>; Fedora und openSUSE: nicht
             vorhanden)</para>
           </listitem>
 
           <listitem>
-            <para><literal>Thread::Pool::Simple</literal> (Debian-Panetname: <literal>libthread-pool-simple-perl</literal>; Fedora und
+            <para><literal>Thread::Pool::Simple</literal> (Debian-Panetname:
+            <literal>libthread-pool-simple-perl</literal>; Fedora und
             openSUSE: nicht vorhanden)</para>
           </listitem>
         </itemizedlist>
