dmdb/model/Mv.cs

221 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
using dezentrale.core;
namespace dezentrale.model
{
public class MvInvitedMember
{
[XmlAttribute] public uint MemberNumber { get; set; }
[XmlAttribute] public bool Invited { get; set; } = false;
[XmlAttribute] public DateTime InvitationDate { get; set; }
[XmlAttribute] public string AuthCode { get; set; } = "";
[XmlAttribute] public bool AttendedMv { get; set; } = false;
[XmlIgnore] public string NumberString { get { return $"{MemberNumber:D3}"; } }
[XmlIgnore] public string InvitedString { get { return Invited ? "Yes" : "No"; } }
[XmlIgnore] public string AttendedString { get { return AttendedMv ? "Yes" : "No"; } }
private Member member = null;
[XmlIgnore] public Member Member
{
get
{
if(member == null)
{
member = Program.members.Find(MemberNumber);
}
return member;
}
}
public MvInvitedMember() { }
public MvInvitedMember(Member m)
{
member = m;
MemberNumber = m.Number;
}
public override string ToString()
{
return $"{Member.Number} ({Member.Nickname})";
}
}
public class Mv : XmlLog, IAttachmentOwner
{
public enum MvStatus
{
InPreparation = 0,
InvitationSent = 1,
Started = 2,
Ended = 3,
Cancelled = 0xFF,
}
private MvStatus status = MvStatus.InPreparation;
private DateTime eventDate;
private DateTime startDateTime;
private DateTime endDateTime;
private string place = "";
private string agenda = "";
private string inviteHeadline = "";
private string inviteBody = "";
private string protocol = "";
[XmlAttribute] public MvStatus Status { get { return status; } set { LogPropertyChange("Status", status, value); status = value; } }
[XmlAttribute] public DateTime EventDate { get { return eventDate; } set { LogPropertyChange("EventDate", eventDate, value); eventDate = value; } }
[XmlAttribute("Started")] public DateTime StartDateTime { get { return startDateTime; } set { LogPropertyChange("StartDateTime", startDateTime, value); startDateTime = value; } }
[XmlAttribute("Ended")] public DateTime EndDateTime { get { return endDateTime; } set { LogPropertyChange("EndDateTime", endDateTime, value); endDateTime = value; } }
[XmlElement] public string Place { get { return place; } set { LogPropertyChange("Place", place, value); place = value; } }
[XmlElement] public string Agenda { get { return agenda; } set { LogPropertyChange("Agenda", agenda, value); agenda = value; } }
[XmlElement] public string InviteHeadline { get { return inviteHeadline; } set { LogPropertyChange("InviteHeadline", inviteHeadline, value); inviteHeadline = value; } }
[XmlElement] public string InviteBody { get { return inviteBody; } set { LogPropertyChange("InviteBody", inviteBody, value); inviteBody = value; } }
[XmlElement] public List<MvInvitedMember> Members { get; set; } = new List<MvInvitedMember>();
[XmlElement] public string Protocol { get { return protocol; } set { LogPropertyChange("Protocol", protocol, value); protocol = value; } }
[XmlElement("Attachments")] public List<Attachment> Attachments { get; set; } = new List<Attachment>();
[XmlIgnore] public string AgendaNumberedString
{
get
{
string ret = "";
string[] AgendaPoints = Agenda.Split('\n');
for(int i = 1; i <= AgendaPoints.Length; i++)
{
if (ret.Length > 0) ret += '\n';
ret += $"{i}. {AgendaPoints[i-1]}";
}
return ret;
}
}
public FormMail BuildInvitation()
{
return null;
}
public void FillDefaults()
{
DateTime inTwoWeeks = DateTime.Now.Add(new TimeSpan(14, 0, 0, 0));
DateTime dtSuggested = inTwoWeeks.Hour < 15 ? inTwoWeeks : inTwoWeeks.Add(new TimeSpan(1, 0, 0, 0));
while (dtSuggested.DayOfWeek != DayOfWeek.Sunday)
dtSuggested = dtSuggested.Add(new TimeSpan(1, 0, 0, 0));
StartLogEvent("MV contents set to its default values", LogEvent.eEventType.DataChange);
SuppressLogging = true;
Status = MvStatus.InPreparation;
EventDate = new DateTime(dtSuggested.Year, dtSuggested.Month, dtSuggested.Day, 15, 0, 0);
Place = "Räumlichkeiten des dezentrale e.V., Dreilindenstr. 19, 04177 Leipzig";
Agenda = "Bestimmung des Versammlungsleiters sowie Protokollanten\n"
+ "Feststellung der ordnungsgemäßen Einberufung\n"
+ "Mitgliedsstatus-Änderung zwischen \"Fördermitglied\" und \"reguläres Mitglied\"\n"
+ "Feststellung der Beschlussfähigkeit\n"
+ "Genehmigung der Tagesordnung\n"
+ "Genehmigung des Protokolls der letzten Mitgliederversammlung\n"
+ "Berichte des Vorstandes\n"
+ "Entlastung des Vorstandes\n"
+ "Neuwahl des Vorstandes\n"
+ "Verschiedenes";
InviteHeadline = "Einladung zur Mitgliederversammlung des dezentrale e.V. am {EventDate}";
InviteBody = "Hallo {EMailName},\n\nhiermit möchte ich Dich als Mitglied\n"
+ "des dezentrale e.V. zur Mitgliederversammlung einladen.\n\n"
+ "Ort: {Place}\n"
+ "Datum und Uhrzeit: {EventDate}\n"
+ "Dein Authentifizierungscode: {AuthCode}\n\n"
+ "Agenda:\n-------\n"
+ "{AgendaNumberedString}\n\n"
+ "Bitte denkt daran, dass für die Beschlussfähigkeit 51% der regulären Mitglieder vonnöten sind [1].\n"
+ "\n\n"
+ "Liebe Grüße,\n\n\n"
+ $"{Program.config.LocalUser}\n\n\n\n"
+ "[1] Unsere Satzung unterscheidet zwischen regulären und Fördermitgliedern.\n"
+ " Der Wechsel zu Fördermitglied ist jederzeit möglich, der Wechsel zu\n"
+ " regulärem Mitglied am Anfang jeder MV. Fördermitglieder stimmen nicht\n"
+ " mit ab und fallen daher aus dem Quorum (51%) raus. Der Vorstand kann\n"
+ " Auskunft über Deinen Mitgliedsstatus geben.";
Members.Clear();
SuppressLogging = true;
FinishLogEvent();
}
//random string generation is borrowed from https://stackoverflow.com/questions/1344221
private static Random random = new Random();
private static string RandomString(int length)
{
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
return new string(Enumerable.Repeat(chars, length)
.Select(s => s[random.Next(s.Length)]).ToArray());
}
public SerialMailProcess<MvInvitedMember> GetInvitationMailProcess(List<MvInvitedMember> entities = null)
{
FormMail fm = (new FormMail()
{
To = "{EMailName} <{EMail}>",
Subject = InviteHeadline,
Body = InviteBody,
}).ReplaceReflect(this);
if (entities == null) entities = Members;
SerialMailProcess<MvInvitedMember> p =
new SerialMailProcess<MvInvitedMember>(fm, entities,
(FormMail f, MvInvitedMember m, IProcessController LogTarget) =>
{
m.Member.StartLogEvent("MV invitation mail", LogEvent.eEventType.EMail, Program.config.LocalUser);
m.AuthCode = RandomString(10);
m.Member.CurrentLog.SubEvents.Add(new LogSubEvent()
{
Type = LogEvent.eEventType.DataChange,
Topic = "New AuthCode for MV",
Details = m.AuthCode,
});
try
{
m.Member.CurrentLog.SubEvents.Add(f.ReplaceReflect(m).Send(m.Member));
m.Member.SaveToFile();
} catch(Exception ex)
{
m.Member.CurrentLog.SubEvents.Add(new LogSubEvent() { Type = LogEvent.eEventType.Error, Topic = "Email invitation failed", Details = ex.Message });
m.Member.SaveToFile();
LogTarget.LogLine(ex.Message, LogEvent.ELogLevel.Error, "SerialMailProcess::mv.invitation");
return false;
}
m.InvitationDate = DateTime.Now;
m.Invited = true;
return true;
});
return p;
}
[Obsolete]
public FormMail GetInvitationMail(Member m = null, string authCode = null)
{
FormMail fm = new FormMail()
{
Subject = this.InviteHeadline,
Body = this.InviteBody,
};
fm = fm.ReplaceReflect(this);
if(m != null) fm = fm.ReplaceReflect(m);
return fm;
}
public void AttachmentChanged(Attachment attachment, eAttachmentAction action)
{
LogSubEvent lse = new LogSubEvent()
{
Type = LogEvent.eEventType.DataChange,
Topic = $"{action}: {attachment.FileName}",
};
if (CurrentLog == null)
StartLogEvent($"{action}: {attachment.FileName}", LogEvent.eEventType.DataChange);
CurrentLog.SubEvents.Add(lse);
}
}
}