public ApiResponse <OrderModel> AddOrder(ApplyOrderModel model) { // 1. 检查输入参数 if (model == null) { throw new ApiBadRequestException("无效的参数"); } // 2. 验证申请单是否有效 /* * 验证不需要返回值,不符合要求弹出提示信息 * * * **/ ValidApplyOrder(model); //新增假单 如果是请假或者提交加班申请需要启动工作申请流程 // 3. Construct API Response var response = new ApiResponse <OrderModel>() { Result = AskLeaveService.AddOrder(model, this.Member) }; return(response); }
/// <summary> /// 修改申请信息 /// </summary> /// <returns>修改状态</returns> public bool UpdateOrder(int userId, int orderNo, UpdateOrderModel model) { using (var dbContext = new MissionskyOAEntities()) { #region 申请信息 //查询申请信息是否存在 var orderEntities = dbContext.Orders.Where(o => o.OrderNo == orderNo); var orderUsers = orderEntities.Select(o => o.UserId).ToArray(); var validateEntity = orderEntities.FirstOrDefault(); if (validateEntity == null) { Log.Error("申请记录不存在。"); throw new KeyNotFoundException("申请记录不存在。"); } var validateOrder = validateEntity.ToModel(); //model转换 var applyModel = new ApplyOrderModel() { OrderType = validateOrder.OrderType, StartDate = model.StartDate, EndDate = model.EndDate, IOHours = model.IOHours, UserIds = orderUsers, InformLeader = model.InformLeader, WorkTransfer = model.WorkTransfer, Recipient = model.Recipient }; //var orderDet = new OrderDet() //{ // StartDate = model.StartDate, // EndDate = model.EndDate, // StartTime = model.StartDate.TimeOfDay, // EndTime = model.EndDate.TimeOfDay, // Description = model.Description, // InformLeader = model.InformLeader ?? false, // WorkTransfer = model.WorkTransfer ?? false, // Recipient = model.Recipient ?? 0, // IOHours = model.IOHours //}; //validateEntity.OrderDets = new List<OrderDet>() { orderDet }; //下一步审批人 var opprover = dbContext.Users.FirstOrDefault( it => validateEntity.NextAudit.HasValue && it.Id == validateEntity.NextAudit.Value); #endregion #region 验证 var validateMsg = string.Empty; if (userId != validateOrder.ApplyUserId && (opprover != null && userId != opprover.Id)) { Log.Error("用户不能修改申请单。"); throw new InvalidOperationException("用户不能修改申请单。"); } if (DateTime.Compare(model.StartDate, DateTime.Now.AddDays(-15)) < 0) { validateMsg = "开始必须大于" + string.Format("{0:F}", DateTime.Now.AddDays(-15)); Log.Error(validateMsg); throw new InvalidOperationException(validateMsg); } if (DateTime.Compare(model.StartDate, DateTime.Now.AddDays(15)) > 0) { validateMsg = "开始必须小于" + string.Format("{0:F}", DateTime.Now.AddDays(15)); Log.Error(validateMsg); throw new InvalidOperationException(validateMsg); } if (model.StartDate >= model.EndDate) { validateMsg = "结束时间必须大于开始时间"; Log.Error(validateMsg); throw new InvalidOperationException(validateMsg); } if (validateOrder.OrderType != OrderType.Overtime && validateOrder.OrderType != 0) { TimeSpan dspWorkingDayAm = DateTime.Parse("08:30").TimeOfDay; TimeSpan dspWorkingDayPm = DateTime.Parse("18:30:59").TimeOfDay; if (model.StartDate.TimeOfDay < dspWorkingDayAm) { throw new InvalidOperationException("开始时间必须大于等于上午8点半"); } if (model.EndDate.TimeOfDay > dspWorkingDayPm) { throw new InvalidOperationException("结束时间必须小于等于下午6点半"); } } else { TimeSpan dspWorkingDayAm = DateTime.Parse("08:30").TimeOfDay; if (model.StartDate.TimeOfDay < dspWorkingDayAm) { throw new InvalidOperationException("开始时间必须大于上午8点半"); } } var invalidUsers = IsOrderTimeAvailiable(applyModel, orderNo); if (!string.IsNullOrEmpty(invalidUsers)) { throw new InvalidOperationException(string.Format("用户({0})此申请时段已经占用。", invalidUsers)); } #endregion #region 更新信息 var existedUser = new List <int>(); //申请单原本已经有的用户 if ((int)OrderStatus.Apply == validateEntity.Status || (opprover != null && opprover.ToModel().IsAdminStaff)) { #region 更新已存在的用户申请 orderEntities.ToList().ForEach(o => { if (model.UserIds.Contains(o.UserId)) //更新用户申请单 { OrderDet detailEntity = null; if (o.OrderDets == null || o.OrderDets.Any() == false) { detailEntity = dbContext.OrderDets.FirstOrDefault(od => od.OrderId == o.Id); } else { detailEntity = o.OrderDets.FirstOrDefault(); } //o.OrderType = (int)model.OrderType; 不能更新申请单类型 if (detailEntity != null) { detailEntity.StartDate = model.StartDate.Date; detailEntity.EndDate = model.EndDate.Date; detailEntity.IOHours = model.IOHours; detailEntity.StartTime = model.StartDate.TimeOfDay; detailEntity.EndTime = model.EndDate.TimeOfDay; detailEntity.Description = model.Description; detailEntity.InformLeader = model.InformLeader ?? detailEntity.InformLeader; detailEntity.WorkTransfer = model.WorkTransfer ?? detailEntity.WorkTransfer; detailEntity.Recipient = model.Recipient ?? detailEntity.Recipient; } existedUser.Add(o.UserId); //申请单原本已经有的用户 } else //移除用户申请单 { o.OrderDets.ToList().ForEach(d => dbContext.OrderDets.Remove(d)); //移出申请单详细 dbContext.Orders.Remove(o); //移出申请单 //o.Status = (int) OrderStatus.Canceled; //o.NextAudit = 0; //o.NextStep = 0; } }); #endregion #region 添加新增用户申请 model.UserIds.ToList().ForEach(it => { //validateOrder if (!existedUser.Contains(it)) { var newOrder = validateEntity.Copyto(); newOrder.UserId = it; //如果是修改撤销单 if (validateEntity.RefOrderId.HasValue) { var refOrder = GetOrderDetail(dbContext, validateEntity.RefOrderId.Value, false); if (refOrder != null) { newOrder.RefOrderId = _orderService.GetOrderIdByOrderNoAndUserId(dbContext, refOrder.OrderNo, it); } } dbContext.Orders.Add(newOrder); } }); #endregion //发送工作交接通知 if (model.WorkTransfer.HasValue && model.WorkTransfer.Value && model.Recipient.HasValue && validateEntity.OrderType != (int)OrderType.Overtime) { _orderService.AddNotification(dbContext, validateEntity.ToModel()); } dbContext.SaveChanges(); return(true); } else { Log.Error("已处于审批流程,不能更新。"); throw new InvalidOperationException("已处于审批流程,不能更新"); } #endregion } }
/// <summary> /// 添加请假信息 /// /// 处理请假申请单逻辑 /// /// </summary> /// <param name="model">申请单详细: 对应APP中的申请单详细</param> /// <param name="applicant">流程申请人Id</param> /// <returns>请假单信息</returns> public OrderModel AddOrder(ApplyOrderModel model, UserModel applicant) { /* * * * * **/ #region 申请单详细 // 1、新建申请单变量 var order = new OrderModel() { OrderType = model.OrderType, Status = OrderStatus.Apply, ApplyUserId = applicant.Id, IsBatchApply = (model.UserIds.Count() > 1), CreatedTime = DateTime.Now, }; // 2、新建申请单详情 var orderDet = new OrderDetModel() { StartDate = model.StartDate, EndDate = model.EndDate, StartTime = model.StartDate.TimeOfDay, EndTime = model.EndDate.TimeOfDay, Description = model.Description, InformLeader = model.InformLeader ?? false, WorkTransfer = model.WorkTransfer ?? false, Recipient = model.Recipient ?? 0, IOHours = model.IOHours }; // 3、将申请单详情变量 放入到 申请单变量中 order.OrderDets = new List <OrderDetModel>() { orderDet }; #endregion // 4、逻辑处理 using (var dbContext = new MissionskyOAEntities()) { // 1、生成申请单号 、申请单用户 // OrderNo --> int order.OrderNo = _orderService.GenerateOrderNo(dbContext); //生成申请单号 /* * OrderUsers --> IList<OrderUserModel> * model.UserIds --> 定义为 int[], 表示可以或者可能有多个申请用户 * * **/ order.OrderUsers = _userService.GetOrderUsers(dbContext, model.UserIds); // 2、验证申请单是否有效,并转换IOHours正负值 ValidOrder(order, WorkflowOperation.Apply); // 3、添加初始审批信息 AddAuditMessages(dbContext, order, applicant); // 4、添加申请单到数据库 var dbOrders = AddOrderToDb(dbContext, order, WorkflowOperation.Apply); // 5、流程申请 WorkflowProcessModel process = _orderService.Apply(dbContext, order); if (process == null) { Log.Error("找不到流程。"); throw new InvalidOperationException("找不到流程。"); } // 6、更新申请单工作流 UpdateOrderProcess(dbContext, dbOrders, order, process, applicant); // 7、发送工作交接通知 if (model.WorkTransfer.HasValue && model.WorkTransfer.Value && model.Recipient.HasValue && model.OrderType != OrderType.Overtime) { _orderService.AddNotification(dbContext, order); } // 8、更新申请单其它信息 dbContext.SaveChanges(); // 9、 return(order); } }
/// <summary> /// 是否时间段重复申请 /// /// 验证用户申请的时间段是否被占用 /// /// </summary> /// <returns>是否时间段重复申请</returns> public string IsOrderTimeAvailiable(ApplyOrderModel model, int updateOrderNo) { using (var dbContext = new MissionskyOAEntities()) { var startDate = model.StartDate; var endDate = model.EndDate; var invalidUsers = new List <int>(); //无效的用户 // RefOrderId 为 审批人Id // 根据申请单号获取审批人Id var refOrderIds = dbContext.Orders.Where(it => it.OrderNo == updateOrderNo).Select(it => it.RefOrderId); model.UserIds.ToList().ForEach(userId => { // var isTimeAvailabel = true; /* * 获取当前用户是否有正在审批或者正在执行的申请单 * 1、当前申请用户 * 2、不是现在正在申请的,也不是修改的 * 3、不是取消状态的 * 4、不是拒绝状态的 * 5、不是撤销状态的 * * **/ var entityOrder = dbContext.Orders.Where( it => it.UserId == userId && //查询用户的申请记录 it.OrderNo != updateOrderNo && //不是当前待添加或修改的申请记录 it.Status != (int)OrderStatus.Canceled && //过滤 取消状态的申请记录 it.Status != (int)OrderStatus.Rejected && //过滤 拒绝状态的申请记录 it.Status != (int)OrderStatus.Revoked); //过滤 撤销状态的申请记录 var orderList = entityOrder.ToList(); foreach (Order item in orderList) { if (refOrderIds.Contains(item.Id)) //过滤撤销单 { continue; } /* * * * **/ //startdate>currentEndate or endate<currentStartdate var avaliableStartDateTimeExist = dbContext.OrderDets.FirstOrDefault( it => it.OrderId == item.Id && (it.StartDate > endDate.Date || it.EndDate < startDate.Date) || (it.StartDate == startDate.Date && it.EndDate == endDate.Date)); if (avaliableStartDateTimeExist == null) { isTimeAvailabel = false; break; } var avaliableDateInTheDbdate = dbContext.OrderDets.FirstOrDefault( it => it.OrderId == item.Id && (it.StartDate < startDate.Date) && it.EndDate > endDate.Date); if (avaliableDateInTheDbdate != null) { isTimeAvailabel = false; break; } var entityStarTimeExist = dbContext.OrderDets.FirstOrDefault( it => it.OrderId == item.Id && it.StartDate == startDate.Date && it.EndDate == endDate.Date && startDate.TimeOfDay >= it.StartTime && startDate.TimeOfDay < it.EndTime); var entityEndTimeExist = dbContext.OrderDets.FirstOrDefault( it => it.OrderId == item.Id && it.StartDate == startDate.Date && it.EndDate == endDate.Date && endDate.TimeOfDay > it.StartTime && endDate.TimeOfDay <= it.EndTime); var DBTimeBetweenCurrentApplyTime = dbContext.OrderDets.FirstOrDefault( it => it.OrderId == item.Id && it.StartDate == startDate.Date && it.EndDate == endDate.Date && startDate.TimeOfDay <= it.StartTime && endDate.TimeOfDay >= it.EndTime); if ((entityStarTimeExist != null) || (entityEndTimeExist != null) || (DBTimeBetweenCurrentApplyTime != null)) { isTimeAvailabel = false; break; } } if (!isTimeAvailabel) { invalidUsers.Add(userId); } }); /* * 如果申请的时间段有被占用的话,那么返回占用时间段的申请人英文名 * * **/ return(invalidUsers.Count > 0 ? _userService.GetUsersName(dbContext, invalidUsers.ToArray()) : string.Empty); } }
/// <summary> /// 验证申请单是否有效 /// /// 这段验证在APP端提交表单到后台之前 /// /// </summary> /// <param name="model">申请单</param> private void ValidApplyOrder(ApplyOrderModel model) { // 1、 验证申请人 if (model.UserIds.Count() < 0) { Log.Error("请选择申请人。"); throw new ApiBadRequestException("请选择申请人。"); } // 2、验证申请时间 /* * DateTime.Now.AddDays(-15) : 当前日期往前算15天 * DateTime.Now.AddDays(15) : 当前日期往后算15天 * **/ if (DateTime.Compare(model.StartDate, DateTime.Now.AddDays(-15)) < 0) { throw new ApiBadRequestException("开始必须大于" + string.Format("{0:F}", DateTime.Now.AddDays(-15))); } if (DateTime.Compare(model.StartDate, DateTime.Now.AddDays(15)) > 0) { throw new ApiBadRequestException("开始必须小于" + string.Format("{0:F}", DateTime.Now.AddDays(15))); } if (model.StartDate >= model.EndDate) { throw new ApiBadRequestException("结束时间必须大于开始时间"); } /* * 3、 * 请假: * 开始时间必须大于等于上午8点半 * 结束时间必须小于等于下午6点半 * * 加班: * 开始时间必须大于上午8点半 * * **/ if (model.OrderType != OrderType.Overtime && model.OrderType != 0) { TimeSpan dspWorkingDayAM = DateTime.Parse("08:30").TimeOfDay; TimeSpan dspWorkingDayPM = DateTime.Parse("18:30:59").TimeOfDay; if (model.StartDate.TimeOfDay < dspWorkingDayAM) { throw new ApiBadRequestException("开始时间必须大于等于上午8点半"); } if (model.EndDate.TimeOfDay > dspWorkingDayPM) { throw new ApiBadRequestException("结束时间必须小于等于下午6点半"); } } else { // 加班 : 开始时间必须大于上午8点半 TimeSpan dspWorkingDayAM = DateTime.Parse("08:30").TimeOfDay; if (model.StartDate.TimeOfDay < dspWorkingDayAM) { throw new ApiBadRequestException("开始时间必须大于上午8点半"); } } /* * 4、验证用户申请的时间段是否被占用 * * 参数0:申请单提交到后台前,申请单号为0 * * **/ var invalidUsers = AskLeaveService.IsOrderTimeAvailiable(model, 0); if (!string.IsNullOrEmpty(invalidUsers)) { throw new ApiBadRequestException(string.Format("用户({0})此申请时段已经占用。", invalidUsers)); } }