CNCEC_SUBQHSE_WUHUAN/SGGL/BLL/JDGL/SGManPower/SGManPowerService.cs

530 lines
23 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Linq;
using Model;
using System.Data;
namespace BLL
{
public class SGManPowerService
{
/// <summary>
/// 检查并发送人力资源预警
/// </summary>
public static List<ToDoItem> CheckAndSendPersonWarning(string userId)
{
var responeData = new Model.ResponeData();
// 合并两个集合
var allItems = new List<ToDoItem>();
var projects = Funs.DB.Base_Project.Where(p => p.ProjectState == BLL.Const.ProjectState_1).ToList();
foreach (var project in projects)
{
// 检查管理人员到期未到岗情况
var items1 = CheckHistoricalContinuousShortage(project.ProjectId);
// 检查作业人员人力偏差情况
var items2 = CheckWorkerDeviation(project.ProjectId);
if (items1 != null)
{
allItems.AddRange(items1);
}
if (items2 != null)
{
allItems.AddRange(items2);
}
}
if (!string.IsNullOrEmpty(userId))
{
//过滤出指定用户的数据
allItems = allItems.Where(x => x.UserId == userId).ToList();
}
return allItems;
}
#region
/// <summary>
/// 检查所有历史数据中连续一周以上人力不足的情况
/// </summary>
private static IEnumerable<ToDoItem> CheckHistoricalContinuousShortage(string projectId)
{
string strSql = @"WITH LatestVersions AS (
SELECT ProjectId, MAX(Version) AS MaxVersion
FROM JDGL_SGManPower
WHERE ProjectId = @ProjectId
GROUP BY ProjectId
),
PlanVsActual AS (
SELECT
p.ProjectId,
p.UnitId,
p.UnitWorkId,
p.WorkPostId,
p.PlanDate,
p.Quantity AS PlanQuantity,
ISNULL(a.num, 0) AS num,
CASE WHEN ISNULL(a.num, 0) < p.Quantity THEN 1 ELSE 0 END AS IsShortage,
lv.MaxVersion
FROM JDGL_SGManPower p
INNER JOIN LatestVersions lv ON p.ProjectId = lv.ProjectId AND p.Version = lv.MaxVersion
LEFT JOIN ( SELECT ProjectId,UnitId,WorkPostId,IntoOutTime,WorkAreaId,num FROM SitePerson_Checking_Statistics ) a ON p.ProjectId = a.ProjectId
AND p.UnitId = a.UnitId
AND p.WorkPostId = a.WorkPostId
AND p.PlanDate = a.IntoOutTime
AND (CHARINDEX(',' + p.UnitWorkId + ',', ',' + ISNULL(a.WorkAreaId, '') + ',') > 0
OR (ISNULL(a.WorkAreaId, '') = '' AND ISNULL(p.UnitWorkId, '') = ''))
WHERE p.ProjectId = @ProjectId AND p.PlanDate <= GETDATE()
),
ShortageWithRowNum AS (
SELECT *,
ROW_NUMBER() OVER (
PARTITION BY ProjectId, UnitId, UnitWorkId, WorkPostId
ORDER BY PlanDate
) AS RowNum
FROM PlanVsActual
WHERE IsShortage = 1
),
ContinuousGroups AS (
SELECT *,
DATEADD(DAY, -RowNum, PlanDate) AS GroupId
FROM ShortageWithRowNum
),
ContinuousCounts AS (
SELECT
ProjectId,
UnitId,
UnitWorkId,
WorkPostId,
GroupId,
COUNT(*) AS ContinuousDays,
MIN(PlanDate) AS StartDate,
MAX(PlanDate) AS EndDate,
SUM(PlanQuantity) as PlanQuantity,
SUM(num) as num,
MaxVersion
FROM ContinuousGroups
GROUP BY ProjectId, UnitId, UnitWorkId, WorkPostId, GroupId,MaxVersion
)
SELECT
ProjectId,
UnitId,
UnitWorkId,
WorkPostId,
ContinuousDays,
MaxVersion,
StartDate,
EndDate,PlanQuantity,num
FROM ContinuousCounts
WHERE ContinuousDays >= 7";
var parameters = new List<System.Data.SqlClient.SqlParameter>
{
new System.Data.SqlClient.SqlParameter("@ProjectId", projectId)
};
var warningItems = new List<ToDoItem>();
var dt = SQLHelper.GetDataTableRunText(strSql, parameters.ToArray());
foreach (DataRow row in dt.Rows)
{
warningItems.AddRange(SendManagerWarning(row["UnitId"].ToString(), row["ProjectId"].ToString(),
row["WorkPostId"].ToString(), row["UnitWorkId"].ToString(),
Convert.ToDateTime(row["StartDate"]), Convert.ToDateTime(row["EndDate"]),
Convert.ToInt32(row["PlanQuantity"]), Convert.ToInt32(row["num"])));
}
return warningItems;
}
/// <summary>
/// 发送管理人员预警
/// </summary>
/// <param name="projectId">项目ID</param>
/// <param name="unitId">单位id</param>
private static List<ToDoItem> SendManagerWarning(string unitId, string projectId, string workPostId,
string unitWorkId, DateTime? startDate, DateTime? endDate, int? quantity, int num)
{
// 发送预警信息
var toDoItems = new List<ToDoItem>();
var unitWorks = (from x in Funs.DB.WBS_UnitWork
where x.UnitWorkId == unitWorkId
select new { x.UnitWorkId, x.UnitWorkName }).FirstOrDefault();
var projectUnits = (from x in Funs.DB.Project_ProjectUnit
join y in Funs.DB.Base_Unit on x.UnitId equals y.UnitId
where x.UnitId == unitId
select new { x.UnitId, y.UnitName, x.UnitType }).FirstOrDefault();
if (projectUnits != null)
{
List<string> toUserIds = new List<string>();
// 施工单位人员推送至施工单位项目经理和总包单位施工经理
if (projectUnits.UnitType == Const.ProjectUnitType_2) // 施工分包单位
{
// 获取施工单位项目经理
var constructionManagers = (from x in Funs.DB.Project_ProjectUser
where x.ProjectId == projectId && x.UnitId == unitId && x.IsPost == true &&
x.RoleId.Contains(Const.ProjectManager)
select x).ToList();
if (constructionManagers.Count > 0)
{
foreach (var projectUser in constructionManagers)
{
toUserIds.Add(projectUser.UserId);
}
}
// 获取总包单位施工经理
var generalContractorUnit = Funs.DB.Project_ProjectUnit.FirstOrDefault(pu =>
pu.ProjectId == projectId && pu.UnitType == Const.ProjectUnitType_1); // 总包单位
if (generalContractorUnit != null)
{
var constructionManagerGCs = (from x in Funs.DB.Project_ProjectUser
where x.ProjectId == projectId && x.UnitId == generalContractorUnit.UnitId &&
x.IsPost == true && x.RoleId.Contains(Const.ConstructionManager)
select x).ToList();
if (constructionManagerGCs.Count > 0)
{
foreach (var projectUser in constructionManagerGCs)
{
toUserIds.Add(projectUser.UserId);
}
}
}
}
// 总包单位人员推送到总包单位施工经理和项目经理
else if (projectUnits.UnitType == Const.ProjectUnitType_1) // 总包单位
{
// 获取总包单位施工经理
var constructionManagers = (from x in Funs.DB.Project_ProjectUser
where x.ProjectId == projectId && x.UnitId == unitId && x.IsPost == true &&
x.RoleId.Contains(Const.ConstructionManager)
select x).ToList();
if (constructionManagers.Count() > 0)
{
foreach (var projectUser in constructionManagers)
{
toUserIds.Add(projectUser.UserId);
}
}
// 获取总包单位项目经理
var projectManagers = (from x in Funs.DB.Project_ProjectUser
where x.ProjectId == projectId && x.UnitId == unitId && x.IsPost == true &&
x.RoleId.Contains(Const.ProjectManager)
select x).ToList();
if (projectManagers.Count() > 0)
{
foreach (var projectUser in projectManagers)
{
toUserIds.Add(projectUser.UserId);
}
}
}
string warningContent = string.Empty;
if (unitWorks != null)
{
warningContent =
$"{projectUnits.UnitName}单位{unitWorks.UnitWorkName}装置计划{string.Format("{0:yyyy-MM-dd}", startDate)}~{string.Format("{0:yyyy-MM-dd}", endDate)}投入人力{quantity}人,实际考勤为{num}人。";
}
else
{
warningContent =
$"{projectUnits.UnitName}单位计划{string.Format("{0:yyyy-MM-dd}", startDate)}~{string.Format("{0:yyyy-MM-dd}", endDate)}投入人力{quantity}人,实际考勤为{num}人。";
}
string urlParams = "JDGL/SGManPower/SGWarningDetailsEdit.aspx?projectId=" + projectId;
// 添加单位参数(如果已选择)
if (!string.IsNullOrEmpty(unitId))
{
urlParams += "&unitId=" + unitId;
}
// 添加装置参数(如果已选择)
if (!string.IsNullOrEmpty(unitWorkId))
{
urlParams += "&unitWorkId=" + unitWorkId;
}
// 添加岗位参数(如果已选择)
if (!string.IsNullOrEmpty(workPostId))
{
urlParams += "&workPostId=" + workPostId;
}
// 添加时间参数
if (startDate.HasValue)
{
urlParams += "&startTime=" + string.Format("{0:yyyy-MM-dd}", startDate);
}
// 添加时间参数
if (endDate.HasValue)
{
urlParams += "&endTime=" + string.Format("{0:yyyy-MM-dd}", endDate);
}
foreach (var userId in toUserIds)
{
Model.ToDoItem toDoItem = new Model.ToDoItem();
toDoItem.DataId = SQLHelper.GetNewID(typeof(Model.ToDoItem));
toDoItem.MenuId = "";
toDoItem.MenuName = "管理人员到岗预警";
toDoItem.ProjectCode = "";
toDoItem.Content = warningContent;
toDoItem.UserId = userId;
toDoItem.UserName = UserService.GetUserNameByUserId(userId);
toDoItem.DataTime = DateTime.Now;
toDoItem.DataTimeStr = DateTime.Now.ToString("yyyy-MM-dd");
toDoItem.PCUrl = urlParams;
toDoItems.Add(toDoItem);
}
}
return toDoItems;
}
#endregion
#region
// /// <summary>
// /// 检查作业人员人力偏差情况(一周内(连续7天不是最近七天)累计偏差值超过计划的10%
// /// </summary>
// /// <param name="projectId">项目ID</param>
private static IEnumerable<ToDoItem> CheckWorkerDeviation(string projectId)
{
string strSql = @"WITH LatestVersions AS (
SELECT ProjectId, MAX(Version) AS MaxVersion
FROM JDGL_SGManPower
WHERE ProjectId = @ProjectId
GROUP BY ProjectId
),
PlanVsActual AS (
SELECT
p.ProjectId,
p.UnitId,
p.UnitWorkId,
p.WorkPostId,
p.PlanDate,
p.Quantity AS PlanQuantity,
ISNULL(a.num, 0) AS num,
CASE
WHEN p.Quantity > 0 AND ABS(CAST((p.Quantity - ISNULL(a.num, 0)) AS FLOAT) / p.Quantity) > 0.1
THEN 1
ELSE 0
END AS HasDeviation,
lv.MaxVersion
FROM JDGL_SGManPower p
INNER JOIN LatestVersions lv ON p.ProjectId = lv.ProjectId AND p.Version = lv.MaxVersion
LEFT JOIN (
SELECT ProjectId,UnitId,WorkPostId,IntoOutTime,WorkAreaId,num
FROM SitePerson_Checking_Statistics
) a ON p.ProjectId = a.ProjectId
AND p.UnitId = a.UnitId
AND p.WorkPostId = a.WorkPostId
AND p.PlanDate = a.IntoOutTime
AND (CHARINDEX(',' + p.UnitWorkId + ',', ',' + ISNULL(a.WorkAreaId, '') + ',') > 0
OR (ISNULL(a.WorkAreaId, '') = '' AND ISNULL(p.UnitWorkId, '') = ''))
WHERE p.ProjectId = @ProjectId AND p.PlanDate <= GETDATE()
),
DeviationWithRowNum AS (
SELECT *,
ROW_NUMBER() OVER (
PARTITION BY ProjectId, UnitId, UnitWorkId, WorkPostId
ORDER BY PlanDate
) AS RowNum
FROM PlanVsActual
WHERE HasDeviation = 1
),
ContinuousGroups AS (
SELECT *,
DATEADD(DAY, -RowNum, PlanDate) AS GroupId
FROM DeviationWithRowNum
),
ContinuousCounts AS (
SELECT
ProjectId,
UnitId,
UnitWorkId,
WorkPostId,
GroupId,
COUNT(*) AS ContinuousDays,
MIN(PlanDate) AS StartDate,
MAX(PlanDate) AS EndDate,
SUM(PlanQuantity) as TotalPlanQuantity,
SUM(num) as num,
MaxVersion
FROM ContinuousGroups
GROUP BY ProjectId, UnitId, UnitWorkId, WorkPostId, GroupId, MaxVersion
)
SELECT
ProjectId,
UnitId,
UnitWorkId,
WorkPostId,
ContinuousDays,
MaxVersion,
StartDate,
EndDate,
TotalPlanQuantity,
num
FROM ContinuousCounts
WHERE ContinuousDays >= 7";
var parameters = new List<System.Data.SqlClient.SqlParameter>
{
new System.Data.SqlClient.SqlParameter("@ProjectId", projectId)
};
var warningItems = new List<ToDoItem>();
var dt = SQLHelper.GetDataTableRunText(strSql, parameters.ToArray());
foreach (DataRow row in dt.Rows)
{
warningItems.AddRange(SendWorkerDeviationWarning(
row["UnitId"].ToString(),
row["ProjectId"].ToString(),
row["WorkPostId"].ToString(),
row["UnitWorkId"].ToString(),
Convert.ToDateTime(row["StartDate"]),
Convert.ToDateTime(row["EndDate"]),
Convert.ToInt32(row["TotalPlanQuantity"]),
Convert.ToInt32(row["num"])
));
}
return warningItems;
}
/// <summary>
/// 发送作业人员偏差预警
/// </summary>
/// <param name="projectId">项目ID</param>
/// <param name="unitId">单位ID</param>
/// <param name="planTotal">计划总人数</param>
/// <param name="actualTotal">实际总人数</param>
/// <param name="deviationPercentage">偏差百分比</param>
private static List<ToDoItem> SendWorkerDeviationWarning(string unitId, string projectId, string workPostId,
string unitWorkId, DateTime? startDate, DateTime? endDate, int? quantity, int num)
{
// 发送预警信息
var toDoItems = new List<ToDoItem>();
List<string> toUserIds = new List<string>();
var unitWorks = (from x in Funs.DB.WBS_UnitWork
where x.UnitWorkId == unitWorkId
select new { x.UnitWorkId, x.UnitWorkName }).FirstOrDefault();
var projectUnits = (from x in Funs.DB.Project_ProjectUnit
join y in Funs.DB.Base_Unit on x.UnitId equals y.UnitId
where x.UnitId == unitId
select new { x.UnitId, y.UnitName, x.UnitType }).FirstOrDefault();
// 获取施工单位项目经理
var constructionManagers = (from x in Funs.DB.Project_ProjectUser
where x.ProjectId == projectId && x.UnitId == unitId && x.IsPost == true &&
x.RoleId.Contains(Const.ProjectManager)
select x).ToList();
if (constructionManagers.Count > 0)
{
foreach (var projectUser in constructionManagers)
{
toUserIds.Add(projectUser.UserId);
}
}
// 获取总包单位施工经理
var generalContractorUnit = Funs.DB.Project_ProjectUnit.FirstOrDefault(pu =>
pu.ProjectId == projectId && pu.UnitType == Const.ProjectUnitType_1); // 总包单位
if (generalContractorUnit != null)
{
var constructionManagerGCs = (from x in Funs.DB.Project_ProjectUser
where x.ProjectId == projectId && x.UnitId == generalContractorUnit.UnitId &&
x.IsPost == true && x.RoleId.Contains(Const.ConstructionManager)
select x).ToList();
if (constructionManagerGCs.Count > 0)
{
foreach (var projectUser in constructionManagerGCs)
{
toUserIds.Add(projectUser.UserId);
}
}
}
// 构建预警信息内容
string warningContent = string.Empty;
if (unitWorks != null)
{
warningContent =
$"{projectUnits.UnitName}单位{unitWorks.UnitWorkName}装置计划投入人力{quantity}人,实际考勤为{num}人。";
}
else
{
warningContent = $"{projectUnits.UnitName}单位计划投入人力{quantity}人,实际考勤为{num}人。";
}
string urlParams = "JDGL/SGManPower/SGWarningDetails.aspx?projectId=" + projectId;
// 添加单位参数(如果已选择)
if (!string.IsNullOrEmpty(unitId))
{
urlParams += "&unitId=" + unitId;
}
// 添加装置参数(如果已选择)
if (!string.IsNullOrEmpty(unitWorkId))
{
urlParams += "&unitWorkId=" + unitWorkId;
}
// 添加岗位参数(如果已选择)
if (!string.IsNullOrEmpty(workPostId))
{
urlParams += "&workPostId=" + workPostId;
}
// 添加时间参数
if (startDate.HasValue && endDate.HasValue)
{
urlParams += "&planDate=" + string.Format("{0:yyyy-MM-dd}", startDate) + "~" +
string.Format("{0:yyyy-MM-dd}", endDate);
}
// 发送预警信息
foreach (var userId in toUserIds)
{
Model.ToDoItem toDoItem = new Model.ToDoItem();
toDoItem.DataId = SQLHelper.GetNewID(typeof(Model.ToDoItem));
toDoItem.MenuId = "";
toDoItem.MenuName = "人力资源偏差预警";
toDoItem.ProjectCode = "";
toDoItem.Content = warningContent;
toDoItem.UserId = userId;
toDoItem.UserName = UserService.GetUserNameByUserId(userId);
toDoItem.DataTime = DateTime.Now;
toDoItem.DataTimeStr = DateTime.Now.ToString("yyyy-MM-dd");
toDoItem.PCUrl = urlParams;
toDoItems.Add(toDoItem);
}
return toDoItems;
}
#endregion
}
}