Skip to content

Commit

Permalink
DSGVO konformes Löschen von Mitgliedern, implementiert #213 (#224)
Browse files Browse the repository at this point in the history
* DSGVO konformes Löschen von Mitgliedern, implementiert #213
  • Loading branch information
JohannMaierhofer authored Sep 23, 2024
1 parent 9de0287 commit 50b2129
Show file tree
Hide file tree
Showing 6 changed files with 244 additions and 17 deletions.
58 changes: 56 additions & 2 deletions src/de/jost_net/JVerein/gui/action/MitgliedDeleteAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,24 @@
package de.jost_net.JVerein.gui.action;

import java.rmi.RemoteException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.math.BigDecimal;

import de.jost_net.JVerein.Einstellungen;
import de.jost_net.JVerein.rmi.Mitglied;
import de.jost_net.JVerein.rmi.Mail;
import de.jost_net.JVerein.rmi.MailEmpfaenger;
import de.willuhn.jameica.gui.Action;
import de.willuhn.jameica.gui.GUI;
import de.willuhn.jameica.gui.dialogs.YesNoDialog;
import de.willuhn.jameica.gui.util.SWTUtil;
import de.willuhn.logging.Logger;
import de.willuhn.util.ApplicationException;
import de.willuhn.datasource.rmi.DBIterator;
import de.willuhn.datasource.rmi.DBService;
import de.willuhn.datasource.rmi.ResultSetExtractor;

/**
* Loeschen eines Mitgliedes.
Expand All @@ -40,14 +51,20 @@ public void handleAction(Object context) throws ApplicationException
}
try
{
Mitglied m = (Mitglied) context;
final Mitglied m = (Mitglied) context;
if (m.isNewObject())
{
return;
}
YesNoDialog d = new YesNoDialog(YesNoDialog.POSITION_CENTER);
d.setTitle("Mitglied löschen");
d.setText("Wollen Sie dieses Mitglied wirklich löschen?");
d.setPanelText("Mitglied löschen?");
d.setSideImage(SWTUtil.getImage("dialog-warning-large.png"));
String text = "Wollen Sie dieses Mitglied wirklich löschen?"
+ "\nDies löscht auch alle Mitglied bezogenen Daten wie"
+ "\nz.B. Sollbuchungen, Spendenbescheinigungen, Mails etc."
+ "\nDiese Daten können nicht wieder hergestellt werden!";
d.setText(text);

try
{
Expand All @@ -60,6 +77,43 @@ public void handleAction(Object context) throws ApplicationException
Logger.error("Fehler beim Löschen des Mitgliedes", e);
return;
}

// Suche Mails mit mehr als einem Empfänger
final DBService service = Einstellungen.getDBService();
String sql = "SELECT mail , count(id) anzahl from mailempfaenger ";
sql += "group by mailempfaenger.mail ";
sql += "HAVING anzahl > 1 ";
ResultSetExtractor rs = new ResultSetExtractor()
{
@Override
public Object extract(ResultSet rs) throws RemoteException, SQLException
{
ArrayList<BigDecimal> list = new ArrayList<BigDecimal>();
while (rs.next())
{
list.add(rs.getBigDecimal(1));
}
return list;
}
};
@SuppressWarnings("unchecked")
ArrayList<BigDecimal> ergebnis = (ArrayList<BigDecimal>) service.execute(sql,
new Object[] { }, rs);

// Alle Mails an das Mitglied löschen wenn nur ein Empfänger vorhanden
DBIterator<MailEmpfaenger> it = Einstellungen.getDBService()
.createList(MailEmpfaenger.class);
it.addFilter("mitglied = ?", m.getID());
while (it.hasNext())
{
Mail ma = ((MailEmpfaenger) it.next()).getMail();
if (!ergebnis.contains(new BigDecimal(ma.getID())))
{
// Die Mail hat keinen weiteren Empfänger also löschen
ma.delete();
}
}

m.delete();
GUI.getStatusBar().setSuccessText("Mitglied gelöscht.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,23 @@
**********************************************************************/
package de.jost_net.JVerein.gui.action;

import java.math.BigDecimal;
import java.rmi.RemoteException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import de.jost_net.JVerein.Einstellungen;
import de.jost_net.JVerein.rmi.Mail;
import de.jost_net.JVerein.rmi.MailEmpfaenger;
import de.jost_net.JVerein.rmi.Mitglied;
import de.willuhn.datasource.rmi.DBIterator;
import de.willuhn.datasource.rmi.DBService;
import de.willuhn.datasource.rmi.ResultSetExtractor;
import de.willuhn.jameica.gui.Action;
import de.willuhn.jameica.gui.GUI;
import de.willuhn.jameica.gui.dialogs.YesNoDialog;
import de.willuhn.jameica.gui.util.SWTUtil;
import de.willuhn.logging.Logger;
import de.willuhn.util.ApplicationException;

Expand All @@ -46,7 +57,13 @@ public void handleAction(Object context) throws ApplicationException
}
YesNoDialog d = new YesNoDialog(YesNoDialog.POSITION_CENTER);
d.setTitle("Nicht-Mitglied löschen");
d.setText("Wollen Sie dieses Nicht-Mitglied wirklich löschen?");
d.setPanelText("Nicht-Mitglied löschen?");
d.setSideImage(SWTUtil.getImage("dialog-warning-large.png"));
String text = "Wollen Sie dieses Nicht-Mitglied wirklich löschen?"
+ "\nDies löscht auch alle Nicht-Mitglied bezogenen Daten wie"
+ "\nz.B. Sollbuchungen, Spendenbescheinigungen, Mails etc."
+ "\nDiese Daten können nicht wieder hergestellt werden!";
d.setText(text);

try
{
Expand All @@ -59,6 +76,43 @@ public void handleAction(Object context) throws ApplicationException
Logger.error("Fehler beim Löschen des Nicht-Mitglied", e);
return;
}

// Suche Mails mit mehr als einem Empfänger
final DBService service = Einstellungen.getDBService();
String sql = "SELECT mail , count(id) anzahl from mailempfaenger ";
sql += "group by mailempfaenger.mail ";
sql += "HAVING anzahl > 1 ";
ResultSetExtractor rs = new ResultSetExtractor()
{
@Override
public Object extract(ResultSet rs) throws RemoteException, SQLException
{
ArrayList<BigDecimal> list = new ArrayList<BigDecimal>();
while (rs.next())
{
list.add(rs.getBigDecimal(1));
}
return list;
}
};
@SuppressWarnings("unchecked")
ArrayList<BigDecimal> ergebnis = (ArrayList<BigDecimal>) service.execute(sql,
new Object[] { }, rs);

// Alle Mails an das Nicht-Mitglied löschen wenn nur ein Empfänger vorhanden
DBIterator<MailEmpfaenger> it = Einstellungen.getDBService()
.createList(MailEmpfaenger.class);
it.addFilter("mitglied = ?", m.getID());
while (it.hasNext())
{
Mail ma = ((MailEmpfaenger) it.next()).getMail();
if (!ergebnis.contains(new BigDecimal(ma.getID())))
{
// Die Mail hat keinen weiteren Empfänger also löschen
ma.delete();
}
}

m.delete();
GUI.getStatusBar().setSuccessText("Nicht-Mitglied gelöscht.");
}
Expand Down
21 changes: 21 additions & 0 deletions src/de/jost_net/JVerein/server/BuchungImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import de.jost_net.JVerein.io.Adressbuch.Adressaufbereitung;
import de.jost_net.JVerein.rmi.Abrechnungslauf;
import de.jost_net.JVerein.rmi.Buchung;
import de.jost_net.JVerein.rmi.BuchungDokument;
import de.jost_net.JVerein.rmi.Buchungsart;
import de.jost_net.JVerein.rmi.Jahresabschluss;
import de.jost_net.JVerein.rmi.Konto;
Expand All @@ -38,6 +39,9 @@
import de.willuhn.datasource.db.AbstractDBObject;
import de.willuhn.datasource.rmi.ObjectNotFoundException;
import de.willuhn.datasource.rmi.DBIterator;
import de.willuhn.datasource.rmi.DBService;
import de.willuhn.jameica.messaging.QueryMessage;
import de.willuhn.jameica.system.Application;
import de.willuhn.logging.Logger;
import de.willuhn.util.ApplicationException;

Expand Down Expand Up @@ -722,4 +726,21 @@ public boolean isToDelete()
{
return delete;
}

@Override
public void delete() throws RemoteException, ApplicationException
{
DBService service = Einstellungen.getDBService();
DBIterator<BuchungDokument> docs = service.createList(BuchungDokument.class);
docs.addFilter("referenz = ?", new Object[] { this.getID() });
while (docs.hasNext())
{
QueryMessage qm = new QueryMessage(
((BuchungDokument) docs.next()).getUUID(), null);
Application.getMessagingFactory().getMessagingQueue(
"jameica.messaging.del").sendSyncMessage(qm);
}
super.delete();
}

}
92 changes: 92 additions & 0 deletions src/de/jost_net/JVerein/server/DDLTool/Updates/Update0443.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/**********************************************************************
* This program is free software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not,
* see <http://www.gnu.org/licenses/>.
*
**********************************************************************/
package de.jost_net.JVerein.server.DDLTool.Updates;

import de.jost_net.JVerein.server.DDLTool.AbstractDDLUpdate;
import de.willuhn.util.ApplicationException;
import de.willuhn.util.ProgressMonitor;

import java.sql.Connection;

public class Update0443 extends AbstractDDLUpdate
{
public Update0443(String driver, ProgressMonitor monitor, Connection conn)
{
super(driver, monitor, conn);
}

@Override
public void run() throws ApplicationException
{
if (getDriver() == DRIVER.H2)
{
runh2();
}
else
{
try
{
runh2();
}
catch (Exception ex)
{
runmysql();
}
}

execute(dropForeignKey("fkLastschrift2", "lastschrift"));
execute(createForeignKey("fkLastschrift2", "lastschrift",
"mitglied", "mitglied", "id", "CASCADE", "NO ACTION"));

execute(dropForeignKey("fkLastschrift3", "lastschrift"));
execute(createForeignKey("fkLastschrift3", "lastschrift",
"kursteilnehmer", "kursteilnehmer", "id", "CASCADE", "NO ACTION"));

execute(dropForeignKey("fkMitgliedDokument1", "mitglieddokument"));
execute(createForeignKey("fkMitgliedDokument1", "mitglieddokument",
"referenz", "mitglied", "id", "CASCADE", "NO ACTION"));

execute(dropForeignKey("fkSpendenbescheinigung2", "spendenbescheinigung"));
execute(createForeignKey("fkSpendenbescheinigung2", "spendenbescheinigung",
"mitglied", "mitglied", "id", "CASCADE", "NO ACTION"));

execute(dropForeignKey("fkWiedervorlage1", "wiedervorlage"));
execute(createForeignKey("fkWiedervorlage1", "wiedervorlage",
"mitglied", "mitglied", "id", "CASCADE", "NO ACTION"));

execute(dropForeignKey("fkZusatzabbuchung1", "zusatzabbuchung"));
execute(createForeignKey("fkZusatzabbuchung1", "zusatzabbuchung",
"mitglied", "mitglied", "id", "CASCADE", "NO ACTION"));

execute(dropForeignKey("fkBuchung5", "buchung"));
execute(createForeignKey("fkBuchung5", "buchung",
"spendenbescheinigung", "spendenbescheinigung", "id", "SET NULL", "NO ACTION"));

}

private void runh2() throws ApplicationException
{
execute(dropForeignKey("fk_sekundaerbeitragegruppe1", "sekundaerebeitragsgruppe"));
execute(createForeignKey("fk_sekundaerbeitragegruppe1", "sekundaerebeitragsgruppe",
"mitglied", "mitglied", "id", "CASCADE", "NO ACTION"));
}

private void runmysql() throws ApplicationException
{
execute(dropForeignKey("sekundaerebeitragsgruppe_ibfk_1", "sekundaerebeitragsgruppe"));
execute(createForeignKey("fk_sekundaerbeitragegruppe1", "sekundaerebeitragsgruppe",
"mitglied", "mitglied", "id", "CASCADE", "NO ACTION"));
}

}
20 changes: 20 additions & 0 deletions src/de/jost_net/JVerein/server/MitgliedImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import de.jost_net.JVerein.rmi.Beitragsgruppe;
import de.jost_net.JVerein.rmi.Felddefinition;
import de.jost_net.JVerein.rmi.Mitglied;
import de.jost_net.JVerein.rmi.MitgliedDokument;
import de.jost_net.JVerein.rmi.Mitgliedfoto;
import de.jost_net.JVerein.rmi.Zusatzfelder;
import de.jost_net.JVerein.util.Datum;
Expand All @@ -48,7 +49,10 @@
import de.jost_net.OBanToo.SEPA.SEPAException.Fehler;
import de.willuhn.datasource.db.AbstractDBObject;
import de.willuhn.datasource.rmi.DBIterator;
import de.willuhn.datasource.rmi.DBService;
import de.willuhn.datasource.rmi.ResultSetExtractor;
import de.willuhn.jameica.messaging.QueryMessage;
import de.willuhn.jameica.system.Application;
import de.willuhn.logging.Logger;
import de.willuhn.util.ApplicationException;

Expand Down Expand Up @@ -1300,4 +1304,20 @@ private Date toDate(String datum)
return d;
}

@Override
public void delete() throws RemoteException, ApplicationException
{
DBService service = Einstellungen.getDBService();
DBIterator<MitgliedDokument> docs = service.createList(MitgliedDokument.class);
docs.addFilter("referenz = ?", new Object[] { this.getID() });
while (docs.hasNext())
{
QueryMessage qm = new QueryMessage(
((MitgliedDokument) docs.next()).getUUID(), null);
Application.getMessagingFactory().getMessagingQueue(
"jameica.messaging.del").sendSyncMessage(qm);
}
super.delete();
}

}
14 changes: 0 additions & 14 deletions src/de/jost_net/JVerein/server/SpendenbescheinigungImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -380,20 +380,6 @@ public void store() throws RemoteException, ApplicationException
}
}

@Override
public void delete() throws RemoteException, ApplicationException
{
if (getSpendenart() == Spendenart.GELDSPENDE)
{
for (Buchung b : getBuchungen())
{
b.setSpendenbescheinigungId(null);
b.store();
}
}
super.delete();
}

@Override
public Mitglied getMitglied() throws RemoteException
{
Expand Down

0 comments on commit 50b2129

Please sign in to comment.