553 lines
20 KiB
C#
553 lines
20 KiB
C#
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<BookingSequenceDC>, 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<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 = "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<int, Appointment> _AppointmentsInSpan = new Dictionary<int, Appointment>();
|
|
|
|
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<int, Appointment> 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<FrequencyTranslation> 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<int, Appointment> CalculateAppointmentsFromSequence(DateTimeSpan pSpanToConsider)
|
|
{
|
|
var lResult = new Dictionary<int, Appointment>();
|
|
|
|
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<ResourceBookingDC>();
|
|
}
|
|
|
|
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<string, object> mCustomFields;
|
|
public System.Collections.Generic.Dictionary<string, object> CustomFields
|
|
{
|
|
get
|
|
{
|
|
if (mCustomFields == null)
|
|
mCustomFields = new System.Collections.Generic.Dictionary<String, object>();
|
|
return mCustomFields;
|
|
}
|
|
}
|
|
}
|
|
} |