Index: /lib/wpsg_basket.class.php
===================================================================
--- /lib/wpsg_basket.class.php	(revision 7219)
+++ /lib/wpsg_basket.class.php	(revision 7220)
@@ -638,58 +638,26 @@
 		 * Ist der Parameter $finish_order auf false so bleiben die Bestelldaten in der Session (Zur Vorspeicherung)
 		 */
-		public function save($finish_order = true, $sendmail = true)
-		{
-
+		public function save($finish_order = true, $sendmail = true) {
+ 
 			$knr = '';
-			try
-			{
+			
+			try {
                
-				// Berechnen
-				$arBasket = $this->toArray();
- 
-				// Keine Produkte nix speichern
-				// Sonst wurden schon beim Betreten des leeren Warenkorb (Bots) leere Bestellungen erzeugt
-				if (!wpsg_isSizedArray($arBasket['produkte'])) return;
-
 				// Eintrag in Kundentabelle
 				$data = array(
-					'email' 	=> wpsg_q(wpsg_getStr($this->arCheckout['email'])),
-					'invisible' => 1, 	// 1=unvollstÃ€ndige Bestellung
-					'geb' 		=> wpsg_q(wpsg_toDate(wpsg_getStr($this->arCheckout['geb']))),
-					'ustidnr' 	=> wpsg_q(wpsg_getStr($this->arCheckout['ustidnr']))
+					'email' => wpsg_q(wpsg_getStr($this->arCheckout['email'])),
+					'invisible' => 1,
+					'geb' => wpsg_q(wpsg_toDate(wpsg_getStr($this->arCheckout['geb']))),
+					'ustidnr' => wpsg_q(wpsg_getStr($this->arCheckout['ustidnr']))
 				);
 
 				$this->shop->callMods('basket_save_kunde', array(&$data, &$this->arCheckout));
                
-				$saved_order_db = array();
 				$k_id = wpsg_getStr($this->arCheckout['id']);
 
-				if (wpsg_isSizedInt($_SESSION['wpsg']['order_id']))
-				{
-
-					$saved_order_db = $this->db->fetchRow("SELECT * FROM `".WPSG_TBL_ORDER."` WHERE `id` = '".wpsg_q($_SESSION['wpsg']['order_id'])."' ");
-
-					if ($saved_order_db['id'] != $_SESSION['wpsg']['order_id'])
-					{
-
-						// Wenn die Bestellung aus der Session nicht in der Datenbank existiert lege ich sie neu an
-						unset($_SESSION['wpsg']['order_id']);
-
-					}
-					else
-					{
-
-						$k_id = $saved_order_db['k_id'];
-
-					}
-
-				}
-
 				// Sollte die ID des eingeloggten Kunden nicht mit der ID in der Bestellung passen
-				if (wpsg_isSizedInt($_SESSION['wpsg']['checkout']['id']))
-				{
-
-					if (wpsg_isSizedInt($k_id) && $k_id != $_SESSION['wpsg']['checkout']['id'])
-					{
+				if (wpsg_isSizedInt($_SESSION['wpsg']['checkout']['id'])) {
+
+					if (wpsg_isSizedInt($k_id) && $k_id != $_SESSION['wpsg']['checkout']['id']) {
 
 						$k_id = $_SESSION['wpsg']['checkout']['id'];
@@ -703,6 +671,5 @@
 				if (isset($this->arCheckout['custom']) && wpsg_isSizedArray($this->arCheckout)) $data['custom'] = $this->arCheckout['custom'];
 
-				if (wpsg_isSizedInt($k_id))
-				{
+				if (wpsg_isSizedInt($k_id)) {
 
 					// Kunde existiert bereits, hier muss aufgepasst werden dass nur abgefragte Kundenvariablen ersetzt werden
@@ -723,6 +690,5 @@
 				$update_customer_data = array();
 
-				if ($k_id > 0)
-				{
+				if ($k_id > 0) {
 
 					$this->db->UpdateQuery(WPSG_TBL_KU, $data, "`id` = '".wpsg_q($k_id)."'");
@@ -732,10 +698,7 @@
 					$this->shop->callMods('customer_updated', array(&$k_id));
 
-				}
-				else
-				{
-
-					if ($this->shop->hasMod('wpsg_mod_customergroup'))
-					{
+				} else {
+
+					if ($this->shop->hasMod('wpsg_mod_customergroup')) {
 
 						if (wpsg_isSizedInt($this->shop->get_option('wpsg_page_mod_kundenverwaltung_group_checkout'))) $data['group_id'] = $this->shop->get_option('wpsg_page_mod_kundenverwaltung_group_checkout');
@@ -743,11 +706,18 @@
 					}
 
-					if (wpsg_isSizedString($data['email']))
-					{
-						$k_id = wpsg_getInt($_SESSION['wpsg']['checkout']['id']);
-						if (!wpsg_isSizedInt($_SESSION['wpsg']['checkout']['id']))
-						{
+					if (wpsg_isSizedString($data['email'])) {
+												
+						if (!wpsg_isSizedInt($_SESSION['wpsg']['checkout']['id'])) {
+							
 							$k_id = $this->db->ImportQuery(WPSG_TBL_KU, $data);
+							
+							$_SESSION['wpsg']['checkout']['id'] = $k_id;
+							
+						} else {
+							
+							$k_id = wpsg_getInt($_SESSION['wpsg']['checkout']['id']);
+							
 						}
+						
 						$knr = $this->shop->buildKNR($k_id);
 
@@ -755,8 +725,9 @@
 						
 					}
+					
 					$this->shop->callMods('customer_created', array(&$k_id, &$this->arCheckout['password']));
 
 				}
-
+				 
 				// Adresse speichern wenn der Kunde noch keine Adresse hat
 				$customer_data = $this->shop->cache->loadKunden($k_id, true);
@@ -775,34 +746,27 @@
 					'land' => wpsg_q(wpsg_getStr($this->arCheckout['land']))
 				);
-				//$adress_data['cdate'] = 'NOW()';
-
-				$re_adress_id = 0;
-				if (false && $finish_order === true)
-				{
-
-					// Adresse als Rechnungsadresse anlegen
-					$re_adress_id = wpsg_q($this->db->ImportQuery(WPSG_TBL_ADRESS, $adress_data));
-
-					if (!wpsg_isSizedInt($customer_data['adress_id']))
-						$update_customer_data['adress_id'] = $re_adress_id;
-
-				}
-
-				if (!wpsg_isSizedInt($customer_data['adress_id']))
-				{
+				
+				$update_data = [
+					'k_id' => wpsg_q($k_id),
+					'language' => wpsg_q($this->shop->getCurrentLanguageCode())
+				];
+				
+				if (!wpsg_isSizedInt($customer_data['adress_id'])) {
 
 					$adress_data['cdate'] = 'NOW()';
-					if (wpsg_isSizedString($adress_data['name']) && wpsg_isSizedString($adress_data['vname']))
-					{
+					
+					if (wpsg_isSizedString($adress_data['name']) && wpsg_isSizedString($adress_data['vname'])) {
+						
 						$customer_data['adress_id'] = wpsg_q($this->db->ImportQuery(WPSG_TBL_ADRESS, $adress_data));
 						$update_customer_data['adress_id'] = $customer_data['adress_id'];
-					}
-				}
-				else
-				{
+						
+					}
+					
+				} else {
 
 					$this->db->UpdateQuery(WPSG_TBL_ADRESS, $adress_data, " `id` = '".wpsg_q($customer_data['adress_id'])."' ");
 
 				}
+				
 				$re_adress_id = $customer_data['adress_id'];
 
@@ -812,281 +776,68 @@
 				$arBasket['checkout']['k_id'] = $k_id;
 				$arBasket['checkout']['knr'] = $knr;
-
-				// Produkte letztmalig ÃŒberprÃŒfen
-				foreach ($arBasket['produkte'] as $p_id => $p)
-				{
-
-					if ($this->shop->hasMod('wpsg_mod_stock'))
-					{
-
-						if (!$this->shop->callMod('wpsg_mod_stock', 'checkBestand', array($p['id'], $p['menge'])) && $this->shop->get_option('wpsg_mod_stock_allow') == '1')
-						{
-
-							$p['menge'] = $this->shop->callMod('wpsg_mod_stock', 'getBestand', array($p['id']));
-
-						}
-
-					}
-
-				}
-
-				$data = array(
-					'cdate' 			=> 'NOW()',
-					'k_id' 				=> $k_id,
-					'ip' 				=> wpsg_q(wpsg_anonymip($_SERVER['REMOTE_ADDR'])),
-					'useragent' 		=> wpsg_q($_SERVER['HTTP_USER_AGENT']),
-					'comment' 			=> wpsg_q(wpsg_getStr($this->arCheckout['comment'])),
-					'shipping_tax_key' => wpsg_q($this->shop->arShipping[$this->arCheckout['shipping']]['mwst']),
-					'payment_tax_key' => wpsg_q($this->shop->arPayment[$this->arCheckout['payment']]['mwst']),
-					'price_gesamt' 		=> wpsg_tf(round($arBasket['sum']['preis_gesamt_brutto'], 2)),
-					'price_gesamt_netto' 		=> wpsg_tf(round($arBasket['sum']['preis_gesamt_netto'], 2)),
-					'price_gesamt_brutto' 		=> wpsg_tf(round($arBasket['sum']['preis_gesamt_brutto'], 2)),
-					'price_shipping' 	=> wpsg_tf($arBasket['sum']['preis_shipping']), // Sollte mal entfernt werden, wird aber an 1000 Stellen verwendet
-					'price_shipping_netto' => wpsg_tf($arBasket['sum']['preis_shipping_netto']),
-					'price_shipping_brutto'	=> wpsg_tf($arBasket['sum']['preis_shipping_brutto']),
-					'price_payment' 	=> wpsg_tf($arBasket['sum']['preis_payment']), // Sollte mal entfernt wedren, wird aber an 1000 Stellen verwendet
-					'price_payment_netto' 	=> wpsg_getFloat($arBasket['sum']['preis_payment_netto']),
-					'price_payment_brutto' 	=> wpsg_getFloat($arBasket['sum']['preis_payment_brutto']),
-					'price_rabatt' 		=> wpsg_tf($arBasket['sum']['preis_rabatt']),
-					'price_frontend'	=> $this->shop->getFrontendTaxview(),
-					'mwst_payment' 		=> wpsg_tf(wpsg_getFloat($arBasket['payment']['preis_payment_brutto']) - wpsg_getFloat($arBasket['payment']['preis_payment_netto'])),
-					'mwst_shipping' 	=> wpsg_tf(wpsg_getFloat($arBasket['shipping']['preis_shipping_brutto']) - wpsg_getFloat($arBasket['shipping']['preis_shipping_netto'])),
-					'type_shipping' 	=> wpsg_q(@$this->arCheckout['shipping']),
-					'type_payment' 		=> wpsg_q(@$this->arCheckout['payment']),
-					'custom_data' 		=> array(
-						'basket' 				=> $arBasket,
-						'preis_backend' 		=> $this->shop->get_option('wpsg_preisangaben'),
-						'preis_frontend' 		=> $this->shop->getFrontendTaxview(),
-						'wpsg_kleinunternehmer' => $this->shop->get_option('wpsg_kleinunternehmer'),
-						'wpsg_kleinunternehmer_text' => $this->shop->get_option('wpsg_kleinunternehmer_text')
-					)
-				);
-
-				if ($finish_order === true) $data['status'] = wpsg_ShopController::STATUS_EINGEGANGEN;
-				else $data['status'] = wpsg_ShopController::STATUS_UNVOLLSTAENDIG;
-
-				// Sprache des Nutzers speichern
-				if ($this->shop->isOtherLang())
-				{
-
-					$data['language'] = wpsg_q($this->shop->getCurrentLanguageCode());
-
-				}
-
-				/** Gutschein speichern */
-				if ($this->gs_id !== false && $this->gs_id > 0)
-				{
-
-					$gs_db = $this->db->fetchRow("SELECT * FROM `".WPSG_TBL_GUTSCHEIN."` WHERE `id` = '".wpsg_q($this->gs_id)."'");
-
-					if ($gs_db['id'] != $this->gs_id) die(__('Unerwarteter Fehler bei Gutscheinzuordnung.', 'wpsg'));
-
-					$data['gs_id'] = wpsg_q($this->gs_id);
-					$data['price_gs'] = wpsg_q($arBasket['sum']['gs']);
-
-				}
-
-				// Rabatt und Gutschein netto und brutto speichern
-				$data['price_rabatt_netto'] = wpsg_getFloat($arBasket['sum']['preis_rabatt_netto']);
-				$data['price_rabatt_brutto'] = wpsg_getFloat($arBasket['sum']['preis_rabatt_brutto']);
-
-				if (isset($arBasket['sum']['gs']))
-				{
-					$data['price_gs_netto'] = $arBasket['sum']['gs_netto'];
-					$data['price_gs_brutto'] = $arBasket['sum']['gs_brutto'];
-				}
-
-				/*
-				if ($this->shop->getFrontendTaxview() == WPSG_BRUTTO)
-				{
-					$tax = $this->shop->subMwSt($arBasket, $arBasket['sum']['preis_rabatt']);
-					$data['price_rabatt_netto'] = $arBasket['sum']['preis_rabatt'] - $tax;
-					$data['price_rabatt_brutto'] = $arBasket['sum']['preis_rabatt'];
-					if (isset($arBasket['sum']['gs']))
-					{
-						$tax = $this->shop->subMwSt($arBasket, $arBasket['sum']['gs']);
-						$data['price_gs_netto'] = $arBasket['sum']['gs'] - $tax;
-						$data['price_gs_brutto'] = $arBasket['sum']['gs'];
-					}
-
-				}
-				else
-				{
-					$tax = $this->shop->addMwSt($arBasket, $arBasket['sum']['preis_rabatt']);
-					$data['price_rabatt_netto'] = $arBasket['sum']['preis_rabatt'];
-					$data['price_rabatt_brutto'] = $arBasket['sum']['preis_rabatt'] + $tax;
-					if (isset($arBasket['sum']['gs']))
-					{
-						$tax = $this->shop->addMwSt($arBasket, $arBasket['sum']['gs']);
-						$data['price_gs_netto'] = $arBasket['sum']['gs'];
-						$data['price_gs_brutto'] = $arBasket['sum']['gs'] + $tax;
-					}
-
-				} $_REQUEST
-				*/
-
-				$this->shop->callMods('basket_save_order', array(&$data, &$this->arCheckout, &$arBasket, $finish_order));
-
-				if (($finish_order === true) && (wpsg_getStr($this->arCheckout['diff_shippingadress']) == '1'))
-				{	// Gesonderte Lieferadresse speichern
+ 				
+				if (($finish_order === true) && (wpsg_getStr($this->arCheckout['diff_shippingadress']) == '1')) {	
+					
+					// Gesonderte Lieferadresse speichern
 
 					$adata['cdate'] = 'NOW()';
 
-					$adata['title'] 	= $data['shipping_title'];
-					$adata['vname'] 	= $data['shipping_vname'];
-					$adata['name'] 		= $data['shipping_name'];
-					$adata['strasse'] 	= $data['shipping_strasse'];
-					$adata['plz'] 		= $data['shipping_plz'];
-					$adata['ort'] 		= $data['shipping_ort'];
-					$adata['firma'] 	= $data['shipping_firma'];
-					$adata['land'] 		= $data['shipping_land'];
-
-					$data['shipping_adress_id'] = wpsg_q($this->db->ImportQuery(WPSG_TBL_ADRESS, $adata));
-
-					// Daten fÃŒr BestellbestÃ€tigungsmail bereitstellen
-					$arBasket['checkout']['shipping_title'] = $data['shipping_title'];
-					$arBasket['checkout']['shipping_vname'] = $data['shipping_vname'];
-					$arBasket['checkout']['shipping_name'] = $data['shipping_name'];
-					$arBasket['checkout']['shipping_strasse'] = $data['shipping_strasse'];
-					$arBasket['checkout']['shipping_plz'] = $data['shipping_plz'];
-					$arBasket['checkout']['shipping_ort'] = $data['shipping_ort'];
-					$arBasket['checkout']['shipping_firma'] = $data['shipping_firma'];
-					$arBasket['checkout']['shipping_land'] = $data['shipping_land'];
-
-				}
-				$data['adress_id'] = $re_adress_id;
-				unset($data['shipping_title']);
-				unset($data['shipping_vname']);
-				unset($data['shipping_name']);
-				unset($data['shipping_strasse']);
-				unset($data['shipping_plz']);
-				unset($data['shipping_ort']);
-				unset($data['shipping_firma']);
-				unset($data['shipping_land']);
-
-				$data['custom_data']['basket']['oOrder'] = Array();
-				//unset($data['custom_data']['basket']['oOrder']['shop']);
-
-				$data['custom_data'] = wpsg_q(serialize($data['custom_data']));
-
-				if (wpsg_isSizedInt($_SESSION['wpsg']['order_id']))
-				{
-
-					$this->db->UpdateQuery(WPSG_TBL_ORDER, $data, " `id` = '".wpsg_q($_SESSION['wpsg']['order_id'])."' ");
-
-					$o_id = $_SESSION['wpsg']['order_id'];
-					$o_nr = $saved_order_db['onr'];
-
-				}
-				else
-				{
-
-					$o_id = $this->db->ImportQuery(WPSG_TBL_ORDER, $data);
-					$o_nr = $this->shop->buildONR($o_id, $k_id, $knr);
-
-					// Bestellnummer speichern
-					$this->db->UpdateQuery(WPSG_TBL_ORDER, array(
-						'onr' => wpsg_q($o_nr)
-					), "`id` = '".wpsg_q($o_id)."'");
-
-				}
-
-				$arBasket['checkout']['onr'] = $o_nr;
-				$arBasket['checkout']['o_id'] = $o_id;
-				$arBasket['checkout']['datum'] = strtotime($this->db->fetchOne("SELECT `cdate` FROM `".WPSG_TBL_ORDER."` WHERE `id` = '".wpsg_q($o_id)."'"));
-
-				if ($finish_order === true)
-				{
-
-					/** Gutschein der Bestellung zuordnen */
-					if ($this->gs_id !== false && $this->gs_id > 0)
-					{
-
-						if ($gs_db['multi'] != '1')
-						{
-
-							$this->db->UpdateQuery(WPSG_TBL_GUTSCHEIN, array('o_id' => $o_id), "`id` = '".wpsg_q($this->gs_id)."'");
-
-						}
-
-					}
-
-					$this->shop->cache->clearOrderCache($o_id);
-					$this->shop->cache->clearKundenCache($k_id);
-
-				}
-
-				// DB bereinigen und alte zur Bestellung gespeicherte Produkte lÃ¶schen
-				$this->db->Query("DELETE FROM `".WPSG_TBL_ORDERPRODUCT."` WHERE `o_id` = '".wpsg_q($o_id)."' ");
-
-				// Produkte eintragen
-				foreach ($arBasket['produkte'] as $p_id => $p)
-				{
-
-					// AufdrÃ¶selung der Varianten damit in der DB die korrekt Produkt ID steht
-					$produkt_id = $this->shop->getProduktID($p['id']);
-
-					$data = array(
-						'o_id' => wpsg_q($o_id),
-						'p_id' => wpsg_q($produkt_id),
-						'productkey' => $p['id'],
-						'product_index' => $p_id,
-						'menge' => wpsg_q($p['menge']),
-						'price' => wpsg_q($p['preis_brutto']),
-						'price_netto' => wpsg_q(wpsg_tf($p['preis_netto'])),
-						'price_brutto' => wpsg_q(wpsg_tf($p['preis_brutto'])),
-						'mwst_key' => wpsg_q($p['mwst_key']),
-						'mwst_value' => wpsg_q(wpsg_tf($p['preis_brutto'] - $p['preis_netto'])),
-						'mod_vp_varkey' => wpsg_q($p['productkey']),
-						'allowedpayments' => wpsg_q($p['allowedpayments']),
-						'allowedshipping' => wpsg_q($p['allowedshipping'])
-					);
-
-					// Hier wird der Lagerbestand final geschrieben, sollte ein Fehler ausgelÃ¶st werden soll zum Warenkorb geleitet werden
-					if ($finish_order === true && $this->shop->hasMod('wpsg_mod_stock'))
-					{
-
-						$p_stock = $p;
-						$bStockError = $this->shop->callMod('wpsg_mod_stock', 'checkReduceStock', array(&$data, &$p_stock));
-
-						if ($bStockError === false)
-						{
-
-							$this->shop->addFrontendError(__('Lagerbestand hat sich zwischenzeitlich geÃ€ndert. Bitte Bestellung ÃŒberprÃŒfen.', 'wpsg'));
-							$this->shop->redirect($this->shop->getUrl(wpsg_ShopController::URL_BASKET));
-
-						}
-
-					}
-
-					$this->shop->callMods('basket_save_product', array(&$data, &$p, $finish_order));
-
-					$this->db->ImportQuery(WPSG_TBL_ORDERPRODUCT, $data);
-
-					// Eventuelle URL Benachrichtigung bei Kauf
-					if ($finish_order === true)
-					{
-
-						$produkt_db = $this->db->fetchRow("SELECT * FROM `".WPSG_TBL_PRODUCTS."` WHERE `id` = '".wpsg_q($produkt_id)."'");
-
+					$adata['title'] 	= $this->arCheckout['shipping_title'];
+					$adata['vname'] 	= $this->arCheckout['shipping_vname'];
+					$adata['name'] 		= $this->arCheckout['shipping_name'];
+					$adata['strasse'] 	= $this->arCheckout['shipping_strasse'];
+					$adata['plz'] 		= $this->arCheckout['shipping_plz'];
+					$adata['ort'] 		= $this->arCheckout['shipping_ort'];
+					$adata['firma'] 	= $this->arCheckout['shipping_firma'];
+					$adata['land'] 		= $this->arCheckout['shipping_land'];
+
+					$update_data['shipping_adress_id'] = wpsg_q($this->db->ImportQuery(WPSG_TBL_ADRESS, $adata));
+
+				}
+				
+				$update_data['adress_id'] = $re_adress_id;
+				
+				$update_data['custom_data']['basket']['oOrder'] = Array();
+				$update_data['custom_data'] = wpsg_q(serialize($update_data['custom_data']));
+
+				// Neu durch calculation Klasse speichern				
+				$oCalculation = \wpsg\wpsg_calculation::getSessionCalculation();
+				$o_id = $oCalculation->toDB(@$_SESSION['wpsg']['order_id'], [], $finish_order);
+							
+				if ($o_id !== @$_SESSION['wpsg']['order_id']) {
+					
+					$update_data['onr'] = wpsg_q($this->shop->buildONR($o_id, $k_id, $knr));
+															
+				}
+				
+				if ($finish_order === true) $update_data['status'] = wpsg_ShopController::STATUS_EINGEGANGEN;
+				else $update_data['status'] = wpsg_ShopController::STATUS_UNVOLLSTAENDIG;
+				
+				$this->db->UpdateQuery(WPSG_TBL_ORDER, $update_data, "`id` = '".wpsg_q($o_id)."'");
+								 
+				// URL Benachrichtigung beim Kauf
+				if ($finish_order === true) {
+					
+					foreach ($oCalculation->getCalculationArray['product'] as $p) {
+						
+						$produkt_db = $this->db->fetchRow("SELECT * FROM `".WPSG_TBL_PRODUCTS."` WHERE `id` = '".wpsg_q($p['product_id'])."'");
+						
 						if ($produkt_db['posturl'] != '' && $produkt_db['posturl_verkauf'] == '1')
 						{
-
-							$this->shop->notifyURL($produkt_db['posturl'], $p['id'], $p['menge'], $o_id, 0, false, array(
-								'product_index' => $p_id
+							
+							$this->shop->notifyURL($produkt_db['posturl'], $p['product_key'], $p['amount'], $o_id, 0, false, array(
+								'product_index' => $p['product_index']
 							));
-
+							
 						}
-
-					}
-
-				}
-
-				if ($finish_order === true)
-				{
-
+						
+					}
+					 
 					$this->shop->callMods('basket_save_done', array(&$o_id, &$k_id, &$this));
 					$this->shop->callMods('basket_save_done_array', array(&$o_id, &$k_id, &$arBasket));
-
+					
+					$this->shop->basket->initFromDB($o_id);
+					$arBasket = $this->shop->basket->toArray();
+					
 					// Wenn CrefoPay aktiv, werden die Mails spÃ€ter versendet
 					if (!$this->shop->hasMod('wpsg_mod_crefopay') && $sendmail) $this->sendOrderSaveMails($o_id, $arBasket);
@@ -1099,5 +850,4 @@
 
 					}
-
 
 					// Eintrag in die Kundentabelle
@@ -1105,4 +855,5 @@
 						'invisible' => 0 	// 0=vollstÃ€ndige Bestellung
 					);
+					
 					$this->db->UpdateQuery(WPSG_TBL_KU, $kdata, "`id` = '".wpsg_q($k_id)."'");
 
@@ -1115,7 +866,5 @@
 					$this->clearSession($k_id);
 
-				}
-				else
-				{
+				} else {
 
 					$_SESSION['wpsg']['order_id'] = $o_id;
@@ -1123,7 +872,5 @@
 				}
 
-			}
-			catch (Exception $e)
-			{
+			} catch (Exception $e) {
 
 				$this->db->unlockTables();
@@ -1448,5 +1195,5 @@
 
 		} // public function hasEULeistungsortProduct(&$arBasket)
-
+				
 		/**
 		 * Wandelt die in der Session gespeicherten Produkte in einen aufgewerteten Array
@@ -1510,33 +1257,11 @@
 
 			if (wpsg_isSizedInt($_SESSION['wpsg']['order_id'])) $arReturn['oOrder'] = wpsg_order::getInstance($_SESSION['wpsg']['order_id']);
-
-			if (wpsg_isSizedInt($this->arCheckout['land']))
-			{
-
-				$db_country_invoice = $this->shop->db->fetchRow("SELECT * FROM `".WPSG_TBL_LAND."` WHERE `id` = '".wpsg_q($this->arCheckout['land'])."'");
-				$arReturn['land'] = $db_country_invoice;
-
-				if (wpsg_isSizedInt($this->arCheckout['shipping_land']))
-				{
-
-					$db_country_shipping = $this->shop->db->fetchRow("SELECT * FROM `".WPSG_TBL_LAND."` WHERE `id` = '".wpsg_q($this->arCheckout['shipping_land'])."'");
-					$arReturn['shipping_land'] = $db_country_shipping;
-					$land = $db_country_shipping;
-
-				}
-				else
-				{
-
-					$db_country_shipping = $db_country_invoice;
-					$land = $db_country_shipping;
-
-				}
-
-			} else $land = 0;
-
+			
+			$land = $this->shop->db->fetchRow("SELECT * FROM `".WPSG_TBL_LAND."` WHERE `id` = '".wpsg_q($this->arCheckout['land'])."'");
+			 
 			if ($land['mwst'] == '1' || $this->shop->get_option('wpsg_kleinunternehmer') == '1') $noMwSt = true;
 			else if ($land['mwst'] == '2' && wpsg_isSizedString($this->arCheckout['ustidnr'])) $noMwSt = true;
 			else $noMwSt = false;
-
+			
 			$arReturn['noMwSt'] = $noMwSt;
 			$arReturn['produkte'] = array();
@@ -1603,5 +1328,5 @@
 				$this->shop->callMods('basket_toArray', array(&$b, $backend, $noMwSt));
 				$this->checkMwSt($b['mwst_key'], $country, $arReturn);
-
+ 
 				if ($noMwSt)
 				{
Index: /lib/wpsg_calculation.class.php
===================================================================
--- /lib/wpsg_calculation.class.php	(revision 7219)
+++ /lib/wpsg_calculation.class.php	(revision 7220)
@@ -37,5 +37,8 @@
     	const TAXMODE_B2C = '2';
     	const TAXMODE_B2B = '3';
-    	    	
+	
+		/**
+		 * wpsg_calculation constructor.
+		 */
         public function __construct() {
             
@@ -75,4 +78,6 @@
 				'd_'.$country_id => $tax_d,
 			];
+	
+			$this->arCalculation = null;
             
         }
@@ -143,4 +148,6 @@
         		
 			}
+	
+			$this->arCalculation = null;
         	
 		}
@@ -167,5 +174,7 @@
 					'id' => $id
 				]
-			]; 
+			];
+			
+			$this->arCalculation = null;
 			
 		}
@@ -182,4 +191,6 @@
 		
 			}
+	
+			$this->arCalculation = null;
             
         }
@@ -199,4 +210,6 @@
 				'data' => [ ]
 			];
+	
+			$this->arCalculation = null;
 	                    
         }
@@ -232,5 +245,7 @@
 				]
 			];
-                        
+	
+			$this->arCalculation = null;
+            
         }
         
@@ -242,4 +257,6 @@
                 
             }
+            
+			$this->arCalculation = null;            
             
         }
@@ -262,5 +279,7 @@
 				]
             ];
-                         
+		
+			$this->arCalculation = null;
+			
         }
 
@@ -282,4 +301,6 @@
 				]
 			];
+	
+			$this->arCalculation = null;
             
         }
@@ -420,5 +441,5 @@
 
         }
-
+         
         /**
          * Speichert die Berechnung in eine Bestellung
@@ -426,6 +447,9 @@
          * @param bool $id
          */
-        public function toDB($id = false, $db_data = []) {
-            
+        public function toDB($id = false, $db_data = [], $finish_order) {
+	
+			$id = $this->db->fetchOne("SELECT `id` FROM `".WPSG_TBL_ORDER."` WHERE `id` = '".wpsg_q($id)."' ");
+        	if (!wpsg_isSizedInt($id)) $id = false;
+        	
             $arCalculation = $this->getCalculationArray();
 
@@ -504,5 +528,5 @@
 					$db_data['gs_id'] = wpsg_q($cr['data']['id']);
 					$db_data['gs_code'] = wpsg_q($cr['data']['code']);
-            		 
+		 					
 				} else if ($cr['type'] === 'shipping') {
             		
@@ -544,5 +568,12 @@
 			$db_data['shop_country_tax_c'] = wpsg_q($oDefaultCountry->mwst_c);
 			$db_data['shop_country_tax_d'] = wpsg_q($oDefaultCountry->mwst_d);
-            
+	
+			// Die Hooks verwenden Daten aus $_SESSION, deshalb nur beim Speichern im Frontend
+			if (!is_admin()) {
+			
+				$this->shop->callMods('calculation_saveOrder', [&$this, $arCalculation, &$db_data, $finish_order]);
+				
+			}
+			
             if (wpsg_isSizedInt($id)) {
                 
@@ -556,23 +587,21 @@
                 
             }
-            
-            /*
-            if (wpsg_isSizedArray($this->arVoucher)) {
-				
-				foreach ($this->arVoucher as $v) {
-										
-					if (wpsg_isSizedInt($v['id'])) {
+	
+			foreach ($this->arCalculationRow as $cr) {
+				
+				if ($cr['type'] === 'voucher') {
+					
+					if (wpsg_isSizedInt($cr['data']['id']) && $finish_order) {
 						
 						$this->db->UpdateQuery(WPSG_TBL_GUTSCHEIN, [
-							'o_id' => wpsg_q($id)							
-						], " `id` = '".wpsg_q($v['id'])."' ");
+							'o_id' => wpsg_q($cr['data']['id'])
+						], " `id` = '".wpsg_q($cr['data']['id'])."' ");
 						
-					} 
-					
-				}
-				
-			}
-            */
-
+					}
+										
+				}
+				
+			}
+                        
             $arOrderProductID = [-1];
             
@@ -582,5 +611,5 @@
 				$db_data = [
 					'o_id' => wpsg_q($id),
-					'p_id' => wpsg_q($p['product_id']),
+					'p_id' => wpsg_q($p['product_id']),										
 					'productkey' => wpsg_q($p['product_key']),
 					'product_index' => wpsg_q($p['product_index']),
@@ -596,15 +625,29 @@
 				];
 				
+				if (!wpsg_isSizedInt($p['order_product_id']) && $p['product_index'] !== false) {
+					
+					$p['order_product_id'] = $this->db->fetchOne("SELECT `id` FROM `".WPSG_TBL_ORDERPRODUCT."` WHERE `o_id` = '".wpsg_q($id)."' AND `p_id` = '".wpsg_q($p['product_id'])."' ");
+					
+				}
+				
+				// Die Hooks verwenden Daten aus $_SESSION, deshalb nur beim Speichern im Frontend
+				if (!is_admin()) {
+				
+					$this->shop->callMods('calculation_saveProduct', [&$this, $p, &$db_data, $finish_order]);
+					
+				}
+				
 				if (wpsg_isSizedInt($p['order_product_id'])) {
 					
 					$arOrderProductID[] = $p['order_product_id'];
-					
+			
 					$this->db->UpdateQuery(WPSG_TBL_ORDERPRODUCT, $db_data, " `id` = '".wpsg_q($p['order_product_id'])."' ");
 					
 				} else {
-
+			
 					$arOrderProductID[] = $this->db->ImportQuery(WPSG_TBL_ORDERPRODUCT, $db_data);
 					
 				}
+			
 				
             }
@@ -716,4 +759,6 @@
         public function fromDB($id) {
             
+			if (!wpsg_isSizedInt($id)) return;
+			
             $db_order = $this->db->fetchRow("SELECT O.*, A.`land` FROM `".WPSG_TBL_ORDER."` AS O LEFT JOIN `".WPSG_TBL_ADRESS."` AS A ON (O.`adress_id` = A.`id`) WHERE O.`id` = '".wpsg_q($id)."' ");
             $db_products = $this->db->fetchAssoc("SELECT * FROM `".WPSG_TBL_ORDERPRODUCT."` WHERE `o_id` = '".wpsg_q($id)."' ");
@@ -757,4 +802,61 @@
         } // public function fromDB($id)
         
+		public function fromSession() {
+			
+			$ses = (isset($_SESSION['wpsg'])?$_SESSION['wpsg']:[]);
+			
+			$oDefaultCountry = $this->shop->getDefaultCountry();			
+			$this->addCountry($oDefaultCountry->id, $oDefaultCountry->mwst, $oDefaultCountry->mwst_a, $oDefaultCountry->mwst_b, $oDefaultCountry->mwst_c, $oDefaultCountry->mwst_d,true);
+			
+			if ($ses['land'] != $oDefaultCountry->id) {
+				
+				$oInvoiceCountry = \wpsg_country::getInstance($ses['land']);
+				$this->addCountry($oInvoiceCountry->id, $oInvoiceCountry->mwst, $oInvoiceCountry->mwst_a, $oInvoiceCountry->mwst_b, $oInvoiceCountry->mwst_c, $oInvoiceCountry->mwst_d,false);
+				
+			}
+			
+			if (wpsg_isSizedArray($ses['basket'])) {
+				
+				foreach ($ses['basket'] as $product_index => $p) {
+					
+					$oProduct = \wpsg_product::getInstance($this->shop->getProduktID($p['id']));
+					
+					$this->addProduct(
+						$oProduct->getPrice($this->shop->getBackendTaxview()), 
+						$this->shop->getBackendTaxview(), 
+						$oProduct->mwst_key, 
+						$p['menge'], 
+						$p['id'], 
+						$product_index, 
+						false, 
+						$oProduct->leistungsortregel
+					);
+					
+				}
+												
+			}
+			
+			$this->shop->callMods('calculation_fromSession',[&$this, true, false]);
+			
+			// Shipping 
+			if (isset($_SESSION['wpsg']['checkout']['payment'])) {
+				
+				$payment = $this->shop->arPayment[$_SESSION['wpsg']['checkout']['payment']];
+				$this->addPayment($payment['price'], $this->shop->getBackendTaxview(), $payment['mwst_key'], $_SESSION['wpsg']['checkout']['payment']);
+				
+			}
+			
+			// Payment
+			if (isset($_SESSION['wpsg']['checkout']['shipping'])) {
+				
+				$shipping = $this->shop->arShipping[$_SESSION['wpsg']['checkout']['shipping']];
+				$this->addShipping($shipping['price'], $this->shop->getBackendTaxview(), $shipping['mwst_key'], $_SESSION['wpsg']['checkout']['shipping']);
+				
+			}
+				
+			$this->shop->callMods('calculation_fromSession',[&$this, true, true]);			
+						
+		}
+		
         public function getMaxProductIndex() {
             
@@ -871,5 +973,5 @@
          * Im Array sollen die Tax SchlÃŒssel immer mit Land gespeichert sein
          */
-        private function normalizeTaxKey($tax_key, $country_id = false) {
+        private function normalizeTaxKey($tax_key, $country_id = false, $defaultCountryID = true) {
 
             if ($tax_key == '') $tax_key = '0';
@@ -877,5 +979,10 @@
             if ($tax_key != '0' && !preg_match('/\_\d+$/', $tax_key)) {
             	
-            	if ($country_id === false) $country_id = $this->getTargetCountryID();
+            	if ($country_id === false) {
+            		
+            		if ($defaultCountryID === true) $country_id = $this->getDefaultCountryID();
+            		else $country_id = $this->getTargetCountryID();
+            		
+				}
             	
             	return $tax_key.'_'.$country_id;
@@ -980,4 +1087,18 @@
         }
 
+        /* Static */
+	
+		/**
+		 * return \wpsg\wpsg_calculation
+		 */
+		public static function getSessionCalculation() {
+	
+			$oCalculation = new wpsg_calculation();
+			$oCalculation->fromSession();
+			
+			return $oCalculation;
+			
+		}
+	        
     }
          
Index: /mods/wpsg_mod_abo.class.php
===================================================================
--- /mods/wpsg_mod_abo.class.php	(revision 7219)
+++ /mods/wpsg_mod_abo.class.php	(revision 7220)
@@ -539,27 +539,25 @@
 
 		} // public function setOrderStatus($order_id, $status_id, $inform)
-
-		public function basket_save_order(&$data, &$checkout, &$arBasket, $finish_order)
-		{
-
-			if ($finish_order !== true) return;
-
-			foreach ($arBasket['produkte'] as $product)
-			{
-
-				if (substr($product['productkey'], 0, 3) == 'abo')
+		
+		public function calculation_saveOrder(&$oCalculation, $arCalculation, &$db_data, $finish_order) { 
+		
+			if (!$finish_order) return;
+			
+			foreach ($_SESSION['wpsg']['basket'] as $p) {
+								
+				if (substr($p['id'], 0, 3) == 'abo')
 				{
-
+					
 					// Ein Abo Produkt wurde gekauft
-					$arAbo = explode('_', $product['productkey']);
-
-					$data['wpsg_mod_abo_origin_order'] = wpsg_q($arAbo[1]);
-
+					$arAbo = explode('_', $p['id']);
+					
+					$db_data['wpsg_mod_abo_origin_order'] = wpsg_q($arAbo[1]);
+					
 				}
-
-			}
-
-		} // public function basket_save_order(&$data, &$checkout, &$arBasket, $finish_order)
-
+				
+			}
+			
+		}
+		
 		public function cron()
 		{
Index: /mods/wpsg_mod_autodebit.class.php
===================================================================
--- /mods/wpsg_mod_autodebit.class.php	(revision 7219)
+++ /mods/wpsg_mod_autodebit.class.php	(revision 7220)
@@ -457,25 +457,22 @@
 		} // private function explodeRow($row)
 		
-		
-		public function basket_save_order(&$data, &$checkout, &$arBasket, $finish_order) 
-		{ 
-			
-			if(!isset($checkout['payment'])) return;
-			
-			if ($checkout['payment'] == $this->id)
-			{
+		public function calculation_saveOrder(&$oCalculation, $arCalculation, &$db_data, $finish_order) { 
+			
+			if (isset($_SESSION['wpsg']['checkout']) && $_SESSION['wpsg']['checkout'] == $this->id) {
+				
+				$checkout = $_SESSION['wpsg']['checkout'];
 				
 				// Daten in die Bestelltabelle hinzutragen
-				$data['mod_autodebit_name'] = $checkout['mod_autodebit_name'];
-				$data['mod_autodebit_blz'] = $checkout['mod_autodebit_blz'];
-				$data['mod_autodebit_bic'] = $checkout['mod_autodebit_bic'];
-				$data['mod_autodebit_inhaber'] = $checkout['mod_autodebit_inhaber'];
-				$data['mod_autodebit_knr'] = $checkout['mod_autodebit_knr'];
-				$data['mod_autodebit_iban'] = $checkout['mod_autodebit_iban'];
-				
-			}
-			
-		} // public function basket_save_order(&$data, &$checkout, &$arBasket, $finish_order)
-		
+				$db_data['mod_autodebit_name'] = wpsg_q($checkout['mod_autodebit_name']);
+				$db_data['mod_autodebit_blz'] = wpsg_q($checkout['mod_autodebit_blz']);
+				$db_data['mod_autodebit_bic'] = wpsg_q($checkout['mod_autodebit_bic']);
+				$db_data['mod_autodebit_inhaber'] = wpsg_q($checkout['mod_autodebit_inhaber']);
+				$db_data['mod_autodebit_knr'] = wpsg_q($checkout['mod_autodebit_knr']);
+				$db_data['mod_autodebit_iban'] = wpsg_q($checkout['mod_autodebit_iban']);
+				
+			}
+			
+		}
+		 
 		public function order_view_afterpayment(&$order_id) 
 		{ 
Index: /mods/wpsg_mod_basic.class.php
===================================================================
--- /mods/wpsg_mod_basic.class.php	(revision 7219)
+++ /mods/wpsg_mod_basic.class.php	(revision 7220)
@@ -205,4 +205,12 @@
 		public function kundenmail_afteragb(&$order_id) { }
 		
+		/** Wird bei der Calculation aufgerufen @var \wpsg\wpsg_calculation $oCalculation */		
+		public function calculation_fromSession(&$oCalculation, $product_done, $payship_done) { }
+		
+		public function calculation_saveProduct(&$oCalculation, $calc_product, &$db_product_data, $finish_order) { }
+	
+		/** @var \wpsg\wpsg_calculation $oCalculation */
+		public function calculation_saveOrder(&$oCalculation, $arCalculation, &$db_data, $finish_order) { }
+				
 		/**
 		 * Gibt den Namen der Zahlungsart zurÃŒck (Eingebaut fÃŒr CrefoPay)
@@ -531,19 +539,8 @@
 		/** Wird beim speichern eines Kunden wÃ€hrend der Bestellung aufgerufen */
 		public function basket_save_kunde(&$data, &$checkout) { }
-		
-		/**
-		 * Wird beim speichern der Bestellung in die Datenbank aufgerufen,
-		 * wird nicht beim Refresh (F5) aufgerufen.
-		 */
-		public function basket_save_order(&$data, &$checkout, &$arBasket, $finish_order) { }
-		
+				
 		/** Wird beim lÃ¶schen der Session nach der Bestellung aufgerufen */
 		public function clearSession() { }
-		
-		/**
-		 * Wird beim Speichern eines bestellten Produkts in die Datenbank aufgerufen
-		 */
-		public function basket_save_product(&$data, &$product_data, $finish_order) { }
-		
+				
 		/**
 		 * Wird nach dem erfolgreichen Speichern der Bestellung mit der Bestell- und Kundenid aufgerufen
Index: /mods/wpsg_mod_creditcard.class.php
===================================================================
--- /mods/wpsg_mod_creditcard.class.php	(revision 7219)
+++ /mods/wpsg_mod_creditcard.class.php	(revision 7220)
@@ -278,11 +278,9 @@
 		}
 		
-		public function basket_save_order(&$data, &$checkout, &$arBasket, $finish_order) 
-		{ 
-			 
-			if(!isset($checkout['payment'])) return;
-			
-			if ($checkout['payment'] == $this->id)
-			{
+		public function calculation_saveOrder(&$oCalculation, $arCalculation, &$db_data, $finish_order) { 
+			
+			if ($_SESSION['wpsg']['checkout']['payment'] == $this->id) {
+				
+				$checkout = $_SESSION['wpsg']['checkout'];
 				
 				// Daten in die Bestelltabelle hinzutragen
@@ -292,18 +290,18 @@
 				$key = $this->shop->get_option("wpsg_mod_creditcard_schluessel");
 				$iv = mcrypt_create_iv(16, MCRYPT_RAND);
-
+				
 				//echo wpsg_q($iv.mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $checkout['mod_creditcard_typ'], MCRYPT_MODE_CBC, $iv));
 				
-				$data['mod_creditcard_typ'] = base64_encode($iv.mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $checkout['mod_creditcard_typ'], MCRYPT_MODE_CBC, $iv));
-				$data['mod_creditcard_pruefz'] = base64_encode($iv.mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $checkout['mod_creditcard_pruefz'], MCRYPT_MODE_CBC, $iv));
-				$data['mod_creditcard_gueltigm'] = base64_encode($iv.mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $checkout['mod_creditcard_gueltigm'], MCRYPT_MODE_CBC, $iv));
-				$data['mod_creditcard_gueltigj'] = base64_encode($iv.mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $checkout['mod_creditcard_gueltigj'], MCRYPT_MODE_CBC, $iv));
-				$data['mod_creditcard_inhaber'] = base64_encode($iv.mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $checkout['mod_creditcard_inhaber'], MCRYPT_MODE_CBC, $iv));
-				$data['mod_creditcard_knr'] = base64_encode($iv.mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $checkout['mod_creditcard_knr'], MCRYPT_MODE_CBC, $iv));
-				
-			}
-			
-		} // public function basket_save_order(&$data, &$checkout, &$arBasket, $finish_order)
-		
+				$db_data['mod_creditcard_typ'] = base64_encode($iv.mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $checkout['mod_creditcard_typ'], MCRYPT_MODE_CBC, $iv));
+				$db_data['mod_creditcard_pruefz'] = base64_encode($iv.mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $checkout['mod_creditcard_pruefz'], MCRYPT_MODE_CBC, $iv));
+				$db_data['mod_creditcard_gueltigm'] = base64_encode($iv.mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $checkout['mod_creditcard_gueltigm'], MCRYPT_MODE_CBC, $iv));
+				$db_data['mod_creditcard_gueltigj'] = base64_encode($iv.mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $checkout['mod_creditcard_gueltigj'], MCRYPT_MODE_CBC, $iv));
+				$db_data['mod_creditcard_inhaber'] = base64_encode($iv.mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $checkout['mod_creditcard_inhaber'], MCRYPT_MODE_CBC, $iv));
+				$db_data['mod_creditcard_knr'] = base64_encode($iv.mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $checkout['mod_creditcard_knr'], MCRYPT_MODE_CBC, $iv));
+								
+			}
+						
+		}
+		 
 		public function order_view_afterpayment(&$order_id) 
 		{ 
Index: /mods/wpsg_mod_customerbudget.class.php
===================================================================
--- /mods/wpsg_mod_customerbudget.class.php	(revision 7219)
+++ /mods/wpsg_mod_customerbudget.class.php	(revision 7220)
@@ -133,22 +133,23 @@
 		} // public function checkCheckout(&$state, &$error, &$arCheckout)
 		
-		public function basket_save_order(&$data, &$checkout, &$arBasket, $finish_order) 
-		{ 
+		public function calculation_saveOrder(&$oCalculation, $arCalculation, &$db_data, $finish_order) {
 			
-			if ($finish_order !== true) return;
+			if (!$finish_order) return;
 			
-			if ($checkout['payment'] == $this->id)
-			{
+			if ($_SESSION['wpsg']['checkout']['payment'] == $this->id) {
 				
-				$kunde = $this->shop->cache->LoadKunden($checkout['id']);
+				$kunde = $this->shop->cache->LoadKunden($_SESSION['wpsg']['checkout']['id']);
+				
+				if ($this->shop->getBackendTaxview() === WPSG_NETTO) $sum = $arCalculation['sum']['brutto'];
+				else $sum = $arCalculation['sum']['netto'];
 				
 				$this->db->UpdateQuery(WPSG_TBL_KU, array(
-					'budget' => wpsg_q($kunde['budget'] - $data['price_gesamt'])
-				), "`id` = '".wpsg_q($checkout['id'])."'");
+					'budget' => wpsg_q($kunde['budget'] - $sum)
+				), "`id` = '".wpsg_q($_SESSION['wpsg']['checkout']['id'])."'");
 				
 			}
 			
-		} // public function basket_save_order(&$data, &$checkout, &$arBasket, $finish_order)
-		
+		}
+		 		
 		public function calcPayment(&$arBasket) { 
 			
Index: /mods/wpsg_mod_discount.class.php
===================================================================
--- /mods/wpsg_mod_discount.class.php	(revision 7219)
+++ /mods/wpsg_mod_discount.class.php	(revision 7220)
@@ -435,5 +435,42 @@
 
 		} // public function basket_top()
-
+		
+		/**
+		 * @param \wpsg\wpsg_calculation $oCalculation
+		 * @param $product_done
+		 * @param $payship_done
+		 */
+		public function calculation_fromSession(&$oCalculation, $product_done, $payship_done) { 
+			
+			if ($product_done && $payship_done) {
+			 
+				$arCalculation = $oCalculation->getCalculationArray();
+				
+				$discount = false; 
+				
+				$value = $arCalculation['sum']['brutto'];
+				if ($value == 0) return;
+				
+				foreach ((array)$this->getOptionData() as $k => $v) {
+				 
+					
+					if (!isset($v['value']) || $value >= $v['value']  && wpsg_tf($v['rabatt']) > 0) {
+						
+						$discount = $v['rabatt'];
+						
+					}
+					
+				}
+			
+				if ($discount !== false) {
+					
+					$oCalculation->addDiscount($discount, $this->shop->getBackendTaxview(), '0', 1);
+					
+				}
+				  
+			}
+			
+		} // public function calculation_fromSession(&$oCalculation, $product_done, $payship_done) { 
+		
 		/* Modulfunktionen */
 		
@@ -461,5 +498,5 @@
 			
 		} // public function hasDiscount($arBasket)
-		
+				
 		private function cmp($a, $b)
 		{
Index: /mods/wpsg_mod_gutschein.class.php
===================================================================
--- /mods/wpsg_mod_gutschein.class.php	(revision 7219)
+++ /mods/wpsg_mod_gutschein.class.php	(revision 7220)
@@ -121,5 +121,21 @@
 
 		} // public function wpsg_add_pages()
-
+		
+		public function calculation_fromSession(&$oCalculation, $product_done, $payship_done) { 
+			
+			if ($product_done && $payship_done) {
+				
+				if (wpsg_isSizedArray($_SESSION['wpsg']['gs'])) {
+					
+					$gs = $_SESSION['wpsg']['gs'];
+					
+					$oCalculation->addVoucher($gs['value'], $this->shop->getBackendTaxview(), '0', 1,$gs['code'],$gs['id']);
+					
+				}
+				
+			}
+			
+		}
+		
         public function editAction() {
 
Index: /mods/wpsg_mod_kundenverwaltung.class.php
===================================================================
--- /mods/wpsg_mod_kundenverwaltung.class.php	(revision 7219)
+++ /mods/wpsg_mod_kundenverwaltung.class.php	(revision 7220)
@@ -448,5 +448,5 @@
 								K.`id` != '".wpsg_q($temp_customer_id)."'  
 						";
-					 
+						 
 						$kunde_id = $this->db->fetchOne($strQuery);
 						
@@ -552,23 +552,22 @@
 		} // public function checkCheckout(&$state, &$error)
 		
-		public function basket_save_order(&$data, &$checkout, &$arBasket, $finish_order) 
-		{ 
-			
-			if ($finish_order !== true) return;
+		public function calculation_saveOrder(&$oCalculation, $arCalculation, &$db_data, $finish_order) {
+			
+			if ($finish_order) return;
 			
 			// Wenn Wordpress User gekoppelt sind, dann auch den Wordpress User einloggen
 			if ($this->shop->get_option('wpsg_mod_kundenverwaltung_wpuser') == '1')
 			{
-			
+				
 				if (wpsg_isSizedInt($_SESSION['wpsg']['checkout']['id']))
 				{
-					 
+					
 					$this->login($_SESSION['wpsg']['checkout']['id'], $_SESSION['wpsg']['checkout']['email'], $_SESSION['wpsg']['checkout']['password']);
 					
 				}
-			
-			}
-			
-		} // public function basket_save_order(&$data, &$checkout, &$arBasket, $finish_order)
+				
+			}
+			
+		} 
 		
 		public function basket_save_kunde(&$data, &$checkout) 
Index: /mods/wpsg_mod_newsletter.class.php
===================================================================
--- /mods/wpsg_mod_newsletter.class.php	(revision 7219)
+++ /mods/wpsg_mod_newsletter.class.php	(revision 7220)
@@ -56,11 +56,11 @@
 		} // public function settings_save()
 		
-		public function basket_save_order(&$data, &$checkout, &$arBasket, $finish_order) 
-		{ 
-			
-			if ($finish_order !== true) return;
-		 
-			if ($this->checkNewsletterPlugin() && $arBasket['checkout']['wpsg_mod_newsletter'] == '1')
-			{
+		public function calculation_saveOrder(&$oCalculation, $arCalculation, &$db_data, $finish_order) { 
+			
+			if (!$finish_order) return;
+			
+			if ($this->checkNewsletterPlugin() && $_SESSION['wpsg']['checkout']['wpsg_mod_newsletter'] == '1') {
+				
+				$checkout = $_SESSION['wpsg']['checkout'];
 				
 				// Abonnent eintragen
@@ -75,17 +75,14 @@
 				$abo->ort = $checkout['ort'];
 				
-				if ($this->shop->get_option('wpsg_mod_newsletter_action') == '0')
-				{
+				if ($this->shop->get_option('wpsg_mod_newsletter_action') == '0') {
 					
 					$abo->status = '1';
 					$abo->save();
 					
-					$abo->sendDoubleOptIn(); 
+					$abo->sendDoubleOptIn();
 					
 					$this->shop->addFrontendMessage(__('Sie haben eine Mail erhalten, in der sie die Newsletteranmeldung bestÃ€tigen mÃŒssen.', 'wpsg'));
 					
-				}
-				else if ($this->shop->get_option('wpsg_mod_newsletter_action') == '1')
-				{
+				} else if ($this->shop->get_option('wpsg_mod_newsletter_action') == '1') {
 					
 					$this->shop->addFrontendMessage(__('Sie wurden erfolgreich fÃŒr den Newsletter angemeldet.', 'wpsg'));
@@ -100,5 +97,5 @@
 			}
 			
-		} // public function basket_save_order(&$data, &$checkout, &$arBasket, $finish_order)
+		}
 		
 		public function wpsg_mod_customer_save(&$customer_data) 
Index: /mods/wpsg_mod_ordervars.class.php
===================================================================
--- /mods/wpsg_mod_ordervars.class.php	(revision 7219)
+++ /mods/wpsg_mod_ordervars.class.php	(revision 7220)
@@ -247,11 +247,14 @@
 		}
 		
-		public function basket_save_order(&$data, &$checkout, &$arBasket, $finish_order) 
-		{ 
- 						
-			$data['bvars'] = serialize(@$_SESSION['wpsg']['wpsg_mod_ordervars']);
+		public function calculation_saveOrder(&$oCalculation, $arCalculation, &$db_data, $finish_order) { 
+			
+			if (isset($_SESSION['wpsg']['wpsg_mod_ordervars'])) {
+					
+				$db_data['bvars'] = serialize(@$_SESSION['wpsg']['wpsg_mod_ordervars']);
+				
+			}
 			
 		}
-
+		 
 		public function order_view($order_id, &$arSidebarArray)
 		{
Index: /mods/wpsg_mod_productvars.class.php
===================================================================
--- /mods/wpsg_mod_productvars.class.php	(revision 7219)
+++ /mods/wpsg_mod_productvars.class.php	(revision 7220)
@@ -330,30 +330,31 @@
 
 		} // public function basket_preUpdate()
-
-		public function basket_save_order(&$data, &$checkout, &$arBasket, $finish_order) {
-
-			$pv_store = array();
-
-			foreach ($arBasket['produkte'] as $product_index => $p)
-			{
-
-				if (isset($p['wpsg_mod_productvars']) && is_array($p['wpsg_mod_productvars']) && sizeof($p['wpsg_mod_productvars']) > 0)
-				{
-
-					$pv_store[$product_index] = $p['wpsg_mod_productvars'];
-
-				}
-
-			}
-
-			if (is_array($pv_store) && sizeof($pv_store) > 0)
-			{
-
-				$data['pvars'] = wpsg_q(serialize($pv_store));
-
-			}
-
+		
+		public function calculation_saveOrder(&$oCalculation, $arCalculation, &$db_data, $finish_order) { 
+			
+			if (wpsg_isSizedArray($_SESSION['wpsg']['basket'])) {
+			
+				$pv_store = [];
+							
+				foreach ($_SESSION['wpsg']['basket'] as $product_index => $p) {
+					
+					if (isset($p['wpsg_mod_productvars']) && is_array($p['wpsg_mod_productvars']) && sizeof($p['wpsg_mod_productvars']) > 0) {
+						
+						$pv_store[$product_index] = $p['wpsg_mod_productvars'];
+						
+					}
+					
+				}
+				
+				if (is_array($pv_store) && sizeof($pv_store) > 0) {
+					
+					$db_data['pvars'] = wpsg_q(serialize($pv_store));
+					
+				}
+				
+			}
+			
 		}
-
+		
 		public function order_view_row(&$p, $i)
 		{
Index: /mods/wpsg_mod_shippingadress.class.php
===================================================================
--- /mods/wpsg_mod_shippingadress.class.php	(revision 7219)
+++ /mods/wpsg_mod_shippingadress.class.php	(revision 7220)
@@ -99,37 +99,5 @@
 			
 		} // public function checkout_inner_prebutton(&$checkout_view)
-		
-		public function basket_save_order(&$data, &$checkout, &$arBasket, $finish_order)
-		{ 
- 
-			if (wpsg_getStr($checkout['diff_shippingadress']) == '1')
-			{
-
-				$data['shipping_title'] 	= wpsg_q(wpsg_getStr($checkout['shipping_title']));
-				$data['shipping_vname'] 	= wpsg_q(wpsg_getStr($checkout['shipping_vname']));
-				$data['shipping_name'] 		= wpsg_q(wpsg_getStr($checkout['shipping_name']));
-				$data['shipping_strasse'] 	= wpsg_q(wpsg_getStr($checkout['shipping_strasse'])); 
-				$data['shipping_plz'] 		= wpsg_q(wpsg_getStr($checkout['shipping_plz']));
-				$data['shipping_ort'] 		= wpsg_q(wpsg_getStr($checkout['shipping_ort']));
-				$data['shipping_firma'] 	= wpsg_q(wpsg_getStr($checkout['shipping_firma']));
-				$data['shipping_land'] 		= wpsg_q(wpsg_getStr($checkout['shipping_land']));
-				 
-			}
-			else 
-			{
-				
-				$data['shipping_title']		= wpsg_q(wpsg_getStr($checkout['title']));
-				$data['shipping_vname'] 	= wpsg_q(wpsg_getStr($checkout['vname']));
-				$data['shipping_name'] 		= wpsg_q(wpsg_getStr($checkout['name']));
-				$data['shipping_strasse'] 	= wpsg_q(wpsg_getStr($checkout['strasse'])); 
-				$data['shipping_plz'] 		= wpsg_q(wpsg_getStr($checkout['plz']));
-				$data['shipping_ort'] 		= wpsg_q(wpsg_getStr($checkout['ort']));
-				$data['shipping_firma'] 	= wpsg_q(wpsg_getStr($checkout['firma']));
-				$data['shipping_land'] 		= wpsg_q(wpsg_getStr($checkout['land']));				
-				
-			}
-
-		} // public function basket_save_order(&$data, &$checkout, &$arBasket, $finish_order)
-		
+		 		
 		public function checkCheckout(&$state, &$error, &$arCheckout)  
 		{
Index: /mods/wpsg_mod_stock.class.php
===================================================================
--- /mods/wpsg_mod_stock.class.php	(revision 7219)
+++ /mods/wpsg_mod_stock.class.php	(revision 7220)
@@ -563,50 +563,4 @@
 
 		} // public function checkBestand(&$produkt_key, $menge)
-
-		public function basket_save_product(&$data, &$product_data_db, $finish_order)
-		{
-
-			return;		// Bestand wird sonst doppelt verringert
-			if ($finish_order !== true) return;
-
-			$product_id = $this->shop->getProduktID($data['productkey']);
-			$product_data = $this->shop->cache->loadProduct($product_id);
-			$stock = $data['menge'];
-
-			/* Produktgruppe runterzÃ€hlen */
-			if ($this->shop->hasMod('wpsg_mod_productgroups'))
-			{
-
-				$pgroup = $this->db->fetchRow("SELECT `stock_aktiv`, `stock_value` FROM `".WPSG_TBL_PRODUCTS_GROUP."` WHERE `id` = '".wpsg_q($product_data['pgruppe'])."' ");
-
-				if ($pgroup['stock_aktiv'] == '1')
-				{
-
-					$this->db->Query("
-						UPDATE `".WPSG_TBL_PRODUCTS_GROUP."` SET `stock_value` = `stock_value` - '".wpsg_q($stock)."' WHERE `id` = '".wpsg_q($product_data['pgruppe'])."'
-					");
-				}
-
-			}
-
-			// Produkt runterzÃ€hlen
-
-			// Wenn ZÃ€hlung im Produkt deaktiviert, dann breche ich hier ab
-			if ($product_data['stock_count'] != '1') return;
-
-			if ($this->shop->hasMod('wpsg_mod_productvariants') && preg_match('/^pv_(.*)/', $data['productkey']))
-			{
-
-				// Bestand der Variationen runterzÃ€hlen
-				$this->shop->callMod('wpsg_mod_productvariants', 'reduceStock', array($data['productkey'], $stock));
-
-			}
-
-			// Im Produkt selbst runterzÃ€hlen
-			$this->db->Query("
-				UPDATE `".WPSG_TBL_PRODUCTS."` SET `stock` = `stock` - '".wpsg_q($stock)."' WHERE `id` = '".wpsg_q($product_id)."'
-			");
-
-		} // public function basket_save_product(&$data, &$product_data)
 
 		public function checkReduceStock(&$data, &$product_data)
Index: /mods/wpsg_mod_trustedshops.class.php
===================================================================
--- /mods/wpsg_mod_trustedshops.class.php	(revision 7219)
+++ /mods/wpsg_mod_trustedshops.class.php	(revision 7220)
@@ -285,16 +285,14 @@
 		} // public function clearSession()
 		
-		public function basket_save_order(&$data, &$checkout, &$arBasket, $finish_order) 
-		{ 
-			
-			if (wpsg_isSizedInt($arBasket['checkout']['wpsg_mod_trustedshops_set']))
-			{
-
-				$data['wpsg_mod_trustedshops_set'] = '1';
-				
-			}
-			
-		} // public function basket_save_order(&$data, &$checkout, &$arBasket, $finish_order)
-		
+		public function calculation_saveOrder(&$oCalculation, $arCalculation, &$db_data, $finish_order) {
+			
+			if (wpsg_isSizedInt($_SESSION['wpsg']['checkout']['wpsg_mod_trustedshops_set'])) {
+				
+				$db_data['wpsg_mod_trustedshops_set'] = '1';
+				
+			}
+			
+		}
+		 
 		public function order_view($order_id, &$arSidebarArray)
 		{ 
Index: /mods/wpsg_mod_weight.class.php
===================================================================
--- /mods/wpsg_mod_weight.class.php	(revision 7219)
+++ /mods/wpsg_mod_weight.class.php	(revision 7220)
@@ -215,18 +215,32 @@
 
 		} // public function basket_toArray_final(&$basket, &$arBasket)
-
-		public function basket_save_order(&$data, &$checkout, &$arBasket, $finish_order) {
-
-			$data['weight'] = $arBasket['sum']['weight'];
-
-		} // public function basket_save_order(&$data, &$checkout, &$arBasket, $finish_order)
-
-		public function basket_save_product(&$data, &$product_data, $finish_order)
-		{
-
-			$data['weight'] = $product_data['weight'];
-
-		} // public function basket_save_product(&$data, &$product_data)
-
+ 
+		/**
+		 * @var \wpsg\wpsg_calculation $oCalculation  
+		 */
+		public function calculation_saveProduct(&$oCalculation, $calc_product, &$db_product_data, $finish_order) { 
+			
+			$oProduct = wpsg_product::getInstance($calc_product['product_key']);
+			
+			$db_product_data['weight'] = wpsg_q($oProduct->weight * $calc_product['amount']);
+			 			
+		}
+		
+		public function calculation_saveOrder(&$oCalculation, $arCalculation, &$db_data, $finish_order) {
+		
+			$weight = 0;
+			
+			foreach ($arCalculation['product'] as $p) {
+				
+				$oProduct = wpsg_product::getInstance($p['product_key']);
+				
+				$weight += $p['amount'] * $oProduct->weight;
+				
+			}
+			
+			$db_data['weight'] = wpsg_q($weight);
+			
+		}
+		
 		/* --- */
 
Index: /views/order/product_table.phtml
===================================================================
--- /views/order/product_table.phtml	(revision 7219)
+++ /views/order/product_table.phtml	(revision 7220)
@@ -31,5 +31,5 @@
 		\wpsg\wpsg_calculation::TAXMODE_B2C => __('Endkundenbesteuerung'),
 		\wpsg\wpsg_calculation::TAXMODE_B2B => __('Firmenkundenbesteuerung')
-	], $this->view['oCalculation']->getTaxMode(), ['onchange' => 'WPSG_BE.updateCalculation();']); ?>
+	], $this->view['oCalculation']->getTaxMode(), ['onchange' => 'WPSG_BE.updateCalculation();', 'help' => 'tax_mode']); ?>
 
 <br />
