Commit a371cde7 by 纪旭 韦

考勤

parent 83de9ea4
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using Performance.DtoModels;
using Performance.EntityModels.Entity;
using Performance.EntityModels.Other;
using Performance.Services;
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.StaticFiles;
using System;
using System.IO;
using Newtonsoft.Json;
namespace Performance.Api.Controllers
{
......@@ -56,8 +57,7 @@ public ApiResponse<List<AttendanceStatistics>> GetAttendance(int allotId)
public ApiResponse<List<view_attendance>> GetCallIn(int allotId)
{
// 查询考勤视图,并按照设计图做格式转换 仅查询调入
var result = _attendanceService.GetCallIn(allotId);
return result;
return _attendanceService.GetCallIn(allotId);
}
/// <summary>
......@@ -66,10 +66,10 @@ public ApiResponse<List<view_attendance>> GetCallIn(int allotId)
/// <returns></returns>
[HttpGet("CallIn/GetBatch")]
[ProducesResponseType(typeof(HandsonTable), StatusCodes.Status200OK)]
public ApiResponse GetBatchCallInHandsonTable()
public ApiResponse GetBatchCallInHandsonTable(int allotId)
{
// 返回HandsonTable格式调动记录
return new ApiResponse(ResponseType.OK, _attendanceService.GetBatchCallInHandsonTable());
return new ApiResponse(ResponseType.OK, _attendanceService.GetBatchCallInHandsonTable(allotId));
}
/// <summary>
......@@ -103,7 +103,7 @@ public ApiResponse BatchCallIn(int allotId, int hospitalId, SaveCollectData requ
[HttpGet("Type/{allotId},{hospitalId}")]
public ApiResponse<List<per_attendance_type>> GetAttendanceType(int allotId, int hospitalId)
{
return _attendanceService.GetAttendanceType(allotId, hospitalId);
return _attendanceService.GetAttendanceType(allotId);
}
/// <summary>
/// 新增或修改考勤类型
......@@ -138,10 +138,10 @@ public ApiResponse DeleteAttendanceType(int id)
/// <returns></returns>
[HttpGet("Vacation")]
[ProducesResponseType(typeof(HandsonTable), StatusCodes.Status200OK)]
public ApiResponse GetAttendanceVacationHandsonTable()
public ApiResponse GetAttendanceVacationHandsonTable(int allotId)
{
// 返回HandsonTable格式考勤记录
return new ApiResponse(ResponseType.OK, _attendanceService.GetAttendanceVacationHandsonTable());
return new ApiResponse(ResponseType.OK, _attendanceService.GetAttendanceVacationHandsonTable(allotId));
}
/// <summary>
......@@ -151,9 +151,9 @@ public ApiResponse GetAttendanceVacationHandsonTable()
/// <param name="hospitalId"></param>
/// <returns></returns>
[HttpGet("Vacation/{allotId},{hospitalId}")]
public ApiResponse<List<RecordAttendcance>> GetAttendanceVacation(int allotId, int hospitalId)
public ApiResponse<List<RecordAttendcance>> GetAttendanceVacation(int allotId)
{
return _attendanceService.GetAttendanceVacation(allotId, hospitalId);
return _attendanceService.GetAttendanceVacation(allotId);
}
/// <summary>
......@@ -172,7 +172,7 @@ public ApiResponse AttendanceBatch(int allotId, int hospitalId, SaveCollectData
// 需要验证工号和姓名是否与“人员字典”(per_employee)完全匹配,不匹配则返回表格错误提示
// 表格错误提醒参考PersonService.CreatePerson方法
return new ApiResponse(ResponseType.OK, _attendanceService.AttendanceBatch(allotId, hospitalId, request));
return _attendanceService.AttendanceBatch(allotId, hospitalId, request);
}
#endregion
......@@ -187,6 +187,7 @@ public ApiResponse<List<AttendanceStatistics>> GetAttendanceStatistics(int allot
// 返回结果参考接口 employee/apr/getdeptdetail
return _attendanceService.GetAttendanceStatistics(allotId);
}
#region 下载
/// <summary>
......@@ -198,16 +199,32 @@ public ApiResponse<List<AttendanceStatistics>> GetAttendanceStatistics(int allot
[Route("download/attendance/{allotId}")]
public IActionResult DownloadAttendance(int allotId)
{
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Template", "医院人员绩效模板.xlsx");
List<ExcelDownloadHeads> excelDownloadHeads = new List<ExcelDownloadHeads>()
{
new ExcelDownloadHeads { Alias = "核算单元名称", Name = "AccountingUnit" },
new ExcelDownloadHeads { Alias = "科室名称", Name = "Department" },
new ExcelDownloadHeads { Alias = "姓名", Name = "PersonnelName" },
new ExcelDownloadHeads { Alias = "员工号", Name = "PersonnelNumber" },
new ExcelDownloadHeads { Alias = "人员类别", Name = "UnitType" },
new ExcelDownloadHeads { Alias = "在科开始时问", Name = "BeginDate" },
new ExcelDownloadHeads { Alias = "在科结束时间", Name = "EndDate" },
};
var result = _attendanceService.GetAttendance(allotId).Data;
var ser = JsonConvert.SerializeObject(result);
var rows = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(ser);
var filepath = _attendanceService.ExcelDownload(rows,"初始考勤记录",allotId, excelDownloadHeads);
var memoryStream = new MemoryStream();
using (var stream = new FileStream(path, FileMode.Open))
using (var stream = new FileStream(filepath, FileMode.Open))
{
stream.CopyToAsync(memoryStream).Wait();
}
memoryStream.Seek(0, SeekOrigin.Begin);
var provider = new FileExtensionContentTypeProvider();
FileInfo fileInfo = new FileInfo(filepath);
var memi = provider.Mappings[".xlsx"];
return File(memoryStream, memi, Path.GetFileName(path));
return File(memoryStream, memi, Path.GetFileName(fileInfo.Name));
}
......@@ -220,16 +237,32 @@ public IActionResult DownloadAttendance(int allotId)
[Route("download/vacation/{allotId}")]
public IActionResult DownloadVacation(int allotId)
{
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Template", "医院人员绩效模板.xlsx");
List<ExcelDownloadHeads> excelDownloadHeads = new List<ExcelDownloadHeads>()
{
new ExcelDownloadHeads { Alias = "姓名", Name = "PersonnelName" },
new ExcelDownloadHeads { Alias = "员工号", Name = "PersonnelNumber" },
new ExcelDownloadHeads { Alias = "考勤类型", Name = "AttendanceName" },
new ExcelDownloadHeads { Alias = "开始时问", Name = "BegDate" },
new ExcelDownloadHeads { Alias = "结束时间", Name = "EndDate" },
new ExcelDownloadHeads { Alias = "天数", Name = "Days" },
};
var result = _attendanceService.GetAttendanceVacation(allotId).Data;
var ser = JsonConvert.SerializeObject(result);
var rows = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(ser);
var filepath = _attendanceService.ExcelDownload(rows, "考勤记录", allotId, excelDownloadHeads);
var memoryStream = new MemoryStream();
using (var stream = new FileStream(path, FileMode.Open))
using (var stream = new FileStream(filepath, FileMode.Open))
{
stream.CopyToAsync(memoryStream).Wait();
}
memoryStream.Seek(0, SeekOrigin.Begin);
var provider = new FileExtensionContentTypeProvider();
FileInfo fileInfo = new FileInfo(filepath);
var memi = provider.Mappings[".xlsx"];
return File(memoryStream, memi, Path.GetFileName(path));
return File(memoryStream, memi, Path.GetFileName(fileInfo.Name));
}
......@@ -242,20 +275,35 @@ public IActionResult DownloadVacation(int allotId)
[Route("download/callin/{allotId}")]
public IActionResult DownloadCallIn(int allotId)
{
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Template", "医院人员绩效模板.xlsx");
List<ExcelDownloadHeads> excelDownloadHeads = new List<ExcelDownloadHeads>()
{
new ExcelDownloadHeads { Alias = "姓名", Name = "PersonnelName" },
new ExcelDownloadHeads { Alias = "员工号", Name = "PersonnelNumber" },
new ExcelDownloadHeads { Alias = "调入核算单元", Name = "AttendanceName" },
new ExcelDownloadHeads { Alias = "调入组别", Name = "UnitType" },
new ExcelDownloadHeads { Alias = "调入时间", Name = "AttendanceDate" },
};
var result = _attendanceService.GetCallIn(allotId).Data;
var ser = JsonConvert.SerializeObject(result);
var rows = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(ser);
var filepath = _attendanceService.ExcelDownload(rows, "调动记录", allotId, excelDownloadHeads);
var memoryStream = new MemoryStream();
using (var stream = new FileStream(path, FileMode.Open))
using (var stream = new FileStream(filepath, FileMode.Open))
{
stream.CopyToAsync(memoryStream).Wait();
}
memoryStream.Seek(0, SeekOrigin.Begin);
var provider = new FileExtensionContentTypeProvider();
FileInfo fileInfo = new FileInfo(filepath);
var memi = provider.Mappings[".xlsx"];
return File(memoryStream, memi, Path.GetFileName(path));
return File(memoryStream, memi, Path.GetFileName(fileInfo.Name));
}
/// <summary>
/// 生成最考勤结果下载
/// 生成最考勤结果下载
/// </summary>
/// <param name="allotId"></param>
/// <returns></returns>
......@@ -263,7 +311,40 @@ public IActionResult DownloadCallIn(int allotId)
[Route("download/statistics/{allotId}")]
public IActionResult DownloadStatistics(int allotId)
{
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Template", "医院人员绩效模板.xlsx");
List<ExcelDownloadHeads> excelDownloadHeads = new List<ExcelDownloadHeads>()
{
new ExcelDownloadHeads { Alias = "科室名称", Name = "Department" },
new ExcelDownloadHeads { Alias = "姓名", Name = "PersonnelName" },
new ExcelDownloadHeads { Alias = "员工号", Name = "PersonnelNumber" },
new ExcelDownloadHeads { Alias = "人员类别", Name = "UnitType" },
new ExcelDownloadHeads { Alias = "开始时问", Name = "BeginDate" },
new ExcelDownloadHeads { Alias = "结束时间", Name = "EndDate" },
};
var type = _attendanceService.GetAttendanceType(allotId);
foreach (var item in type.Data)
{
excelDownloadHeads.Add(new ExcelDownloadHeads() { Alias = item.AttendanceName, Name = item.AttendanceName });
}
excelDownloadHeads.Add(new ExcelDownloadHeads() { Alias = "考勤天数", Name = "AttendanceDays" });
var result = _attendanceService.GetAttendanceStatistics(allotId).Data;
var ser = JsonConvert.SerializeObject(result);
var rows = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(ser);
var filepath = _attendanceService.ExcelDownload(rows, "最终考勤结果", allotId, excelDownloadHeads);
var memoryStream = new MemoryStream();
using (var stream = new FileStream(filepath, FileMode.Open))
{
stream.CopyToAsync(memoryStream).Wait();
}
memoryStream.Seek(0, SeekOrigin.Begin);
var provider = new FileExtensionContentTypeProvider();
FileInfo fileInfo = new FileInfo(filepath);
var memi = provider.Mappings[".xlsx"];
return File(memoryStream, memi, Path.GetFileName(fileInfo.Name));
/*var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Template", "医院人员绩效模板.xlsx");
var memoryStream = new MemoryStream();
using (var stream = new FileStream(path, FileMode.Open))
{
......@@ -272,8 +353,10 @@ public IActionResult DownloadStatistics(int allotId)
memoryStream.Seek(0, SeekOrigin.Begin);
var provider = new FileExtensionContentTypeProvider();
var memi = provider.Mappings[".xlsx"];
return File(memoryStream, memi, Path.GetFileName(path));
return File(memoryStream, memi, Path.GetFileName(path));*/
}
#endregion
}
}
......@@ -334,7 +334,7 @@
<param name="allotId"></param>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.AttendanceController.GetBatchCallInHandsonTable">
<member name="M:Performance.Api.Controllers.AttendanceController.GetBatchCallInHandsonTable(System.Int32)">
<summary>
返回HandsonTable格式调动记录
</summary>
......@@ -373,13 +373,13 @@
<param name="id"></param>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.AttendanceController.GetAttendanceVacationHandsonTable">
<member name="M:Performance.Api.Controllers.AttendanceController.GetAttendanceVacationHandsonTable(System.Int32)">
<summary>
返回HandsonTable格式考勤记录
</summary>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.AttendanceController.GetAttendanceVacation(System.Int32,System.Int32)">
<member name="M:Performance.Api.Controllers.AttendanceController.GetAttendanceVacation(System.Int32)">
<summary>
查询考勤记录
</summary>
......@@ -426,7 +426,7 @@
</member>
<member name="M:Performance.Api.Controllers.AttendanceController.DownloadStatistics(System.Int32)">
<summary>
生成最考勤结果下载
生成最考勤结果下载
</summary>
<param name="allotId"></param>
<returns></returns>
......
......@@ -8880,6 +8880,21 @@
科室名称
</summary>
</member>
<member name="P:Performance.EntityModels.Other.AttendanceType.Id">
<summary>
Id
</summary>
</member>
<member name="P:Performance.EntityModels.Other.AttendanceType.AttendanceName">
<summary>
考勤类型名称
</summary>
</member>
<member name="P:Performance.EntityModels.Other.AttendanceType.IsDeduction">
<summary>
是否核减出勤 1 核减 2 不核减
</summary>
</member>
<member name="P:Performance.EntityModels.HisData.HisDepartment">
<summary>
His科室
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Performance.DtoModels
{
public class ExcelDownloadHeads
{
public string Alias { get; set; }
public string Name { get; set; }
}
}
......@@ -19,6 +19,6 @@ public class per_attendance
public string PersonnelName { get; set; } //姓名
public string CallInUnitType { get; set; } //人员类别
public string CallInAccountingUnit { get; set; } //核算单元
public Nullable<DateTime> CallInDate { get; set; } //调入时间
public DateTime? CallInDate { get; set; } //调入时间
}
}
......@@ -18,8 +18,8 @@ public class per_attendance_vacation
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; } //结束时间
public DateTime BegDate { get; set; } //开始时间
public DateTime EndDate { get; set; } //结束时间
}
}
......@@ -31,7 +31,7 @@ public class view_attendance
/// <summary>
/// 考勤时间
/// </summary>
public Nullable<DateTime> AttendanceDate { get; set; }
public DateTime AttendanceDate { get; set; }
/// <summary>
/// 来源
/// </summary>
......@@ -52,14 +52,6 @@ public class InitialAttendance
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; }
......@@ -76,8 +68,18 @@ public class AttendaceHeads
public class AttendanceType
{
public string AttendanceName { get; set; } //考勤类型名称
public string IsDeduction { get; set; } //是否核减出勤 1 核减 2 不核减
/// <summary>
/// Id
/// </summary>
public int Id { get; set; } //考勤类型名称
/// <summary>
/// 考勤类型名称
/// </summary>
public string AttendanceName { get; set; }
/// <summary>
/// 是否核减出勤 1 核减 2 不核减
/// </summary>
public string IsDeduction { get; set; }
}
......
......@@ -280,20 +280,20 @@ public IEnumerable<string> GetSecondWorkloadMaps(int hospitalId)
public IEnumerable<view_attendance> GetAttendance(int allotId)
{
using (var connection = context.Database.GetDbConnection())
var connection = context.Database.GetDbConnection();
if (connection.State != ConnectionState.Open) connection.Open();
try
{
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;
}
string query = $@"SELECT * FROM view_attendance where allotId = @allotId";
return connection.Query<view_attendance>(query, new { allotId }, commandTimeout: 60 * 60);
}
catch (Exception)
{
throw;
}
}
/// <summary>
......
using AutoMapper;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using OfficeOpenXml;
using OfficeOpenXml.Style;
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.EntityModels.Entity;
......@@ -9,6 +12,7 @@
using Performance.Repository.Repository;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
......@@ -25,7 +29,7 @@ public class AttendanceService : IAutoInjection
private readonly PerfoPperAttendanceVacationeRepository perfoPperAttendanceVacationeRepository;
private readonly PerforPerdeptdicRepository perdeptdicRepository;
private readonly PerforPeremployeeRepository perforPeremployeeRepository;
private readonly PerforCofaccountingRepository cofaccountingRepository;
public AttendanceService(
IMapper mapper,
ILogger<AttendanceService> logger,
......@@ -34,7 +38,8 @@ public class AttendanceService : IAutoInjection
PerfoPperAttendanceTypeRepository perfoPperAttendanceTypeRepository,
PerfoPperAttendanceVacationeRepository perfoPperAttendanceVacationeRepository,
PerforPerdeptdicRepository perdeptdicRepository,
PerforPeremployeeRepository perforPeremployeeRepository)
PerforPeremployeeRepository perforPeremployeeRepository,
PerforCofaccountingRepository cofaccountingRepository)
{
this.mapper = mapper;
this.logger = logger;
......@@ -44,9 +49,11 @@ public class AttendanceService : IAutoInjection
this.perfoPperAttendanceVacationeRepository = perfoPperAttendanceVacationeRepository;
this.perdeptdicRepository = perdeptdicRepository;
this.perforPeremployeeRepository = perforPeremployeeRepository;
this.cofaccountingRepository = cofaccountingRepository;
}
#region 初始考勤页面
public ApiResponse<List<AttendanceStatistics>> GetAttendance(int allotId)
{
var allot = perforPerallotRepository.GetEntity(w => w.ID == allotId);
......@@ -63,8 +70,8 @@ public ApiResponse<List<AttendanceStatistics>> GetAttendance(int allotId)
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;
var begDate = attendances.ElementAt(i).AttendanceDate.Date;
var endDate = attendances.ElementAt(i + 1).AttendanceDate.Date;
// 调入科室需要额外减去1天作为上一个科室结束时间
var days = attendances.ElementAt(i + 1).Source == Attendance.Type.调入.ToString() ? -1 : 0;
if (endDate > begDate)
......@@ -85,7 +92,6 @@ public ApiResponse<List<AttendanceStatistics>> GetAttendance(int allotId)
}
}
}
if (statistics != null)
return new ApiResponse<List<AttendanceStatistics>>(ResponseType.OK, statistics);
else
......@@ -110,7 +116,7 @@ public ApiResponse<List<view_attendance>> GetCallIn(int allotId)
}
}
public HandsonTable GetBatchCallInHandsonTable()
public HandsonTable GetBatchCallInHandsonTable(int allotId)
{
HandsonTable handson = new HandsonTable((int)SheetType.Unidentifiable, Person.Select(c => c.Item2).ToArray(), Person.Select(t => new collect_permission
{
......@@ -120,30 +126,69 @@ public HandsonTable GetBatchCallInHandsonTable()
}).ToList());
if (handson.Columns != null && handson.Columns.Any())
{
var cofaccounting = cofaccountingRepository.GetEntities(w => w.UnitType != "" && w.AllotId == allotId);
foreach (var column in handson.Columns)
{
column.Type = "text";
if (column.Data == "调入组别")
{
column.Type = "autocomplete";
column.Source = EnumHelper.GetItems<UnitType>().Select(w => w.Description.Replace("行政后勤", "行政工勤")).ToArray();
//column.Source = EnumHelper.GetItems<UnitType>().Select(w => w.Description.Replace("行政后勤", "行政工勤")).ToArray();
column.Source = cofaccounting.Select(w => w.UnitType).Distinct().ToArray();
column.Strict = true;
}
if (column.Data == "调入核算单元")
{
column.Type = "autocomplete";
column.Source = EnumHelper.GetItems<AccountUnitType>().Where(w => w.Description != "").Select(w => w.Description).ToArray();
//column.Source = EnumHelper.GetItems<AccountUnitType>().Where(w => w.Description != "").Select(w => w.Description).ToArray();
column.Source = cofaccounting.Select(w => w.AccountingUnit).Distinct().ToArray();
column.Strict = true;
}
if (column.Data == "调入时间")
{
column.Type = "date";
column.DateFormat = "YYYY/MM/DD";
}
//if (column.Data == "调入时间")
//{
// column.Type = "date";
// column.DateFormat = "YYYY/MM/DD";
//}
}
}
List<view_attendance> data = new List<view_attendance>();
data = GetCallIn(allotId).Data;
var convertDate = data.Select(t =>
new
{
t.PersonnelName,
t.PersonnelNumber,
t.AccountingUnit,
t.UnitType,
AttendanceDate = t.AttendanceDate.ToString("d")
});
if (convertDate == null)
return handson;
List<HandsonRowData> rowDatas = new List<HandsonRowData>();
int i = 1;
var dict = new Dictionary<string, string>();
Person2.ForEach(t => dict.Add(t.Item1, t.Item2));
foreach (var item in convertDate)
{
var json = JsonHelper.Serialize(item);
var firstDic = JsonHelper.Deserialize<Dictionary<string, string>>(json);
var cells = (from conf in dict join fst in firstDic on conf.Key.ToUpper() equals fst.Key.ToUpper() select new HandsonCellData(conf.Value, fst.Value)).ToList();
rowDatas.Add(new HandsonRowData(i, cells));
i++;
}
handson.SetRowData(rowDatas, rowDatas != null);
foreach (var item in handson.Data)
{
item.Remove("编号");
}
return handson;
}
......@@ -158,14 +203,14 @@ public ApiResponse BatchCallIn(int allotId, int hospitalId, SaveCollectData requ
var convertDicData = dicData.Select(w => new per_attendance
{
PersonnelNumber = w["AttendanceName"],
PersonnelNumber = w["PersonnelNumber"],
PersonnelName = w["PersonnelName"],
CallInAccountingUnit = w["CallInAccountingUnit"],
CallInUnitType = w["CallInUnitType"],
CallInDate = ConvertHelper.To<DateTime>(w["CallInDate"]),
});
var jsons = JsonHelper.Serialize(dicData);
var jsons = JsonHelper.Serialize(convertDicData);
var newAttendanceVacatione = JsonHelper.Deserialize<List<per_attendance>>(jsons);
var oldCallinAttendance = perforPerAttendanceRepository.GetEntities(t => t.AllotId == allotId && t.HospitalId == hospitalId);
......@@ -173,7 +218,8 @@ public ApiResponse BatchCallIn(int allotId, int hospitalId, SaveCollectData requ
if (per_allot == null) return new ApiResponse(ResponseType.Error, "无绩效数据");
var per_dept_dic = perdeptdicRepository.GetEntities(t => t.HospitalId == hospitalId);
var cofaccounting = cofaccountingRepository.GetEntities(ca => ca.AllotId == allotId);
var per_employee = perforPeremployeeRepository.GetEntities(t => t.AllotId == allotId && t.HospitalId == hospitalId);
List<Dictionary<string, string>> error = new List<Dictionary<string, string>>();
......@@ -215,8 +261,7 @@ public ApiResponse BatchCallIn(int allotId, int hospitalId, SaveCollectData requ
});
}
if (newAttendanceVacatione[i].CallInUnitType != per_dept_dic.FirstOrDefault(t => t.AccountingUnit == newAttendanceVacatione[i].CallInAccountingUnit)?.UnitType)
if (newAttendanceVacatione[i].CallInUnitType != cofaccounting.FirstOrDefault(t => t.AccountingUnit == newAttendanceVacatione[i].CallInAccountingUnit)?.UnitType)
{
error.Add(new Dictionary<string, string>
{
......@@ -265,7 +310,6 @@ public ApiResponse BatchCallIn(int allotId, int hospitalId, SaveCollectData requ
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)
{
......@@ -273,11 +317,9 @@ public ApiResponse BatchCallIn(int allotId, int hospitalId, SaveCollectData requ
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());
perforPerAttendanceRepository.RemoveRange(oldCallinAttendance.ToArray());
if (addPer_Attendances != null && addPer_Attendances.Any())
perforPerAttendanceRepository.AddRange(addPer_Attendances.ToArray());
......@@ -289,9 +331,9 @@ public ApiResponse BatchCallIn(int allotId, int hospitalId, SaveCollectData requ
#region 考勤类型
public ApiResponse<List<per_attendance_type>> GetAttendanceType(int allotId, int hospitalId)
public ApiResponse<List<per_attendance_type>> GetAttendanceType(int allotId)
{
var result = perfoPperAttendanceTypeRepository.GetEntities(t => t.AllotId == allotId && t.HospitalId == hospitalId).ToList();
var result = perfoPperAttendanceTypeRepository.GetEntities(t => t.AllotId == allotId).ToList();
if (result != null)
return new ApiResponse<List<per_attendance_type>>(ResponseType.OK, result);
else
......@@ -302,9 +344,10 @@ public ApiResponse<List<per_attendance_type>> GetAttendanceType(int allotId, int
}
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);
var any = perfoPperAttendanceTypeRepository.GetEntities().FirstOrDefault(t => t.Id == attendanceType.Id);
if (any != null)
{
any.AttendanceName = attendanceType.AttendanceName;
any.IsDeduction = Convert.ToInt32(attendanceType.IsDeduction);
if (perfoPperAttendanceTypeRepository.Update(any)) return new ApiResponse<AttendanceType>(ResponseType.OK, "修改成功");
else return new ApiResponse<AttendanceType>(ResponseType.Fail, "修改失败");
......@@ -326,9 +369,13 @@ public ApiResponse<AttendanceType> InsertAttendanceType(int allotId, int hospita
}
public ApiResponse DeleteAttendanceType(int id)
{
var any = perfoPperAttendanceTypeRepository.GetEntities().FirstOrDefault(t => t.Id == id);
var any = perfoPperAttendanceTypeRepository.GetEntity(t => t.Id == id);
if (any == null) return new ApiResponse(ResponseType.Fail, "没有该数据");
var use = perfoPperAttendanceVacationeRepository.GetEntity(t => t.TypeId == any.Id);
if (use != null) return new ApiResponse(ResponseType.Fail, "该类型正在使用!");
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, "删除成功");
......@@ -339,7 +386,7 @@ public ApiResponse DeleteAttendanceType(int id)
#endregion
#region 考勤记录
public HandsonTable GetAttendanceVacationHandsonTable()
public HandsonTable GetAttendanceVacationHandsonTable(int allotId)
{
HandsonTable handson = new HandsonTable((int)SheetType.Unidentifiable, Vacation.Select(c => c.Item2).ToArray(), Vacation.Select(t => new collect_permission
{
......@@ -349,27 +396,69 @@ public HandsonTable GetAttendanceVacationHandsonTable()
}).ToList());
if (handson.Columns != null && handson.Columns.Any())
{
var type = perfoPperAttendanceTypeRepository.GetEntities(t => t.AllotId == allotId);
foreach (var column in handson.Columns)
{
column.Type = "text";
if (column.Data.Contains("时间"))
{
column.Type = "date";
column.DateFormat = "YYYY/MM/DD";
}
//if (column.Data.Contains("时间"))
//{
// column.Type = "date";
// column.DateFormat = "YYYY/MM/DD";
//}
if (column.Data == "考勤类型")
{
column.Source = perfoPperAttendanceTypeRepository.GetEntities().Select(t => t.AttendanceName).ToArray();
column.Type = "autocomplete";
column.Source = type.Select(t => t.AttendanceName).ToArray();
}
}
}
List<RecordAttendcance> data = new List<RecordAttendcance>();
data = GetAttendanceVacation(allotId).Data;
var convertDate = data.Select(t =>
new
{
t.PersonnelName,
t.PersonnelNumber,
t.AttendanceName,
BegDate = t.BegDate.ToString("d"),
EndDate = t.EndDate.ToString("d")
});
if (convertDate == null)
return handson;
List<HandsonRowData> rowDatas = new List<HandsonRowData>();
int i = 1;
var dict = new Dictionary<string, string>();
Vacation.ForEach(t => dict.Add(t.Item1, t.Item2));
foreach (var item in convertDate)
{
var json = JsonHelper.Serialize(item);
var firstDic = JsonHelper.Deserialize<Dictionary<string, string>>(json);
var cells = (from conf in dict join fst in firstDic on conf.Key.ToUpper() equals fst.Key.ToUpper() select new HandsonCellData(conf.Value, fst.Value)).ToList();
rowDatas.Add(new HandsonRowData(i, cells));
i++;
}
handson.SetRowData(rowDatas, rowDatas != null);
foreach (var item in handson.Data)
{
item.Remove("编号");
}
return handson;
}
public ApiResponse<List<RecordAttendcance>> GetAttendanceVacation(int allotId, int hospitalId)
public ApiResponse<List<RecordAttendcance>> GetAttendanceVacation(int allotId)
{
var vacatione = perfoPperAttendanceVacationeRepository.GetEntities(t => t.AllotId == allotId && t.HospitalId == hospitalId);
var type = perfoPperAttendanceTypeRepository.GetEntities(t => t.AllotId == allotId && t.HospitalId == hospitalId);
var vacatione = perfoPperAttendanceVacationeRepository.GetEntities(t => t.AllotId == allotId);
var type = perfoPperAttendanceTypeRepository.GetEntities(t => t.AllotId == allotId);
if (type.Count == 0)
return new ApiResponse<List<RecordAttendcance>>(ResponseType.Fail, "没有考勤类型");
var data = from a in vacatione
join b in type on a.TypeId equals b.Id into temp
......@@ -385,15 +474,13 @@ public ApiResponse<List<RecordAttendcance>> GetAttendanceVacation(int allotId, i
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
Days = SplitEveryDay(ConvertHelper.To<DateTime>(a.BegDate), ConvertHelper.To<DateTime>(a.EndDate)).Count()
};
if (data != null)
return new ApiResponse<List<RecordAttendcance>>(ResponseType.OK, data.ToList());
else
{
return new ApiResponse<List<RecordAttendcance>>(ResponseType.Fail);
}
}
......@@ -410,7 +497,7 @@ public ApiResponse AttendanceBatch(int allotId, int hospitalId, SaveCollectData
var convertDicData = dicData.Select(w => new RecordAttendcance
{
PersonnelNumber = w["AttendanceName"],
PersonnelNumber = w["PersonnelNumber"],
PersonnelName = w["PersonnelName"],
AttendanceName = w["AttendanceName"],
BegDate = ConvertHelper.To<DateTime>(w["BegDate"]),
......@@ -433,8 +520,8 @@ public ApiResponse AttendanceBatch(int allotId, int hospitalId, SaveCollectData
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)
|| newAttendanceVacatione[i].BegDate == DateTime.MinValue
|| newAttendanceVacatione[i].EndDate == DateTime.MinValue)
{
error.Add(new Dictionary<string, string>
{
......@@ -449,8 +536,8 @@ public ApiResponse AttendanceBatch(int allotId, int hospitalId, SaveCollectData
});
}
var typeAny = attendanceType.Where(t => t.AttendanceName.Contains(newAttendanceVacatione[i].AttendanceName));
if (typeAny == null || !typeAny.Any())
var typeAny = attendanceType.FirstOrDefault(t => t.AllotId == allotId && t.HospitalId == hospitalId && t.AttendanceName == newAttendanceVacatione[i].AttendanceName);
if (typeAny == null)
{
error.Add(new Dictionary<string, string>
{
......@@ -510,24 +597,10 @@ public ApiResponse AttendanceBatch(int allotId, int hospitalId, SaveCollectData
{ "错误原因", "考勤时间不在该绩效月份内" },
});
}
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))
if (newAttendanceVacatione[i].BegDate > newAttendanceVacatione[i].EndDate)
{
var oldDate = SplitEveryDay(Convert.ToDateTime(item.BegDate), Convert.ToDateTime(item.EndDate));
bool any = false;
foreach (var old in oldDate)
error.Add(new Dictionary<string, string>
{
if (newDate.Contains(old))
any = true;
}
if (any)
error.Add(new Dictionary<string, string>
{
{ "行号", $"第{i+1}行" },
{ "人员工号", newAttendanceVacatione[i].PersonnelNumber??"" },
{ "人员姓名", newAttendanceVacatione[i].PersonnelName??"" },
......@@ -535,17 +608,42 @@ public ApiResponse AttendanceBatch(int allotId, int hospitalId, SaveCollectData
{ "开始日期", 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);
var type = GetAttendanceType(allotId);
foreach (var data in newAttendanceVacatione)
{
data.AllotId = allotId;
......@@ -553,11 +651,9 @@ public ApiResponse AttendanceBatch(int allotId, int hospitalId, SaveCollectData
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());
perfoPperAttendanceVacationeRepository.RemoveRange(oldAttendanceVacatione.ToArray());
if (addAttendanceVacatione != null && addAttendanceVacatione.Any())
perfoPperAttendanceVacationeRepository.AddRange(addAttendanceVacatione.ToArray());
......@@ -575,11 +671,11 @@ public ApiResponse<List<AttendanceStatistics>> GetAttendanceStatistics(int allot
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);
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>();
// 交叉补全科室结束时间
......@@ -588,8 +684,8 @@ public ApiResponse<List<AttendanceStatistics>> GetAttendanceStatistics(int allot
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;
var begDate = attendances.ElementAt(i).AttendanceDate.Date;
var endDate = attendances.ElementAt(i + 1).AttendanceDate.Date;
// 调入科室需要额外减去1天作为上一个科室结束时间
var days = attendances.ElementAt(i + 1).Source == Attendance.Type.调入.ToString() ? -1 : 0;
if (endDate > begDate)
......@@ -612,12 +708,12 @@ public ApiResponse<List<AttendanceStatistics>> GetAttendanceStatistics(int allot
}
var vacationes = vacationeData
.Where(w => w.BegDate.HasValue && w.EndDate.HasValue)
.Where(w => w.BegDate > DateTime.MinValue && w.EndDate > DateTime.MinValue)
.Select(w => new
{
w.PersonnelNumber,
Type = types.FirstOrDefault(p => p.Id == w.TypeId)?.AttendanceName ?? "考勤类型缺失",
Dates = SplitEveryDay(w.BegDate.Value.Date, w.EndDate.Value.Date),
Dates = SplitEveryDay(w.BegDate.Date, w.EndDate.Date),
Remark = types.FirstOrDefault(p => p.Id == w.TypeId)?.IsDeduction == (int)Attendance.Deduction.核减 ? "核减" : "不核减",
});
......@@ -646,7 +742,6 @@ public ApiResponse<List<AttendanceStatistics>> GetAttendanceStatistics(int allot
});
}
}
int vacationesDays = stat.Detial.Where(w => !w.Remark.Contains("不核减")).Sum(w => w.Value);
stat.AttendanceDays = SplitEveryDay(stat.BeginDate, stat.EndDate).Where(date => date >= stat.BeginDate && date <= stat.EndDate).Count() - vacationesDays;
}
......@@ -696,7 +791,102 @@ private List<DateTime> SplitEveryDay(DateTime begin, DateTime end)
return result;
}
public string ExcelDownload(List<Dictionary<string, object>> rows, string name,int allotId, List<ExcelDownloadHeads> headList)
{
var perAllot = perforPerallotRepository.GetEntity(t => t.ID == allotId);
string title = $"{ perAllot.Year}{perAllot.Month}{name}";
var data = new List<Dictionary<string, object>>();
foreach (var obj in rows)
{
Dictionary<string, object> nobj = new Dictionary<string, object>();
foreach (var item in obj)
{
var lower = item.Key.ToLower();
if (lower.Contains("date"))
nobj[lower] = Convert.ToDateTime(item.Value).ToString("d");
else if (lower.Contains("detial"))
{
var detRows = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(item.Value.ToString());
foreach (var detlist in detRows)
{
string value = "";
foreach (var detitem in detlist)
{
if (detitem.Key == "Value") value = detitem.Value.ToString();
if (detitem.Key == "Title") nobj[detitem.Value.ToString()] = value;
}
}
}
else
nobj[lower] = item.Value;
}
data.Add(nobj);
}
var dpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Files");
if (!Directory.Exists(dpath)) Directory.CreateDirectory(dpath);
string filepath = Path.Combine(dpath, $"{name}{DateTime.Now:yyyyMMdd}");
if (File.Exists(filepath)) File.Delete(filepath);
using (FileStream fs = new FileStream(filepath, FileMode.OpenOrCreate))
using (ExcelPackage package = new ExcelPackage(fs))
{
var worksheet = package.Workbook.Worksheets.Add(name);
if (rows != null && rows.Count() > 0)
{
worksheet.SetValue(1, 1, title);
for (int col = 0; col < headList.Count; col++)
{
worksheet.SetValue(2, col + 1, headList[col].Alias);
}
for (int col = 0; col < headList.Count; col++)
{
for (int row = 0; row < data.Count(); row++)
{
var temp = data.ElementAt(row);
var low = temp.Keys.ToString().ToLower();
var value = temp[headList[col].Name.ToLower()];
worksheet.Cells[row + 3, col + 1].Value = value;
}
}
#region 样式设置
for (int row = worksheet.Dimension.Start.Row; row <= worksheet.Dimension.End.Row; row++)
{
worksheet.Row(row).Height = 20;
for (int col = worksheet.Dimension.Start.Column; col <= worksheet.Dimension.End.Column; col++)
{
worksheet.Cells[row, col].Style.Border.BorderAround(ExcelBorderStyle.Thin);
worksheet.Cells[row, col].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
worksheet.Cells[row, col].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
}
}
worksheet.Cells[1, 1, 1, headList.Count].Merge = true;
worksheet.Cells[1, 1, 1, headList.Count].Style.Font.Bold = true;
worksheet.Cells[1, 1, 1, headList.Count].Style.Font.Size = 16;
worksheet.Row(1).Height = 24;
worksheet.Cells[2, 1, 2, headList.Count].Style.Font.Bold = true;
worksheet.View.FreezePanes(3, 1);
worksheet.Cells.AutoFitColumns();
for (int col = worksheet.Dimension.Start.Column; col <= worksheet.Dimension.End.Column; col++)
{
worksheet.Column(col).Width = worksheet.Column(col).Width > 20 ? 20 : worksheet.Column(col).Width;
}
#endregion
}
package.Save();
}
return filepath;
}
public static List<(string, string, Func<per_attendance, object>)> Person { get; } = new List<(string, string, Func<per_attendance, object>)>
{
......@@ -706,6 +896,14 @@ private List<DateTime> SplitEveryDay(DateTime begin, DateTime end)
(nameof(per_attendance.CallInUnitType), "调入组别", t => t.CallInUnitType),
(nameof(per_attendance.CallInDate), "调入时间", t => t.CallInDate),
};
public static List<(string, string, Func<view_attendance, object>)> Person2 { get; } = new List<(string, string, Func<view_attendance, object>)>
{
(nameof(view_attendance.PersonnelName), "人员姓名", t => t.PersonnelName),
(nameof(view_attendance.PersonnelNumber), "员工工号", t => t.PersonnelNumber),
(nameof(view_attendance.AccountingUnit), "调入核算单元" ,t => t.AccountingUnit),
(nameof(view_attendance.UnitType), "调入组别", t => t.UnitType),
(nameof(view_attendance.AttendanceDate), "调入时间", t => t.AttendanceDate),
};
public static List<(string, string, Func<RecordAttendcance, object>)> Vacation { get; } = new List<(string, string, Func<RecordAttendcance, object>)>
{
......
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