210217PX Bugfix for member account can get < -2 montly fees

This commit is contained in:
phantomix 2021-02-18 17:00:56 +01:00
parent 14daad398e
commit 2aded95f62
3 changed files with 76 additions and 69 deletions

View File

@ -24,6 +24,7 @@ TODO
- Configuration window: MoneyTransferRegEx
- Bug: Generating testdata doesn't remove old xml files, thus the memberlist will be mixed after next restart
- Bug: Member list not reloaded after ProcessCSV (balance display is wrong)
- Bug: Import/Export gpg uses command line parameter for password - this can be read out by any system user via "ps uxa"
- CronjobConfig
- CustomListView: implement generic filtering
@ -32,13 +33,6 @@ TODO
or "two months behind", in order to have an escalation chain
- PGP for mails
DONE
----
- Member: add database field for contact name e.g.: name <mail@example.com> filled with nickname by default
- Testmail feature for every member account
- 2019-12-04: frmProcessWithLog: Implementation for non-immediate GUI actions (process csv, cronjob, import/export) with background thread
- Bug: Database import fails on some PCs (seems that writing xml files during decompression is problematic)
*/
namespace dezentrale
{

View File

@ -220,9 +220,17 @@ namespace dezentrale.core
if (months > 0)
{
m.StartLogEvent($"Membership fee: {months} Months * {m.PaymentAmount} EURcents = {months * m.PaymentAmount} EURcents", LogEvent.eEventType.MembershipFee, "automatic");
m.AccountBalance -= (Int64)(((Int64)months) * (Int64)m.PaymentAmount);
m.LastBalanceDegrade = DateTime.Now;
//We need to cap the negative balance here to -2 monthly fees.
if (m.AccountBalance > -2 * (Int64)m.PaymentAmount)
{
m.StartLogEvent($"Membership fee: {months} Months * {m.PaymentAmount} EURcents = {months * m.PaymentAmount} EURcents", LogEvent.eEventType.MembershipFee, "automatic");
m.AccountBalance -= (Int64)(((Int64)months) * (Int64)m.PaymentAmount);
m.LastBalanceDegrade = DateTime.Now;
} else
{
m.StartLogEvent($"Skipping membership fee for {months} Months ({months * m.PaymentAmount} EURcents) as balance is already <= 2 monthly fees!", LogEvent.eEventType.MembershipFee, "automatic");
m.LastBalanceDegrade = DateTime.Now;
}
m.SaveToFile();
}
}
@ -241,82 +249,86 @@ namespace dezentrale.core
private static void CheckBalance_PostDegrade(Member m, Member sm = null)
{
if (m.Status != Member.eStatus.Active || m.PaymentAmount == 0) return;
bool skipInsufficientNotify = false;
if (DateTime.Now.Day < 8) skipInsufficientNotify = true;
TimeSpan tsLastMail = ProgramStartTime.Subtract(m.LastCronjobBalanceMail);
bool skipInsufficientNotify = ((DateTime.Now.Day < 8) || (tsLastMail.TotalDays < 14));
int currentDeptLevel = 0; //no payments missed
int currentDebtLevel = 0; //no payments missed
if (m.AccountBalance < -2 * (int)m.PaymentAmount) currentDeptLevel = -3;
else if (m.AccountBalance == -2 * (int)m.PaymentAmount) currentDeptLevel = -2;
else if (m.AccountBalance < 0) currentDeptLevel = -1;
else if (m.AccountBalance > 200 * 100) currentDeptLevel = 1;
//Account balance is capped to -2 monthly fees
//if (m.AccountBalance < -2 * (int)m.PaymentAmount) currentDeptLevel = -3;
if (m.AccountBalance <= -2 * (int)m.PaymentAmount) currentDebtLevel = -2;
else if (m.AccountBalance < 0) currentDebtLevel = -1;
else if (m.AccountBalance > 200 * 100) currentDebtLevel = 1;
bool debtLevelDecrease = (m.DebtLevel > currentDebtLevel);
bool debtLevelIncrease = (m.DebtLevel < currentDebtLevel);
if (tsLastMail.TotalDays < 14)
if(!skipInsufficientNotify)
{
skipInsufficientNotify = true;
} else
{
if (m.DebtLevel >= currentDeptLevel) m.DebtLevel--;
else m.DebtLevel = currentDeptLevel;
if (debtLevelDecrease) m.DebtLevel--;
else m.DebtLevel = currentDebtLevel;
//We don't set skipInsufficientNotify here as we don't want to not-warn
//if it's still negative
}
switch(currentDeptLevel)
switch(m.DebtLevel)
{
case 1:
{
//Member has given much money
m.StartLogEvent($"Excess amount of payments", LogEvent.eEventType.EMail, "automatic");
if (sm != null)
{
FormMail above200 = FormMail.GenerateBalanceAbove200NotifySM().ReplaceReflect(m);
above200.To = $"{sm.Nickname} <{sm.EMail}>";
m.CurrentLog.SubEvents.Add(above200.Send());
} else
Console.WriteLine("ERROR: CheckBalance_PostDegrade: sm = null");
} break;
{
if (debtLevelIncrease)
{
//Member has given much money
m.StartLogEvent($"Excess amount of payments", LogEvent.eEventType.EMail, "automatic");
if (sm != null)
{
FormMail above200 = FormMail.GenerateBalanceAbove200NotifySM().ReplaceReflect(m);
above200.To = $"{sm.EMailName} <{sm.EMail}>";
m.CurrentLog.SubEvents.Add(above200.Send());
}
else
Console.WriteLine("ERROR: CheckBalance_PostDegrade: sm = null");
}
} break;
case 0:
{
//all is fine.
} break;
{
//all is fine.
} break;
case -1:
{
if (!skipInsufficientNotify)
{
m.StartLogEvent($"Insufficient amount of payments #1", LogEvent.eEventType.EMail, "automatic");
m.CurrentLog.SubEvents.Add(FormMail.GenerateBalanceNegativeMemberNotify1().Send(m));
}
} break;
if (!skipInsufficientNotify)
{
m.StartLogEvent($"Insufficient amount of payments #1", LogEvent.eEventType.EMail, "automatic");
m.CurrentLog.SubEvents.Add(FormMail.GenerateBalanceNegativeMemberNotify1().Send(m));
}
} break;
case -2:
{
if (!skipInsufficientNotify)
{
m.StartLogEvent($"Insufficient amount of payments #2", LogEvent.eEventType.EMail, "automatic");
m.CurrentLog.SubEvents.Add(FormMail.GenerateBalanceNegativeMemberNotify2().Send(m));
if (sm != null)
{
FormMail below2sm = FormMail.GenerateBalanceNegativeNotify2SM().ReplaceReflect(m);
below2sm.To = $"{sm.Nickname} <{sm.EMail}>";
m.CurrentLog.SubEvents.Add(below2sm.Send());
} else
Console.WriteLine("ERROR: CheckBalance_PostDegrade: sm = null");
}
} break;
case -3:
{
if (!skipInsufficientNotify)
{
m.StartLogEvent($"Deactivation (insufficient payment)", LogEvent.eEventType.Deactivation, "automatic");
m.CurrentLog.SubEvents.Add(FormMail.GenerateBalanceNegativeMemberDeactivation().ReplaceReflect(Program.config.VS).Send(m));
m.CurrentLog.SubEvents.Add(FormMail.GenerateBalanceNegativeMemberDeactivationVS().ReplaceReflect(Program.config.VS).Send(m));
m.Status = Member.eStatus.Disabled;
}
} break;
if (!skipInsufficientNotify)
{
if(debtLevelDecrease)
{
m.StartLogEvent($"Insufficient amount of payments #2", LogEvent.eEventType.EMail, "automatic");
m.CurrentLog.SubEvents.Add(FormMail.GenerateBalanceNegativeMemberNotify2().Send(m));
if (sm != null)
{
FormMail below2sm = FormMail.GenerateBalanceNegativeNotify2SM().ReplaceReflect(m);
below2sm.To = $"{sm.EMailName} <{sm.EMail}>";
m.CurrentLog.SubEvents.Add(below2sm.Send());
} else
Console.WriteLine("ERROR: CheckBalance_PostDegrade: sm = null");
} else
{
m.StartLogEvent($"Deactivation (insufficient payment)", LogEvent.eEventType.Deactivation, "automatic");
m.CurrentLog.SubEvents.Add(FormMail.GenerateBalanceNegativeMemberDeactivation().ReplaceReflect(Program.config.VS).Send(m));
m.CurrentLog.SubEvents.Add(FormMail.GenerateBalanceNegativeMemberDeactivationVS().ReplaceReflect(Program.config.VS).Send(m));
m.Status = Member.eStatus.Disabled;
}
}
} break;
default:
break;
@ -324,7 +336,7 @@ namespace dezentrale.core
if (m.CurrentLog != null)
{
m.LastCronjobBalanceMail = ProgramStartTime;
m.LastCronjobBalanceMail = DateTime.Now;
m.SaveToFile();
}
}

View File

@ -21,6 +21,7 @@ namespace dezentrale.core
//! \param log Optional logger instance. If ommitted, Console.WriteLine() will be used
//! \return true if the program executed successfully
//! \return false if gpg was not found or there was another error (see log output)
//! \todo Applying passphrase through a cmdline argument is a potential security risk and needs to be changed.
public static bool Gpg(string args, string gpgPassword, ILogger log = null)
{
string argsFull = $"--batch --yes --passphrase \"{gpgPassword}\" {args}";