I have a question about creating an appointment if matches the block date to check weekly in the hr organizer within the start date and stop date then cannot make an appointment. I am using for each to loop every week, to detect but cannot work.
For the scenario sample (This is what I want the result):
In the hr organizer, the admin set the user cannot create an appointment every Tuesday from 5 PM until Wednesday 12 PM, it will start from 22 Nov 2022 until 22 Dec 2022. Means that every week Tuesday from 5 PM until Wednesday 12 PM will block to create appointments until the end of 22 Dec 2022.
So now the user needs to create an appointment starting on 22 Nov 2022 at 5:40 PM and ending on 22 Nov 2022 at 6:40 PM. By right between this appointment time it won't let the user create the appointment because it has been blocked by the hr organizer. (**I am facing this problem the condition is not correct in my existing code.)
formatAptStartDate= 22 Nov 2022 17:40 PM
aptEndDate = 22 Nov 2022 18:40 PM
formatStartDate = 22 Nov 2022 05:00 PM
formatEndDate = 23 Nov 2022 12:00:00 PM
stopLastDate = 22 Dec 2022 12:00 PM
Existing sample code: (This code is not working meet what I mentioned in the above requirements)
if (repeatType == "Weekly")
{
int weekDayNumberAptStartDate = (int)(formatAptStartDate.DayOfWeek 6) % 7;
int weekDayNumberStartDate = (int)(formatStartDate.DayOfWeek 6) % 7;
int weekDayNumberEndDate = (int)(formatEndDate.DayOfWeek 6) % 7;
if (weekDayNumberAptStartDate >= weekDayNumberStartDate && weekDayNumberAptStartDate <= weekDayNumberEndDate)
{
if (formatStopLastDate.Date >= formatAptStartDate.Date && formatStartDate.Date <= formatAptStartDate.Date)
{
for (DateTime dt = formatStartDate; dt <= stopLastDate; dt = dt.AddDays(7))
{
if (formatAptEndDate < dt || formatAptStartDate > formatEndDate)
{
orgTimeSlot.IsAvailable = true;
orgTimeSlot.StartDate = null;
orgTimeSlot.StopDate = null;
continue;
}
else
{
orgTimeSlot.IsAvailable = false;
orgTimeSlot.StartDate = formatStartDate;
orgTimeSlot.StopDate = formatEndDate;
break;
}
}
}
}
}
Remark
orgTimeSlot.IsAvailable = true;
means that if not match the hr organizer block date, it will let the user create an appointment, else if orgTimeSlot.IsAvailable = false;
means that the user cannot create an appointment.
Hope someone can guide or show me how to solve this problem and can meet the requirements.
CodePudding user response:
IMHO, do not try to do it the way you are trying to do. Instead create a collection of blocked datetimes and check user request overlaps with any of the blocks. ie:
void Main()
{
var blockDateStart = new DateTime(2022, 11, 22);
var blockDateEnd = new DateTime(2022, 12, 23); // until end of 11/22
DayBlock[] blockWeekdays = {
new DayBlock {DayOfWeek=DayOfWeek.Tuesday, Start=TimeSpan.FromHours(17), End=TimeSpan.FromHours(24)},
new DayBlock {DayOfWeek=DayOfWeek.Wednesday, Start=TimeSpan.FromHours(0), End=TimeSpan.FromHours(12)},
};
var blocked = Enumerable.Range(0, (int)(blockDateEnd - blockDateStart).TotalDays)
.Select(e => new {Date=blockDateStart.AddDays(e)})
.Where(e => blockWeekdays.Any(w => w.DayOfWeek == e.Date.DayOfWeek))
.Select(e => new {
From = e.Date.Add(blockWeekdays.Single(w => w.DayOfWeek == e.Date.DayOfWeek).Start),
To = e.Date.Add(blockWeekdays.Single(w => w.DayOfWeek == e.Date.DayOfWeek).End)
});
var userApptStart = new DateTime(2022, 11, 22, 17, 40, 0);
var userApptEnd = new DateTime(2022, 11, 22, 18, 40, 0);
var isBlocked = blocked.Any(b => userApptEnd > b.From && userApptStart < b.To);
Console.WriteLine(isBlocked);
}
class DayBlock
{
public DayOfWeek DayOfWeek { get; set; }
public TimeSpan Start { get; set; }
public TimeSpan End { get; set; }
}
EDIT If you want to get on which date\time its is blocked:
var blocking = blocked.Where(b => userApptEnd > b.From && userApptStart < b.To);
CodePudding user response:
You can also use if checks:
void Main()
{
var blockDateStart = new DateTime(2022, 11, 22);
var blockDateEnd = new DateTime(2022, 12, 23); // until end of 11/22
DayBlock[] blockWeekdays = {
new DayBlock {DayOfWeek=DayOfWeek.Tuesday, Start=TimeSpan.FromHours(17), End=TimeSpan.FromHours(24)},
new DayBlock {DayOfWeek=DayOfWeek.Wednesday, Start=TimeSpan.FromHours(0), End=TimeSpan.FromHours(12)},
};
var userApptStart = new DateTime(2022, 11, 22, 17, 40, 0);
var userApptEnd = new DateTime(2022, 11, 22, 18, 40, 0);
var blocked = false;
if (userApptEnd > blockDateStart && userApptStart < blockDateEnd)
{
var appTimeStart = userApptStart.TimeOfDay;
var appTimeEnd = userApptEnd.TimeOfDay;
var bmatch = blockWeekdays.SingleOrDefault(w => w.DayOfWeek == userApptStart.DayOfWeek &&
appTimeEnd > w.Start && appTimeStart < w.End);
if (bmatch != null)
{
Console.WriteLine($"Blocked by {userApptStart.Date.Add(bmatch.Start)}-{userApptStart.Date.Add(bmatch.End)} on {bmatch.DayOfWeek}");
blocked = true;
}
}
Console.WriteLine(blocked);
}
class DayBlock
{
public DayOfWeek DayOfWeek { get; set; }
public TimeSpan Start { get; set; }
public TimeSpan End { get; set; }
}
CodePudding user response:
This is how I would do it :
DateTime formatAptStartDate = DateTime.Parse("22 Nov 2022 17:40 PM");
DateTime aptEndDate = DateTime.Parse("22 Nov 2022 18:40 PM");
DateTime formatStartDate = DateTime.Parse("22 Nov 2022 05:00 PM");
DateTime formatEndDate = DateTime.Parse("23 Nov 2022 12:00:00 PM");
DateTime stopLastDate = DateTime.Parse("22 Dec 2022 12:00 PM");
DateTime sundayMidnight = formatAptStartDate.Date.AddDays(-1 * (int)formatAptStartDate.DayOfWeek);
DateTime blockStartTime = sundayMidnight.AddDays((int)DayOfWeek.Tuesday).AddHours(17);
DateTime blockEndTime = sundayMidnight.AddDays((int)DayOfWeek.Wednesday).AddHours(12);
if ((aptEndDate <= blockStartTime) || (formatAptStartDate >= blockEndTime ))
{
}