327 lines
12 KiB
C#
327 lines
12 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.ComponentModel;
|
|
using BS.Shared.Core;
|
|
using BS.Shared.Services;
|
|
using BeWo.Data.Access;
|
|
using BeWo.Data.Entities;
|
|
using DevExpress.XtraReports.UI;
|
|
using BeWo.Report.ReportObjects;
|
|
using BeWo.Report;
|
|
using System.Collections.Generic;
|
|
|
|
namespace BeWo.ZMDLengerichReports
|
|
{
|
|
public partial class Stundenzettel : DevExpress.XtraReports.UI.XtraReport, IBeWoReport<ServicesOverviewRO>
|
|
{
|
|
public Stundenzettel()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
public void SetReportDataSource(ServicesOverviewRO pRO)
|
|
{
|
|
CalculateFLSSollIstThisMonth(pRO);
|
|
//CalculateFLSSollIstTotal(pRO);
|
|
|
|
|
|
if (pRO.Services != null)
|
|
{
|
|
List<ServicesOverviewRO.ServiceDetail> servicesBillable = new List<ServicesOverviewRO.ServiceDetail>();
|
|
|
|
foreach (ServicesOverviewRO.ServiceDetail s in pRO.Services)
|
|
{
|
|
if (s.IsBillable)
|
|
{
|
|
s.Minutes = s.Minutes*(double)pRO.RateFactor;
|
|
servicesBillable.Add(s);
|
|
}
|
|
}
|
|
|
|
pRO.Services = servicesBillable;
|
|
}
|
|
|
|
this.bindingSource1.DataSource = pRO;
|
|
}
|
|
|
|
public void CalculateFLSSollIstTotal(ServicesOverviewRO pRO)
|
|
{
|
|
double totalFLMBillable = pRO.TotalFLMBillable * (double)pRO.RateFactor;
|
|
|
|
decimal flmSoll = 0;
|
|
|
|
DateTime startHP = pRO.StartDate;
|
|
|
|
if (!String.IsNullOrEmpty(pRO.ApprovedStartDate))
|
|
{
|
|
DateTime.TryParse(pRO.ApprovedStartDate, out startHP);
|
|
}
|
|
else
|
|
{
|
|
if (!String.IsNullOrEmpty(pRO.RequestedStartDate))
|
|
{
|
|
DateTime.TryParse(pRO.RequestedStartDate, out startHP);
|
|
}
|
|
}
|
|
|
|
TimeSpan ts = pRO.StartDate.Subtract(startHP);
|
|
|
|
decimal flsPerWeek = pRO.ApprovedFLSPerWeek;
|
|
int months = (int)Math.Round(ts.TotalDays / 30);
|
|
|
|
|
|
decimal flmSollBisEndeInsgesamtNachAlterBerechnung = 0;
|
|
int daysPassed = 0;
|
|
|
|
ts = pRO.EndDate.Subtract(startHP);
|
|
|
|
daysPassed = ts.Days + 1;
|
|
|
|
flmSollBisEndeInsgesamtNachAlterBerechnung = ((daysPassed / 7m) * flsPerWeek) * 60;
|
|
|
|
if (!pRO.FreeMinutesThisMonth.HasValue)
|
|
pRO.FreeMinutesThisMonth = 0;
|
|
decimal minutenIstGesamt = flmSollBisEndeInsgesamtNachAlterBerechnung - pRO.FreeMinutesThisMonth.Value;
|
|
|
|
flmSoll = (flsPerWeek * 4.34m * 60) * months;
|
|
|
|
|
|
decimal minutenLetztenMonat = minutenIstGesamt - (decimal)totalFLMBillable;
|
|
|
|
pRO.FreeMinutesThisMonth = flmSoll - minutenLetztenMonat;
|
|
|
|
|
|
}
|
|
|
|
public void CalculateFLSSollIstThisMonth(ServicesOverviewRO ro)
|
|
{
|
|
if (ro.SupportConceptCostBearer != null && ro.SupportConceptCostBearer.CostBearer2SupportConceptOid != null)
|
|
{
|
|
if (ro.SupportConceptCostBearer.StartDate != null)
|
|
{
|
|
CostBearer2SupportConcept c2s =
|
|
DAOFactory.GenericDAO.LoadByID<CostBearer2SupportConcept>(
|
|
ro.SupportConceptCostBearer.CostBearer2SupportConceptOid.Value);
|
|
|
|
var calc = Calculations.GetInstance(c2s.CostBearer.ID);
|
|
DateTime startHilfeplan = ro.SupportConceptCostBearer.StartDate.Value;
|
|
DateTime startAuswerteMonat = ro.StartDate;
|
|
|
|
decimal flmSollLetztenMonat = 0;
|
|
decimal flmSollDiesenMonat = 0;
|
|
decimal flmIst = 0;
|
|
int daysPassed = 0;
|
|
|
|
|
|
TimeSpan ts;
|
|
if (startAuswerteMonat > startHilfeplan)
|
|
ts = ro.EndDate.Subtract(startAuswerteMonat);
|
|
else
|
|
ts = ro.EndDate.Subtract(startHilfeplan);
|
|
DateTime startFuerAbsenceDays = startAuswerteMonat;
|
|
if (startAuswerteMonat < startHilfeplan && startHilfeplan.Day > 1)
|
|
startFuerAbsenceDays = startHilfeplan;
|
|
daysPassed = ts.Days + 1;
|
|
|
|
DateTime endeAuswerteMonats = startAuswerteMonat.AddMonths(1);
|
|
endeAuswerteMonats = new DateTime(endeAuswerteMonats.Year, endeAuswerteMonats.Month, 1);
|
|
bool berechneAlteMethode = startAuswerteMonat < new DateTime(2013, 3, 1);
|
|
|
|
|
|
int abcenceDays = 0;
|
|
decimal abcenceMaxMinutes = 0;
|
|
|
|
if (berechneAlteMethode)
|
|
{
|
|
abcenceDays = GetAbsenceDaysInRange(ro.SupportConceptCostBearer.SupportConcept.Customer.AbsenceTimes,
|
|
startFuerAbsenceDays, endeAuswerteMonats, ro.ApprovedFLSPerWeek);
|
|
abcenceMaxMinutes = GetAbsenceMaxMinutesInRange(ro.SupportConceptCostBearer.SupportConcept.Customer.AbsenceTimes,
|
|
startFuerAbsenceDays, endeAuswerteMonats, ro.ApprovedFLSPerWeek);
|
|
}
|
|
ro.ApprovedFLSPerMonth = ro.ApprovedFLSPerWeek * 4.34m * 60m;
|
|
daysPassed -= abcenceDays;
|
|
if ((startHilfeplan.Day > 1 && startHilfeplan > startAuswerteMonat) || abcenceDays > 0) //Bin im erstenMonat && Hilfeplan fängt mitten im Monat an
|
|
{
|
|
ro.ApprovedFLSPerMonth = ro.ApprovedFLSPerWeek * (daysPassed / 7m) * 60m;
|
|
|
|
}
|
|
ro.ApprovedFLSPerMonth += abcenceMaxMinutes;
|
|
|
|
if (ro.ApprovedFLSPerMonth < 0)
|
|
ro.ApprovedFLSPerMonth = 0;
|
|
|
|
DateTime startIterator = startHilfeplan;
|
|
while (startIterator < ro.EndDate)
|
|
{
|
|
decimal flsSollPerWeekThisMonth = calc.GetApprovedHoursPerWeek(ro.SupportConceptCostBearer, startIterator, false) ?? 0;
|
|
|
|
decimal flmSollThisMonth = flsSollPerWeekThisMonth * 4.34m * 60m;
|
|
|
|
DateTime endeDesMonats = startIterator.AddMonths(1);
|
|
endeDesMonats = new DateTime(endeDesMonats.Year, endeDesMonats.Month, 1);
|
|
daysPassed = endeDesMonats.Subtract(startIterator).Days;
|
|
|
|
DateTime nextstart = startIterator.AddMonths(1);
|
|
nextstart = new DateTime(nextstart.Year, nextstart.Month, 1);
|
|
berechneAlteMethode = startIterator < new DateTime(2013, 3, 1);
|
|
abcenceDays = 0;
|
|
if (berechneAlteMethode)
|
|
{
|
|
abcenceDays = GetAbsenceDaysInRange(ro.SupportConceptCostBearer.SupportConcept.Customer.AbsenceTimes,
|
|
startIterator, nextstart, flsSollPerWeekThisMonth);
|
|
daysPassed -= abcenceDays;
|
|
}
|
|
|
|
|
|
|
|
if (startIterator.Day > 1 || abcenceDays > 0) //Bin im erstenMonat && Hilfeplan fängt mitten im Monat an
|
|
{
|
|
flmSollThisMonth = flsSollPerWeekThisMonth * (daysPassed / 7m) * 60m;
|
|
}
|
|
|
|
if (berechneAlteMethode)
|
|
flmSollThisMonth += GetAbsenceMaxMinutesInRange(ro.SupportConceptCostBearer.SupportConcept.Customer.AbsenceTimes, startIterator, nextstart, flsSollPerWeekThisMonth);
|
|
|
|
|
|
|
|
if (startIterator < ro.StartDate)
|
|
flmSollLetztenMonat += flmSollThisMonth;
|
|
else
|
|
{
|
|
flmSollDiesenMonat = flmSollThisMonth;
|
|
}
|
|
|
|
|
|
startIterator = nextstart;
|
|
}
|
|
|
|
|
|
|
|
// Berechne FLM Ist bis Ende des Monats vom Quittierungsbeleg
|
|
IList<ServiceRecord> allServiceRecords = c2s.ServiceRecords;
|
|
decimal minutenIst = 0;
|
|
|
|
DateTime end = ro.EndDate.Date.AddDays(1);
|
|
|
|
Dictionary<long, bool> groupBookingDict = new Dictionary<long, bool>();
|
|
foreach (var item in allServiceRecords)
|
|
{
|
|
if (!item.GroupOid.HasValue || !groupBookingDict.ContainsKey(item.GroupOid.Value))
|
|
{
|
|
if (item.Start != null)
|
|
{
|
|
if (item.Start >= ro.SupportConceptCostBearer.StartDate.Value && item.Start.Value < end)
|
|
{
|
|
if (item.ServiceDescription != null &&
|
|
item.ServiceDescription.ServiceCategory != null &&
|
|
item.ServiceDescription.ServiceCategory.IsBillable)
|
|
{
|
|
var p = item.ServiceDescription.ServiceCategory.ProzentAbrechnung;
|
|
if (item.ServiceDescription.ProzentAbrechnung.HasValue)
|
|
{
|
|
p = item.ServiceDescription.ProzentAbrechnung.Value;
|
|
|
|
}
|
|
|
|
minutenIst += (item.RoundedDuration * p) / 100;
|
|
|
|
if (item.GroupOid.HasValue)
|
|
groupBookingDict.Add(item.GroupOid.Value, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
minutenIst *= ro.RateFactor;
|
|
|
|
decimal minutenBisLetztenMonat = minutenIst - ((decimal)ro.TotalFLMBillable * ro.RateFactor);
|
|
|
|
ro.FreeMinutesThisMonth = flmSollLetztenMonat - minutenBisLetztenMonat;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
private decimal GetAbsenceMaxMinutesInRange(List<BS.Shared.DataContracts.AbsenceTimeDC> absenceTimes, DateTime start, DateTime end, decimal flsPerWeek)
|
|
{
|
|
decimal flsPerDay = flsPerWeek / 7;
|
|
decimal maxMinutes = 0;
|
|
if (absenceTimes != null)
|
|
{
|
|
foreach (var item in absenceTimes)
|
|
{
|
|
decimal tage = 0;
|
|
decimal maxMinutesPerDay = 0;
|
|
|
|
if (item.Reason.BillableMinutes.HasValue && item.Reason.BillableMinutes.Value > 0 && item.Reason.BillableMinutes < (flsPerWeek * 60))
|
|
{
|
|
int daysInMonth = DateTime.DaysInMonth(start.Year, start.Month);
|
|
maxMinutesPerDay = (item.Reason.BillableMinutes.Value * 4.34m) / daysInMonth;
|
|
|
|
DateTimeSpan span = new DateTimeSpan();
|
|
|
|
span.StartDate = start;
|
|
|
|
if (item.Start.HasValue && item.Start.Value > span.StartDate)
|
|
{
|
|
span.StartDate = item.Start.Value;
|
|
}
|
|
span.EndDate = end;
|
|
if (item.End.HasValue && item.End.Value.Date.AddDays(1) < span.EndDate)
|
|
{
|
|
span.EndDate = item.End.Value.Date.AddDays(1);
|
|
}
|
|
if (span.EndDate >= start && span.StartDate < end)
|
|
{
|
|
tage += (decimal)span.GetTimeSpan().TotalHours;
|
|
}
|
|
}
|
|
tage /= 24;
|
|
maxMinutes += (maxMinutesPerDay * tage);
|
|
//}
|
|
}
|
|
}
|
|
|
|
return maxMinutes;
|
|
}
|
|
|
|
private int GetAbsenceDaysInRange(List<BS.Shared.DataContracts.AbsenceTimeDC> absenceTimes, DateTime start, DateTime end, decimal flsPerWeek)
|
|
{
|
|
decimal tage = 0;
|
|
if (absenceTimes != null)
|
|
{
|
|
foreach (var item in absenceTimes)
|
|
{
|
|
//if (!String.IsNullOrEmpty(item.AbsenceReason.Description) && (item.AbsenceReason.Description.ToLower().IndexOf("urlaub") >= 0
|
|
// || item.AbsenceReason.Description.ToLower().IndexOf("krank") >= 0))
|
|
//{
|
|
if (item.Reason.BillableMinutes.HasValue && item.Reason.BillableMinutes.Value > 0 && item.Reason.BillableMinutes < (flsPerWeek * 60))
|
|
{
|
|
|
|
DateTimeSpan span = new DateTimeSpan();
|
|
|
|
span.StartDate = start;
|
|
|
|
if (item.Start.HasValue && item.Start.Value > span.StartDate)
|
|
{
|
|
span.StartDate = item.Start.Value;
|
|
}
|
|
span.EndDate = end;
|
|
if (item.End.HasValue && item.End.Value.Date.AddDays(1) < span.EndDate)
|
|
{
|
|
span.EndDate = item.End.Value.Date.AddDays(1);
|
|
}
|
|
if (span.EndDate >= start && span.StartDate < end)
|
|
{
|
|
tage += (decimal)span.GetTimeSpan().TotalHours;
|
|
}
|
|
}
|
|
//}
|
|
}
|
|
}
|
|
tage /= 24;
|
|
return (int)tage;
|
|
}
|
|
}
|
|
}
|