// (1) Global d.3 libraries import com.dvelop.d3.server.core.D3Interface import com.dvelop.d3.server.Document import com.dvelop.d3.server.User import com.dvelop.d3.server.Condition import com.dvelop.d3.server.DocumentType import groovy.sql.GroovyRowResult import com.dvelop.d3.server.ValueSet import com.dvelop.d3.server.RepositoryField import java.sql.Timestamp import java.util.Calendar import java.text.SimpleDateFormat // Libraries to handle the different hook types import com.dvelop.d3.server.Entrypoint public class sg02_sozialakte { // Dokumentarten private static String SG02_DS_SOZ_AKTE = "ASOZ"; private static String SG02_DS_SOZ_DOKU = "DSOZ"; private static String G01_DS_POSTEINGANG = ""; // DB-Positionen private static int POS_SACHGEBIET = 1 // Sachgebiet private static int POS_AZ = 2 // Aktenzeichen private static int POS_NACHNAME = 3 // Nachname (HV) private static int POS_VORNAME = 4 // Vorname (HV) private static int POS_STRASSE = 9 // Straße private static int POS_PLZ = 10 // PLZ private static int POS_ZDA = 13 // zdA-verfügt private static int POS_DOKTYP = 14 // Dokumenttyp private static int POS_DOKGRP = 15 // Dokumentgruppe private static int POS_HNR = 16 // Hausnummer private static int POS_ORT = 17 // Ort private static int POS_AUSART = 23 // Aussonderungsart private static int POS_STORNO = 27 // in LISSA storbniert private static int POS_WIDERSPRUCH = 30 // Interne 50-1-4 Widerspruchsnummer private static int POS_AZ_RECHT = 31 // Aktenzeichen Rechtsanwälte private static int POS_LOESCH_FLAG = 33 // zum Löschen markiert private static int POS_GEBURTSDATUM = 50 // Geburtsdatum (HV) private static int POS_AUSSONDDAT = 51 // Aussonderungsdatum private static int POS_LOESCHGRD = 35 // Löschgrund private static int POS_ZLM = 33 // Zum Löschen Markiert // DB Tabellen private static String TB_LISSA_DOKTYP = "CS_LISSA_DOKTYP" // kundenspezifische Werte private static int FRIST_AUSSONDERUNG = 84 // statische Werte (nicht ändern) private static int STATUS_SACHGEBIET = 0 private static int STATUS_ZDA = 0 private static int SG01_SCHALTER_POST = 0 //Diesen schalter auf 1 setzen, wenn die Posteingangsbearbeitung in Verbindung mit Sozialdokumenten genutzt wird. private static String STR_JA = "Ja" private static String STR_NEIN = "Nein" private static int laengeAZ = 8 // Länge des Aktenzeichens private static String G01_STR_NEIN = "Nein" private static String G01_STR_JA = "Ja" @Entrypoint( entrypoint = "hook_insert_entry_10" ) public int hook_insert_entry_10(D3Interface d3, User user, DocumentType docType, Document doc) { d3.log.error("START | hook_insert_entry_10 " + doc.id() ); sg02_split_AZ( d3, doc, 0 ); def iRet = sg02_fuelleFelder( d3, doc, docType.id ); d3.log.error("ENDE | hook_insert_entry_10 " + doc.id() ); return iRet; } @Entrypoint( entrypoint = "hook_new_version_entry_10" ) public int hookNewVersionEntry10(D3Interface d3, Document doc, String fileSource, String fileDestination, User user, DocumentType docType) { d3.log.error("START | hookNewVersionEntry10 " + doc.id() ); sg02_split_AZ( d3, doc, 0 ); def iRet = sg02_fuelleFelder( d3, doc, docType.id ); d3.log.error("ENDE | hookNewVersionEntry10 " + doc.id() ); return iRet; } @Entrypoint( entrypoint = "hook_upd_attrib_entry_20" ) public int hookUpdAttribEntry20(D3Interface d3, Document doc, User user, DocumentType docType, DocumentType docTypeNew) { d3.log.error("START | hookUpdAttribEntry20" + doc.id() ); def rc = 0; // temporäres Objekt holen, um zu prüfen, das sich Eigenschaften geändert haben oldDocAttributes = d3.archive.getDocument(doc.id()); sg02_split_AZ( d3, doc, 0); if ( docType.id == SG02_DS_SOZ_AKTE ) { STATUS_SACHGEBIET = 1; } if ( oldDocAttributes.field[ POS_ZDA ] == doc.field[ POS_ZDA ] ) { def massen_sql = "select f.doku_id from firmen_spezifisch f, phys_datei p where f.kue_dokuart = 'SG02_DS_SOZ_DOKU' and f.dok_dat_feld_" + POS_AZ + " = '" + doc.field[ POS_AZ ] + "' and p.logi_verzeichnis = 'Be' and f.doku_id = p.doku_id"; def massen_ergebnis = d3.sql.executeAndGet( massen_sql ); if ( massen_ergebnis.size() > 0 ) { d3.log.error( "[sg02_upd_attrib_entry_20] Sozialakte (" + doc.field[POS_AZ] + ") kann nicht zdA-verfügt werden da noch Dokumente in Bearbeitung sind." ); rc = -350; } if ( rc == 0 ) { STATUS_ZDA = 1; } } if ( docType.id == SG02_DS_SOZ_DOKU ) { if ( doc.field[ POS_ZLM ] == STR_JA ) { if ( doc.field[ POS_LOESCHGRD ] == "" ) { return -403; } } else if ( doc.field[ POS_ZLM ] == STR_NEIN ) { doc.field[ POS_LOESCHGRD ] = ""; } if ( oldDocAttributes.field[ POS_STORNO ] == doc.field[ POS_STORNO ] ) { if ( doc.field[ POS_STORNO ] == G01_STR_JA ) { doc.field[ POS_LOESCH_FLAG ] = G01_STR_JA; doc.field[ POS_LOESCHGRD ] = "In LISSA storniert."; } } } if ( rc == 0 && docType.id == G01_DS_POSTEINGANG ) { sg02_clear_vorname( d3, doc, docType.id ); } d3.log.error("ENDE | hookUpdAttribEntry20" + doc.id() ); return rc; } @Entrypoint( entrypoint = "hook_upd_attrib_exit_20" ) public int hookUpdAttribExit20(D3Interface d3, Document doc, Integer errorCode, User user, DocumentType docType, DocumentType docTypeOld) { d3.log.error("START | hookUpdAttribExit20 " + doc.id() ); if ( errorCode == 0 ) { if ( STATUS_SACHGEBIET == 1 ) { STATUS_SACHGEBIET = 0; // hier wird das docSearchCreate übernommen; dafür gibt es aber aktuell keine Entsprechung in Groovy. // das wird in Groovy direkt umgesetzt; d.h. man macht das manuell, was der JPL-Massenänderungs-Code en gros macht: def massen_sql = "select doku_id from firmen_spezifisch where kue_dokuart = '" + SG02_DS_SOZ_DOKU + "' and dok_dat_feld_" + POS_AZ + " = '" + doc.field(POS_AZ) + "'"; def massen_ergebnis = d3.sql.executeAndGet( massen_sql ); if ( massen_ergebnis.size() > 0 ) { int i; for ( i = 0 ; i < massen_ergebnis.size(); i++ ) { def updateDoc = d3.archive.getDocument( massen_ergebnis[ i ].doku_id ); updateDoc.field[ POS_SACHGEBIET ] = doc.field[ POS_SACHGEBIET ]; updateDoc.updateAttributes( "Master" ); } } } if ( STATUS_ZDA == 1 ) { STATUS_ZDA = 0; def strZDA, strDatum, strArt; if ( doc.field[ POS_ZDA ] == G01_STR_JA ) { strZDA = G01_STR_JA; strDatum = sg02_getDate( FRIST_AUSSONDERUNG, 1 ); } else if ( doc.field[POS_ZDA] == G01_STR_NEIN ) { strZDA = G01_STR_NEIN; strDatum = ""; } strArt = doc.field[ POS_AUSART ] if ( strArt == "" ) { strArt = "B"; } // hier wird das docSearchCreate übernommen; dafür gibt es aber aktuell keine Entsprechung in Groovy. // das wird in Groovy direkt umgesetzt; d.h. man macht das manuell, was der JPL-Massenänderungs-Code en gros macht: def massen_sql = "select doku_id from firmen_spezifisch where ( kue_dokuart = '" + SG02_DS_SOZ_AKTE + "' or kue_dokuart = '" + SG02_DS_SOZ_DOKU + "' )and dok_dat_feld_" + POS_AZ + " = '" + doc.field(POS_AZ) + "'"; def massen_ergebnis = d3.sql.executeAndGet( massen_sql ); if ( massen_ergebnis.size() > 0 ) { int i; for ( i = 0 ; i < massen_ergebnis.size(); i++ ) { def updateDoc = d3.archive.getDocument( massen_ergebnis[ i ].doku_id ); updateDoc.field[ POS_ZDA ] = strZDA; updateDoc.field[ POS_AUSSONDDAT ] = strDatum; updateDoc.field[ POS_AZ ] = strArt; // man könnte updateAttributes auch mit dem zweiten Parameter "true" aufrufen, das sollte dann das Ausführen von Hooks // für das Update unterbinden. Beim JPL-Masterdata-update läuft das vermutlich nämlich genau so. Machen wir hier aber erstmal nicht. updateDoc.updateAttributes( "Master" ); } } } } d3.log.error("ENDE | hookUpdAttribExit20 " + doc.id() ); return 0; } @Entrypoint( entrypoint = "hook_search_entry_10" ) public int hookSearchEntry10(D3Interface d3, User user, DocumentType docType, Document searchContext) { d3.log.error("START | hookSearchEntry10 " ); sg02_split_AZ( d3, doc, 1 ); if ( isNumeric( doc.field[ POS_AZ ] ) ) { if ( doc.field[ POS_AZ ].length() > 0 && doc.field[ POS_AZ ].length() < laengeAZ ) { doc.field[ POS_AZ ] = sg02_FillLeadingChar( doc.field[ POS_AZ ] ); } } d3.log.error("ENDE | hookSearchEntry10 " ); return 0; } @Entrypoint( entrypoint = "hook_validate_update_entry_10" ) public int hookValidateUpdateEntry10(D3Interface d3, User user, DocumentType docType, Document doc, String nextcall) { d3.log.error("START | hookValidateUpdateEntry10 " + doc.id() ); sg02_split_AZ( d3, doc, 0 ); if ( doc.field[ POS_AZ ].length() < laengeAZ ) { doc.field[ POS_AZ ] = sg02_FillLeadingChar( doc.field[ POS_AZ ] ); } def rc = sg02_fuelleFelder( d3, doc, docType.id ); d3.log.error("ENDE | hookValidateUpdateEntry10 " + doc.id() ); return rc; } // ---------------------------------- Wertemengen ---------------------------------- //////////////////////////////// sg02_SOZ_WM_Aktenzeichen //////////////////////////// // -> Funktion füllt das Feld Aktenzeichen mit Wertemenge // aus der d.3 Datenbank ////////////////////////////////////////////////////////////////////////////////////// @ValueSet( entrypoint = "sg02_SOZ_WM_Aktenzeichen" ) def sg02_SOZ_WM_Aktenzeichen(D3Interface d3, RepositoryField reposField, User user, DocumentType docType, int rowNo, int validate, Document doc ) { if ( doc.field[ POS_AZ ] != null ) { if ( doc.field[ POS_AZ ].length() > 2 ) { def sqlQuery = "select dok_dat_feld_" + POS_AZ + " POS_AZ, dok_dat_feld_" + POS_NACHNAME + " POS_NACHNAME, dok_dat_feld_" + POS_VORNAME + " POS_VORNAME, dok_dat_feld_" + POS_SACHGEBIET + " POS_SACHGEBIET, CONVERT(varchar, dok_dat_feld_" + POS_GEBURTSDATUM + ", 104) POS_GEBURTSDATUM from firmen_spezifisch where kue_dokuart = '" + SG02_DS_SOZ_AKTE + "' and ( dok_dat_feld_" + POS_AZ + " like '%" + doc.field[ POS_AZ ] + "%' or dok_dat_feld_" + POS_NACHNAME + " like '%" + doc.field[ POS_AZ ] + "%' or dok_dat_feld_" + POS_VORNAME + " like '%" + doc.field[ POS_AZ ] + "%' or dok_dat_feld_" + POS_SACHGEBIET + " like '%" + doc.field[ POS_AZ ] + "%' or CONVERT(varchar, dok_dat_feld_" + POS_GEBURTSDATUM + ", 104) like '%" + doc.field[ POS_AZ ] + "%' ) "; def resultRows = d3.sql.executeAndGet( sqlQuery ); if ( resultRows.size() > 0 ) { reposField.provideValuesForValueSet( resultRows.collect{ it.POS_AZ + "~" + it.POS_NACHNAME + "~" + it.POS_VORNAME + "~" + it.POS_GEBURTSDATUM + "~" + it.POS_SACHGEBIET } ); } } } } //////////////////////////////// sg02_SOZ_WM_Dokumentgruppe ////////////////////////// // // füllt das Feld Dokumenttruppe anhand des Feldes Kategorie ////////////////////////////////////////////////////////////////////////////////////// @ValueSet( entrypoint = "sg02_SOZ_WM_Dokumentgruppe" ) def sg02_SOZ_WM_Dokumentgruppe(D3Interface d3, RepositoryField reposField, User user, DocumentType docType, int rowNo, int validate, Document doc ) { def resultRows = d3.sql.executeAndGet( "select distinct Dokumentgruppe from " + TB_LISSA_DOKTYP ); if ( resultRows.size() > 0 ) { reposField.provideValuesForValueSet( resultRows.collect{ it.Dokumentgruppe } ); } } //////////////////////////////// sg02_SOZ_WM_Dokumenttyp ///////////////////////////// // // füllt das Feld Dokumenttyp anhand des Feldes Dokumentgruppe ////////////////////////////////////////////////////////////////////////////////////// @ValueSet( entrypoint = "sg02_SOZ_WM_Dokumenttyp" ) def sg02_SOZ_WM_Dokumenttyp(D3Interface d3, RepositoryField reposField, User user, DocumentType docType, int rowNo, int validate, Document doc ) { def sqlQuery = ""; if ( doc.field[ POS_AZ ] != null && ! doc.field[ POS_AZ ].isEmpty() ) { sqlQuery = "select distinct Dokumenttyp from " + TB_LISSA_DOKTYP + " where Dokumentgruppe = '" + doc.field[ POS_DOKGRP ] + "' "; } else { sqlQuery = "select distinct Dokumenttyp from " + TB_LISSA_DOKTYP; } def resultRows = d3.sql.executeAndGet( sqlQuery ); if ( resultRows.size() > 0 ) { reposField.provideValuesForValueSet( resultRows.collect{ it.Dokumenttyp } ); } } //////////////////////////////// sg02_SOZ_WM_WiderspruchNr ///////////////////////////// // // füllt das Feld Widerspruchsnummern anhand des Feldes Aktenzeichen ////////////////////////////////////////////////////////////////////////////////////// @ValueSet( entrypoint = "sg02_SOZ_WM_WiderspruchNr" ) def sg02_SOZ_WM_WiderspruchNr(D3Interface d3, RepositoryField reposField, User user, DocumentType docType, int rowNo, int validate, Document doc ) { sg02_split_AZ( d3, doc, 1 ); def sqlQuery = ""; if ( doc.field[ POS_AZ ] != "" ) { sqlQuery = "select distinct dok_dat_feld_" + POS_WIDERSPRUCH + " POS_WIDERSPRUCH from firmen_spezifisch where dok_dat_feld_" + POS_AZ + " = '" + doc.field[ POS_AZ ] + "' "; } else { sqlQuery = "select distinct dok_dat_feld_" + POS_WIDERSPRUCH + " POS_WIDERSPRUCH from firmen_spezifisch"; } def resultRows = d3.sql.executeAndGet( sqlQuery ); if ( resultRows.size() > 0 ) { reposField.provideValuesForValueSet( resultRows.collect{ it.POS_WIDERSPRUCH } ); } } //////////////////////////////// sg02_SOZ_WM_AZ_Rechtsanwalt ///////////////////////////// // // füllt das Feld Aktenzeichen Rechtsanwälte anhand des Feldes Aktenzeichen ////////////////////////////////////////////////////////////////////////////////////// @ValueSet( entrypoint = "sg02_SOZ_WM_AZ_Rechtsanwalt" ) def sg02_SOZ_WM_AZ_Rechtsanwalt(D3Interface d3, RepositoryField reposField, User user, DocumentType docType, int rowNo, int validate, Document doc ) { sg02_split_AZ( d3, doc, 1 ); def sqlQuery = ""; if ( doc.field[ POS_AZ ] != "" ) { sqlQuery = "select distinct dok_dat_feld_" + POS_AZ_RECHT + " POS_AZ_RECHT from firmen_spezifisch where dok_dat_feld_" + POS_AZ + " = '" + doc.field[ POS_AZ ] + "' "; } else { sqlQuery = "select distinct dok_dat_feld_" + POS_AZ_RECHT + " POS_AZ_RECHT from firmen_spezifisch"; } def resultRows = d3.sql.executeAndGet( sqlQuery ); if ( resultRows.size() > 0 ) { reposField.provideValuesForValueSet( resultRows.collect{ it.POS_AZ_RECHT } ); } } // ---------------------------------- Funktionen ---------------------------------- /////////////////////////// sg02_isSozial ////////////////////////////////////////// // Püft ob das übergebene Dokumentartkürzel zur Lösung gehört ////////////////////////////////////////////////////////////////////////////////////// public int sg02_isSozial(doc_type_short) { if ( doc_type_short == SG02_DS_SOZ_AKTE || doc_type_short == SG02_DS_SOZ_DOKU ) { return true; } return false; } //////////////////////////////// sg02_split_AZ /////////////////////////////////////// // -> Ermittelt den Wert Aktenzeichen aus der Wertemenge ////////////////////////////////////////////////////////////////////////////////////// public void sg02_split_AZ( D3Interface d3, Document doc, int IsSearch ) { if ( doc.field[ POS_AZ ] != null ) { if ( ! doc.field[ POS_AZ ].isEmpty() ) { if ( doc.field[ POS_AZ ].indexOf( "~" ) >= 0 ) { def tok = doc.field[ POS_AZ ].tokenize( "~" ); if ( tok.size() > 1 ) { doc.field[ POS_AZ ] = tok[ 0 ]; if ( IsSearch == 0 ) { doc.field[ POS_NACHNAME ] = tok[ 1 ]; doc.field[ POS_VORNAME ] = tok[ 2 ]; SimpleDateFormat dateFormat = new SimpleDateFormat( "dd.MM.yyyy" ); Date parsedDate = dateFormat.parse( tok[ 3 ] ); doc.field[ POS_GEBURTSDATUM ] = new Timestamp( parsedDate.getTime() ); doc.field[ POS_SACHGEBIET ] = tok[ 4 ]; } } } } } } /////////////////////////// sg02_getDate ///////////////////////////////////////////// // Gibt das Tagesdatum + Frist zurück // // strFrist Die Frist in Monaten um die das Tagesdatum erhoeht wird // iEndOfYear Unterscheidung ob der genaue Wert oder der letzte Tag des Jahres berechnet wird // 0 = genauer Wert / 1 = Ende des Jahres ////////////////////////////////////////////////////////////////////////////////////// public String sg02_getDate( int iFrist, int iEndOfYear ) { String strDatum = ""; String strEndOfYear = ""; def STATEMENT = "SELECT DATEADD(month, " + iFrist + ", GETDATE()) zeitstempel, '31.12.' + CONVERT(varchar,YEAR(DATEADD(month, " + iFrist + ", GETDATE()))) datum"; def resultRows = d3.sql.executeAndGet( STATEMENT ); if ( resultRows.size() > 0 ) { if ( iEndOfYear == 1 ) { return resultRows[ 0 ].datum; } else { return resultRows[ 0 ].zeitstempel; } } } ////////////////////////// sg02_fuelleFelder ///////////////////////////////////////////// public int sg02_fuelleFelder( D3Interface d3, Document doc, String doc_type_short ) { int retVal = 0; if ( doc_type_short == SG02_DS_SOZ_DOKU ) { def STATEMENT = "select doku_id from firmen_spezifisch where kue_dokuart = '" + SG02_DS_SOZ_AKTE + "' and dok_dat_feld_" + POS_AZ + " = '" + doc.field[ POS_AZ ] + "' "; def treffer = d3.sql.executeAndGet( (String) STATEMENT ); if ( treffer.size() > 0 ) { int i; for ( i = 0 ; i < treffer.size(); i++ ) { def updateDoc = d3.archive.getDocument( treffer[ i ].doku_id ); if ( updateDoc.field[ POS_ZDA ] == G01_STR_JA ) { d3.log.error( "[sg02_fuelleFelder] Sozialakte (:dok_dat_feld[POS_AZ]) ist zdA-verfügt und darf nicht bearbeitet werden." ); retVal = -316; //Änderung oder Archivierung nicht erlaubt - Akte oder Vorgang ist schon abgeschlossen } else { if ( doc.field[ POS_SACHGEBIET ] == "" ) { doc.field[ POS_SACHGEBIET ] = updateDoc.field[ POS_SACHGEBIET ]; } if ( doc.field[ POS_NACHNAME ] == "" ) { doc.field[ POS_NACHNAME ] = updateDoc.field[ POS_NACHNAME ]; } if ( doc.field[ POS_VORNAME ] == "" ) { doc.field[ POS_VORNAME ] = updateDoc.field[ POS_VORNAMEPOS_VORNAME ]; } if ( doc.field[ POS_STRASSE ] == "" ) { doc.field[ POS_STRASSE ] = updateDoc.field[ POS_STRASSE ]; } if ( doc.field[ POS_PLZ ] == "" ) { doc.field[ POS_PLZ ] = updateDoc.field[ POS_PLZ ]; } if ( doc.field[ POS_HNR ] == "" ) { doc.field[ POS_HNR ] = updateDoc.field[ POS_HNR ]; } if ( doc.field[ POS_ORT ] == "" ) { doc.field[ POS_ORT ] = updateDoc.field[ POS_ORT ]; } if ( doc.field[ POS_GEBURTSDATUM ] == "" ) { doc.field[ POS_GEBURTSDATUM ] = updateDoc.field[ POS_GEBURTSDATUM ]; } } } } } return retVal; } // Funktion: Wenn ein Posteingangsdokument in ein Sozialdokument umgewandelt wird, muss das Dokdatfeld Vorname geleert werden, // da es ansonsten in der Aktenbildung nach oben vererbt wird. In der Posteingangsbearbeitung ist das Dokdatfeld 4 Original behalten. // Rückgabewert: // 0 = wurde geleert. public int sg02_clear_vorname( D3Interface d3, Document doc, String doc_type_short ) { if ( doc.field[ POS_VORNAME ] == "Nein" || doc.field[ POS_VORNAME ] == "Ja" ) { doc.field[ POS_VORNAME ] = ""; } return 0; } // Kommentar in JPL-Datei passt nicht zur Funktion. public String sg02_FillLeadingChar( String strAZ ) { def paddedString = String.format( "%08d", strAZ ); return paddedString; } }