using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Linq; using BeWo.Controls.Calendar; using BS.Shared; using BS.Shared.Core; using BS.Shared.DataContracts; using BS.Shared.DataContracts.Compact; using BS.Shared.Extensions; using BeWo.ViewModel; namespace BeWo.Scheduler.ViewModel { public class ResourceBookingVM : AbstractDCMapperVM, IBeWoAppointment { 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 _ChangedElements = new Dictionary(); private readonly List _PossibleFrequencies = new List { new FrequencyTranslation { Frequency = ResourceBookingFrequencyType.Once, Translation = "Einmalig" }, new FrequencyTranslation { Frequency = ResourceBookingFrequencyType.Daily, Translation = "Täglich" }, new FrequencyTranslation { Frequency = ResourceBookingFrequencyType.Weekly, Translation = "Wöchentlich" }, new FrequencyTranslation { Frequency = ResourceBookingFrequencyType.Monthly, Translation = "Monatlich" }, new FrequencyTranslation { Frequency = ResourceBookingFrequencyType.Yearly, Translation = "Jährlich" } }; //private Dictionary _AppointmentsInSpan = new Dictionary(); private CompactEmployeeDC _Employee; private ResourceBookingFrequencyType _Frequency; private string _Notice; private int _RepeatInterval = 1; private ResourceDC _Resource; private Appointment _RootAppointment; private DateTime _SequenceEnd; private DateTimeSpan _SpanToConsider; public ResourceBookingVM(BookingSequenceDC pDC) : base(pDC, pDC.SequenceOid == null) { } public Dictionary ChangedElements { get { return this._ChangedElements; } } public CompactEmployeeDC Employee { get { return this._Employee; } set { if (this.AreDifferent(this._Employee, value)) { this._Employee = value; // StoreDirtyInformation(AreDifferent(DataContract.Employee, value), PropertyName_Employee); this.FirePropertyChanged(PropertyName_Employee); } } } public ResourceBookingFrequencyType Frequency { get { return this._Frequency; } set { if (this.AreDifferent(this._Frequency, value)) { this._Frequency = value; this.StoreDirtyInformation(this.AreDifferent(this.DataContract.Frequency, value), PropertyName_Frequency); this.FirePropertyChanged(PropertyName_Frequency); } } } public string Notice { get { return this._Notice; } set { if (this.AreDifferent(this._Notice, value)) { this._Notice = value; this.StoreDirtyInformation(this.AreDifferent(this.DataContract.Notice, value), PropertyName_Notice); this.FirePropertyChanged(PropertyName_Notice); } } } public List PossibleFrequencies { get { return this._PossibleFrequencies; } } public int RepeatInterval { get { return this._RepeatInterval; } set { if (this.AreDifferent(this._RepeatInterval, value)) { this._RepeatInterval = value; this.StoreDirtyInformation(this.AreDifferent(this.DataContract.RepeatInterval, value), PropertyName_RepeatInterval); this.FirePropertyChanged(PropertyName_RepeatInterval); } } } public ResourceDC Resource { get { return this._Resource; } set { this._Resource = value; this.RootAppointment.Index = (int)value.ResourceOid.Value; this.RootAppointment.Brush = value.GetBrush(); foreach (var iChanged in this._ChangedElements) { iChanged.Value.Index = (int)value.ResourceOid.Value; iChanged.Value.Brush = value.GetBrush(); } this.FirePropertyChanged(PropertyName_Resource); } } public Appointment RootAppointment { get { return this._RootAppointment; } set { if (this.AreDifferent(this._RootAppointment, value)) { this._RootAppointment = value; this.StoreDirtyInformation(!this.AreEqual(this.DataContract.RootBooking, this._RootAppointment), PropertyName_RootAppointment); this.FirePropertyChanged(PropertyName_RootAppointment); this._RootAppointment.PropertyChanged += this._RootAppointment_PropertyChanged; this._RootAppointment.Duration.SynchEndDate = true; } } } public DateTime SequenceEnd { get { return this._SequenceEnd; } set { if (this.AreDifferent(this._SequenceEnd, value)) { value = value.Date.AddHours(23).AddMinutes(59); this._SequenceEnd = value; this.StoreDirtyInformation(this.AreDifferent(this.DataContract.SequenceEnd, value), PropertyName_SequenceEnd); this.FirePropertyChanged(PropertyName_SequenceEnd); } } } public DateTimeSpan SpanToConsider { get { return this._SpanToConsider; } set { if (this.AreDifferent(this._SpanToConsider, value)) { this._SpanToConsider = value; } } } private bool IsChangedElementsDirty { get { if (this.DataContract.ChangedElements.Count != this._ChangedElements.Count) { return true; } if (this.DataContract.ChangedElements.Count(dc => !this._ChangedElements.ContainsKey(dc.SequencePosition) || !this.AreEqual(dc, this._ChangedElements[dc.SequencePosition])) > 0) { return true; } return false; } } public Dictionary CalculateAppointmentsFromSequence(DateTimeSpan pSpanToConsider) { var lResult = new Dictionary(); DateTime lCurrentStart = this.RootAppointment.Duration.StartDateTime; DateTime lCurrentEnd = this.RootAppointment.Duration.EndDateTime; int lCurrentPostion = 0; int lCurrentSequencePosition = 0; if (this.RootAppointment.Duration.Overlaps(pSpanToConsider)) { lResult.Add(0, this._RootAppointment); } lCurrentStart = this.Next(lCurrentStart, this._Frequency); lCurrentEnd = this.Next(lCurrentEnd, this._Frequency); if (this._Frequency != ResourceBookingFrequencyType.Once) { while (lCurrentStart <= pSpanToConsider.EndDateTime && lCurrentStart <= this._SequenceEnd) { lCurrentPostion++; if (lCurrentPostion % this._RepeatInterval == 0) { lCurrentSequencePosition++; if (this._ChangedElements.ContainsKey(lCurrentSequencePosition)) { if (this._ChangedElements[lCurrentSequencePosition] != null && this._ChangedElements[lCurrentSequencePosition].Duration.Overlaps(pSpanToConsider)) { lResult.Add(lCurrentSequencePosition, this._ChangedElements[lCurrentSequencePosition]); } } else if (new DateTimeSpan { StartDateTime = lCurrentStart, EndDateTime = lCurrentEnd }.Overlaps(pSpanToConsider)) { Appointment app = new Appointment(); DateTimeSpan dts = new DateTimeSpan(); dts.StartDateTime = lCurrentStart; dts.EndDateTime = lCurrentEnd; app.Duration = dts; app.Notice = this.RootAppointment.Notice; app.Index = this.RootAppointment.Index; app.Brush = this._Resource.GetBrush(); app.Tag = this.RootAppointment.Tag; string text = this.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 = this.Next(lCurrentStart, this._Frequency); lCurrentEnd = this.Next(lCurrentEnd, this._Frequency); } } return lResult; } public void ChangeElement(int pSequencePosition, Appointment pAppointment) { this._ChangedElements[pSequencePosition] = pAppointment; this.StoreDirtyInformation(this.IsChangedElementsDirty, PropertyName_ChangedElements); } public void ClearChanged() { this._ChangedElements.Clear(); this.StoreDirtyInformation(this.IsChangedElementsDirty, PropertyName_ChangedElements); } public DateTimeSpan GetSequenceSpan() { return new DateTimeSpan { StartDateTime = this.RootAppointment.Duration.StartDateTime, EndDateTime = this.SequenceEnd }; } 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(); } this.RootAppointment = new Appointment { Duration = pDataContract.RootBooking.Duration, Notice = pDataContract.RootBooking.Notice, Text = text, Tag = pDataContract.RootBooking.Employee, }; if (pDataContract.Resource != null) { this.RootAppointment.Index = (int)pDataContract.Resource.ResourceOid.Value; this.RootAppointment.Brush = pDataContract.Resource.GetBrush(); } if (pDataContract.ChangedElements == null) { pDataContract.ChangedElements = new List(); } foreach (var iBooking in pDataContract.ChangedElements) { this._ChangedElements.Add( iBooking.SequencePosition, iBooking.IsDeleted ? null : new Appointment { Duration = iBooking.Duration.Clone(), Notice = iBooking.Notice, Index = this.RootAppointment.Index, Brush = this.RootAppointment.Brush, Tag = iBooking.Employee }); } this._Frequency = pDataContract.Frequency; this._RepeatInterval = pDataContract.RepeatInterval; this._SequenceEnd = pDataContract.SequenceEnd; this._Resource = pDataContract.Resource; this._Notice = pDataContract.Notice; this._Employee = pDataContract.Employee; } protected override BookingSequenceDC MapToDataContract(BookingSequenceDC pDataContract, bool doCommit) { pDataContract.Frequency = this._Frequency; pDataContract.RepeatInterval = this._RepeatInterval; pDataContract.Notice = this._Notice; pDataContract.Resource = this._Resource; pDataContract.SequenceEnd = this._SequenceEnd; pDataContract.Employee = this.RootAppointment.Tag as CompactEmployeeDC; pDataContract.RootBooking.Duration = this.RootAppointment.Duration.Clone(); pDataContract.RootBooking.Notice = this.RootAppointment.Notice; pDataContract.RootBooking.Employee = this.RootAppointment.Tag as CompactEmployeeDC; if (this._Frequency == ResourceBookingFrequencyType.Once) { pDataContract.SequenceEnd = pDataContract.RootBooking.Duration.EndDateTime; } pDataContract.ChangedElements.RemoveRange(dc => !this._ChangedElements.ContainsKey(dc.SequencePosition)); foreach (var iDC in pDataContract.ChangedElements) { if (this._ChangedElements[iDC.SequencePosition] != null) { iDC.Duration = this._ChangedElements[iDC.SequencePosition].Duration.Clone(); iDC.Notice = this._ChangedElements[iDC.SequencePosition].Notice; iDC.Employee = this._ChangedElements[iDC.SequencePosition].Tag as CompactEmployeeDC; } else { iDC.IsDeleted = true; } } foreach (var iEntry in this._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 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.Yearly: return pDate.AddYears(1); default: return pDate; } } private void _RootAppointment_PropertyChanged(object sender, PropertyChangedEventArgs e) { this.StoreDirtyInformation(!this.AreEqual(this.DataContract.RootBooking, this._RootAppointment), PropertyName_RootAppointment); } public BeWoAppointmentCategory AppointmentCategory { get; set; } public object Id { get; set; } public DateTime Start { get { return DateTime.Now; } set { } } public DateTime End { get; set; } public int LabelId { get; set; } public string Subject { get; set; } public string Description { get; set; } public int Status { get; set; } public string Location { get; set; } public bool AllDay { get; set; } public int EventType { get; set; } public string RecurrenceInfo { get; set; } public string ReminderInfo { get; set; } public object ResourceId { get; set; } private System.Collections.Generic.Dictionary mCustomFields; public System.Collections.Generic.Dictionary CustomFields { get { if (mCustomFields == null) mCustomFields = new System.Collections.Generic.Dictionary(); return mCustomFields; } } } }