Fixed entry dates bug in calculation.
Added cost overview in details.
This commit is contained in:
@@ -30,13 +30,18 @@ namespace UCalc.Data
|
|||||||
public class CostCalculationResult
|
public class CostCalculationResult
|
||||||
{
|
{
|
||||||
public decimal TotalAmount { get; }
|
public decimal TotalAmount { get; }
|
||||||
|
public decimal PastAmount { get; }
|
||||||
|
public decimal FutureAmount { get; }
|
||||||
public string Details { get; }
|
public string Details { get; }
|
||||||
public string DetailsForLandlord { get; }
|
public string DetailsForLandlord { get; }
|
||||||
public bool AffectsTenant { get; }
|
public bool AffectsTenant { get; }
|
||||||
|
|
||||||
public CostCalculationResult(decimal totalAmount, string details, string detailsForLandlord, bool affectsTenant)
|
public CostCalculationResult(decimal totalAmount, decimal pastAmount, decimal futureAmount, string details,
|
||||||
|
string detailsForLandlord, bool affectsTenant)
|
||||||
{
|
{
|
||||||
TotalAmount = totalAmount;
|
TotalAmount = totalAmount;
|
||||||
|
PastAmount = pastAmount;
|
||||||
|
FutureAmount = futureAmount;
|
||||||
Details = details;
|
Details = details;
|
||||||
DetailsForLandlord = detailsForLandlord;
|
DetailsForLandlord = detailsForLandlord;
|
||||||
AffectsTenant = affectsTenant;
|
AffectsTenant = affectsTenant;
|
||||||
@@ -121,7 +126,7 @@ namespace UCalc.Data
|
|||||||
{
|
{
|
||||||
if (tenant.EntryDate != null && tenant.EntryDate.Value.IsBetween(billing.StartDate, billing.EndDate))
|
if (tenant.EntryDate != null && tenant.EntryDate.Value.IsBetween(billing.StartDate, billing.EndDate))
|
||||||
{
|
{
|
||||||
AddEvent(tenant.EntryDate.Value, tenant, true);
|
AddEvent(tenant.EntryDate.Value.AddDays(-1), tenant, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tenant.DepartureDate != null &&
|
if (tenant.DepartureDate != null &&
|
||||||
@@ -264,7 +269,7 @@ namespace UCalc.Data
|
|||||||
details.Append(costPerDay.CeilAmountToString(Constants.InternalPrecision));
|
details.Append(costPerDay.CeilAmountToString(Constants.InternalPrecision));
|
||||||
details.Append(" €\n\n");
|
details.Append(" €\n\n");
|
||||||
|
|
||||||
return costPerDay;
|
return costPerDay.Ceil2(Constants.InternalPrecision);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IEnumerable<Flat> AffectedFlats(this Cost cost, Billing billing)
|
private static IEnumerable<Flat> AffectedFlats(this Cost cost, Billing billing)
|
||||||
@@ -455,7 +460,7 @@ namespace UCalc.Data
|
|||||||
return totalAmount;
|
return totalAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CalculateCostInPast(Billing billing, Tenant tenant, Cost cost, StringBuilder details,
|
private static decimal CalculateCostInPast(Billing billing, Tenant tenant, Cost cost, StringBuilder details,
|
||||||
IEnumerable<CostEntry> pastCoveringEntries)
|
IEnumerable<CostEntry> pastCoveringEntries)
|
||||||
{
|
{
|
||||||
details.Append("In vergangener Abrechnung bereits gezahlt (geschätzt) = ");
|
details.Append("In vergangener Abrechnung bereits gezahlt (geschätzt) = ");
|
||||||
@@ -500,9 +505,11 @@ namespace UCalc.Data
|
|||||||
|
|
||||||
details.Append(totalAmount.CeilToString());
|
details.Append(totalAmount.CeilToString());
|
||||||
details.Append(" €\n");
|
details.Append(" €\n");
|
||||||
|
|
||||||
|
return totalAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CalculateCostInFuture(Billing billing, Tenant tenant, Cost cost, StringBuilder details,
|
private static decimal CalculateCostInFuture(Billing billing, Tenant tenant, Cost cost, StringBuilder details,
|
||||||
IEnumerable<CostEntry> futureCoveringEntries)
|
IEnumerable<CostEntry> futureCoveringEntries)
|
||||||
{
|
{
|
||||||
details.Append("In nächster Abrechnung erwartet (geschätzt) = ");
|
details.Append("In nächster Abrechnung erwartet (geschätzt) = ");
|
||||||
@@ -547,13 +554,15 @@ namespace UCalc.Data
|
|||||||
|
|
||||||
details.Append(totalAmount.CeilToString());
|
details.Append(totalAmount.CeilToString());
|
||||||
details.Append(" €\n");
|
details.Append(" €\n");
|
||||||
|
|
||||||
|
return totalAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CostCalculationResult CalculateCost(Billing billing, Tenant tenant, Cost cost)
|
private static CostCalculationResult CalculateCost(Billing billing, Tenant tenant, Cost cost)
|
||||||
{
|
{
|
||||||
if (!AffectsTenant(tenant, cost))
|
if (!AffectsTenant(tenant, cost))
|
||||||
{
|
{
|
||||||
return new CostCalculationResult(0, "", "", false);
|
return new CostCalculationResult(0, 0, 0, "", "", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
var details = new StringBuilder("Kostenpunkt: ");
|
var details = new StringBuilder("Kostenpunkt: ");
|
||||||
@@ -579,12 +588,13 @@ namespace UCalc.Data
|
|||||||
details.Append(" €\n");
|
details.Append(" €\n");
|
||||||
|
|
||||||
var detailsLandlord = new StringBuilder(details.ToString());
|
var detailsLandlord = new StringBuilder(details.ToString());
|
||||||
CalculateCostInPast(billing, tenant, cost, detailsLandlord, pastCoveringEntries);
|
var pastAmount = CalculateCostInPast(billing, tenant, cost, detailsLandlord, pastCoveringEntries);
|
||||||
CalculateCostInFuture(billing, tenant, cost, detailsLandlord, futureCoveringEntries);
|
var futureAmount = CalculateCostInFuture(billing, tenant, cost, detailsLandlord, futureCoveringEntries);
|
||||||
details.Append("\n");
|
details.Append("\n");
|
||||||
detailsLandlord.Append("\n");
|
detailsLandlord.Append("\n");
|
||||||
|
|
||||||
return new CostCalculationResult(totalAmount, details.ToString(), detailsLandlord.ToString(), true);
|
return new CostCalculationResult(totalAmount, pastAmount, futureAmount, details.ToString(),
|
||||||
|
detailsLandlord.ToString(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TenantCalculationResult CalculateForTenant(Billing billing, Tenant tenant)
|
public static TenantCalculationResult CalculateForTenant(Billing billing, Tenant tenant)
|
||||||
@@ -630,5 +640,62 @@ namespace UCalc.Data
|
|||||||
return new TenantCalculationResult(tenant, costResults, subTotalAmount, totalAmount, details.ToString(),
|
return new TenantCalculationResult(tenant, costResults, subTotalAmount, totalAmount, details.ToString(),
|
||||||
detailsLandlord.ToString());
|
detailsLandlord.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string CalculateCostOverview(Billing billing)
|
||||||
|
{
|
||||||
|
var str = new StringBuilder();
|
||||||
|
var tenantResults = billing.Tenants.Select(tenant => CalculateForTenant(billing, tenant)).ToList();
|
||||||
|
|
||||||
|
decimal landlordAmount = 0;
|
||||||
|
|
||||||
|
foreach (var cost in billing.Costs)
|
||||||
|
{
|
||||||
|
str.Append("Kostenpunkt: ");
|
||||||
|
str.Append(cost.Name);
|
||||||
|
str.Append("\n\n");
|
||||||
|
|
||||||
|
var totalAmount = cost.Entries.Aggregate((decimal) 0, (sum, entry) => sum + entry.Amount);
|
||||||
|
str.Append("Insgesamter Betrag: ");
|
||||||
|
str.Append(totalAmount.CeilToString());
|
||||||
|
str.Append(" €\n");
|
||||||
|
|
||||||
|
var (tenantAmount, pastTenantAmount, futureTenantAmount) = tenantResults.Aggregate(
|
||||||
|
new Tuple<decimal, decimal, decimal>(0, 0, 0),
|
||||||
|
(sum, tenantResult) =>
|
||||||
|
{
|
||||||
|
var costResult = tenantResult.Costs[cost];
|
||||||
|
return new Tuple<decimal, decimal, decimal>(sum.Item1 + costResult.TotalAmount,
|
||||||
|
sum.Item2 + costResult.PastAmount, sum.Item3 + costResult.FutureAmount);
|
||||||
|
});
|
||||||
|
|
||||||
|
str.Append("Auf Mieter umgelegt:\n");
|
||||||
|
str.Append("- Unvermietete Wohnungen werden umgelegt: ");
|
||||||
|
str.Append(cost.ShiftUnrented ? "Ja\n" : "Nein\n");
|
||||||
|
str.Append("- In dieser Abrechnung: ");
|
||||||
|
str.Append(tenantAmount.CeilToString());
|
||||||
|
str.Append(" €\n");
|
||||||
|
str.Append("- In vergangener Abrechnung (geschätzt): ");
|
||||||
|
str.Append(pastTenantAmount.CeilToString());
|
||||||
|
str.Append(" €\n");
|
||||||
|
str.Append("- In zukünftiger Abrechnung (geschätzt): ");
|
||||||
|
str.Append(futureTenantAmount.CeilToString());
|
||||||
|
str.Append(" €\n");
|
||||||
|
|
||||||
|
var t = totalAmount - (tenantAmount + pastTenantAmount + futureTenantAmount);
|
||||||
|
str.Append("Verbleibende Kosten: ");
|
||||||
|
str.Append(t.CeilToString());
|
||||||
|
str.Append(" €\n");
|
||||||
|
|
||||||
|
landlordAmount += t;
|
||||||
|
|
||||||
|
str.Append("\n---\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
str.Append("Nicht umgelegte Kosten: ");
|
||||||
|
str.Append(landlordAmount.CeilToString());
|
||||||
|
str.Append(" €");
|
||||||
|
|
||||||
|
return str.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -15,12 +15,12 @@
|
|||||||
<DockPanel Margin="12, 12, 12, 0"
|
<DockPanel Margin="12, 12, 12, 0"
|
||||||
DockPanel.Dock="Top">
|
DockPanel.Dock="Top">
|
||||||
<Label DockPanel.Dock="Left"
|
<Label DockPanel.Dock="Left"
|
||||||
Content="Mieter:"
|
Content="Details zu:"
|
||||||
Width="180"
|
Width="180"
|
||||||
Foreground="{x:Static local:Constants.SubMainColor}" />
|
Foreground="{x:Static local:Constants.SubMainColor}" />
|
||||||
|
|
||||||
<ComboBox
|
<ComboBox
|
||||||
ItemsSource="{Binding Path=Tenants, RelativeSource={RelativeSource AncestorType=pages:DetailsPage}}"
|
ItemsSource="{Binding Path=Items, RelativeSource={RelativeSource AncestorType=pages:DetailsPage}}"
|
||||||
SelectionChanged="OnSelectedTenantChanged"
|
SelectionChanged="OnSelectedTenantChanged"
|
||||||
x:Name="TenantComboBox">
|
x:Name="TenantComboBox">
|
||||||
<ComboBox.ItemTemplate>
|
<ComboBox.ItemTemplate>
|
||||||
|
|||||||
@@ -5,15 +5,26 @@ using UCalc.Models;
|
|||||||
|
|
||||||
namespace UCalc.Pages
|
namespace UCalc.Pages
|
||||||
{
|
{
|
||||||
|
public class DetailsItem
|
||||||
|
{
|
||||||
|
public Tenant Tenant { get; }
|
||||||
|
public string Name => Tenant != null ? Tenant.Name : "Kostenübersicht";
|
||||||
|
|
||||||
|
public DetailsItem(Tenant tenant)
|
||||||
|
{
|
||||||
|
Tenant = tenant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public partial class DetailsPage
|
public partial class DetailsPage
|
||||||
{
|
{
|
||||||
public Model Model { get; set; }
|
public Model Model { get; set; }
|
||||||
private Billing _billing;
|
private Billing _billing;
|
||||||
public ObservableCollection<Tenant> Tenants { get; }
|
public ObservableCollection<DetailsItem> Items { get; }
|
||||||
|
|
||||||
public DetailsPage()
|
public DetailsPage()
|
||||||
{
|
{
|
||||||
Tenants = new ObservableCollection<Tenant>();
|
Items = new ObservableCollection<DetailsItem>();
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,10 +39,11 @@ namespace UCalc.Pages
|
|||||||
}
|
}
|
||||||
|
|
||||||
_billing = Model.Dump();
|
_billing = Model.Dump();
|
||||||
Tenants.Clear();
|
Items.Clear();
|
||||||
|
Items.Add(new DetailsItem(null));
|
||||||
foreach (var tenant in _billing.Tenants)
|
foreach (var tenant in _billing.Tenants)
|
||||||
{
|
{
|
||||||
Tenants.Add(tenant);
|
Items.Add(new DetailsItem(tenant));
|
||||||
}
|
}
|
||||||
|
|
||||||
TenantComboBox.IsEnabled = true;
|
TenantComboBox.IsEnabled = true;
|
||||||
@@ -41,15 +53,21 @@ namespace UCalc.Pages
|
|||||||
|
|
||||||
private void OnSelectedTenantChanged(object sender, SelectionChangedEventArgs e)
|
private void OnSelectedTenantChanged(object sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
var tenant = (Tenant) ((ComboBox) sender).SelectedItem;
|
var item = (DetailsItem) ((ComboBox) sender).SelectedItem;
|
||||||
|
|
||||||
if (tenant == null)
|
if (item == null)
|
||||||
{
|
{
|
||||||
CalculationTextBox.Text = "Bitte wählen Sie einen Mieter aus, um die Berechnungen anzuzeigen.";
|
CalculationTextBox.Text = "Bitte wählen Sie einen Mieter aus, um die Berechnungen anzuzeigen.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = BillingCalculator.CalculateForTenant(_billing, tenant);
|
if (item.Tenant == null)
|
||||||
|
{
|
||||||
|
CalculationTextBox.Text = BillingCalculator.CalculateCostOverview(_billing);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = BillingCalculator.CalculateForTenant(_billing, item.Tenant);
|
||||||
|
|
||||||
CalculationTextBox.Text = result.DetailsForLandlord;
|
CalculationTextBox.Text = result.DetailsForLandlord;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user