Commit 09660823 by ruyun.zhang@suvalue.com

Merge branch 'feature/考勤' into develop

parents 8f5ffe65 4226f21a
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Performance.DtoModels;
using Performance.EntityModels.Entity;
using Performance.EntityModels.Other;
using Performance.Services;
using System.Collections.Generic;
namespace Performance.Api.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class AttendanceController : ControllerBase
{
private readonly AttendanceService _attendanceService;
public AttendanceController(
AttendanceService attendanceService
)
{
_attendanceService = attendanceService;
}
/*
per_attendance 考勤-调动记录表
per_attendance_type 考勤-考勤类型
per_attendance_vacation 考勤-考勤记录表
view_attendance 考勤视图
*/
/// <summary>
/// 查询绩效考勤记录
/// </summary>
/// <param name="allotId"></param>
/// <returns></returns>
[HttpGet("GetAttendance/{allotId}")]
public ApiResponse<List<AttendanceStatistics>> GetAttendance(int allotId)
{
// 查询考勤视图,并按照设计图做格式转换 仅查询开始结束
var result = _attendanceService.GetAttendance(allotId);
return result;
}
#region 调动记录
/// <summary>
/// 查询绩效调动记录
/// </summary>
/// <param name="allotId"></param>
/// <returns></returns>
[HttpGet("CallIn/{allotId}")]
public ApiResponse<List<view_attendance>> GetCallIn(int allotId)
{
// 查询考勤视图,并按照设计图做格式转换 仅查询调入
var result = _attendanceService.GetCallIn(allotId);
return result;
}
/// <summary>
/// 返回HandsonTable格式调动记录
/// </summary>
/// <returns></returns>
[HttpGet("CallIn/GetBatch")]
[ProducesResponseType(typeof(HandsonTable), StatusCodes.Status200OK)]
public ApiResponse GetBatchCallInHandsonTable()
{
// 返回HandsonTable格式调动记录
return new ApiResponse(ResponseType.OK, _attendanceService.GetBatchCallInHandsonTable());
}
/// <summary>
/// 批量插入调动记录
/// </summary>
/// <param name="allotId"></param>
/// <param name="hospitalId"></param>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost("CallIn/Batch/{allotId}")]
public ApiResponse BatchCallIn(int allotId, int hospitalId, SaveCollectData request)
{
// obj自己定义结构
// 批量插入调动记录,插入前需要删除所有后重新插入
// 需要验证工号和姓名是否与“人员字典”(per_employee)完全匹配,不匹配则返回表格错误提示
// 需要验证核算组别和核算单元是否与“核算单元及组别”(cof_accounting)完全匹配,不匹配则返回表格错误提示
// 表格错误提醒参考PersonService.CreatePerson方法
return _attendanceService.BatchCallIn(allotId, hospitalId, request);
}
#endregion
#region 考勤类型
/// <summary>
/// 查询绩效考勤类型
/// </summary>
/// <param name="allotId"></param>
/// <param name="hospitalId"></param>
/// <returns></returns>
[HttpGet("Type/{allotId},{hospitalId}")]
public ApiResponse<List<per_attendance_type>> GetAttendanceType(int allotId, int hospitalId)
{
return _attendanceService.GetAttendanceType(allotId, hospitalId);
}
/// <summary>
/// 新增或修改考勤类型
/// </summary>
/// <param name="allotId"></param>
/// <param name="hospitalId"></param>
/// <param name="attendanceType"></param>
/// <returns></returns>
[HttpPost("Type/Edit/{allotId},{hospitalId}")]
public ApiResponse<AttendanceType> InsertAttendanceType(int allotId, int hospitalId, AttendanceType attendanceType)
{
// obj自己定义结构
return _attendanceService.InsertAttendanceType(allotId, hospitalId, attendanceType);
}
/// <summary>
/// 删除考勤类型
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpPost("Type/Delete/{id}")]
public ApiResponse DeleteAttendanceType(int id)
{
// 删除前需要验证当前类型是否被使用,如果被使用则禁止删除
return _attendanceService.DeleteAttendanceType(id);
}
#endregion
#region 考勤记录
/// <summary>
/// 返回HandsonTable格式考勤记录
/// </summary>
/// <returns></returns>
[HttpGet("Vacation")]
[ProducesResponseType(typeof(HandsonTable), StatusCodes.Status200OK)]
public ApiResponse GetAttendanceVacationHandsonTable()
{
// 返回HandsonTable格式考勤记录
return new ApiResponse(ResponseType.OK, _attendanceService.GetAttendanceVacationHandsonTable());
}
/// <summary>
/// 查询考勤记录
/// </summary>
/// <param name="allotId"></param>
/// <param name="hospitalId"></param>
/// <returns></returns>
[HttpGet("Vacation/{allotId},{hospitalId}")]
public ApiResponse<List<RecordAttendcance>> GetAttendanceVacation(int allotId, int hospitalId)
{
return _attendanceService.GetAttendanceVacation(allotId, hospitalId);
}
/// <summary>
/// 批量插入考勤记录,插入前需要删除所有后重新插入
/// </summary>
/// <param name="allotId"></param>
/// <param name="hospitalId"></param>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost("Vacation/Batch/{allotId}")]
public ApiResponse AttendanceBatch(int allotId, int hospitalId, SaveCollectData request)
{
// obj自己定义结构
// 批量插入考勤记录,插入前需要删除所有后重新插入
// 需要验证考勤类型是否正确
// 需要验证工号和姓名是否与“人员字典”(per_employee)完全匹配,不匹配则返回表格错误提示
// 表格错误提醒参考PersonService.CreatePerson方法
return new ApiResponse(ResponseType.OK, _attendanceService.AttendanceBatch(allotId, hospitalId, request));
}
#endregion
/// <summary>
/// 考勤结果统计
/// </summary>
/// <param name="allotId"></param>
/// <returns></returns>
[HttpGet("statistics/{allotId}")]
public ApiResponse<List<AttendanceStatistics>> GetAttendanceStatistics(int allotId)
{
// 返回结果参考接口 employee/apr/getdeptdetail
return _attendanceService.GetAttendanceStatistics(allotId);
}
}
}
...@@ -51,6 +51,9 @@ ...@@ -51,6 +51,9 @@
<Content Update="wwwroot\Performance.DtoModels.xml"> <Content Update="wwwroot\Performance.DtoModels.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
<Content Update="wwwroot\Performance.DtoModels.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\Performance.EntityModels.xml"> <Content Update="wwwroot\Performance.EntityModels.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
...@@ -89,6 +92,10 @@ ...@@ -89,6 +92,10 @@
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>
<ProjectExtensions> <ProjectExtensions>
<VisualStudio> <VisualStudio>
<UserProperties appsettings_1json__JSONSchema="" /> <UserProperties appsettings_1json__JSONSchema="" />
......
...@@ -312,6 +312,89 @@ ...@@ -312,6 +312,89 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:Performance.Api.Controllers.AttendanceController.GetAttendance(System.Int32)">
<summary>
查询绩效考勤记录
</summary>
<param name="allotId"></param>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.AttendanceController.GetCallIn(System.Int32)">
<summary>
查询绩效调动记录
</summary>
<param name="allotId"></param>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.AttendanceController.GetBatchCallInHandsonTable">
<summary>
返回HandsonTable格式调动记录
</summary>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.AttendanceController.BatchCallIn(System.Int32,System.Int32,Performance.DtoModels.SaveCollectData)">
<summary>
批量插入调动记录
</summary>
<param name="allotId"></param>
<param name="hospitalId"></param>
<param name="request"></param>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.AttendanceController.GetAttendanceType(System.Int32,System.Int32)">
<summary>
查询绩效考勤类型
</summary>
<param name="allotId"></param>
<param name="hospitalId"></param>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.AttendanceController.InsertAttendanceType(System.Int32,System.Int32,Performance.EntityModels.Other.AttendanceType)">
<summary>
新增或修改考勤类型
</summary>
<param name="allotId"></param>
<param name="hospitalId"></param>
<param name="attendanceType"></param>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.AttendanceController.DeleteAttendanceType(System.Int32)">
<summary>
删除考勤类型
</summary>
<param name="id"></param>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.AttendanceController.GetAttendanceVacationHandsonTable">
<summary>
返回HandsonTable格式考勤记录
</summary>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.AttendanceController.GetAttendanceVacation(System.Int32,System.Int32)">
<summary>
查询考勤记录
</summary>
<param name="allotId"></param>
<param name="hospitalId"></param>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.AttendanceController.AttendanceBatch(System.Int32,System.Int32,Performance.DtoModels.SaveCollectData)">
<summary>
批量插入考勤记录,插入前需要删除所有后重新插入
</summary>
<param name="allotId"></param>
<param name="hospitalId"></param>
<param name="request"></param>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.AttendanceController.GetAttendanceStatistics(System.Int32)">
<summary>
考勤结果统计
</summary>
<param name="allotId"></param>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.BudgetController.Query(Performance.DtoModels.Request.BudgetRequest)"> <member name="M:Performance.Api.Controllers.BudgetController.Query(Performance.DtoModels.Request.BudgetRequest)">
<summary> <summary>
预算管理查询(包含金额、占比) 预算管理查询(包含金额、占比)
......
...@@ -202,7 +202,7 @@ ...@@ -202,7 +202,7 @@
<member name="F:Performance.DtoModels.DataFormat.分数"> <member name="F:Performance.DtoModels.DataFormat.分数">
<summary> 分数 </summary> <summary> 分数 </summary>
</member> </member>
<member name="F:Performance.DtoModels.DataFormat.日期"> <member name="F:Performance.DtoModels.DataFormat.日期YYYYMMDD">
<summary> 日期 </summary> <summary> 日期 </summary>
</member> </member>
<member name="M:Performance.DtoModels.HandsonTable.SetRowData(System.Collections.Generic.IEnumerable{Performance.DtoModels.HandsonRowData},System.Boolean)"> <member name="M:Performance.DtoModels.HandsonTable.SetRowData(System.Collections.Generic.IEnumerable{Performance.DtoModels.HandsonRowData},System.Boolean)">
...@@ -2703,6 +2703,56 @@ ...@@ -2703,6 +2703,56 @@
科室 科室
</summary> </summary>
</member> </member>
<member name="P:Performance.DtoModels.AttendanceStatistics.UnitType">
<summary>
核算组别
</summary>
</member>
<member name="P:Performance.DtoModels.AttendanceStatistics.AccountingUnit">
<summary>
核算单元
</summary>
</member>
<member name="P:Performance.DtoModels.AttendanceStatistics.Department">
<summary>
科室名称
</summary>
</member>
<member name="P:Performance.DtoModels.AttendanceStatistics.PersonnelNumber">
<summary>
工号
</summary>
</member>
<member name="P:Performance.DtoModels.AttendanceStatistics.PersonnelName">
<summary>
姓名
</summary>
</member>
<member name="P:Performance.DtoModels.AttendanceStatistics.BeginDate">
<summary>
在科开始时间
</summary>
</member>
<member name="P:Performance.DtoModels.AttendanceStatistics.EndDate">
<summary>
在科结束时间
</summary>
</member>
<member name="P:Performance.DtoModels.AttendanceStatisticsDetial.Value">
<summary>
请假天数
</summary>
</member>
<member name="P:Performance.DtoModels.AttendanceStatisticsDetial.Title">
<summary>
考勤类型
</summary>
</member>
<member name="P:Performance.DtoModels.AttendanceStatisticsDetial.Remark">
<summary>
备注
</summary>
</member>
<member name="P:Performance.DtoModels.BudgetRatioResponse.HospitalId"> <member name="P:Performance.DtoModels.BudgetRatioResponse.HospitalId">
<summary> <summary>
医院Id 医院Id
......
...@@ -6120,6 +6120,11 @@ ...@@ -6120,6 +6120,11 @@
验证失败描述 验证失败描述
</summary> </summary>
</member> </member>
<member name="P:Performance.EntityModels.Entity.per_attendance_type.IsDeduction">
<summary>
是否核减出勤 1 核减 2 不核减
</summary>
</member>
<member name="T:Performance.EntityModels.per_batch"> <member name="T:Performance.EntityModels.per_batch">
<summary> <summary>
分批发放记录 分批发放记录
...@@ -8845,6 +8850,41 @@ ...@@ -8845,6 +8850,41 @@
</summary> </summary>
</member> </member>
<member name="P:Performance.EntityModels.Other.view_attendance.UnitType">
<summary>
人员类别
</summary>
</member>
<member name="P:Performance.EntityModels.Other.view_attendance.AccountingUnit">
<summary>
核算单元
</summary>
</member>
<member name="P:Performance.EntityModels.Other.view_attendance.PersonnelNumber">
<summary>
工号
</summary>
</member>
<member name="P:Performance.EntityModels.Other.view_attendance.PersonnelName">
<summary>
姓名
</summary>
</member>
<member name="P:Performance.EntityModels.Other.view_attendance.AttendanceDate">
<summary>
考勤时间
</summary>
</member>
<member name="P:Performance.EntityModels.Other.view_attendance.Source">
<summary>
来源
</summary>
</member>
<member name="P:Performance.EntityModels.Other.view_attendance.Department">
<summary>
科室名称
</summary>
</member>
<member name="P:Performance.EntityModels.HisData.HisDepartment"> <member name="P:Performance.EntityModels.HisData.HisDepartment">
<summary> <summary>
His科室 His科室
......
...@@ -116,7 +116,7 @@ public enum DataFormat ...@@ -116,7 +116,7 @@ public enum DataFormat
/// <summary> 分数 </summary> /// <summary> 分数 </summary>
分数, 分数,
/// <summary> 日期 </summary> /// <summary> 日期 </summary>
日期 日期YYYYMMDD
} }
public enum Role public enum Role
...@@ -155,4 +155,19 @@ public enum Status ...@@ -155,4 +155,19 @@ public enum Status
超时 = 99, 超时 = 99,
} }
} }
public class Attendance
{
public enum Type
{
开始,
调入,
结束,
}
public enum Deduction
{
核减 = 1,
不核减 = 2,
}
}
} }
...@@ -127,6 +127,11 @@ public HandsonColumn(string data, bool readOnly = false, DataFormat format = Dat ...@@ -127,6 +127,11 @@ public HandsonColumn(string data, bool readOnly = false, DataFormat format = Dat
Type = "text"; Type = "text";
break; break;
case DataFormat.日期YYYYMMDD:
Type = "DateFormat";
DateFormat = "YYYY/MM/DD";
break;
case DataFormat.小数: case DataFormat.小数:
Type = "numeric"; Type = "numeric";
NumericFormat = new NumericFormat { Pattern = "0,00.00" }; NumericFormat = new NumericFormat { Pattern = "0,00.00" };
...@@ -152,6 +157,7 @@ public HandsonColumn(string data, bool readOnly = false, DataFormat format = Dat ...@@ -152,6 +157,7 @@ public HandsonColumn(string data, bool readOnly = false, DataFormat format = Dat
public string Data { get; set; } public string Data { get; set; }
public bool ReadOnly { get; set; } public bool ReadOnly { get; set; }
public string Type { get; set; } public string Type { get; set; }
public string DateFormat { get; set; }
public string[] Source { get; set; } public string[] Source { get; set; }
public bool Strict { get; set; } = false; public bool Strict { get; set; } = false;
......
using System;
using System.Collections.Generic;
namespace Performance.DtoModels
{
public class AttendanceStatistics
{
public int AllotID { get; set; }
/// <summary>
/// 核算组别
/// </summary>
public string UnitType { get; set; }
/// <summary>
/// 核算单元
/// </summary>
public string AccountingUnit { get; set; }
/// <summary>
/// 科室名称
/// </summary>
public string Department { get; set; }
/// <summary>
/// 工号
/// </summary>
public string PersonnelNumber { get; set; }
/// <summary>
/// 姓名
/// </summary>
public string PersonnelName { get; set; }
/// <summary>
/// 在科开始时间
/// </summary>
public DateTime BeginDate { get; set; }
/// <summary>
/// 在科结束时间
/// </summary>
public DateTime EndDate { get; set; }
public List<AttendanceStatisticsDetial> Detial { get; set; }
public int AttendanceDays { get; set; }
}
public class AttendanceStatisticsDetial
{
/// <summary>
/// 请假天数
/// </summary>
public int Value { get; set; }
/// <summary>
/// 考勤类型
/// </summary>
public string Title { get; set; }
/// <summary>
/// 备注
/// </summary>
public string Remark { get; set; }
}
}
using System; using System;
using System.Collections.Generic;
using System.Text; using System.Text;
namespace Performance.DtoModels namespace Performance.DtoModels
......
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Performance.EntityModels.Entity;
using System; using System;
namespace Performance.EntityModels namespace Performance.EntityModels
...@@ -245,5 +246,8 @@ public PerformanceDbContext(DbContextOptions<PerformanceDbContext> options) ...@@ -245,5 +246,8 @@ public PerformanceDbContext(DbContextOptions<PerformanceDbContext> options)
/// <summary> 用户角色关联表 </summary> /// <summary> 用户角色关联表 </summary>
public virtual DbSet<sys_user_role> sys_user_role { get; set; } public virtual DbSet<sys_user_role> sys_user_role { get; set; }
public virtual DbSet<sys_version> sys_version { get; set; } public virtual DbSet<sys_version> sys_version { get; set; }
public virtual DbSet<per_attendance> per_attendance { get; set; }
public virtual DbSet<per_attendance_type> per_attendance_type { get; set; }
public virtual DbSet<per_attendance_vacation> per_attendance_vacation { get; set; }
} }
} }
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Performance.EntityModels.Entity
{
[Table("per_attendance")]
public class per_attendance
{
[Key]
public int Id { get; set; }
public int HospitalId { get; set; } //医院Id
public int AllotId { get; set; } //绩效Id
public string PersonnelNumber { get; set; } //工号
public string PersonnelName { get; set; } //姓名
public string CallInUnitType { get; set; } //人员类别
public string CallInAccountingUnit { get; set; } //核算单元
public Nullable<DateTime> CallInDate { get; set; } //调入时间
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Performance.EntityModels.Entity
{
[Table("per_attendance_type")]
public class per_attendance_type
{
[Key]
public int Id { get; set; }
public int HospitalId { get; set; } //医院Id
public int AllotId { get; set; } //绩效Id
public string AttendanceName { get; set; } //考勤类型名称
/// <summary>
/// 是否核减出勤 1 核减 2 不核减
/// </summary>
public int IsDeduction { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Performance.EntityModels.Entity
{
[Table("per_attendance_vacation")]
public class per_attendance_vacation
{
[Key]
public int Id { get; set; }
public int HospitalId { get; set; } //医院Id
public int AllotId { get; set; } //绩效Id
public string PersonnelNumber { get; set; } //工号
public string PersonnelName { get; set; } //姓名
public int TypeId { get; set; } //per_attendance_type表中ID
public Nullable<DateTime> BegDate { get; set; } //开始时间
public Nullable<DateTime> EndDate { get; set; } //结束时间
}
}
using Performance.EntityModels.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Performance.EntityModels.Other
{
public class view_attendance
{
public int ALLOTID { get; set; }
public int YEAR { get; set; }
public int MONTH { get; set; }
/// <summary>
/// 人员类别
/// </summary>
public string UnitType { get; set; }
/// <summary>
/// 核算单元
/// </summary>
public string AccountingUnit { get; set; }
/// <summary>
/// 工号
/// </summary>
public string PersonnelNumber { get; set; }
/// <summary>
/// 姓名
/// </summary>
public string PersonnelName { get; set; }
/// <summary>
/// 考勤时间
/// </summary>
public Nullable<DateTime> AttendanceDate { get; set; }
/// <summary>
/// 来源
/// </summary>
public string Source { get; set; }
/// <summary>
/// 科室名称
/// </summary>
public string Department { get; set; }
}
public class InitialAttendance
{
public string UnitType { get; set; } //人员类别
public string AccountingUnit { get; set; } //核算单元
public string PersonnelNumber { get; set; } //工号
public string PersonnelName { get; set; } //姓名
public Nullable<DateTime> StartDate { get; set; } //入科开始时间
public Nullable<DateTime> EndDate { get; set; } //入科结束时间
public string Department { get; set; } //科室名称
}
public class InitialAttendanceJoin : InitialAttendance
{
public string AttendanceName { get; set; } //考勤类型名称
public int IsDeduction { get; set; } //是否核减出勤 1 核减 2 不核减
public Nullable<DateTime> BegDate { get; set; } //开始时间
public Nullable<DateTime> bEndDate { get; set; } //结束时间
}
public class RecordAttendcance : per_attendance_vacation
{
public int Days { get; set; }
public string AttendanceName { get; set; }
}
public class AttendaceHeads
{
public string Column { get; set; }
public string Name { get; set; }
}
public class AttendanceType
{
public string AttendanceName { get; set; } //考勤类型名称
public string IsDeduction { get; set; } //是否核减出勤 1 核减 2 不核减
}
}
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
using Dapper; using Dapper;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Performance.EntityModels; using Performance.EntityModels;
using Performance.EntityModels.Other;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
...@@ -278,5 +279,23 @@ public IEnumerable<string> GetSecondWorkloadMaps(int hospitalId) ...@@ -278,5 +279,23 @@ public IEnumerable<string> GetSecondWorkloadMaps(int hospitalId)
} }
} }
} }
public IEnumerable<view_attendance> GetAttendance(int allotId)
{
using (var connection = context.Database.GetDbConnection())
{
if (connection.State != ConnectionState.Open) connection.Open();
try
{
string query = $@"SELECT * FROM view_attendance where allotId = @allotId";
return connection.Query<view_attendance>(query, new { allotId }, commandTimeout: 60 * 60);
}
catch (Exception)
{
throw;
}
}
}
} }
} }
\ No newline at end of file
using Performance.EntityModels;
using Performance.EntityModels.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Performance.Repository.Repository
{
public partial class PerfoPperAttendanceTypeRepository : PerforRepository<per_attendance_type>
{
/// <summary>
/// per_attendance_type Repository
/// </summary>
public PerfoPperAttendanceTypeRepository(PerformanceDbContext context) : base(context)
{
}
}
}
using Performance.EntityModels;
using Performance.EntityModels.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Performance.Repository.Repository
{
public partial class PerfoPperAttendanceVacationeRepository : PerforRepository<per_attendance_vacation>
{
/// <summary>
/// per_attendance_vacation Repository
/// </summary>
public PerfoPperAttendanceVacationeRepository(PerformanceDbContext context) : base(context)
{
}
}
}
using Performance.EntityModels;
using Performance.EntityModels.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Performance.Repository.Repository
{
public partial class PerforPerAttendanceRepository : PerforRepository<per_attendance>
{
/// <summary>
/// per_attendance Repository
/// </summary>
public PerforPerAttendanceRepository(PerformanceDbContext context) : base(context)
{
}
}
}
using AutoMapper;
using Microsoft.Extensions.Logging;
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.EntityModels.Entity;
using Performance.EntityModels.Other;
using Performance.Infrastructure;
using Performance.Repository;
using Performance.Repository.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Performance.Services
{
public class AttendanceService : IAutoInjection
{
private readonly IMapper mapper;
private readonly ILogger<AttendanceService> logger;
private readonly PerforPerallotRepository perforPerallotRepository;
private readonly PerforPerAttendanceRepository perforPerAttendanceRepository;
private readonly PerfoPperAttendanceTypeRepository perfoPperAttendanceTypeRepository;
private readonly PerfoPperAttendanceVacationeRepository perfoPperAttendanceVacationeRepository;
private readonly PerforPerdeptdicRepository perdeptdicRepository;
private readonly PerforPeremployeeRepository perforPeremployeeRepository;
public AttendanceService(
IMapper mapper,
ILogger<AttendanceService> logger,
PerforPerallotRepository perforPerallotRepository,
PerforPerAttendanceRepository perforPerAttendanceRepository,
PerfoPperAttendanceTypeRepository perfoPperAttendanceTypeRepository,
PerfoPperAttendanceVacationeRepository perfoPperAttendanceVacationeRepository,
PerforPerdeptdicRepository perdeptdicRepository,
PerforPeremployeeRepository perforPeremployeeRepository)
{
this.mapper = mapper;
this.logger = logger;
this.perforPerallotRepository = perforPerallotRepository;
this.perforPerAttendanceRepository = perforPerAttendanceRepository;
this.perfoPperAttendanceTypeRepository = perfoPperAttendanceTypeRepository;
this.perfoPperAttendanceVacationeRepository = perfoPperAttendanceVacationeRepository;
this.perdeptdicRepository = perdeptdicRepository;
this.perforPeremployeeRepository = perforPeremployeeRepository;
}
#region 初始考勤页面
public ApiResponse<List<AttendanceStatistics>> GetAttendance(int allotId)
{
var allot = perforPerallotRepository.GetEntity(w => w.ID == allotId);
if (allot == null)
throw new PerformanceException("当前绩效记录不存在");
var attendanceData = perforPerallotRepository.GetAttendance(allotId);
List<AttendanceStatistics> statistics = new List<AttendanceStatistics>();
// 交叉补全科室结束时间
foreach (var personnelNumber in attendanceData.Select(w => w.PersonnelNumber).Distinct())
{
var attendances = attendanceData.Where(w => w.PersonnelNumber == personnelNumber).OrderBy(w => w.AttendanceDate);
for (int i = 0; i < attendances.Count() - 1; i++)
{
var begDate = attendances.ElementAt(i).AttendanceDate.Value.Date;
var endDate = attendances.ElementAt(i + 1).AttendanceDate.Value.Date;
// 调入科室需要额外减去1天作为上一个科室结束时间
var days = attendances.ElementAt(i + 1).Source == Attendance.Type.调入.ToString() ? -1 : 0;
if (endDate > begDate)
{
var stat = new AttendanceStatistics
{
AllotID = attendances.ElementAt(i).ALLOTID,
UnitType = attendances.ElementAt(i).UnitType,
AccountingUnit = attendances.ElementAt(i).AccountingUnit,
Department = attendances.ElementAt(i).Department,
PersonnelNumber = attendances.ElementAt(i).PersonnelNumber,
PersonnelName = attendances.ElementAt(i).PersonnelName,
BeginDate = begDate,
EndDate = endDate.AddDays(days),
Detial = new List<AttendanceStatisticsDetial>()
};
statistics.Add(stat);
}
}
}
if (statistics != null)
return new ApiResponse<List<AttendanceStatistics>>(ResponseType.OK, statistics);
else
{
return new ApiResponse<List<AttendanceStatistics>>(ResponseType.Fail);
}
}
#endregion
#region 调入记录
public ApiResponse<List<view_attendance>> GetCallIn(int allotId)
{
var view_attendance = perforPerallotRepository.GetAttendance(allotId).Where(t => t.Source.Contains("调入")).ToList();
if (view_attendance != null)
return new ApiResponse<List<view_attendance>>(ResponseType.OK, view_attendance);
else
{
return new ApiResponse<List<view_attendance>>(ResponseType.Fail);
}
}
public HandsonTable GetBatchCallInHandsonTable()
{
HandsonTable handson = new HandsonTable((int)SheetType.Unidentifiable, Person.Select(c => c.Item2).ToArray(), Person.Select(t => new collect_permission
{
HeadName = t.Item2,
Visible = 1,
Readnoly = 0
}).ToList());
if (handson.Columns != null && handson.Columns.Any())
{
foreach (var column in handson.Columns)
{
column.Type = "text";
if (column.Data == "调入组别")
{
column.Source = EnumHelper.GetItems<UnitType>().Select(w => w.Description.Replace("行政后勤", "行政工勤")).ToArray();
column.Strict = true;
}
if (column.Data == "调入核算单元")
{
column.Source = EnumHelper.GetItems<AccountUnitType>().Where(w => w.Description != "").Select(w => w.Description).ToArray();
column.Strict = true;
}
}
}
return handson;
}
public ApiResponse BatchCallIn(int allotId, int hospitalId, SaveCollectData request)
{
var dict = new Dictionary<string, string>();
Person.ForEach(t => dict.Add(t.Item1, t.Item2));
var dicData = CreateDataRow(request, dict);
if (dicData == null || dicData.Count == 0)
return new ApiResponse(ResponseType.Error, "空数据,无效操作");
var jsons = JsonHelper.Serialize(dicData);
var newAttendanceVacatione = JsonHelper.Deserialize<List<per_attendance>>(jsons);
var oldCallinAttendance = perforPerAttendanceRepository.GetEntities(t => t.AllotId == allotId && t.HospitalId == hospitalId);
var per_allot = perforPerallotRepository.GetEntities(t => t.ID == allotId && t.HospitalId == hospitalId).FirstOrDefault();
if (per_allot == null) return new ApiResponse(ResponseType.Error, "无绩效数据");
var per_dept_dic = perdeptdicRepository.GetEntities(t => t.HospitalId == hospitalId);
var per_employee = perforPeremployeeRepository.GetEntities(t => t.AllotId == allotId && t.HospitalId == hospitalId);
List<Dictionary<string, string>> error = new List<Dictionary<string, string>>();
for (int i = 0; i < newAttendanceVacatione.Count; i++)
{
if (string.IsNullOrEmpty(newAttendanceVacatione[i].PersonnelName?.Trim())
|| string.IsNullOrEmpty(newAttendanceVacatione[i].PersonnelNumber?.Trim())
|| string.IsNullOrEmpty(newAttendanceVacatione[i].CallInAccountingUnit?.Trim())
|| string.IsNullOrEmpty(newAttendanceVacatione[i].CallInUnitType?.Trim())
|| newAttendanceVacatione[i].CallInDate == null)
{
error.Add(new Dictionary<string, string>
{
{ "行号", $"第{i+1}行" },
{ "人员工号", newAttendanceVacatione[i].PersonnelNumber??"" },
{ "人员姓名", newAttendanceVacatione[i].PersonnelName??"" },
{ "调入核算单元", newAttendanceVacatione[i].CallInAccountingUnit??"" },
{ "调入组别", newAttendanceVacatione[i].CallInUnitType??"" },
{ "调入时间", newAttendanceVacatione[i].CallInDate.ToString()??"" },
{ "来源", "粘贴数据" },
{ "错误原因", "“关键信息缺失”请补全或删除" },
});
}
DateTime dt = new DateTime(per_allot.Year, per_allot.Month, 1).AddMonths(1);
if (newAttendanceVacatione[i].CallInDate > dt)
{
error.Add(new Dictionary<string, string>
{
{ "行号", $"第{i+1}行" },
{ "人员工号", newAttendanceVacatione[i].PersonnelNumber??"" },
{ "人员姓名", newAttendanceVacatione[i].PersonnelName??"" },
{ "调入核算单元", newAttendanceVacatione[i].CallInAccountingUnit??"" },
{ "调入组别", newAttendanceVacatione[i].CallInUnitType??"" },
{ "调入时间", newAttendanceVacatione[i].CallInDate.ToString()??"" },
{ "来源", "粘贴数据" },
{ "错误原因", "调入时间不在当前绩效月份范围内" },
});
}
if (newAttendanceVacatione[i].CallInUnitType != per_dept_dic.FirstOrDefault(t => t.AccountingUnit == newAttendanceVacatione[i].CallInAccountingUnit)?.UnitType)
{
error.Add(new Dictionary<string, string>
{
{ "行号", $"第{i+1}行" },
{ "人员工号", newAttendanceVacatione[i].PersonnelNumber??"" },
{ "人员姓名", newAttendanceVacatione[i].PersonnelName??"" },
{ "调入核算单元", newAttendanceVacatione[i].CallInAccountingUnit??"" },
{ "调入组别", newAttendanceVacatione[i].CallInUnitType??"" },
{ "调入时间", newAttendanceVacatione[i].CallInDate.ToString()??"" },
{ "来源", "粘贴数据" },
{ "错误原因", "该核算单元的调入组别不一致或不存在" },
});
}
if (newAttendanceVacatione[i].PersonnelName != per_employee.FirstOrDefault(t => t.PersonnelNumber == newAttendanceVacatione[i].PersonnelNumber && t.AllotId == allotId && t.HospitalId == hospitalId)?.DoctorName)
{
error.Add(new Dictionary<string, string>
{
{ "行号", $"第{i+1}行" },
{ "人员工号", newAttendanceVacatione[i].PersonnelNumber??"" },
{ "人员姓名", newAttendanceVacatione[i].PersonnelName??"" },
{ "调入核算单元", newAttendanceVacatione[i].CallInAccountingUnit??"" },
{ "调入组别", newAttendanceVacatione[i].CallInUnitType??"" },
{ "调入时间", newAttendanceVacatione[i].CallInDate.ToString()??"" },
{ "来源", "粘贴数据" },
{ "错误原因", "该人员与人员字典不一致或不存在" },
});
}
var oldEmp = oldCallinAttendance.FirstOrDefault(w => w.PersonnelNumber == newAttendanceVacatione[i].PersonnelNumber);
if (!string.IsNullOrEmpty(newAttendanceVacatione[i].PersonnelName) && oldEmp != null && oldEmp.PersonnelName != newAttendanceVacatione[i].PersonnelName)
{
error.Add(new Dictionary<string, string>
{
{ "行号", $"第{i+1}行" },
{ "人员工号", newAttendanceVacatione[i].PersonnelNumber??"" },
{ "人员姓名", newAttendanceVacatione[i].PersonnelName??"" },
{ "调入核算单元", newAttendanceVacatione[i].CallInAccountingUnit??"" },
{ "调入组别", newAttendanceVacatione[i].CallInUnitType??"" },
{ "调入时间", newAttendanceVacatione[i].CallInDate.ToString()??"" },
{ "来源", "“粘贴数据”与“历史数据”比对" },
{ "错误原因", $"原名“{oldEmp.PersonnelName}”,工号相同但姓名不同,请删除“历史数据”中该员工" },
});
}
}
if (error.Count > 0)
return new ApiResponse(ResponseType.WarningTable, "验证不通过,当前操作已拒绝", error);
List<per_attendance> addPer_Attendances = new List<per_attendance>();
List<per_attendance> deletePer_Attendances = new List<per_attendance>();
foreach (var data in newAttendanceVacatione)
{
data.AllotId = allotId;
data.HospitalId = hospitalId;
addPer_Attendances.Add(data);
var any = oldCallinAttendance.FirstOrDefault(w => w.AllotId == allotId && w.HospitalId == hospitalId && w.CallInDate == data.CallInDate && w.CallInAccountingUnit?.Trim() == data.CallInAccountingUnit?.Trim() && w.CallInUnitType?.Trim() == data.CallInUnitType?.Trim() && w.PersonnelName?.Trim() == data.PersonnelName?.Trim() && w.PersonnelNumber?.Trim() == data.PersonnelNumber?.Trim());
if (any != null) deletePer_Attendances.Add(any);
}
if (deletePer_Attendances != null && deletePer_Attendances.Any())
perforPerAttendanceRepository.RemoveRange(deletePer_Attendances.ToArray());
if (addPer_Attendances != null && addPer_Attendances.Any())
perforPerAttendanceRepository.AddRange(addPer_Attendances.ToArray());
return new ApiResponse(ResponseType.OK, "");
}
#endregion
#region 考勤类型
public ApiResponse<List<per_attendance_type>> GetAttendanceType(int allotId, int hospitalId)
{
var result = perfoPperAttendanceTypeRepository.GetEntities(t => t.AllotId == allotId && t.HospitalId == hospitalId).ToList();
if(result != null)
return new ApiResponse<List<per_attendance_type>>(ResponseType.OK, result);
else
{
return new ApiResponse<List<per_attendance_type>>(ResponseType.Fail);
}
}
public ApiResponse<AttendanceType> InsertAttendanceType(int allotId, int hospitalId, AttendanceType attendanceType)
{
var any = perfoPperAttendanceTypeRepository.GetEntities().FirstOrDefault(t => t.AllotId == allotId && t.HospitalId == hospitalId && t.AttendanceName == attendanceType.AttendanceName);
if (any != null)
{
any.IsDeduction = Convert.ToInt32(attendanceType.IsDeduction);
if (perfoPperAttendanceTypeRepository.Update(any)) return new ApiResponse<AttendanceType>(ResponseType.OK, "修改成功");
else return new ApiResponse<AttendanceType>(ResponseType.Fail, "修改失败");
}
else
{
per_attendance_type per_Attendance_Type = new per_attendance_type()
{
AllotId = allotId,
HospitalId = hospitalId,
AttendanceName = attendanceType.AttendanceName,
IsDeduction = Convert.ToInt32(attendanceType.IsDeduction)
};
if (perfoPperAttendanceTypeRepository.Add(per_Attendance_Type)) return new ApiResponse<AttendanceType>(ResponseType.OK, "添加成功");
else return new ApiResponse<AttendanceType>(ResponseType.Fail, "添加失败");
}
}
public ApiResponse DeleteAttendanceType(int id)
{
var any = perfoPperAttendanceTypeRepository.GetEntities().FirstOrDefault(t => t.Id == id);
var use = perfoPperAttendanceVacationeRepository.GetEntities().FirstOrDefault(t => t.TypeId == any.Id);
if (any != null && use == null)
{
if (perfoPperAttendanceTypeRepository.DeleteFromQuery(t => t.Id == id) > 0) return new ApiResponse(ResponseType.OK, "删除成功");
else return new ApiResponse(ResponseType.Fail, "删除失败");
}
else return new ApiResponse(ResponseType.Fail, "删除失败");
}
#endregion
#region 考勤记录
public HandsonTable GetAttendanceVacationHandsonTable()
{
HandsonTable handson = new HandsonTable((int)SheetType.Unidentifiable, Vacation.Select(c => c.Item2).ToArray(), Vacation.Select(t => new collect_permission
{
HeadName = t.Item2,
Visible = 1,
Readnoly = 0
}).ToList());
if (handson.Columns != null && handson.Columns.Any())
{
foreach (var column in handson.Columns)
{
column.Type = "text";
if (column.Data.Contains("时间"))
{
column.Type = "DateFormat";
column.DateFormat = "YYYY/MM/DD";
}
if (column.Data == "考勤类型")
{
column.Source = perfoPperAttendanceTypeRepository.GetEntities().Select(t => t.AttendanceName).ToArray();
}
}
}
return handson;
}
public ApiResponse<List<RecordAttendcance>> GetAttendanceVacation(int allotId, int hospitalId)
{
var vacatione = perfoPperAttendanceVacationeRepository.GetEntities(t => t.AllotId == allotId && t.HospitalId == hospitalId);
var type = perfoPperAttendanceTypeRepository.GetEntities(t => t.AllotId == allotId && t.HospitalId == hospitalId);
var data = from a in vacatione
join b in type on a.TypeId equals b.Id into temp
from tt in temp.DefaultIfEmpty()
select new RecordAttendcance
{
Id = a.Id,
AllotId = a.AllotId,
HospitalId = a.HospitalId,
PersonnelName = a.PersonnelName,
PersonnelNumber = a.PersonnelNumber,
AttendanceName = tt.AttendanceName,
TypeId = a.TypeId,
BegDate = a.BegDate,
EndDate = a.EndDate,
Days = Convert.ToInt32(new TimeSpan(Convert.ToDateTime(a.BegDate).Ticks).Subtract(new TimeSpan(Convert.ToDateTime(a.EndDate).Ticks)).Duration().Days) + 1
};
if (data != null)
return new ApiResponse<List<RecordAttendcance>>(ResponseType.OK, data.ToList());
else
{
return new ApiResponse<List<RecordAttendcance>>(ResponseType.Fail);
}
}
public ApiResponse AttendanceBatch(int allotId, int hospitalId, SaveCollectData request)
{
var dict = new Dictionary<string, string>();
Vacation.ForEach(t => dict.Add(t.Item1, t.Item2));
var dicData = CreateDataRow(request, dict);
if (dicData == null || dicData.Count == 0)
return new ApiResponse(ResponseType.Error, "空数据,无效操作");
var jsons = JsonHelper.Serialize(dicData);
var newAttendanceVacatione = JsonHelper.Deserialize<List<RecordAttendcance>>(jsons);
var oldAttendanceVacatione = perfoPperAttendanceVacationeRepository.GetEntities(t => t.AllotId == allotId && t.HospitalId == hospitalId);
var attendanceType = perfoPperAttendanceTypeRepository.GetEntities();
var per_employee = perforPeremployeeRepository.GetEntities(t => t.AllotId == allotId && t.HospitalId == hospitalId);
List<Dictionary<string, string>> error = new List<Dictionary<string, string>>();
var per_allot = perforPerallotRepository.GetEntities(t => t.ID == allotId && t.HospitalId == hospitalId).FirstOrDefault();
for (int i = 0; i < newAttendanceVacatione.Count; i++)
{
if (string.IsNullOrEmpty(newAttendanceVacatione[i].PersonnelName?.Trim())
|| string.IsNullOrEmpty(newAttendanceVacatione[i].PersonnelNumber?.Trim())
|| string.IsNullOrEmpty(newAttendanceVacatione[i].AttendanceName?.Trim())
|| newAttendanceVacatione[i].BegDate == null
|| newAttendanceVacatione[i].EndDate == null)
{
error.Add(new Dictionary<string, string>
{
{ "行号", $"第{i+1}行" },
{ "人员工号", newAttendanceVacatione[i].PersonnelNumber??"" },
{ "人员姓名", newAttendanceVacatione[i].PersonnelName??"" },
{ "考勤类型", newAttendanceVacatione[i].AttendanceName??"" },
{ "开始日期", newAttendanceVacatione[i].BegDate.ToString()??"" },
{ "结束日期", newAttendanceVacatione[i].EndDate.ToString()??"" },
{ "来源", "粘贴数据" },
{ "错误原因", "“关键信息缺失”请补全或删除" },
});
}
var typeAny = attendanceType.Where(t => t.AttendanceName.Contains(newAttendanceVacatione[i].AttendanceName));
if (typeAny == null || !typeAny.Any())
{
error.Add(new Dictionary<string, string>
{
{ "行号", $"第{i+1}行" },
{ "人员工号", newAttendanceVacatione[i].PersonnelNumber??"" },
{ "人员姓名", newAttendanceVacatione[i].PersonnelName??"" },
{ "考勤类型", newAttendanceVacatione[i].AttendanceName??"" },
{ "开始日期", newAttendanceVacatione[i].BegDate.ToString()??"" },
{ "结束日期", newAttendanceVacatione[i].EndDate.ToString()??"" },
{ "来源", "粘贴数据" },
{ "错误原因", "没有该考勤类型" },
});
}
if (newAttendanceVacatione[i].PersonnelName != per_employee.FirstOrDefault(t => t.PersonnelNumber == newAttendanceVacatione[i].PersonnelNumber && t.AllotId == allotId && t.HospitalId == hospitalId)?.DoctorName)
{
error.Add(new Dictionary<string, string>
{
{ "行号", $"第{i+1}行" },
{ "人员工号", newAttendanceVacatione[i].PersonnelNumber??"" },
{ "人员姓名", newAttendanceVacatione[i].PersonnelName??"" },
{ "考勤类型", newAttendanceVacatione[i].AttendanceName??"" },
{ "开始日期", newAttendanceVacatione[i].BegDate.ToString()??"" },
{ "结束日期", newAttendanceVacatione[i].EndDate.ToString()??"" },
{ "来源", "粘贴数据" },
{ "错误原因", "该人员与人员字典不一致或不存在" },
});
}
var oldEmp = oldAttendanceVacatione.FirstOrDefault(w => w.PersonnelNumber == newAttendanceVacatione[i].PersonnelNumber);
if (!string.IsNullOrEmpty(newAttendanceVacatione[i].PersonnelName) && oldEmp != null && oldEmp.PersonnelName != newAttendanceVacatione[i].PersonnelName)
{
error.Add(new Dictionary<string, string>
{
{ "行号", $"第{i+1}行" },
{ "人员工号", newAttendanceVacatione[i].PersonnelNumber??"" },
{ "人员姓名", newAttendanceVacatione[i].PersonnelName??"" },
{ "考勤类型", newAttendanceVacatione[i].AttendanceName??"" },
{ "开始日期", newAttendanceVacatione[i].BegDate.ToString()??"" },
{ "结束日期", newAttendanceVacatione[i].EndDate.ToString()??"" },
{ "来源", "“粘贴数据”与“历史数据”比对" },
{ "错误原因", $"原名“{oldEmp.PersonnelName}”,工号相同但姓名不同,请删除“历史数据”中该员工" },
});
}
DateTime dt = new DateTime(per_allot.Year, per_allot.Month, 1);
if (newAttendanceVacatione[i].BegDate >= dt && newAttendanceVacatione[i].EndDate > dt.AddMonths(1))
{
error.Add(new Dictionary<string, string>
{
{ "行号", $"第{i+1}行" },
{ "人员工号", newAttendanceVacatione[i].PersonnelNumber??"" },
{ "人员姓名", newAttendanceVacatione[i].PersonnelName??"" },
{ "考勤类型", newAttendanceVacatione[i].AttendanceName??"" },
{ "开始日期", newAttendanceVacatione[i].BegDate.ToString()??"" },
{ "结束日期", newAttendanceVacatione[i].EndDate.ToString()??"" },
{ "来源", "粘贴数据" },
{ "错误原因", "考勤时间不在该绩效月份内" },
});
}
var newDate = SplitEveryDay(Convert.ToDateTime(newAttendanceVacatione[i].BegDate), Convert.ToDateTime(newAttendanceVacatione[i].EndDate));
foreach (var item in oldAttendanceVacatione.Where(w => w.PersonnelNumber == newAttendanceVacatione[i].PersonnelNumber))
{
var oldDate = SplitEveryDay(Convert.ToDateTime(item.BegDate), Convert.ToDateTime(item.EndDate));
bool any = false;
foreach (var old in oldDate)
{
if (newDate.Contains(old))
any = true;
}
if(any)
error.Add(new Dictionary<string, string>
{
{ "行号", $"第{i+1}行" },
{ "人员工号", newAttendanceVacatione[i].PersonnelNumber??"" },
{ "人员姓名", newAttendanceVacatione[i].PersonnelName??"" },
{ "考勤类型", newAttendanceVacatione[i].AttendanceName??"" },
{ "开始日期", newAttendanceVacatione[i].BegDate.ToString()??"" },
{ "结束日期", newAttendanceVacatione[i].EndDate.ToString()??"" },
{ "来源", "粘贴数据" },
{ "错误原因", "该考勤时间范围与历史考勤时间冲突" },
});
}
}
if (error.Count > 0)
return new ApiResponse(ResponseType.WarningTable, "验证不通过,当前操作已拒绝", error);
List<per_attendance_vacation> addAttendanceVacatione = new List<per_attendance_vacation>();
List<per_attendance_vacation> deleteAttendanceVacatione = new List<per_attendance_vacation>();
var type = GetAttendanceType(allotId, hospitalId);
foreach (var data in newAttendanceVacatione)
{
data.AllotId = allotId;
data.HospitalId = hospitalId;
data.TypeId = type.Data.FirstOrDefault(t => t.AttendanceName == data.AttendanceName).Id;
addAttendanceVacatione.Add(data);
var any = oldAttendanceVacatione.FirstOrDefault(w => w.AllotId == allotId && w.HospitalId == hospitalId && w.BegDate == data.BegDate && w.EndDate == data.EndDate && w.PersonnelName?.Trim() == data.PersonnelName?.Trim() && w.PersonnelNumber?.Trim() == data.PersonnelNumber?.Trim() && w.TypeId == data.TypeId);
if (any != null) deleteAttendanceVacatione.Add(any);
}
if (deleteAttendanceVacatione != null && deleteAttendanceVacatione.Any())
perfoPperAttendanceVacationeRepository.RemoveRange(deleteAttendanceVacatione.ToArray());
if (addAttendanceVacatione != null && addAttendanceVacatione.Any())
perfoPperAttendanceVacationeRepository.AddRange(addAttendanceVacatione.ToArray());
return new ApiResponse(ResponseType.OK, "");
}
#endregion
public ApiResponse<List<AttendanceStatistics>> GetAttendanceStatistics(int allotId)
{
var allot = perforPerallotRepository.GetEntity(w => w.ID == allotId);
if (allot == null)
throw new PerformanceException("当前绩效记录不存在");
var types = perfoPperAttendanceTypeRepository.GetEntities(t => t.AllotId == allotId) ?? new List<per_attendance_type>();
var vacationeData = perfoPperAttendanceVacationeRepository.GetEntities(t => t.AllotId == allotId) ?? new List<per_attendance_vacation>();
// 只关注请假的人
var numbers = vacationeData.Select(w => w.PersonnelNumber).ToList();
var attendanceData = perforPerallotRepository.GetAttendance(allotId)
.Where(w => numbers.Contains(w.PersonnelNumber))
.ToList();
//var attendanceData = perforPerallotRepository.GetAttendance(allotId);
List<AttendanceStatistics> statistics = new List<AttendanceStatistics>();
// 交叉补全科室结束时间
foreach (var personnelNumber in attendanceData.Select(w => w.PersonnelNumber).Distinct())
{
var attendances = attendanceData.Where(w => w.PersonnelNumber == personnelNumber).OrderBy(w => w.AttendanceDate);
for (int i = 0; i < attendances.Count() - 1; i++)
{
var begDate = attendances.ElementAt(i).AttendanceDate.Value.Date;
var endDate = attendances.ElementAt(i + 1).AttendanceDate.Value.Date;
// 调入科室需要额外减去1天作为上一个科室结束时间
var days = attendances.ElementAt(i + 1).Source == Attendance.Type.调入.ToString() ? -1 : 0;
if (endDate > begDate)
{
var stat = new AttendanceStatistics
{
AllotID = attendances.ElementAt(i).ALLOTID,
UnitType = attendances.ElementAt(i).UnitType,
AccountingUnit = attendances.ElementAt(i).AccountingUnit,
Department = attendances.ElementAt(i).Department,
PersonnelNumber = attendances.ElementAt(i).PersonnelNumber,
PersonnelName = attendances.ElementAt(i).PersonnelName,
BeginDate = begDate,
EndDate = endDate.AddDays(days),
Detial = new List<AttendanceStatisticsDetial>()
};
statistics.Add(stat);
}
}
}
var vacationes = vacationeData
.Where(w => w.BegDate.HasValue && w.EndDate.HasValue)
.Select(w => new
{
w.PersonnelNumber,
Type = types.FirstOrDefault(p => p.Id == w.TypeId)?.AttendanceName ?? "考勤类型缺失",
Dates = SplitEveryDay(w.BegDate.Value.Date, w.EndDate.Value.Date),
Remark = types.FirstOrDefault(p => p.Id == w.TypeId)?.IsDeduction == (int)Attendance.Deduction.核减 ? "核减" : "不核减",
});
foreach (var stat in statistics)
{
stat.Detial = vacationes
.Where(w => w.PersonnelNumber == stat.PersonnelNumber)
.Select(w => new AttendanceStatisticsDetial
{
Title = w.Type,
Value = w.Dates.Where(date => date >= stat.BeginDate && date <= stat.EndDate).Count(),
Remark = w.Remark,
})
.ToList();
int vacationesDays = 0;
foreach (var item in stat.Detial)
{
if (!item.Remark.Contains("不核减"))
vacationesDays += item.Value;
}
stat.AttendanceDays = SplitEveryDay(stat.BeginDate, stat.EndDate).Where(date => date >= stat.BeginDate && date <= stat.EndDate).Count() - vacationesDays;
}
return new ApiResponse<List<AttendanceStatistics>>(ResponseType.OK, "", statistics);
}
// 拆分请假时间段为每个日期
private List<DateTime> SplitEveryDay(DateTime begin, DateTime end)
{
List<DateTime> dates = new List<DateTime>();
for (int i = 0; i <= (end - begin).TotalDays; i++)
{
dates.Add(begin.AddDays(i));
}
return dates;
}
private List<Dictionary<string, string>> CreateDataRow(SaveCollectData request, Dictionary<string, string> config)
{
List<Dictionary<string, string>> allData = new List<Dictionary<string, string>>();
for (int r = 0; r < request.Data.Length; r++)
{
// 创建固定数据列
Dictionary<string, string> baseData = CreateBaseData(request, config, r);
allData.Add(baseData);
}
return allData;
}
private Dictionary<string, string> CreateBaseData(SaveCollectData request, Dictionary<string, string> config, int rownumber)
{
Dictionary<string, string> result = new Dictionary<string, string>();
for (int c = 0; c < request.ColHeaders.Length; c++)
{
var header = request.ColHeaders[c];
var first = config.FirstOrDefault(w => w.Value == header);
if (!default(KeyValuePair<string, string>).Equals(first)
&& !result.ContainsKey(header)
&& request.Data[rownumber].Length > c)
{
result.Add(first.Key, request.Data[rownumber][c]);
}
}
return result;
}
public static List<(string, string, Func<per_attendance, object>)> Person { get; } = new List<(string, string, Func<per_attendance, object>)>
{
(nameof(per_attendance.PersonnelName), "人员姓名", t => t.PersonnelName),
(nameof(per_attendance.PersonnelNumber), "员工工号", t => t.PersonnelNumber),
(nameof(per_attendance.CallInAccountingUnit), "调入核算单元" ,t => t.CallInAccountingUnit),
(nameof(per_attendance.CallInUnitType), "调入组别", t => t.CallInUnitType),
(nameof(per_attendance.CallInDate), "调入时间", t => t.CallInDate),
};
public static List<(string, string, Func<RecordAttendcance, object>)> Vacation { get; } = new List<(string, string, Func<RecordAttendcance, object>)>
{
(nameof(RecordAttendcance.PersonnelName), "人员姓名", t => t.PersonnelName),
(nameof(RecordAttendcance.PersonnelNumber), "员工工号", t => t.PersonnelNumber),
(nameof(RecordAttendcance.AttendanceName), "考勤类型" ,t => t.AttendanceName),
(nameof(RecordAttendcance.BegDate), "开始时间", t => t.BegDate),
(nameof(RecordAttendcance.EndDate), "结束时间", t => t.EndDate),
};
}
}
...@@ -37,7 +37,7 @@ public class RecognitionDataFormat ...@@ -37,7 +37,7 @@ public class RecognitionDataFormat
{ DataFormat.百分比, new[] { 9,10 } }, { DataFormat.百分比, new[] { 9,10 } },
{ DataFormat.科学计数, new[] { 11 } }, { DataFormat.科学计数, new[] { 11 } },
{ DataFormat.分数, new[] { 12,13 } }, { DataFormat.分数, new[] { 12,13 } },
{ DataFormat.日期, new[] { 14,15,16,17 } }, { DataFormat.日期YYYYMMDD, new[] { 14,15,16,17 } },
}; };
public static DataFormat GetDataFormat(short type) public static DataFormat GetDataFormat(short type)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment