210423PX Added process for finishing MV (including sending mails to the members and adapting the membership type according to the missed MV) *untested yet*

This commit is contained in:
phantomix 2021-04-23 17:31:23 +02:00
parent f2cf3b07c7
commit 2934e9c75a
5 changed files with 128 additions and 11 deletions

115
core/MvFinishProcess.cs Normal file
View File

@ -0,0 +1,115 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using dezentrale.model;
using dezentrale.model.money;
namespace dezentrale.core
{
//! \brief Process for finishing a MV. This includes sending out multiple
//! E-Mails to the previously invited members, processing the
//! Foerdermitglied/regulaer state of the members etc.
public class MvFinishProcess : BackgroundProcess
{
private Mv mv = null;
public MvFinishProcess(Mv mv)
{
this.mv = mv;
if (mv == null) throw new NullReferenceException("MV given to MvFinishProcess() is null");
Caption = "Finish MV";
Steps = (uint) (mv.Members.Count + 3);
}
//! \short Run MV finish process
//! \brief For each invited member, check the attended status and
//! set the mv miss counter / Foerdermitglied/regular status.
//! Additionally, send an E-Mail with status changes or thanks
//! for attendance. Also, send a summary about Foerdermitglied/regular
//! to the Vorstand
//! \return true if the process was successful.
protected override bool Run()
{
uint step = 0;
try
{
//Check mv
if (mv.Status != Mv.MvStatus.Started)
throw new Exception($"MV is not in state {Mv.MvStatus.Started}");
FormMail mvFinishedNotification = FormMail.GenerateMvFinishedNotification();
FormMail mvTypeChangeNotification = FormMail.GenerateMembershipTypeChanged();
foreach (MvInvitedMember mvi in mv.Members)
{
string entryDesc = $"{mvi.MemberNumber} ({mvi.Member.Nickname})";
LogTarget.StepStarted(++step, $"Processing entry {entryDesc}");
LogSubEvent lse = null;
if (mvi.Invited)
{
try
{
if (mvi.AttendedMv)
{
mvi.Member.StartLogEvent($"MV attended at {mv.EventDate}", LogEvent.eEventType.Generic);
//Optional: Send mail to thank that MV was attended
lse = mvFinishedNotification.Send(mvi.Member);
if (lse.Type == LogEvent.eEventType.Error) throw new Exception($"Sending mail to {entryDesc} failed.");
mvi.Member.MvMissCounter = 0;
}
else
{
mvi.Member.StartLogEvent($"MV missed at {mv.EventDate}", LogEvent.eEventType.Generic);
if (mvi.Member.Type == Member.eType.Regulaer)
{
mvi.Member.MvMissCounter++;
if (mvi.Member.MvMissCounter >= 2)
{
//Send mail that type changed to Foerdermitglied
lse = mvTypeChangeNotification.Send(mvi.Member);
if (lse.Type == LogEvent.eEventType.Error) throw new Exception($"Sending mail to {entryDesc} failed.");
mvi.Member.Type = Member.eType.Foerdermitglied;
}
else
{
//Optional: Send mail that MV was missed
}
}
}
if (lse != null) mvi.Member.CurrentLog.SubEvents.Add(lse);
mvi.Member.SaveToFile();
LogTarget.StepCompleted(step, $"Completed member entry {entryDesc}", true);
} catch(Exception ex)
{
if (lse == null) lse = new LogSubEvent() { Type = LogEvent.eEventType.Error, Topic = ex.Message, Details = ex.StackTrace };
mvi.Member.CurrentLog.SubEvents.Add(lse);
LogTarget.LogLine(ex.Message, LogEvent.ELogLevel.Error, "MvFinishProcess");
if(ex.InnerException != null)
LogTarget.LogLine(ex.InnerException.Message, LogEvent.ELogLevel.Error, "MvFinishProcess");
LogTarget.StepCompleted(step, $"Completed member entry {entryDesc}", false);
}
} else
LogTarget.StepCompleted(step, $"Not invited - skipped {entryDesc}", true);
}
mv.Status = Mv.MvStatus.Ended;
mv.EndDateTime = DateTime.Now;
//Send report to Vorstand
return true;
}
catch (Exception ex)
{
LogTarget.LogLine($"An Error occurred: {ex.Message}", LogEvent.ELogLevel.Error, "MvFinishProcess");
LogTarget.StepCompleted(step, $"MV finish", false);
return false;
}
}
}
}

View File

@ -207,6 +207,7 @@
<Compile Include="view\FormWithActionButtons.cs" />
<Compile Include="view\LvMvInvitations.cs" />
<Compile Include="model\XmlLog.cs" />
<Compile Include="core\MvFinishProcess.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />

View File

@ -243,7 +243,7 @@ namespace dezentrale.model
}
public static FormMail GenerateManualTypeChanged()
public static FormMail GenerateMembershipTypeChanged()
{
//Regular / Foerdermitglied
return new FormMail()
@ -252,12 +252,14 @@ namespace dezentrale.model
Subject = "Mitgliedschaft geändert in \"{Type}\". Membership type changed to \"{Type}\"",
Body = "Hallo {EMailName}!\n"
+ "\n"
+ "Deine Mitgliedschaft bei uns wurde manuell geändert zu \"{Type}\".\n"
+ "Deine Mitgliedschaft bei uns wurde geändert zu \"{Type}\".\n"
+ "Verpasste Mitgliederversammlungen: {MvMissCounter}\n"
+ "\n"
+ "\n"
+ "Hello {EMailName}!\n"
+ "\n"
+ "Your membership type was changed manually to \"{Type}\".\n"
+ "Your membership type was changed to \"{Type}\".\n"
+ "Missed MV: {MvMissCounter}\n"
+ "\n"
+ "\n"
+ "--\n"
@ -594,10 +596,6 @@ namespace dezentrale.model
Body = "Hallo {EMailName}!\n"
+ "\n"
+ "Danke für Deine Teilnahme an der Mitgliederversammlung!\n"
+ "Die MV ging von {StartDateTime} bis {EndDateTime}.\n"
+ "Folgende Einladung zur MV ist hinfällig:\n"
+ "The following MV invitation is cancelled:\n"
+ "Titel/Subject: \"{InviteHeadline}\"\n"
+ "\n"
+ "--\n"
+ "Dies ist eine automatisch generierte E-Mail.\n"

View File

@ -189,6 +189,8 @@ namespace dezentrale.model
});
return p;
}
[Obsolete]
public FormMail GetInvitationMail(Member m = null, string authCode = null)
{

View File

@ -239,10 +239,11 @@ namespace dezentrale.view
MessageBox.Show($"MV must be in state {Mv.MvStatus.Started}!");
return;
}
mv.Status = Mv.MvStatus.Ended;
mv.EndDateTime = DateTime.Now;
MessageBox.Show("MV ended");
//Ask for sending end mail to attended users
MvFinishProcess finishProcess = new MvFinishProcess(mv);
frmProcessWithLog frmProcess = new frmProcessWithLog(finishProcess, false);
frmProcess.ShowDialog();
Program.mvList.SaveToFile();
UpdateGui();
}