Files
BeWoPlaner/BeWo/ViewModel/BookingSequenceVM.cs
2016-06-27 01:45:38 +02:00

635 lines
23 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using BeWo.Controls.Controls.Calendar;
using BS.Shared;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;
using BS.Shared.Extensions;
namespace BeWo.ViewModel
{
public class BookingSequenceVM : AbstractDCMapperVM<BookingSequenceDC>
{
public static string PropertyName_ChangedElements = "ChangedElements";
public static string PropertyName_Employee = "Employee";
public static string PropertyName_Frequency = "Frequency";
public static string PropertyName_Notice = "Notice";
public static string PropertyName_RepeatInterval = "RepeatInterval";
public static string PropertyName_Resource = "Resource";
public static string PropertyName_RootAppointment = "RootAppointment";
public static string PropertyName_SequenceEnd = "SequenceEnd";
private readonly Dictionary<int, Appointment> _ChangedElements = new Dictionary<int, Appointment>();
private readonly List<FrequencyTranslation> _PossibleFrequencies = new List<FrequencyTranslation>
{
new FrequencyTranslation
{
Frequency = ResourceBookingFrequencyType.Once,
Translation = "Einmalig"
},
new FrequencyTranslation
{
Frequency = ResourceBookingFrequencyType.Daily,
Translation = "jeden Tag"
},
new FrequencyTranslation
{
Frequency = ResourceBookingFrequencyType.Weekly
},
new FrequencyTranslation
{
Frequency = ResourceBookingFrequencyType.Monthly
},
new FrequencyTranslation
{
Frequency = ResourceBookingFrequencyType.MonthlyOnFirstDay
},
new FrequencyTranslation
{
Frequency = ResourceBookingFrequencyType.MonthlyOnLastDay
},
};
private Dictionary<int, Appointment> _AppointmentsInSpan = new Dictionary<int, Appointment>();
private CompactEmployeeDC _Employee;
private ResourceBookingFrequencyType _Frequency;
private bool _NeedsRecalculation = true;
private string _Notice;
private int _RepeatInterval = 1;
private ResourceDC _Resource;
private Appointment _RootAppointment;
private DateTime _SequenceEnd;
private DateTimeSpan _SpanToConsider;
public BookingSequenceVM(BookingSequenceDC pDC) : base(pDC, pDC.SequenceOid == null)
{
}
public List<Appointment> AppointmentsInSpan
{
get
{
if (_NeedsRecalculation && _SpanToConsider != null)
{
Dictionary<int, Appointment> lBak = _AppointmentsInSpan;
_AppointmentsInSpan = CalculateAppointmentsFromSequence(_SpanToConsider);
if (lBak.Count > 0)
{
foreach (int lPos in lBak.Keys)
{
if (_AppointmentsInSpan.ContainsKey(lPos) && _AppointmentsInSpan[lPos] != null)
{
lBak[lPos].Duration = _AppointmentsInSpan[lPos].Duration;
lBak[lPos].Notice = _AppointmentsInSpan[lPos].Notice;
lBak[lPos].Text = _AppointmentsInSpan[lPos].Text;
_AppointmentsInSpan[lPos] = lBak[lPos];
}
}
}
_NeedsRecalculation = false;
}
return _AppointmentsInSpan.Values.ToList();
}
}
public Dictionary<int, Appointment> ChangedElements
{
get { return _ChangedElements; }
}
public CompactEmployeeDC Employee
{
get { return _Employee; }
set
{
if (AreDifferent(_Employee, value))
{
_Employee = value;
// StoreDirtyInformation(AreDifferent(DataContract.Employee, value), PropertyName_Employee);
FirePropertyChanged(PropertyName_Employee);
}
}
}
public ResourceBookingFrequencyType Frequency
{
get { return _Frequency; }
set
{
if (AreDifferent(_Frequency, value))
{
_NeedsRecalculation = true;
_Frequency = value;
StoreDirtyInformation(AreDifferent(DataContract.Frequency, value), PropertyName_Frequency);
FirePropertyChanged(PropertyName_Frequency);
}
}
}
public string Notice
{
get { return _Notice; }
set
{
if (AreDifferent(_Notice, value))
{
_Notice = value;
StoreDirtyInformation(AreDifferent(DataContract.Notice, value), PropertyName_Notice);
FirePropertyChanged(PropertyName_Notice);
}
}
}
public List<FrequencyTranslation> PossibleFrequencies
{
get { return _PossibleFrequencies; }
}
public int RepeatInterval
{
get { return _RepeatInterval; }
set
{
if (AreDifferent(_RepeatInterval, value))
{
_NeedsRecalculation = true;
_RepeatInterval = value;
StoreDirtyInformation(AreDifferent(DataContract.RepeatInterval, value), PropertyName_RepeatInterval);
FirePropertyChanged(PropertyName_RepeatInterval);
}
}
}
public ResourceDC Resource
{
get { return _Resource; }
set
{
_Resource = value;
RootAppointment.Index = (int) value.ResourceOid.Value;
RootAppointment.Brush = value.GetBrush();
foreach (var iChanged in _ChangedElements)
{
iChanged.Value.Index = (int) value.ResourceOid.Value;
iChanged.Value.Brush = value.GetBrush();
}
FirePropertyChanged(PropertyName_Resource);
}
}
public Appointment RootAppointment
{
get { return _RootAppointment; }
set
{
if (AreDifferent(_RootAppointment, value))
{
_RootAppointment = value;
StoreDirtyInformation(!AreEqual(DataContract.RootBooking, _RootAppointment),
PropertyName_RootAppointment);
FirePropertyChanged(PropertyName_RootAppointment);
_RootAppointment.PropertyChanged += _RootAppointment_PropertyChanged;
_RootAppointment.Duration.PropertyChanged += Duration_PropertyChanged;
_RootAppointment.Duration.SynchEndDate = true;
}
}
}
public DateTime SequenceEnd
{
get { return _SequenceEnd; }
set
{
if (AreDifferent(_SequenceEnd, value))
{
value = value.Date.AddHours(23).AddMinutes(59);
_SequenceEnd = value;
StoreDirtyInformation(AreDifferent(DataContract.SequenceEnd, value), PropertyName_SequenceEnd);
FirePropertyChanged(PropertyName_SequenceEnd);
}
}
}
public DateTimeSpan SpanToConsider
{
get { return _SpanToConsider; }
set
{
if (AreDifferent(_SpanToConsider, value))
{
_SpanToConsider = value;
_NeedsRecalculation = true;
}
}
}
private bool IsChangedElementsDirty
{
get
{
if (DataContract.ChangedElements.Count != _ChangedElements.Count)
{
return true;
}
if (
DataContract.ChangedElements.Count(
dc =>
!_ChangedElements.ContainsKey(dc.SequencePosition) ||
!AreEqual(dc, _ChangedElements[dc.SequencePosition])) > 0)
{
return true;
}
return false;
}
}
public Dictionary<int, Appointment> CalculateAppointmentsFromSequence(DateTimeSpan pSpanToConsider)
{
var lResult = new Dictionary<int, Appointment>();
DateTime lCurrentStart = RootAppointment.Duration.StartDateTime;
DateTime lCurrentEnd = RootAppointment.Duration.EndDateTime;
int lCurrentPostion = 0;
int lCurrentSequencePosition = 0;
if (RootAppointment.Duration.Overlaps(pSpanToConsider))
{
lResult.Add(0, _RootAppointment);
}
lCurrentStart = Next(lCurrentStart, _Frequency);
lCurrentEnd = Next(lCurrentEnd, _Frequency);
if (_Frequency != ResourceBookingFrequencyType.Once)
{
while (lCurrentStart <= pSpanToConsider.EndDateTime && lCurrentStart <= _SequenceEnd)
{
lCurrentPostion++;
if (lCurrentPostion%_RepeatInterval == 0)
{
lCurrentSequencePosition++;
if (_ChangedElements.ContainsKey(lCurrentSequencePosition))
{
if (_ChangedElements[lCurrentSequencePosition] != null &&
_ChangedElements[lCurrentSequencePosition].Duration.Overlaps(pSpanToConsider))
{
lResult.Add(lCurrentSequencePosition, _ChangedElements[lCurrentSequencePosition]);
}
}
else if (new DateTimeSpan
{
StartDateTime = lCurrentStart,
EndDateTime = lCurrentEnd
}.Overlaps(pSpanToConsider))
{
var app = new Appointment();
var dts = new DateTimeSpan();
dts.StartDateTime = lCurrentStart;
dts.EndDateTime = lCurrentEnd;
app.Duration = dts;
app.Notice = RootAppointment.Notice;
app.Index = RootAppointment.Index;
app.Brush = _Resource.GetBrush();
app.Tag = RootAppointment.Tag;
string text = RootAppointment.Text;
if (text.LastIndexOf("\n") > 0)
{
text = text.Substring(0, text.LastIndexOf("\n") + 1);
text += dts.ToString();
}
app.Text = text;
lResult.Add(lCurrentSequencePosition, app);
}
}
lCurrentStart = Next(lCurrentStart, _Frequency);
lCurrentEnd = Next(lCurrentEnd, _Frequency);
}
}
return lResult;
}
public void ChangeElement(int pSequencePosition, Appointment pAppointment)
{
_ChangedElements[pSequencePosition] = pAppointment;
StoreDirtyInformation(IsChangedElementsDirty, PropertyName_ChangedElements);
}
public void ClearChanged()
{
_NeedsRecalculation = true;
_ChangedElements.Clear();
StoreDirtyInformation(IsChangedElementsDirty, PropertyName_ChangedElements);
}
public void DeleteElement(int pSequencePosition)
{
_ChangedElements[pSequencePosition] = null;
if (_AppointmentsInSpan.ContainsKey(pSequencePosition))
{
_AppointmentsInSpan.Remove(pSequencePosition);
}
StoreDirtyInformation(IsChangedElementsDirty, PropertyName_ChangedElements);
}
public Appointment GetAppointment(int pSequencePostion)
{
if (_AppointmentsInSpan.ContainsKey(pSequencePostion))
{
return _AppointmentsInSpan[pSequencePostion];
}
return null;
}
public int GetSequencePosition(Appointment pAppointment)
{
foreach (var iPair in _AppointmentsInSpan)
{
if (iPair.Value == pAppointment)
{
return iPair.Key;
}
}
return -1;
}
public DateTimeSpan GetSequenceSpan()
{
return new DateTimeSpan
{
StartDateTime = RootAppointment.Duration.StartDateTime,
EndDateTime = SequenceEnd
};
}
public void UpdatePossibleFrequencies(DateTime pStartDate)
{
DateTimeFormatInfo lDateInfo = DateTimeFormatInfo.CurrentInfo;
_PossibleFrequencies.Single(f => f.Frequency == ResourceBookingFrequencyType.Weekly).Translation =
"jeden " + lDateInfo.GetDayName(pStartDate.DayOfWeek);
_PossibleFrequencies.Single(f => f.Frequency == ResourceBookingFrequencyType.Monthly).Translation =
"jeden " + pStartDate.Day + "ten des Monats";
_PossibleFrequencies.Single(f => f.Frequency == ResourceBookingFrequencyType.MonthlyOnFirstDay).Translation
= "jeden " + pStartDate.GetWeekdayOccurence(true) + ". " +
lDateInfo.GetShortestDayName(pStartDate.DayOfWeek) + ". des Monats";
_PossibleFrequencies.Single(f => f.Frequency == ResourceBookingFrequencyType.MonthlyOnLastDay).Translation =
"jeden " + pStartDate.GetWeekdayOccurence(false) + ". letzten " +
lDateInfo.GetShortestDayName(pStartDate.DayOfWeek) + ". des Monats";
}
protected override void InitByDataContract(BookingSequenceDC pDataContract)
{
string text = string.Empty;
if (pDataContract.RootBooking.Employee != null)
{
text = pDataContract.RootBooking.Employee.FirstName + " " + pDataContract.RootBooking.Employee.LastName +
":\n";
}
if (pDataContract.Resource != null)
{
text += pDataContract.Resource.Name + "\n";
}
if (!String.IsNullOrEmpty(pDataContract.RootBooking.Notice))
{
text += "\n";
text += pDataContract.RootBooking.Notice;
text += "\n";
}
text += "\n";
if (pDataContract.RootBooking.Duration.StartDate.Date == pDataContract.RootBooking.Duration.EndDate.Date)
{
// return StartDateTime.ToMyDateTimeString() + " " + StartDateTime.ToShortTimeString() + " - " + EndDateTime.ToMyDateTimeString() + " " + EndDateTime.ToShortTimeString();
text += String.Format("{0:ddd, dd.MM.yy HH:mm} - {1:HH:mm}",
pDataContract.RootBooking.Duration.StartDateTime, pDataContract.RootBooking.Duration.EndDateTime);
// text += DataContract.RootBooking.Duration.ToString();
}
else
{
text += pDataContract.RootBooking.Duration.ToString();
}
RootAppointment = new Appointment
{
Duration = pDataContract.RootBooking.Duration,
Notice = pDataContract.RootBooking.Notice,
Text = text,
Tag = pDataContract.RootBooking.Employee,
};
if (pDataContract.Resource != null)
{
RootAppointment.Index = (int) pDataContract.Resource.ResourceOid.Value;
RootAppointment.Brush = pDataContract.Resource.GetBrush();
}
if (pDataContract.ChangedElements == null)
{
pDataContract.ChangedElements = new List<ResourceBookingDC>();
}
foreach (ResourceBookingDC iBooking in pDataContract.ChangedElements)
{
if (!_ChangedElements.ContainsKey(iBooking.SequencePosition))
{
_ChangedElements.Add(
iBooking.SequencePosition,
iBooking.IsDeleted
? null
: new Appointment
{
Duration = iBooking.Duration.Clone(),
Notice = iBooking.Notice,
Index = RootAppointment.Index,
Brush = RootAppointment.Brush,
Tag = iBooking.Employee
});
}
}
_Frequency = pDataContract.Frequency;
_RepeatInterval = pDataContract.RepeatInterval;
_SequenceEnd = pDataContract.SequenceEnd;
_Resource = pDataContract.Resource;
_Notice = pDataContract.Notice;
_Employee = pDataContract.Employee;
UpdatePossibleFrequencies(_RootAppointment.Duration.StartDateTime);
}
protected override BookingSequenceDC MapToDataContract(BookingSequenceDC pDataContract, bool doCommit)
{
pDataContract.Frequency = _Frequency;
pDataContract.RepeatInterval = _RepeatInterval;
pDataContract.Notice = _Notice;
pDataContract.Resource = _Resource;
pDataContract.SequenceEnd = _SequenceEnd;
pDataContract.Employee = RootAppointment.Tag as CompactEmployeeDC;
pDataContract.RootBooking.Duration = RootAppointment.Duration.Clone();
pDataContract.RootBooking.Notice = RootAppointment.Notice;
pDataContract.RootBooking.Employee = RootAppointment.Tag as CompactEmployeeDC;
if (_Frequency == ResourceBookingFrequencyType.Once)
{
pDataContract.SequenceEnd = pDataContract.RootBooking.Duration.EndDateTime;
}
pDataContract.ChangedElements.RemoveRange(dc => !_ChangedElements.ContainsKey(dc.SequencePosition));
foreach (ResourceBookingDC iDC in pDataContract.ChangedElements)
{
if (_ChangedElements[iDC.SequencePosition] != null)
{
iDC.Duration = _ChangedElements[iDC.SequencePosition].Duration.Clone();
iDC.Notice = _ChangedElements[iDC.SequencePosition].Notice;
iDC.Employee = _ChangedElements[iDC.SequencePosition].Tag as CompactEmployeeDC;
}
else
{
iDC.IsDeleted = true;
}
}
foreach (
var iEntry in
_ChangedElements.Where(
entry =>
pDataContract.ChangedElements.SingleOrDefault(dc => dc.SequencePosition == entry.Key) ==
null))
{
if (iEntry.Value == null)
{
pDataContract.ChangedElements.Add(
new ResourceBookingDC
{
SequencePosition = iEntry.Key,
IsDeleted = true,
Duration = null
});
}
else
{
pDataContract.ChangedElements.Add(
new ResourceBookingDC
{
SequencePosition = iEntry.Key,
IsDeleted = false,
Duration = iEntry.Value.Duration.Clone(),
Notice = iEntry.Value.Notice,
Employee = iEntry.Value.Tag as CompactEmployeeDC
});
}
}
return pDataContract;
}
private bool AreEqual(ResourceBookingDC x, Appointment y)
{
NullCompareResult lResult = Utils.NullCompare(x, y);
return lResult.BothNotNull
? x.Duration.StartDateTime == y.Duration.StartDateTime &&
x.Duration.EndDateTime == y.Duration.EndDateTime && x.Notice == y.Notice
: lResult.Different;
}
private void Duration_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == DateTimeSpan.PropertyName_StartDate)
{
UpdatePossibleFrequencies(_RootAppointment.Duration.StartDateTime);
}
}
private DateTime Next(DateTime pDate, ResourceBookingFrequencyType pFrequency)
{
switch (pFrequency)
{
case ResourceBookingFrequencyType.Daily:
return pDate.AddDays(1);
case ResourceBookingFrequencyType.Weekly:
return pDate.AddDays(7);
case ResourceBookingFrequencyType.Monthly:
return pDate.AddMonths(1);
case ResourceBookingFrequencyType.MonthlyOnFirstDay:
return pDate.AddMonthsDayDependent(1, true);
case ResourceBookingFrequencyType.MonthlyOnLastDay:
return pDate.AddMonthsDayDependent(1, false);
default:
return pDate;
}
}
private void _RootAppointment_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == Appointment.PropertyName_Duration)
{
UpdatePossibleFrequencies(_RootAppointment.Duration.StartDateTime);
}
StoreDirtyInformation(!AreEqual(DataContract.RootBooking, _RootAppointment), PropertyName_RootAppointment);
}
}
}