Robert Bedner il y a 12 ans
commit
5b2c9656fc
80 fichiers modifiés avec 7051 ajouts et 0 suppressions
  1. 3 0
      .gitignore
  2. 126 0
      App.xaml
  3. 112 0
      App.xaml.cs
  4. BIN
      AssemblyVersion.exe
  5. 98 0
      Control/DepartmentCase.cs
  6. 57 0
      Control/IO/ConfigIO.cs
  7. 34 0
      Control/IO/GchrConfigIO.cs
  8. 16 0
      Control/IO/KontenIO.cs
  9. 34 0
      Control/Logger.cs
  10. 103 0
      Control/Printing/PageElement.cs
  11. 68 0
      Control/Printing/Paginator.cs
  12. 166 0
      Control/Tasks/Datenimport.cs
  13. 142 0
      Control/Tasks/Export.cs
  14. 128 0
      Control/Tasks/Kontenrahmen.cs
  15. 14 0
      Control/Tasks/ManuelleKonten.cs
  16. 144 0
      Control/Tasks/Task.cs
  17. 109 0
      Control/Tasks/TaskManager.cs
  18. 183 0
      Control/Tasks/Uebersetzung.cs
  19. 26 0
      Control/Tasks/UebersetzungStat.cs
  20. 25 0
      Control/Tasks/UebersetzungSuSa.cs
  21. 138 0
      Control/Tasks/Verarbeitung.cs
  22. 104 0
      Control/Tasks/Verrechnung.cs
  23. 184 0
      Control/ThreadXData.cs
  24. 330 0
      GCHR.5.1.ReSharper.user
  25. 259 0
      GCHR.csproj
  26. 18 0
      GCHR.csproj.user
  27. BIN
      GCHR.ico
  28. BIN
      GCHR.png
  29. 20 0
      GCHR.sln
  30. BIN
      GCHR.suo
  31. 5 0
      LocalTestRun.testrunconfig
  32. 192 0
      Main.xaml
  33. 202 0
      Main.xaml.cs
  34. 73 0
      Mandantenschnittstelle/Citroen.cs
  35. 72 0
      Mandantenschnittstelle/Fiat.cs
  36. 7 0
      Mandantenschnittstelle/Ford.cs
  37. 83 0
      Mandantenschnittstelle/Honda.cs
  38. 42 0
      Mandantenschnittstelle/IMandant.cs
  39. 4 0
      Mandantenschnittstelle/Mandanten.cs
  40. 72 0
      Mandantenschnittstelle/Opel.cs
  41. 73 0
      Mandantenschnittstelle/Peugeot.cs
  42. 66 0
      Mandantenschnittstelle/Test.cs
  43. 187 0
      Mandantenschnittstelle/Volkswagen.cs
  44. 86 0
      Model/CTripleDES.cs
  45. 73 0
      Model/Constants.cs
  46. 15 0
      Model/DateipfadeXml.cs
  47. 154 0
      Model/GchrConfig.cs
  48. 357 0
      Model/Konfiguration.cs
  49. 294 0
      Model/Konto/HaendlerKonto.cs
  50. 9 0
      Model/Konto/IKonto.cs
  51. 15 0
      Model/Konto/Konten.cs
  52. 4 0
      Model/Konto/KontoTypen.cs
  53. 47 0
      Model/Konto/Saldo.cs
  54. 81 0
      Model/Periode.cs
  55. 66 0
      Model/Uebersetzung/Eintrag.cs
  56. 60 0
      Model/Uebersetzung/Exceptions.cs
  57. 47 0
      Model/Uebersetzung/HerstellerKontenrahmen.cs
  58. 60 0
      Model/Uebersetzung/HerstellerKonto.cs
  59. 102 0
      Model/Uebersetzung/KontoTyp.cs
  60. 45 0
      Model/Uebersetzung/Regel.cs
  61. 46 0
      Model/Uebersetzung/Uebersetzungstabelle.cs
  62. 54 0
      Properties/AssemblyInfo.cs
  63. 63 0
      Properties/Resources.Designer.cs
  64. 120 0
      Properties/Resources.resx
  65. 26 0
      Properties/Settings.Designer.cs
  66. 7 0
      Properties/Settings.settings
  67. BIN
      Resources/GlobalCube.png
  68. 76 0
      Tests.cs
  69. 20 0
      Themes/Generic.xaml
  70. 73 0
      UpgradeLog.XML
  71. 63 0
      View/Ampel.xaml
  72. 140 0
      View/Ampel.xaml.cs
  73. 259 0
      View/Einstellungen.xaml
  74. 243 0
      View/Einstellungen.xaml.cs
  75. 84 0
      View/ManuelleKontenBearbeiten.xaml
  76. 104 0
      View/ManuelleKontenBearbeiten.xaml.cs
  77. 207 0
      _UpgradeReport_Files/UpgradeReport.css
  78. 232 0
      _UpgradeReport_Files/UpgradeReport.xslt
  79. BIN
      _UpgradeReport_Files/UpgradeReport_Minus.gif
  80. BIN
      _UpgradeReport_Files/UpgradeReport_Plus.gif

+ 3 - 0
.gitignore

@@ -0,0 +1,3 @@
+bin/
+obj/
+_ReSharper.*/

+ 126 - 0
App.xaml

@@ -0,0 +1,126 @@
+<Application x:Class="GCHR.App"
+    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" DispatcherUnhandledException="ApplicationDispatcherUnhandledException">
+    <Application.Resources>
+         <ControlTemplate x:Key="GlassButton" TargetType="{x:Type Button}">
+            <ControlTemplate.Resources>
+                <Storyboard x:Key="Timeline1">
+                    <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="glow" Storyboard.TargetProperty="(UIElement.Opacity)">
+                        <SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="1"/>
+                    </DoubleAnimationUsingKeyFrames>
+                </Storyboard>
+                <Storyboard x:Key="Timeline2">
+                    <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="glow" Storyboard.TargetProperty="(UIElement.Opacity)">
+                        <SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0"/>
+                    </DoubleAnimationUsingKeyFrames>
+                </Storyboard>
+            </ControlTemplate.Resources>
+            <Border BorderBrush="#FFFFFFFF" BorderThickness="1,1,1,1" CornerRadius="4,4,4,4">
+                <Border x:Name="border" Background="#9EBFDE" BorderBrush="#FF000000" BorderThickness="1,1,1,1" CornerRadius="4,4,4,4">
+                    <Grid>
+                        <Grid.RowDefinitions>
+                            <RowDefinition Height="0.507*"/>
+                            <RowDefinition Height="0.493*"/>
+                        </Grid.RowDefinitions>
+
+                        <Border Grid.RowSpan="2" HorizontalAlignment="Stretch" Margin="0,0,0,0" x:Name="shine" Width="Auto" CornerRadius="4,4,0,0">
+                            <Border.Background>
+                                <LinearGradientBrush EndPoint="0.494,0.889" StartPoint="0.494,0.028">
+                                    <!--<GradientStop Color="#99FFFFFF" Offset="0"/>
+                                    <GradientStop Color="#33FFFFFF" Offset="1"/>-->
+                                    <GradientStop Color="#FF9EBFDE" Offset="0"/>
+                                    <GradientStop Color="#FF30567A" Offset="1"/>
+                                </LinearGradientBrush>
+                            </Border.Background>
+                        </Border>
+                        <Border Opacity="0" HorizontalAlignment="Stretch" x:Name="glow" Width="Auto" Grid.RowSpan="2" CornerRadius="4,4,4,4">
+                            <Border.Background>
+                                <RadialGradientBrush>
+                                    <RadialGradientBrush.RelativeTransform>
+                                        <TransformGroup>
+                                            <ScaleTransform ScaleX="1.702" ScaleY="2.243"/>
+                                            <SkewTransform AngleX="0" AngleY="0"/>
+                                            <RotateTransform Angle="0"/>
+                                            <TranslateTransform X="-0.368" Y="-0.152"/>
+                                        </TransformGroup>
+                                    </RadialGradientBrush.RelativeTransform>
+                                    <GradientStop Color="#B29EBFDE" Offset="0"/>
+                                    <GradientStop Color="#009EBFDE" Offset="1"/>
+                                    <!--<GradientStop Color="White" Offset="0"/>
+                                    <GradientStop Color="LightBlue" Offset="1"/>-->
+                                </RadialGradientBrush>
+                            </Border.Background>
+                        </Border>
+                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Width="Auto" Grid.RowSpan="2"/>
+                    </Grid>
+                </Border>
+            </Border>
+            <ControlTemplate.Triggers>
+                <Trigger Property="IsEnabled" Value="False">
+                    <Setter Property="Opacity" TargetName="shine" Value="0.0"/>
+                    <Setter Property="Background" TargetName="border" Value="#FFCCCCCC"/>
+                    <Setter Property="Visibility" TargetName="glow" Value="Hidden"/>
+                </Trigger>
+                <Trigger Property="IsPressed" Value="True">
+                    <Setter Property="Opacity" TargetName="shine" Value="0.4"/>
+                    <Setter Property="Background" TargetName="border" Value="#100000FF"/>
+                    <Setter Property="Visibility" TargetName="glow" Value="Hidden"/>
+                </Trigger>
+                <Trigger Property="IsMouseOver" Value="True">
+                    <Trigger.EnterActions>
+                        <BeginStoryboard Storyboard="{StaticResource Timeline1}"/>
+                    </Trigger.EnterActions>
+                    <Trigger.ExitActions>
+                        <BeginStoryboard x:Name="Timeline2_BeginStoryboard" Storyboard="{StaticResource Timeline2}"/>
+                    </Trigger.ExitActions>
+                </Trigger>
+            </ControlTemplate.Triggers>
+            </ControlTemplate>
+
+        <ControlTemplate x:Key="GlassProgressBar" TargetType="{x:Type ProgressBar}">
+            <Border BorderBrush="#FFFFFFFF" BorderThickness="1,1,1,1" CornerRadius="4,4,4,4">
+                <Border x:Name="border" Background="#9EBFDE" BorderBrush="#FF000000" BorderThickness="1,1,1,1" CornerRadius="4,4,4,4">
+                    <Grid>
+                        <Grid.RowDefinitions>
+                            <RowDefinition Height="0.507*"/>
+                            <RowDefinition Height="0.493*"/>
+                        </Grid.RowDefinitions>
+                        <Decorator Grid.RowSpan="2" Name="PART_Track">
+                            <Border Name="PART_Indicator" HorizontalAlignment="Left"
+                                Width="Auto" Grid.RowSpan="2" CornerRadius="4,4,4,4"
+                                Background="Black" />
+                        </Decorator>
+                        <Border Opacity="0" HorizontalAlignment="Stretch" x:Name="glow" Width="Auto" Grid.RowSpan="2" CornerRadius="4,4,4,4">
+                            <Border.Background>
+                                <RadialGradientBrush>
+                                    <RadialGradientBrush.RelativeTransform>
+                                        <TransformGroup>
+                                            <ScaleTransform ScaleX="1.702" ScaleY="2.243"/>
+                                            <SkewTransform AngleX="0" AngleY="0"/>
+                                            <RotateTransform Angle="0"/>
+                                            <TranslateTransform X="-0.368" Y="-0.152"/>
+                                        </TransformGroup>
+                                    </RadialGradientBrush.RelativeTransform>
+                                    <GradientStop Color="#B29EBFDE" Offset="0"/>
+                                    <GradientStop Color="#009EBFDE" Offset="1"/>
+                                </RadialGradientBrush>
+                            </Border.Background>
+                        </Border>
+                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Width="Auto" Grid.RowSpan="2"/>
+                        <Border HorizontalAlignment="Stretch" Margin="0,0,0,0" x:Name="shine" Width="Auto" CornerRadius="4,4,0,0">
+                            <Border.Background>
+                                <LinearGradientBrush EndPoint="0.494,0.889" StartPoint="0.494,0.028">
+                                    <GradientStop Color="#99FFFFFF" Offset="0" />
+                                    <GradientStop Color="#338DBDFF" Offset="1" />
+                                </LinearGradientBrush>
+                            </Border.Background>
+                        </Border>
+                    </Grid>
+                </Border>
+            </Border>
+            <ControlTemplate.Triggers>
+
+            </ControlTemplate.Triggers>
+        </ControlTemplate>
+    </Application.Resources>
+</Application>

+ 112 - 0
App.xaml.cs

@@ -0,0 +1,112 @@
+using System;
+using System.ComponentModel;
+using System.IO;
+using System.Windows;
+using System.Windows.Threading;
+using GCHR.Control;
+using GCHR.Control.Tasks;
+using GCHR.Model;
+using Microsoft.Win32;
+
+namespace GCHR
+{
+    public partial class App
+    {
+        private TaskManager _tasks;
+
+        protected override void OnStartup(StartupEventArgs e)
+        {
+            FrameworkVersionPruefen();
+            KonfigdateiUmbenennen();
+            
+            if (e.Args.Length == 0)
+            {
+                StartupUri = new Uri("Main.xaml", UriKind.Relative);
+                base.OnStartup(e);
+            }
+            else
+            {
+                if (e.Args[0].Length == 6)
+                {
+                    ConsoleStart(e.Args[0]);
+                }
+                else
+                {
+                    Console.WriteLine(@"Aufruf:\n\tGCHR.exe JJJJMM");
+                    Shutdown();
+                }
+
+            }
+        }
+
+        private void KonfigdateiUmbenennen()
+        {
+            if (File.Exists(Constants.ConfigDatei)) return;
+            if (File.Exists(Constants.ConfigDateiAlt))
+            {
+                File.Move(Constants.ConfigDateiAlt, Constants.ConfigDatei);
+            }
+            else
+            {
+                MessageBox.Show(string.Format("Konfigurationsdatei '{0}' nicht vorhanden!", Constants.ConfigDatei));
+                Logger.Info(string.Format("Konfigurationsdatei '{0}' nicht vorhanden!", Constants.ConfigDatei));
+                Shutdown();
+            }
+        }
+
+        private static void FrameworkVersionPruefen()
+        {
+            try
+            {
+                // ReSharper disable PossibleNullReferenceException
+                var installedVersions = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP");
+                var versionNames = installedVersions.GetSubKeyNames();
+                var framework = versionNames[versionNames.Length - 1].Substring(1);
+                var sp = installedVersions.OpenSubKey(versionNames[versionNames.Length - 1]).GetValue("SP", 0).ToString();
+                // ReSharper restore PossibleNullReferenceException
+
+                if ((framework == "3.5" || sp == "1") || framework.Substring(0, 1) == "4") return;
+                MessageBox.Show(string.Format(".NET-Framework Version {0} SP{1} gefunden.", framework, sp));
+                Logger.Info(string.Format(".NET-Framework Version {0} SP{1} gefunden.", framework, sp));
+            }
+            catch (NullReferenceException)
+            {
+                Logger.Info(string.Format("Keine Informationen über .NET-Framework-Installationen gefunden."));
+            }
+        }
+
+        private void ConsoleStart(String periode)
+        {
+            Logger.Info("GCHR - Start im Konsolenmodus");
+            _tasks = new TaskManager();
+            _tasks.CreateTasks(Ablaufsteuerung, new Periode(periode));
+            _tasks.TryRunNextWorker();
+            _tasks.Data.AufManuelleKontenWarten.Set();
+        }
+
+        private void Ablaufsteuerung(object s, RunWorkerCompletedEventArgs e)
+        {
+            var aktuellerWorker = (BackgroundWorker)s;
+            var aktuelleAufgabe = _tasks.GetAufgabeByWorker(aktuellerWorker);
+
+            if (e.Error == null)
+            {
+                Console.WriteLine(aktuelleAufgabe + @"... OK.");
+            }
+            else
+            {
+                Console.WriteLine(aktuelleAufgabe + @"... Abbruch." + Environment.NewLine + e.Error.Message);
+                Shutdown();
+            }
+            if (aktuelleAufgabe.ID == 9)
+            {
+                Shutdown();
+            }
+        }
+
+        private void ApplicationDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
+        {
+            Logger.Info(e.Exception.ToString());
+        }
+    }
+}

BIN
AssemblyVersion.exe


+ 98 - 0
Control/DepartmentCase.cs

@@ -0,0 +1,98 @@
+using System.Linq;
+using GCHR.Model.Konto;
+
+namespace GCHR.Control
+{
+    public class DepartmentCase
+    {
+        private readonly string[] _markenCase4 = new[] { "1", "2", "3" };
+
+        private readonly string _hauptbetrieb;
+        private readonly string _hauptmarke;
+        private readonly string _bilanzBetrieb = "07";
+        private readonly string _bilanzMarke = "0";
+
+        private readonly string _betriebWildcard;
+        private readonly string _markeWildcard;
+
+        private readonly int _kontoLaenge;
+
+        public DepartmentCase(string marke, string betrieb, string bilanzMarke, string bilanzBetrieb, int kontoLaenge)
+        {
+            _hauptmarke = marke;
+            _hauptbetrieb = betrieb;
+            _bilanzMarke = bilanzMarke;
+            _bilanzBetrieb = bilanzBetrieb;
+            _markeWildcard = new string('?', _hauptmarke.Length);
+            _betriebWildcard = new string('?', _hauptbetrieb.Length);
+            _kontoLaenge = kontoLaenge;
+        }
+
+        public void DepartmentUmwandeln(HaendlerKonto konto)
+        {
+            if (konto.Case == null || konto.Case.Length <= 0) return;
+            var departmentCase = konto.Case.Replace("-", "");
+            
+            switch (departmentCase.Substring(0, 1))
+            {
+                case "1":
+                    konto.Marke = MarkeAusCaseOderHauptmarke(departmentCase);
+                    konto.Betrieb = _hauptbetrieb;
+                    return;
+                case "2":
+                    if (departmentCase.Length > 1)
+                    {
+                        konto.Marke = departmentCase.Substring(1);
+                        return;
+                    }
+                    break;
+                case "3":
+                    konto.Marke = _hauptmarke;
+                    return;
+                case "4":
+                    if (_markenCase4.Contains(konto.Marke))
+                    {
+                        return;
+                    }
+                    konto.Marke = _hauptmarke;
+                    return;
+                case "5":
+                    if (departmentCase.Length > 1 || konto.Kontonummer.Length > _kontoLaenge)
+                    {
+                        var dept = (departmentCase.Length > 1) ? departmentCase.Substring(1) : konto.Kontonummer;
+
+                        konto.Marke = Marke(dept);
+                        konto.Betrieb = Betrieb(dept);
+                    }
+                    
+                    konto.Marke = (konto.Marke == null || konto.Marke == _markeWildcard) ? _hauptmarke : konto.Marke;
+                    konto.Betrieb = (konto.Betrieb == null || konto.Betrieb == _betriebWildcard) ? _hauptbetrieb : konto.Betrieb;
+
+                    if (departmentCase.Length > 1 || konto.Kontonummer.Length <= _kontoLaenge) return;
+                    konto.Kontonummer = konto.Kontonummer.Substring(_hauptmarke.Length + _hauptbetrieb.Length);
+                    return;
+                case "B":
+                    konto.Marke = _bilanzMarke;
+                    konto.Betrieb = _bilanzBetrieb;
+                    return;
+                default:
+                    break;
+            }
+        }
+
+        private string MarkeAusCaseOderHauptmarke(string departmentCase)
+        {
+            return (departmentCase.Length > 1) ? departmentCase.Substring(1, _hauptmarke.Length) : _hauptmarke;
+        }
+
+        private string Marke(string dept)
+        {
+            return dept.Substring(0, _hauptmarke.Length);
+        }
+
+        private string Betrieb (string dept)
+        {
+            return dept.Substring(_hauptmarke.Length, _hauptbetrieb.Length);
+        }
+    }
+}

+ 57 - 0
Control/IO/ConfigIO.cs

@@ -0,0 +1,57 @@
+using System;
+using System.IO;
+using System.Windows;
+using System.Xml.Serialization;
+
+namespace GCHR.Control.IO
+{
+    abstract class ConfigIO
+    {
+        protected ConfigIO(string datei, Type type)
+        {
+            _datei = datei;
+            _type = type;
+        }
+
+        private readonly string _datei;
+        private readonly Type _type;
+
+        private string BackupDatei { get { return string.Format("{0}.bak", _datei); } }
+
+        public abstract object Laden();
+
+        protected object DateiLaden()
+        {
+            if (!File.Exists(_datei)) return null;
+            var serializer = new XmlSerializer(_type);
+            using (var stream = File.OpenText(_datei))
+            {
+                var gcsConfig = serializer.Deserialize(stream);
+                stream.Close();
+                return gcsConfig;
+            }
+        }
+
+        public void Speichern(object config)
+        {
+            var serializer = new XmlSerializer(_type);
+
+            try
+            {
+                using (var stream = File.CreateText(BackupDatei))
+                {
+                    serializer.Serialize(stream, config);
+                    stream.Close();
+                }
+                File.Delete(_datei);
+                File.Move(BackupDatei, _datei);
+            }
+            catch (Exception)
+            {
+                MessageBox.Show(
+                    string.Format("Es ist ein Fehler aufgetreten. Die Datei '{0}' konnte nicht gespeichert werden.",
+                                  _datei));
+            }
+        }
+    }
+}

+ 34 - 0
Control/IO/GchrConfigIO.cs

@@ -0,0 +1,34 @@
+using GCHR.Model;
+
+namespace GCHR.Control.IO
+{
+    class GchrConfigIO : ConfigIO
+    {
+        public GchrConfigIO(string datei) : base(datei, typeof(GchrConfig))
+        {
+        }
+
+        public override object Laden()
+        {
+            var config = (GchrConfig)DateiLaden() ?? NeueInstanz();
+            VersionsUpdate(config);
+            return config;
+        }
+
+        private static void VersionsUpdate(GchrConfig config)
+        {
+            config.Einstellungen.Update = null;
+            config.Einstellungen.Steuerungsdateien = null;
+            
+            if (config.Einstellungen.BilanzDepartment != null)
+            {
+                
+            }
+        }
+
+        private static GchrConfig NeueInstanz()
+        {
+            return new GchrConfig();
+        }
+    }
+}

+ 16 - 0
Control/IO/KontenIO.cs

@@ -0,0 +1,16 @@
+using GCHR.Model.Konto;
+
+namespace GCHR.Control.IO
+{
+    class KontenIO : ConfigIO
+    {
+        public KontenIO(string datei) : base(datei, typeof(Konten))
+        {
+        }
+
+        public override object Laden()
+        {
+            return DateiLaden() ?? new Konten();
+        }
+    }
+}

+ 34 - 0
Control/Logger.cs

@@ -0,0 +1,34 @@
+using System.IO;
+
+namespace GCHR.Control
+{
+    public class Logger
+    {
+        private const string LogDatei = "logs\\gchr.log";
+        public static string ExportLog = LogDatei;
+
+        public static void Info(string message)
+        {
+            lock(LogDatei)
+            {
+                Log(message, LogDatei);    
+            }
+        }
+
+        public static void Progress(string message)
+        {
+            lock(ExportLog)
+            {
+                Log(message, ExportLog);
+            }
+        }
+
+        private static void Log(string message, string datei)
+        {
+            using (var sw = new StreamWriter(datei, true))
+            {
+                sw.WriteLine(message);
+            }
+        }
+    }
+}

+ 103 - 0
Control/Printing/PageElement.cs

@@ -0,0 +1,103 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using GCHR.Model.Konto;
+
+namespace GCHR.Control.Printing
+{
+    public class PageElement : UserControl
+    {
+        private const int PageMargin = 75;
+        private const int HeaderHeight = 25;
+        private const int LineHeight = 20;
+        private const int ColumnWidth1 = 75;
+        private const int ColumnWidth2 = 350;
+        private const int ColumnWidth3 = 100;
+        private const int ColumnWidth4 = 100;
+
+        private readonly int _currentRow;
+        private readonly int _rows;
+        private readonly List<HaendlerKonto> _konten;
+        private readonly String _aktuellePeriode;
+        private readonly String _altePeriode;
+
+        public PageElement(int currentRow, int rows, List<HaendlerKonto> konten, String aktuellePeriode, String altePeriode)
+        {
+            //Console.WriteLine("Test");
+            Margin = new Thickness(PageMargin);
+            _currentRow = currentRow;
+            _rows = rows;
+            _konten = konten;
+            _aktuellePeriode = aktuellePeriode;
+            _altePeriode = altePeriode;
+        }
+
+        public static int RowsPerPage(double height)
+        {
+            return (int)Math.Floor((height - (2 * PageMargin) - HeaderHeight) / LineHeight);
+        }
+
+        private static FormattedText MakeText(string text, bool rechtsbündig)
+        {
+            if (rechtsbündig)
+                return new FormattedText(text, CultureInfo.CurrentCulture,
+                    FlowDirection.RightToLeft, new Typeface("Tahoma"), 10, Brushes.Black);
+            return new FormattedText(text, CultureInfo.CurrentCulture,
+                                     FlowDirection.LeftToRight, new Typeface("Tahoma"), 10, Brushes.Black);
+        }
+
+        protected override void OnRender(DrawingContext dc)
+        {
+            var curPoint = new Point(0, 0);
+
+            dc.DrawText(MakeText("Kontonummer", false), curPoint);
+            curPoint.X += ColumnWidth1;
+            /*for (int i = 1; i < 4; i++)
+            {
+                dc.DrawText(MakeText("Column " + i), curPoint);
+                curPoint.X += ColumnWidth;
+            }*/
+            dc.DrawText(MakeText("Beschriftung", false), curPoint);
+            curPoint.X += ColumnWidth2;
+            curPoint.X += ColumnWidth3;
+            String temp = "Neuer Wert - " + _aktuellePeriode;
+            dc.DrawText(MakeText(temp, true), curPoint);
+            curPoint.X += ColumnWidth4;
+            temp = "Vormonat - " + _altePeriode;
+            dc.DrawText(MakeText(temp, true), curPoint);
+
+            curPoint.X = 0;
+            curPoint.Y += LineHeight;
+
+            dc.DrawRectangle(Brushes.Black, null, new Rect(curPoint, new Size(Width, 2)));
+            curPoint.Y += HeaderHeight - LineHeight;
+
+            // var numberGen = new Random();
+            for (var i = _currentRow; i < _currentRow + _rows; i++)
+            {
+                HaendlerKonto konto = _konten[i];
+                //Console.WriteLine("Aktuell: " + konto.Kontonummer);
+                //dc.DrawText(MakeText(i.ToString()), curPoint);
+                dc.DrawText(MakeText(konto.Kontonummer, false), curPoint);
+                curPoint.X += ColumnWidth1;
+                dc.DrawText(MakeText(konto.Bezeichnung, false), curPoint);
+                curPoint.X += ColumnWidth2;
+                curPoint.X += ColumnWidth3;
+                dc.DrawText(MakeText(konto.Soll.ToString("0.00"), true), curPoint);
+                curPoint.X += ColumnWidth4;
+                dc.DrawText(MakeText(konto.Haben.ToString("0.00"), true), curPoint);
+                
+                /*for (int j = 1; j < 4; j++)
+                {
+                    dc.DrawText(MakeText(numberGen.Next().ToString()), curPoint);
+                    curPoint.X += ColumnWidth;
+                }*/
+                curPoint.Y += LineHeight;
+                curPoint.X = 0;
+            }
+        }
+    }
+}

+ 68 - 0
Control/Printing/Paginator.cs

@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Windows;
+using System.Windows.Documents;
+using GCHR.Model.Konto;
+
+namespace GCHR.Control.Printing
+{
+    public class RandomTabularPaginator : DocumentPaginator
+    {
+        private int _rowsPerPage;
+        private Size _pageSize;
+        private readonly int _rows;
+        private readonly List<HaendlerKonto> _konten;
+        private readonly String _aktuellePeriode;
+        private readonly String _altePeriode;
+
+        public RandomTabularPaginator(String aktuellePeriode, String altePeriode, List<HaendlerKonto> konten, Size pageSize)
+        {
+            _aktuellePeriode = aktuellePeriode;
+            _altePeriode = altePeriode;
+            _konten = konten;
+            _rows = konten.Count;
+            PageSize = pageSize;
+        }
+
+        public override DocumentPage GetPage(int pageNumber)
+        {
+            var currentRow = _rowsPerPage * pageNumber;
+
+            var page = new PageElement(currentRow, Math.Min(_rowsPerPage, _rows - currentRow), _konten, _aktuellePeriode, _altePeriode)
+            {
+                Width = PageSize.Width,
+                Height = PageSize.Height,
+            };
+
+            page.Measure(PageSize);
+            page.Arrange(new Rect(new Point(0, 0), PageSize));
+
+            return new DocumentPage(page);
+        }
+
+        public override bool IsPageCountValid
+        { get { return true; } }
+
+        public override int PageCount
+        { get { return (int)Math.Ceiling(_rows / (double)_rowsPerPage); } }
+
+        public override sealed Size PageSize
+        {
+            get { return _pageSize; }
+            set
+            {
+                _pageSize = value;
+
+                _rowsPerPage = PageElement.RowsPerPage(PageSize.Height);
+
+                //Can't print anything if you can't fit a row on a page
+                Debug.Assert(_rowsPerPage > 0);
+            }
+        }
+
+        public override IDocumentPaginatorSource Source
+        { get { return null; } }
+    }
+
+}

+ 166 - 0
Control/Tasks/Datenimport.cs

@@ -0,0 +1,166 @@
+using System;
+using System.Collections.Generic;
+using System.Data.Odbc;
+using System.IO;
+using System.Linq;
+using GCHR.Model;
+using GCHR.Model.Konto;
+
+namespace GCHR.Control.Tasks
+{
+    class Datenimport : Task
+    {
+        public static Datenimport DatenimportSuSa(int id, string name)
+        {
+            var datenimport = new Datenimport(id, name) {_kontoTyp = KontoTypen.SuSa};
+            return datenimport;
+        }
+
+        public static Datenimport DatenimportStat(int id, string name)
+        {
+            var datenimport = new Datenimport(id, name) {_kontoTyp = KontoTypen.Stat};
+            return datenimport;
+        }
+
+        private Datenimport(int id, string name)
+            : base(id, name) { }
+
+
+
+        private KontoTypen _kontoTyp;
+        private string QueryStr
+        {
+            get { return (_kontoTyp == KontoTypen.SuSa) ? Config.SuSaKontenQuery : Config.StatKontenQuery; }
+        }
+                
+
+
+        protected override void AufgabeAusfuehren()
+        {
+            var import = Importieren();
+            Data.AddKonten(ImportInKontenUmwandeln(import));
+        }
+
+        private IEnumerable<string> Importieren()
+        {
+            List<string> import;
+            if (Data.Offlinemodus && File.Exists(Dateiname()))
+            {
+                import = File.ReadAllLines(Dateiname()).ToList();
+            }
+            else
+            {
+                import = KontenVonOdbcLaden();
+
+                if (Data.ImportdatenSichern)
+                {
+                    ImportdatenSichern(import);
+                }
+            }
+            return import;
+        }
+
+        private List<string> KontenVonOdbcLaden()
+        {
+            var result = new List<string>();
+            using (var con = new OdbcConnection(Config.OdbcConnectionString))
+            {
+                con.ConnectionTimeout = 300;
+                con.Open();
+                var query = new OdbcCommand(QueryStr, con) {CommandTimeout = 300};
+                var reader = query.ExecuteReader();
+
+                while (reader.Read())
+                {
+                    var zeile = reader.GetString(0).Trim();
+                    for (var i = 1; i < reader.FieldCount; i++)
+                    {
+                        zeile += ";" + reader.GetString(i).Trim();
+                    }
+                    result.Add(zeile);
+                }
+                reader.Close();
+                con.Close();
+            }
+
+            return result;
+        }
+
+        private void ImportdatenSichern(List<string> import)
+        {
+            using (var sw = new StreamWriter(Dateiname(), false, Constants.CsvEncoding))
+            {
+                sw.WriteLine(String.Join(Environment.NewLine, import.ToArray()));
+            }
+        }
+
+        private string Dateiname()
+        {
+            return String.Format(Constants.Importdaten, HaendlerKonto.AktuellePeriode, _kontoTyp);
+        }
+
+
+        private List<HaendlerKonto> ImportInKontenUmwandeln(IEnumerable<string> import)
+        {
+            var konten = (from tempZeile in import
+                                  select tempZeile.Split(';') into feld
+                                  group feld by (feld[0] + ";" + feld[3]) into kontoSaldi
+                                  select NeuesKonto(kontoSaldi.ToList())).ToList();
+
+            if (_kontoTyp == KontoTypen.SuSa)
+            {
+                SummeSaldiPruefen(konten.Sum(konto => konto.Summe));
+            }
+            ReportProgress(80);
+            return konten;
+        }
+
+        private void SummeSaldiPruefen(Decimal summe)
+        {
+            var summeString = String.Format(Constants.Zahlenformat, "{0:c}", summe);
+            Logger.Progress("Summe über alle SuSa-Konten: " + summeString);
+
+            if (summe != 0.0m)
+            {
+                ReportProgress(75, "Beim Import der SuSa-Konten trat ein Fehler auf." + Environment.NewLine +
+                                          "Die Summe über alle SuSa-Konten ist " + summeString + " €");
+            }
+        }
+
+        private HaendlerKonto NeuesKonto(IEnumerable<string[]> kontoSaldi)
+        {
+            var neuesKonto = new HaendlerKonto(_kontoTyp);
+            var feld = kontoSaldi.First();
+
+            neuesKonto.Kontonummer = Config.HaendlerKontonummerFormatieren(feld[0].Trim());
+            neuesKonto.DepartmentImport = feld[3].Trim();
+            Config.DepartmentAnpassen(neuesKonto);
+
+            if (PeriodeMitgeliefert(feld))
+            {
+                foreach (var saldo in kontoSaldi)
+                {
+                    neuesKonto.SaldoZuordnen(saldo[4].Substring(0,6), ToDecimal(saldo[1]), ToDecimal(saldo[2]));
+                }
+            }
+            else
+            {
+                neuesKonto.Soll = (from saldo in kontoSaldi
+                                    select ToDecimal(saldo[1])).Sum();
+                neuesKonto.Haben = (from saldo in kontoSaldi
+                                     select ToDecimal(saldo[2])).Sum();
+            }
+            return neuesKonto;
+        }
+
+        private static Decimal ToDecimal(string feld)
+        {
+            return Decimal.Parse(feld, Constants.ZahlenformatImport);
+        }
+
+        private static bool PeriodeMitgeliefert(IEnumerable<string> feld)
+        {
+            return feld.Count() > 4;
+        }
+    }
+}

+ 142 - 0
Control/Tasks/Export.cs

@@ -0,0 +1,142 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using GCHR.Mandantenschnittstelle;
+using GCHR.Model;
+using GCHR.Model.Konto;
+
+namespace GCHR.Control.Tasks
+{
+    sealed class Export : Task
+    {
+        private readonly Konfiguration _config = Konfiguration.GetInstance();
+
+        private List<HaendlerKonto> _konten;
+        private readonly IMandant _mandant;
+
+        private readonly string _debugExportFile;
+
+        public Export(int id, string name)
+            : base(id, name) 
+        {
+            _mandant = MandantRegistrieren();
+            _debugExportFile = (Data.Exportprotokoll) ? "export\\exportprotokoll.csv" : "";
+        }
+
+        private const String DebugHeader = "KontoExport;Kontonummer;Description;KontoTyp;Ebene1;DepartmentImport;Marke;Betrieb;Case;Soll;Haben;SollSumme;HabenSumme;Gesamt;" +
+                                     "KontoExportHaendler;KontonummerHaendler;DescriptionHaendler;KontoTypHaendler;Ebene1Haendler;DepartmentImportHaendler;MarkeHaendler;BetriebHaendler;CaseHaendler;SollHaendler;HabenHaendler;SollSummeHaendler;HabenSummeHaendler;GesamtHaendler;" +
+                                     "Periode;PeriodeSoll;PeriodeHaben";
+
+
+        private IMandant MandantRegistrieren()
+        {
+            switch (Config.Mandantenname)
+            {
+                case Mandanten.Citroen:
+                    return new Citroen();
+                case Mandanten.Fiat:
+                    return new Fiat();
+                case Mandanten.Ford:
+                    return new Ford();
+                case Mandanten.Honda:
+                    return new Honda();
+                case Mandanten.Opel:
+                    return new Opel();
+                case Mandanten.Peugeot:
+                    return new Peugeot();
+                case Mandanten.Volkswagen:
+                    return new Volkswagen();
+            }
+            return null;
+        }
+
+        /// <summary>
+        /// Wartet auf das Eintreffen der manuellen Konten und startet dann den Export von Balance, Accounts und Debug, 
+        /// falls entsprechende Dateiangaben gesetzt sind.
+        /// </summary>
+        protected override void AufgabeAusfuehren()
+        {
+            ReportProgress(5);
+            _konten = Data.GetKonten();
+            
+            if (_mandant.BalanceDatei)
+            {
+                var balanceStream = DateiStream(_config.BalanceDatei);
+                ReportProgress(20);
+
+                balanceStream.WriteLine(_mandant.BalanceHeader);
+
+                foreach (var kto in _konten.Where(k => (k.Summe != 0.0m)))
+                {
+                    var zeile = _mandant.BalanceBody(kto);
+                    if (zeile.Length > 0)
+                    {
+                        balanceStream.WriteLine(zeile);
+                    }
+                }
+                balanceStream.Write(_mandant.BalanceFooter);
+                balanceStream.Close();
+            }
+
+            ReportProgress(40);
+
+            if (_mandant.AccountsDatei)
+            {
+                var accountsStream = DateiStream(_config.AccountsDatei);
+                ReportProgress(60);
+
+                accountsStream.WriteLine(_mandant.AccountsHeader);
+                foreach (var kto in _konten.Where(k => (k.Summe != 0.0m)))
+                {
+                    accountsStream.WriteLine(_mandant.AccountsBody(kto));
+                }
+                accountsStream.Write(_mandant.AccountsFooter);
+                accountsStream.Close();
+            }
+
+            if (!_debugExportFile.Equals(""))
+            {
+                var debugStream = DateiStream(_debugExportFile);
+                ReportProgress(80);
+
+                var liste = new List<string>();
+                foreach (var kto in _konten)
+                {
+                    liste.AddRange(kto.KontoCsv);
+                }
+                liste.Sort();
+
+                debugStream.WriteLine(DebugHeader);
+                liste.ForEach(debugStream.WriteLine);
+                debugStream.Close();
+            }
+
+            var summeSusa = String.Format("{0:c}", _konten.Sum(k => (k.KontoTyp == KontoTypen.SuSa) ? k.Summe : 0.0m));
+            var summeOhneFaktor = String.Format("{0:c}", _konten.Sum(k => (k.KontoTyp == KontoTypen.SuSa) ? k.Summe : 0.0m));
+            var summeBilanz = String.Format("{0:c}", _konten.Sum(k => (k.Case == "B") ? k.Summe : 0.0m));
+
+            Logger.Progress("Export-Summe über alle SuSa-Konten: " + summeSusa);
+            Logger.Progress("Export-Summe ohne Faktoren: " + summeOhneFaktor);
+            Logger.Progress("Export-Summe über alle Bilanz-Konten: " + summeBilanz);
+
+            var zero = String.Format("{0:c}", 0);
+
+            if (!summeSusa.Equals(zero) && !summeOhneFaktor.Equals(zero))
+            {
+                ReportProgress(80, "Der Export war erfolgreich" + Environment.NewLine +
+                                          "ACHTUNG SuSa Abweichung im Export!" + Environment.NewLine +
+                                          "Export-Summe über alle SuSa-Konten: " + summeSusa);
+            }
+
+            ReportProgress(100);
+        }
+
+        private static StreamWriter DateiStream (string datei)
+        {
+            var info = new FileInfo(datei);
+            info.Directory.Create();
+            return new StreamWriter(info.FullName, false, Constants.CsvEncoding);
+        }
+    }
+}

+ 128 - 0
Control/Tasks/Kontenrahmen.cs

@@ -0,0 +1,128 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using GCHR.Model;
+
+namespace GCHR.Control.Tasks
+{
+    class KontoDoppeltException : ArgumentException
+    {
+        public KontoDoppeltException(String kontonummer)
+            : base(kontonummer) { }
+    }
+
+    class FehlendeBeschriftungException : ArgumentException
+    {
+        public FehlendeBeschriftungException(String kontonummer)
+            : base(kontonummer) { }
+    }
+
+    class FehlenderCaseException : ArgumentException
+    {
+        public FehlenderCaseException(String kontonummer)
+            : base(kontonummer) { }
+    }
+
+    class FehlerhafteZeileException : ArgumentException
+    {
+        public FehlerhafteZeileException(String zeile)
+            : base(zeile) { }
+    }
+
+    class KontenrahmenAlt : Task
+    {
+        public KontenrahmenAlt(int id, string name)
+            : base(id, name) { }
+
+        private readonly Dictionary<String, String[]> _kontenrahmen = new Dictionary<string, string[]>();
+
+        protected override void AufgabeAusfuehren()
+        {
+            Config.DateiVonServerHolen("Kontenrahmen.csv");
+            ReportProgress(40);
+            KontenrahmenAusDateiAbrufen();
+            Data.SetKontenrahmen(_kontenrahmen);
+        }
+
+        private void KontenrahmenAusDateiAbrufen()
+        {
+            #region Fehlerlisten
+            var fehlerlisten = new Dictionary<string, List<string>>
+                                   {
+                                       {"KontoDoppelt", new List<string> {"Im Kontenrahmen doppelt vorhandene Konten"}},
+                                       {"FehlendeBeschriftung", new List<string> {"Konten ohne Beschriftung"}},
+                                       {"FehlenderCase", new List<string> {"Konten ohne Case"}},
+                                       {
+                                           "FehlerhafteZeile",
+                                           new List<string> {"Im Kontenrahmen nicht als Konto erkannte Zeilen"}
+                                           }
+                                   };
+            var statusmeldung = "";
+            #endregion
+
+            var stream = new StreamReader(Constants.KontenrahmenDatei, Constants.CsvEncoding);
+
+            // Kopfzeile ignorieren
+            stream.ReadLine();
+
+            while (!stream.EndOfStream)
+            {
+                try
+                {
+                    ZeileVerarbeiten(stream.ReadLine());
+                }
+                catch (KontoDoppeltException e)
+                {
+                    fehlerlisten["KontoDoppelt"].Add(e.Message);
+                    Logger.Progress("Doppeltes Konto im Kontenrahmen: " + e.Message);
+                }
+                catch (FehlendeBeschriftungException e)
+                {
+                    fehlerlisten["FehlendeBeschriftung"].Add(e.Message);
+                }
+                catch (FehlenderCaseException e)
+                {
+                    fehlerlisten["FehlenderCase"].Add(e.Message);
+                }
+                catch (FehlerhafteZeileException e)
+                {
+                    fehlerlisten["FehlerhafteZeile"].Add(e.Message);
+                }
+            }
+
+            foreach (var fehlerliste in fehlerlisten.Values)
+            {
+                if (fehlerliste.Count <= 1) continue;
+                statusmeldung += string.Format("{0}: {1}{2}", fehlerliste[0], fehlerliste.Count, Environment.NewLine);
+                Logger.Progress(string.Format("{0} ({1}){2}{3}{4}", fehlerliste[0], fehlerliste.Count, Environment.NewLine, String.Join(Environment.NewLine, fehlerliste.ToArray()), Environment.NewLine));
+            }
+            if (statusmeldung != "")
+            {
+                ReportProgress(80, statusmeldung);
+            }
+
+            stream.Close();
+        }
+
+        private void ZeileVerarbeiten(string zeile)
+        {
+            if (zeile.Equals("")) return;
+            var felder = zeile.Split(';');
+
+            if (felder.Count() < 3) throw new FehlerhafteZeileException(zeile);
+
+            var kontoNummer = felder[0].PadLeft(Config.HerstellerKontenrahmenZiffern, '0');
+            if (_kontenrahmen.ContainsKey(kontoNummer)) throw new KontoDoppeltException(kontoNummer);
+
+            var kontoDesc = felder[1].Trim();
+            var kontoCase = felder[2].Trim();
+            var kontoInfo = (felder.Count() > 3) ? felder[3].Trim() : "";
+
+            _kontenrahmen.Add(kontoNummer, new[] { kontoDesc, kontoCase, kontoInfo });
+
+            if (kontoDesc.Equals("")) throw new FehlendeBeschriftungException(kontoNummer);
+            if (kontoCase.Equals("")) throw new FehlenderCaseException(kontoNummer);
+        }
+    }
+}

+ 14 - 0
Control/Tasks/ManuelleKonten.cs

@@ -0,0 +1,14 @@
+namespace GCHR.Control.Tasks
+{
+    class ManuelleKonten : Task
+    {
+        public ManuelleKonten(int id, string name) 
+            : base(id, name) { }
+
+
+        protected override void AufgabeAusfuehren()
+        {
+            ReportProgress(100);
+        }
+    }
+}

+ 144 - 0
Control/Tasks/Task.cs

@@ -0,0 +1,144 @@
+using System;
+using System.Linq;
+using System.ComponentModel;
+using GCHR.Model;
+using GCHR.View;
+
+namespace GCHR.Control.Tasks
+{
+    abstract class Task
+    {
+        protected ThreadXData Data = ThreadXData.GetInstance();
+        protected Konfiguration Config = Konfiguration.GetInstance();
+        
+        public int ID;
+        private readonly string _name;
+        public Ampel Ampel;
+        public BackgroundWorker Worker;
+        private int[] _warteliste;
+        
+        public static Task CreateInstance(int id, string name, RunWorkerCompletedEventHandler completed, int[] waitfor)
+        {
+            var currentTask = GetTask(id, name);
+            currentTask.Worker.RunWorkerCompleted += completed;
+            currentTask.SetWarteliste(waitfor);
+            return currentTask;
+        }
+
+        private static Task GetTask(int id, string name)
+        {
+            switch (name)
+            {
+                case "Kontenrahmen":
+                    return new KontenrahmenAlt(id, name);
+                case "UebersetzungSuSa":
+                    return new UebersetzungSuSa(id, name);
+                case "UebersetzungStat":
+                    return new UebersetzungStat(id, name);
+                case "ManuelleKonten":
+                    return new ManuelleKonten(id, name);
+                case "DatenimportSuSa":
+                    return Datenimport.DatenimportSuSa(id, name);
+                case "DatenimportStat":
+                    return Datenimport.DatenimportStat(id, name);
+                case "Verarbeitung":
+                    return new Verarbeitung(id, name);
+                case "Verrechnung":
+                    return new Verrechnung(id, name);
+                case "Export":
+                    return new Export(id, name);
+                default:
+                    return new DummyTask(id, name);
+            }
+        }
+
+        protected Task(int id, string name)
+        {
+            ID = id;
+            _name = name;
+            Ampel = new Ampel();
+
+            Worker = new BackgroundWorker
+                         {
+                             WorkerReportsProgress = true,
+                             WorkerSupportsCancellation = false
+                         };
+            Worker.DoWork += DoWork;
+        }
+
+        private void DoWork(object sender, DoWorkEventArgs e)
+        {
+            ReportProgress(5);
+            AufgabeAusfuehren();
+            ReportProgress(100);
+        }
+
+        protected abstract void AufgabeAusfuehren();
+
+        public void SetWarteliste(int[] waitfor)
+        {
+            _warteliste = waitfor;
+        }
+
+        public void WartelisteAktualisieren(int aufgabeId)
+        {
+            if (_warteliste == null) return;
+            for (var i = 0; i < _warteliste.Count(); i++)
+            {
+                if (_warteliste[i] == aufgabeId)
+                {
+                    _warteliste[i] = -1;
+                }
+            }
+        }
+
+        public override String ToString()
+        {
+            return _name;
+        }
+
+        public bool TryRun()
+        {
+            if (_warteliste == null)
+                return false;
+
+            for (var i = 0; i < _warteliste.Count(); i++)
+            {
+                if (_warteliste[i] != -1)
+                    return false;
+            }
+
+            _warteliste = null;
+            Worker.RunWorkerAsync();
+            return true;
+        }
+
+        public void RegisterAmpel(Ampel ampel)
+        {
+            Ampel = ampel;
+            Worker.ProgressChanged += (s1, e1) => Ampel.ProgressChanged(e1.ProgressPercentage, e1.UserState);
+            Ampel.Reset();
+        }
+
+        public void ReportProgress(int percentProgress)
+        {
+            Worker.ReportProgress(percentProgress);
+        }
+
+        public void ReportProgress(int percentProgress, object userState)
+        {
+            Worker.ReportProgress(percentProgress, userState);
+        }
+    }
+
+    class DummyTask : Task
+    {
+        public DummyTask(int id, string name) 
+            : base(id, name) { }
+        
+        protected override void AufgabeAusfuehren()
+        {
+            return;
+        }
+    }
+}

+ 109 - 0
Control/Tasks/TaskManager.cs

@@ -0,0 +1,109 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using GCHR.Model;
+using GCHR.Model.Konto;
+using GCHR.View;
+
+namespace GCHR.Control.Tasks
+{
+    class TaskManager
+    {
+        public ThreadXData Data = ThreadXData.CreateInstance();
+        private List<Task> _taskList;
+        private Konfiguration _config;
+
+        public void CreateTasks(RunWorkerCompletedEventHandler completed, Periode periode)
+        {
+            HaendlerKonto.AktuellePeriode = periode;
+            
+            _config = Konfiguration.CreateInstance(Constants.ConfigDatei, Constants.KontenDatei);
+            Data.SetDepartmentCase(CreateDepartmentCaseInstance());
+
+            completed += Ablaufsteuerung;
+
+            _taskList = new List<Task> {
+                            Task.CreateInstance(0, "Kontenrahmen",     completed, new[] { -1 }),
+                            Task.CreateInstance(1, "UebersetzungSuSa", completed, new[] { 0 }),
+                            Task.CreateInstance(2, "UebersetzungStat", completed, new[] { 0 }),
+                            Task.CreateInstance(3, "ManuelleKonten",   completed, new[] { 2 }),
+                            Task.CreateInstance(4, "DatenimportSuSa",  completed, new[] { 1, 2 }),
+                            Task.CreateInstance(5, "DatenimportStat",  completed, new[] { 4 }),
+                            Task.CreateInstance(6, "Verarbeitung",     completed, new[] { 5 }),
+                            Task.CreateInstance(7, "Verrechnung",      completed, new[] { 3 }),
+                            Task.CreateInstance(8, "Export",           completed, new[] { 7 })
+            };
+
+            Logger.ExportLog = _config.LogDatei;
+            Logger.Info(string.Format("Prozess gestartet. Weitere Infos siehe '{0}'", Logger.ExportLog));
+            Logger.Progress(DateTime.Now + " Prozess gestartet.");
+        }
+
+        private void Ablaufsteuerung(object s, RunWorkerCompletedEventArgs e)
+        {
+            var aktuellerWorker = (BackgroundWorker)s;
+            var aktuelleAufgabe = GetAufgabeByWorker(aktuellerWorker);
+
+            if (e.Error == null)
+            {
+                if (aktuelleAufgabe.Ampel != null && aktuelleAufgabe.Ampel.Message.Equals(""))
+                {
+                    aktuelleAufgabe.Ampel.Message = "Die Verarbeitung war erfolgreich.";
+                }
+                SetWorkerCompleted(aktuelleAufgabe.ID);
+                var weitereAufgabe = TryRunNextWorker();
+
+                if (!weitereAufgabe)
+                {
+                    _config.Speichern();
+                }
+            }
+            else
+            {
+                if (aktuelleAufgabe.Ampel != null)
+                {
+                    aktuelleAufgabe.Ampel.Status = Ampelstatus.Rot;
+                    aktuelleAufgabe.Ampel.Message += e.Error.Message;
+                }
+                Logger.Info(e.Error.ToString());
+                Logger.Progress(e.Error.ToString());
+            }
+        }
+
+        public Task GetAufgabeByWorker(BackgroundWorker worker)
+        {
+            var aufgabe = (from a in _taskList
+                           where a.Worker == worker
+                           select a).First();
+
+            return aufgabe;
+        }
+
+        private void SetWorkerCompleted(int aufgabeId)
+        {
+            foreach (var aufgabe in _taskList)
+            {
+                aufgabe.WartelisteAktualisieren(aufgabeId);
+            }
+        }
+
+        public bool TryRunNextWorker()
+        {
+            return (_taskList.Where(aufgabe => aufgabe.TryRun())).Count() > 0;
+        }
+        
+        public void RegisterAmpeln(Ampel[] ampeln)
+        {
+            for (var i = 0; i < Math.Min(ampeln.Count(), _taskList.Count); i++)
+            {
+                _taskList[i].RegisterAmpel(ampeln[i]);
+            }
+        }
+
+        private DepartmentCase CreateDepartmentCaseInstance()
+        {
+            return new DepartmentCase(_config.Hauptmarke, _config.Hauptbetrieb, _config.BilanzMarke, _config.BilanzBetrieb, _config.HerstellerKontenrahmenZiffern);
+        }
+    }
+}

+ 183 - 0
Control/Tasks/Uebersetzung.cs

@@ -0,0 +1,183 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
+using GCHR.Model;
+using GCHR.Model.Konto;
+
+namespace GCHR.Control.Tasks
+{
+    abstract class Uebersetzung : Task
+    {
+        protected Uebersetzung(int id, string name)
+            : base(id, name) { }
+        
+        protected string Dateiname;
+        protected KontoTypen KontoTyp;
+
+        private readonly Dictionary<string, string> _uebersetzungstabelle = new Dictionary<string, string>();
+
+
+        protected override void AufgabeAusfuehren()
+        {
+            UebersetzungstabelleLaden();
+            TabelleUebergeben(_uebersetzungstabelle);
+        }
+
+        protected abstract void TabelleUebergeben(Dictionary<string, string> uebersetzung);
+
+
+        private void UebersetzungstabelleLaden()
+        {
+            var debugFehlerhafteZeile = new List<string>();
+            var debugHerstellerkontoFehlt = new List<string>();
+            var debugNichtImKontenrahmen = new List<string>();
+            var debugDoppeltesHaendlerkonto = new List<string>();
+
+            Config.DateiVonServerHolen(Dateiname);
+
+            var stream = new StreamReader(Constants.DatenexportPfad + Dateiname, Constants.CsvEncoding);
+
+            // Erste Zeile (Überschrift) ignorieren
+            stream.ReadLine();
+
+            while (!stream.EndOfStream)
+            {
+                var zeile = stream.ReadLine();
+                if (zeile == null) continue;
+
+                if (IstUeberschrift(zeile))
+                {
+                    // wird vorerst ignoriert
+                    /*
+                    string ueberschrift = zeile.Split(';').First().Substring(1);
+
+                    Konto konto = new ManStatKonto() { Kontonummer = ueberschrift };
+                    ManuelleKonten.Add(konto);
+                     */
+                }
+                else if (IstSplitKonto(zeile))
+                {
+                    var felder = zeile.Split(';');
+
+                    var herstellerkonto = FehlendeZiffernErgaenzen(felder[0], Config.HerstellerKontenrahmenZiffern);
+                    var herstellerkonto2 = FehlendeZiffernErgaenzen(felder[1], Config.HerstellerKontenrahmenZiffern);
+                    var haendlerkonto = FehlendeZiffernErgaenzen(felder[2], Config.HaendlerKontenrahmenZiffern);
+
+                    if (!_uebersetzungstabelle.ContainsKey(haendlerkonto))
+                    {
+                        _uebersetzungstabelle.Add(haendlerkonto, herstellerkonto + "," + herstellerkonto2);
+                    }
+                    else
+                    {
+                        debugDoppeltesHaendlerkonto.Add(haendlerkonto);
+                    }
+                }
+                else if (IstNormalesKonto(zeile))
+                {
+                    var felder = zeile.Split(';');
+
+                    var herstellerkonto = FehlendeZiffernErgaenzen(felder[0], Config.HerstellerKontenrahmenZiffern);
+                    var haendlerkonto = FehlendeZiffernErgaenzen(felder[2], Config.HaendlerKontenrahmenZiffern);
+
+                    if (!_uebersetzungstabelle.ContainsKey(haendlerkonto))
+                    {
+                        _uebersetzungstabelle.Add(haendlerkonto, herstellerkonto);
+                    }
+                    else
+                    {
+                        debugDoppeltesHaendlerkonto.Add(herstellerkonto);
+                    }
+
+                }
+                else if (IstManuellesKonto(zeile))
+                {
+                    var kontonummer = zeile.Split(';').First().PadLeft(Config.HerstellerKontenrahmenZiffern, '0');
+
+                    if (!ManuellesKonto(kontonummer) && !debugNichtImKontenrahmen.Contains(kontonummer))
+                    {
+                        debugNichtImKontenrahmen.Add(kontonummer);
+                    }
+                }
+                else if (HerstellerkontoFehlt(zeile))
+                {
+                    debugHerstellerkontoFehlt.Add(zeile);
+                }
+                else
+                {
+                    if (!zeile.Equals("ACC_NO_5;DESCRIPTION;ACC_NO_8;x;y") && !zeile.Equals("") && !zeile.Contains("Konto_"))
+                    {
+                        debugFehlerhafteZeile.Add(zeile);
+                    }
+                }
+            }
+
+            stream.Close();
+
+            #region Verarbeitung der Fehlerlisten
+
+            if (debugFehlerhafteZeile.Count > 0)
+            {
+                Logger.Progress(string.Format("Fehlerhafte Zeilen ({0}): {1}{2}{3}", debugFehlerhafteZeile.Count, Environment.NewLine, String.Join(Environment.NewLine, debugFehlerhafteZeile.ToArray()), Environment.NewLine));
+
+                ReportProgress(70, string.Format("Die Übersetzungstabelle enthält {0} fehlerhafte Zeilen.", debugFehlerhafteZeile.Count));
+            }
+
+            if (debugHerstellerkontoFehlt.Count > 0)
+            {
+                Logger.Progress(string.Format("Zeilen ohne Herstellerkonto ({0}): {1}{2}{3}", debugHerstellerkontoFehlt.Count, Environment.NewLine, String.Join(Environment.NewLine, debugHerstellerkontoFehlt.ToArray()), Environment.NewLine));
+
+                ReportProgress(80, string.Format("In {0} Zeilen fehlt das Herstellerkonto.", debugHerstellerkontoFehlt.Count));
+            }
+
+            if (debugNichtImKontenrahmen.Count > 0)
+            {
+                Logger.Progress(string.Format("Fehlende Manuelle Konten im Kontenrahmen ({0}): {1}{2}{3}", debugNichtImKontenrahmen.Count, Environment.NewLine, String.Join(Environment.NewLine, debugNichtImKontenrahmen.ToArray()), Environment.NewLine));
+
+                ReportProgress(90, string.Format("Zu {0} manuellen Konten fehlt der Eintrag im Kontenrahmen.", debugNichtImKontenrahmen.Count));
+            }
+
+            if (debugDoppeltesHaendlerkonto.Count > 0)
+            {
+                Logger.Progress(string.Format("Mehrfach zugeordnete Händlerkonten in der Übersetzungstabelle {0} ({1}): {2}{3}{4}", KontoTyp, debugDoppeltesHaendlerkonto.Count, Environment.NewLine, String.Join(Environment.NewLine, debugDoppeltesHaendlerkonto.ToArray()), Environment.NewLine));
+
+                throw new ArgumentException(string.Format("Abbruch: {0} Händlerkonten sind in der Übersetzungstabelle {1} mehrfach zugeordnet.", debugDoppeltesHaendlerkonto.Count, KontoTyp));
+            }
+            #endregion
+        }
+
+        protected abstract bool ManuellesKonto(string kontonummer);
+
+        private static String FehlendeZiffernErgaenzen(String kontonummer, int ziffern)
+        {
+            return (kontonummer.Length >= ziffern) ? kontonummer : kontonummer.PadLeft(ziffern, '0');
+        }
+
+        private static bool IstSplitKonto(string zeile)
+        {
+            return Regex.IsMatch(zeile, @"^[^;]+;[^;]+;[^;]+");
+        }
+
+        private static bool HerstellerkontoFehlt(string zeile)
+        {
+            return Regex.IsMatch(zeile, @"^;;[^;]+");
+        }
+
+        private static bool IstManuellesKonto(string zeile)
+        {
+            return Regex.IsMatch(zeile, @"^[^;]+;");
+        }
+
+        private static bool IstUeberschrift(string zeile)
+        {
+            return Regex.IsMatch(zeile, @"^[\+]");
+        }
+
+        private static bool IstNormalesKonto(string zeile)
+        {
+            return Regex.IsMatch(zeile, @"^[^;]+;;[^;]+");
+        }
+
+    }
+}

+ 26 - 0
Control/Tasks/UebersetzungStat.cs

@@ -0,0 +1,26 @@
+using System.Collections.Generic;
+using GCHR.Model.Konto;
+
+namespace GCHR.Control.Tasks
+{
+    class UebersetzungStat : Uebersetzung
+    {
+        public UebersetzungStat(int id, string name)
+            : base(id, name)
+        {
+            Dateiname = "uebersetzungstabelle_stat.csv";
+            KontoTyp = KontoTypen.Stat;
+        }
+
+        protected override void TabelleUebergeben(Dictionary<string, string> uebersetzung)
+        {
+            Data.SetUebersetzungStat(uebersetzung);
+        }
+
+        protected override bool ManuellesKonto(string kontonummer)
+        {
+            var konto = Config.ManuellesKontoSuchen(kontonummer);
+            return Data.AddManStatKonto(konto);
+        }
+    }
+}

+ 25 - 0
Control/Tasks/UebersetzungSuSa.cs

@@ -0,0 +1,25 @@
+using System.Collections.Generic;
+using GCHR.Model.Konto;
+
+namespace GCHR.Control.Tasks
+{
+    class UebersetzungSuSa : Uebersetzung
+    {
+        public UebersetzungSuSa(int id, string name)
+            : base(id, name)
+        {
+            Dateiname = "uebersetzungstabelle.csv";
+            KontoTyp = KontoTypen.SuSa;
+        }
+
+        protected override void TabelleUebergeben(Dictionary<string, string> uebersetzung)
+        {
+            Data.SetUebersetzungSuSa(uebersetzung);
+        }
+
+        protected override bool ManuellesKonto(string kontonummer)
+        {
+            return false;
+        }
+    }
+}

+ 138 - 0
Control/Tasks/Verarbeitung.cs

@@ -0,0 +1,138 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Xml.Serialization;
+using GCHR.Model.Konto;
+
+namespace GCHR.Control.Tasks
+{
+    class Verarbeitung : Task
+    {
+        public Verarbeitung(int id, string name)
+            : base(id, name) { }
+
+        protected override void AufgabeAusfuehren()
+        {
+            var konten = Data.GetKonten();
+            // if (Data.ImportdatenSichern) KontenXmlSpeichern(konten);
+            Data.SetKonten(KontenrahmenUebersetzen(konten));
+            KontenXmlSpeichern(_zielKonten.Values.ToList());
+            Data.AufSusaStatWarten.Set();
+        }
+
+        private readonly Dictionary<string, HaendlerKonto> _zielKonten = new Dictionary<string, HaendlerKonto>();
+
+        private readonly Dictionary<string, string> _nichtZugeordnet = new Dictionary<string, string>();
+        private readonly Dictionary<string, string> _nichtImKontenrahmen = new Dictionary<string, string>();
+
+        private readonly HaendlerKonto _debugKontoKontenrahmen = new HaendlerKonto(KontoTypen.Debug) { Kontonummer = "_1", Bezeichnung = "nicht im Kontenrahmen" };
+        private readonly HaendlerKonto _debugKontoUebersetzung = new HaendlerKonto(KontoTypen.Debug) { Kontonummer = "_2", Bezeichnung = "Uebersetzung fehlt" };
+
+
+        private List<HaendlerKonto> KontenrahmenUebersetzen(IEnumerable<HaendlerKonto> kontenimport)
+        {
+            Data.KontoOhneUebersetzungUebernehmen = Config.KontoOhneUebersetzungUebernehmen;
+
+            foreach (var aktKonto in kontenimport)
+            {
+                KontoUebersetzen(aktKonto);
+            }
+
+            ReportNichtZugeordnet();
+            ReportNichtImKontenrahmen();
+
+            return _zielKonten.Values.ToList();
+        }
+
+        private void KontoUebersetzen(HaendlerKonto aktKonto)
+        {
+            var kontonummer = SplitKontoVerarbeiten(Data.KontoUebersetzen(aktKonto), aktKonto.Marke);
+
+            if (kontonummer == null)
+            {
+                if (aktKonto.Summe != 0.0m && !_nichtZugeordnet.ContainsKey(aktKonto.Kontonummer + aktKonto.KontoTyp))
+                {
+                    _nichtZugeordnet.Add(aktKonto.Kontonummer + aktKonto.KontoTyp, DebugInfo(aktKonto));
+                }
+                _debugKontoUebersetzung.KontoZuordnen(aktKonto);
+                return;
+            }
+
+            var ziel = Data.KontoAusKontenrahmen(kontonummer, aktKonto);
+
+            if (ziel == null)
+            {
+                if (aktKonto.Summe != 0.0m && !_nichtImKontenrahmen.ContainsKey(kontonummer))
+                {
+                    _nichtImKontenrahmen.Add(kontonummer, DebugInfo(kontonummer, aktKonto));
+                }
+                _debugKontoKontenrahmen.KontoZuordnen(aktKonto);
+                return;
+            }
+
+            if (!_zielKonten.ContainsKey(ziel.ToString()))
+            {
+                _zielKonten.Add(ziel.ToString(), ziel);
+            }
+            else
+            {
+                ziel = _zielKonten[ziel.ToString()];
+            }
+            ziel.KontoZuordnen(aktKonto);
+            return;
+        }
+
+        private string SplitKontoVerarbeiten(string konto, string marke)
+        {
+            if (konto == null || !konto.Contains(",")) return konto;
+
+            if (marke.Equals(Config.Hauptmarke))
+            {
+                return konto.Split(',')[0];
+            }
+            return konto.Split(',')[1];
+        }
+
+
+
+
+        private void ReportNichtImKontenrahmen()
+        {
+            if (_nichtImKontenrahmen.Count <= 0) return;
+            ReportProgress(60, "Es fehlen " + _nichtImKontenrahmen.Count + " Konten im Kontenrahmen.");
+            Logger.Progress("Fehlende Konten im Kontenrahmen (" + _nichtImKontenrahmen.Count + "): " + Environment.NewLine + String.Join(Environment.NewLine, _nichtImKontenrahmen.Values.ToArray()));
+            _zielKonten.Add(_debugKontoKontenrahmen.Kontonummer, _debugKontoKontenrahmen);
+        }
+
+        private void ReportNichtZugeordnet()
+        {
+            if (_nichtZugeordnet.Count <= 0) return;
+            ReportProgress(50, "Es konnten " + _nichtZugeordnet.Count + " Konten nicht zugeordnet werden." + Environment.NewLine);
+            Logger.Progress("Nicht zugeordnete Konten (" + _nichtZugeordnet.Count + "): " + Environment.NewLine + String.Join(Environment.NewLine, _nichtZugeordnet.Values.ToArray()));
+            _zielKonten.Add(_debugKontoUebersetzung.Kontonummer, _debugKontoUebersetzung);
+        }
+
+        private static string DebugInfo(string kontonummer, HaendlerKonto aktKonto)
+        {
+            return String.Format("{0} (Typ: {1}, Summe: {2}, Anzahl Perioden: {3})",
+                                    kontonummer, aktKonto.KontoTyp, aktKonto.Summe, aktKonto.ZugeordneteSaldi.Count);
+        }
+
+        private static string DebugInfo(HaendlerKonto aktKonto)
+        {
+            return DebugInfo(aktKonto.Kontonummer, aktKonto);
+        }
+
+
+
+        private static void KontenXmlSpeichern(List<HaendlerKonto> konten)
+        {
+            var serializer = new XmlSerializer(typeof(Konten));
+            using (var stream = File.CreateText("logs\\Zuordnung.xml"))
+            {
+                serializer.Serialize(stream, new Konten { Kontenliste = konten });
+            }
+        }
+    }
+}

+ 104 - 0
Control/Tasks/Verrechnung.cs

@@ -0,0 +1,104 @@
+namespace GCHR.Control.Tasks
+{
+    class Verrechnung : Task
+    {
+        public Verrechnung(int id, string name)
+            : base(id, name) { }
+
+
+        protected override void AufgabeAusfuehren()
+        {
+            Data.AufManuelleKontenWarten.WaitOne();
+            var manuelleKonten = Data.GetManuelleKonten();
+
+            #region Verrechnungskonten alte Funktion
+            /*
+            #region Verrechnungskontenvorbereitung
+            Dictionary<string, string> VerrechnungskontenDict = new Dictionary<string, string>();
+
+            var über = from XElement Über in config.ConfigDatei.Element("GCEHRep").Element("Einstellungen").Element("Verrechnungskonten").Elements("Konto")
+                       select new String[] { Über.Attribute("von").Value, Über.Attribute("nach").Value };
+
+            int herstellerkontenrahmenlänge = Int32.Parse(config.ConfigDatei.Element("GCEHRep").Element("Einstellungen").Element("Herstellerkontenrahmen").Value);
+
+            foreach (String[] ü in über)
+            {
+                VerrechnungskontenDict.Add(ü[0].PadLeft(herstellerkontenrahmenlänge, '0'), ü[1].PadLeft(herstellerkontenrahmenlänge, '0'));
+            }
+            #endregion
+            */
+
+
+            /*for (int i = 1; i < lbManuelle.Items.Count; i++)
+            {
+                try
+                {
+                    Grid zeile = (Grid)lbManuelle.Items[i];
+                    Label labelKontonummer = (Label)zeile.Children[0];
+                    String kontonummer = (String)labelKontonummer.Content;
+                    TextBox textWert = (TextBox)zeile.Children[2];
+                    String wert = textWert.Text;
+
+                    Stat_Konto temp = ManuelleKonten.Find(new Predicate<Stat_Konto>(konto => konto.Kontonummer == kontonummer));
+
+                    if (VerrechnungskontenDict.Keys.Contains(temp.Kontonummer))
+                    {
+                        temp.Credit = Double.Parse(wert);
+                        string outValue = "";
+                        if (VerrechnungskontenDict.TryGetValue(temp.Kontonummer, out outValue))
+                        {
+                            SuSa_Konto gefundenesKonto = SuSaKonten.Find(new Predicate<SuSa_Konto>(konto => konto.Kontonummer == outValue));
+
+                            if (gefundenesKonto != null)
+                            {
+                                SuSaKonten.Remove(gefundenesKonto);
+                                gefundenesKonto.Debit = .0;
+                                gefundenesKonto.Credit = gefundenesKonto.Credit + Double.Parse(wert);
+                                SuSaKonten.Add(gefundenesKonto);
+                            }
+                            else
+                            {
+                                SuSa_Konto tempKto = new SuSa_Konto();
+                                tempKto.Kontonummer = outValue;//.PadLeft(config.ConfigDatei.Element("GCEHRep").Element("Einstellungen").Element;
+                                tempKto.Debit = .0;
+                                tempKto.Credit = Double.Parse(wert);
+                                tempKto.Department = "000";
+                                SuSaKonten.Add(tempKto);
+                            }
+                        }
+                    }
+                    else
+                    {
+                        temp.Debit = Double.Parse(wert);
+                    }
+
+                    if (!kontonummer.Substring(0, 1).Equals("+"))
+                    {
+                        try
+                        {
+                            config.ConfigDatei.XPathSelectElement("/GCEHRep/Konten/Konto[@kontonummer='" + kontonummer + "']/periode[@name='" + config.periode + "']").SetAttributeValue("wert", Regex.Replace(String.Format("{0:0.00}", wert), ",", "."));
+                        }
+                        catch (Exception)
+                        {
+                            config.ConfigDatei.XPathSelectElement("/GCEHRep/Konten/Konto[@kontonummer='" + kontonummer + "']").Add(
+                                                    new XElement("periode",
+                                                        new XAttribute("name", config.periode),
+                                                        new XAttribute("wert", Regex.Replace(String.Format("{0:0.00}", wert), ",", "."))));
+                        }
+                    }
+                }
+                catch (ArgumentOutOfRangeException)
+                {
+
+                }
+            }*/
+            #endregion
+
+            Config.ManuelleKontenSetzen(manuelleKonten);
+            Data.AufSusaStatWarten.WaitOne();
+            Data.AddKonten(manuelleKonten);
+
+            ReportProgress(100);
+        }
+    }
+}

+ 184 - 0
Control/ThreadXData.cs

@@ -0,0 +1,184 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using GCHR.Model.Konto;
+
+namespace GCHR.Control
+{
+    public class ThreadXData
+    {
+        #region Singleton
+        private static ThreadXData _instance;
+
+        public static ThreadXData GetInstance()
+        {
+            return _instance ?? (_instance = new ThreadXData());
+        }
+
+        public static ThreadXData CreateInstance()
+        {
+            _instance = new ThreadXData();
+            return _instance;
+        }
+
+        private ThreadXData()
+        {
+        }
+        #endregion
+
+        public AutoResetEvent AufSusaStatWarten = new AutoResetEvent(false);
+        public AutoResetEvent AufManuelleKontenWarten = new AutoResetEvent(false);
+
+        private List<HaendlerKonto> _konten = new List<HaendlerKonto>();
+        private List<HaendlerKonto> _manuelleKonten = new List<HaendlerKonto>();
+
+        private DepartmentCase _departmentCase;
+
+        public bool Offlinemodus;
+        public bool ImportdatenSichern;
+        public bool Exportprotokoll;
+        public bool KeinJahresabschluss;
+        public bool KontoOhneUebersetzungUebernehmen;
+
+        private Dictionary<String, String[]> _kontenrahmen = new Dictionary<string,string[]>();
+        private Dictionary<String, String> _uebersetzungSuSa = new Dictionary<string,string>();
+        private Dictionary<String, String> _uebersetzungStat = new Dictionary<string,string>();
+
+        public List<HaendlerKonto> GetKonten()
+        {
+            lock (_konten)
+            {
+                _konten.Sort((k1, k2) => k1.ToString().CompareTo(k2.ToString()));
+                return _konten;
+            }
+        }
+
+        public void SetKonten(List<HaendlerKonto> konten)
+        {
+            lock (this)
+            {
+                _konten = konten;
+            }
+        }
+
+        public List<HaendlerKonto> GetManuelleKonten()
+        {
+            lock (_manuelleKonten)
+            {
+                return _manuelleKonten;
+            }
+        }
+
+        public void AddKonten(List<HaendlerKonto> konten)
+        {
+            lock (_konten)
+            {
+                _konten.AddRange(konten);
+            }
+        }
+
+        public void SetManuelleKonten(List<HaendlerKonto> konten)
+        {
+            lock (_manuelleKonten)
+            {
+                _manuelleKonten = konten;
+            }
+        }
+
+        public void SetKontenrahmen(Dictionary<string, string[]> kontenrahmen)
+        {
+            lock (_kontenrahmen)
+            {
+                _kontenrahmen = kontenrahmen;
+            }
+        }
+
+        public bool KontenrahmenTryGetValue(string kontonummer, out string[] kontoDescriptionCase)
+        {
+            lock (_kontenrahmen)
+            {
+                return _kontenrahmen.TryGetValue(kontonummer, out kontoDescriptionCase);
+            }
+        }
+
+        public bool AddManStatKonto(HaendlerKonto konto)
+        {
+            lock (_manuelleKonten)
+            {
+                if (!_kontenrahmen.ContainsKey(konto.Kontonummer))
+                {
+                    if (!_kontenrahmen.ContainsKey(konto.ToString())) return false;
+                    konto.Bezeichnung = _kontenrahmen[konto.ToString()][0];
+                    konto.Case = _kontenrahmen[konto.ToString()][1];
+                    konto.Ebene1 = _kontenrahmen[konto.ToString()][2];
+                }
+                else
+                {
+                    konto.Bezeichnung = _kontenrahmen[konto.Kontonummer][0];
+                    konto.Case = _kontenrahmen[konto.Kontonummer][1];
+                    konto.Ebene1 = _kontenrahmen[konto.Kontonummer][2];
+                }
+                _departmentCase.DepartmentUmwandeln(konto);
+                _manuelleKonten.Add(konto);
+                return true;
+            }
+        }
+
+        public string KontoUebersetzen(HaendlerKonto aktKonto)
+        {
+            if (aktKonto.KontoTyp == KontoTypen.SuSa && _uebersetzungSuSa.ContainsKey(aktKonto.Kontonummer))
+            {
+                return _uebersetzungSuSa[aktKonto.Kontonummer];
+            }
+            if (aktKonto.KontoTyp == KontoTypen.Stat && _uebersetzungStat.ContainsKey(aktKonto.Kontonummer))
+            {
+                return _uebersetzungStat[aktKonto.Kontonummer];
+            }
+            if (KontoOhneUebersetzungUebernehmen)
+            {
+                return aktKonto.Kontonummer;
+            }
+            return null;
+        }
+
+        public void SetUebersetzungSuSa(Dictionary<string, string> dictionary)
+        {
+            lock (_uebersetzungSuSa)
+            {
+                _uebersetzungSuSa = dictionary;
+            }
+        }
+
+        public void SetUebersetzungStat(Dictionary<string, string> dictionary)
+        {
+            lock (_uebersetzungStat)
+            {
+                _uebersetzungStat = dictionary;
+            }
+        }
+
+        public void SetDepartmentCase(DepartmentCase departmentCase)
+        {
+            _departmentCase = departmentCase;
+        }
+
+        public HaendlerKonto KontoAusKontenrahmen(string kontonummer, HaendlerKonto child)
+        {
+            if (!_kontenrahmen.ContainsKey(kontonummer))
+                return null;
+
+            var konto = new HaendlerKonto(child.KontoTyp)
+            {
+                Kontonummer = kontonummer,
+                Bezeichnung = _kontenrahmen[kontonummer][0],
+                Case = _kontenrahmen[kontonummer][1],
+                Ebene1 = _kontenrahmen[kontonummer][2],
+                DepartmentImport = child.DepartmentImport,
+                Marke = child.Marke,
+                Betrieb = child.Betrieb
+            };
+            _departmentCase.DepartmentUmwandeln(konto);
+            return konto;
+        }
+    }
+}

+ 330 - 0
GCHR.5.1.ReSharper.user

@@ -0,0 +1,330 @@
+<Configuration>
+  <SettingsComponent>
+    <string />
+    <integer />
+    <boolean>
+      <setting name="SolutionAnalysisEnabled">False</setting>
+    </boolean>
+  </SettingsComponent>
+  <CompletionStatisticsManager>
+    <ItemStatistics item="Default">
+      <Item value="Vormonat1" priority="0" />
+      <Item value="try" priority="0" />
+      <Item value="catch" priority="0" />
+      <Item value="NullReferenceException`0" priority="0" />
+      <Item value="_log" priority="0" />
+      <Item value="String`0" priority="0" />
+      <Item value="private" priority="8" />
+      <Item value="bool" priority="1" />
+      <Item value="return" priority="20" />
+      <Item value="false" priority="1" />
+      <Item value="ImportdatenSichern" priority="0" />
+      <Item value="btnImportdatenSichern" priority="0" />
+      <Item value="btnOffline" priority="0" />
+      <Item value="Offlinemodus" priority="0" />
+      <Item value="Exportprotokoll" priority="0" />
+      <Item value="KeinJahresabschluss" priority="1" />
+      <Item value="Main`0" priority="0" />
+      <Item value="if" priority="9" />
+      <Item value="zeile" priority="0" />
+      <Item value="continue" priority="0" />
+      <Item value="public" priority="9" />
+      <Item value="new" priority="12" />
+      <Item value="DateipfadeXml" priority="0" />
+      <Item value="string" priority="25" />
+      <Item value="File`0" priority="3" />
+      <Item value="Constants`0" priority="5" />
+      <Item value="else" priority="1" />
+      <Item value="Shutdown`0" priority="0" />
+      <Item value="MessageBox`0" priority="0" />
+      <Item value="Environment`0" priority="4" />
+      <Item value="Config" priority="1" />
+      <Item value="DateTime`0" priority="2" />
+      <Item value="kto" priority="6" />
+      <Item value="decimal" priority="2" />
+      <Item value="Periode`0" priority="0" />
+      <Item value="ZugeordneteSaldi" priority="1" />
+      <Item value="s" priority="1" />
+      <Item value="XmlIgnore" priority="0" />
+      <Item value="Soll" priority="0" />
+      <Item value="Haben" priority="0" />
+      <Item value="ZugeordneteKonten" priority="1" />
+      <Item value="k" priority="0" />
+      <Item value="periode" priority="1" />
+      <Item value="Monatssumme`0" priority="0" />
+      <Item value="AktuellePeriode" priority="0" />
+      <Item value="_datei" priority="0" />
+      <Item value="null" priority="2" />
+      <Item value="konto" priority="6" />
+      <Item value="var" priority="10" />
+      <Item value="marke" priority="0" />
+      <Item value="readonly" priority="1" />
+      <Item value="_betriebWildcard" priority="1" />
+      <Item value="_hauptbetrieb" priority="1" />
+      <Item value="_markeWildcard" priority="0" />
+      <Item value="Marke" priority="1" />
+      <Item value="Marke`0" priority="1" />
+      <Item value="_hauptmarke" priority="1" />
+      <Item value="_bilanzBetrieb" priority="1" />
+      <Item value="Betrieb`0" priority="0" />
+      <Item value="bilanzDepartment" priority="0" />
+      <Item value="_bilanzMarke" priority="0" />
+      <Item value="typ" priority="0" />
+      <Item value="Debug" priority="0" />
+      <Item value="Betrieb" priority="0" />
+      <Item value="_markeLength" priority="0" />
+      <Item value="_betriebLength" priority="0" />
+      <Item value="switch" priority="0" />
+      <Item value="KontoTyp" priority="2" />
+      <Item value="case" priority="3" />
+      <Item value="KontoTypen`0" priority="1" />
+      <Item value="sb" priority="3" />
+      <Item value="Faktor" priority="0" />
+      <Item value="char" priority="0" />
+      <Item value="Array`0" priority="0" />
+      <Item value="List" priority="1" />
+      <Item value="liste" priority="4" />
+      <Item value="List&lt;string&gt;" priority="0" />
+      <Item value="config" priority="2" />
+      <Item value="HaendlerKonto`0" priority="0" />
+      <Item value="Kontonummer`0" priority="0" />
+      <Item value="_config" priority="3" />
+      <Item value="_gchrConfig" priority="0" />
+      <Item value="FileInfo`0" priority="0" />
+      <Item value="fileInfo" priority="0" />
+      <Item value="StreamWriter`0" priority="0" />
+      <Item value="info" priority="1" />
+      <Item value="static" priority="1" />
+      <Item value="void" priority="1" />
+      <Item value="LogDatei" priority="2" />
+      <Item value="Log`0" priority="0" />
+      <Item value="message" priority="0" />
+      <Item value="ExportLog" priority="1" />
+      <Item value="Logger`0" priority="6" />
+      <Item value="dateiName" priority="0" />
+      <Item value="datei" priority="0" />
+      <Item value="lock" priority="2" />
+      <Item value="orderby" priority="0" />
+      <Item value="int" priority="1" />
+      <Item value="bilanzMarke" priority="0" />
+      <Item value="bilanzBetrieb" priority="0" />
+      <Item value="_kontoLaenge" priority="1" />
+      <Item value="kontoLaenge" priority="0" />
+      <Item value="dateiInfo" priority="0" />
+      <Item value="btnProtokoll" priority="0" />
+      <Item value="Visibility" priority="0" />
+      <Item value="aktKonto" priority="0" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:log4net.ILog">
+      <Item value="Warn`0" priority="0" />
+      <Item value="Info`0" priority="0" />
+      <Item value="Error`0" priority="0" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:@System.String">
+      <Item value="Format`0" priority="3" />
+      <Item value="Empty" priority="3" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:System.Windows.Controls.CheckBox">
+      <Item value="IsChecked" priority="0" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:@GCHR.Main">
+      <Item value="Log" priority="0" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:System.Collections.Generic.IEnumerable`1">
+      <Item value="Count`1" priority="0" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:@System.IO.File">
+      <Item value="Exists`0" priority="2" />
+      <Item value="Move`0" priority="0" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:@GCHR.Model.Constants">
+      <Item value="ConfigDatei" priority="2" />
+      <Item value="ConfigDateiAlt" priority="1" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:@System.Windows.MessageBox">
+      <Item value="Show`0" priority="0" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:System.String">
+      <Item value="Indexer" priority="0" />
+      <Item value="Equals`0" priority="0" />
+      <Item value="Length" priority="2" />
+      <Item value="Split`0" priority="1" />
+      <Item value="Substring`0" priority="1" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:@System.Environment">
+      <Item value="NewLine" priority="4" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:GCHR.Model.Periode">
+      <Item value="Jahr" priority="0" />
+      <Item value="Jahresbeginn`0" priority="0" />
+      <Item value="Monat" priority="0" />
+      <Item value="ToString`0" priority="2" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:GCHR.Model.Konfiguration">
+      <Item value="Geschaeftsjahr" priority="0" />
+      <Item value="LogDatei" priority="0" />
+      <Item value="BilanzBetrieb" priority="0" />
+      <Item value="HerstellerKontenrahmenZiffern" priority="0" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:@System.DateTime">
+      <Item value="Now" priority="2" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:System.DateTime">
+      <Item value="ToString`0" priority="0" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:GCHR.Model.Konto.HaendlerKonto">
+      <Item value="Bezeichnung" priority="0" />
+      <Item value="Vormonat1" priority="0" />
+      <Item value="Monatssumme`0" priority="0" />
+      <Item value="SummeAktuellePeriode" priority="0" />
+      <Item value="Marke" priority="5" />
+      <Item value="Betrieb" priority="3" />
+      <Item value="Kontonummer" priority="4" />
+      <Item value="Ebene1" priority="0" />
+      <Item value="ToString`0" priority="0" />
+      <Item value="Case" priority="0" />
+      <Item value="Soll" priority="0" />
+      <Item value="SummeOhneFaktor" priority="0" />
+      <Item value="KontoTyp" priority="0" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:System.Collections.Generic.List`1">
+      <Item value="Count" priority="1" />
+      <Item value="Sum`1" priority="1" />
+      <Item value="Add`0" priority="0" />
+      <Item value="ToArray`0" priority="0" />
+      <Item value="AddRange`0" priority="0" />
+      <Item value="Sort`0" priority="0" />
+      <Item value="ForEach`0" priority="0" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:GCHR.Model.Konto.Saldo">
+      <Item value="Periode" priority="0" />
+      <Item value="Soll" priority="0" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:GCHR.Model.GchrConfig">
+      <Item value="Konten" priority="0" />
+      <Item value="Einstellungen" priority="3" />
+      <Item value="Dateipfade" priority="0" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:@GCHR.Model.Konto.KontoTypen">
+      <Item value="SuSa" priority="0" />
+      <Item value="Stat" priority="0" />
+      <Item value="ManStat" priority="0" />
+      <Item value="Debug" priority="0" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:System.Text.StringBuilder">
+      <Item value="AppendLine`0" priority="0" />
+      <Item value="ToString`0" priority="1" />
+      <Item value="Append`0" priority="0" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:@System.Array">
+      <Item value="Sort`1" priority="0" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:GCHR.Model.EinstellungenXml">
+      <Item value="Update" priority="0" />
+      <Item value="Steuerungsdateien" priority="0" />
+      <Item value="BilanzDepartment" priority="0" />
+      <Item value="BalanceDatei" priority="0" />
+      <Item value="LogDatei" priority="0" />
+      <Item value="BilanzMarke" priority="0" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:System.IO.FileInfo">
+      <Item value="Directory" priority="1" />
+      <Item value="Create`0" priority="0" />
+      <Item value="FullName" priority="0" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:System.IO.DirectoryInfo">
+      <Item value="Create`0" priority="0" />
+      <Item value="ToString`0" priority="0" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:@GCHR.Control.Logger">
+      <Item value="Info`0" priority="1" />
+      <Item value="ExportLog" priority="3" />
+      <Item value="Progress`0" priority="1" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:System.Linq.IOrderedEnumerable`1">
+      <Item value="ToList`1" priority="0" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:System.Windows.Controls.Button">
+      <Item value="Visibility" priority="0" />
+    </ItemStatistics>
+    <ItemStatistics item="Qualified:System.Windows.Visibility">
+      <Item value="Visible" priority="0" />
+    </ItemStatistics>
+  </CompletionStatisticsManager>
+  <RecentFiles>
+    <RecentFiles>
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Mandantenschnittstelle/f:Ford.cs" caret="0" fromTop="0" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Mandantenschnittstelle/f:Opel.cs" caret="378" fromTop="18" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:View/f:Ampel.xaml.cs" caret="3277" fromTop="37" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Mandantenschnittstelle/f:Honda.cs" caret="316" fromTop="14" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/f:App.xaml.cs" caret="3926" fromTop="28" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/d:Tasks/f:Kontenrahmen.cs" caret="0" fromTop="0" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Model/f:DateipfadeXml.cs" caret="493" fromTop="12" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/d:Tasks/f:Task.cs" caret="2495" fromTop="30" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/d:IO/f:GchrConfigIO.cs" caret="0" fromTop="0" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Model/f:GchrConfig.cs" caret="2282" fromTop="0" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/d:Tasks/f:UebersetzungStat.cs" caret="645" fromTop="21" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Model/d:Konto/f:KontoTypen.cs" caret="0" fromTop="0" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Model/d:Uebersetzung/f:HerstellerKonto.cs" caret="212" fromTop="10" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:View/f:ManuelleKontenBearbeiten.xaml" caret="1746" fromTop="6" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:View/f:ManuelleKontenBearbeiten.xaml.cs" caret="1205" fromTop="28" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/f:ThreadXData.cs" caret="3840" fromTop="0" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/d:Tasks/f:Uebersetzung.cs" caret="3694" fromTop="36" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Model/f:Constants.cs" caret="802" fromTop="24" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Model/f:CTripleDES.cs" caret="246" fromTop="7" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Model/d:Konto/f:Saldo.cs" caret="0" fromTop="0" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/d:Tasks/f:Datenimport.cs" caret="1748" fromTop="11" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/f:DepartmentCase.cs" caret="3749" fromTop="98" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/f:Logger.cs" caret="170" fromTop="7" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/d:Tasks/f:TaskManager.cs" caret="1739" fromTop="28" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Model/f:Konfiguration.cs" caret="11896" fromTop="35" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/f:Main.xaml.cs" caret="4663" fromTop="40" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/f:Main.xaml" caret="10830" fromTop="6" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Model/d:Konto/f:HaendlerKonto.cs" caret="3939" fromTop="26" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/d:Tasks/f:Export.cs" caret="4889" fromTop="34" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/d:Tasks/f:Verarbeitung.cs" caret="4313" fromTop="20" />
+    </RecentFiles>
+    <RecentEdits>
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/d:Tasks/f:UebersetzungStat.cs" caret="614" fromTop="21" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/f:ThreadXData.cs" caret="3778" fromTop="20" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/f:ThreadXData.cs" caret="3779" fromTop="29" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/f:ThreadXData.cs" caret="3480" fromTop="29" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Model/f:Konfiguration.cs" caret="2809" fromTop="25" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Model/f:Konfiguration.cs" caret="2975" fromTop="33" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Model/f:Konfiguration.cs" caret="3082" fromTop="37" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/d:Tasks/f:TaskManager.cs" caret="4188" fromTop="28" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/f:DepartmentCase.cs" caret="661" fromTop="16" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/f:DepartmentCase.cs" caret="1010" fromTop="27" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/f:DepartmentCase.cs" caret="2457" fromTop="28" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/f:DepartmentCase.cs" caret="2850" fromTop="34" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/f:DepartmentCase.cs" caret="2363" fromTop="26" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Model/d:Uebersetzung/f:HerstellerKonto.cs" caret="33" fromTop="1" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Model/d:Uebersetzung/f:HerstellerKonto.cs" caret="212" fromTop="10" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Model/d:Konto/f:HaendlerKonto.cs" caret="68" fromTop="2" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Model/d:Konto/f:HaendlerKonto.cs" caret="577" fromTop="24" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Model/f:CTripleDES.cs" caret="1537" fromTop="9" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Model/d:Konto/f:HaendlerKonto.cs" caret="3938" fromTop="48" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Model/d:Konto/f:HaendlerKonto.cs" caret="3840" fromTop="46" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/d:Tasks/f:Export.cs" caret="5190" fromTop="36" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/f:Main.xaml.cs" caret="7154" fromTop="50" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/f:Main.xaml.cs" caret="6676" fromTop="50" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/f:Main.xaml.cs" caret="6501" fromTop="48" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/f:Main.xaml.cs" caret="6483" fromTop="44" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/f:Main.xaml.cs" caret="4663" fromTop="40" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/f:Main.xaml" caret="10896" fromTop="7" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/d:Tasks/f:Export.cs" caret="4889" fromTop="34" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/d:Tasks/f:Verarbeitung.cs" caret="2145" fromTop="26" />
+      <File id="1F2176BE-09E4-4D43-87DB-E61E7F4913DF/d:Control/d:Tasks/f:Verarbeitung.cs" caret="4311" fromTop="20" />
+    </RecentEdits>
+  </RecentFiles>
+  <NAntValidationSettings>
+    <NAntPath value="" />
+  </NAntValidationSettings>
+  <UnitTestRunner>
+    <Providers />
+  </UnitTestRunner>
+  <UnitTestRunnerNUnit>
+    <NUnitInstallDir>C:\Program Files (x86)\NUnit 2.5.3\bin\net-2.0\</NUnitInstallDir>
+    <UseAddins>Never</UseAddins>
+  </UnitTestRunnerNUnit>
+</Configuration>

+ 259 - 0
GCHR.csproj

@@ -0,0 +1,259 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.21022</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{1F2176BE-09E4-4D43-87DB-E61E7F4913DF}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>GCHR</RootNamespace>
+    <AssemblyName>GCHR</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <WarningLevel>4</WarningLevel>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <StartupObject>GCHR.App</StartupObject>
+    <ApplicationIcon>GCHR.ico</ApplicationIcon>
+    <NoWin32Manifest>true</NoWin32Manifest>
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>
+    </DocumentationFile>
+    <PlatformTarget>x86</PlatformTarget>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\Debug\GCEHRep_doc.xml</DocumentationFile>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.DataSetExtensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+    <Reference Include="UIAutomationProvider">
+      <RequiredTargetFramework>3.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="WindowsBase">
+      <RequiredTargetFramework>3.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="PresentationCore">
+      <RequiredTargetFramework>3.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="PresentationFramework">
+      <RequiredTargetFramework>3.0</RequiredTargetFramework>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <ApplicationDefinition Include="App.xaml">
+      <SubType>Designer</SubType>
+      <SubType>Designer</SubType>
+    </ApplicationDefinition>
+    <Page Include="View\Ampel.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Page Include="View\Einstellungen.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Page Include="Main.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Page Include="View\ManuelleKontenBearbeiten.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="Themes\Generic.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Compile Include="App.xaml.cs">
+      <DependentUpon>App.xaml</DependentUpon>
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Control\IO\ConfigIO.cs" />
+    <Compile Include="Control\IO\GchrConfigIO.cs" />
+    <Compile Include="Control\IO\KontenIO.cs" />
+    <Compile Include="Control\Logger.cs" />
+    <Compile Include="Main.xaml.cs">
+      <DependentUpon>Main.xaml</DependentUpon>
+      <SubType>Code</SubType>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Control\Tasks\Export.cs" />
+    <Compile Include="Mandantenschnittstelle\Honda.cs" />
+    <Compile Include="Mandantenschnittstelle\IMandant.cs" />
+    <Compile Include="Mandantenschnittstelle\Volkswagen.cs" />
+    <Compile Include="Model\DateipfadeXml.cs" />
+    <Compile Include="Model\Konto\IKonto.cs" />
+    <Compile Include="Model\Konto\KontoTypen.cs" />
+    <Compile Include="Model\Uebersetzung\Eintrag.cs" />
+    <Compile Include="Model\Uebersetzung\Exceptions.cs" />
+    <Compile Include="Model\Uebersetzung\HerstellerKontenrahmen.cs" />
+    <Compile Include="Model\Uebersetzung\HerstellerKonto.cs" />
+    <Compile Include="Model\Uebersetzung\KontoTyp.cs" />
+    <Compile Include="Model\Uebersetzung\Regel.cs" />
+    <Compile Include="Model\Uebersetzung\Uebersetzungstabelle.cs" />
+    <Compile Include="View\Ampel.xaml.cs">
+      <DependentUpon>Ampel.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Model\Constants.cs" />
+    <Compile Include="Model\CTripleDES.cs" />
+    <Compile Include="Control\DepartmentCase.cs" />
+    <Compile Include="View\Einstellungen.xaml.cs">
+      <DependentUpon>Einstellungen.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Model\GchrConfig.cs" />
+    <Compile Include="Control\Tasks\Verrechnung.cs" />
+    <Compile Include="Model\Konfiguration.cs" />
+    <Compile Include="Model\Konto\Konten.cs" />
+    <Compile Include="Model\Konto\Saldo.cs" />
+    <Compile Include="Mandantenschnittstelle\Fiat.cs" />
+    <Compile Include="View\ManuelleKontenBearbeiten.xaml.cs">
+      <DependentUpon>ManuelleKontenBearbeiten.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Model\Periode.cs" />
+    <Compile Include="Control\Tasks\TaskManager.cs" />
+    <None Include="Tests.cs" />
+    <Compile Include="Model\Konto\HaendlerKonto.cs" />
+    <Compile Include="Mandantenschnittstelle\Mandanten.cs" />
+    <Compile Include="Mandantenschnittstelle\Citroen.cs" />
+    <Compile Include="Mandantenschnittstelle\Ford.cs" />
+    <Compile Include="Mandantenschnittstelle\Opel.cs" />
+    <Compile Include="Mandantenschnittstelle\Peugeot.cs" />
+    <Compile Include="Mandantenschnittstelle\Test.cs" />
+    <Compile Include="Control\Printing\PageElement.cs" />
+    <Compile Include="Control\Printing\Paginator.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+    <Compile Include="Control\Tasks\Datenimport.cs" />
+    <Compile Include="Control\Tasks\Kontenrahmen.cs" />
+    <Compile Include="Control\Tasks\ManuelleKonten.cs" />
+    <Compile Include="Control\Tasks\Task.cs" />
+    <Compile Include="Control\Tasks\Uebersetzung.cs" />
+    <Compile Include="Control\Tasks\UebersetzungStat.cs" />
+    <Compile Include="Control\Tasks\UebersetzungSuSa.cs" />
+    <Compile Include="Control\Tasks\Verarbeitung.cs" />
+    <Compile Include="Control\ThreadXData.cs" />
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+    <AppDesigner Include="Properties\" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="GCHR.ico" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="Resources\GlobalCube.png" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <PropertyGroup>
+    <PreBuildEvent>cd $(ProjectDir)
+AssemblyVersion.exe</PreBuildEvent>
+  </PropertyGroup>
+</Project>

+ 18 - 0
GCHR.csproj.user

@@ -0,0 +1,18 @@
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <PublishUrlHistory>publish\</PublishUrlHistory>
+    <InstallUrlHistory>
+    </InstallUrlHistory>
+    <SupportUrlHistory>
+    </SupportUrlHistory>
+    <UpdateUrlHistory>
+    </UpdateUrlHistory>
+    <BootstrapperUrlHistory>
+    </BootstrapperUrlHistory>
+    <ErrorReportUrlHistory>
+    </ErrorReportUrlHistory>
+    <FallbackCulture>de-DE</FallbackCulture>
+    <VerifyUploadedFiles>false</VerifyUploadedFiles>
+    <ProjectView>ProjectFiles</ProjectView>
+  </PropertyGroup>
+</Project>

BIN
GCHR.ico


BIN
GCHR.png


+ 20 - 0
GCHR.sln

@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GCHR", "GCHR.csproj", "{1F2176BE-09E4-4D43-87DB-E61E7F4913DF}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{1F2176BE-09E4-4D43-87DB-E61E7F4913DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{1F2176BE-09E4-4D43-87DB-E61E7F4913DF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{1F2176BE-09E4-4D43-87DB-E61E7F4913DF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{1F2176BE-09E4-4D43-87DB-E61E7F4913DF}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

BIN
GCHR.suo


+ 5 - 0
LocalTestRun.testrunconfig

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TestRunConfiguration name="Lokaler Testlauf" id="44bc5a9f-6f46-45a7-901f-2a9f00f936b4" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2006">
+  <Description>Dies ist eine standardmäßige Testlaufkonfiguration für einen lokalen Testlauf.</Description>
+  <TestTypeSpecific />
+</TestRunConfiguration>

+ 192 - 0
Main.xaml

@@ -0,0 +1,192 @@
+<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="GCHR.Main" xmlns:View="clr-namespace:GCHR.View" xml:lang="de-DE"
+    Title="GCHR - GlobalCube Herstellerreporting" 
+        Height="507" Width="633" 
+        WindowStyle="SingleBorderWindow" SizeToContent="Manual" ResizeMode="CanMinimize" Loaded="WindowLoaded"> <!-- Icon="pack://siteOfOrigin:,,,/img/GCHR.ico">-->
+    
+    <Window.Resources>
+        <Storyboard x:Key="sbGridMainAusblenden">
+            <DoubleAnimation From="1.0" To=".0" Duration="0:0:0.3" Storyboard.TargetName="GridMain" Storyboard.TargetProperty="Opacity" />
+        </Storyboard>
+        
+        <Storyboard x:Key="sbGridMainEinblenden">
+            <DoubleAnimation From=".0" To="1.0" Duration="0:0:0.3" Storyboard.TargetName="GridMain" Storyboard.TargetProperty="Opacity" />
+        </Storyboard>
+        
+        <Storyboard x:Key="sbGridManuelleAusblenden">
+            <DoubleAnimation From="1.0" To=".0" Duration="0:0:0.3" Storyboard.TargetName="GridManuelle" Storyboard.TargetProperty="Opacity" />
+        </Storyboard>
+        
+        <Storyboard x:Key="sbGridManuelleEinblenden">
+            <DoubleAnimation From=".0" To="1.0" Duration="0:0:0.3" Storyboard.TargetName="GridManuelle" Storyboard.TargetProperty="Opacity" />
+        </Storyboard>
+
+        <Storyboard x:Key="sbGridOverlayAusblenden">
+            <DoubleAnimation From="1.0" To=".0" Duration="0:0:0.3" Storyboard.TargetName="GridOverlay" Storyboard.TargetProperty="Opacity" />
+        </Storyboard>
+
+        <Storyboard x:Key="sbGridOverlayEinblenden">
+            <DoubleAnimation From=".0" To="1.0" BeginTime="0:0:0" Duration="0:0:0.3" Storyboard.TargetName="GridOverlay" Storyboard.TargetProperty="Opacity" />
+        </Storyboard>
+    	<Style x:Key="taskLabel" TargetType="{x:Type TextBlock}">
+            <Setter Property="FontSize" Value="12" />
+            <Setter Property="Margin" Value="25,0,0,0" />
+            <Setter Property="Foreground" Value="White" />
+            <Setter Property="VerticalAlignment" Value="Center" />
+        </Style>
+        <Style x:Key="taskHead" TargetType="{x:Type TextBlock}">
+            <Setter Property="FontSize" Value="14" />
+            <Setter Property="FontWeight" Value="Bold" />
+            <Setter Property="Margin" Value="10,0,0,0" />
+            <Setter Property="Foreground" Value="White" />
+            <Setter Property="VerticalAlignment" Value="Center" />
+        </Style>
+    </Window.Resources>
+    
+    <Grid>
+        <Grid Opacity="1.0" Name="GridMain">
+            <Grid.Background>
+                <LinearGradientBrush StartPoint="0,1" EndPoint="0,0">
+                    <GradientStop Color="#FF9EBFDE" Offset=".5"/>
+                    <GradientStop Color="#FF30567A" Offset="1"/>
+                </LinearGradientBrush>
+            </Grid.Background>
+            <Label Height="32" Margin="12,0,0,0" Foreground="White" VerticalAlignment="Top" HorizontalAlignment="Left" FontSize="14" FontWeight="Bold">
+                Periode auswählen
+            </Label>
+            <WrapPanel Margin="12,30,168,2" ClipToBounds="False">
+                <Label Foreground="White">Monat:</Label>
+                <ComboBox Name="monatsbox" Width="100" Margin="0,0,10,0">
+                    <ComboBoxItem>Januar</ComboBoxItem>
+                    <ComboBoxItem>Februar</ComboBoxItem>
+                    <ComboBoxItem>März</ComboBoxItem>
+                    <ComboBoxItem>April</ComboBoxItem>
+                    <ComboBoxItem>Mai</ComboBoxItem>
+                    <ComboBoxItem>Juni</ComboBoxItem>
+                    <ComboBoxItem>Juli</ComboBoxItem>
+                    <ComboBoxItem>August</ComboBoxItem>
+                    <ComboBoxItem>September</ComboBoxItem>
+                    <ComboBoxItem>Oktober</ComboBoxItem>
+                    <ComboBoxItem>November</ComboBoxItem>
+                    <ComboBoxItem>Dezember</ComboBoxItem>
+                </ComboBox>
+                <Label Foreground="White">Jahr:</Label>
+                <ComboBox Name="jahrbox" Width="55" Margin="0,0,15,0" />
+                <Button Template="{DynamicResource GlassButton}" Margin="10,0,0,0" Click="BtnStartenClick" Width="131" Foreground="White" Name="btnStarten">
+                    Prozess starten
+                </Button>
+            </WrapPanel>
+
+            <Border CornerRadius="5" BorderThickness="0.5" BorderBrush="Black" Margin="12,74,192,15.553" Padding="3,3,3,10">
+                <Border.Effect>
+                    <DropShadowEffect Color="Black" />
+                </Border.Effect>
+                <Border.Background>
+                    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
+                        <GradientStop Color="#FF9EBFDE" Offset="-.1"/>
+                        <GradientStop Color="#FF30567A" Offset="1"/>
+                    </LinearGradientBrush>
+                </Border.Background>
+
+                <Grid Background="Transparent" Width="360">
+                    <Grid.ColumnDefinitions>
+                        <ColumnDefinition />
+                        <ColumnDefinition Width="55" />
+                    </Grid.ColumnDefinitions>
+
+                    <Grid.RowDefinitions>
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                    </Grid.RowDefinitions>
+
+                    <TextBlock Style="{StaticResource taskHead}" Grid.ColumnSpan="2">Vorbereitungen</TextBlock>
+
+
+                    <TextBlock Style="{StaticResource taskLabel}" Grid.Row="1">Kontenrahmen laden</TextBlock>
+                    <View:Ampel x:Name="ampel_KontenrahmenLaden" Grid.Row="1" Grid.Column="1" />
+
+                    <TextBlock Style="{StaticResource taskLabel}" Grid.Row="2">Übersetzungstabelle laden</TextBlock>
+                    <View:Ampel x:Name="ampel_ÜbersetzungstabelleLaden" Grid.Row="2" Grid.Column="1" />
+
+                    <TextBlock Style="{StaticResource taskLabel}" Grid.Row="3">Übersetzungstabelle für Statistikkonten laden</TextBlock>
+                    <View:Ampel x:Name="ampel_ÜbersetzungstabelleStatLaden" Grid.Row="3" Grid.Column="1" />
+
+                    <TextBlock Style="{StaticResource taskLabel}" Grid.Row="4" HorizontalAlignment="Left" Width="282">Vormonatswerte für manuelle Konten laden</TextBlock>
+                    <View:Ampel x:Name="ampel_ManuelleLaden" Grid.Row="4" Grid.Column="1" />
+
+                    <TextBlock Style="{StaticResource taskHead}" Grid.Row="5" Grid.ColumnSpan="2">
+                            Verarbeitung der Konten 
+                            <CheckBox Name="btnOffline" Margin="100,0,0,0" Checked="BtnOfflineChecked" Unchecked="BtnOfflineChecked">
+                                <TextBlock FontSize="9" FontWeight="Normal" Foreground="White">Offlinemodus</TextBlock>
+                            </CheckBox>
+                        </TextBlock>
+
+                    <TextBlock Style="{StaticResource taskLabel}" Grid.Row="6">Import der SuSa-Konten</TextBlock>
+                    <View:Ampel x:Name="ampel_SuSaKontenImport" Grid.Row="6" Grid.Column="1" />
+
+                    <TextBlock Style="{StaticResource taskLabel}" Grid.Row="7">
+                            <CheckBox Name="btnKeinJahresabschluss">
+                                <TextBlock Foreground="White">Eröffnungsbilanz berechnen</TextBlock>
+                            </CheckBox>
+                    </TextBlock>
+
+                    <TextBlock Style="{StaticResource taskLabel}" Grid.Row="8">Import der Statistikkonten</TextBlock>
+                    <View:Ampel x:Name="ampel_StatKontenImport"  Grid.Row="8" Grid.Column="1" />
+
+                    <TextBlock Style="{StaticResource taskLabel}" Grid.Row="9">
+                            <CheckBox Name="btnImportdatenSichern" Checked="BtnImportdatenSichernChecked" Unchecked="BtnImportdatenSichernUnchecked">
+                                <TextBlock Foreground="White">Importierte Werte sichern</TextBlock>
+                            </CheckBox>
+                    </TextBlock>
+
+                    <TextBlock Style="{StaticResource taskLabel}" Grid.Row="10">Übersetzung der Konten</TextBlock>
+                    <View:Ampel x:Name="ampel_SuSaKontenVerarbeitung"  Grid.Row="10" Grid.Column="1"/>
+
+                    <TextBlock Style="{StaticResource taskLabel}" Grid.Row="11">Verarbeitung der manuellen Konten</TextBlock>
+                    <View:Ampel x:Name="ampel_ManuelleKontenVerarbeitung"  Grid.Row="11" Grid.Column="1" />
+
+                    <TextBlock Style="{StaticResource taskHead}" Grid.Row="12" Grid.ColumnSpan="2">Ergebnisse exportieren</TextBlock>
+
+                    <TextBlock Style="{StaticResource taskLabel}" Grid.Row="13">Dateien schreiben</TextBlock>
+                    <View:Ampel x:Name="ampel_Export"  Grid.Row="13" Grid.Column="1" />
+
+                    <TextBlock Style="{StaticResource taskLabel}" Grid.Row="14">
+                            <CheckBox Name="btnExportprotokoll">
+                                <TextBlock Foreground="White">Exportprotokoll schreiben</TextBlock>
+                            </CheckBox>
+                    </TextBlock>
+                </Grid>
+            </Border>
+
+            <StackPanel Margin="0,12,12,0" HorizontalAlignment="Right" Name="stack1" Width="210" Height="149.605" VerticalAlignment="Top">
+                <!--<Image Name="imgGlobalCube" Source="pack://siteOfOrigin:,,,/img/GlobalCube.png" />-->
+                <!--
+                <Label Height="50" Name="label1" VerticalAlignment="Top" FontSize="35" FontWeight="Normal" FontFamily="Gill Sans Ultra Bold" HorizontalAlignment="Right" Width="72" HorizontalContentAlignment="Right" VerticalContentAlignment="Top" Foreground="White">GC</Label>
+                <Label Height="23" HorizontalAlignment="Right" Name="label2" FontFamily="Gill Sans Ultra Bold" VerticalAlignment="Top" Width="160" Foreground="White">Herstellerreporting</Label>
+                <Image HorizontalAlignment="Right" Name="image1" Stretch="None" Width="50" /> -->
+            </StackPanel>
+            
+            <StackPanel VerticalAlignment="Bottom" Margin="0,0,5,10" HorizontalAlignment="Right" Width="155">
+                <Button Margin="3" Template="{DynamicResource GlassButton}" Click="BtnManuelleKontenClick" Foreground="White" Height="23" Name="btnManuelleKonten" Visibility="Hidden">Manuelle Konten</Button>
+                <Button Margin="3" Template="{DynamicResource GlassButton}" Click="BtnProtokollClick" Foreground="White" Height="23" Name="btnProtokoll" Visibility="Hidden">Export-Verzeichnis</Button>
+                <Button Margin="3" Template="{DynamicResource GlassButton}" Click="BtnEinstellungenClick" Foreground="White" Height="23" Name="btnEinstellungen">Einstellungen</Button>
+                <Button Margin="3" Template="{DynamicResource GlassButton}" Click="BtnBeendenClick" Foreground="White" Height="23" Name="btnBeenden">Beenden</Button>
+            </StackPanel>
+        </Grid>
+
+ 
+    </Grid>
+</Window>

+ 202 - 0
Main.xaml.cs

@@ -0,0 +1,202 @@
+using System;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.IO;
+using System.Windows;
+using System.Windows.Controls;
+using GCHR.Control;
+using GCHR.Control.Tasks;
+using GCHR.Model;
+using GCHR.View;
+
+namespace GCHR
+{
+    public partial class Main
+    {
+        private TaskManager _aufgabenListe;
+
+        private bool ImportdatenSichern
+        {
+            get { return (btnImportdatenSichern.IsChecked != null) ? (bool) btnImportdatenSichern.IsChecked : false; }
+        }
+
+        private bool Offlinemodus
+        {
+            get { return (btnOffline.IsChecked != null) ? (bool)btnOffline.IsChecked : false; }
+        }
+
+        private bool Exportprotokoll
+        {
+            get { return (btnExportprotokoll.IsChecked != null) ? (bool)btnExportprotokoll.IsChecked : false; }
+        }
+
+        private bool KeinJahresabschluss
+        {
+            get { return (btnKeinJahresabschluss.IsChecked != null) ? (bool)btnKeinJahresabschluss.IsChecked : false; }
+        }
+
+        public Main()
+        {
+            InitializeComponent();
+        }
+
+        private void WindowLoaded(object sender, RoutedEventArgs e)
+        {
+            AktuellenMonatEinstellen();
+            Logger.Info(DateTime.Now + " GCHR gestartet.");
+        }
+
+        private void AktuellenMonatEinstellen()
+        {
+            jahrbox.Items.Clear();
+            for (var i = 2008; i <= DateTime.Today.Year; i++)
+            {
+                jahrbox.Items.Add(i);
+            }
+
+            var jahr = DateTime.Today.Year;
+            var vormonat = DateTime.Today.Month - 1;
+
+            if (vormonat < 1)
+            {
+                vormonat += 12;
+                jahr--;
+            }
+            monatsbox.SelectedIndex = vormonat - 1;
+            jahrbox.SelectedValue = jahr;
+        }
+
+        private void BtnStartenClick(object sender, RoutedEventArgs e)
+        {
+            btnStarten.IsEnabled = false;
+            btnManuelleKonten.Visibility = Visibility.Hidden;
+
+            AufgabenListeErstellen();
+            AmpelnRegistrieren();
+            _aufgabenListe.TryRunNextWorker();
+        }
+
+        private string PeriodeAusAuswahl()
+        {
+            var monat = (monatsbox.SelectedIndex + 1).ToString().PadLeft(2, '0');
+            return jahrbox.Text + monat;
+        }
+
+        private void AufgabenListeErstellen()
+        {
+            _aufgabenListe = new TaskManager
+                                 {
+                                     Data =
+                                         {
+                                             ImportdatenSichern = ImportdatenSichern,
+                                             Offlinemodus = Offlinemodus,
+                                             Exportprotokoll = Exportprotokoll,
+                                             KeinJahresabschluss = KeinJahresabschluss
+                                         }
+                                 };
+            _aufgabenListe.CreateTasks(Ablaufsteuerung, new Periode(PeriodeAusAuswahl(), KeinJahresabschluss));
+        }
+
+        private void AmpelnRegistrieren()
+        {
+            var ampeln = new[]
+                             {
+                                 ampel_KontenrahmenLaden, ampel_ÜbersetzungstabelleLaden,
+                                 ampel_ÜbersetzungstabelleStatLaden,
+                                 ampel_ManuelleLaden, ampel_SuSaKontenImport, ampel_StatKontenImport,
+                                 ampel_SuSaKontenVerarbeitung,
+                                 ampel_ManuelleKontenVerarbeitung, ampel_Export
+                             };
+
+            _aufgabenListe.RegisterAmpeln(ampeln);
+        }
+
+        private void Ablaufsteuerung(object s, RunWorkerCompletedEventArgs e)
+        {
+            var aktuellerWorker = (BackgroundWorker)s;
+            var aktuelleAufgabe = _aufgabenListe.GetAufgabeByWorker(aktuellerWorker);
+
+            if (e.Error != null)
+            {
+                btnStarten.IsEnabled = true;
+            }
+            else
+            {
+                if (aktuelleAufgabe.ID == 3 && ampel_ManuelleLaden.Done)
+                {
+                    var mkb = new ManuelleKontenBearbeiten(_aufgabenListe.Data.GetManuelleKonten());
+                    mkb.Closed += ManuelleKontenBearbeitenClosed;
+                    mkb.Show();
+                }
+
+                if (aktuelleAufgabe.ID == 8)
+                {
+                    btnStarten.IsEnabled = true;
+                    btnProtokoll.Visibility = Visibility.Visible;
+                }
+            }
+        }
+
+        private void ManuelleKontenBearbeitenClosed(object sender, EventArgs e)
+        {
+            var mkb = (ManuelleKontenBearbeiten)sender;
+            _aufgabenListe.Data.SetManuelleKonten(mkb.ManuelleKonten);
+            _aufgabenListe.Data.AufManuelleKontenWarten.Set();                
+        }
+
+        #region Events für Buttons auf der rechten Seite
+
+        private void BtnBeendenClick(object sender, RoutedEventArgs e)
+        {
+            Close();
+        }
+
+        private void BtnEinstellungenClick(object sender, RoutedEventArgs e)
+        {
+            new Einstellungen().ShowDialog();
+        }
+
+
+        private void BtnManuelleKontenClick(object sender, RoutedEventArgs e)
+        {
+            return;
+        }
+
+        #endregion
+
+
+        #region Events für Checkboxen
+
+        private void BtnOfflineChecked(object sender, RoutedEventArgs e)
+        {
+            var chk = sender as CheckBox;
+            btnImportdatenSichern.IsChecked = false;
+            if (chk != null && chk.IsChecked != null) btnImportdatenSichern.IsEnabled = !(bool)chk.IsChecked;
+        }
+
+        private void BtnImportdatenSichernChecked(object sender, RoutedEventArgs e)
+        {
+            btnOffline.IsChecked = false;
+            btnOffline.Visibility = Visibility.Hidden;
+        }
+
+        private void BtnImportdatenSichernUnchecked(object sender, RoutedEventArgs e)
+        {
+            btnOffline.Visibility = Visibility.Visible;
+        }
+
+        #endregion
+
+        private void BtnProtokollClick(object sender, RoutedEventArgs e)
+        {
+            var dateiInfo = new FileInfo(Logger.ExportLog);
+            var psi = new ProcessStartInfo("explorer.exe", dateiInfo.Directory.ToString())
+            {
+                RedirectStandardOutput = true,
+                WindowStyle = ProcessWindowStyle.Normal,
+                UseShellExecute = false
+            };
+            Process.Start(psi);
+        }
+    }
+}

+ 73 - 0
Mandantenschnittstelle/Citroen.cs

@@ -0,0 +1,73 @@
+using System;
+using System.Text.RegularExpressions;
+using GCHR.Model;
+using GCHR.Model.Konto;
+
+namespace GCHR.Mandantenschnittstelle
+{
+    class Citroen : IMandant
+    {
+        private readonly Konfiguration _config = Konfiguration.GetInstance();
+
+        public bool BalanceDatei
+        {
+            get
+            {
+                return true;
+            }
+        }
+
+        public bool AccountsDatei
+        {
+            get
+            {
+                return false;
+            }
+        }
+
+        public string BalanceHeader
+        {
+            get
+            {
+                return String.Format("01{0}{1}{2}{3}", _config.Händlernummer.PadLeft(7, '0'), _config.Eurodatanummer, HaendlerKonto.AktuellePeriode.Monat, HaendlerKonto.AktuellePeriode.JahrZweistellig);
+            }
+        }
+
+        public string BalanceFooter
+        {
+            get
+            {
+                return String.Empty;
+            }
+        }
+
+        public string BalanceBody(HaendlerKonto kto)
+        {
+            return ("02" + kto +
+                        Regex.Replace(String.Format("{0:0.00+;0.00+;0.00+}", kto.Soll), ",", "").PadLeft(13, '0') +
+                        Regex.Replace(String.Format("{0:0.00+;0.00+;0.00+}", kto.Haben), ",", "").PadLeft(13, '0') +
+                        "000000000000+" + "000000000000+");
+        }
+
+        public string AccountsHeader
+        {
+            get
+            {
+                return String.Empty;
+            }
+        }
+
+        public string AccountsFooter
+        {
+            get
+            {
+                return String.Empty;
+            }
+        }
+
+        public string AccountsBody(HaendlerKonto kto)
+        {
+            return String.Empty;
+        }
+    }
+}

+ 72 - 0
Mandantenschnittstelle/Fiat.cs

@@ -0,0 +1,72 @@
+using System;
+using GCHR.Model;
+using GCHR.Model.Konto;
+
+namespace GCHR.Mandantenschnittstelle
+{
+    /**
+     * <summary>Im Vergleich zu Opel wird bei Fiat im BalanceHeader das "M" weggelassen und die Salden mit Komma getrennt.</summary>
+     */
+    class Fiat : IMandant
+    {
+        private readonly Konfiguration _config = Konfiguration.GetInstance();
+
+        public bool BalanceDatei
+        {
+            get
+            {
+                return true;
+            }
+        }
+
+        public bool AccountsDatei
+        {
+            get
+            {
+                return true;
+            }
+        }
+
+        public string BalanceHeader
+        {
+            get
+            {
+                return String.Format("AA{0} {1}{2} ,20EUR", _config.Händlernummer, HaendlerKonto.AktuellePeriode.Monat, HaendlerKonto.AktuellePeriode.JahrZweistellig);
+            }
+        }
+
+        public string BalanceFooter
+        {
+            get
+            {
+                return String.Format("XX{0} {1}{2}", _config.Händlernummer, HaendlerKonto.AktuellePeriode.Monat, HaendlerKonto.AktuellePeriode.JahrZweistellig);
+            }
+        }
+
+        public string BalanceBody(HaendlerKonto kto)
+        {
+            return (kto + String.Format("{0,30:0.00}", (kto.Summe)));
+        }
+
+        public string AccountsHeader
+        {
+            get
+            {
+                return "Account Code".PadRight(42, ' ') + "Description";
+            }
+        }
+
+        public string AccountsFooter
+        {
+            get
+            {
+                return String.Empty;
+            }
+        }
+
+        public string AccountsBody(HaendlerKonto kto)
+        {
+            return (kto.ToString().PadRight(42, ' ') + kto.Bezeichnung);
+        }
+    }
+}

+ 7 - 0
Mandantenschnittstelle/Ford.cs

@@ -0,0 +1,7 @@
+
+namespace GCHR.Mandantenschnittstelle
+{
+    class Ford : Opel
+    {
+    }
+}

+ 83 - 0
Mandantenschnittstelle/Honda.cs

@@ -0,0 +1,83 @@
+using System;
+using GCHR.Model;
+using GCHR.Model.Konto;
+
+namespace GCHR.Mandantenschnittstelle
+{
+    class Honda : IMandant
+    {
+        protected Konfiguration Config = Konfiguration.GetInstance();
+
+        public bool BalanceDatei
+        {
+            get
+            {
+                return true;
+            }
+        }
+
+        public bool AccountsDatei
+        {
+            get
+            {
+                return false;
+            }
+        }
+
+        public string BalanceHeader
+        {
+            get
+            {
+                return
+                    string.Format(
+                        "{1};Dealernumber{0};Honda Germany{0}{2};Evaluation;{3}{0}{4};Fiscal-Year;{5}{0};Timestamp;{6}",
+                        Environment.NewLine, Config.Händlernummer, HaendlerKonto.AktuellePeriode.Jahr,
+                        HaendlerKonto.AktuellePeriode.Monat,
+                        HaendlerKonto.AktuellePeriode.Jahresbeginn(Config.Geschaeftsjahr).Jahr,
+                        HaendlerKonto.AktuellePeriode.Jahresbeginn(Config.Geschaeftsjahr).Monat,
+                        DateTime.Now.ToString("MMddyyyy;HHmmss"));
+            }
+        }
+
+        public string BalanceFooter
+        {
+            get
+            {
+                return string.Empty;
+            }
+
+        }
+
+        public string BalanceBody(HaendlerKonto kto)
+        {
+            return (string.Format("{0};{1};{2};{3}", Kontonummer(kto), kto.Bezeichnung, kto.SummeAktuellePeriode, kto.Summe).Replace(',', '.'));
+        }
+
+        private static string Kontonummer(HaendlerKonto kto)
+        {
+            return kto.Kontonummer.Substring(0, 4) + kto.Marke + kto.Betrieb + kto.Kontonummer.Substring(4);
+        }
+
+        public string AccountsHeader
+        {
+            get
+            {
+                return string.Empty;
+            }
+        }
+
+        public string AccountsFooter
+        {
+            get
+            {
+                return string.Empty;
+            }
+
+        }
+
+        public string AccountsBody(HaendlerKonto kto)
+        {
+            return string.Empty;
+        }
+    }
+}

+ 42 - 0
Mandantenschnittstelle/IMandant.cs

@@ -0,0 +1,42 @@
+using GCHR.Model.Konto;
+
+namespace GCHR.Mandantenschnittstelle
+{
+    interface IMandant
+    {
+        /// <summary>
+        /// Zieldatei für Balance-Werte, standardmäßig 'export\export_MM-JJJJ_balance.txt'
+        /// </summary>
+        bool BalanceDatei { get; }
+        /// <summary>
+        /// Kopfzeile von BalanceDatei
+        /// </summary>
+        string BalanceHeader { get; }
+        /// <summary>
+        /// Zeilenformatierung von BalanceDatei
+        /// </summary>
+        string BalanceBody(HaendlerKonto kto);
+        /// <summary>
+        /// Fußzeile von BalanceDatei
+        /// </summary>
+        string BalanceFooter { get; }
+
+
+        /// <summary>
+        /// Zieldatei für den Kontenrahmen, standardmäßig 'export\export_MM-JJJJ_accounts.txt'
+        /// </summary>
+        bool AccountsDatei { get; }
+        /// <summary>
+        /// Kopfzeile von AccountsDatei
+        /// </summary>
+        string AccountsHeader { get; }
+        /// <summary>
+        /// Zeilenformatierung von AccountsDatei
+        /// </summary>
+        string AccountsBody(HaendlerKonto kto);
+        /// <summary>
+        /// Fußzeile von AccountsDatei
+        /// </summary>
+        string AccountsFooter { get; }
+    }
+}

+ 4 - 0
Mandantenschnittstelle/Mandanten.cs

@@ -0,0 +1,4 @@
+namespace GCHR.Mandantenschnittstelle
+{
+    public enum Mandanten { Citroen, Fiat, Ford, Honda, Opel, Peugeot, Volkswagen };
+}

+ 72 - 0
Mandantenschnittstelle/Opel.cs

@@ -0,0 +1,72 @@
+using System;
+using GCHR.Model;
+using GCHR.Model.Konto;
+
+namespace GCHR.Mandantenschnittstelle
+{
+    class Opel : IMandant
+    {
+        protected Konfiguration Config = Konfiguration.GetInstance();
+
+        public bool BalanceDatei
+        {
+            get
+            {
+                return true;
+            }
+        }
+
+        public bool AccountsDatei
+        {
+            get
+            {
+                return true;
+            }
+        }
+
+        public string BalanceHeader
+        {
+            get
+            {
+                return String.Format("AA{0}M{1}{2} .20EUR", Config.Händlernummer, HaendlerKonto.AktuellePeriode.Monat, HaendlerKonto.AktuellePeriode.JahrZweistellig);
+            }
+        }
+
+        public string BalanceFooter
+        {
+            get
+            {
+                return String.Format("XX{0}M{1}{2}", Config.Händlernummer, HaendlerKonto.AktuellePeriode.Monat, HaendlerKonto.AktuellePeriode.JahrZweistellig);
+            }
+
+        }
+
+        public string BalanceBody(HaendlerKonto kto)
+        {
+            return (kto + String.Format("{0,30:0.00}", (kto.Summe)).Replace(',', '.'));
+        }
+
+
+        public string AccountsHeader
+        {
+            get
+            {
+                return "Account Code".PadRight(42, ' ') + "Description";
+            }
+        }
+
+        public string AccountsFooter
+        {
+            get
+            {
+                return String.Empty;
+            }
+
+        }
+
+        public string AccountsBody(HaendlerKonto kto)
+        {
+            return (kto.ToString().PadRight(42, ' ') + kto.Bezeichnung);
+        }
+    }
+}

+ 73 - 0
Mandantenschnittstelle/Peugeot.cs

@@ -0,0 +1,73 @@
+using System;
+using System.Text.RegularExpressions;
+using GCHR.Model;
+using GCHR.Model.Konto;
+
+namespace GCHR.Mandantenschnittstelle
+{
+    class Peugeot : IMandant
+    {
+        private readonly Konfiguration _config = Konfiguration.GetInstance();
+
+        public bool BalanceDatei
+        {
+            get
+            {
+                return true;
+            }
+        }
+
+        public bool AccountsDatei
+        {
+            get
+            {
+                return false;
+            }
+        }
+
+        public string BalanceHeader
+        {
+            get
+            {
+                return String.Format("01{0}{1}{2}{3}", _config.Händlernummer.PadLeft(7, '0'), _config.Eurodatanummer, HaendlerKonto.AktuellePeriode.Monat, HaendlerKonto.AktuellePeriode.JahrZweistellig);
+            }
+        }
+
+        public string BalanceFooter
+        {
+            get
+            {
+                return String.Empty;
+            }
+        }
+
+        public string BalanceBody(HaendlerKonto kto)
+        {
+            return ("02" + kto +
+                            Regex.Replace(String.Format("{0:0.00+;0.00+;0.00+}", kto.Soll), ",", "").PadLeft(13, '0') +
+                            Regex.Replace(String.Format("{0:0.00+;0.00+;0.00+}", kto.Haben), ",", "").PadLeft(13, '0') +
+                            "000000000000+" + "000000000000+");
+        }
+
+        public string AccountsHeader
+        {
+            get
+            {
+                return String.Empty;
+            }
+        }
+
+        public string AccountsFooter
+        {
+            get
+            {
+                return String.Empty;
+            }
+        }
+
+        public string AccountsBody(HaendlerKonto kto)
+        {
+            return String.Empty;
+        }
+    }
+}

+ 66 - 0
Mandantenschnittstelle/Test.cs

@@ -0,0 +1,66 @@
+using System;
+using GCHR.Model.Konto;
+
+namespace GCHR.Mandantenschnittstelle
+{
+    class Test : IMandant
+    {
+        public bool BalanceDatei
+        {
+            get
+            {
+                return true;
+            }
+        }
+
+        public bool AccountsDatei
+        {
+            get
+            {
+                return true;
+            }
+        }
+
+        public string BalanceHeader
+        {
+            get 
+            { 
+                return String.Empty;
+            }
+        }
+
+        public string BalanceFooter
+        {
+            get
+            {
+                return String.Empty;
+            }
+        }
+
+        public string BalanceBody(HaendlerKonto kto)
+        {
+            return String.Empty;
+        }
+
+        public string AccountsHeader
+        {
+            get
+            {
+                return String.Empty;
+            }
+        }
+
+        public string AccountsFooter
+        {
+            get
+            {
+                return String.Empty;
+            }
+        }
+
+        public string AccountsBody(HaendlerKonto kto)
+        {
+            return String.Empty;
+        }
+    }
+}

+ 187 - 0
Mandantenschnittstelle/Volkswagen.cs

@@ -0,0 +1,187 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Xml.Linq;
+using GCHR.Model;
+using GCHR.Model.Konto;
+
+namespace GCHR.Mandantenschnittstelle
+{
+    class Volkswagen : IMandant
+    {
+        /// <summary>
+        /// V = Volkswagen,
+        /// A = Audi,
+        /// S = Seat,
+        /// C = Skoda,
+        /// E = Bentley,
+        /// L = Lamborghini
+        /// </summary>
+        enum Hauptmarke { V, A, S, C, E, L };
+
+        /// <summary>
+        /// 1 = Istdaten,
+        /// 2 = Plandaten
+        /// </summary>
+        private const string Level = "1";
+
+        private const string Country = "DEU";
+
+        private const string Currency = "EUR";
+
+        private static readonly XNamespace Tns = "http://xmldefs.volkswagenag.com/Retail/AccountBalanceDTS/V1";
+        private static XNamespace _tns1 = "http://xmldefs.volkswagenag.com/DD/BasicTypes";
+        private static XNamespace _xsi = "http://www.w3.org/2001/XMLSchema-instance";
+
+        private XDocument _xmlDocument;
+        private readonly XElement _accounts = new XElement(Tns + "Accounts");
+
+        private readonly Konfiguration _config = Konfiguration.GetInstance();
+
+        public bool BalanceDatei
+        {
+            get
+            {
+                return true;
+            }
+        }
+
+        public bool AccountsDatei
+        {
+            get { return false; }
+        }
+
+        public string BalanceHeader
+        {
+            get
+            {
+                _xmlDocument = new XDocument();
+                _xmlDocument.Add(new XElement(Tns + "ShowAccountBalance",
+                                    new XAttribute(XNamespace.Xmlns + "tns", Tns),
+                                    // new XAttribute(XNamespace.Xmlns + "tns1", tns1),
+                                    // new XAttribute(XNamespace.Xmlns + "xsi", xsi),
+                                    // new XAttribute(xsi + "schemaLocation", "http://xmldefs.volkswagenag.com/Retail/AccountBalanceDTS/V1 AccountBalanceDTS.xsd"),
+                                    new XElement(Tns + "PartnerKey",
+                                        new XElement(Tns + "Country", Country),
+                                        new XElement(Tns + "Brand", Hauptmarke.V),
+                                        new XElement(Tns + "PartnerNumber", _config.Händlernummer)
+                                    ),
+                                    new XElement(Tns + "IsCumulative", "true"),
+                                    new XElement(Tns + "AccountingDate",
+                                        new XElement(Tns + "AccountingMonth", HaendlerKonto.AktuellePeriode.Monat),
+                                        new XElement(Tns + "AccountingYear", HaendlerKonto.AktuellePeriode.Jahr)
+                                    ),
+                                    new XElement(Tns + "Currency", Currency),
+                                    new XElement(Tns + "Level", Level),
+                                    _accounts
+                                ));
+
+                return "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
+                /*
+                return String.Format("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + Environment.NewLine +
+                          "<tns:ShowAccountBalance" + Environment.NewLine +
+                          "    xmlns:tns=\"http://xmldefs.volkswagenag.com/Retail/AccountBalanceDTS/V1\" " + Environment.NewLine +
+                          "    xmlns:tns1=\"http://xmldefs.volkswagenag.com/DD/BasicTypes\" " + Environment.NewLine +
+                          "    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " + Environment.NewLine +
+                          "    xsi:schemaLocation=\"http://xmldefs.volkswagenag.com/Retail/AccountBalanceDTS/V1 AccountBalanceDTS.xsd\">" + Environment.NewLine +
+                          "    <tns:PartnerKey>" + Environment.NewLine +
+                          "        <tns:Country>{0}</tns:Country>" + Environment.NewLine +
+                          "        <tns:Brand>{1}</tns:Brand>" + Environment.NewLine +
+                          "        <tns:PartnerNumber>{2}</tns:PartnerNumber>" + Environment.NewLine +
+                          "    </tns:PartnerKey>" + Environment.NewLine +
+                          "    <tns:IsCumulative>true</tns:IsCumulative>" + Environment.NewLine +
+                          "    <tns:AccountingDate>" + Environment.NewLine +
+                          "        <tns:AccountingMonth>{3}</tns:AccountingMonth>" + Environment.NewLine +
+                          "        <tns:AccountingYear>{4}</tns:AccountingYear>" + Environment.NewLine +
+                          "    </tns:AccountingDate>" + Environment.NewLine +
+                          "    <tns:Currency>{5}</tns:Currency>" + Environment.NewLine +
+                          "    <tns:Level>{6}</tns:Level>" + Environment.NewLine +
+                          "    <tns:Accounts>",
+
+                              country, Hauptmarke.V, config.Händlernummer, Konto.aktuellePeriode.Monat, Konto.aktuellePeriode.Jahr, currency, level);
+                 */
+            }
+        }
+
+        public string BalanceFooter
+        {
+            get 
+            {
+                return _xmlDocument.ToString();    
+            }
+        }
+
+        public string BalanceBody(HaendlerKonto kto)
+        {
+            _accounts.Add(new XElement(Tns + "Account",
+                         new XElement(Tns + "ProfitCenter", "00"),
+                         new XElement(Tns + "AccountKey", 
+                              AccountKey(kto)
+                              // accountAttributes(kto)
+                         ),
+                         new XElement(Tns + "AccountValue", AccountValue(kto))
+            ));
+            return String.Empty;
+        }
+
+        private string AccountKey(HaendlerKonto kto)
+        {
+            return String.Join("", AccountKeyDict(kto).Values.ToArray());
+        }
+
+        private object[] AccountAttributes(HaendlerKonto kto)
+        {
+            return (from attrib in AccountKeyDict(kto)
+                    select new XAttribute(attrib.Key, attrib.Value)).ToArray();
+        }
+
+        private static Dictionary<string, string> AccountKeyDict(HaendlerKonto kto)
+        {
+            var marke = kto.Marke.PadRight(6, '?');
+            var kontonummer = kto.Kontonummer.PadRight(10, '?');
+
+            var dict = new Dictionary<string, string>();
+            dict.Add("Brand", marke.Substring(0,2));
+            dict.Add("ModelCode", marke.Substring(2));
+            dict.Add("Account", kontonummer.Substring(0,4));
+            dict.Add("CostCentre", kontonummer.Substring(4, 2));
+            dict.Add("TradeChannel", kontonummer.Substring(6, 2));
+            dict.Add("CostUnit", kontonummer.Substring(8, 2));
+            dict.Add("Location", kto.Betrieb);
+            dict.Add("TaxCode", "000");
+            return dict;
+        }
+
+        private static string AccountValue(HaendlerKonto kto)
+        {
+            /*
+            if (kto.KontoTyp == KontoTypen.SuSa)
+            {
+                return String.Format("{0:-0.00;+0.00;+0.00}", kto.Summe).Replace(',', '.');
+            }*/
+            return String.Format("{0:+0.00;-0.00;+0.00}", kto.Summe).Replace(',', '.');
+        }
+
+
+        public string AccountsHeader
+        {
+            get
+            {
+                return String.Empty;
+            }
+        }
+
+        public string AccountsFooter
+        {
+            get
+            {
+                return String.Empty;
+            }
+        }
+
+        public string AccountsBody(HaendlerKonto kto)
+        {
+            return String.Empty;
+        }
+    }
+}

+ 86 - 0
Model/CTripleDES.cs

@@ -0,0 +1,86 @@
+using System;
+using System.IO;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace GCHR.Model
+{
+    class CTripleDes
+    {
+        // define the triple des provider
+
+        private readonly TripleDESCryptoServiceProvider _des =
+                 new TripleDESCryptoServiceProvider();
+
+        // define the string handler
+
+        private readonly UTF8Encoding _utf8 = new UTF8Encoding();
+
+        // define the local property arrays
+
+        private readonly byte[] _key;
+        private readonly byte[] _iv;
+
+        public CTripleDes(byte[] key, byte[] iv)
+        {
+            _key = key;
+            _iv = iv;
+        }
+
+        public byte[] Encrypt(byte[] input)
+        {
+            return Transform(input,
+                   _des.CreateEncryptor(_key, _iv));
+        }
+
+        public byte[] Decrypt(byte[] input)
+        {
+            return Transform(input,
+                   _des.CreateDecryptor(_key, _iv));
+        }
+
+        public string Encrypt(string text)
+        {
+            var input = _utf8.GetBytes(text);
+            var output = Transform(input,
+                            _des.CreateEncryptor(_key, _iv));
+            return Convert.ToBase64String(output);
+        }
+
+        public string Decrypt(string text)
+        {
+            var input = Convert.FromBase64String(text);
+            var output = Transform(input,
+                            _des.CreateDecryptor(_key, _iv));
+            var des = _des.CreateDecryptor(_key, _iv);
+            return _utf8.GetString(output);
+        }
+
+        private static byte[] Transform(byte[] input,
+                       ICryptoTransform cryptoTransform)
+        {
+            // create the necessary streams
+
+            var memStream = new MemoryStream();
+            var cryptStream = new CryptoStream(memStream,
+                         cryptoTransform, CryptoStreamMode.Write);
+            // transform the bytes as requested
+
+            cryptStream.Write(input, 0, input.Length);
+            cryptStream.FlushFinalBlock();
+            // Read the memory stream and
+
+            // convert it back into byte array
+
+            memStream.Position = 0;
+            var result = memStream.ToArray();
+            // close and release the streams
+
+            memStream.Close();
+            cryptStream.Close();
+            // hand back the encrypted buffer
+
+            return result;
+        }
+    }
+}

+ 73 - 0
Model/Constants.cs

@@ -0,0 +1,73 @@
+using System;
+using System.Globalization;
+using System.Text;
+
+namespace GCHR.Model
+{
+    internal static class Constants
+    {
+        public static string Vormonat(string periode)
+        {
+            var jahr = Int32.Parse(periode.Substring(0, 4));
+            var monat = Int32.Parse(periode.Substring(4, 2));
+
+            monat--;
+            if (monat == 0)
+            {
+                monat = 12;
+                jahr--;
+            }
+            return jahr + monat.ToString().PadLeft(2, '0');
+        }
+
+        private static byte[] key = {76, 123, 122, 84, 45, 12, 44, 78, 56, 43, 47, 6, 
+              2, 13, 23, 23, 45, 255, 65, 20, 33, 5, 235, 66};
+        private static readonly byte[] iv = { 56, 254, 98, 123, 66, 4, 90, 34, 111, 34, 78, 33, 222, 80, 74, 35 };
+
+        internal static string Encrypt(string toenc)
+        {
+            var des = new CTripleDes(key, iv);
+            return des.Encrypt(toenc);
+        }
+
+        internal static string Decrypt(string todec)
+        {
+            var des = new CTripleDes(key, iv);
+            return des.Decrypt(todec);
+        }
+
+        public static Encoding CsvEncoding = Encoding.Default;
+
+        public static string Importdaten = "data\\import\\import_{0}_{1}.txt";
+
+        public const string ConfigDatei = "config\\gchr.xml";
+        public const string ConfigDateiAlt = "config\\config.xml";
+
+        public const string KontenDatei = "data\\ManuelleKonten.xml";
+
+        public const string KontenrahmenDatei = "data\\Kontenrahmen.csv";
+        public const string DatenexportPfad = "data\\";
+
+        public const string DepartmentFilter = "'01','1'";
+
+        public static NumberFormatInfo Zahlenformat = CultureInfo.GetCultureInfo("de-DE").NumberFormat;
+        public static NumberFormatInfo ZahlenformatImport = CultureInfo.GetCultureInfo("en-US").NumberFormat;
+    }
+
+    public enum Ampelstatus
+    {
+        Keine = -1,
+        Arbeitend = 0,
+        Gruen = 1,
+        Gelb = 2,
+        Rot = 3
+    }
+
+    public class Status
+    {
+        public Ampelstatus Ampelstatus;
+        public string Message;
+    }
+
+
+}

+ 15 - 0
Model/DateipfadeXml.cs

@@ -0,0 +1,15 @@
+namespace GCHR.Model
+{
+    public class DateipfadeXml
+    {
+        public string ConfigPfad = "config\\";
+        public string DataPfad = "data\\";
+
+        public string ImportPfad = "data\\import\\";
+        public string ExportPfad = "export\\";
+
+        public string BalanceDatei = "export\\{0}\\export_{0}-{1}_balance.txt";
+        public string AccountsDatei = "export\\{0}\\export_{0}-{1}_accounts.txt";
+        public string LogDatei = "export\\{0}\\export_{0}-{1}.log";
+    }
+}

+ 154 - 0
Model/GchrConfig.cs

@@ -0,0 +1,154 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Xml.Schema;
+using System.Xml.Serialization;
+using GCHR.Mandantenschnittstelle;
+using GCHR.Model.Konto;
+
+namespace GCHR.Model
+{
+    [XmlRoot("GCEHRep")]
+    public class GchrConfig
+    {
+        [XmlAttribute(AttributeName = "noNamespaceSchemaLocation", Namespace = XmlSchema.InstanceNamespace)]
+        public string NoNamespaceSchemaLocation = "http://dev.global-cube.de/gchr.xsd";
+
+        public static GchrConfig GetInstance(String cfgDatei)
+        {
+            var serializer = new XmlSerializer(typeof(GchrConfig));
+            using (var stream = File.OpenText(cfgDatei))
+            {
+                var gcsConfig = (GchrConfig)serializer.Deserialize(stream);
+                gcsConfig._configDatei = cfgDatei;
+                return gcsConfig;
+            }
+        }
+
+        private string _configDatei;
+
+        public void Save()
+        {
+            var serializer = new XmlSerializer(typeof(GchrConfig));
+            using (var stream = File.CreateText(_configDatei))
+            {
+                serializer.Serialize(stream, this);
+            }
+        }
+
+        public DateipfadeXml Dateipfade = new DateipfadeXml();
+
+        [XmlElement("Einstellungen")]
+        public EinstellungenXml Einstellungen = new EinstellungenXml();
+
+        [XmlArray("Konten")]
+        [XmlArrayItem("Konto")]
+        public List<HaendlerKonto> Konten;
+    }
+
+    [XmlRoot("Einstellungen")]
+    public class EinstellungenXml
+    {
+        public Mandanten Mandantenname;
+        public string Eurodatanummer;
+
+        [XmlElement("Händlernummer")]
+        public string Haendlernummer;
+
+        [XmlElement("Herstellerkontenrahmen", DataType = "int")]
+        public int Herstellerkontenrahmen;
+
+        [XmlElement("Händlerkontenrahmen", DataType = "int")]
+        public int Haendlerkontenrahmen;
+
+        public string Marke = "Department,3,1";
+        public string Betrieb = "Department,1,2";
+
+        public string Hauptmarke;
+        public string Hauptbetrieb;
+
+        public string BilanzDepartment;
+        public string BilanzMarke = "0";
+        public string BilanzBetrieb = "07";
+
+        public string BilanzKontoart = "1";
+
+        [XmlElement("Geschäftsjahr")]
+        public string Geschaeftsjahr = "01";
+
+        [XmlElement("ODBC")]
+        public string Odbc;
+
+        [XmlElement("U")]
+        public string OdbcUsername;
+
+        [XmlElement("P")]
+        public string OdbcPassword;
+
+        public AbfragenXml Abfragen;
+        
+        [XmlArray("DepartmentÜbersetzung")]
+        [XmlArrayItem("Über")]
+        public List<UebersetzungXml> DepartmentUebersetzung = new List<UebersetzungXml>();
+
+        public bool KontoOhneUebersetzungUebernehmen;
+
+        public UpdateXml Update;
+        public SteuerungsdateienXml Steuerungsdateien;
+        public string Verrechnungskonten;
+    }
+
+    [XmlRoot("Update")]
+    public class UpdateXml
+    {
+        [XmlAttribute("aktiviert", DataType = "boolean")]
+        public bool IsActive;
+        
+        [XmlElement("Dateipfad")]
+        public string Dateipfad;
+
+        [XmlElement("Proxy")]
+        public ProxyXml Proxy = new ProxyXml();
+    }
+
+    [XmlRoot("Proxy")]
+    public class ProxyXml
+    {
+        public string Adresse;
+        public string Port;
+        public string Benutzer;
+        public string Passwort;
+        [XmlElement("Domäne")]
+        public string Domaene;
+    }
+
+    [XmlRoot("Steuerungsdateien")]
+    public class SteuerungsdateienXml
+    {
+        public string Typ = "verzeichnis";
+        public string Pfad = "";
+    }
+
+    [XmlRoot("Abfragen")]
+    public class AbfragenXml
+    {
+        [XmlElement("AB")]
+        public string SuSaKontenQuery;
+
+        [XmlElement("ABS")]
+        public string StatKontenQuery;
+
+        [XmlArray("DepartmentFilter")]
+        [XmlArrayItem("Department")]
+        public List<String> DepartmentFilter = new List<String>();
+    }
+
+    [XmlRoot("Über")]
+    public class UebersetzungXml
+    {
+        [XmlAttribute("von")]
+        public string Von;
+        [XmlAttribute("nach")]
+        public string Nach;
+    }
+}

+ 357 - 0
Model/Konfiguration.cs

@@ -0,0 +1,357 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Text.RegularExpressions;
+using System.Windows;
+using GCHR.Control;
+using GCHR.Control.IO;
+using GCHR.Mandantenschnittstelle;
+using GCHR.Model.Konto;
+
+namespace GCHR.Model
+{
+    public class Konfiguration
+    {
+        #region Singleton
+
+        private static Konfiguration _instance;
+
+        public static Konfiguration CreateInstance(string cfgDatei, string kontenDatei)
+        {
+            return _instance ?? (_instance = new Konfiguration(cfgDatei, kontenDatei));
+        }
+
+        public static Konfiguration GetInstance()
+        {
+            if (_instance == null)
+            {
+                throw new NullReferenceException("Konfiguration nicht initialisiert!");
+            }
+            return _instance;
+        }
+
+        #endregion
+
+        private readonly GchrConfig _gchrConfig;
+        private readonly Konten _konten;
+        private readonly string _configDatei;
+        private readonly string _kontenDatei;
+
+        public Konfiguration(string cfgDatei, string kontenDatei)
+        {
+            _configDatei = cfgDatei;
+            _gchrConfig = (GchrConfig)new GchrConfigIO(_configDatei).Laden();
+
+            _kontenDatei = kontenDatei;
+            _konten = (Konten) new KontenIO(_kontenDatei).Laden();
+            KontenXmlUmsortieren();
+        }
+
+        private void KontenXmlUmsortieren()
+        {
+            if (_konten.Kontenliste.Count > 0 || _gchrConfig.Konten == null || _gchrConfig.Konten.Count == 0) return;
+
+            foreach (var kto in _gchrConfig.Konten)
+            {
+                if (kto.Periode != null && kto.Periode.Count == 0) kto.Periode = null;
+
+                if (kto.Periode == null) continue;
+                kto.ZugeordneteSaldi = kto.Periode;
+                kto.Periode = null;
+            }
+            _konten.Kontenliste = _gchrConfig.Konten;
+            _gchrConfig.Konten = null;
+            Speichern();
+        }
+
+        public void Speichern()
+        {
+            new KontenIO(_kontenDatei).Speichern(_konten);
+            new GchrConfigIO(_configDatei).Speichern(_gchrConfig);
+        }
+
+
+        public string Händlernummer
+        {
+            get
+            {
+                return _gchrConfig.Einstellungen.Haendlernummer;
+            }
+        }
+        public string Hauptmarke
+        {
+            get
+            {
+                return _gchrConfig.Einstellungen.Hauptmarke;
+            }
+        }
+        public string Hauptbetrieb
+        {
+            get
+            {
+                return _gchrConfig.Einstellungen.Hauptbetrieb;
+            }
+        }
+
+        public string BilanzMarke
+        {
+            get
+            {
+                return _gchrConfig.Einstellungen.BilanzMarke;
+            }
+        }
+
+        public string BilanzBetrieb
+        {
+            get
+            {
+                return _gchrConfig.Einstellungen.BilanzBetrieb;
+            }
+        }
+
+        public string Eurodatanummer
+        {
+            get
+            {
+                if (_gchrConfig.Einstellungen.Eurodatanummer == null)
+                {
+                    _gchrConfig.Einstellungen.Eurodatanummer = "00000000";
+                    Logger.Info("Eurodatanummer wurde bisher noch nicht festgelegt. Bitte in config.xml anpassen!");
+                }
+                return _gchrConfig.Einstellungen.Eurodatanummer.PadLeft(8, '0');
+            }
+        }
+        public string Geschaeftsjahr
+        {
+            get
+            {
+                return _gchrConfig.Einstellungen.Geschaeftsjahr;
+            }
+        }
+        public int HerstellerKontenrahmenZiffern
+        {
+            get
+            {
+                return _gchrConfig.Einstellungen.Herstellerkontenrahmen;
+
+            }
+        }
+        public int HaendlerKontenrahmenZiffern
+        {
+            get
+            {
+                return _gchrConfig.Einstellungen.Haendlerkontenrahmen;
+            }
+        }
+        public string SuSaKontenQuery
+        {
+            get
+            {
+                return QueryAnpassen(Constants.Decrypt(_gchrConfig.Einstellungen.Abfragen.SuSaKontenQuery));
+            }
+        }
+        public string StatKontenQuery
+        {
+            get
+            {
+                return QueryAnpassen(Constants.Decrypt(_gchrConfig.Einstellungen.Abfragen.StatKontenQuery));
+            }
+        }
+
+        public Mandanten Mandantenname
+        {
+            get
+            {
+                return _gchrConfig.Einstellungen.Mandantenname;
+            }
+        }
+
+        public bool KontoOhneUebersetzungUebernehmen 
+        {
+            get
+            {
+                return _gchrConfig.Einstellungen.KontoOhneUebersetzungUebernehmen;
+            }
+        }
+
+        private String DepartmentFilter
+        {
+            get
+            {
+                if (_gchrConfig.Einstellungen.Abfragen.DepartmentFilter.Count == 0) return "'?'";
+                return string.Format("'{0}'", String.Join("','", _gchrConfig.Einstellungen.Abfragen.DepartmentFilter.ToArray()));
+            }
+        }
+
+        public void DateiVonServerHolen(string dateiName)
+        {
+            try
+            {
+                return;
+                var dateiTyp = _gchrConfig.Einstellungen.Steuerungsdateien.Typ;
+                var dateiPfad = _gchrConfig.Einstellungen.Steuerungsdateien.Pfad;
+
+                if (dateiPfad.Equals("")) return;
+
+                if (!dateiPfad.EndsWith("/"))
+                {
+                    dateiPfad += "/";
+                }
+
+                if (dateiTyp.Equals("http"))
+                {
+                    var web = new WebClient();
+                    web.DownloadFile(dateiPfad + dateiName, "data\\" + dateiName);
+                }
+                else if (dateiTyp.Equals("verzeichnis"))
+                {
+                    File.Copy(dateiPfad + dateiName, "data\\" + dateiName);
+                }
+            }
+            catch (Exception e)
+            {
+                var message = string.Format("Beim Laden der Datei '{0}' ist ein Fehler aufgetreten.", dateiName);
+                MessageBox.Show(message, "Fehler");
+                Logger.Info(message);
+                Logger.Info(e.Message);
+            }
+        }
+
+        public string JuengstenVormonatBestimmen(string aktPeriode)
+        {
+            return Array.Find(VorhandenePerioden(), eintrag => String.Compare(eintrag, aktPeriode) < 0) ?? aktPeriode;
+        }
+
+        private string[] VorhandenePerioden()
+        {
+            var vorhandenePerioden = (from HaendlerKonto konto in _konten.Kontenliste
+                                      select konto.ZugeordneteSaldi
+                                      into perioden
+                                      from Saldo p in perioden
+                                      select p.Periode).Distinct().ToArray();
+
+            Array.Sort(vorhandenePerioden);
+            Array.Reverse(vorhandenePerioden);
+            return vorhandenePerioden;
+        }
+
+        public string OdbcConnectionString
+        {
+            get
+            {
+                return
+                    (string.Format("DSN={0};UID={1};PWD={2};", _gchrConfig.Einstellungen.Odbc,
+                                   Constants.Decrypt(_gchrConfig.Einstellungen.OdbcUsername),
+                                   Constants.Decrypt(_gchrConfig.Einstellungen.OdbcPassword)));
+            }
+        }
+
+        private string MarkeUebersetzen(string marke)
+        {
+            var suchergebnis = _gchrConfig.Einstellungen.DepartmentUebersetzung.Where(eintrag => eintrag.Von.Equals(marke));
+
+            if (suchergebnis.Count() < 1) return marke;
+            var uebersetzung = suchergebnis.First();
+            return uebersetzung.Nach;
+        }
+
+        private string BetriebUebersetzen(string betrieb)
+        {
+            // Funktionen sind derzeit noch identisch
+            return MarkeUebersetzen(betrieb);
+        }
+
+        public void DepartmentAnpassen(HaendlerKonto konto)
+        {
+            konto.Betrieb = BetriebUebersetzen(BetriebNormalisieren(BetriebExtrahieren(konto.DepartmentImport)));
+            konto.Marke = MarkeUebersetzen(MarkeNormalisieren(MarkeExtrahieren(konto.DepartmentImport)));
+        }
+
+        private string BetriebNormalisieren(string betrieb)
+        {
+            return (betrieb.Length > Hauptbetrieb.Length)
+                       ? betrieb.Substring(0, Hauptbetrieb.Length)
+                       : betrieb.PadLeft(Hauptbetrieb.Length, '0');
+        }
+
+        private string MarkeNormalisieren(string marke)
+        {
+            return (marke.Length > Hauptmarke.Length)
+                       ? marke.Substring(0, Hauptmarke.Length)
+                       : marke.PadLeft(Hauptmarke.Length, '0');
+        }
+
+        private string BetriebExtrahieren(string department)
+        {
+            return (department.Length >= Hauptbetrieb.Length) 
+                       ? department.Substring(0, Hauptbetrieb.Length) 
+                       : department;
+        }
+
+        private string MarkeExtrahieren(string department)
+        {
+            return (department.Length > Hauptbetrieb.Length) 
+                       ? department.Substring(Hauptbetrieb.Length) 
+                       : "";
+        }
+
+        private string QueryAnpassen(string queryStr)
+        {
+            queryStr = Regex.Replace(queryStr, @"\<datenbank\>", "");
+
+            queryStr = Regex.Replace(queryStr, @"\<period[e]?\>", HaendlerKonto.AktuellePeriode.ToString());
+            queryStr = Regex.Replace(queryStr, @"\<jahresbeginn\>", HaendlerKonto.AktuellePeriode.Jahresbeginn(Geschaeftsjahr).ToString());
+            queryStr = Regex.Replace(queryStr, @"\<bilanzbeginn\>", HaendlerKonto.AktuellePeriode.Bilanzbeginn(Geschaeftsjahr).ToString());
+
+            return Regex.Replace(queryStr, @"\<department_filter\>", DepartmentFilter);
+        }
+
+        internal string HaendlerKontonummerFormatieren(string kontonummer)
+        {
+            return kontonummer.PadLeft(HaendlerKontenrahmenZiffern, '0');
+        }
+
+        public HaendlerKonto ManuellesKontoSuchen(string kontonummer)
+        {
+            var konten = (from HaendlerKonto kto in _konten.Kontenliste
+                          where (kto.Kontonummer.Equals(kontonummer)
+                                 || kto.ToString().Equals(kontonummer))
+                          select kto).ToList();
+            return (konten.Count > 0) ? konten.First() : HaendlerKonto.ManStatNeu(kontonummer);
+        }
+
+        public void ManuelleKontenSetzen(List<HaendlerKonto> manKonten)
+        {
+            _konten.Kontenliste = manKonten;
+        }
+
+        public string BalanceDatei
+        {
+            get
+            {
+                return string.Format(_gchrConfig.Dateipfade.BalanceDatei, HaendlerKonto.AktuellePeriode.Jahr, HaendlerKonto.AktuellePeriode.Monat);
+            }
+        }
+
+        public string AccountsDatei
+        {
+            get
+            {
+                return string.Format(_gchrConfig.Dateipfade.AccountsDatei, HaendlerKonto.AktuellePeriode.Jahr, HaendlerKonto.AktuellePeriode.Monat);
+            }
+        }
+
+        public string LogDatei
+        {
+            get
+            {
+                var datei = string.Format(_gchrConfig.Dateipfade.LogDatei, HaendlerKonto.AktuellePeriode.Jahr, HaendlerKonto.AktuellePeriode.Monat);
+                var info = new FileInfo(datei);
+                info.Directory.Create();
+                return datei;
+            }
+        }
+    }
+}

+ 294 - 0
Model/Konto/HaendlerKonto.cs

@@ -0,0 +1,294 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Xml.Serialization;
+
+namespace GCHR.Model.Konto
+{
+    [XmlRoot("Konto")]
+    public class HaendlerKonto : IKonto
+    {
+        internal static Periode AktuellePeriode = new Periode("200001");
+
+        private static int _markeLength = 1;
+        private static int _betriebLength = 2;
+
+
+        public HaendlerKonto()
+            : this(KontoTypen.ManStat)
+        {
+        }
+
+        public HaendlerKonto(KontoTypen typ)
+        {
+            KontoTyp = typ;
+            if (typ != KontoTypen.Debug) return;
+            Marke = new string('0', _markeLength);
+            Betrieb = new string('0', _betriebLength);
+        }
+
+        public static HaendlerKonto ManStatNeu(string kontonummer)
+        {
+            var kto = new HaendlerKonto(KontoTypen.ManStat) {DepartmentImport = "000", Kontonummer = kontonummer};
+            return kto;
+        }
+
+        #region KontoXml-Umwandlung
+
+        [XmlAttribute("kontonummer")]
+        public string KontonummerAlt
+        {
+            set { Kontonummer = value; }
+            get { return null; }
+        }
+
+        [XmlElement("periode")]
+        public List<Saldo> Periode;
+
+        #endregion
+
+
+        [XmlAttribute("Konto_Nr")]
+        public string Kontonummer { get; set; }
+
+        [XmlAttribute("Konto_Bezeichnung")]
+        public string Bezeichnung { get; set; }
+
+        [XmlAttribute("Konto_Typ")]
+        public KontoTypen KontoTyp { get; set; }
+
+        [XmlIgnore]
+        public string DepartmentImport { get; set; }
+
+        [XmlAttribute("Konto_Marke")]
+        public string Marke { get; set; }
+
+        [XmlAttribute("Konto_Betrieb")]
+        public string Betrieb { get; set; }
+
+        [XmlAttribute("Ebene1")]
+        public string Ebene1 { get; set; }
+
+        [XmlAttribute("Konto_Case")]
+        public string Case { get; set; }
+
+        [XmlIgnore]
+        public decimal Faktor { get { return (Case != null && Case.Contains("-")) ? -1m : 1m; } }
+
+        [XmlAttribute("Soll")]
+        public decimal Soll 
+        {
+            get
+            {
+                return (KontoTyp == KontoTypen.ManStat)
+                           ? SaldoVon(AktuellePeriode.ToString())
+                           : Math.Round(
+                               Faktor*
+                               (_soll + ZugeordneteKonten.Sum(kto => kto.Soll) +
+                                ZugeordneteSaldi.Sum(saldo => saldo.Soll)), 2);
+            }
+            set
+            {
+                _soll = value;
+            }
+        }
+        private decimal _soll;
+
+        [XmlAttribute("Haben")]
+        public decimal Haben
+        {
+            get
+            {
+                return (KontoTyp == KontoTypen.ManStat)
+                           ? 0m
+                           : Math.Round(
+                               Faktor*
+                               (_haben + ZugeordneteKonten.Sum(kto => kto.Haben) +
+                                ZugeordneteSaldi.Sum(saldo => saldo.Haben)), 2);
+            }
+            set
+            {
+                _haben = value;
+            }
+        }
+        private decimal _haben;
+
+        [XmlIgnore]
+        public decimal Summe
+        {
+            get
+            {
+                if (KontoTyp == KontoTypen.Debug) return 0m;
+                return Soll + Haben;
+            }
+        }
+
+        [XmlIgnore]
+        public decimal SummeOhneFaktor
+        {
+            get
+            {
+                return (KontoTyp == KontoTypen.ManStat)
+                           ? 0m
+                           : Math.Round(
+                               (_soll + _haben) + ZugeordneteKonten.Sum(kto => (kto.SummeOhneFaktor)) +
+                               ZugeordneteSaldi.Sum(saldo => (saldo.Soll + saldo.Haben)), 2);
+            }
+        }
+
+        public override string ToString()
+        {
+            return Marke + Betrieb + Kontonummer;
+        }
+
+
+        [XmlElement("Konto")]
+        public List<HaendlerKonto> ZugeordneteKonten = new List<HaendlerKonto>();
+
+        public bool KontoZuordnen(HaendlerKonto kto)
+        {
+            if (KontoTyp != KontoTypen.Debug && KontoTyp != kto.KontoTyp) return false;
+            ZugeordneteKonten.Add(kto);
+            ZugeordneteKonten.Sort((k1, k2) => k1.Kontonummer.CompareTo(k2.Kontonummer));
+            return true;
+        }
+
+        [XmlElement("Saldo")]
+        public List<Saldo> ZugeordneteSaldi = new List<Saldo>();
+
+        public void SaldoZuordnen(string periode, Decimal soll, Decimal haben)
+        {
+            ZugeordneteSaldi.Add(new Saldo { Periode = periode, Soll = soll, Haben = haben });
+            ZugeordneteSaldi.Sort((s1, s2) => s1.Periode.CompareTo(s2.Periode));
+        }
+
+        [XmlIgnore]
+        public List<string> KontoCsv
+        {
+            get
+            {
+                if (ZugeordneteKonten.Count > 0)
+                {
+                    var liste = new List<string>();
+                    var csv = Kontonummer + ";" +
+                              Marke + ";" +
+                              Betrieb;
+
+                    foreach (var kto in ZugeordneteKonten)
+                    {
+                        liste.Add(kto.KontoCsv[0] + ";" + csv);
+                    }
+                    return liste;
+                }
+
+                return new List<string>
+                           {
+                               Kontonummer + ";" +
+                               KontoTypKuerzel(KontoTyp) + Minus + ";" +
+                               Marke + ";" +
+                               Betrieb
+                           };
+            }
+        }
+
+        private string Minus { get { return (Faktor < 0) ? "-" : ""; } }
+
+        private string KontoTypKuerzel(KontoTypen kontoTyp)
+        {
+            switch(kontoTyp)
+            {
+                case KontoTypen.SuSa:
+                    return "A";
+                case KontoTypen.Stat:
+                    return "Q";
+                case KontoTypen.ManStat:
+                    return "M";
+                case KontoTypen.Debug:
+                    return "D";
+            }
+            return "?";
+        }
+
+        public string DebugInfo()
+        {
+            return String.Format("{0} (Typ: {1}, Summe: {2}, Anzahl Perioden: {3})",
+                                    Kontonummer, KontoTyp, Summe, ZugeordneteSaldi.Count);
+        }
+
+        private decimal SaldoVon(string periode)
+        {
+            var saldo = SaldoSuchen(periode);
+            return (saldo != null) ? saldo.Soll : 0m;
+        }
+
+        private Saldo SaldoSuchen(string periode)
+        {
+            var saldi = (from saldo in ZugeordneteSaldi
+                                 where saldo.Periode.Equals(periode)
+                                 select saldo).ToList();
+            return (saldi.Count > 0) ? saldi.First() : null;
+        }
+
+        [XmlIgnore]
+        public string Saldo
+        {
+            get 
+            {
+                var saldo = SaldoSuchen(AktuellePeriode.ToString());
+                if (saldo != null)
+                    return saldo.Soll.ToString(Constants.Zahlenformat);
+                SaldoZuordnen(AktuellePeriode.ToString(), Decimal.Parse(Vormonat1, Constants.Zahlenformat), 0m);
+                return Vormonat1;
+            }
+            set
+            {
+                var saldo = SaldoSuchen(AktuellePeriode.ToString());
+                if (saldo != null)
+                    saldo.Soll = Decimal.Parse(value, Constants.Zahlenformat);
+                else
+                    SaldoZuordnen(AktuellePeriode.ToString(), Decimal.Parse(value, Constants.Zahlenformat), 0m);
+            }
+        }
+
+        [XmlIgnore]
+        public string Vormonat1
+        {
+            get { return SaldoVon(AktuellePeriode.Vormonat(1)).ToString(Constants.Zahlenformat); }
+        }
+
+        [XmlIgnore]
+        public string Vormonat2
+        {
+            get { return SaldoVon(AktuellePeriode.Vormonat(2)).ToString(Constants.Zahlenformat); }
+        }
+
+        [XmlIgnore]
+        public string Vormonat3
+        {
+            get { return SaldoVon(AktuellePeriode.Vormonat(3)).ToString(Constants.Zahlenformat); }
+        }
+
+        [XmlIgnore]
+        public string Vormonat4
+        {
+            get { return SaldoVon(AktuellePeriode.Vormonat(4)).ToString(Constants.Zahlenformat); }
+        }
+
+        [XmlIgnore]
+        public string Vormonat5
+        {
+            get { return SaldoVon(AktuellePeriode.Vormonat(5)).ToString(Constants.Zahlenformat); }
+        }
+
+        private decimal Monatssumme (string periode)
+        {
+            if (ZugeordneteSaldi.Count > 0)
+            {
+                return ZugeordneteSaldi.Sum(s => (s.Periode.Equals(periode)) ? s.Summe : 0m);
+            }
+            return (ZugeordneteKonten.Count > 0) ? ZugeordneteKonten.Sum(k => k.Monatssumme(periode)) : 0m;
+        }
+
+        public decimal SummeAktuellePeriode { get { return Monatssumme(AktuellePeriode.ToString()); } }
+    }
+}

+ 9 - 0
Model/Konto/IKonto.cs

@@ -0,0 +1,9 @@
+namespace GCHR.Model.Konto
+{
+    interface IKonto
+    {
+        string Kontonummer { get; set; }
+        string Bezeichnung { get; set; }
+        // KontoTypen KontoTyp { get; set; }
+    }
+}

+ 15 - 0
Model/Konto/Konten.cs

@@ -0,0 +1,15 @@
+using System.Collections.Generic;
+using System.Xml.Schema;
+using System.Xml.Serialization;
+
+namespace GCHR.Model.Konto
+{
+    public class Konten
+    {
+        [XmlAttribute(AttributeName = "noNamespaceSchemaLocation", Namespace = XmlSchema.InstanceNamespace)]
+        public string NoNamespaceSchemaLocation = "http://dev.global-cube.de/GCHR.Konten.xsd";
+
+        [XmlElement("Konto")]
+        public List<HaendlerKonto> Kontenliste = new List<HaendlerKonto>();
+    }
+}

+ 4 - 0
Model/Konto/KontoTypen.cs

@@ -0,0 +1,4 @@
+namespace GCHR.Model.Konto
+{
+    public enum KontoTypen { SuSa, Stat, ManStat, Debug };
+}

+ 47 - 0
Model/Konto/Saldo.cs

@@ -0,0 +1,47 @@
+using System;
+using System.Xml.Serialization;
+
+namespace GCHR.Model.Konto
+{
+    public class Saldo
+    {
+        #region veraltet
+
+        /// <summary>veraltet</summary>
+        [XmlAttribute("name")]
+        public string Name
+        {
+            set { Periode = value; }
+            get { return null; }
+        }
+
+        /// <summary>veraltet</summary>
+        [XmlAttribute("wert")]
+        public string Wert
+        {
+            set { Soll = Decimal.Parse(value, Constants.ZahlenformatImport); }
+            get { return null; }
+        }
+
+        #endregion
+
+        [XmlAttribute("Periode")]
+        public string Periode;
+
+
+        [XmlAttribute("Soll")]
+        public decimal Soll;
+
+        [XmlAttribute("Haben")]
+        public decimal Haben;
+
+        [XmlIgnore]
+        public string SaldoCsv
+        {
+            get { return Periode + ";" + Soll + ";" + Haben + Environment.NewLine; }
+        }
+
+        [XmlIgnore]
+        public decimal Summe { get { return Soll + Haben; } }
+    }
+}

+ 81 - 0
Model/Periode.cs

@@ -0,0 +1,81 @@
+using System;
+
+namespace GCHR.Model
+{
+    public class Periode
+    {
+        public string Jahr;
+        public string Monat;
+        public string JahrZweistellig { get { return Jahr.Substring(2, 2); } }
+        
+        private readonly bool _keinJahresabschluss;
+
+
+        public Periode(string periode)
+            : this(periode, false)
+        {
+        }
+
+        public Periode(string periode, bool keinJahresabschluss)
+        {
+            Jahr = periode.Substring(0, 4);
+            Monat = periode.Substring(4, 2);
+
+            _keinJahresabschluss = keinJahresabschluss;
+        }
+
+        public Periode Jahresbeginn(string geschaeftsjahr)
+        {
+            return Jahresbeginn(geschaeftsjahr, false);
+        }
+
+        public Periode Bilanzbeginn(string geschaeftsjahr)
+        {
+            return Jahresbeginn(geschaeftsjahr, _keinJahresabschluss);
+        }
+
+        private Periode Jahresbeginn(string geschaeftsjahr, bool keinJahresabschluss)
+        {
+            int ersterMonat; // erster Monat im Geschäftsjahr
+            try
+            {
+                ersterMonat = Int32.Parse(geschaeftsjahr);
+                if (ersterMonat > 12 || ersterMonat < 1) throw new OverflowException("Erster Monat im Geschäftsjahr muss zwischen 1 und 12 sein.");
+            }
+            catch (Exception)
+            {
+                ersterMonat = 1;
+            }
+            var aktJahr = Int32.Parse(Jahr);
+            if (Int32.Parse(Monat) < ersterMonat) aktJahr--;
+            if (keinJahresabschluss) aktJahr--;
+            return new Periode(aktJahr + ersterMonat.ToString().PadLeft(2, '0'));
+        }
+
+
+        public string Vormonat (int verschiebung)
+        {
+            var monat = Int32.Parse(Monat);
+            var jahr = Int32.Parse(Jahr);
+            
+            monat -= verschiebung;
+            if (monat < 1)
+            {
+                monat += 12;
+                jahr--;
+            }
+            return (jahr + monat.ToString().PadLeft(2, '0'));
+        }
+
+
+        public override string ToString()
+        {
+            return (Jahr + Monat);
+        }
+
+        public string Klartext
+        {
+            get { return (Monat + "/" + Jahr); }
+        }
+    }
+}

+ 66 - 0
Model/Uebersetzung/Eintrag.cs

@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using GCHR.Model.Konto;
+
+namespace GCHR.Model.Uebersetzung
+{
+    class Eintrag
+    {
+        public string KontonummerHaendler;
+
+        private string ktnrHerstellerSusa = "";
+        private string ktnrHerstellerSusaSplit = "";
+        private string ktnrHerstellerStat = "";
+        private string ktnrHerstellerStatSplit = "";
+
+        public Eintrag(string csv)
+        {
+            string[] feld = csv.Split(new char[] { ';' });
+
+            try
+            {
+                KontonummerHaendler = feld[0];
+                ktnrHerstellerSusa = feld[1];
+                ktnrHerstellerSusaSplit = feld[2];
+                ktnrHerstellerStat = feld[3];
+                ktnrHerstellerStatSplit = feld[4];
+            }
+            catch (ArgumentOutOfRangeException)
+            {
+            }
+        }
+
+        public override string ToString()
+        {
+            return String.Join(";", new string[] { KontonummerHaendler, ktnrHerstellerSusa, ktnrHerstellerSusaSplit,
+                                                   ktnrHerstellerStat, ktnrHerstellerStatSplit });
+        }    
+
+        public string Uebersetzen(HaendlerKonto haendlerKonto, bool split)
+        {
+            string herstellerKontonummer = uebersetzen(haendlerKonto, split);
+            if (herstellerKontonummer == "") throw new KontoNichtZugeordnetException(haendlerKonto);
+            return herstellerKontonummer;
+        }
+
+        private string uebersetzen(HaendlerKonto haendlerKonto, bool split)
+        {
+            if (haendlerKonto.KontoTyp == KontoTypen.Stat)
+            {
+                return (split) ? ktnrHerstellerStatSplit : ktnrHerstellerStat;
+            }
+            else
+            {
+                return (split) ? ktnrHerstellerSusaSplit : ktnrHerstellerSusa;
+            }
+        }
+
+        public void Debug(bool susaKonto, bool splitKontenVerwenden)
+        {
+            if (susaKonto && ktnrHerstellerSusa == "")
+                throw new KontoNichtZugeordnetException(KontonummerHaendler);
+        }
+    }
+}

+ 60 - 0
Model/Uebersetzung/Exceptions.cs

@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using GCHR.Model.Konto;
+
+namespace GCHR.Model.Uebersetzung
+{
+    class KontoNichtZugeordnetException : NullReferenceException
+    {
+        public KontoNichtZugeordnetException(HaendlerKonto haendlerKonto)
+            : base(haendlerKonto.DebugInfo())
+        {
+        }
+
+        public KontoNichtZugeordnetException(string haendlerKontonummer)
+            : base(haendlerKontonummer)
+        {
+        }
+    }
+
+    class HerstellerkontoNichtVorhandenException : NullReferenceException
+    {
+        public HerstellerkontoNichtVorhandenException(HaendlerKonto haendlerKonto, string herstellerKontonummer)
+            : base(haendlerKonto.DebugInfo() + " => " + herstellerKontonummer)
+        {
+        }
+
+        public HerstellerkontoNichtVorhandenException(string herstellerKontonummer)
+            : base(herstellerKontonummer)
+        {
+        }
+    }
+
+    class UebersetzungNichtVorhandenException : NullReferenceException
+    {
+        public UebersetzungNichtVorhandenException(HaendlerKonto haendlerKonto)
+            : base(haendlerKonto.DebugInfo())
+        {
+        }
+
+        public UebersetzungNichtVorhandenException(string haendlerKontonummer)
+            : base(haendlerKontonummer)
+        {
+        }
+    }
+
+    class HerstellerkontoTypArgumentException : ArgumentException
+    {
+        public HerstellerkontoTypArgumentException(HaendlerKonto haendlerKonto, string herstellerKontonummer)
+            : base(haendlerKonto.DebugInfo() + " => " + herstellerKontonummer)
+        {
+        }
+
+        public HerstellerkontoTypArgumentException(string herstellerKontonummer)
+            : base(herstellerKontonummer)
+        {
+        }
+    }
+}

+ 47 - 0
Model/Uebersetzung/HerstellerKontenrahmen.cs

@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+
+namespace GCHR.Model.Uebersetzung
+{
+    class HerstellerKontenrahmen
+    {
+        private Dictionary<string, HerstellerKonto> kontenrahmen = new Dictionary<string, HerstellerKonto>();
+
+        public HerstellerKontenrahmen(StreamReader sr)
+        {
+            while (!sr.EndOfStream)
+            {
+                HerstellerKonto kto = new HerstellerKonto(sr.ReadLine());
+                while (kontenrahmen.ContainsKey(kto.Kontonummer))
+                {
+                    kto.Kontonummer += "X";
+                }
+                kontenrahmen.Add(kto.Kontonummer, kto);
+            }
+        }
+
+        public void Speichern(StreamWriter sw)
+        {
+            foreach (HerstellerKonto kto in kontenrahmen.Values)
+            {
+                sw.WriteLine(kto);
+            }
+        }
+
+        public bool Contains(string kontonummer)
+        {
+            return kontenrahmen.ContainsKey(kontonummer);
+        }
+
+        public HerstellerKonto Get(string kontonummer)
+        {
+            return kontenrahmen[kontonummer];
+        }
+
+
+
+    }
+}

+ 60 - 0
Model/Uebersetzung/HerstellerKonto.cs

@@ -0,0 +1,60 @@
+using System;
+using System.Linq;
+using GCHR.Model.Konto;
+
+namespace GCHR.Model.Uebersetzung
+{
+    class HerstellerKonto : IKonto
+    {
+        public HerstellerKonto(string csv)
+        {
+            var kontoInfo = csv.Split(new char[] { ';' }, 11);
+
+            try
+            {
+                Kontonummer = kontoInfo[0];
+                Bezeichnung = kontoInfo[1];
+                KontoArt = kontoInfo[2];
+                KontoTyp = new KontoTyp(kontoInfo[3]);
+                KontoRegel = new Regel(kontoInfo[4]);
+                VerrechnungVon = kontoInfo[5];
+                VerrechnungNach = kontoInfo[6];
+                Konto_3 = kontoInfo[7];
+                Konto_4 = kontoInfo[8];
+                Konto_5 = kontoInfo[9];
+                Ebenen = kontoInfo[10];
+            }
+            catch (ArgumentOutOfRangeException)
+            {
+                if (kontoInfo.Count() < 4) KontoTyp = new KontoTyp("S");
+                if (kontoInfo.Count() < 5) KontoRegel = new Regel("0,0");
+            }
+        }
+
+        public override string ToString()
+        {
+            return String.Join(";", new string[] { Kontonummer, Bezeichnung, KontoArt, KontoTyp.ToString(), KontoRegel.ToString(), 
+                                                   VerrechnungVon, VerrechnungNach, Konto_3, Konto_4, Konto_5, Ebenen });
+        }
+        
+        #region IKonto Member
+
+        public string Kontonummer { get; set; }
+        
+        public string Bezeichnung { get; set; }
+
+        public KontoTyp KontoTyp { get; set; }
+
+        #endregion
+
+        public string KontoArt { get; set; }
+
+        public Regel KontoRegel { get; set; }
+        public string VerrechnungVon { get; set; }
+        public string VerrechnungNach { get; set; }
+        public string Konto_3 { get; set; }
+        public string Konto_4 { get; set; }
+        public string Konto_5 { get; set; }
+        public string Ebenen { get; set; }
+    }
+}

+ 102 - 0
Model/Uebersetzung/KontoTyp.cs

@@ -0,0 +1,102 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace GCHR.Model.Uebersetzung
+{
+    class KontoTyp
+    {
+        enum Typ { S, Q, M, V, D };
+        enum Buchung { HH, HS, SH, SS };
+ 
+
+        public KontoTyp(string typ)
+        {
+            if (typ.Length > 0)
+            {
+                kontoTyp = tryParseKontoTyp(typ.Substring(0, 1));
+                negativ = typ.Contains('-');
+                alternativ = typ.Contains('A');
+
+                if (kontoTyp == Typ.V)
+                {
+                    if (typ.Contains("HH")) buchung = Buchung.HH;
+                    if (typ.Contains("HS")) buchung = Buchung.HS;
+                    if (typ.Contains("SH")) buchung = Buchung.SH;
+                    if (typ.Contains("SS")) buchung = Buchung.SS;
+                }
+            }
+        }
+
+        private static Typ tryParseKontoTyp(string typ)
+        {
+            try
+            {
+                return (Typ)Enum.Parse(typeof(Typ), typ);
+            }
+            catch (Exception)
+            {
+                return Typ.S;
+            }
+        }
+
+        private Typ kontoTyp = Typ.S;
+        private bool negativ = false;
+        private bool alternativ = false;
+
+        private Buchung buchung = Buchung.SH;
+
+        public decimal Faktor
+        {
+            get { return (negativ) ? -1m : 1m; }
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (obj is KontoTyp)
+            {
+                return equals(((KontoTyp)obj).kontoTyp);
+            }
+            if (obj is Typ)
+            {
+                return equals((Typ)obj);
+            }
+            if (obj is string)
+            {
+                try
+                {
+                    return equals((Typ)Enum.Parse(typeof(Typ), ((string)obj).Substring(0, 1)));
+                }
+                catch (Exception)
+                {
+                }
+            }
+            return base.Equals(obj);
+        }
+
+        private bool equals(Typ typ)
+        {
+            if (typ == kontoTyp)
+                return true;
+
+            if (typ == Typ.D || typ == Typ.D)
+                return true;
+
+            if ((typ == Typ.V && kontoTyp == Typ.S) || (typ == Typ.S && kontoTyp == Typ.V))
+                return true;
+
+            return false;
+        }
+
+        public override string ToString()
+        {
+            return kontoTyp + ((alternativ) ? "A" : "") + ((kontoTyp == Typ.V) ? buchung.ToString() : "") + ((negativ) ? "-" : "");
+        }
+
+        public override int GetHashCode()
+        {
+            return ToString().GetHashCode();
+        }
+    }
+}

+ 45 - 0
Model/Uebersetzung/Regel.cs

@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace GCHR.Model.Uebersetzung
+{
+    class Regel
+    {
+        internal static string Hauptmarke = "1";
+        internal static string Hauptbetrieb = "01";
+
+        public Regel(string regel)
+        {
+            if (regel == "")
+            {
+                markeDefault = Hauptmarke;
+                betriebDefault = Hauptbetrieb;
+                return;
+            }
+            string[] split = regel.Split(new char[] { ',' });
+
+            string[] markeSplit = split[0].Split(new char[] { ':' });
+            markeRegel = (markeSplit[0] != "") ? markeSplit[0] : "0";
+            markeDefault = (markeSplit.Count() > 1) ? markeSplit[1] : Hauptmarke;
+
+            if (split.Count() > 1)
+            {
+                string[] betriebSplit = split[1].Split(new char[] { ':' });
+                betriebRegel = (betriebSplit[0] != "") ? betriebSplit[0] : "0";
+                betriebDefault = (betriebSplit.Count() > 1) ? betriebSplit[1] : Hauptbetrieb;
+            }
+        }
+
+        private string markeRegel = "0";
+        private string markeDefault;
+        private string betriebRegel = "0";
+        private string betriebDefault;
+
+        public override string ToString()
+        {
+            return String.Format("{0}:{1},{2}:{3}", markeRegel, markeDefault, betriebRegel, betriebDefault);
+        }
+    }
+}

+ 46 - 0
Model/Uebersetzung/Uebersetzungstabelle.cs

@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+using GCHR.Model.Konto;
+
+namespace GCHR.Model.Uebersetzung
+{
+    class Uebersetzungstabelle
+    {
+        public HerstellerKontenrahmen herstellerKontenrahmen { set; private get; }
+        private Dictionary<string, Eintrag> uebersetzungstabelle = new Dictionary<string, Eintrag>();
+
+        public Uebersetzungstabelle(StreamReader sr)
+        {
+            while (!sr.EndOfStream)
+            {
+                Eintrag eintrag = new Eintrag(sr.ReadLine());
+                while (uebersetzungstabelle.ContainsKey(eintrag.KontonummerHaendler))
+                {
+                    eintrag.KontonummerHaendler += "X";
+                }
+                uebersetzungstabelle.Add(eintrag.KontonummerHaendler, eintrag);
+            }
+        }
+
+        public void Speichern(StreamWriter sw)
+        {
+            foreach (Eintrag eintrag in uebersetzungstabelle.Values)
+            {
+                sw.WriteLine(eintrag);
+            }
+        }
+
+        public HerstellerKonto Uebersetzen(HaendlerKonto haendlerKonto, bool split)
+        {
+            return herstellerKontenrahmen.Get(uebersetzen(haendlerKonto, split));
+        }
+
+        public string uebersetzen(HaendlerKonto haendlerKonto, bool split)
+        {
+            return uebersetzungstabelle[haendlerKonto.Kontonummer].Uebersetzen(haendlerKonto, split);
+        }
+    }
+}

+ 54 - 0
Properties/AssemblyInfo.cs

@@ -0,0 +1,54 @@
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// Allgemeine Informationen über eine Assembly werden über die folgenden 
+// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
+// die mit einer Assembly verknüpft sind.
+[assembly: AssemblyTitle("GCHR")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("GlobalCube")]
+[assembly: AssemblyProduct("GCHR")]
+[assembly: AssemblyCopyright("Copyright © GlobalCube 2010")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar 
+// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von 
+// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
+[assembly: ComVisible(false)]
+
+//Um mit dem Erstellen lokalisierbarer Anwendungen zu beginnen, legen Sie 
+//<UICulture>ImCodeVerwendeteKultur</UICulture> in der .csproj-Datei
+//in einer <PropertyGroup> fest. Wenn Sie in den Quelldateien beispielsweise Deutsch
+//(Deutschland) verwenden, legen Sie <UICulture> auf \"de-DE\" fest. Heben Sie dann die Auskommentierung
+//des nachstehenden NeutralResourceLanguage-Attributs auf. Aktualisieren Sie "en-US" in der nachstehenden Zeile,
+//sodass es mit der UICulture-Einstellung in der Projektdatei übereinstimmt.
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly: ThemeInfo(
+    ResourceDictionaryLocation.None, //Speicherort der designspezifischen Ressourcenwörterbücher
+    //(wird verwendet, wenn eine Ressource auf der Seite
+    // oder in den Anwendungsressourcen-Wörterbüchern nicht gefunden werden kann.)
+    ResourceDictionaryLocation.SourceAssembly //Speicherort des generischen Ressourcenwörterbuchs
+    //(wird verwendet, wenn eine Ressource auf der Seite, in der Anwendung oder einem 
+    // designspezifischen Ressourcenwörterbuch nicht gefunden werden kann.)
+)]
+
+
+// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
+//
+//      Hauptversion
+//      Nebenversion 
+//      Buildnummer
+//      Revision
+//
+// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern 
+// übernehmen, indem Sie "*" eingeben:
+[assembly: AssemblyVersion("1.28.13.*")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 63 - 0
Properties/Resources.Designer.cs

@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     Dieser Code wurde von einem Tool generiert.
+//     Laufzeitversion:2.0.50727.4952
+//
+//     Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
+//     der Code erneut generiert wird.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace GCHR.Properties {
+    using System;
+    
+    
+    /// <summary>
+    ///   Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
+    /// </summary>
+    // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
+    // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
+    // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
+    // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GCHR.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
+        ///   Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+    }
+}

+ 120 - 0
Properties/Resources.resx

@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 26 - 0
Properties/Settings.Designer.cs

@@ -0,0 +1,26 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     Dieser Code wurde von einem Tool generiert.
+//     Laufzeitversion:2.0.50727.4927
+//
+//     Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
+//     der Code erneut generiert wird.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace GCHR.Properties {
+    
+    
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+        
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+        
+        public static Settings Default {
+            get {
+                return defaultInstance;
+            }
+        }
+    }
+}

+ 7 - 0
Properties/Settings.settings

@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>

BIN
Resources/GlobalCube.png


+ 76 - 0
Tests.cs

@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using System.Diagnostics;
+using System.IO;
+using System.Xml.Serialization;
+using System.Threading;
+
+namespace HRep_WPF
+{
+    [TestFixture]
+    public class KonfigurationTest
+    {
+        private Konfiguration config;
+
+        public KonfigurationTest()
+        {
+            String configFile = "test2.xml";
+
+            GCExportConfig gceConfig = gceConfigTestwerteGenerieren();
+            gceConfigTestwerteSpeichern(gceConfig, configFile);
+
+            config = new Konfiguration(new ThreadXData(), configFile, "201001");
+        }
+
+        private void gceConfigTestwerteSpeichern(GCExportConfig gceConfig, String configFile)
+        {
+            XmlSerializer serializer = new XmlSerializer(typeof(GCExportConfig));
+            using (TextWriter stream = new StreamWriter(configFile))
+            {
+                serializer.Serialize(stream, gceConfig);
+            }
+        }
+
+        private GCExportConfig gceConfigTestwerteGenerieren()
+        {
+            GCExportConfig gceConfig = new GCExportConfig();
+
+            gceConfig.Einstellungen.DepartmentUebersetzung.Add(new UebersetzungXml() { von = "1", nach = "2" });
+            gceConfig.Einstellungen.DepartmentUebersetzung.Add(new UebersetzungXml() { von = "22", nach = "33" });
+            gceConfig.Einstellungen.Eurodatanummer = "12345";
+            KontoXml kto = new KontoXml() { Kontonummer = "81000" };
+            kto.Periode.Add(new PeriodeXml() { Name = "201001", Debit = 0.01 });
+            gceConfig.Konten.Add(kto);
+
+            return gceConfig;
+        }
+
+        [Test]
+        public void AktuellePeriode()
+        {
+            Assert.AreEqual("201001", config.aktuellePeriode.ToString());
+            Assert.AreEqual("01", config.aktuellePeriode.Monat);
+            Assert.AreEqual("2010", config.aktuellePeriode.Jahr);
+            Assert.AreEqual("10", config.aktuellePeriode.JahrZweistellig);
+        }
+
+        [Test]
+        public void Variablen()
+        {
+            Assert.AreEqual("00012345", config.Eurodatanummer);
+            Assert.AreEqual("01", config.Geschaeftsjahr);
+        }
+
+        [Test]
+        public void DepartmentUebersetzung()
+        {
+            Assert.AreEqual("312", config.DepartmentAnpassen("123"));
+            Assert.AreEqual("211", config.DepartmentAnpassen("111"));
+            Assert.AreEqual("033", config.DepartmentAnpassen("220"));
+            Assert.AreEqual("233", config.DepartmentAnpassen("221"));
+        }
+    }
+}

+ 20 - 0
Themes/Generic.xaml

@@ -0,0 +1,20 @@
+<ResourceDictionary
+    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+    xmlns:local="clr-namespace:GCHR"
+    xmlns:printing="clr-namespace:GCHR.Control.Printing">
+
+
+    <Style TargetType="{x:Type printing:PageElement}">
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="{x:Type printing:PageElement}">
+                    <Border Background="{TemplateBinding Background}"
+                            BorderBrush="{TemplateBinding BorderBrush}"
+                            BorderThickness="{TemplateBinding BorderThickness}">
+                    </Border>
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
+    </Style>
+</ResourceDictionary>

+ 73 - 0
UpgradeLog.XML

@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type='text/xsl' href='_UpgradeReport_Files/UpgradeReport.xslt'?><UpgradeLog>
+<Properties><Property Name="Solution" Value="GCHR">
+</Property><Property Name="Projektmappendatei" Value="D:\Projekte\GCHR\GCHR.sln">
+</Property><Property Name="Benutzeroptionendatei" Value="D:\Projekte\GCHR\GCHR.suo">
+</Property><Property Name="Date" Value="Donnerstag, 9. Juni 2011">
+</Property><Property Name="Time" Value="10:31">
+</Property></Properties><Event ErrorLevel="0" Project="" Source="GCHR.sln" Description="Datei wurde erfolgreich als &quot;D:\Projekte\GCHR\Backup\GCHR.sln&quot; gesichert">
+</Event><Event ErrorLevel="0" Project="" Source="GCHR.suo" Description="Datei wurde erfolgreich als &quot;D:\Projekte\GCHR\Backup\GCHR.suo&quot; gesichert">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="GCHR.csproj" Description="Projektdatei erfolgreich gesichert als D:\Projekte\GCHR\Backup\GCHR.csproj">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="GCHR.csproj.user" Description="Die Projektbenutzerdatei wurde erfolgreich als &quot;D:\Projekte\GCHR\Backup\GCHR.csproj.user&quot; gesichert.">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="App.xaml.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\App.xaml.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Main.xaml.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Main.xaml.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Control\Tasks\Export.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Control\Tasks\Export.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Mandantenschnittstelle\Default.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Mandantenschnittstelle\Default.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Mandantenschnittstelle\Volkswagen.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Mandantenschnittstelle\Volkswagen.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Model\Konto\IKonto.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Model\Konto\IKonto.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Model\Konto\KontoTypen.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Model\Konto\KontoTypen.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Model\Uebersetzung\Eintrag.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Model\Uebersetzung\Eintrag.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Model\Uebersetzung\Exceptions.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Model\Uebersetzung\Exceptions.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Model\Uebersetzung\HerstellerKontenrahmen.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Model\Uebersetzung\HerstellerKontenrahmen.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Model\Uebersetzung\HerstellerKonto.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Model\Uebersetzung\HerstellerKonto.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Model\Uebersetzung\KontoTyp.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Model\Uebersetzung\KontoTyp.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Model\Uebersetzung\Regel.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Model\Uebersetzung\Regel.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Model\Uebersetzung\Uebersetzungstabelle.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Model\Uebersetzung\Uebersetzungstabelle.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="View\Ampel.xaml.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\View\Ampel.xaml.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Model\Constants.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Model\Constants.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Model\cTripleDES.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Model\cTripleDES.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Control\DepartmentCase.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Control\DepartmentCase.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="View\Einstellungen.xaml.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\View\Einstellungen.xaml.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Model\GCExportConfig.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Model\GCExportConfig.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Control\Tasks\Verrechnung.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Control\Tasks\Verrechnung.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Model\Konfiguration.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Model\Konfiguration.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Model\Konto\Konten.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Model\Konto\Konten.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Model\Konto\Saldo.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Model\Konto\Saldo.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Mandantenschnittstelle\Fiat.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Mandantenschnittstelle\Fiat.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="View\ManuelleKontenBearbeiten.xaml.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\View\ManuelleKontenBearbeiten.xaml.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Model\Periode.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Model\Periode.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Control\Tasks\TaskManager.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Control\Tasks\TaskManager.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Model\Konto\HaendlerKonto.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Model\Konto\HaendlerKonto.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Mandantenschnittstelle\Mandant.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Mandantenschnittstelle\Mandant.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Mandantenschnittstelle\Citroen.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Mandantenschnittstelle\Citroen.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Mandantenschnittstelle\Ford.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Mandantenschnittstelle\Ford.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Mandantenschnittstelle\Opel.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Mandantenschnittstelle\Opel.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Mandantenschnittstelle\Peugeot.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Mandantenschnittstelle\Peugeot.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Mandantenschnittstelle\Test.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Mandantenschnittstelle\Test.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Control\Printing\PageElement.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Control\Printing\PageElement.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Control\Printing\Paginator.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Control\Printing\Paginator.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Properties\AssemblyInfo.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Properties\AssemblyInfo.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Properties\Resources.Designer.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Properties\Resources.Designer.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Properties\Settings.Designer.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Properties\Settings.Designer.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Control\Tasks\Datenimport.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Control\Tasks\Datenimport.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Control\Tasks\Kontenrahmen.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Control\Tasks\Kontenrahmen.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Control\Tasks\ManuelleKonten.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Control\Tasks\ManuelleKonten.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Control\Tasks\Task.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Control\Tasks\Task.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Control\Tasks\Uebersetzung.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Control\Tasks\Uebersetzung.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Control\Tasks\UebersetzungStat.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Control\Tasks\UebersetzungStat.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Control\Tasks\UebersetzungSuSa.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Control\Tasks\UebersetzungSuSa.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Control\Tasks\Verarbeitung.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Control\Tasks\Verarbeitung.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Control\ThreadXData.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Control\ThreadXData.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Tests.cs" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Tests.cs">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Properties\Settings.settings" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Properties\Settings.settings">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Properties\Resources.resx" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Properties\Resources.resx">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="App.xaml" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\App.xaml">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="View\Ampel.xaml" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\View\Ampel.xaml">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="View\Einstellungen.xaml" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\View\Einstellungen.xaml">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Main.xaml" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Main.xaml">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="View\ManuelleKontenBearbeiten.xaml" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\View\ManuelleKontenBearbeiten.xaml">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="Themes\Generic.xaml" Description="Datei erfolgreich gesichert als D:\Projekte\GCHR\Backup\Themes\Generic.xaml">
+</Event><Event ErrorLevel="0" Project="GCHR" Source="GCHR.csproj" Description="Die Projektdatei erfordert keine Konvertierung.">
+</Event><Event ErrorLevel="3" Project="GCHR" Source="GCHR.csproj" Description="Keine Konvertierung erforderlich">
+</Event><Event ErrorLevel="0" Project="" Source="GCHR.sln" Description="Die Projektmappe wurde erfolgreich konvertiert.">
+</Event><Event ErrorLevel="3" Project="" Source="GCHR.sln" Description="Converted">
+</Event></UpgradeLog>

+ 63 - 0
View/Ampel.xaml

@@ -0,0 +1,63 @@
+<UserControl x:Class="GCHR.View.Ampel"
+    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+    Height="15" Width="45" BorderThickness="0">
+    
+    <UserControl.Resources>
+        <Storyboard x:Key="sbWorkingAnimation" AutoReverse="False" RepeatBehavior="Forever">
+            <!--<ColorAnimation Storyboard.TargetName="Grün"
+                                Storyboard.TargetProperty="Fill.Color"
+                                From="Transparent" To="Green" 
+                                AutoReverse="True"
+                                BeginTime="0:0:0" Duration="0:0:.5" />-->
+            <ColorAnimation Storyboard.TargetName="Gelb"
+                                Storyboard.TargetProperty="Fill.Color"
+                                From="Transparent" To="Yellow" 
+                                AutoReverse="True"
+                                BeginTime="0:0:0" Duration="0:0:1.5" />
+            <!--<ColorAnimation Storyboard.TargetName="Rot"
+                                Storyboard.TargetProperty="Fill.Color"
+                                From="Transparent" To="Red" 
+                                AutoReverse="True"
+                                BeginTime="0:0:2.0" Duration="0:0:.5" />-->
+        </Storyboard>
+    </UserControl.Resources>
+        
+    <Grid Name="mainCanvas" Background="Transparent">
+        <!--<Button Background="Transparent" Click="Button_Click" Panel.ZIndex="100" BorderThickness="0" Foreground="Transparent" Focusable="True" BorderBrush="Transparent">
+            <Button.Triggers>
+                <EventTrigger RoutedEvent="Button.Click">
+                    
+                </EventTrigger>
+            </Button.Triggers>
+        </Button>-->
+        
+        
+        <!--<Label Name="Grün" Background="Transparent" HorizontalAlignment="Left" Width="15" Height="15" Panel.ZIndex="1" BorderThickness="15" Foreground="Transparent" Focusable="False" BorderBrush="Green"></Label>
+        <Label Name="Gelb" Background="Transparent" HorizontalAlignment="Center" Width="15" Height="15" Panel.ZIndex="1" BorderThickness="15" Foreground="Transparent" Focusable="False" BorderBrush="Yellow"></Label>
+        <Label Name="Rot" Background="Transparent" HorizontalAlignment="Right" Width="15" Height="15" Panel.ZIndex="1" BorderThickness="15" Foreground="Transparent" Focusable="False" BorderBrush="Red"></Label>-->
+        <Rectangle Name="Grün" Width="15" Canvas.Top="-1" HorizontalAlignment="Left">
+            <Rectangle.Fill>
+                <SolidColorBrush Color="Transparent" Opacity="1" />
+            </Rectangle.Fill>
+        </Rectangle>
+        
+        <Rectangle Name="Gelb" Margin="15,0" Canvas.Top="-1">
+            <Rectangle.Fill>
+                <SolidColorBrush Color="Transparent" Opacity="1" />
+            </Rectangle.Fill>
+        </Rectangle>
+        
+        <Rectangle Name="Rot" Width="15" Margin="30,0,0,0" Canvas.Top="-1">
+            <Rectangle.Fill>
+                <SolidColorBrush Color="Transparent" Opacity="1" />
+            </Rectangle.Fill>
+        </Rectangle>
+        <Button MouseEnter="BtnStatusMouseEnter" Click="BtnStatusClick" HorizontalAlignment="Left" Margin="0" Name="btnGruen" Width="15" BorderThickness="0" Background="Green" Height="15" Visibility="Hidden" IsEnabled="True" Focusable="False" />
+        <Button MouseEnter="BtnStatusMouseEnter" Click="BtnStatusClick" Background="Yellow" BorderThickness="0" Height="15" Margin="15,0" Name="btnGelb" VerticalAlignment="Bottom" Width="15" Visibility="Hidden" Focusable="False" />
+        <Button MouseEnter="BtnStatusMouseEnter" Click="BtnStatusClick" Background="Red" BorderThickness="0" Height="15" Margin="0" Name="btnRot" VerticalAlignment="Bottom" Width="15" HorizontalAlignment="Right" Visibility="Hidden" Focusable="False" />
+        <ProgressBar Height="15" Margin="0,0,0,0" Name="pbThread" VerticalAlignment="Top" HorizontalAlignment="Left" Width="45" Background="White" Foreground="DarkSlateGray" Value="0" SmallChange="1" IsIndeterminate="True" Visibility="Hidden" />
+        <Button MouseEnter="BtnStatusMouseEnter" Click="BtnStatusClick" Background="Transparent" BorderThickness="0" Height="15" Margin="0" Name="btnStatus" VerticalAlignment="Bottom" Width="45" HorizontalAlignment="Right" Visibility="Hidden" Opacity="0" Focusable="False" />
+    </Grid>
+    
+</UserControl>

+ 140 - 0
View/Ampel.xaml.cs

@@ -0,0 +1,140 @@
+using System;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using GCHR.Model;
+
+namespace GCHR.View
+{
+    public partial class Ampel
+    {
+        private readonly Button[] _buttons;
+        delegate void DelAsyncWindowAction();
+
+
+        public Ampel()
+        {
+            InitializeComponent();
+            _buttons = new[] { btnStatus, btnGruen, btnGelb, btnRot };
+
+            _anzeigeAnStatusAnpassen = delegate()
+            {
+                for (var i = 0; i < _buttons.Count(); i++)
+                {
+                    _buttons[i].Visibility = (i == (int)_status) ? Visibility.Visible : Visibility.Hidden;
+                }
+                pbThread.Visibility = (_status == Ampelstatus.Arbeitend) ? Visibility.Visible : Visibility.Hidden;
+            };
+
+            Status = Ampelstatus.Keine;
+        }
+
+        /// <summary>
+        /// Muss festgelegt werden, dass dynamisch darauf zugegriffen werden kann.
+        /// </summary>
+        public static DependencyProperty SourceProperty = DependencyProperty.Register(
+            "Message", typeof(String), typeof(Ampel));
+
+        /// <summary>
+        /// Gibt an, ob der der Ampel zugehörige Prozess beendet ist. 
+        /// working und rot => false
+        /// gelb und grün => true
+        /// </summary>
+        public bool Done 
+        { 
+            get 
+            {
+                return (Status == Ampelstatus.Gruen || Status == Ampelstatus.Gelb);
+            }
+        }
+
+        public Ampelstatus Status
+        {
+            get
+            {
+                return _status;
+            }
+            set
+            {
+                _status = value;
+                Dispatcher.BeginInvoke(_anzeigeAnStatusAnpassen, null);
+            }
+        }
+        private Ampelstatus _status;
+
+        private readonly DelAsyncWindowAction _anzeigeAnStatusAnpassen;
+
+        public int Progress 
+        {
+            set
+            {
+                DelAsyncWindowAction fortschritt = delegate
+                                                       {
+                                                           pbThread.Value = value;
+                                                           pbThread.IsIndeterminate = !(value > 0);
+                                                       };
+                pbThread.Dispatcher.BeginInvoke(fortschritt, null);
+                if (Status == Ampelstatus.Keine)
+                {
+                    Status = Ampelstatus.Arbeitend;
+                }
+                if (value == 100 && Status != Ampelstatus.Rot)
+                {
+                    Status = (Message == "") ? Ampelstatus.Gruen : Ampelstatus.Gelb;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Benutzt <see cref="Ampel.SourceProperty"/>, um den Wert des Statustextes zu schreiben oder zu lesen.
+        /// </summary>
+        public string Message
+        {
+            get 
+            { 
+                return (String)GetValue(SourceProperty); 
+            }
+            set 
+            { 
+                SetValue(SourceProperty, value.Trim()); 
+            }
+        }
+
+        public void ProgressChanged(int progress, object status)
+        {
+            Progress = progress;
+            if (status is Status)
+            {
+                Status = ((Status)status).Ampelstatus;
+                Message = ((Status)status).Message;
+            }
+            else if (status is Ampelstatus)
+            {
+                Status = (Ampelstatus)status;
+            }
+            else if (status is String && !((String)status).Equals(""))
+            {
+                Message += (String)status + Environment.NewLine;
+            }
+        }
+        
+        private void BtnStatusClick(object sender, RoutedEventArgs e)
+        {
+            // MessageBox.Show(Message);
+        }
+
+        public void Reset()
+        {
+            Status = Ampelstatus.Keine;
+            Message = "";
+        }
+
+        private void BtnStatusMouseEnter(object sender, MouseEventArgs e)
+        {
+            var btn = (Button)sender;
+            btn.ToolTip = new ToolTip { Content = Message, StaysOpen = true };
+            
+        }
+    }
+}

+ 259 - 0
View/Einstellungen.xaml

@@ -0,0 +1,259 @@
+<Window x:Class="GCHR.View.Einstellungen"
+    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+    Title="Einstellungen" Height="531" Width="861">
+    <Grid>
+        <Grid.Background>
+            <LinearGradientBrush StartPoint="0,1" EndPoint="0,0">
+                <GradientStop Color="#FF9EBFDE" Offset=".5"/>
+                <GradientStop Color="#FF30567A" Offset="1"/>
+            </LinearGradientBrush>
+        </Grid.Background>
+        
+        <Grid.RowDefinitions>
+            <RowDefinition Height="*" />
+            <RowDefinition Height="72" />
+        </Grid.RowDefinitions>
+        
+        <WrapPanel>
+            <Border Margin="6" HorizontalAlignment="Left" CornerRadius="10" VerticalAlignment="Top" BorderBrush="Black" BorderThickness="1">
+                <Border.Effect>
+                    <DropShadowEffect Color="Black" />
+                </Border.Effect>
+                <Border.Background>
+                    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
+                        <GradientStop Color="#FF9EBFDE" Offset=".5"/>
+                        <GradientStop Color="#FF30567A" Offset="1"/>
+                    </LinearGradientBrush>
+                </Border.Background>
+                <Grid Width="257">
+                    <Grid.ColumnDefinitions>
+                        <ColumnDefinition Width="116" />
+                        <ColumnDefinition Width="*" />
+                    </Grid.ColumnDefinitions>
+                    <Grid.RowDefinitions>
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                    </Grid.RowDefinitions>
+                    <Label Grid.ColumnSpan="2" Margin="2" Foreground="White">Allgemeine Einstellungen:</Label>
+                    <Label Grid.Row="1" Grid.Column="0" Margin="2" FontSize="9" VerticalAlignment="Center" Foreground="White">Mandant:</Label>
+                    <ComboBox Grid.Row="1" Name="cbMandant" Grid.Column="1" Margin="6" SelectedIndex="0" FontSize="9" VerticalAlignment="Center">
+                        <ComboBoxItem>Citroen</ComboBoxItem>
+                        <ComboBoxItem>Fiat</ComboBoxItem>
+                        <ComboBoxItem>Ford</ComboBoxItem>
+                        <ComboBoxItem>Honda</ComboBoxItem>
+                        <ComboBoxItem>Opel</ComboBoxItem>
+                        <ComboBoxItem>Peugeot</ComboBoxItem>
+                        <ComboBoxItem>Volkswagen</ComboBoxItem>
+                    </ComboBox>
+                    <Label Grid.Row="2" Grid.Column="0" Margin="2" FontSize="9" VerticalAlignment="Center" Foreground="White">BM-Code:</Label>
+                    <TextBox Name="txtHnr"  Grid.Row="2" Grid.Column="1" Margin="6" FontSize="9" VerticalAlignment="Center"></TextBox>
+                    <Label Grid.Row="3" Grid.Column="0" Margin="2" FontSize="9" VerticalAlignment="Center" Foreground="White">Händlerkontenrahmen:</Label>
+                    <TextBox Name="txtHändlerKontenrahmen" Grid.Row="3" Grid.Column="1" Margin="6" FontSize="9" VerticalAlignment="Center"></TextBox>
+                    <Label Grid.Row="4" Grid.Column="0" Margin="2" FontSize="9" VerticalAlignment="Center" Foreground="White">Herstellerkontenrahmen:</Label>
+                    <TextBox Name="txtHerstellerKontenrahmen" Grid.Row="4" Grid.Column="1" Margin="6" FontSize="9" VerticalAlignment="Center"></TextBox>
+                    <Label Grid.Row="5" Grid.Column="0" Margin="2" FontSize="9" VerticalAlignment="Center" Foreground="White">Hauptmarke:</Label>
+                    <TextBox Name="txtHauptmarke" Grid.Row="5" Grid.Column="1" Margin="6" FontSize="9" VerticalAlignment="Center"></TextBox>
+                    <Label Grid.Row="6" Grid.Column="0" Margin="2" FontSize="9" VerticalAlignment="Center" Foreground="White">Hauptbetrieb:</Label>
+                    <TextBox Name="txtHauptbetrieb" Grid.Row="6" Grid.Column="1" Margin="6,6,6,10" FontSize="9" VerticalAlignment="Center"></TextBox>
+                    <Label Grid.Row="7" Grid.Column="0" Margin="2" FontSize="9" VerticalAlignment="Center" Foreground="White">Geschäftsjahresbeginn:</Label>
+                    <TextBox Name="txtGeschäftsjahr" Grid.Row="7" Grid.Column="1" Margin="6,6,6,10" FontSize="9" VerticalAlignment="Center"></TextBox>
+                </Grid>
+            </Border>
+
+            <Border Margin="6" HorizontalAlignment="Left" CornerRadius="10" VerticalAlignment="Top" BorderBrush="Black" BorderThickness="1" Height="145.73">
+                <Border.Effect>
+                    <DropShadowEffect Color="Black" />
+                </Border.Effect>
+                <Border.Background>
+                    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
+                        <GradientStop Color="#FF9EBFDE" Offset=".5"/>
+                        <GradientStop Color="#FF30567A" Offset="1"/>
+                    </LinearGradientBrush>
+                </Border.Background>
+                <Grid>
+                    <Grid.ColumnDefinitions>
+                        <ColumnDefinition Width="38" />
+                        <ColumnDefinition Width="82" />
+                        <ColumnDefinition Width="38" />
+                        <ColumnDefinition Width="82" />
+                        <ColumnDefinition Width="40" />
+                    </Grid.ColumnDefinitions>
+                    <Grid.RowDefinitions>
+                        <RowDefinition Height="27" />
+                        <RowDefinition Height="27" />
+                        <RowDefinition Height="68*" />
+                    </Grid.RowDefinitions>
+                    <Label Grid.ColumnSpan="4" Margin="2" Foreground="White">Departmentübersetzungen:</Label>
+                    <Label Grid.Row="1" VerticalContentAlignment="Center" Grid.ColumnSpan="2" Margin="2" Foreground="White">Von:</Label>
+                    <TextBox Grid.Row="1" Grid.Column="1" FontSize="9" VerticalAlignment="Bottom" Margin="6,0,6,4" VerticalContentAlignment="Top" Name="txtVon" GotFocus="TxtVonGotFocus" Height="16.863" KeyDown="TxtVonKeyDown"></TextBox>
+                    <Label Grid.Row="1" Grid.Column="2" VerticalContentAlignment="Center" Margin="0,2,0,0" Foreground="White">Nach:</Label>
+                    <TextBox Grid.Row="1" Grid.Column="3" FontSize="9" VerticalAlignment="Bottom" Margin="6,0,6,4" VerticalContentAlignment="Top" Name="txtNach" GotFocus="TxtNachGotFocus" KeyDown="TxtNachKeyDown" Height="16.863"></TextBox>
+                    <Button Template="{DynamicResource GlassButton}" Grid.Row="1" Grid.Column="4" Margin="6,0,6,0" HorizontalAlignment="Center" Width="21" Click="ButtonClick2" Height="20" Name="butPlus" Foreground="White">+</Button>
+                    <ListBox Grid.Row="2" Grid.ColumnSpan="4" Margin="6,6,6,8.999" Name="lbÜbersetzungen" MaxHeight="Infinity" MinHeight="20">
+
+                    </ListBox>
+                    <Button Template="{DynamicResource GlassButton}" Grid.Row="2" Grid.Column="4" Margin="6" HorizontalAlignment="Center" Width="21" Click="ButMinusClick" Name="butMinus" VerticalAlignment="Top" Height="20" Foreground="White">-</Button>
+                </Grid>
+            </Border>
+            
+            <Border Margin="6" HorizontalAlignment="Left" CornerRadius="10" VerticalAlignment="Top" BorderBrush="Black" BorderThickness="1">
+                <Border.Effect>
+                    <DropShadowEffect Color="Black" />
+                </Border.Effect>
+                <Border.Background>
+                    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
+                        <GradientStop Color="#FF9EBFDE" Offset=".5"/>
+                        <GradientStop Color="#FF30567A" Offset="1"/>
+                    </LinearGradientBrush>
+                </Border.Background>
+                <Grid Width="257">
+                    <Grid.ColumnDefinitions>
+                        <ColumnDefinition Width="116" />
+                        <ColumnDefinition Width="*" />
+                    </Grid.ColumnDefinitions>
+                    <Grid.RowDefinitions>
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                    </Grid.RowDefinitions>
+                    <Label Grid.Row="0" Grid.ColumnSpan="2" Margin="2" Foreground="White">Updateeinstellungen:</Label>
+                    <CheckBox Name="cbAktiviert" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Margin="7" FontSize="9" VerticalAlignment="Center" Foreground="Black" />
+                    <Label Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Margin="20,5,5,5" FontSize="9" VerticalAlignment="Center" Foreground="White">Automatisches Update aktivieren</Label>
+                    <Label Grid.Row="2" Grid.Column="0" Margin="2" FontSize="9" VerticalAlignment="Center" Foreground="White">Bezug von:</Label>
+                    <TextBox Grid.Row="2" Name="txtUpdateadresse" Grid.Column="1" Margin="6" FontSize="9" VerticalAlignment="Center" IsEnabled="False" />
+                    <Label Grid.Row="3" Grid.Column="0" Margin="2" FontSize="9" VerticalAlignment="Center" Foreground="White">Proxy-Adresse:</Label>
+                    <TextBox IsEnabled="{Binding ElementName=cbAktiviert, Path=IsChecked}" Name="txtProxyAdresse" Grid.Row="3" Grid.Column="1" Margin="6" FontSize="9" VerticalAlignment="Center"></TextBox>
+                    <Label Grid.Row="4" Grid.Column="0" Margin="2" FontSize="9" VerticalAlignment="Center" Foreground="White">Proxy-Port:</Label>
+                    <TextBox IsEnabled="{Binding ElementName=cbAktiviert, Path=IsChecked}" Name="txtProxyPort" Grid.Row="4" Grid.Column="1" Margin="6" FontSize="9" VerticalAlignment="Center"></TextBox>
+                    <Label Grid.Row="5" Grid.Column="0" Margin="2" FontSize="9" VerticalAlignment="Center" Foreground="White">Proxy-Benutzername:</Label>
+                    <TextBox IsEnabled="{Binding ElementName=cbAktiviert, Path=IsChecked}" Name="txtProxyBenutzer" Grid.Row="5" Grid.Column="1" Margin="6" FontSize="9" VerticalAlignment="Center"></TextBox>
+                    <Label Grid.Row="6" Grid.Column="0" Margin="2" FontSize="9" VerticalAlignment="Center" Foreground="White">Proxy-Passwort:</Label>
+                    <PasswordBox IsEnabled="{Binding ElementName=cbAktiviert, Path=IsChecked}" Name="txtProxyPasswort" Grid.Row="6" Grid.Column="1" Margin="6" FontSize="9" VerticalAlignment="Center"></PasswordBox>
+                    <Label Grid.Row="7" Grid.Column="0" Margin="2" FontSize="9" VerticalAlignment="Center" Foreground="White">Proxy-Domäne:</Label>
+                    <TextBox IsEnabled="{Binding ElementName=cbAktiviert, Path=IsChecked}" Name="txtProxyDomäne" Grid.Row="7" Grid.Column="1" Margin="6,6,6,10" FontSize="9" VerticalAlignment="Center"></TextBox>
+                </Grid>
+            </Border>
+            <!--
+            <Border Margin="6" HorizontalAlignment="Left" CornerRadius="10" VerticalAlignment="Top" BorderBrush="Black" BorderThickness="1" Height="145.73">
+                <Border.Effect>
+                    <DropShadowEffect Color="Black" />
+                </Border.Effect>
+                <Border.Background>
+                    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
+                        <GradientStop Color="#FF9EBFDE" Offset=".5"/>
+                        <GradientStop Color="#FF30567A" Offset="1"/>
+                    </LinearGradientBrush>
+                </Border.Background>
+                
+                <Grid>
+                    <Grid.ColumnDefinitions>
+                        <ColumnDefinition Width="38" />
+                        <ColumnDefinition Width="82" />
+                        <ColumnDefinition Width="38" />
+                        <ColumnDefinition Width="82" />
+                        <ColumnDefinition Width="40" />
+                    </Grid.ColumnDefinitions>
+                    <Grid.RowDefinitions>
+                        <RowDefinition Height="27" />
+                        <RowDefinition Height="27" />
+                        <RowDefinition Height="68*" />
+                    </Grid.RowDefinitions>
+                    <Label Grid.ColumnSpan="4" Margin="2" Foreground="White">Verrechnungskonten:</Label>
+                    <Label Grid.Row="1" VerticalContentAlignment="Center" Grid.ColumnSpan="2" Margin="2" Foreground="White">Von:</Label>
+                    <TextBox Grid.Row="1" Grid.Column="1" FontSize="9" VerticalAlignment="Bottom" Margin="6,0,6,4" VerticalContentAlignment="Top" Name="txtVon2" GotFocus="txtVon2_GotFocus" Height="16.863" KeyDown="txtVon2_KeyDown"></TextBox>
+                    <Label Grid.Row="1" Grid.Column="2" VerticalContentAlignment="Center" Margin="0,2,0,0" Foreground="White">Nach:</Label>
+                    <TextBox Grid.Row="1" Grid.Column="3" FontSize="9" VerticalAlignment="Bottom" Margin="6,0,6,4" VerticalContentAlignment="Top" Name="txtNach2" GotFocus="txtNach2_GotFocus" KeyDown="txtNach2_KeyDown" Height="16.863"></TextBox>
+                    <Button Template="{DynamicResource GlassButton}" Grid.Row="1" Grid.Column="4" Margin="6,0,6,0" HorizontalAlignment="Center" Width="21" Click="butPlus2_Click" Height="20" Name="butPlus2" Foreground="White">+</Button>
+                    <ListBox Grid.Row="2" Grid.ColumnSpan="4" Margin="6,6,6,8.999" Name="lbÜbersetzungen2" MaxHeight="Infinity" MinHeight="20">
+
+                    </ListBox>
+                    <Button Template="{DynamicResource GlassButton}" Grid.Row="2" Grid.Column="4" Margin="6" HorizontalAlignment="Center" Width="21" Click="butMinus2_Click" Name="butMinus2" VerticalAlignment="Top" Height="20" Foreground="White">-</Button>
+                </Grid>
+            </Border>-->
+
+            <Border Margin="6" HorizontalAlignment="Left" CornerRadius="10" VerticalAlignment="Top" BorderBrush="Black" BorderThickness="1">
+                <Border.Effect>
+                    <DropShadowEffect Color="Black" />
+                </Border.Effect>
+                <Border.Background>
+                    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
+                        <GradientStop Color="#FF9EBFDE" Offset=".5"/>
+                        <GradientStop Color="#FF30567A" Offset="1"/>
+                    </LinearGradientBrush>
+                </Border.Background>
+                <Grid Width="221" Height="142">
+                    <Grid.ColumnDefinitions>
+                        <ColumnDefinition Width="72" />
+                        <ColumnDefinition Width="69.813*" />
+                    </Grid.ColumnDefinitions>
+                    <Grid.RowDefinitions>
+                        <RowDefinition Height="28*" />
+                        <RowDefinition Height="28*" />
+                        <RowDefinition Height="28*" />
+                        <RowDefinition Height="28*" />
+                        <RowDefinition Height="28*" />
+                    </Grid.RowDefinitions>
+                    <Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="2" Foreground="White">ODBC-Einstellungen:</Label>
+                    <Label Grid.Row="1" Grid.Column="0" Margin="2" FontSize="9" VerticalAlignment="Center" Height="Auto" Foreground="White">ODBC-Name:</Label>
+                    <TextBox Grid.Row="1" Grid.Column="1" Margin="6" FontSize="9" Name="txtODBCName"></TextBox>
+                    <Label Grid.Row="2" Grid.Column="0" Margin="2" FontSize="9" VerticalAlignment="Center" Height="Auto" Foreground="White">User:</Label>
+                    <TextBox Grid.Row="2" Grid.Column="1" Margin="6" FontSize="9" Name="txtUser"></TextBox>
+                    <Label Grid.Row="3" Grid.Column="0" Margin="2" FontSize="9" VerticalAlignment="Center" Height="Auto" Foreground="White">Passwort:</Label>
+                    <PasswordBox Grid.Row="3" Grid.Column="1" Margin="6,6,6,10" FontSize="9" Name="txtPwd"></PasswordBox>
+                    <Button FontSize="9" Foreground="White" Margin="6,3.131,43,7.269" Template="{DynamicResource GlassButton}" Grid.Column="1" Grid.Row="4" Name="btnOdbcVerbindungTesten" Click="BtnOdbcVerbindungTestenClick">Verbindung testen</Button>
+                </Grid>
+            </Border>
+            
+            <Border Margin="6" HorizontalAlignment="Left" CornerRadius="10" VerticalAlignment="Top" BorderBrush="Black" BorderThickness="1" Width="237">
+                <Border.Effect>
+                    <DropShadowEffect Color="Black" />
+                </Border.Effect>
+                <Border.Background>
+                    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
+                        <!--<GradientStop Color="White" Offset=".5" />
+                        <GradientStop Color="LightBlue" Offset="1" />-->
+                        <GradientStop Color="#FF9EBFDE" Offset=".5"/>
+                        <GradientStop Color="#FF30567A" Offset="1"/>
+                    </LinearGradientBrush>
+                </Border.Background>
+                <Grid>
+                    <Grid.ColumnDefinitions>
+                        <ColumnDefinition Width="56" />
+                        <ColumnDefinition Width="179*" />
+                    </Grid.ColumnDefinitions>
+                    <Grid.RowDefinitions>
+                        <RowDefinition />
+                        <RowDefinition />
+                        <RowDefinition />
+                    </Grid.RowDefinitions>
+                    <Label Grid.ColumnSpan="2" Margin="2" Foreground="White">Bezug der Steuerungsdateien:</Label>
+                    <Label Grid.Row="1" Margin="3,2,0,0" FontSize="9" Grid.ColumnSpan="2" HorizontalAlignment="Left" Width="Auto" VerticalAlignment="Center" Foreground="White">Typ:</Label>
+                    <ComboBox Grid.Row="1" Grid.Column="1" Margin="6,6,10,6" SelectedIndex="0" FontSize="9" VerticalAlignment="Center" Name="cbTyp">
+                        <ComboBoxItem>verzeichnis</ComboBoxItem>
+                        <ComboBoxItem>http</ComboBoxItem>
+                    </ComboBox>
+                    <Label Grid.Row="2" Margin="3,2,0,0" FontSize="9" Grid.ColumnSpan="2" HorizontalAlignment="Left" Width="Auto" VerticalAlignment="Center" Foreground="White">Pfad:</Label>
+                    <TextBox Grid.Row="2" Grid.Column="1" Margin="6,6,10,10" FontSize="9" VerticalAlignment="Center" Name="txtPfad"></TextBox>
+                </Grid>
+            </Border>
+        </WrapPanel>
+        
+        <StackPanel Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Bottom" Height="71.59" Width="144">
+            <Button Template="{DynamicResource GlassButton}" Margin="3" Width="100" FontSize="9" HorizontalAlignment="Right" Click="ButtonClick1" Foreground="White" Height="18">Speichern</Button>
+            <Button Template="{DynamicResource GlassButton}" Margin="3" Width="100" Click="ButtonClick" FontSize="9" HorizontalAlignment="Right" Foreground="White" Height="18">Abbrechen</Button>
+            <Button Template="{DynamicResource GlassButton}" Margin="3" Width="136" FontSize="9" HorizontalAlignment="Right" Click="ButtonClick3" Foreground="White" Height="18">Alte "manuelle" Werte löschen</Button>
+        </StackPanel>
+    </Grid>
+</Window>

+ 243 - 0
View/Einstellungen.xaml.cs

@@ -0,0 +1,243 @@
+using System;
+using System.Data.Odbc;
+using System.IO;
+using System.Windows;
+using System.Windows.Input;
+using GCHR.Mandantenschnittstelle;
+using GCHR.Model;
+
+namespace GCHR.View
+{
+    public partial class Einstellungen
+    {
+        private GchrConfig _gchrConfig;
+
+        public Einstellungen()
+        {
+            InitializeComponent();
+            KonfigurationLaden();
+        }
+
+        private void ButtonClick(object sender, RoutedEventArgs e)
+        {
+            Close();
+        }
+
+        private void KonfigurationLaden()
+        {
+            if (File.Exists(Constants.ConfigDatei))
+            {
+                _gchrConfig = GchrConfig.GetInstance(Constants.ConfigDatei);
+            }
+
+            cbMandant.Text = _gchrConfig.Einstellungen.Mandantenname.ToString();
+            txtHnr.Text = _gchrConfig.Einstellungen.Haendlernummer;
+            txtHändlerKontenrahmen.Text = _gchrConfig.Einstellungen.Haendlerkontenrahmen.ToString();
+            txtHerstellerKontenrahmen.Text = _gchrConfig.Einstellungen.Herstellerkontenrahmen.ToString();
+            txtHauptmarke.Text = _gchrConfig.Einstellungen.Hauptmarke;
+            txtHauptbetrieb.Text = _gchrConfig.Einstellungen.Hauptbetrieb;
+            txtGeschäftsjahr.Text = _gchrConfig.Einstellungen.Geschaeftsjahr;
+
+            cbAktiviert.IsChecked = _gchrConfig.Einstellungen.Update.IsActive;
+            txtUpdateadresse.Text = Constants.Decrypt(_gchrConfig.Einstellungen.Update.Dateipfad);
+            txtProxyAdresse.Text = Constants.Decrypt(_gchrConfig.Einstellungen.Update.Proxy.Adresse);
+            txtProxyPort.Text = Constants.Decrypt(_gchrConfig.Einstellungen.Update.Proxy.Port);
+            txtProxyBenutzer.Text = Constants.Decrypt(_gchrConfig.Einstellungen.Update.Proxy.Benutzer);
+            txtProxyPasswort.Password = Constants.Decrypt(_gchrConfig.Einstellungen.Update.Proxy.Passwort);
+            txtProxyDomäne.Text = Constants.Decrypt(_gchrConfig.Einstellungen.Update.Proxy.Domaene);
+
+            txtODBCName.Text = _gchrConfig.Einstellungen.Odbc;
+            txtUser.Text = Constants.Decrypt(_gchrConfig.Einstellungen.OdbcUsername);
+            txtPwd.Password = Constants.Decrypt(_gchrConfig.Einstellungen.OdbcPassword);
+
+            cbTyp.Text = _gchrConfig.Einstellungen.Steuerungsdateien.Typ;
+            txtPfad.Text = _gchrConfig.Einstellungen.Steuerungsdateien.Pfad;
+
+            foreach (var eintrag in _gchrConfig.Einstellungen.DepartmentUebersetzung)
+            {
+                lbÜbersetzungen.Items.Add(eintrag.Von + ": " + eintrag.Nach);
+            }
+
+            /*
+            IEnumerable<XElement> Verrechnungsktos = Einstellungen.Element("Verrechnungskonten").Elements("Konto");
+
+            foreach (XElement element in Verrechnungsktos)
+            {
+                lbÜbersetzungen2.Items.Add(element.Attribute("von").Value + ": " + element.Attribute("nach").Value);
+            }
+             */
+        }
+
+        private void ButtonClick1(object sender, RoutedEventArgs e)
+        {
+            _gchrConfig.Einstellungen.Mandantenname = (Mandanten)Enum.Parse(typeof(Mandanten), cbMandant.Text);
+            _gchrConfig.Einstellungen.Haendlernummer = txtHnr.Text;
+            _gchrConfig.Einstellungen.Haendlerkontenrahmen = Int32.Parse(txtHändlerKontenrahmen.Text);
+            _gchrConfig.Einstellungen.Herstellerkontenrahmen = Int32.Parse(txtHerstellerKontenrahmen.Text);
+            _gchrConfig.Einstellungen.Hauptmarke = txtHauptmarke.Text;
+            _gchrConfig.Einstellungen.Hauptbetrieb = txtHauptbetrieb.Text;
+            _gchrConfig.Einstellungen.Geschaeftsjahr = txtGeschäftsjahr.Text;
+
+            if (cbAktiviert.IsChecked != null) _gchrConfig.Einstellungen.Update.IsActive = (bool)cbAktiviert.IsChecked;
+            _gchrConfig.Einstellungen.Update.Dateipfad = Constants.Encrypt(txtUpdateadresse.Text);
+            _gchrConfig.Einstellungen.Update.Proxy.Adresse = Constants.Encrypt(txtProxyAdresse.Text);
+            _gchrConfig.Einstellungen.Update.Proxy.Port = Constants.Encrypt(txtProxyPort.Text);
+            _gchrConfig.Einstellungen.Update.Proxy.Benutzer = Constants.Encrypt(txtProxyBenutzer.Text);
+            _gchrConfig.Einstellungen.Update.Proxy.Passwort = Constants.Encrypt(txtProxyPasswort.Password);
+            _gchrConfig.Einstellungen.Update.Proxy.Domaene = Constants.Encrypt(txtProxyDomäne.Text);
+
+            _gchrConfig.Einstellungen.Odbc = txtODBCName.Text;
+            _gchrConfig.Einstellungen.OdbcUsername = Constants.Encrypt(txtUser.Text);
+            _gchrConfig.Einstellungen.OdbcPassword = Constants.Encrypt(txtPwd.Password);
+
+            _gchrConfig.Einstellungen.Steuerungsdateien.Typ = cbTyp.Text;
+            _gchrConfig.Einstellungen.Steuerungsdateien.Pfad = txtPfad.Text;
+
+            _gchrConfig.Einstellungen.DepartmentUebersetzung.Clear();
+            foreach (var eintrag in lbÜbersetzungen.Items)
+            {
+                var split = eintrag.ToString().Split(':');
+                _gchrConfig.Einstellungen.DepartmentUebersetzung.Add(new UebersetzungXml() { Von = split[0].Trim(), Nach = split[1].Trim() });
+            }
+
+            _gchrConfig.Save();
+            Close();
+        }
+
+        private void ButtonClick2(object sender, RoutedEventArgs e)
+        {
+            lbÜbersetzungen.Items.Add(txtVon.Text + ": " + txtNach.Text);
+
+            txtVon.Clear();
+            txtNach.Clear();
+
+            txtVon.Focus();
+        }
+
+        private void TxtVonGotFocus(object sender, RoutedEventArgs e)
+        {
+            txtVon.SelectAll();
+        }
+
+        private void TxtNachGotFocus(object sender, RoutedEventArgs e)
+        {
+            txtNach.SelectAll();
+        }
+
+        private void TxtVonKeyDown(object sender, KeyEventArgs e)
+        {
+            if (e.Key != Key.Return) return;
+            if (!txtVon.Text.Trim().Equals(""))
+                txtNach.Focus();
+            else
+            {
+                MessageBox.Show("Das \"Von\"-Feld darf nicht leer sein.", "Hinweis", MessageBoxButton.OK, MessageBoxImage.Information);
+            }
+        }
+
+        private void TxtNachKeyDown(object sender, KeyEventArgs e)
+        {
+            if (e.Key != Key.Return || e.IsRepeat) return;
+            if (!txtNach.Text.Trim().Equals(""))
+                if (!txtVon.Text.Trim().Equals(""))
+                    ButtonClick2(sender, e);
+                else
+                {
+                    MessageBox.Show("Das \"Von\"-Feld darf nicht leer sein.", "Hinweis", MessageBoxButton.OK, MessageBoxImage.Information);
+                    txtVon.Focus();
+                }
+            else
+            {
+                MessageBox.Show("Das \"Nach\"-Feld darf nicht leer sein.", "Hinweis", MessageBoxButton.OK, MessageBoxImage.Information);
+            }
+        }
+
+        private void ButMinusClick(object sender, RoutedEventArgs e)
+        {
+            if (lbÜbersetzungen.SelectedIndex > -1)
+            {
+                lbÜbersetzungen.Items.RemoveAt(lbÜbersetzungen.SelectedIndex);
+            }
+        }
+
+        private void ButtonClick3(object sender, RoutedEventArgs e)
+        {
+            if (_gchrConfig.Konten != null) _gchrConfig.Konten.Clear();
+        }
+
+        private void TxtVon2KeyDown(object sender, KeyEventArgs e)
+        {
+            /*
+            if (e.Key == Key.Return)
+                if (!txtVon2.Text.Trim().Equals(""))
+                    txtNach2.Focus();
+                else
+                {
+                    MessageBox.Show("Das \"Von\"-Feld darf nicht leer sein.", "Hinweis", MessageBoxButton.OK, MessageBoxImage.Information);
+                }
+             */
+        }
+
+        private void TxtNach2KeyDown(object sender, KeyEventArgs e)
+        {
+            /*
+            if (e.Key == Key.Return && !e.IsRepeat)
+                if (!txtNach2.Text.Trim().Equals(""))
+                    if (!txtVon2.Text.Trim().Equals(""))
+                        butPlus2_Click(sender, e);
+                    else
+                    {
+                        MessageBox.Show("Das \"Von\"-Feld darf nicht leer sein.", "Hinweis", MessageBoxButton.OK, MessageBoxImage.Information);
+                        txtVon.Focus();
+                    }
+                else
+                {
+                    MessageBox.Show("Das \"Nach\"-Feld darf nicht leer sein.", "Hinweis", MessageBoxButton.OK, MessageBoxImage.Information);
+                }
+             */
+        }
+
+        private void ButPlus2Click(object sender, RoutedEventArgs e)
+        {
+            /*
+            lbÜbersetzungen2.Items.Add(txtVon2.Text + ": " + txtNach2.Text);
+
+            txtVon2.Clear();
+            txtNach2.Clear();
+
+            txtVon2.Focus();
+             */
+        }
+
+        private void ButMinus2Click(object sender, RoutedEventArgs e)
+        {
+            /*
+            if (lbÜbersetzungen2.SelectedIndex > -1)
+            {
+                lbÜbersetzungen2.Items.RemoveAt(lbÜbersetzungen2.SelectedIndex);
+            }
+             */
+        }
+
+        private void BtnOdbcVerbindungTestenClick(object sender, RoutedEventArgs e)
+        {
+            try
+            {
+                var con = new OdbcConnection(OdbcConnectionString());
+                con.Open();
+                con.Close();
+                MessageBox.Show("Verbindung erfolgreich.");
+            }
+            catch (Exception exc)
+            {
+                MessageBox.Show("Verbindung fehlgeschlagen.\nDetails:\n" + exc.Message);
+            }
+
+        }
+
+        private string OdbcConnectionString()
+        {
+            return (string.Format("DSN={0};UID={1};PWD={2};", txtODBCName.Text, txtUser.Text, txtPwd.Password));
+        }
+    }
+}

+ 84 - 0
View/ManuelleKontenBearbeiten.xaml

@@ -0,0 +1,84 @@
+<Window x:Class="GCHR.View.ManuelleKontenBearbeiten"
+    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+    xmlns:local="clr-namespace:GCHR"
+    x:Name="root"
+    Title="Manuelle Konten bearbeiten" Height="480" Width="780">
+
+    <Grid Name="GridManuelle">
+        <Grid.Background>
+            <LinearGradientBrush StartPoint="0,1" EndPoint="0,0">
+                <GradientStop Color="#FF9EBFDE" Offset=".5"/>
+                <GradientStop Color="#FF30567A" Offset="1"/>
+            </LinearGradientBrush>
+        </Grid.Background>
+        <Label Margin="12,12,12,0" VerticalAlignment="Top" Foreground="White">Bitte geben Sie die aktuellen Werte für die manuellen Konten ein:</Label>
+
+        <ListView Name="lvManuelle" Opacity="1.0" Margin="12,36,12,42" Focusable="True" KeyboardNavigation.TabNavigation="Continue" HorizontalContentAlignment="Stretch">
+            <ListView.ItemContainerStyle>
+                <Style TargetType="{x:Type ListViewItem}">
+                    <Setter Property="IsTabStop" Value="False" />
+                    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
+                    <Setter Property="VerticalContentAlignment" Value="Stretch" />
+                </Style>
+            </ListView.ItemContainerStyle>
+
+            <ListView.View>
+                <GridView AllowsColumnReorder="False">
+                    <GridViewColumn Width="90" Header="Kontonummer">
+                        <GridViewColumn.CellTemplate>
+                            <DataTemplate>
+                                <Label HorizontalContentAlignment="Left" VerticalAlignment="Center" Content="{Binding Path=Kontonummer}" FontSize="18" />
+                            </DataTemplate>
+                        </GridViewColumn.CellTemplate>
+                    </GridViewColumn>
+                    <GridViewColumn Header="Beschriftung">
+                        <GridViewColumn.CellTemplate>
+                            <DataTemplate>
+                                <Grid>
+                                    <Grid.ColumnDefinitions>
+                                        <ColumnDefinition />
+                                    </Grid.ColumnDefinitions>
+                                    <Grid.RowDefinitions>
+                                        <RowDefinition />
+                                        <RowDefinition />
+                                    </Grid.RowDefinitions>
+
+                                    <Label HorizontalContentAlignment="Left" Content="{Binding Path=Bezeichnung}" FontSize="12" />
+                                    <WrapPanel Grid.Row="1" TextElement.FontSize="9">
+                                        <TextBox HorizontalContentAlignment="Right" IsReadOnly="True" IsTabStop="False" TextAlignment="Right" Width="70" Cursor="Hand" Text="{Binding Path=Vormonat5, Mode=OneWay}" ToolTip="{Binding ElementName=root, Path=Vormonat5, Mode=OneWay}" GotFocus="VormonatGotFocus" />
+                                        <TextBox HorizontalContentAlignment="Right" IsReadOnly="True" IsTabStop="False" TextAlignment="Right" Width="70" Cursor="Hand" Text="{Binding Path=Vormonat4, Mode=OneWay}" ToolTip="{Binding ElementName=root, Path=Vormonat4, Mode=OneWay}" GotFocus="VormonatGotFocus" />
+                                        <TextBox HorizontalContentAlignment="Right" IsReadOnly="True" IsTabStop="False" TextAlignment="Right" Width="70" Cursor="Hand" Text="{Binding Path=Vormonat3, Mode=OneWay}" ToolTip="{Binding ElementName=root, Path=Vormonat3, Mode=OneWay}" GotFocus="VormonatGotFocus" />
+                                        <TextBox HorizontalContentAlignment="Right" IsReadOnly="True" IsTabStop="False" TextAlignment="Right" Width="70" Cursor="Hand" Text="{Binding Path=Vormonat2, Mode=OneWay}" ToolTip="{Binding ElementName=root, Path=Vormonat2, Mode=OneWay}" GotFocus="VormonatGotFocus" />
+                                        <TextBox HorizontalContentAlignment="Right" IsReadOnly="True" IsTabStop="False" TextAlignment="Right" Width="70" Cursor="Hand" Text="{Binding Path=Vormonat1, Mode=OneWay}" ToolTip="{Binding ElementName=root, Path=Vormonat1, Mode=OneWay}" GotFocus="VormonatGotFocus" />
+                                    </WrapPanel>
+                                </Grid>                                
+                            </DataTemplate>
+                        </GridViewColumn.CellTemplate>
+                    </GridViewColumn>
+                    <GridViewColumn Width="100" Header="Aktuelle Periode">
+                        <GridViewColumn.CellTemplate>
+                            <DataTemplate>
+                                <TextBox HorizontalContentAlignment="Right" Text="{Binding Path=Saldo, Mode=TwoWay}" GotFocus="TextBoxGotFocus" TextAlignment="Right" FontSize="12" VerticalAlignment="Top" Width="90" />
+                            </DataTemplate>
+                        </GridViewColumn.CellTemplate>
+                    </GridViewColumn>
+                    <!--<GridViewColumn Width="100" Header="Vormonat">
+                        <GridViewColumn.CellTemplate>
+                            <DataTemplate>
+                                <TextBox HorizontalContentAlignment="Right" Text="{Binding Path=Vormonat, StringFormat=\{0:0.00\}, Mode=OneTime}" BorderThickness="0" TextAlignment="Right" FontSize="9" Focusable="False" IsTabStop="False" IsReadOnly="True" IsEnabled="True" />
+                            </DataTemplate>
+                        </GridViewColumn.CellTemplate>
+                    </GridViewColumn>-->
+                </GridView>
+            </ListView.View>
+        </ListView>
+
+        <WrapPanel VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="12,0,12,6">
+            <Button Margin="3" Width="80" Height="24" Template="{DynamicResource GlassButton}" Click="BtnManuelleDruckenClick"  Foreground="White" Name="btnManuelleDrucken">Drucken</Button>
+            <Button Margin="3" Width="80" Height="24" Template="{DynamicResource GlassButton}" Click="BtnManuelleAusblendenClick" Foreground="White" Name="btnManuelleAusblenden">Ausblenden</Button>
+            <Button Margin="3" Width="80" Height="24" Template="{DynamicResource GlassButton}" Click="BtnManuelleIgnorierenClick" Foreground="White" Name="btnManuelleIgnorieren">Ignorieren</Button>
+            <Button Margin="3" Width="80" Height="24" Template="{DynamicResource GlassButton}" Click="BtnManuelleSpeichernClick" Name="btnManuelleSpeichern" Foreground="White">Speichern</Button>
+        </WrapPanel>
+    </Grid>
+</Window>

+ 104 - 0
View/ManuelleKontenBearbeiten.xaml.cs

@@ -0,0 +1,104 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+using GCHR.Control.Printing;
+using GCHR.Model;
+using GCHR.Model.Konto;
+
+namespace GCHR.View
+{
+    public partial class ManuelleKontenBearbeiten
+    {
+        delegate void DelAsyncWindowAction();
+
+        public string Vormonat1 { get { return new Periode(HaendlerKonto.AktuellePeriode.Vormonat(1)).Klartext; } }
+        public string Vormonat2 { get { return new Periode(HaendlerKonto.AktuellePeriode.Vormonat(2)).Klartext; } }
+        public string Vormonat3 { get { return new Periode(HaendlerKonto.AktuellePeriode.Vormonat(3)).Klartext; } }
+        public string Vormonat4 { get { return new Periode(HaendlerKonto.AktuellePeriode.Vormonat(4)).Klartext; } }
+        public string Vormonat5 { get { return new Periode(HaendlerKonto.AktuellePeriode.Vormonat(5)).Klartext; } }
+
+        public List<HaendlerKonto> ManuelleKonten;
+
+
+        public ManuelleKontenBearbeiten(IEnumerable<HaendlerKonto> konten)
+        {
+            ManuelleKonten = (from kto in konten orderby kto.Ebene1, kto.Kontonummer select kto).ToList();
+
+            InitializeComponent();
+            lvManuelle.ItemsSource = ManuelleKonten;
+        }
+
+        private void BtnManuelleAusblendenClick(object sender, RoutedEventArgs e)
+        {
+            return;
+        }
+
+        private void BtnManuelleIgnorierenClick(object sender, RoutedEventArgs e)
+        {
+            btnManuelleIgnorieren.IsEnabled = false;
+            btnManuelleSpeichern.IsEnabled = false;
+
+            Close();
+        }
+
+        private void BtnManuelleSpeichernClick(object sender, RoutedEventArgs e)
+        {
+            btnManuelleIgnorieren.IsEnabled = false;
+            btnManuelleSpeichern.IsEnabled = false;
+
+            Close();
+        }
+
+        private void BtnManuelleDruckenClick(object sender, RoutedEventArgs e)
+        {
+            DelAsyncWindowAction drucken = delegate
+                                               {
+                                                   var kontenAktuelleWerte =
+                                                       (List<HaendlerKonto>) lvManuelle.Items.SourceCollection;
+                                                       //ItemsSource;
+                                                   var kontenVormonatswerte =
+                                                       (List<HaendlerKonto>) lvManuelle.ItemsSource;
+                                                   var konten = kontenAktuelleWerte.Join(kontenVormonatswerte,
+                                                                                         k1 => k1.Kontonummer,
+                                                                                         k2 => k2.Kontonummer,
+                                                                                         (k1, k2) =>
+                                                                                         new HaendlerKonto(
+                                                                                             KontoTypen.Stat)
+                                                                                             {
+                                                                                                 Kontonummer =
+                                                                                                     k1.Kontonummer,
+                                                                                                 Bezeichnung =
+                                                                                                     k1.Bezeichnung,
+                                                                                                 Soll = k1.Soll,
+                                                                                                 Haben = k2.Haben
+                                                                                             }).ToList();
+
+
+                                                   var printDialog = new PrintDialog();
+                                                   if (printDialog.ShowDialog() != true) return;
+                                                   var paginator =
+                                                       new RandomTabularPaginator(
+                                                           HaendlerKonto.AktuellePeriode.ToString(),
+                                                           HaendlerKonto.AktuellePeriode.ToString(), konten,
+                                                           new Size(printDialog.PrintableAreaWidth,
+                                                                    printDialog.PrintableAreaHeight));
+
+                                                   printDialog.PrintDocument(paginator,
+                                                                             "GlobalCube Herstellerreporting - Manuelle Werte");
+                                               };
+
+            Dispatcher.BeginInvoke(drucken, null);
+        }
+
+        private void TextBoxGotFocus(object sender, RoutedEventArgs e)
+        {
+            ((TextBox)sender).SelectAll();
+        }
+
+        private void VormonatGotFocus(object sender, RoutedEventArgs e)
+        {
+            MessageBox.Show(((TextBox)sender).Text);
+        }
+    }
+}

+ 207 - 0
_UpgradeReport_Files/UpgradeReport.css

@@ -0,0 +1,207 @@
+BODY
+{
+	BACKGROUND-COLOR: white;
+	FONT-FAMILY: "Verdana", sans-serif;
+	FONT-SIZE: 100%;
+	MARGIN-LEFT: 0px;
+	MARGIN-TOP: 0px
+}
+P
+{
+	FONT-FAMILY: "Verdana", sans-serif;
+	FONT-SIZE: 70%;
+	LINE-HEIGHT: 12pt;
+	MARGIN-BOTTOM: 0px;
+	MARGIN-LEFT: 10px;
+	MARGIN-TOP: 10px
+}
+.note
+{
+	BACKGROUND-COLOR:  #ffffff;
+	COLOR: #336699;
+	FONT-FAMILY: "Verdana", sans-serif;
+	FONT-SIZE: 100%;
+	MARGIN-BOTTOM: 0px;
+	MARGIN-LEFT: 0px;
+	MARGIN-TOP: 0px;
+	PADDING-RIGHT: 10px
+}
+.infotable
+{
+	BACKGROUND-COLOR: #f0f0e0;
+	BORDER-BOTTOM: #ffffff 0px solid;
+	BORDER-COLLAPSE: collapse;
+	BORDER-LEFT: #ffffff 0px solid;
+	BORDER-RIGHT: #ffffff 0px solid;
+	BORDER-TOP: #ffffff 0px solid;
+	FONT-SIZE: 70%;
+	MARGIN-LEFT: 10px
+}
+.issuetable
+{
+	BACKGROUND-COLOR: #ffffe8;
+	BORDER-COLLAPSE: collapse;
+	COLOR: #000000;
+	FONT-SIZE: 100%;
+	MARGIN-BOTTOM: 10px;
+	MARGIN-LEFT: 13px;
+	MARGIN-TOP: 0px
+}
+.issuetitle
+{
+	BACKGROUND-COLOR: #ffffff;
+	BORDER-BOTTOM: #dcdcdc 1px solid;
+	BORDER-TOP: #dcdcdc 1px;
+	COLOR: #003366;
+	FONT-WEIGHT: normal
+}
+.header
+{
+	BACKGROUND-COLOR: #cecf9c;
+	BORDER-BOTTOM: #ffffff 1px solid;
+	BORDER-LEFT: #ffffff 1px solid;
+	BORDER-RIGHT: #ffffff 1px solid;
+	BORDER-TOP: #ffffff 1px solid;
+	COLOR: #000000;
+	FONT-WEIGHT: bold
+}
+.issuehdr
+{
+	BACKGROUND-COLOR: #E0EBF5;
+	BORDER-BOTTOM: #dcdcdc 1px solid;
+	BORDER-TOP: #dcdcdc 1px solid;
+	COLOR: #000000;
+	FONT-WEIGHT: normal
+}
+.issuenone
+{
+	BACKGROUND-COLOR: #ffffff;
+	BORDER-BOTTOM: 0px;
+	BORDER-LEFT: 0px;
+	BORDER-RIGHT: 0px;
+	BORDER-TOP: 0px;
+	COLOR: #000000;
+	FONT-WEIGHT: normal
+}
+.content
+{
+	BACKGROUND-COLOR: #e7e7ce;
+	BORDER-BOTTOM: #ffffff 1px solid;
+	BORDER-LEFT: #ffffff 1px solid;
+	BORDER-RIGHT: #ffffff 1px solid;
+	BORDER-TOP: #ffffff 1px solid;
+	PADDING-LEFT: 3px
+}
+.issuecontent
+{
+	BACKGROUND-COLOR: #ffffff;
+	BORDER-BOTTOM: #dcdcdc 1px solid;
+	BORDER-TOP: #dcdcdc 1px solid;
+	PADDING-LEFT: 3px
+}
+A:link
+{
+	COLOR: #cc6633;
+	TEXT-DECORATION: underline
+}
+A:visited
+{
+	COLOR: #cc6633;
+}
+A:active
+{
+	COLOR: #cc6633;
+}
+A:hover
+{
+	COLOR: #cc3300;
+	TEXT-DECORATION: underline
+}
+H1
+{
+	BACKGROUND-COLOR: #003366;
+	BORDER-BOTTOM: #336699 6px solid;
+	COLOR: #ffffff;
+	FONT-SIZE: 130%;
+	FONT-WEIGHT: normal;
+	MARGIN: 0em 0em 0em -20px;
+	PADDING-BOTTOM: 8px;
+	PADDING-LEFT: 30px;
+	PADDING-TOP: 16px
+}
+H2
+{
+	COLOR: #000000;
+	FONT-SIZE: 80%;
+	FONT-WEIGHT: bold;
+	MARGIN-BOTTOM: 3px;
+	MARGIN-LEFT: 10px;
+	MARGIN-TOP: 20px;
+	PADDING-LEFT: 0px
+}
+H3
+{
+	COLOR: #000000;
+	FONT-SIZE: 80%;
+	FONT-WEIGHT: bold;
+	MARGIN-BOTTOM: -5px;
+	MARGIN-LEFT: 10px;
+	MARGIN-TOP: 20px
+}
+H4
+{
+	COLOR: #000000;
+	FONT-SIZE: 70%;
+	FONT-WEIGHT: bold;
+	MARGIN-BOTTOM: 0px;
+	MARGIN-TOP: 15px;
+	PADDING-BOTTOM: 0px
+}
+UL
+{
+	COLOR: #000000;
+	FONT-SIZE: 70%;
+	LIST-STYLE: square;
+	MARGIN-BOTTOM: 0pt;
+	MARGIN-TOP: 0pt
+}
+OL
+{
+	COLOR: #000000;
+	FONT-SIZE: 70%;
+	LIST-STYLE: square;
+	MARGIN-BOTTOM: 0pt;
+	MARGIN-TOP: 0pt
+}
+LI
+{
+	LIST-STYLE: square;
+	MARGIN-LEFT: 0px
+}
+.expandable
+{
+	CURSOR: hand
+}
+.expanded
+{
+	color: black
+}
+.collapsed
+{
+	DISPLAY: none
+}
+.foot
+{
+BACKGROUND-COLOR: #ffffff;
+BORDER-BOTTOM: #cecf9c 1px solid;
+BORDER-TOP: #cecf9c 2px solid
+}
+.settings
+{
+MARGIN-LEFT: 25PX;
+}
+.help
+{
+TEXT-ALIGN: right;
+margin-right: 10px;
+}

+ 232 - 0
_UpgradeReport_Files/UpgradeReport.xslt

@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
+
+    <xsl:key name="ProjectKey" match="Event" use="@Project"/>
+
+    <xsl:template match="Events" mode="createProjects">
+        <projects>
+            <xsl:for-each select="Event">
+                <!--xsl:sort select="@Project" order="descending"/-->
+                <xsl:if test="(1=position()) or (preceding-sibling::*[1]/@Project != @Project)">
+
+                    <xsl:variable name="ProjectName" select="@Project"/>
+
+                    <project>
+                        <xsl:attribute name="name">
+                            <xsl:value-of select="@Project"/>
+                        </xsl:attribute> 
+
+                        <xsl:if test="@Project=''">
+                        <xsl:attribute name="solution">
+                            <xsl:value-of select="@Solution"/>
+                        </xsl:attribute> 
+                        </xsl:if>
+
+                        <xsl:for-each select="key('ProjectKey', $ProjectName)">
+                            <!--xsl:sort select="@Source" /-->
+                            <xsl:if test="(1=position()) or (preceding-sibling::*[1]/@Source != @Source)">
+
+                                <source>
+                                    <xsl:attribute name="name">
+                                        <xsl:value-of select="@Source"/>
+                                    </xsl:attribute>
+
+                                    <xsl:variable name="Source">
+                                        <xsl:value-of select="@Source"/>
+                                    </xsl:variable>
+
+                                    <xsl:for-each select="key('ProjectKey', $ProjectName)[ @Source = $Source ]">
+
+                                        <event>
+                                            <xsl:attribute name="error-level">
+                                                <xsl:value-of select="@ErrorLevel"/>
+                                            </xsl:attribute> 
+                                            <xsl:attribute name="description">
+                                                <xsl:value-of select="@Description"/>
+                                            </xsl:attribute> 
+                                        </event>
+                                    </xsl:for-each>
+                                </source>
+                            </xsl:if>
+                        </xsl:for-each>
+
+                    </project>
+                </xsl:if>
+            </xsl:for-each>
+        </projects>
+    </xsl:template>
+
+    <xsl:template match="projects">
+    <xsl:for-each select="project">
+    <xsl:sort select="@Name" order="ascending"/>
+        <h2>
+        <xsl:if test="@solution"><a _locID="Solution">Projektmappe</a>: <xsl:value-of select="@solution"/></xsl:if>
+        <xsl:if test="not(@solution)"><a _locID="Project">Projekt</a>: <xsl:value-of select="@name"/>
+            <xsl:for-each select="source">
+                <xsl:variable name="Hyperlink" select="@name"/>
+            <xsl:for-each select="event[@error-level='4']">
+             <A class="note"><xsl:attribute name="HREF"><xsl:value-of select="$Hyperlink"/></xsl:attribute><xsl:value-of select="@description"/></A>
+                </xsl:for-each>
+            </xsl:for-each>
+        </xsl:if>
+        </h2>
+
+        <table cellpadding="2" cellspacing="0" width="98%" border="1" bordercolor="white" class="infotable">
+            <tr>
+                <td nowrap="1" class="header" _locID="Filename">Dateiname</td>
+                <td nowrap="1" class="header" _locID="Status">Status</td>
+                <td nowrap="1" class="header" _locID="Errors">Fehler</td>
+                <td nowrap="1" class="header" _locID="Warnings">Warnungen</td>
+            </tr>
+
+            <xsl:for-each select="source">
+                <xsl:sort select="@name" order="ascending"/>
+                <xsl:variable name="source-id" select="generate-id(.)"/>
+
+                <xsl:if test="count(event)!=count(event[@error-level='4'])">
+
+                <tr class="row">
+                    <td class="content">
+                        <A HREF="javascript:"><xsl:attribute name="onClick">javascript:document.images['<xsl:value-of select="$source-id"/>'].click()</xsl:attribute><IMG border="0" _locID="IMG.alt" _locAttrData="alt" alt="Bereich erweitern/reduzieren" class="expandable" height="11" onclick="changepic()" src="_UpgradeReport_Files/UpgradeReport_Plus.gif" width="9"><xsl:attribute name="name"><xsl:value-of select="$source-id"/></xsl:attribute><xsl:attribute name="child">src<xsl:value-of select="$source-id"/></xsl:attribute></IMG></A> <xsl:value-of select="@name"/> 
+                    </td>
+                    <td class="content">
+                        <xsl:if test="count(event[@error-level='3'])=1">
+                            <xsl:for-each select="event[@error-level='3']">
+                            <xsl:if test="@description='Converted'"><a _locID="Converted1">Konvertiert</a></xsl:if>
+                            <xsl:if test="@description!='Converted'"><xsl:value-of select="@description"/></xsl:if>
+                            </xsl:for-each>
+                        </xsl:if>
+                        <xsl:if test="count(event[@error-level='3'])!=1 and count(event[@error-level='3' and @description='Converted'])!=0"><a _locID="Converted2">Konvertiert</a>
+                        </xsl:if>
+                    </td>
+                    <td class="content"><xsl:value-of select="count(event[@error-level='2'])"/></td>
+                    <td class="content"><xsl:value-of select="count(event[@error-level='1'])"/></td>
+                </tr>
+
+                <tr class="collapsed" bgcolor="#ffffff">
+                    <xsl:attribute name="id">src<xsl:value-of select="$source-id"/></xsl:attribute>
+
+                    <td colspan="7">
+                        <table width="97%" border="1" bordercolor="#dcdcdc" rules="cols" class="issuetable">
+                            <tr>
+                                <td colspan="7" class="issuetitle" _locID="ConversionIssues">Konvertierungsbericht - <xsl:value-of select="@name"/>:</td>
+                            </tr>
+
+                            <xsl:for-each select="event[@error-level!='3']">
+                                <xsl:if test="@error-level!='4'">
+                                <tr>
+                                    <td class="issuenone" style="border-bottom:solid 1 lightgray">
+                                        <xsl:value-of select="@description"/>
+                                    </td>
+                                </tr>
+                                </xsl:if>
+                            </xsl:for-each>
+                        </table>
+                    </td>
+                </tr>
+                </xsl:if>
+            </xsl:for-each>
+
+            <tr valign="top">
+                <td class="foot">
+                    <xsl:if test="count(source)!=1">
+                        <xsl:value-of select="count(source)"/><a _locID="file1"> Dateien</a>
+                    </xsl:if>
+                    <xsl:if test="count(source)=1">
+                        <a _locID="file2">1 Datei</a>
+                    </xsl:if>
+                </td>
+                <td class="foot">
+					<a _locID="Converted3">Konvertiert</a>: <xsl:value-of select="count(source/event[@error-level='3' and @description='Converted'])"/><BR/>
+					<a _locID="NotConverted">Nicht konvertiert</a>: <xsl:value-of select="count(source) - count(source/event[@error-level='3' and @description='Converted'])"/>
+                </td>
+                <td class="foot"><xsl:value-of select="count(source/event[@error-level='2'])"/></td>
+                <td class="foot"><xsl:value-of select="count(source/event[@error-level='1'])"/></td>
+            </tr>
+        </table>
+    </xsl:for-each>
+    </xsl:template>
+
+    <xsl:template match="Property">
+        <xsl:if test="@Name!='Date' and @Name!='Time' and @Name!='LogNumber' and @Name!='Solution'">
+        <tr><td nowrap="1"><b><xsl:value-of select="@Name"/>: </b><xsl:value-of select="@Value"/></td></tr>
+        </xsl:if>
+    </xsl:template>
+
+    <xsl:template match="UpgradeLog">
+        <html>
+            <head>
+                <META HTTP-EQUIV="Content-Type" content="text/html; charset=utf-8"/>
+                <link rel="stylesheet" href="_UpgradeReport_Files\UpgradeReport.css"/>
+                <title _locID="ConversionReport0">Konvertierungsbericht 
+                    <xsl:if test="Properties/Property[@Name='LogNumber']">
+                        <xsl:value-of select="Properties/Property[@Name='LogNumber']/@Value"/>
+                    </xsl:if>
+                </title>
+                <script language="javascript">
+                    function outliner () {
+                        oMe = window.event.srcElement
+                        //get child element
+                        var child = document.all[event.srcElement.getAttribute("child",false)];
+                        //if child element exists, expand or collapse it.
+                        if (null != child)
+                            child.className = child.className == "collapsed" ? "expanded" : "collapsed";
+                    }
+
+                    function changepic() {
+                        uMe = window.event.srcElement;
+                        var check = uMe.src.toLowerCase();
+                        if (check.lastIndexOf("upgradereport_plus.gif") != -1)
+                        {
+                            uMe.src = "_UpgradeReport_Files/UpgradeReport_Minus.gif"
+                        }
+                        else
+                        {
+                            uMe.src = "_UpgradeReport_Files/UpgradeReport_Plus.gif"
+                        }
+                    }
+                </script>
+            </head>
+            <body topmargin="0" leftmargin="0" rightmargin="0" onclick="outliner();">
+                <h1 _locID="ConversionReport">Konvertierungsbericht - <xsl:value-of select="Properties/Property[@Name='Solution']/@Value"/></h1>
+
+                <p><span class="note">
+                <b _locID="TimeOfConversion">Konvertierungsdauer:</b>  <xsl:value-of select="Properties/Property[@Name='Date']/@Value"/>  <xsl:value-of select="Properties/Property[@Name='Time']/@Value"/><br/>
+                </span></p>
+
+                <xsl:variable name="SortedEvents">
+                    <Events>
+                        <xsl:for-each select="Event">
+                            <xsl:sort select="@Project" order="ascending"/>
+                            <xsl:sort select="@Source" order="ascending"/>
+                            <xsl:sort select="@ErrorLevel" order="ascending"/>
+                            <Event>
+                                <xsl:attribute name="Project"><xsl:value-of select="@Project"/> </xsl:attribute> 
+                                <xsl:attribute name="Solution"><xsl:value-of select="/UpgradeLog/Properties/Property[@Name='Solution']/@Value"/> </xsl:attribute> 
+                                <xsl:attribute name="Source"><xsl:value-of select="@Source"/> </xsl:attribute> 
+                                <xsl:attribute name="ErrorLevel"><xsl:value-of select="@ErrorLevel"/> </xsl:attribute> 
+                                <xsl:attribute name="Description"><xsl:value-of select="@Description"/> </xsl:attribute> 
+                            </Event>
+                        </xsl:for-each>     
+                    </Events>
+                </xsl:variable>
+                
+                <xsl:variable name="Projects">
+                    <xsl:apply-templates select="msxsl:node-set($SortedEvents)/*" mode="createProjects"/>
+                </xsl:variable>
+
+                <xsl:apply-templates select="msxsl:node-set($Projects)/*"/>
+
+                <p></p><p>
+                <table class="note">
+                    <tr>
+                        <td nowrap="1">
+                            <b _locID="ConversionSettings">Konvertierungseinstellungen</b>
+                        </td>
+                    </tr>
+                    <xsl:apply-templates select="Properties"/>
+                </table></p>
+            </body>
+        </html>
+    </xsl:template>
+</xsl:stylesheet>

BIN
_UpgradeReport_Files/UpgradeReport_Minus.gif


BIN
_UpgradeReport_Files/UpgradeReport_Plus.gif