fix:施工人力预警

This commit is contained in:
geh 2025-12-05 14:37:05 +08:00
parent aea21182c7
commit 968c1ccb7a
3 changed files with 205 additions and 367 deletions

View File

@ -21,7 +21,6 @@ namespace BLL
foreach (var project in projects) foreach (var project in projects)
{ {
// 检查管理人员到期未到岗情况 // 检查管理人员到期未到岗情况
// var items1 = CheckManagerNotArrived(project.ProjectId);
var items1 = CheckHistoricalContinuousShortage(project.ProjectId); var items1 = CheckHistoricalContinuousShortage(project.ProjectId);
// 检查作业人员人力偏差情况 // 检查作业人员人力偏差情况
@ -49,114 +48,101 @@ namespace BLL
} }
/*/// <summary> #region
/// 检查管理人员到期未到岗情况(超过一周发出预警)
/// <summary>
/// 检查所有历史数据中连续一周以上人力不足的情况
/// </summary> /// </summary>
/// <param name="projectId">项目ID</param> private static IEnumerable<ToDoItem> CheckHistoricalContinuousShortage(string projectId)
private static IEnumerable<ToDoItem> CheckManagerNotArrived(string projectId)
{ {
//获取计划的最新版本 string strSql = @"WITH LatestVersions AS (
var version = "1"; SELECT ProjectId, MAX(Version) AS MaxVersion
var sgMan = Funs.DB.JDGL_SGManPower.Where(x => x.ProjectId == projectId).OrderByDescending(x => x.Version) FROM JDGL_SGManPower
.FirstOrDefault(); WHERE ProjectId = @ProjectId
if (sgMan != null) GROUP BY ProjectId
{ ),
version = sgMan.Version; PlanVsActual AS (
} SELECT
p.ProjectId,
// 先获取计划表超过一周的管理岗位有哪些 p.UnitId,
var dataList = (from x in Funs.DB.JDGL_SGManPower p.UnitWorkId,
join p in Funs.DB.Base_WorkPost on x.WorkPostId equals p.WorkPostId into pp p.WorkPostId,
from y in pp.DefaultIfEmpty() p.PlanDate,
where x.ProjectId == projectId && (y.PostType == "4" || y.PostType == "1") && p.Quantity AS PlanQuantity,
x.PlanDate <= DateTime.Now.AddDays(-7) && x.Version == version ISNULL(a.num, 0) AS num,
select x).ToList(); CASE WHEN ISNULL(a.num, 0) < p.Quantity THEN 1 ELSE 0 END AS IsShortage,
lv.MaxVersion
var lItems = new List<ToDoItem>(); FROM JDGL_SGManPower p
//循环检查实际考勤中的人数 INNER JOIN LatestVersions lv ON p.ProjectId = lv.ProjectId AND p.Version = lv.MaxVersion
foreach (var data in dataList) 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
int num = getInOutRecordNum(data); AND p.PlanDate = a.IntoOutTime
if (data.Quantity > num) AND (CHARINDEX(',' + p.UnitWorkId + ',', ',' + ISNULL(a.WorkAreaId, '') + ',') > 0
{ OR (ISNULL(a.WorkAreaId, '') = '' AND ISNULL(p.UnitWorkId, '') = ''))
lItems = SendManagerWarning(data.UnitId, projectId, data.WorkPostId, data.UnitWorkId, data.PlanDate, WHERE p.ProjectId = @ProjectId AND p.PlanDate <= GETDATE()
data.Quantity, num); ),
} ShortageWithRowNum AS (
} SELECT *,
ROW_NUMBER() OVER (
return lItems; PARTITION BY ProjectId, UnitId, UnitWorkId, WorkPostId
}*/ ORDER BY PlanDate
) AS RowNum
/*//获取实际考勤人员数 FROM PlanVsActual
private static int getInOutRecordNum(JDGL_SGManPower sgManPower) WHERE IsShortage = 1
{ ),
string strSql = @" ContinuousGroups AS (
SELECT e.UnitId, e.PostId, e.RecordDate, p.WorkAreaId as UnitWorkId SELECT *,
FROM T_d_EmployInOutRecord e INNER JOIN SitePerson_Person p ON e.IDCardNo = p.IdentityCard AND e.ProjectId = p.ProjectId DATEADD(DAY, -RowNum, PlanDate) AS GroupId
WHERE e.PostId IS NOT NULL AND e.PostId != '' FROM ShortageWithRowNum
AND e.ProjectId = @ProjectId ),
AND e.RecordDate = @RecordDate ContinuousCounts AS (
AND e.UnitId = @UnitId SELECT
AND e.PostId = @PostId"; 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> var parameters = new List<System.Data.SqlClient.SqlParameter>
{ {
new System.Data.SqlClient.SqlParameter("@ProjectId", sgManPower.ProjectId), new System.Data.SqlClient.SqlParameter("@ProjectId", projectId)
new System.Data.SqlClient.SqlParameter("@RecordDate", sgManPower.PlanDate),
new System.Data.SqlClient.SqlParameter("@UnitId", sgManPower.UnitId),
new System.Data.SqlClient.SqlParameter("@PostId", sgManPower.WorkPostId),
}; };
var warningItems = new List<ToDoItem>();
// 执行查询获取分组数据
var dt = SQLHelper.GetDataTableRunText(strSql, parameters.ToArray()); var dt = SQLHelper.GetDataTableRunText(strSql, parameters.ToArray());
// 创建一个新的DataTable来存储处理后的数据
DataTable processedDt = dt.Clone();
foreach (System.Data.DataRow row in dt.Rows) foreach (DataRow row in dt.Rows)
{ {
string ids = row["UnitWorkId"] != DBNull.Value ? row["UnitWorkId"].ToString() : string.Empty; warningItems.AddRange(SendManagerWarning(row["UnitId"].ToString(), row["ProjectId"].ToString(),
if (!string.IsNullOrEmpty(ids)) row["WorkPostId"].ToString(), row["UnitWorkId"].ToString(),
{ Convert.ToDateTime(row["StartDate"]), Convert.ToDateTime(row["EndDate"]),
string[] unitWorkIdArray = ids.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); Convert.ToInt32(row["PlanQuantity"]), Convert.ToInt32(row["num"])));
foreach (string unitWorkId in unitWorkIdArray)
{
// 往processedDt里面添加数据每个UnitWorkId一行
DataRow newRow = processedDt.NewRow();
newRow["UnitId"] = row["UnitId"];
newRow["PostId"] = row["PostId"];
newRow["RecordDate"] = row["RecordDate"];
newRow["UnitWorkId"] = unitWorkId.Trim();
processedDt.Rows.Add(newRow);
}
}
else
{
DataRow newRow = processedDt.NewRow();
newRow["UnitId"] = row["UnitId"];
newRow["PostId"] = row["PostId"];
newRow["RecordDate"] = row["RecordDate"];
newRow["UnitWorkId"] = string.Empty;
processedDt.Rows.Add(newRow);
}
} }
// 确定要用于后续处理的数据源 return warningItems;
IEnumerable<DataRow> dataSource = processedDt.AsEnumerable();
if (string.IsNullOrEmpty(sgManPower.UnitWorkId))
{
dataSource = dataSource.Where(x => x["UnitWorkId"] == null);
}
else
{
dataSource = dataSource.Where(x =>
x["UnitWorkId"] != DBNull.Value && x["UnitWorkId"].ToString() == sgManPower.UnitWorkId);
} }
return dataSource.Count();
}*/
/// <summary> /// <summary>
/// 发送管理人员预警 /// 发送管理人员预警
@ -290,23 +276,6 @@ namespace BLL
urlParams += "&endTime=" + string.Format("{0:yyyy-MM-dd}", endDate); urlParams += "&endTime=" + string.Format("{0:yyyy-MM-dd}", endDate);
} }
// // 添加岗位参数(如果已选择)
// if (quantity.HasValue)
// {
// urlParams += "&quantity=" + quantity.Value;
// }
//
// // 添加岗位参数(如果已选择)
// if (num >= 0)
// {
// urlParams += "&num=" + num;
// }
// else
// {
// urlParams += "&num=0";
// }
foreach (var userId in toUserIds) foreach (var userId in toUserIds)
{ {
Model.ToDoItem toDoItem = new Model.ToDoItem(); Model.ToDoItem toDoItem = new Model.ToDoItem();
@ -327,142 +296,119 @@ namespace BLL
return toDoItems; return toDoItems;
} }
#endregion
#region
// /// <summary> // /// <summary>
// /// 检查作业人员人力偏差情况一周内累计偏差值超过计划的10% // /// 检查作业人员人力偏差情况(一周内(连续7天不是最近七天)累计偏差值超过计划的10%
// /// </summary> // /// </summary>
// /// <param name="projectId">项目ID</param> // /// <param name="projectId">项目ID</param>
private static IEnumerable<ToDoItem> CheckWorkerDeviation(string projectId) private static IEnumerable<ToDoItem> CheckWorkerDeviation(string projectId)
{ {
//获取计划的最新版本 string strSql = @"WITH LatestVersions AS (
var version = "1"; SELECT ProjectId, MAX(Version) AS MaxVersion
var sgMan = Funs.DB.JDGL_SGManPower.Where(x => x.ProjectId == projectId).OrderByDescending(x => x.Version) FROM JDGL_SGManPower
.FirstOrDefault(); WHERE ProjectId = @ProjectId
if (sgMan != null) GROUP BY ProjectId
{ ),
version = sgMan.Version; PlanVsActual AS (
} SELECT
p.ProjectId,
//当前时间 p.UnitId,
var endDate = DateTime.Now; p.UnitWorkId,
//当前时间前7天 p.WorkPostId,
var startDate = DateTime.Now.AddDays(-7); p.PlanDate,
// 先获取计划表一周的作业岗位有哪些 p.Quantity AS PlanQuantity,
var dataList = (from x in Funs.DB.JDGL_SGManPower ISNULL(a.num, 0) AS num,
join p in Funs.DB.Base_WorkPost on x.WorkPostId equals p.WorkPostId into pp CASE
from y in pp.DefaultIfEmpty() WHEN p.Quantity > 0 AND ABS(CAST((p.Quantity - ISNULL(a.num, 0)) AS FLOAT) / p.Quantity) > 0.1
where x.ProjectId == projectId && (y.PostType == "2" || y.PostType == "3") && THEN 1
x.PlanDate >= startDate && x.PlanDate <= endDate && x.Version == version ELSE 0
group x by new END AS HasDeviation,
{ lv.MaxVersion
x.UnitId, FROM JDGL_SGManPower p
x.UnitWorkId, INNER JOIN LatestVersions lv ON p.ProjectId = lv.ProjectId AND p.Version = lv.MaxVersion
x.WorkPostId LEFT JOIN (
} SELECT ProjectId,UnitId,WorkPostId,IntoOutTime,WorkAreaId,num
into g FROM SitePerson_Checking_Statistics
select new ) a ON p.ProjectId = a.ProjectId
{ AND p.UnitId = a.UnitId
UnitId = g.Key.UnitId, AND p.WorkPostId = a.WorkPostId
UnitWorkId = g.Key.UnitWorkId, AND p.PlanDate = a.IntoOutTime
WorkPostId = g.Key.WorkPostId, AND (CHARINDEX(',' + p.UnitWorkId + ',', ',' + ISNULL(a.WorkAreaId, '') + ',') > 0
QuantitySum = g.Sum(x => x.Quantity) OR (ISNULL(a.WorkAreaId, '') = '' AND ISNULL(p.UnitWorkId, '') = ''))
}).ToList(); WHERE p.ProjectId = @ProjectId AND p.PlanDate <= GETDATE()
),
var lItems = new List<ToDoItem>(); DeviationWithRowNum AS (
//循环检查实际考勤中的人数 SELECT *,
foreach (var data in dataList) ROW_NUMBER() OVER (
{ PARTITION BY ProjectId, UnitId, UnitWorkId, WorkPostId
//根据人员计划表获取计划中的作业人员数 ORDER BY PlanDate
int num = getInOutRecordNum1(data.UnitId, data.UnitWorkId, data.WorkPostId, projectId); ) AS RowNum
FROM PlanVsActual
// 计算偏差百分比 WHERE HasDeviation = 1
if (data.QuantitySum != 0) ),
{ ContinuousGroups AS (
double deviationPercentage = Math.Abs((double)((data.QuantitySum - num) / data.QuantitySum)); SELECT *,
// 如果偏差超过10%,发出预警 DATEADD(DAY, -RowNum, PlanDate) AS GroupId
if (deviationPercentage > 0.1) FROM DeviationWithRowNum
{ ),
lItems = SendWorkerDeviationWarning(data.UnitId, projectId, data.WorkPostId, data.UnitWorkId, ContinuousCounts AS (
startDate, endDate, data.QuantitySum, num); SELECT
} ProjectId,
} UnitId,
} UnitWorkId,
WorkPostId,
return lItems; GroupId,
} COUNT(*) AS ContinuousDays,
MIN(PlanDate) AS StartDate,
MAX(PlanDate) AS EndDate,
//获取实际考勤人员数 SUM(PlanQuantity) as TotalPlanQuantity,
private static int getInOutRecordNum1(string unitId, string unitWorkId, string workPostId, string projectId) SUM(num) as num,
{ MaxVersion
string strSql = @" FROM ContinuousGroups
SELECT e.UnitId, e.PostId, e.RecordDate, p.WorkAreaId as UnitWorkId GROUP BY ProjectId, UnitId, UnitWorkId, WorkPostId, GroupId, MaxVersion
FROM T_d_EmployInOutRecord e INNER JOIN SitePerson_Person p ON e.IDCardNo = p.IdentityCard AND e.ProjectId = p.ProjectId )
WHERE e.PostId IS NOT NULL AND e.PostId != '' SELECT
AND e.ProjectId = @ProjectId ProjectId,
AND e.UnitId = @UnitId UnitId,
AND e.PostId = @PostId UnitWorkId,
AND e.RecordDate >= @StartDate WorkPostId,
AND e.RecordDate <= @EndDate"; ContinuousDays,
MaxVersion,
StartDate,
EndDate,
TotalPlanQuantity,
num
FROM ContinuousCounts
WHERE ContinuousDays >= 7";
var parameters = new List<System.Data.SqlClient.SqlParameter> var parameters = new List<System.Data.SqlClient.SqlParameter>
{ {
new System.Data.SqlClient.SqlParameter("@ProjectId", projectId), new System.Data.SqlClient.SqlParameter("@ProjectId", projectId)
new System.Data.SqlClient.SqlParameter("@UnitId", unitId),
new System.Data.SqlClient.SqlParameter("@PostId", workPostId),
new System.Data.SqlClient.SqlParameter("@StartDate", DateTime.Now.AddDays(-7)),
new System.Data.SqlClient.SqlParameter("@EndDate", DateTime.Now),
}; };
// 执行查询获取分组数据 var warningItems = new List<ToDoItem>();
var dt = SQLHelper.GetDataTableRunText(strSql, parameters.ToArray()); var dt = SQLHelper.GetDataTableRunText(strSql, parameters.ToArray());
// 创建一个新的DataTable来存储处理后的数据 foreach (DataRow row in dt.Rows)
DataTable processedDt = dt.Clone();
foreach (System.Data.DataRow row in dt.Rows)
{ {
string ids = row["UnitWorkId"] != DBNull.Value ? row["UnitWorkId"].ToString() : string.Empty; warningItems.AddRange(SendWorkerDeviationWarning(
if (!string.IsNullOrEmpty(ids)) row["UnitId"].ToString(),
{ row["ProjectId"].ToString(),
string[] unitWorkIdArray = ids.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); row["WorkPostId"].ToString(),
foreach (string id in unitWorkIdArray) row["UnitWorkId"].ToString(),
{ Convert.ToDateTime(row["StartDate"]),
// 往processedDt里面添加数据每个UnitWorkId一行 Convert.ToDateTime(row["EndDate"]),
DataRow newRow = processedDt.NewRow(); Convert.ToInt32(row["TotalPlanQuantity"]),
newRow["UnitId"] = row["UnitId"]; Convert.ToInt32(row["num"])
newRow["PostId"] = row["PostId"]; ));
newRow["RecordDate"] = row["RecordDate"];
newRow["UnitWorkId"] = id.Trim();
processedDt.Rows.Add(newRow);
}
}
else
{
DataRow newRow = processedDt.NewRow();
newRow["UnitId"] = row["UnitId"];
newRow["PostId"] = row["PostId"];
newRow["RecordDate"] = row["RecordDate"];
newRow["UnitWorkId"] = string.Empty;
processedDt.Rows.Add(newRow);
}
} }
// 确定要用于后续处理的数据源 return warningItems;
IEnumerable<DataRow> dataSource = processedDt.AsEnumerable();
if (string.IsNullOrEmpty(unitWorkId))
{
dataSource = dataSource.Where(x => x["UnitWorkId"] == null);
} }
else
{
dataSource = dataSource.Where(x =>
x["UnitWorkId"] != DBNull.Value && x["UnitWorkId"].ToString() == unitWorkId);
}
return dataSource.Count();
}
/// <summary> /// <summary>
/// 发送作业人员偏差预警 /// 发送作业人员偏差预警
@ -473,8 +419,7 @@ namespace BLL
/// <param name="actualTotal">实际总人数</param> /// <param name="actualTotal">实际总人数</param>
/// <param name="deviationPercentage">偏差百分比</param> /// <param name="deviationPercentage">偏差百分比</param>
private static List<ToDoItem> SendWorkerDeviationWarning(string unitId, string projectId, string workPostId, private static List<ToDoItem> SendWorkerDeviationWarning(string unitId, string projectId, string workPostId,
string unitWorkId, string unitWorkId, DateTime? startDate, DateTime? endDate, int? quantity, int num)
DateTime? startDate, DateTime? endDate, int? quantity, int num)
{ {
// 发送预警信息 // 发送预警信息
var toDoItems = new List<ToDoItem>(); var toDoItems = new List<ToDoItem>();
@ -560,23 +505,6 @@ namespace BLL
string.Format("{0:yyyy-MM-dd}", endDate); string.Format("{0:yyyy-MM-dd}", endDate);
} }
// 添加岗位参数(如果已选择)
if (quantity.HasValue)
{
urlParams += "&quantity=" + quantity.Value;
}
// 添加岗位参数(如果已选择)
if (num >= 0)
{
urlParams += "&num=" + num;
}
else
{
urlParams += "&num=0";
}
// 发送预警信息 // 发送预警信息
foreach (var userId in toUserIds) foreach (var userId in toUserIds)
{ {
@ -597,100 +525,6 @@ namespace BLL
return toDoItems; return toDoItems;
} }
#endregion
/// <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.ActualQuantity, 0) AS ActualQuantity,
CASE WHEN ISNULL(a.ActualQuantity, 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
* FROM View_EmployInOutRecord
) a ON p.ProjectId = a.ProjectId
AND p.UnitId = a.UnitId
AND p.WorkPostId = a.PostId
AND p.PlanDate = a.RecordDate
AND ISNULL(p.UnitWorkId, '') = ISNULL(a.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(ActualQuantity) as ActualQuantity,
MaxVersion
FROM ContinuousGroups
GROUP BY ProjectId, UnitId, UnitWorkId, WorkPostId, GroupId,MaxVersion
)
SELECT
ProjectId,
UnitId,
UnitWorkId,
WorkPostId,
ContinuousDays,
MaxVersion,
StartDate,
EndDate,PlanQuantity,ActualQuantity
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["ActualQuantity"])));
}
return warningItems;
}
} }
} }

View File

@ -63,9 +63,12 @@
<f:RenderField Width="100px" ColumnID="Quantity" DataField="Quantity" <f:RenderField Width="100px" ColumnID="Quantity" DataField="Quantity"
HeaderText="计划人力" HeaderTextAlign="Center" TextAlign="Left"> HeaderText="计划人力" HeaderTextAlign="Center" TextAlign="Left">
</f:RenderField> </f:RenderField>
<f:RenderField Width="100px" ColumnID="ActualQuantity" DataField="ActualQuantity" <f:RenderField Width="100px" ColumnID="num" DataField="num"
HeaderText="实际考勤" HeaderTextAlign="Center" TextAlign="Left"> HeaderText="实际考勤" HeaderTextAlign="Center" TextAlign="Left">
</f:RenderField> </f:RenderField>
<f:RenderField Width="100px" ColumnID="Bias" DataField="Bias"
HeaderText="偏差" HeaderTextAlign="Center" TextAlign="Left">
</f:RenderField>
</Columns> </Columns>
<Listeners> <Listeners>
<f:Listener Event="beforerowcontextmenu" Handler="onRowContextMenu"/> <f:Listener Event="beforerowcontextmenu" Handler="onRowContextMenu"/>

View File

@ -135,15 +135,16 @@ namespace FineUIPro.Web.JDGL.SGManPower
p.Version, p.Version,
p.Quantity, p.Quantity,
p.PlanDate, p.PlanDate,
ISNULL(a.ActualQuantity, 0) AS ActualQuantity ISNULL(a.num, 0) AS num,
FROM JDGL_SGManPower p (CASE WHEN p.Quantity > 0 AND ABS(CAST((p.Quantity - ISNULL(a.num, 0)) AS FLOAT) / p.Quantity) > 0.1
LEFT JOIN ( THEN ABS(CAST((p.Quantity - ISNULL(a.num, 0)) AS FLOAT) / p.Quantity)
SELECT * from View_EmployInOutRecord ELSE 0 end ) as Bias
) a ON p.ProjectId = a.ProjectId FROM JDGL_SGManPower p
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.UnitId = a.UnitId
AND p.WorkPostId = a.PostId AND p.WorkPostId = a.WorkPostId
AND p.PlanDate = a.RecordDate AND p.PlanDate = a.IntoOutTime
AND ISNULL(p.UnitWorkId, '') = ISNULL(a.UnitWorkId, '') where p.Version = '" + Version + "'"; AND (CHARINDEX(',' + p.UnitWorkId + ',', ',' + ISNULL(a.WorkAreaId, '') + ',') > 0 OR (ISNULL(a.WorkAreaId, '') = '' AND ISNULL(p.UnitWorkId, '') = '')) where p.Version = '" + Version + "'";
List<SqlParameter> listStr = new List<SqlParameter>(); List<SqlParameter> listStr = new List<SqlParameter>();
if (!string.IsNullOrEmpty(this.ProjectId)) if (!string.IsNullOrEmpty(this.ProjectId))