private ParkFeeRuleDetail GetLastFeeRuleDetail() { ParkFeeRuleDetail detail = new ParkFeeRuleDetail(); detail.RuleDetailID = this.LastRuleDetailID; detail.RuleID = this.FeeRuleID; detail.StartTime = string.IsNullOrWhiteSpace(this.LastStartTime) ? "17:00" : this.LastStartTime; detail.EndTime = string.IsNullOrWhiteSpace(this.LastEndTime) ? "07:00" : this.LastEndTime; detail.Supplement = this.FirstSupplement == 1; detail.LoopType = this.LastLoopType; detail.Limit = this.LastLimit; detail.FreeTime = this.LastFreeTime; detail.FirstTime = this.LastFirstTime; detail.FirstFee = this.LastFirstFee; if (this.LastFeeRuleTypes == (int)FeeRuleType.TimeFee) { detail.Loop1PerTime = this.LastLoop1PerTime; detail.Loop1PerFee = this.LastLoop1PerFee; detail.Loop2Start = this.LastLoop2Start; detail.Loop2PerTime = this.LastLoop2PerTime; detail.Loop2PerFee = this.LastLoop2PerFee; } else { detail.Loop1PerTime = 0; detail.Loop1PerFee = 0; detail.Loop2Start = 0; detail.Loop2PerTime = 0; detail.Loop2PerFee = 0; } return(detail); }
/// <summary> /// 惠州公园 /// </summary> /// <returns></returns> public decimal Calc_Day() { decimal total = 0; TimeSpan ts = ParkingEndTime - ParkingBeginTime; long min = ts.Days * 24 * 60 + ts.Hours * 60 + ts.Minutes; if (min == 0) { return(0); } //规则详情 ParkFeeRuleDetail DayRuleDetail = (from d in listRuleDetail let start = Convert.ToDateTime(d.StartTime) let end = Convert.ToDateTime(d.EndTime) where start < end select d).FirstOrDefault(); //规则详情 ParkFeeRuleDetail RuleDetail = (from d in listRuleDetail let start = Convert.ToDateTime(d.StartTime) let end = Convert.ToDateTime(d.EndTime) where start > end select d).FirstOrDefault(); //本夜晚段所属日期取整 string strDate = ParkingBeginTime.Date.ToString("yyyy-MM-dd "); //本白天段开始时间 DateTime dtThisDayStart = Convert.ToDateTime(strDate + DayRuleDetail.StartTime); //本白天段结束时间 DateTime dtThisDayEnd = Convert.ToDateTime(strDate + DayRuleDetail.EndTime); //如果入场时间不在本白天段内,从黑夜段开始算 if (ParkingBeginTime < dtThisDayStart || ParkingBeginTime > dtThisDayEnd) { if (min > RuleDetail.FreeTime) { total += ts.Days * RuleDetail.Limit; if (min % (24 * 60) > RuleDetail.FreeTime) { total += RuleDetail.FirstFee; } } } else { if (min > DayRuleDetail.FreeTime) { total += ts.Days * DayRuleDetail.Limit; if (min % (24 * 60) > DayRuleDetail.FreeTime) { total += DayRuleDetail.FirstFee; } } } return(total); }
private void FillParkFeeRuleDetail(List <ParkFeeRuleDetail> details) { if (details == null || details.Count == 0) { return; } ParkFeeRuleDetail first = details.OrderBy(p => p.ID).FirstOrDefault(); this.FirstRuleDetailID = first.RuleDetailID; this.FirstStartTime = first.StartTime; this.FirstEndTime = first.EndTime; this.FirstFirstFee = (decimal)first.FirstFee; this.FirstFirstTime = first.FirstTime; this.FirstFreeTime = first.FreeTime; this.FirstLimit = (decimal)first.Limit; this.FirstLoop1PerFee = (decimal)first.Loop1PerFee; this.FirstLoop1PerTime = first.Loop1PerTime; this.FirstLoop2PerFee = (decimal)first.Loop2PerFee; this.FirstLoop2PerTime = first.Loop2PerTime; this.FirstLoop2Start = first.Loop2Start; this.FirstLoopType = first.LoopType; this.FirstSupplement = first.Supplement?1:0; this.FirstFeeRuleTypes = first.Loop1PerTime > 0 ? (int)FeeRuleType.TimeFee : (int)FeeRuleType.NumberOfTimes; if (details.Count > 1) { ParkFeeRuleDetail last = details.OrderBy(p => p.ID).LastOrDefault(); this.LastRuleDetailID = last.RuleDetailID; this.LastStartTime = last.StartTime; this.LastEndTime = last.EndTime; this.LastFirstFee = (decimal)last.FirstFee; this.LastFirstTime = last.FirstTime; this.LastFreeTime = last.FreeTime; this.LastLimit = (decimal)last.Limit; this.LastLoop1PerFee = (decimal)last.Loop1PerFee; this.LastLoop1PerTime = last.Loop1PerTime; this.LastLoop2PerFee = (decimal)last.Loop2PerFee; this.LastLoop2PerTime = last.Loop2PerTime; this.LastLoop2Start = last.Loop2Start; this.LastLoopType = last.LoopType; this.LastSupplement = last.Supplement?1:0; this.LastFeeRuleTypes = last.Loop1PerTime > 0 ? (int)FeeRuleType.TimeFee : (int)FeeRuleType.NumberOfTimes; } }
/// <summary> /// 计算主体,大循环 /// </summary> /// <param name="loop">标记"是否循环"</param> /// <param name="dtLoopStart">本次大循环内开始计费时间</param> /// <param name="total">累计费用</param> /// <returns>累计费用(已加上本次大循环的费用)</returns> public decimal Calc(bool loop, DateTime dtLoopStart, decimal total) { if (ParkingEndTime <= dtLoopStart) { return(total); } //规则详情 ParkFeeRuleDetail RuleDetail = listRuleDetail[0]; //小段开始时间 DateTime dtTmpStart = dtLoopStart; //本次大循环收费限额 decimal limit = RuleDetail.Limit == 0 ? int.MaxValue : (int)RuleDetail.Limit; //本次大循环费用 decimal sum = 0; #region 免费时段 if ((!loop && IsFirstFree == 1) || (loop && RuleDetail.LoopType == LoopType.AllContain)) { //出场时间小于免费时段结束时间 if (dtTmpStart.AddMinutes((int)RuleDetail.FreeTime) >= ParkingEndTime) { return(total); } //dtTmpStart = dtTmpStart.AddMinutes((int)RuleDetail.FreeTime); } #endregion 免费时段 #region 首时段 if (!loop || (loop && (RuleDetail.LoopType == LoopType.OnlyFirstTime || RuleDetail.LoopType == LoopType.AllContain))) { sum = Math.Min(limit, sum + (decimal)RuleDetail.FirstFee); if (dtTmpStart.AddMinutes((int)RuleDetail.FirstTime) >= ParkingEndTime) { return(total + sum); } dtTmpStart = dtTmpStart.AddMinutes((int)RuleDetail.FirstTime); } #endregion 首时段 #region 次收费 if (RuleDetail.Loop1PerTime == 0) { sum = Math.Min(limit, sum + (decimal)RuleDetail.Loop1PerFee); //如果出场时间在12小时以内 if (dtLoopStart.AddHours(12) >= ParkingEndTime) { return(total + sum); } //超过12小时,再来一个大循环 return(Calc(true, dtLoopStart.AddHours(12), total + sum)); } #endregion 次收费 #region 小循环段1 //小循环段1总结束时间 DateTime dtLoop1End = dtLoopStart.AddMinutes((int)RuleDetail.Loop2Start); //没设定小循环段2,表示小循环段1循环到入场12小时结束 if (RuleDetail.Loop2Start == 0) { dtLoop1End = dtLoopStart.AddHours(12); } //开始小循环 while (dtTmpStart < dtLoop1End) { sum = Math.Min(limit, sum + (decimal)RuleDetail.Loop1PerFee); //出场时间小于本小循环段结束时间 if (dtTmpStart.AddMinutes((int)RuleDetail.Loop1PerTime) >= ParkingEndTime) { return(total + sum); } dtTmpStart = dtTmpStart.AddMinutes((int)RuleDetail.Loop1PerTime); } #endregion 小循环段1 #region 小循环段2 if (RuleDetail.Loop2Start > 0 && RuleDetail.Loop2PerTime > 0) { //小循环段2总开始时间,其实就是小循环段1总结束时间 //本小段开始时间 dtTmpStart = dtLoopStart.AddMinutes((int)RuleDetail.Loop2Start); //小循环段2循环到入场12小时结束 while (dtTmpStart < dtLoopStart.AddHours(12)) { sum = Math.Min(limit, sum + (decimal)RuleDetail.Loop2PerFee); if (sum == limit) { break; } //出场时间小于本小循环段结束时间 if (dtTmpStart.AddMinutes((int)RuleDetail.Loop2PerTime) >= ParkingEndTime) { return(total + sum); } dtTmpStart = dtTmpStart.AddMinutes((int)RuleDetail.Loop2PerTime); } } #endregion 小循环段2 //出场时间>本次大循环12小时 if (ParkingEndTime > dtLoopStart.AddHours(12)) { return(Calc(true, dtLoopStart.AddHours(12), total + sum)); } return(total + sum); }
/// <summary> /// 计算主体,白天 /// </summary> /// <param name="loop">标记"是否循环"</param> /// <param name="dtLoopStart">本次大循环内开始计费时间</param> /// <param name="total">累计费用</param> /// <returns>累计费用(已加上本次大循环的费用)</returns> public decimal Calc_Day(bool loop, DateTime dtLoopStart, decimal total) { if (ParkingEndTime <= dtLoopStart) { return(total); } //规则详情 ParkFeeRuleDetail RuleDetail = (from d in listRuleDetail let start = Convert.ToDateTime(d.StartTime) let end = Convert.ToDateTime(d.EndTime) where start < end select d).FirstOrDefault(); //本白天段所属日期取整 string strDate = dtLoopStart.Date.ToString("yyyy-MM-dd "); //本白天段开始时间 DateTime dtThisDayStart = Convert.ToDateTime(strDate + RuleDetail.StartTime); //本白天段结束时间 DateTime dtThisDayEnd = Convert.ToDateTime(strDate + RuleDetail.EndTime); //如果入场时间不在本白天段内,从黑夜段开始算 if (dtLoopStart < dtThisDayStart || dtLoopStart > dtThisDayEnd) { return(Calc_Night(false, dtLoopStart, 0)); } //小段开始时间 DateTime dtTmpStart = dtLoopStart; //本白天段收费限额 decimal limit = RuleDetail.Limit == 0 ? decimal.MaxValue : (decimal)RuleDetail.Limit; //本白天段费用 decimal sum = 0; //是否补时 bool supp = (bool)RuleDetail.Supplement; #region 免费时段 if ((!loop && IsFirstFree == 1) || (loop && RuleDetail.LoopType == LoopType.AllContain)) { //免费时段超过本白天段结束时间,跳过本白天段算下一个夜晚段 if (dtTmpStart.AddMinutes((int)RuleDetail.FreeTime) >= dtThisDayEnd && !supp) { TimeSpan tspan = (supp ? dtTmpStart.AddMinutes((int)RuleDetail.FreeTime) - dtThisDayEnd : new TimeSpan()); return(Calc_Night(true, dtThisDayEnd + tspan, 0)); } //免费时段结束时间超过出场时间 if (dtTmpStart.AddMinutes((int)RuleDetail.FreeTime) >= ParkingEndTime) { return(total); } //dtTmpStart = dtTmpStart.AddMinutes((int)RuleDetail.FreeTime); } #endregion 免费时段 #region 首时段 if (!loop || (loop && (RuleDetail.LoopType == LoopType.OnlyFirstTime || RuleDetail.LoopType == LoopType.AllContain))) { sum = Math.Min(limit, sum + (decimal)RuleDetail.FirstFee); //首时段超过本白天段结束时间,继续下一个夜晚段 if (dtTmpStart.AddMinutes((int)RuleDetail.FirstTime) >= dtThisDayEnd) { TimeSpan tspan = (supp ? dtTmpStart.AddMinutes((int)RuleDetail.FirstTime) - dtThisDayEnd : new TimeSpan()); return(Calc_Night(true, dtThisDayEnd + tspan, sum)); } if (dtTmpStart.AddMinutes((int)RuleDetail.FirstTime) >= ParkingEndTime) { return(total + sum); } dtTmpStart = dtTmpStart.AddMinutes((int)RuleDetail.FirstTime); } #endregion 首时段 #region 次收费 if (RuleDetail.Loop1PerTime == 0) { sum = Math.Min(limit, sum + (decimal)RuleDetail.Loop1PerFee); //如果出场时间不超过本白天段 if (ParkingEndTime <= dtThisDayEnd) { return(total + sum); } //超过本白天段,继续算下一个夜晚段 return(Calc_Night(true, dtThisDayEnd, total + sum)); } #endregion 次收费 #region 小循环段1 //小循环段1总结束时间 DateTime dtLoop1End = dtLoopStart.AddMinutes((int)RuleDetail.Loop2Start); //没设定小循环段2,表示小循环段1循环到本白天段结束 if (RuleDetail.Loop2Start == 0) { dtLoop1End = dtThisDayEnd; } //开始小循环 while (dtTmpStart < dtLoop1End) { sum = Math.Min(limit, sum + (decimal)RuleDetail.Loop1PerFee); //本小循环段结束时间超过本白天段,继续算下一个夜晚段 if (dtTmpStart.AddMinutes((int)RuleDetail.Loop1PerTime) >= dtThisDayEnd) { TimeSpan tspan = (supp ? dtTmpStart.AddMinutes((int)RuleDetail.Loop1PerTime) - dtThisDayEnd : new TimeSpan()); return(Calc_Night(true, dtThisDayEnd + tspan, total + sum)); } //本小循环段结束时间超过出场时间 if (dtTmpStart.AddMinutes((int)RuleDetail.Loop1PerTime) >= ParkingEndTime) { return(total + sum); } dtTmpStart = dtTmpStart.AddMinutes((int)RuleDetail.Loop1PerTime); } #endregion 小循环段1 #region 小循环段2 if (RuleDetail.Loop2Start > 0 && RuleDetail.Loop2PerTime > 0) { //小循环段2总开始时间,其实就是小循环段1总结束时间 //本小段开始时间 dtTmpStart = dtLoopStart.AddMinutes((int)RuleDetail.Loop2Start); //小循环段2循环到本白天段结束 while (dtTmpStart < dtThisDayEnd) { sum = Math.Min(limit, sum + (decimal)RuleDetail.Loop2PerFee); if (sum == limit) { break; } //本小循环段结束时间超过本白天段,继续算下一个夜晚段 if (dtTmpStart.AddMinutes((int)RuleDetail.Loop2PerTime) >= dtThisDayEnd) { TimeSpan tspan = (supp ? dtTmpStart.AddMinutes((int)RuleDetail.Loop2PerTime) - dtThisDayEnd : new TimeSpan()); return(Calc_Night(true, dtThisDayEnd + tspan, total + sum)); } //本小循环段结束时间超过出场时间 if (dtTmpStart.AddMinutes((int)RuleDetail.Loop2PerTime) >= ParkingEndTime) { return(total + sum); } dtTmpStart = dtTmpStart.AddMinutes((int)RuleDetail.Loop2PerTime); } } #endregion 小循环段2 //出场时间大于本白天段结束时间 if (ParkingEndTime > dtThisDayEnd) { return(Calc_Night(true, dtThisDayEnd, total + sum)); } return(total + sum); }
/// <summary> /// 计算主体,大循环 /// </summary> /// <param name="loop">标记"是否循环"</param> /// <param name="dtLoopStart">本次大循环内开始计费时间</param> /// <param name="total">累计费用</param> /// <returns>累计费用(已加上本次大循环的费用)</returns> public decimal Calc(bool loop, DateTime dtLoopStart, decimal total) { if (ParkingEndTime <= dtLoopStart) { return(total); } //规则详情 ParkFeeRuleDetail RuleDetail = listRuleDetail[0]; //今天结束时间 DateTime dtThisDayEnd = dtLoopStart.AddDays(1).Date; //下一个自然天开始时间 DateTime dtNextDayStart = dtLoopStart.AddDays(1).Date; //小段开始时间 DateTime dtTmpStart = dtLoopStart; //今天收费限额 decimal limit = RuleDetail.Limit == 0 ? int.MaxValue : (int)RuleDetail.Limit; //今天费用 decimal sum = 0; #region 免费时段 if ((!loop && IsFirstFree == 1) || (loop && RuleDetail.LoopType == LoopType.AllContain)) { //免费时段超过今天结束时间,跳过今天算下一个自然天 if (dtTmpStart.AddMinutes((int)RuleDetail.FreeTime) >= dtThisDayEnd) { return(Calc(true, dtNextDayStart, 0)); } //出场时间小于免费时段结束时间 if (dtTmpStart.AddMinutes((int)RuleDetail.FreeTime) >= ParkingEndTime) { return(total); } // dtTmpStart = dtTmpStart.AddMinutes((int)RuleDetail.FreeTime); } #endregion 免费时段 #region 首时段 if (!loop || (loop && (RuleDetail.LoopType == LoopType.OnlyFirstTime || RuleDetail.LoopType == LoopType.AllContain))) { sum = Math.Min(limit, sum + (decimal)RuleDetail.FirstFee); //首时段超过今天结束时间,继续下一个自然天 if (dtTmpStart.AddMinutes((int)RuleDetail.FirstTime) >= dtThisDayEnd) { return(Calc(true, dtNextDayStart, sum)); } if (dtTmpStart.AddMinutes((int)RuleDetail.FirstTime) >= ParkingEndTime) { return(total + sum); } dtTmpStart = dtTmpStart.AddMinutes((int)RuleDetail.FirstTime); } #endregion 首时段 #region 次收费 if (RuleDetail.Loop1PerTime == 0) { sum = Math.Min(limit, sum + (decimal)RuleDetail.Loop1PerFee); //如果出场时间不超过今天 if (ParkingEndTime <= dtThisDayEnd) { return(total + sum); } //超过今天,继续算下一个自然天 return(Calc(true, dtNextDayStart, total + sum)); } #endregion 次收费 #region 小循环段1 //小循环段1总结束时间 DateTime dtLoop1End = dtLoopStart.AddMinutes((int)RuleDetail.Loop2Start); //没设定小循环段2,表示小循环段1循环到今天结束 if (RuleDetail.Loop2Start == 0) { dtLoop1End = dtThisDayEnd; } //开始小循环 while (dtTmpStart < dtLoop1End) { sum = Math.Min(limit, sum + (decimal)RuleDetail.Loop1PerFee); //本小循环段结束时间超过今天,继续算下一个自然天 if (dtTmpStart.AddMinutes((int)RuleDetail.Loop1PerTime) >= dtThisDayEnd) { return(Calc(true, dtNextDayStart, total + sum)); } //本小循环段结束时间超过出场时间 if (dtTmpStart.AddMinutes((int)RuleDetail.Loop1PerTime) >= ParkingEndTime) { return(total + sum); } dtTmpStart = dtTmpStart.AddMinutes((int)RuleDetail.Loop1PerTime); } #endregion 小循环段1 #region 小循环段2 if (RuleDetail.Loop2Start > 0 && RuleDetail.Loop2PerTime > 0) { //小循环段2总开始时间,其实就是小循环段1总结束时间 //本小段开始时间 dtTmpStart = dtLoopStart.AddMinutes((int)RuleDetail.Loop2Start); //小循环段2循环到今天结束 while (dtTmpStart < dtThisDayEnd) { sum = Math.Min(limit, sum + (decimal)RuleDetail.Loop2PerFee); if (sum == limit) { break; } //本小循环段结束时间超过出场时间 if (dtTmpStart.AddMinutes((int)RuleDetail.Loop2PerTime) >= ParkingEndTime) { return(total + sum); } dtTmpStart = dtTmpStart.AddMinutes((int)RuleDetail.Loop2PerTime); } } #endregion 小循环段2 //出场时间大于今天结束时间 if (ParkingEndTime > dtThisDayEnd) { return(Calc(true, dtNextDayStart, total + sum)); } return(total + sum); }