Fortuna Entwickler Blog

Hier wird Ihnen geholfen

Import von Versichrungs- und HV/BV-Daten in VENTA

Nach Aufruf des Programm wird die zentrale Benutzeroberfläche angezeigt:

  • VKVO: Hier ist die VKVO des Benutzer/HFB einzutragen. Über diese VKVO werden die Verträge (Versicherung, HV, BV) selektiert.
  • VENTA Benutzername: Hier ist der Benutzername des HFB in VENTA einzutragen. Über den Benutzernamen werden die HV/BV selektiert und die Anmeldung am VENTA-Service zu Übertragung der HV/BV durchgeführt.
  • VENTA Benutzerkennwort: Hier ist das Kennwort des o.a. Benutzers anzugeben. Über das Kennwort wird die Anmeldung am VENTA-Service zu Übertragung der HV/BV durchgeführt.

Die nächsten Auswahlen sind optional. Man kann wählen, ob Versicherungsverträge und/oder HV/BV exportiert werden sollen.

  • Export Versicherungsdaten in CSV: Entsprechend der VKVO werden die Versicherungsverträge zum HFB exportiert. Der Export erfolgt per CSV und kann dann in VENTA über den CSV-Import eingelesen werden. Die CSV-Datei wird unter C:\Temp\Venta_[VKVO]_[Datum].csv abgelegt. Der Pfad ist hierbei konfigurierbar.
  • Export/Import HV/BV Daten per Service: Entsprechend der VKVO und dem Benutzernamen werden HV/BV exportiert und über den VENTA-Service importiert in VENTA.

Schaltfläche Export: Der Export (und ggf. Import) wird entsprechend der angegebenen Daten / gewählten Optionen durchgeführt. Die Schaltfläche ist nur aktiviert/klickbar, wenn eine 6-stellige VKVO eingegeben wurde.

Schaltfläche Schließen: Die Anwendung wird beendet.


NuGet Package Source für myLife Bibliotheken

Zum Testen der Möglichkeiten eines eigenen NuGet Package Servers habe ich selbigen mal - mit Hilfe eines NuGet Packages - erstellt und auf WEBENTW3 gepublished.
Die "Quellen" für den Server habe ich unter Fortuna/Tools/Ares.NuGetServer abgelegt und unter http://webentw3/Ares/myLifeNuGet/ veröffentlicht.

In Visual Studio kann man nun den sogenannten Package Feed hinzufügen:


Im nächsten Schritt habe ich eine unserer Bibliotheken zu einem NuGetPackage gemacht; da es hier keine weiteren Referenzen auf weitere Bibliotheken gab, habe ich Fortuna.Security verwendet.

Hierfür sind im Grunde nur zwei Schritte notwendig. Zum einen benötigt man eine Spezifikationsdatei; hierin werden Informationen zum Package abgelegt, welche dann später im Package Manager (z.B. von Visual Studio ersichtlich sind bzw. nach denen gesucht werden kann. Praktischerweise kann man einige Informationen aus den Projektproperties referenzieren:

<?xml version="1.0"?>
<package >
  <metadata>
    <id>$id$</id>
    <version>$version$</version>
    <title>$title$</title>
    <authors>myLife Lebensversicherung AG</authors>
    <owners>myLife Lebensversicherung AG</owners>
    <licenseUrl>http://webentw3/Fortuna</licenseUrl>
    <projectUrl>http://webentw3/Fortuna</projectUrl>
    <iconUrl>http://webentw3/Ares/myLifeNuGet/logo.ico</iconUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Kryptos myLife</description>
    <releaseNotes>Aktuelle Version der Bibliothek</releaseNotes>
    <copyright>Copyright 2015</copyright>
    <tags>myLife Fortuna Security Kryptologie</tags>
  </metadata>
</package>

Im zweiten Schritt habe ich dem Projekt einen Post Build Event hinzugefügt (Unter Properties -> Build Events):

nuget pack "$(ProjectPath)" -outputdirectory "\\WEBENTW3\inetpub\wwwroot\Ares\myLifeNuGet\Packages" -IncludeReferencedProjects


Wenn das Projekt nun erstellt wird, wird nach erfolgreichem Build das Binary in ein Package gepackt und im angegeben Pfad abgelegt.

Will man nun in einem Projekt das Package verwenden, ruft man wie gewohnt den Package Manger auf, wählt den myLife Feed und wählt das gewünschte Package aus. Fertig.

Vorteil: Man fügt seinem Projekt nur noch jene Bibliothek hinzu, die man tatsächlich benötigt; abhängige Bibliotheken werden automatisch geladen.

Nachteil: Die Bibliothek selbst kann man direkt nicht mehr ändern; hierzu muss man das Projekt der Bibliothek laden, die Änderung durchführen und neu builden.

Was wäre zu noch tun: Alle Bibliotheken müssen wie oben beschrieben bearbeitet werden. Bestehende Referenzen müssen entfernt und dann über NuGet neu gesetzt werden. Also auch Bibliotheken, die andere Bibliotheken referenzieren, müssen diese dann über NuGet referenzieren.

Dokumente im Rahmen des ML-Tschechien-Geschäftes

Posteingänge im Zusammenhang mit unserem Tschechien-Geschäft müssen im VWS erfasst werden. Es ist derzeit nicht möglich, die Verträge selber (mit Ihren Vertragsdaten) in das VWS zu übernehmen. Aus diesem Grund habe ich mit Peter Ellrott folgendes Vorgehen vereinbart:

  • Eingehende Dokumente erhalten eine Dokumenten-Nr. und werden, sofern möglich, entsprechend umbenannt, z. B.
  • výpověď = Kündigung
  • zrušení = Storno
  • přihláška = Antrag
  • Die Dok.-Nr. wir den folgenden Partnern zugeordnet:
  • SCOR Global Life SE, Partner Nr. 559037 und
  • Broker Consulting a. s., Partner Nr. 559038.
  • Beim Scan-Vorgang werden in das freie Textfeld folgende Angaben eingetragen:
  • VSNR
  • Vorname und Name der VP
  • Anschrift, wenn vorhanden
  • Diese ergänzenden Informationen sind für die SB im VWS nicht einsehbar! Christoph Biegner, der das Tschechien-Geschäft von IT-Seite betreut, kann die Daten abrufen.
  • Nach dem Scannen gehen die Original-Posteingänge an Kathrin Delling.
Arbeitsanweisung Dokumentation Tschechien-Geschäft.pdf (13,2KB)

Konzept.pdf (196,2KB)

Passwörter aus PDFs entfernen (KIID)

Alle 30 Tage werden die KIIDs zu allen aktuellen Fonds automatisch nachts geladen. Manche KIIDs sind Passwortgewchützt. Dadurch können sie dann nicht in die Antragsmappe integriert werden; es kommt ein Fehler beim Erstellen der Antragsmappe.

Aus diesem Grund werden bei allen KIIDs morgens nach dem Herunterladen eventuell vorhandene Passwörter entfernt.

Die passiert derzeit mit der Testversion (Triel) von A-PDF Secuity

http://www.a-pdf.com/security/password.htm

Das Vorgehen ist einfach: Programm herunterladen, installieren, aufrufen

Batch-Verarbeitung auswählen -> Next

Add Dir -> KIID-Verzeichnis wählen -> Next -> Save

Das dauert dann ein wenig, weil alle PDFs geprüft werden.

Anschliessend liegen ale KIIDs ungeschützt vor. Fertig.


Testfälle myLife Suite

Testfall: Vorläufiger Status während Anlage

  • Anlegen eines Vertrages in VWS. Die Mailadresse des Versicherungsnehmers sollte die eigene sein bzw. ein, die man jederzeit abrufen kann.

Es wird eine EMail erzeugt. In der Mail befindet sich ein Link, über welchen man den Status des Vertrags abfragen kann. Der Versand dieser Mail kann bis zu 60 Minuten dauern.

  • Auf den Link klicken um den Status des Vertrags abzufragen. Wird der Status korrekt wiedergegeben?
  • Im VWS weitere Tätigkeiten zur Anlage durchführen; Policierung aber noch nicht durchführen.
  • Den Link nochmals aufrufen um den Status des Vertrags abzufragen. Wird der Status korrekt wiedergegeben?
  • Im VWS die Policierung abschließen.
  • Den Link nochmals aufrufen um den Status des Vertrags abzufragen. Wird der Status korrekt wiedergegeben?

Testfall: Anzeige des policierten Vertrags

Nach Abschluss des obigen Testfalls wird eine Mail erzeugt, in welcher der Versicherungnehmer seine Zugangsdaten erhält. In der Mail ist zudem ein Link zur myLife Suite enthalten. Der Versand dieser Mail kann bis zu 60 Minuten dauern.

  • Aufruf des in der Mail enthaltenen Links. Wird die Anmeldeseite der myLifeSuite angezeigt?
  • Anmelden mit den übermittelten Anmeldedaten. Ist die Anmeldung erfolgreich?
  • Letzte Aktivitäten: Gibt es hier einen Eintrag, welcher auf die Policierung hinweist?
  • Ein Eintrag unter Letzte Aktivitäten verlinkt immer auf den jeweiligen Vertrag. Ist dieser Link klickbar und wird daraufhin der Vertrag angezeigt?
  • Sind die angezeigten Informationen korrekt?
  • Sollten zusätzliche Informationen angezeigt werden?

Testfall: Anzeige des policierten Vertrags (Grafiken)

  • Gibt es im angezeigten Vertrag Grafiken?
  • Sind diese aussagekräftig?
  • Gibt es Interaktionsmöglichkeiten in den Grafiken?

Testfall: Anzeige des policierten Vertrags (Dokumente)

  • Sind dem angezeigten Vertrag Dokumente angehängt?
  • Können diese Dokumente geladen und/oder angezeigt werden?
  • Sind die Inhalte der Dokumente korrekt?

Testfall: Versicherungsverträge

  • Gibt es (weitere) Verträge in der Vertragsübersicht?
  • Sind diese Verträge aufrufbar?
  • Zu jedem der Verträge nochmals die Testfälle 'Anzeige des policierten Vertrags' ausführen

Testfall: Downloadcenter

  • Ist der Downloadcenter aufrufbar?
  • Werden dort Formulare zum Abruf angeboten?
  • Gibt es Erläuterungen zu den Formularen und sind diese Inhaltlich und grammatikalisch korrekt?
  • Werden die Formulare geladen und/oder angezeigt?
  • Sind die Formulare korrekt?
  • Sollten weitere Formulare angeboten werden?

Testfall: Persönliche Daten verwalten

  • Sind die Persönlichen Daten aufrufbar?
  • Sind die angezeigten Informationen korrekt?

Bei Änderungen (Ausnahme: Passwort) werden die Daten nicht direkt geändert, sondern es wird eine EMail generiert und an test@mylife-leben.de (In Produktivumgebung: service@mylife-leben.de) geschickt. Die Änderungen selbst müssen dann im VWS vorgenommen werden.

  • Können die Kommunikationsdaten (Telefon, email etc.) geändert werden? Wird eine EMail generiert?
  • Kann die Adresse geändert werden? Wird eine EMail generiert?

Testfall: Persönliche Daten ändern

  • Ändern der Adressdaten und Kommunikationsdaten in VWS.
  • Erneute Anmeldung in myLifeSuite.
  • Aufruf der Persönlichen Daten. Sind die Informationen hier entsprechend der Änderungen in VWS geändert?

Testfall: Kennwort ändern

  • Ändern des persönlichen Kennworts.
  • Abmelden aus myLifeSuite
  • Erneutes Anmelden mit neuem Kennwort
  • War die Anmeldung erfolgreich?

Testfall: Ungelesene Dokumente I

  • Sind nach Anmeldung in der myLifeSuite unter Ungelesene Dokumente Einträge vorhanden?
  • Die Einträger verlinken immer zum jeweiligen Dokument. Ist der Link aufrufbar?
  • Kann das Dokument geladen / angezeigt werden?
  • Wird das Dokument weiterhin unter Ungelesene Dokumente angezeigt?

Testfall: Ungelesene Dokumente II

  • Gibt es in der Vertragsanzeige Dokumente?
  • Sind einzelne oder alle Dokumente in der Anzeige fett geschrieben?
  • Können diese Dokumente geladen / angezeigt werden?
  • Sind diese Dokumente anschließend weiterhin fett geschrieben?


Aktualisierung von DevArt Oracle DLL

Nach einer Übergabe in die Produktonsumgebung wird die aktuelle Version von DevArt geladen und unter \\VCENTER2\Entwickler-Tools\Datenbank\devart abgelegt.
Alle Entwickler aktualisieren daraufhin ihre lokale Installation von DevArt
Zudem wird der Entwicklungsserver //WEBENTW3 und der Buildserver //BUILDSERVER aktualisiert.
Diese Version bleibt dann unverändert und wird nciht im laufenden Entwicklungsprozess erneut aktualisiert.

Zur Übergabe auf die Testumgebung wird DevArt auf dem Testserver //WEBTESTDMZ3 aktualisiert und die Übergabe durchgeführt.

Nach der Übergabe in die Produktionsumgebung wird wieder wie oben verfahren.

Ausnahme von diesem Vorgehen: Es tritt in der Entwicklung ein Fehler auf, welcher auf die aktuell verwendete DevArt-Version schliessen lässt und durch eine neuere DevArt-Version beseitigen lässt. In diesem Falle wird die neue Version von DevArt geladen und unter \\VCENTER2\Entwickler-Tools\Datenbank\devart abgelegt, lokal, auf der Entwicklungsumgebung und dem Buildserver installiert.


Scan Programm

Mit der Umstellung auf DBDok wurde es auch notwendig, die Applikation zum Scannen von Dokumenten zu aktualisieren.

Hierzu wurde eine neue Applikation unter .NET erstellt; die Quellen sind im TFS unter /VWS/Tools/ScanToPDF abgelegt. Die Applikation verwendet iTextSharp (über nuget) und TwaiDotNet (referenziert aus /Fortuna/External/DLL) und zudem DevArt. Bei Letzterem ist darauf zu achten, daß die Lizenzinformationen mitgeliefert werden; dies geschieht in Visual Studio 2013 im Projekt über Tools -> Oracle -> License Information.

Danach kann man einfach eine Version als Release erstellen und das bin/Release-Verzeichnis auf den Ziel-PC kopieren. Ggf. kann man in der app.config noch Optionen anpassen; ansonsten ist die Anwendung sofort einsatzbereit.



Historisierung von Dokumenten in DBDOK

Möglicher Zustand von Dokumenten

1.    Noch nicht gescannt
2.    DOK_CONTAINER_WORK auf GUTINGIA
3.    DOK_CONTAINER auf ARCHIV
4.    DOK_CONTAINER auf DBDOK

Den ersten Punkt kann man ausklammern. Es gibt noch kein gescanntes Dokument.

Bei 2. Wird das existierende Dokument verworfen und durch das neue ersetzt. Dies geschieht quasi zeitgleich. Da sich Dokumente nur sehr kurz in DOK_CONTAINER_WORK befinden, greift dieser Punkt üblicherweise nur, wenn beim Scannen ein Fehler auftrat, z.B. eine Seite nicht gescannt wurde, zwei Seiten auf einmal eingezogen wurden oder Ähnliches.

Bei 3. Und 4. greift dann die eigentliche Behandlung der Historisierung.

Betroffen bei Punkt 3 ist der Prozess, welcher Dokumente aus DOK_CONTAINER_WORK nach DOK_CONTAINER (auf ARCHIV) verschiebt: Gibt es zur DOK_NR bereits einen Eintrag in DOK_CONTAINER (ARCHIV), so wird dieser nach DOK_CONTAINER_HISTORIE (ARCHIV) verschoben und das neue Dokument in DOK_CONTAINER geschrieben. DOK_CONTAINER_HISTORIE hat neben den Felder aus DOK_CONTAINER zudem ein automatisch gesetzten Datumsfeld, sodass auch mehrere gleiche DOK-Nummern korrekt historisiert werden können.

Betroffen bei Punkt 4 ist zudem der Prozess, welcher Dokumente aus DOK_CONTAINER (ARCHIV) nach DOK_CONTAINER (DBDOK) verschiebt: Gibt es zur DOK_NR bereits einen Eintrag in DOK_CONTAINER (DBDOK), so wird dieser nach DOK_CONTAINER_HISTORIE (DBDOK) verschoben und das neue Dokument in DOK_CONTAINER geschrieben. DOK_CONTAINER_HISTORIE hat neben den Felder aus DOK_CONTAINER zudem ein automatisch gesetzten Datumsfeld, sodass auch mehrere gleiche DOK-Nummern korrekt historisiert werden können.

In diesem Zuge sind auch sämtliche Einträge aus DOK_CONTAINER_HISTORIE (ARCHIV) nach DOK_CONTAINER_HISTORIE (DBDOK) zu verschieben.

ToDo:

  • Erstellen von DOK_CONTAINER_HISTORIE auf ARCHIV
  • Erstellen von DOK_CONTAINER_HISTORIE auf DBDOK
  • Anpassen des Prozesses beim Speichern eingescannter Dokumente
  • Erweitern des Prozesses bei Übernahme der Dokumente aus DOK_CONTAINER_WORK nach DOK_CONTAINER (ARCHIV)
  • Erstellen des Prozesses bei Übernahme der Dokumente aus DOK_CONTAINER (ARCHIV) nach DOK_CONTAINER (DBDOK)


DBDOK Abläufe.xlsx (14KB)

Hier habe ich die Abläufe dokumentiert, wie ich sie für möglich halte.
Tabellenblatt Variante 1 ist die ursprünglich gedachte Vorgehensweise; Tabellenblatt Variante 2 ist jene, die entsprechend dem Vorschlag von Torsten notwendig wäre. Änderungen im Vorgehen sind dort blau markiert.

Die Abläufe im Einzelnen:

  1. Einscannen, nochmal Einscannen vor Übertragung, Übertragung, Archivierung. Also: was passiert, wenn ein Dokument kurz nach dem Einscannen nochmal eingescannt wird.
  2. Einscannen, Übertragen, nochmal Einscannen, wieder Übertragen, Archivieren. Also: was passiert, wenn ein Dokument, welches bereits übertragen wurde, nochmals eingescannt wird.
  3. Einscannen, Übertragen, nochmal Einscannen, wieder Übertragen, nochmal Einscannen, wieder Übertragen, Archivieren. Also, was passiert, wenn ein Dokument mehrfach nach der Übertragung nochmals eingescannt wird.
  4. Einscannen, Übertragen, nochmal Einscannen, wieder Übertragen, Archivieren, nochmal Einscannen, wieder Übertragen, Archivieren. Also wie unter 3. aber dieses mal wird anschließend noch ein weiteres Mal eingescannt.
  5. Einscannen, Übertragen, nochmal Einscannen, wieder Übertragen, Archivieren, nochmal Einscannen, wieder Übertragen, nochmal Einscannen, wieder Übertragen, Archivieren. Also: Wie unter 4. aber es wird nach der ersten Archivierung noch mehrfach eingescannt.


HK by gut beraten

Gelegentlich ist für HK eine Auswertung zu erstellen, kurz genannt 'HK by gut beraten'.

Hierfür wird eine Liste von Personen (aus der IWM Datenbank) selektiert, welche im ebenso benannten Kommunikationsfeld einen Eintrag haben.

SELECT prs.CNAME, prs.CVORNAME,
tel.CNUMMER
FROM ADRESSEN adr
INNER JOIN PERSON prs ON adr.NPERSON = prs.NVIRTNR
INNER JOIN TELECOM tel ON tel.NCOMART = '11110000000022' AND tel.NADRESSEN = adr.NVIRTNR
WHERE adr.NCOMART00 = '11110000000022'
OR adr.NCOMART01 = '11110000000022'
OR adr.NCOMART02 = '11110000000022'
OR adr.NCOMART03 = '11110000000022'
OR adr.NCOMART04 = '11110000000022'
OR adr.NCOMART05 = '11110000000022'
OR adr.NCOMART06 = '11110000000022'
OR adr.NCOMART07 = '11110000000022'
OR adr.NCOMART08 = '11110000000022'
OR adr.NCOMART09 = '11110000000022'
ORDER BY prs.CNAME, prs.CVORNAME;

Mit der letzten Auswertung wurde hier eine weiter Information benötigt, die Kategorie des Mitarbeiters. Aufgrund des Aufbaus der Daten machte das sie Auswertung deutlich komplexer: Die Kategorie ist direkt dem Mitarbeiter zugeordnet; das Kommnikationsfeld ist bisher immer bei einem Ansprechpartner des Mitarbeiters hinterlegt. Beide werden in der Tabelle PERSON geführt, stehen aber in einer Relation zueinander.

Der notwendige Code bleibt dennoch überschaubar:

SELECT	per.CNAME, per.CVORNAME, tel.CNUMMER,
ISNULL(kat.CKATEGORIE, '') AS KATEGORIE
FROM TELECOM tel
INNER JOIN ADRESSEN adr ON tel.NADRESSEN = adr.NVIRTNR
INNER JOIN PERSON per ON adr.NPERSON = per.NVIRTNR
INNER JOIN ANSPRECH ans ON ans.NPERSON = per.NVIRTNR
INNER JOIN PERSON per2 ON ans.NANSPRECH = per2.NVIRTNR
INNER JOIN MITARB mit ON per2.NVIRTNR = mit.NPERSON
LEFT OUTER JOIN KUNDKAT kat ON mit.NKUNDKAT = kat.NVIRTNR
WHERE tel.NCOMART = '11110000000022';

Die exportierten Daten werden dann als Excel geliefert.

Profiler in Fortuna Tools

Ich habe in die Solution Fortuna.Web.Tools einen Profiler eingebaut. Der Profiler wird derzeit nur auf der Entwicklungs- und Testumgebung aktiviert. In der Produktivumgebung sollte dieser nicht zum Einsatz kommen, da die Profiling-Ergebnisse auf den jeweiligen Seiten eingeblendet werden. Realisiert wird dies über ein Conditional Compiler Symbol (PROFILER_ACTIVE) in den Eigenschaften der Webapplikation. In den Konfigurationen Debug und Test wird dies gesetzt; das sind die Konfigurationen, die beim Publishen auf die Entwicklungsumgebung (Debug) bzw. Testumgebung (Test) verwendet werden.

Verwendet wird der Miniprofiler für .NET, welcher über nuget ins Projekt integriert wurde.

In der global.asax wurden die Anweisungen zum Starten bzw. beenden des Profilers hinzugefügt:

        protected void Application_BeginRequest()
        {
#if PROFILER_ACTIVE
            MiniProfiler.Start();
#endif
        }
        protected void Application_EndRequest()
        {
#if PROFILER_ACTIVE
            MiniProfiler.Stop();
#endif
        }

In der _Layout.cshtml wurde als letzte Zeile im <body> die Ausgabe der Profilerdaten integriert:

@MiniProfiler.RenderIncludes()

In den Controllern kann man dann beliebige Codeblöcke profilen.

Beispiel Homecontroller:

using StackExchange.Profiling;
...
        [Authorize]
        public ActionResult Index()
        {
            var profiler = MiniProfiler.Current;
            using(profiler.Step("Home - Index: Darf Investment"))
            {
                ViewBag.DarfInvestment = DarfInvestment(User.Vermittler().OrgId);
            }
            return View();
        }

Beispiel AccountController:

        [HttpPost]
        public ActionResult Login(LogOnModel logOnModel, string returnUrl)
        {
            var profiler = MiniProfiler.Current;
            using (profiler.Step("Account - Login: Start"))
            {
                if (ModelState.IsValid)
                {
                    using (profiler.Step("Account - Login: SignIn"))
                    {
                        if (AuthenticationHelper.SignIn(logOnModel))
                        {
                            using (profiler.Step("Account - Login: IsCustomer"))
                            {
                                if (AuthenticationHelper.IsCustomer(logOnModel.UserName))
                                {
                                    using (profiler.Step("Account - Login: Logout"))
                                    {
                                        Logout();
                                        ModelState.AddModelError("", Resources.ERR_KUNDE_STATT_VERMITTLER);
                                    }
                                }
                                else
                                {
                                    using (profiler.Step("Account - Login: IsLocalUrl"))
                                    {
                                        if (Url.IsLocalUrl(returnUrl))
                                        {
                                            return Redirect(returnUrl);
                                        }
                                        else
                                        {
                                            return RedirectToAction("Index", "Home");
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            ModelState.AddModelError("", Resources.ERR_BENUTZER_FALSCH);
                        }
                    }
                }
            }
            using (profiler.Step("Account - Login: return View"))
            {
                return View(logOnModel);
            }
        }