456 lines
20 KiB
C#
456 lines
20 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text.RegularExpressions;
|
|
using System.Windows.Threading;
|
|
using BeWo.Data.Access;
|
|
using BeWo.Data.Entities;
|
|
using BeWo.Report;
|
|
using BeWo.Report.ReportObjects;
|
|
using BeWo.Service.DCEntityMapper;
|
|
using BeWo.Service.Plugins;
|
|
using BS.Shared;
|
|
using BS.Shared.Core;
|
|
using BS.Shared.DataContracts;
|
|
using BS.Shared.Extensions;
|
|
using BS.Shared.Services;
|
|
using DevExpress.XtraReports.UI;
|
|
|
|
namespace LebenshilfeBadKreuznach
|
|
{
|
|
public partial class Quittierungsbeleg : XtraReport, IBeWoReport<ServicesOverviewRO>
|
|
{
|
|
public Quittierungsbeleg()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
public void SetReportDataSource(ServicesOverviewRO pRO)
|
|
{
|
|
|
|
// Get calling method name
|
|
//StackTrace stackTrace = new StackTrace();
|
|
//Debug.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);
|
|
|
|
bool hatGruppen = false;
|
|
double bg1 = 0;
|
|
double bg2 = 0;
|
|
double gruppe = 0;
|
|
|
|
//if (pRO == null)
|
|
// return;
|
|
|
|
if (pRO.Services != null)
|
|
{
|
|
List<ServicesOverviewRO.ServiceDetail> servicesBillable = new List<ServicesOverviewRO.ServiceDetail>();
|
|
|
|
foreach (var sd in pRO.Services)
|
|
{
|
|
CreateGoalList(sd);
|
|
if (sd.ServiceCategory != null && sd.ServiceCategory.StartsWith("BG1"))
|
|
{
|
|
bg1 += Math.Round(sd.Minutes / 60, 2, MidpointRounding.AwayFromZero);
|
|
}
|
|
else if (sd.ServiceCategory != null && sd.ServiceCategory.StartsWith("BG2"))
|
|
{
|
|
bg2 += Math.Round(sd.Minutes / 60, 2, MidpointRounding.AwayFromZero);
|
|
}
|
|
else if (sd.ServiceCategory != null && sd.ServiceCategory.StartsWith("Gruppe"))
|
|
{
|
|
gruppe += Math.Round(sd.Minutes / 60, 2, MidpointRounding.AwayFromZero);
|
|
}
|
|
servicesBillable.Add(sd);
|
|
}
|
|
|
|
pRO.Services = servicesBillable;
|
|
}
|
|
|
|
var std = BerechneBewilligungenProWoche(pRO);
|
|
pRO.ApprovedFLSPerWeek = std.BG1;
|
|
pRO.ApprovedFLSPerWeekTotal = std.BG2;
|
|
pRO.ApprovedFLSTotal = std.Gruppe;
|
|
|
|
lblBg1.Text = String.Format("{0:0.00}", bg1);
|
|
lblBg2.Text = String.Format("{0:0.00}", bg2);
|
|
lblGruppe.Text = String.Format("{0:0.00}", gruppe);
|
|
|
|
ErstelleAbwesenheitenTabelle(pRO);
|
|
|
|
|
|
//Einmal getätigte Unterschriften sollen nicht verfallen, auch wenn es anschließend Ergänzungen gab
|
|
var serviceRecordOids = pRO.Services.Select(service => service.ServiceRecordOid).ToList();
|
|
if (serviceRecordOids.Count > 0 && (pRO.EmployeeSignature == null || pRO.CustomerSignature == null))
|
|
{
|
|
var sql = @"
|
|
select distinct crs.SignatureImage, crs.SignatureType, crs.InsTs from
|
|
confirmationreceiptsignature crs
|
|
inner join confirmationreceiptsignature2servicerecord c2s on c2s.ConfirmationReceiptSignatureOid = crs.Oid
|
|
where c2s.ServiceRecordOid in (:LISTE)
|
|
order by crs.oid desc
|
|
";
|
|
sql = sql.Replace(":LISTE", String.Join(",", serviceRecordOids));
|
|
var sqlResult = DAOFactory.SearchDAO.GetSqlResult(sql);
|
|
|
|
foreach (object[] item in sqlResult)
|
|
{
|
|
var sig = item[0] as String;
|
|
var t = (sbyte)item[1];
|
|
var dt = (DateTime)item[2];
|
|
|
|
if (t == 0)
|
|
{
|
|
if (pRO.EmployeeSignature == null)
|
|
{
|
|
pRO.EmployeeSignature = ImageUtils.ConvertBase64StringToBitmap(sig);
|
|
pRO.EmployeeSignatureDate = dt;
|
|
}
|
|
}
|
|
else if (t == 1)
|
|
{
|
|
if (pRO.CustomerSignature == null)
|
|
{
|
|
pRO.CustomerSignature = ImageUtils.ConvertBase64StringToBitmap(sig);
|
|
pRO.CustomerSignatureDate = dt;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bindingSource1.DataSource = pRO;
|
|
}
|
|
|
|
public static void CreateGoalList(ServicesOverviewRO.ServiceDetail sd)
|
|
{
|
|
var serviceRecord = DAOFactory.GenericDAO.LoadByID<ServiceRecord>(sd.ServiceRecordOid);
|
|
var srDc = MapperFactory.ServiceRecordDC_ServiceRecord.MapToNewDC(serviceRecord);
|
|
|
|
sd.GoalList = String.Empty;
|
|
if (srDc.Goals != null && srDc.Goals.Count > 0)
|
|
{
|
|
Dictionary<long, string> key2Value = new Dictionary<long, string>();
|
|
Dictionary<long, long> ziel2kapitel = new Dictionary<long, long>();
|
|
Dictionary<long, string> ziel2value = new Dictionary<long, string>();
|
|
|
|
//masnahmen und foreach Schleife dazu können ab 2024 raus - ist auch getestet. Die brauchen keine Maßnahmen mehr dokumentieren und haben die auch alle gelöscht...
|
|
var masnahmen = srDc.Goals.Where(g => g.Type == BS.Shared.ValueListEntryType.SupportConceptIndividualGoalType || g.Type == BS.Shared.ValueListEntryType.SupportConceptGoalType).OrderBy(g => g.ParentOid).ThenBy(g => g.TypeDescription).ToList();
|
|
var kapitel = srDc.Goals.Where(g => (g.Type == BS.Shared.ValueListEntryType.SupportConceptIndividualGoalCategoryType || g.Type == BS.Shared.ValueListEntryType.SupportConceptGoalCategoryType) && (g.TypeDescription != null && g.TypeDescription.StartsWith("Kapitel")) || (g.DisplayName != null && g.DisplayName.StartsWith("Kapitel"))).OrderBy(g => g.DisplayName).ToList();
|
|
var ziele = srDc.Goals.Where(g => (g.Type == BS.Shared.ValueListEntryType.SupportConceptIndividualGoalCategoryType || g.Type == BS.Shared.ValueListEntryType.SupportConceptGoalCategoryType) && !g.DisplayName.StartsWith("Kapitel")).OrderBy(g => g.DisplayName).ToList();
|
|
srDc.Goals = srDc.Goals.Where(g => g.Type == BS.Shared.ValueListEntryType.SupportConceptIndividualGoalCategoryType || g.Type == BS.Shared.ValueListEntryType.SupportConceptGoalCategoryType).OrderBy(g => g.ParentOid).ToList();
|
|
|
|
foreach (var goal in kapitel) //nimm zuerst alle Kapitel
|
|
{
|
|
var key = goal.ValueListEntryOid.Value;
|
|
string value = null;
|
|
if (!string.IsNullOrEmpty(goal.TypeDescription))
|
|
{
|
|
value = goal.TypeDescription;
|
|
}
|
|
else
|
|
{
|
|
value = goal.Abbreviation;
|
|
}
|
|
|
|
key2Value.Add(key, value);
|
|
}
|
|
foreach (var goal in ziele) //dann füge ziele zu bestehendem Kapitel - falls nicht eingetragen ergänze Kapitel
|
|
{
|
|
var key = goal.ValueListEntryOid.Value;
|
|
string value = null;
|
|
if (!string.IsNullOrEmpty(goal.TypeDescription))
|
|
{
|
|
value = goal.TypeDescription;
|
|
}
|
|
else
|
|
{
|
|
value = goal.Abbreviation;
|
|
}
|
|
|
|
if (goal.ParentOid.HasValue)
|
|
{
|
|
ziel2value[key] = value;
|
|
if (key2Value.ContainsKey(goal.ParentOid.Value))
|
|
{
|
|
ziel2kapitel.Add(key, goal.ParentOid.Value);
|
|
}
|
|
else
|
|
{
|
|
var goalParent = DAOFactory.GenericDAO.LoadByID<ValueListEntry>(goal.ParentOid.Value);
|
|
var parent = MapperFactory.ValueListEntryDC_ValueListEntry.MapToNewDC(goalParent);
|
|
string parentValue;
|
|
if (!string.IsNullOrEmpty(parent.TypeDescription))
|
|
{
|
|
parentValue = parent.TypeDescription;
|
|
}
|
|
else
|
|
{
|
|
parentValue = parent.Abbreviation;
|
|
}
|
|
|
|
key2Value.Add(goal.ParentOid.Value, parentValue);
|
|
ziel2kapitel.Add(key, goal.ParentOid.Value);
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
key2Value.Add(key, value);
|
|
}
|
|
}
|
|
foreach (var m in masnahmen)
|
|
{
|
|
var key = m.ValueListEntryOid.Value;
|
|
string value = null;
|
|
if (!string.IsNullOrEmpty(m.TypeDescription))
|
|
{
|
|
value = m.TypeDescription;
|
|
}
|
|
else
|
|
{
|
|
value = m.Abbreviation;
|
|
}
|
|
if (m.ParentOid.HasValue)
|
|
{
|
|
var goalParent = DAOFactory.GenericDAO.LoadByID<ValueListEntry>(m.ParentOid.Value);
|
|
var parent = MapperFactory.ValueListEntryDC_ValueListEntry.MapToNewDC(goalParent);
|
|
string parentValue = null;
|
|
if (!string.IsNullOrEmpty(parent.TypeDescription))
|
|
{
|
|
parentValue = parent.TypeDescription;
|
|
}
|
|
else
|
|
{
|
|
parentValue = parent.Abbreviation;
|
|
}
|
|
|
|
if (!ziel2kapitel.ContainsKey(m.ParentOid.Value)) //kein Ziel gewählt
|
|
{
|
|
if (parent.ParentOid.HasValue)
|
|
{
|
|
ziel2kapitel.Add(m.ParentOid.Value, parent.ParentOid.Value);
|
|
}
|
|
}
|
|
if (!ziel2value.ContainsKey(m.ParentOid.Value)) //kein Ziel gewählt
|
|
{
|
|
{
|
|
ziel2value[m.ParentOid.Value] = parentValue;
|
|
}
|
|
}
|
|
|
|
ziel2value[m.ParentOid.Value] += ", " + value;
|
|
|
|
if (!key2Value.ContainsKey(parent.ParentOid.Value)) //und kein Kapitel gewählt
|
|
{
|
|
var parentParent = DAOFactory.GenericDAO.LoadByID<ValueListEntry>(parent.ParentOid.Value);
|
|
var parentKapitel = MapperFactory.ValueListEntryDC_ValueListEntry.MapToNewDC(parentParent);
|
|
string kapitelValue = null;
|
|
if (!string.IsNullOrEmpty(parentKapitel.TypeDescription))
|
|
{
|
|
kapitelValue = parentKapitel.TypeDescription;
|
|
}
|
|
else
|
|
{
|
|
kapitelValue = parentKapitel.Abbreviation;
|
|
}
|
|
key2Value.Add(parent.ParentOid.Value, kapitelValue);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
key2Value.Add(key, value);
|
|
}
|
|
}
|
|
|
|
|
|
foreach (var item in ziel2kapitel)
|
|
{
|
|
key2Value[item.Value] += ", " + ziel2value[item.Key];
|
|
}
|
|
|
|
foreach (KeyValuePair<long, string> item in key2Value.OrderBy(key => key.Value))
|
|
{
|
|
if (sd.GoalList.Length > 0)
|
|
{
|
|
sd.GoalList += ", ";
|
|
}
|
|
sd.GoalList += item.Value;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ErstelleAbwesenheitenTabelle(ServicesOverviewRO pRo)
|
|
{
|
|
var reportSpan = new DateTimeSpan(pRo.StartDate, pRo.EndDate);
|
|
var customer = MapperFactory.CustomerDC_Customer.MapToNewDC(DAOFactory.GenericDAO.GetByID<Customer>(pRo.CustomerOid));
|
|
Dictionary<string, List<AbsenceTimeDC>> allAbsInSpan = new Dictionary<string, List<AbsenceTimeDC>>();
|
|
|
|
if (customer != null && customer.AbsenceTimes != null && customer.AbsenceTimes.Count > 0)
|
|
{
|
|
foreach (var abs in customer.AbsenceTimes)
|
|
{
|
|
abs.End = abs.End.HasValue ? abs.End.Value : pRo.EndDate;
|
|
|
|
if (abs.Start >= pRo.StartDate && abs.Start <= pRo.EndDate || abs.End >= pRo.StartDate && abs.End <= pRo.EndDate)
|
|
{
|
|
if (!allAbsInSpan.ContainsKey(abs.Reason.Description))
|
|
allAbsInSpan.Add(abs.Reason.Description, new List<AbsenceTimeDC>());
|
|
allAbsInSpan[abs.Reason.Description].Add(abs);
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (var abs in allAbsInSpan)
|
|
{
|
|
if (abs.Key.ToLower() == "klient urlaub")
|
|
{
|
|
lblKlientUrlaub.Visible = true;
|
|
foreach (var u in abs.Value)
|
|
{
|
|
lblKlientUrlaub.Text += u.Start.Value.Date == u.End.Value.Date ? string.Format("am {0:dd.MM.yyyy}", u.Start) : string.Format("vom {0:dd.MM.yyyy} bis {1:dd.MM.yyyy}", u.Start, u.End);
|
|
if (abs.Value.Last() != u)
|
|
lblKlientUrlaub.Text += ", ";
|
|
}
|
|
}
|
|
else if (abs.Key.ToLower() == "klient krank")
|
|
{
|
|
lblKlientKrank.Visible = true;
|
|
foreach (var u in abs.Value)
|
|
{
|
|
lblKlientKrank.Text += u.Start.Value.Date == u.End.Value.Date ? string.Format("am {0:dd.MM.yyyy}", u.Start) : string.Format("vom {0:dd.MM.yyyy} bis {1:dd.MM.yyyy}", u.Start, u.End);
|
|
if (abs.Value.Last() != u)
|
|
lblKlientKrank.Text += ", ";
|
|
}
|
|
}
|
|
}
|
|
|
|
if (allAbsInSpan.Count > 0)
|
|
{
|
|
int newRows = 0;
|
|
int index = 1;
|
|
foreach (var abs in allAbsInSpan)
|
|
{
|
|
if (abs.Key.ToLower() == "klient krank" || abs.Key.ToLower() == "klient urlaub")
|
|
continue;
|
|
|
|
foreach (var at in abs.Value)
|
|
{
|
|
DevExpress.XtraReports.UI.XRTableRow row = null;
|
|
if (index < xrTableAbwesenheiten.Rows.Count)
|
|
{
|
|
row = xrTableAbwesenheiten.Rows[index];
|
|
}
|
|
else
|
|
{
|
|
row = xrTableAbwesenheiten.InsertRowBelow(xrTableAbwesenheiten.Rows[xrTableAbwesenheiten.Rows.Count - 1]);
|
|
newRows++;
|
|
}
|
|
|
|
row.Cells[0].Text = String.Format("{0:dd.MM.yyyy}", at.Start);
|
|
int? days = null;
|
|
|
|
if (at.End.HasValue)
|
|
{
|
|
row.Cells[1].Text = String.Format("{0:dd.MM.yyyy}", at.End);
|
|
days = (int)at.End.Value.Subtract(at.Start.Value).TotalDays + 1;
|
|
}
|
|
else
|
|
{
|
|
row.Cells[1].Text = "unbekannt";
|
|
}
|
|
|
|
row.Cells[2].Text = days != null ? String.Format("{0:0}", days) : "";
|
|
row.Cells[3].Text = at.Reason != null && !at.Reason.Description.IsNullOrEmpty() ? at.Reason.Description : "";
|
|
index++;
|
|
}
|
|
}
|
|
|
|
if (newRows > 0)
|
|
{
|
|
lblUnterschriftKlient.Top += newRows * 20;
|
|
}
|
|
}
|
|
}
|
|
|
|
private Stunden BerechneBewilligungenProWoche(ServicesOverviewRO pRO)
|
|
{
|
|
|
|
Stunden std = new Stunden();
|
|
if (pRO.SupportConceptCostBearer != null)
|
|
{
|
|
CostBearer2SupportConcept c2s = DAOFactory.GenericDAO.LoadByID<CostBearer2SupportConcept>(pRO.SupportConceptCostBearer.CostBearer2SupportConceptOid.Value);
|
|
var calc = PluginLoader.FindClass<BS.Shared.Services.Calculations>(c2s.CostBearer.ID) ?? BS.Shared.Services.Calculations.GetInstance(c2s.CostBearer.ID);
|
|
|
|
if (c2s.StartDate.HasValue && c2s.StartDate > pRO.StartDate)
|
|
{
|
|
pRO.StartDate = c2s.StartDate.Value;
|
|
}
|
|
|
|
//if (c2s.EndDate.HasValue && c2s.EndDate < pRO.EndDate)
|
|
//{
|
|
// pRO.EndDate = c2s.EndDate.Value;
|
|
//}
|
|
|
|
//var c2s = GetCostBearer2SupportConcept(pRo);
|
|
|
|
foreach (var scap in pRO.SupportConceptCostBearer.ApprovalPeriodList)
|
|
{
|
|
if (scap.StartDate <= pRO.EndDate && scap.EndDate >= pRO.StartDate)
|
|
{
|
|
var bewilligt = calc.GetApprovedHoursPerWeek(scap, pRO.SupportConceptCostBearer.CostBearer.CostRatePeriods) ?? 0;
|
|
if (scap.ServiceCategory != null)
|
|
{
|
|
if (scap.ServiceCategory.Name.StartsWith("BG1"))
|
|
{
|
|
std.BG1 += bewilligt;
|
|
}
|
|
else if (scap.ServiceCategory.Name.StartsWith("BG2"))
|
|
{
|
|
std.BG2 += bewilligt;
|
|
}
|
|
else if (scap.ServiceCategory.Name.StartsWith("Gruppe"))
|
|
{
|
|
std.Gruppe += bewilligt;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (std.BG1 == 0 && std.BG2 == 0 && std.Gruppe == 0)
|
|
{
|
|
foreach (var scap in pRO.SupportConceptCostBearer.ApprovalPeriodList)
|
|
{
|
|
if (std.BG1 != 0 && scap.StartDate <= pRO.EndDate)
|
|
{
|
|
var bewilligt = calc.GetApprovedHoursPerWeek(scap, pRO.SupportConceptCostBearer.CostBearer.CostRatePeriods) ?? 0;
|
|
if (scap.ServiceCategory.Name.StartsWith("BG1"))
|
|
{
|
|
std.BG1 += bewilligt;
|
|
}
|
|
else if (scap.ServiceCategory.Name.StartsWith("BG2"))
|
|
{
|
|
std.BG2 += bewilligt;
|
|
}
|
|
else if (scap.ServiceCategory.Name.StartsWith("Gruppe"))
|
|
{
|
|
std.Gruppe += bewilligt;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return std;
|
|
}
|
|
|
|
public class Stunden
|
|
{
|
|
public decimal BG1 { get; set; }
|
|
public decimal BG2 { get; set; }
|
|
public decimal Gruppe { get; set; }
|
|
}
|
|
}
|
|
}
|