public override void Save(ObligatedRange obligatedRange) { using (var db = new EngineContext()) { if (obligatedRange.Id == 0) { db.ObligatedRanges.Add(obligatedRange); } else { var record = db.ObligatedRanges.Find(obligatedRange.Id); if (record == null) { throw new JServiceException("رکورد موجود نیست"); } db.Entry(record).CurrentValues.SetValues(obligatedRange); foreach (var weekDay in obligatedRange.ObligatedRangeWeeks) { if (weekDay.Id == 0) { record.ObligatedRangeWeeks.Add(weekDay); } else { ObligatedRangeWeeks recordWeekDay = null; recordWeekDay = record.ObligatedRangeWeeks.First(w => w.Id == weekDay.Id); db.Entry(recordWeekDay).CurrentValues.SetValues(weekDay); if (weekDay.IsRemoved) { foreach (var dayTimese in recordWeekDay.ObligatedRangeDayTimes) { db.Entry(dayTimese).State = EntityState.Deleted; } db.Entry(recordWeekDay).State = EntityState.Deleted; continue; } foreach (var time in weekDay.ObligatedRangeDayTimes) { if (time.Id == 0) { recordWeekDay.ObligatedRangeDayTimes.Add(time); } else if (time.IsRemoved) { var existTime = recordWeekDay.ObligatedRangeDayTimes.First(t => t.Id == time.Id); db.Entry(existTime).State = EntityState.Deleted; } else { var existTime = recordWeekDay.ObligatedRangeDayTimes.First(t => t.Id == time.Id); db.Entry(existTime).CurrentValues.SetValues(time); db.Entry(existTime).State = EntityState.Modified; } } db.Entry(recordWeekDay).State = EntityState.Modified; } } db.Entry(record).State = EntityState.Modified; } db.SaveChanges(); } }
public List <BiometryCalculatedDetail> CompareAndJoin(DateTime fromDate, DateTime toDate, List <BiometricData> biometricData, ObligatedRange obligatedRange) { var totalDays = (toDate.Date - fromDate.Date).TotalDays; List <BiometryCalculatedDetail> data = new List <BiometryCalculatedDetail>(); var firstDay = fromDate; for (int i = 0; i < totalDays; i++) { var vm = new BiometryCalculatedDetail(); vm.Date = i == 0 ? fromDate : fromDate.AddDays(1); fromDate = vm.Date; // در کدام روز بازه موظفی قرار دارد ؟ ObligatedRangeWeeks whichDayInInterval = DetermineDate(firstDay, vm.Date, obligatedRange.ObligatedRangeWeeks); // بازه موظفی امروز را بده var obligatedRangeDayTimeses = whichDayInInterval.ObligatedRangeDayTimes.OrderBy(t => t.Start.Hour).ToList(); // تاریخ های بازه را به همان روزی می برد که میخواهیم مقایسه های ساعت هارا انجام دهیم for (var index = 0; index < obligatedRangeDayTimeses.Count; index++) { obligatedRangeDayTimeses[index].Start = new DateTime(vm.Date.Year , vm.Date.Month , vm.Date.Day , obligatedRangeDayTimeses[index].Start.TimeOfDay.Hours , obligatedRangeDayTimeses[index].Start.TimeOfDay.Minutes, obligatedRangeDayTimeses[index].Start.TimeOfDay.Seconds); var enddate = new DateTime(vm.Date.Year , vm.Date.Month , vm.Date.Day , obligatedRangeDayTimeses[index].End.TimeOfDay.Hours , obligatedRangeDayTimeses[index].End.TimeOfDay.Minutes, obligatedRangeDayTimeses[index].End.TimeOfDay.Seconds); // اگر بازه دو روزه ای باشد ، تاریخ پایان یک روز آن طرف تر می رود if (obligatedRangeDayTimeses[index].IsTwoDay) { enddate = enddate.AddDays(1); } obligatedRangeDayTimeses[index].End = enddate; } // کارکرد امروز را بده var workday = biometricData.FirstOrDefault(d => d.Date.Date == vm.Date.Date); if (workday == null) { // هیچ کارکردی نیست پس کل ان غیبت obligatedRangeDayTimeses.ForEach(o => vm.Times.Add( new BiometryCalculatedDetailTime { RangeTimeIn = o.Start, RangeTimeOut = o.End, TimeIn = o.Start, TimeOut = o.End, Absence = o.End - o.Start, Type = BiometryCalculatedDetailTimeType.Absence } )); CalculateTotalForADay(vm); data.Add(vm); continue; } // کارکرد دارد // کل حضور workday.BiometricDataTimes.Where(b => b.TimeIn.HasValue && b.TimeOut.HasValue).ForEach(b => vm.Total += b.TimeOut.Value - b.TimeIn.Value); //todo:exception for more than two days // تمامی رنج ساعت های حظور و عدم حظور List <DateTime?> intervals = IntervalHelper.ToOneOrderedTimeList(workday.BiometricDataTimes, obligatedRangeDayTimeses); // بازه های حظور و عدم حظور List <BiometryCalculatedDetailTime> calculatedIntervals = new List <BiometryCalculatedDetailTime>(); /*if (intervals.Count % 2 != 0) * { * throw new Exception("اشکال در سیستم تعداد بازه یافت شده زوج نیست"); * }*/ for (int j = 0; j < intervals.Count; j++) { if (j + 1 != intervals.Count) { ObligatedRangeDayTimes range = IntervalHelper.IsInRanges(intervals[j], intervals[j + 1], obligatedRangeDayTimeses); bool isInRange = range != null; BiometricDataTime biometricDataTime = IntervalHelper.IsInWorkTimes(intervals[j], intervals[j + 1], workday.BiometricDataTimes); bool isInWorkTimes = biometricDataTime != null; var detailTime = new BiometryCalculatedDetailTime { TimeIn = intervals[j], TimeOut = intervals[j + 1] }; // در ساعات بازه موظفی حضور دارد if (isInRange && isInWorkTimes) { switch (range.RangeType) { case RangeType.Normal: detailTime.Type = BiometryCalculatedDetailTimeType.Valid; break; case RangeType.Overtime: detailTime.Type = BiometryCalculatedDetailTimeType.Overtime; break; default: detailTime.Type = BiometryCalculatedDetailTimeType.Valid; break; } } // در ساعات موضفی حظور ندارد else if (isInRange && !isInWorkTimes) { detailTime.Type = BiometryCalculatedDetailTimeType.Absence; } // حظور دارد اما بازه موظفی نیست else if (!isInRange && isInWorkTimes) { detailTime.Type = BiometryCalculatedDetailTimeType.NotValid; } // نه حظور دارد و نه بازه موظفی است // این مورد نباید پیش بیاید چون تمامی زمان های محاسبه از بازه ها و کارکرد گرفته شده اند else if (!isInRange && !isInWorkTimes) { //throw new Exception("کاربر حضور ندارد و در رنج نیست"); // detailTime.Type = BiometryCalculatedDetailTimeType.NotValid; continue; } calculatedIntervals.Add(detailTime); } } var temp = vm.Times.ToList(); temp.AddRange(calculatedIntervals); vm.Times = temp; vm.BiometricData = workday; data.Add(vm); } return(data); }