Index: /changelog
===================================================================
--- /changelog	(revision 7745)
+++ /changelog	(revision 7746)
@@ -366,4 +366,5 @@
 
 #4.2.4
+- Feature: Export/Import von Varianten und Variationen
 - Bugfix: Durch den Fix in 4.2.3. ("Zuordnung Produkt zu Artikel") wurden die Kategorien nicht mehr gespeichert. Dies ist korrigiert.
 - Bugfix: Eigene Kundenvariablen erzeugen bei bestehenden Kunden nicht mehr das Problem das man die Kundenverwaltung nicht Ã¶ffnen kann
Index: /controller/wpsg_ProduktController.class.php
===================================================================
--- /controller/wpsg_ProduktController.class.php	(revision 7745)
+++ /controller/wpsg_ProduktController.class.php	(revision 7746)
@@ -241,15 +241,26 @@
 			if (!wpsg_isSizedArray($arData)) { $this->addBackendError(__('Keine Daten zum Exportieren vorhanden.', 'wpsg')); $this->redirect(WPSG_URL_WP.'wp-admin/admin.php?page=wpsg-Produkt&action=index'); return; }
 
-			foreach ($arData as $k => $v)
-			{
+			foreach ($arData as $k => $v) {
+
+			    $product_id = intval($v['id']);
+
+                $addColum = function($col_key) use (&$arData) {
+
+                    foreach ($arData as $k => $v) {
+
+                        if (!isset($arData[$k][$col_key])) $arData[$k][$col_key] = '';
+
+                    }
+
+                };
 
 				// Produktattribute laden
-				if ($this->shop->hasMod('wpsg_mod_produktattribute'))
-				{
+				if ($this->shop->hasMod('wpsg_mod_produktattribute')) {
 
 					$att = $this->db->fetchAssoc("SELECT * FROM `".WPSG_TBL_AT."`");
 
-					foreach ($att as $a)
-					{
+					foreach ($att as $a) {
+
+					    $addColum('ATT_'.$a['name']);
 
 						$arData[$k]["ATT_".$a['name']] = $this->db->fetchOne("SELECT `value` FROM `".WPSG_TBL_PRODUCTS_AT."` WHERE `p_id` = '".wpsg_q($v['id'])."' AND `a_id` = '".wpsg_q($a['id'])."' ");
@@ -258,4 +269,53 @@
 
 				}
+
+				if (wpsg_ShopController::getShop()->hasMod('wpsg_mod_productvariants')) {
+
+                    if (wpsg_ShopController::getShop()->callMod('wpsg_mod_productvariants', 'isVariantsProduct', [$product_id])) {
+
+                        $arVariInfo = wpsg_ShopController::getShop()->callMod('wpsg_mod_productvariants', 'getVariants', [$product_id, true, false, true]);
+
+                        foreach ($arVariInfo as $var) {
+
+                            $row_var = $arData[$k];
+
+                            foreach ($var as $k2 => $v2) {
+
+                                if (!in_array($k2, ['arVariation'])) {
+
+                                    $addColum('PV_'.$k2);
+                                    $row_var['PV_'.$k2] = $v2;
+
+                                } else if ($k2 === 'arVariation') {
+
+                                    foreach ($v2 as $k3 => $v3) {
+
+                                        foreach ($v3 as $k4 => $v4) {
+
+                                            $addColum('PV_VARI_'.$k4);
+
+                                            $row_var['PV_VARI_'.$k4] = $v4;
+
+                                        }
+
+                                        $arData[] = $row_var;
+
+                                    }
+
+                                }
+
+                            }
+
+                            if (!wpsg_isSizedArray($var['arVariation'])) {
+
+                                $arData[] = $row_var;
+
+                            }
+
+                        }
+
+                    }
+
+                }
 
 			}
@@ -265,14 +325,12 @@
 
 			$fp = fopen($path.'/wpsg_productexport.csv', 'w');
-			fputcsv($fp, array_keys($arData[0]));;
+			fputcsv($fp, array_keys($arData[0]), ';', '"');;
 
 			$arDataExport = array();
 
-			foreach ($arData as $e)
-			{
+			foreach ($arData as $e) {
 
 				// ZeilenumbrÃŒche entfernen
-				if (get_option('wpsg_impexp_clearlinebreak') === '1')
-				{
+				if (get_option('wpsg_impexp_clearlinebreak') === '1') {
 
 					foreach ($e as $k => $v) { $e[$k] = preg_replace('/\r|\n/', '', $v); }
@@ -282,12 +340,12 @@
 				$arDataExport[] = $e;
 
-				fputcsv($fp, $e, ',', '"');
-
-			}
+				fputcsv($fp, $e, ';', '"');
+
+			}
+
 			fclose($fp);
 
 			if ($bReturnData) return array($path.'/wpsg_productexport.csv', $arDataExport);
-			else
-			{
+			else {
 
 				header('Content-type: application/download');
@@ -305,5 +363,5 @@
 
 		public function exportMediaAction() {
-	 
+
 			check_admin_referer('wpsg-product-exportMedia');
 
@@ -314,5 +372,5 @@
 			$zip = new ZipArchive();
 
-			if ($zip->open($zip_file, ZIPARCHIVE::CREATE) == true) {
+			if ($zip->open($zip_file, ZIPARCHIVE::OVERWRITE) == true) {
 
 				// Produktdaten, wie normaler Export
@@ -321,23 +379,22 @@
 
 				// Bilddaten
-				foreach ($arData as $d)
-				{
+				foreach ($arData as $d) {
 
 					$arAttachmentIDs = $this->imagehandler->getAttachmentIDs($d['id']);
 
-					if (wpsg_isSizedArray($arAttachmentIDs))
-					{
+					if (wpsg_isSizedArray($arAttachmentIDs)) {
 
 						$zip->addEmptyDir($d['id']);
 
-						foreach ($arAttachmentIDs as $attachment_id)
-						{
+						$arAttachmentIDMapping = [];
+
+						foreach ($arAttachmentIDs as $attachment_id) {
 
 							$file = get_attached_file($attachment_id);
 
-							if (file_exists($file) && is_file($file))
-							{
+							if (file_exists($file) && is_file($file)) {
 
 								$zip->addFile($file, $d['id'].'/'.basename($file));
+								$arAttachmentIDMapping[$attachment_id]['filename'] = basename($file);
 
 							}
@@ -345,4 +402,6 @@
 						}
 
+						$zip->addFromString($d['id'].'/attachment.json', json_encode($arAttachmentIDMapping));
+
 					}
 
@@ -350,5 +409,8 @@
 
 				$zip->close();
- 
+
+				// Sonst gab es im Shop Probleme mit dem Download
+				ob_clean(); ob_end_flush(); ob_end_clean();
+
 				wpsg_header::ZIP($zip_file, 'wpsg_export.zip');
 				exit;
@@ -382,12 +444,12 @@
 				$keys = array();
 				$extract_dir = '';
-
-				if (preg_match('/\.zip$/i', $_FILES['wpsg_importfile']['name']))
-				{
+				$arProductIDsHandled = [];
+                $arAttachmentMeta = [];
+
+				if (preg_match('/\.zip$/i', $_FILES['wpsg_importfile']['name'])) {
 
 					$zip = new ZipArchive();
 
-					if ($zip->open($_FILES['wpsg_importfile']['tmp_name']) === true)
-					{
+					if ($zip->open($_FILES['wpsg_importfile']['tmp_name']) === true) {
 
 						$extract_dir = sys_get_temp_dir().'/'.time();
@@ -396,21 +458,16 @@
 						$zip->close();
 
-						if (!file_exists($extract_dir) || !is_dir($extract_dir))
-						{
+						if (!file_exists($extract_dir) || !is_dir($extract_dir)) {
 
 							$this->shop->addBackendError(__('Konnte ZIP Archiv nicht entpacken.', 'wpsg'));
 							$this->redirect(WPSG_URL_WP.'wp-admin/admin.php?page=wpsg-Produkt');
 
-						}
-						else
-						{
+						} else {
 
 							$arZIPData = scandir($extract_dir);
 
-							foreach ($arZIPData as $z)
-							{
-
-								if (is_numeric($z))
-								{
+							foreach ($arZIPData as $z) {
+
+								if (is_numeric($z)) {
 
 									$arImages[$z] = array();
@@ -419,4 +476,10 @@
 									foreach ($arImageFiles as $if) { if (is_file($extract_dir.'/'.$z.'/'.$if)) { $arImages[$z][] = $if; } }
 
+									if (file_exists($extract_dir.'/'.$z.'/attachment.json')) {
+
+									    $arAttachmentMeta[$z] = json_decode(file_get_contents($extract_dir.'/'.$z.'/attachment.json'), true);
+
+                                    }
+
 								}
 
@@ -425,6 +488,5 @@
 						}
 
-						if (!file_exists($extract_dir.'/productdata.csv'))
-						{
+						if (!file_exists($extract_dir.'/productdata.csv')) {
 
 							$this->shop->addBackendError(__('Keine Produktdaten im ZIP Archiv gefunden.', 'wpsg'));
@@ -435,7 +497,5 @@
 						$handle = fopen($extract_dir.'/productdata.csv', "r");
 
-					}
-					else
-					{
+					} else {
 
 						$this->shop->addBackendError(__('Konnte ZIP Archiv nicht Ã¶ffnen.', 'wpsg'));
@@ -445,6 +505,5 @@
 
 				}
-				else
-				{
+				else {
 
 					$handle = fopen($_FILES['wpsg_importfile']['tmp_name'], "r");
@@ -453,117 +512,310 @@
 
 				$i = 0;
-				while (($row = fgetcsv ($handle, 0, ",")) !== FALSE )
-				{
-
-					if ($i > 0)
-					{
-
-						$data = array();
-
-						foreach ($keys as $k => $k_name)
-						{
-							$data[$k_name] = wpsg_q($row[$k]);
-						}
-
-						if ($data['id'] <= 0) unset($data['id']);
-
-						// Alte Sachen lÃ¶sche ich vor dem Import mit der Ãbergebenen ID !
-
-						// Produkt lÃ¶schen
-						$this->db->Query("DELETE FROM `".WPSG_TBL_PRODUCTS."` WHERE `id` = '".wpsg_q($data['id'])."'");
-
-						// Attributwerte lÃ¶schen
-						if ($this->shop->hasMod('wpsg_mod_produktattribute'))
-						{
-							$this->db->Query("DELETE FROM `".WPSG_TBL_PRODUCTS_AT."` WHERE `p_id` = '".wpsg_q($data['id'])."'");
-						}
-
-						if (!isset($data['lang_parent']) || $data['lang_parent'] <= 0) $nImported ++;
-
-						unset($data['v_id']);
-						unset($data['mwst_value']);
-						unset($data['ptemplate']);
-
-						$data_import = $data;
-
-						foreach ($data_import as $k => $v)
-						{
-							if (preg_match("/^ATT_(.*)/", $k)) { unset($data_import[$k]); }
-						}
-
-						$pNeu_id = $this->db->ImportQuery(WPSG_TBL_PRODUCTS, $data_import, true);
-
-						// Attribute speichern
-						foreach ($data as $k => $v)
-						{
-
-							if (preg_match("/^ATT_(.*)/", $k))
-							{
-
-								// Attribute ID auslesen
-								$att_id = $this->db->fetchOne("SELECT `id` FROM `".WPSG_TBL_AT."` WHERE `name` = '".wpsg_q(preg_replace("/^ATT_/", "", $k))."' ");
-
-								if ($att_id > 0)
-								{
-
-									// Attribut speichern
-									$this->db->ImportQuery(WPSG_TBL_PRODUCTS_AT, array(
-										"p_id" => wpsg_q($pNeu_id),
-										"a_id" => wpsg_q($att_id),
-										"value" => $v
-									));
-
-								}
-
-							}
-
-						}
-
-						// Bilder?
-						if (wpsg_isSizedInt($data['id']) && wpsg_isSizedArray($arImages[$data['id']]))
-						{
-
-							$arAttachmentIDs = $this->imagehandler->getAttachmentIDs($data['id']);
-
-							foreach (array_reverse($arImages[$data['id']]) as $img)
-							{
-
-								$exist = false;
-
-								// PrÃŒfen ob ein Bild anhand des Namens schon im Produkt existiert
-								foreach ($arAttachmentIDs as $attachment_id)
-								{
-
-									$file = get_attached_file($attachment_id);
-
-									if (strtolower(basename($file)) == strtolower($img)) { $exist = true; break; }
-
-								}
-
-								if (!$exist)
-								{
-
-									$this->imagehandler->addImageToProduct($extract_dir.'/'.$data['id'].'/'.$img, $data['id']);
-
-								}
-
-							}
-
-						}
-
-					}
-					else
-					{
-
-						// SchlÃŒssel erzeugen
-						$keys = $row;
-
-					}
-
-					$i ++;
-
-				}
-
-				fclose($handle);
+
+                while (($row = fgetcsv ($handle, 0, ";")) !== false) {
+
+                    if ($i > 0) {
+
+                        $data = array();
+
+                        foreach ($keys as $k => $k_name) {
+
+                            $data[$k_name] = wpsg_q($row[$k]);
+
+                        }
+
+                        if ($data['id'] <= 0) unset($data['id']);
+
+                        $product_id = intval($data['id']);
+
+                        // Alte Sachen lÃ¶sche ich vor dem Import mit der Ãbergebenen ID !
+
+                        if (!in_array($product_id, $arProductIDsHandled)) {
+
+                            // Produkt lÃ¶schen
+                            $this->db->Query("DELETE FROM `".WPSG_TBL_PRODUCTS."` WHERE `id` = '".wpsg_q($data['id'])."'");
+
+                            // Attributwerte lÃ¶schen
+                            if ($this->shop->hasMod('wpsg_mod_produktattribute')) {
+
+                                $this->db->Query("DELETE FROM `".WPSG_TBL_PRODUCTS_AT."` WHERE `p_id` = '".wpsg_q($data['id'])."'");
+
+                            }
+
+                            if (wpsg_ShopController::getShop()->hasMod('wpsg_mod_productvariants')) {
+
+                                $handledVarID = [];
+
+                                // Produktvarianten lÃ¶schen
+
+                                if ($product_id > 0 && wpsg_getInt($data['PV_id']) <= 0 && wpsg_getInt($data['PV_VARI_variation_id']) <= 0) {
+
+                                    $this->db->Query("DELETE FROM `".WPSG_TBL_PRODUCTS_VARIANT."` WHERE `product_id` = '".wpsg_q($product_id)."' ");
+                                    $this->db->Query("DELETE FROM `".WPSG_TBL_PRODUCTS_VARIATION."` WHERE `product_id` = '".wpsg_q($product_id)."' ");
+
+                                    $arProductVariant = $this->db->fetchAssoc("SELECT * FROM `".WPSG_TBL_VARIANTS."` WHERE `product_id` = '".wpsg_q($product_id)."' ");
+
+                                    foreach ($arProductVariant as $pv) {
+
+                                        $this->db->Query("DELETE FROM `".WPSG_TBL_VARIANTS."` WHERE `id` = '".wpsg_q($pv['id'])."' ");
+                                        $this->db->Query("DELETE FROM `".WPSG_TBL_VARIANTS_VARI."` WHERE `variant_id` = '".wpsg_q($pv['id'])."' ");
+
+                                    }
+
+                                }
+
+                            }
+
+                            // Bilder?
+                            if (wpsg_isSizedInt($data['id']) && wpsg_isSizedArray($arImages[$data['id']])) {
+
+                                $arAttachmentIDs = $this->imagehandler->getAttachmentIDs($data['id']);
+
+                                foreach (array_reverse($arImages[$data['id']]) as $img) {
+
+                                    if ($img === 'attachment.json') continue;
+
+                                    $exist = false;
+
+                                    // PrÃŒfen ob ein Bild anhand des Namens schon im Produkt existiert
+                                    foreach ($arAttachmentIDs as $attachment_id) {
+
+                                        $file = get_attached_file($attachment_id);
+
+                                        if (strtolower(basename($file)) == strtolower($img)) {
+
+                                            // Alte Attachment ID suchen und zuweisen
+                                            if (isset($arAttachmentMeta[$product_id])) {
+
+                                                foreach ($arAttachmentMeta[$product_id] as $a_id => $a_data) {
+
+                                                    if ($a_data['filename'] === $img) {
+
+                                                        $arAttachmentMeta[$product_id][$a_id]['attachment_new_id'] = $attachment_id;
+
+                                                    }
+
+                                                }
+
+                                            }
+
+                                            $exist = true; break;
+
+                                        }
+
+                                    }
+
+                                    if (!$exist) {
+
+                                        $attachment_new_id = $this->imagehandler->addImageToProduct($extract_dir.'/'.$data['id'].'/'.$img, $data['id']);
+
+                                        // Alte Attachment ID suchen und zuweisen
+                                        if (isset($arAttachmentMeta[$product_id])) {
+
+                                            foreach ($arAttachmentMeta[$product_id] as $a_id => $a_data) {
+
+                                                if ($a_data['filename'] === $img) {
+
+                                                    $arAttachmentMeta[$product_id][$a_id]['attachment_new_id'] = $attachment_new_id;
+
+                                                }
+
+                                            }
+
+                                        }
+
+                                    }
+
+                                }
+
+                            }
+
+                        }
+
+                        // Produktvariante eintragen
+                        if (wpsg_ShopController::getShop()->hasMod('wpsg_mod_productvariants')) {
+
+                            if (intval($data['PV_id']) > 0 && !in_array(intval($data['PV_id']), $handledVarID)) {
+
+                                // Eintrag der Variante prÃŒfen
+                                $exist_row = $this->db->fetchRow("SELECT * FROM `".WPSG_TBL_VARIANTS."` WHERE `id` = '".wpsg_q($data['PV_id'])."' ");
+                                $var_data = [];
+
+                                foreach ($data as $k => $v) {
+
+                                    if (substr($k, 0, 3) === 'PV_' && substr($k, 0, 8) !== 'PV_VARI_') {
+
+                                        $var_data[substr($k, 3)] = $v;
+
+                                    }
+
+                                }
+
+                                if (isset($exist_row['id']) && intval($exist_row['id']) === intval($data['PV_id']) && intval($exist_row['product_id']) === intval($data['PV_product_id'])) {
+
+                                    // Update
+                                    wpsg_ShopController::getShop()->db->UpdateQuery(WPSG_TBL_VARIANTS, $var_data, " `id` = '".intval($exist_row['id'])."' ", true);
+
+                                } else if (!isset($exist_row['id'])) {
+
+                                    // Insert
+                                    wpsg_ShopController::getShop()->db->ImportQuery(WPSG_TBL_VARIANTS, $var_data, true);
+
+                                } else die('Es gab ein Fehler in Zeile ".$i." mit den Varianten.');
+
+                                // Eintrag in products_variant prÃŒfen
+                                if (intval($data['PV_product_id']) > 0) {
+
+                                    $exist_row = wpsg_ShopController::getShop()->db->fetchRow("SELECT * FROM `".WPSG_TBL_PRODUCTS_VARIANT."` WHERE `variant_id` = '".intval($data['PV_id'])."' AND `product_id` = '".intval($product_id)."' ");
+                                    $var_data['variant_id'] = $data['PV_id'];
+
+                                    unset($var_data['id']);
+
+                                    if (isset($exist_row['id'])) {
+
+                                        // Update
+                                        wpsg_ShopController::getShop()->db->UpdateQuery(WPSG_TBL_PRODUCTS_VARIANT, $var_data, " `id` = '".intval($exist_row['id'])."' ", true);
+
+                                    } else {
+
+                                        // Insert
+                                        wpsg_ShopController::getShop()->db->ImportQuery(WPSG_TBL_PRODUCTS_VARIANT, $var_data, true);
+
+                                    }
+
+                                }
+
+                                $handledVarID[] = intval($data['PV_id']);
+
+                            }
+
+                            // Produktvariation eintragen
+                            if (intval($data['PV_VARI_variation_id']) > 0) {
+
+                                $vari_data = [
+                                    'variant_id' => intval($data['PV_id'])
+                                ];
+
+                                foreach ($data as $k => $v) {
+
+                                    if (substr($k, 0, 8) === 'PV_VARI_' && !in_array($k, ['PV_VARI_id'])) {
+
+                                        $vari_data[substr($k, 8)] = $v;
+
+                                    }
+
+                                }
+
+                                // Eintrag in Vari prÃŒfen
+                                $exist_row = wpsg_ShopController::getShop()->db->fetchRow("SELECT * FROM `".WPSG_TBL_VARIANTS_VARI."` WHERE `id` = '".intval($data['PV_VARI_variation_id'])."' ");
+                                $vari_data['id'] = $data['PV_VARI_variation_id'];
+
+                                if (isset($exist_row['id'])) {
+
+                                    // Update
+                                    wpsg_ShopController::getShop()->db->UpdateQuery(WPSG_TBL_VARIANTS_VARI, $vari_data, " `id` = '".intval($exist_row['id'])."' ", true);
+
+                                } else {
+
+                                    // Insert
+                                    wpsg_ShopController::getShop()->db->ImportQuery(WPSG_TBL_VARIANTS_VARI, $vari_data, true);
+
+                                }
+
+                                // Eintrag in products_variation prÃŒfen
+                                $exist_row = wpsg_ShopController::getShop()->db->fetchRow("SELECT * FROM `".WPSG_TBL_PRODUCTS_VARIATION."` WHERE `variation_id` = '".intval($data['PV_VARI_variation_id'])."' AND `product_id` = '".intval($product_id)."' ");
+
+                                foreach (['images', 'images_set'] as $col) {
+
+                                    $arNewExploded = [];
+
+                                    foreach (explode(',', $vari_data[$col]) as $old_id) {
+
+                                        if (isset($arAttachmentMeta[$product_id][$old_id]['attachment_new_id'])) $arNewExploded[] = $arAttachmentMeta[$product_id][$old_id]['attachment_new_id'];
+                                        else if ($old_id > 0) $arNewExploded[] = $old_id;
+
+                                    }
+
+                                    $vari_data[$col] = implode(',', $arNewExploded);
+
+                                }
+
+                                if (isset($exist_row['id'])) {
+
+                                    // Update
+                                    wpsg_ShopController::getShop()->db->UpdateQuery(WPSG_TBL_PRODUCTS_VARIATION, $vari_data, " `id` = '".intval($exist_row['id'])."' ", true);
+
+                                } else {
+
+                                    // Insert
+                                    wpsg_ShopController::getShop()->db->ImportQuery(WPSG_TBL_PRODUCTS_VARIATION, $vari_data, true);
+
+                                }
+
+                            }
+
+                        }
+
+                        if (in_array($product_id, $arProductIDsHandled)) continue;
+                        else $arProductIDsHandled[] = $product_id;
+
+                        if (!isset($data['lang_parent']) || $data['lang_parent'] <= 0) $nImported ++;
+
+                        unset($data['v_id']);
+                        unset($data['mwst_value']);
+                        unset($data['ptemplate']);
+
+                        $data_import = $data;
+
+                        foreach ($data_import as $k => $v) {
+
+                            if (
+                                preg_match("/^ATT_(.*)/", $k) ||
+                                preg_match("/^PV_(.*)/", $k)
+                            ) { unset($data_import[$k]); }
+
+                        }
+
+                        $pNeu_id = $this->db->ImportQuery(WPSG_TBL_PRODUCTS, $data_import, true);
+
+                        // Attribute speichern
+                        foreach ($data as $k => $v)
+                        {
+
+                            if (preg_match("/^ATT_(.*)/", $k))
+                            {
+
+                                // Attribute ID auslesen
+                                $att_id = $this->db->fetchOne("SELECT `id` FROM `".WPSG_TBL_AT."` WHERE `name` = '".wpsg_q(preg_replace("/^ATT_/", "", $k))."' ");
+
+                                if ($att_id > 0)
+                                {
+
+                                    // Attribut speichern
+                                    $this->db->ImportQuery(WPSG_TBL_PRODUCTS_AT, array(
+                                        "p_id" => wpsg_q($pNeu_id),
+                                        "a_id" => wpsg_q($att_id),
+                                        "value" => $v
+                                    ));
+
+                                }
+
+                            }
+
+                        }
+
+                    }
+                    else
+                    {
+
+                        // SchlÃŒssel erzeugen
+                        $keys = $row;
+
+                    }
+
+                    $i ++;
+
+                }
+                fclose($handle);
 
 				$this->shop->addBackendMessage(wpsg_translate(__('#1# Produkte wurden importiert.', 'wpsg'), $nImported));
Index: /controller/wpsg_SystemController.class.php
===================================================================
--- /controller/wpsg_SystemController.class.php	(revision 7745)
+++ /controller/wpsg_SystemController.class.php	(revision 7746)
@@ -7,5 +7,5 @@
 	{
 				
-		/** Datenbankobjekt */
+		/** @var wpsg_db Datenbankobjekt */
 		var $db;
 		
Index: /lib/wpsg_calculation.class.php
===================================================================
--- /lib/wpsg_calculation.class.php	(revision 7745)
+++ /lib/wpsg_calculation.class.php	(revision 7746)
@@ -1023,5 +1023,5 @@
 				$oInvoiceCountry = \wpsg_country::getInstance($country_id);
 				 
-				if (!$oInvoiceCountry->isLoaded()) throw new \Exception(wpsg_translate(__('Land mit der ID #1# existiert nicht mehr.', 'wpsg'), $country_id));
+				if (!$oInvoiceCountry->isLoaded()) throw new \Exception(wpsg_translate(__('Land mit der ID #1# in Adress ID #2# existiert nicht mehr.', 'wpsg'), $country_id, $db_order['adress_id']));
 				
 				$this->addCountry($oInvoiceCountry->id, $oInvoiceCountry->mwst, $oInvoiceCountry->mwst_a,$oInvoiceCountry->mwst_b, $oInvoiceCountry->mwst_c, $oInvoiceCountry->mwst_d, false);
Index: /lib/wpsg_header.class.php
===================================================================
--- /lib/wpsg_header.class.php	(revision 7745)
+++ /lib/wpsg_header.class.php	(revision 7746)
@@ -83,5 +83,5 @@
 		public static function ZIP($file, $filename = false)
 		{
-			
+
 			if ($filename === false) $filename = basename($file);
 			
@@ -94,5 +94,5 @@
 			header("Content-Disposition: attachment; filename=\"".$filename."\"");
 			header("Content-Transfer-Encoding: binary");
-			header("Content-Length: ".filesize($file));
+			header("Content-Length: ".filesize($file)."\\n");
 		
 			readfile($file);
Index: /mods/wpsg_mod_productvariants.class.php
===================================================================
--- /mods/wpsg_mod_productvariants.class.php	(revision 7745)
+++ /mods/wpsg_mod_productvariants.class.php	(revision 7746)
@@ -1855,6 +1855,5 @@
 		 * @param Boolean $global Globale Varianten?
 		 */
-		public function getVariants($product_id = false, $global = true, $onlyActive = false, $loadVariationen = false)
-		{
+		public function getVariants($product_id = false, $global = true, $onlyActive = false, $loadVariationen = false) {
 
 			$strQuerySELECT = "";
@@ -1863,6 +1862,5 @@
 			$strProductQuery = " AND ( 0 ";
 
-			if (wpsg_isSizedInt($product_id))
-			{
+			if (wpsg_isSizedInt($product_id)) {
 
 				$strProductQuery .= " OR V.`product_id` = '".wpsg_q($product_id)."' ";
@@ -1892,7 +1890,5 @@
 				$strQueryORDER .= " PV.`pos` ASC, ";
 
-			}
-			else
-			{
+			} else {
 
 				$strQuerySELECT .= ", '0' AS `count_active` ";
@@ -1900,6 +1896,5 @@
 			}
 
-			if ($global === true)
-			{
+			if ($global === true) {
 
 				$strProductQuery .= " OR V.`product_id` = '0' ";
@@ -1959,5 +1954,5 @@
 							SELECT
 								PVI.*,
-								VI.`name`
+								VI.`name`, VI.`shortname`, VI.`deleted`, VI.`pos`
 							FROM
 								`".WPSG_TBL_VARIANTS_VARI."` AS VI
@@ -2300,3 +2295,2 @@
 	} // class wpsg_mod_productvariants extends wpsg_mod_basic
 
-?>
Index: /mods/wpsg_mod_produktattribute.class.php
===================================================================
--- /mods/wpsg_mod_produktattribute.class.php	(revision 7745)
+++ /mods/wpsg_mod_produktattribute.class.php	(revision 7746)
@@ -58,9 +58,11 @@
 			 */
 			$sql = "CREATE TABLE ".WPSG_TBL_PRODUCTS_AT." (
+			        id mediumint(9) NOT NULL AUTO_INCREMENT,
 			   		p_id mediumint(9) NOT NULL,
 			   		a_id mediumint(9) NOT NULL,
 			   		value TEXT NOT NULL,
 			   		KEY p_id (p_id),
-			   		KEY a_id (a_id)
+			   		KEY a_id (a_id),
+			   		PRIMARY KEY (id)
 				) ENGINE=MyISAM DEFAULT CHARSET=utf8;";
 
Index: /views/mods/mod_productvariants/admin_edit.phtml
===================================================================
--- /views/mods/mod_productvariants/admin_edit.phtml	(revision 7745)
+++ /views/mods/mod_productvariants/admin_edit.phtml	(revision 7746)
@@ -18,9 +18,10 @@
       			<?php $colspan = 0; if (wpsg_isSizedInt($this->view['product_id'])) { ?>
       			<th class="col_active"><?php echo __('Aktiv', 'wpsg'); ?></th>
-      		
+      		    <?php } ?>
+
       			<th class="col_id"><?php echo __('Id', 'wpsg'); ?></th>
         		<th class="col1"><?php echo __('Name', 'wpsg'); ?></th> 
         		<th class="col_shortname"><?php echo __('Kurzname'); ?></th>
-      			<?php $colspan += 3; } ?>
+      			<?php $colspan += 3; ?>
         		
         		<?php if (wpsg_isSizedInt($this->view['product_id'])) { $colspan += 2; ?>
