PersonnelModuleController.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. using Aspose.Cells;
  2. using OASystem.API.OAMethodLib;
  3. using OASystem.API.OAMethodLib.QiYeWeChatAPI;
  4. using OASystem.Domain.Dtos.PersonnelModule;
  5. using OASystem.Domain.Entities.PersonnelModule;
  6. using OASystem.Domain.ViewModels.PersonnelModule;
  7. using OASystem.Domain.ViewModels.QiYeWeChat;
  8. using OASystem.Infrastructure.Repositories.PersonnelModule;
  9. using System.Diagnostics;
  10. using System.Globalization;
  11. namespace OASystem.API.Controllers
  12. {
  13. /// <summary>
  14. /// 人事模块
  15. /// </summary>
  16. [Route("api/[controller]/[action]")]
  17. public class PersonnelModuleController : ControllerBase
  18. {
  19. private Result _result;
  20. private readonly IMapper _mapper;
  21. private readonly decimal _chengDuMinimumWage = 2100.00M;
  22. private readonly IQiYeWeChatApiService _qiYeWeChatApiService;
  23. private readonly WageSheetRepository _wageSheetRep;
  24. private readonly UsersRepository _usersRep;
  25. /// <summary>
  26. /// 初始化
  27. /// </summary>
  28. /// <param name="qiYeWeChatApiService"></param>
  29. /// <param name="wageSheetRep"></param>
  30. /// <param name="usersRep"></param>
  31. /// <param name="mapper"></param>
  32. public PersonnelModuleController(IQiYeWeChatApiService qiYeWeChatApiService,WageSheetRepository wageSheetRep, UsersRepository usersRep, IMapper mapper)
  33. {
  34. _mapper = mapper;
  35. _usersRep = usersRep;
  36. _qiYeWeChatApiService = qiYeWeChatApiService;
  37. _wageSheetRep = wageSheetRep;
  38. _result = new Result();
  39. }
  40. #region 工资表单
  41. /// <summary>
  42. /// 工资 月列表
  43. /// </summary>
  44. /// <returns></returns>
  45. [HttpPost]
  46. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  47. public async Task<IActionResult> GetWageSheetMonth()
  48. {
  49. string sql = string.Format("Select * From Pm_WageIssueWorkingDay Where IsDel = 0 Order By YearMonth Desc");
  50. var data = await _wageSheetRep._sqlSugar.SqlQueryable<WageSheetMonthView>(sql).ToListAsync();
  51. return Ok(JsonView(true, "查询成功!", data));
  52. }
  53. /// <summary>
  54. /// 工资 工作日信息
  55. /// </summary>
  56. /// <returns></returns>
  57. [HttpPost]
  58. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  59. public async Task<IActionResult> GetWageSheetMonthWorkdays(string startDt, string endDt )
  60. {
  61. //参数处理
  62. string dtFormat = "yyyy-MM-dd";
  63. DateTime startDt1, endDt1;
  64. bool startDtIsValid = DateTime.TryParseExact(startDt, dtFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out startDt1);
  65. bool endDtIsValid = DateTime.TryParseExact(endDt, dtFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out endDt1);
  66. if (!startDtIsValid) return Ok(JsonView(false, "开始日期格式错误!正确时间格式:yyyy-MM-dd "));
  67. if (!endDtIsValid) return Ok(JsonView(false, "结束格式错误!正确时间格式:yyyy-MM-dd "));
  68. string sql = string.Format(@"Select * From Sys_Calendar
  69. Where Isdel = 0 And Dt between '{0}' And '{1}'", startDt, endDt);
  70. var data = await _wageSheetRep._sqlSugar.SqlQueryable<CalendarInfoView>(sql).ToListAsync();
  71. return Ok(JsonView(true, "查询成功!", data));
  72. }
  73. /// <summary>
  74. /// 工资 工作日信息
  75. /// </summary>
  76. /// <returns></returns>
  77. [HttpPost]
  78. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  79. public async Task<IActionResult> GetWageSheetMonthWorkdaysAddOrEdit(WageSheetMonthWorkdaysAddOrEditDto dto)
  80. {
  81. //参数处理
  82. string yearFormat = "yyyy-MM";
  83. string dtFormat = "yyyy-MM-dd";
  84. DateTime yearDt, startDt1, endDt1;
  85. bool yearDtIsValid = DateTime.TryParseExact(dto.YearMonth, yearFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out yearDt);
  86. bool startDtIsValid = DateTime.TryParseExact(dto.StartDate, dtFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out startDt1);
  87. bool endDtIsValid = DateTime.TryParseExact(dto.EndDate, dtFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out endDt1);
  88. if (!yearDtIsValid) return Ok(JsonView(false, "年月日期格式错误!正确时间格式:yyyy-MM "));
  89. if (!startDtIsValid) return Ok(JsonView(false, "开始日期格式错误!正确时间格式:yyyy-MM-dd "));
  90. if (!endDtIsValid) return Ok(JsonView(false, "结束格式错误!正确时间格式:yyyy-MM-dd "));
  91. int res = -1;
  92. #region 处理数据
  93. Pm_WageIssueWorkingDay pm_WageIssueWorkingDay = new Pm_WageIssueWorkingDay();
  94. pm_WageIssueWorkingDay = _mapper.Map<Pm_WageIssueWorkingDay>(dto);
  95. List<Sys_Calendar> sys_Calendars = new List<Sys_Calendar>();
  96. sys_Calendars = _mapper.Map<List<Sys_Calendar>>(dto.CalendarInfos);
  97. pm_WageIssueWorkingDay.Workdays = sys_Calendars.Where(it => it.IsWorkDays == true).ToList().Count();
  98. foreach (var item in sys_Calendars)
  99. {
  100. item.Remark = pm_WageIssueWorkingDay.Remark;
  101. item.CreateUserId = pm_WageIssueWorkingDay.CreateUserId;
  102. item.CreateTime = pm_WageIssueWorkingDay.CreateTime;
  103. }
  104. #endregion
  105. var _sqlSugar = _wageSheetRep._sqlSugar;
  106. if (dto.Status == 1)
  107. {
  108. string sql = string.Format("Select * From Pm_WageIssueWorkingDay Where IsDel = 0 and YearMonth='{0}'",dto.YearMonth);
  109. var data = await _sqlSugar.SqlQueryable<WageSheetMonthView>(sql).FirstAsync();
  110. if (data != null)
  111. {
  112. return Ok(JsonView(false, dto.YearMonth + "日期数据已存在,请前往修改!"));
  113. }
  114. _sqlSugar.BeginTran();
  115. int add1 = await _sqlSugar.Insertable< Pm_WageIssueWorkingDay>(pm_WageIssueWorkingDay).ExecuteCommandAsync();
  116. if (add1 > 0) res = 0;
  117. int add2 = await _sqlSugar.Insertable<Sys_Calendar>(sys_Calendars).ExecuteCommandAsync();
  118. if (add2 > 0) res = 0;
  119. _sqlSugar.CommitTran();
  120. }
  121. else if (dto.Status == 1)
  122. {
  123. _sqlSugar.BeginTran();
  124. int upd1 = await _sqlSugar.Updateable< Pm_WageIssueWorkingDay >(pm_WageIssueWorkingDay)
  125. .UpdateColumns(it => new { it.YearMonth,it.StartDate,it.EndDate,it.Workdays,it.DeleteTime })
  126. .ExecuteCommandAsync();
  127. if (upd1 > 0) res = 0;
  128. int upd2 = await _sqlSugar.Updateable<Sys_Calendar>(sys_Calendars)
  129. .UpdateColumns(it => new { it.Dt, it.IsWorkDays, it.IsHoliDay, it.HoliDayName })
  130. .ExecuteCommandAsync();
  131. if (upd2 > 0) res = 0;
  132. _sqlSugar.CommitTran();
  133. }
  134. else return Ok(JsonView(false, "Status 请传入正确的状态码 1 添加 2 修改"));
  135. if (res == 0) return Ok(JsonView(true, "操作成功!"));
  136. return Ok(JsonView(false, "操作失败!"));
  137. }
  138. /// <summary>
  139. /// 工资表单 基础数据源
  140. /// </summary>
  141. /// <returns></returns>
  142. [HttpPost]
  143. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  144. public async Task<IActionResult> GetWageSheetBasicsDataSource()
  145. {
  146. string companySql = string.Format("Select * From Sys_Company Where IsDel = 0");
  147. var compnayData = await _wageSheetRep._sqlSugar.SqlQueryable<CompanyNameView>(companySql).ToListAsync();
  148. string depSql = string.Format("Select * From Sys_Department Where IsDel = 0");
  149. var depData = await _wageSheetRep._sqlSugar.SqlQueryable<Domain.ViewModels.System.DepartmentView>(depSql).ToListAsync();
  150. //获取OA系统内所有用户
  151. var nameData = await _usersRep.GetUserNameList(1);
  152. if (nameData.Code != 0)
  153. {
  154. return Ok(JsonView(false, nameData.Msg));
  155. }
  156. var data = new {
  157. compnayData = compnayData,
  158. depData = depData,
  159. userNames = nameData.Data
  160. };
  161. return Ok(JsonView(true, "查询成功!", data));
  162. }
  163. /// <summary>
  164. /// 获取工资发放月份
  165. /// </summary>
  166. /// <param name="dto"></param>
  167. /// <returns></returns>
  168. [HttpPost]
  169. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  170. public async Task<IActionResult> GetWageYaerMonths(WageYearDto dto)
  171. {
  172. string sql = string.Format(@"Select * From Pm_WageIssueWorkingDay
  173. Where Isdel = 0 And YearMonth Like '%{0}%'
  174. Order By YearMonth Asc", dto.Year);
  175. var data = await _wageSheetRep._sqlSugar.SqlQueryable<WageYearMonthView>(sql).ToListAsync();
  176. return Ok(JsonView(true,"操作成功!", data));
  177. }
  178. /// <summary>
  179. /// 获取工资表单
  180. /// </summary>
  181. /// <param name="dto"></param>
  182. /// <returns></returns>
  183. [HttpPost]
  184. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  185. public async Task<IActionResult> GetWageSheetList(WageSheetListDto dto)
  186. {
  187. //参数处理
  188. string ymFormat = "yyyy-MM";
  189. DateTime yearMonthDt;
  190. bool yearMonthDttIsValid = DateTime.TryParseExact(dto.YearMonth, ymFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out yearMonthDt);
  191. if (!yearMonthDttIsValid)
  192. {
  193. _result.Msg = "年月格式错误!正确时间格式:yyyy-MM ";
  194. return Ok(JsonView(false, _result.Msg));
  195. }
  196. //获取月工资数据
  197. string yearMonth = yearMonthDt.ToString("yyyy-MM");
  198. if (dto.PortType == 1)
  199. {
  200. _result = await _wageSheetRep.Get_WageSheet_ListByYearMonthAsync(yearMonth);
  201. if (_result.Code != 0)
  202. {
  203. return Ok(JsonView(false, _result.Msg));
  204. }
  205. }
  206. else if (dto.PortType == 2)
  207. { }
  208. else if (dto.PortType == 3)
  209. { }
  210. else
  211. {
  212. return Ok(JsonView(false, "请选择正确的端口参数"));
  213. }
  214. return Ok(JsonView(true, _result.Msg, _result.Data));
  215. }
  216. /// <summary>
  217. /// 获取工资 详情
  218. /// </summary>
  219. /// <param name="dto"></param>
  220. /// <returns></returns>
  221. [HttpPost]
  222. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  223. public async Task<IActionResult> GetWageSheetById(WageSheetInfoDto dto)
  224. {
  225. if (dto.PortType == 1)
  226. {
  227. _result = await _wageSheetRep.Get_WageSheet_InfoByIdAsync(dto.Id);
  228. if (_result.Code != 0)
  229. {
  230. return Ok(JsonView(false, _result.Msg));
  231. }
  232. }
  233. else if (dto.PortType == 2)
  234. { }
  235. else if (dto.PortType == 3)
  236. { }
  237. else
  238. {
  239. return Ok(JsonView(false, "请选择正确的端口参数"));
  240. }
  241. return Ok(JsonView(true, _result.Msg, _result.Data));
  242. }
  243. /// <summary>
  244. /// 人事模块 工资表单 删除
  245. /// </summary>
  246. /// <param name="dto"></param>
  247. /// <returns></returns>
  248. [HttpPost]
  249. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  250. public async Task<IActionResult> PostWageSheetDel(WageDelDto dto)
  251. {
  252. try
  253. {
  254. _result = await _wageSheetRep.Post_WageSheet_DelAsync(dto);
  255. if (_result.Code != 0)
  256. {
  257. return Ok(JsonView(false, _result.Msg));
  258. }
  259. }
  260. catch (Exception ex)
  261. {
  262. return Ok(JsonView(false, ex.Message));
  263. }
  264. return Ok(JsonView(true, _result.Msg, _result.Data));
  265. }
  266. /// <summary>
  267. /// 人事模块 工资表单 添加 Or 修改
  268. /// </summary>
  269. /// <param name="dto"></param>
  270. /// <returns></returns>
  271. [HttpPost]
  272. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  273. public async Task<IActionResult> PostWageSheetAddOrEdit(WageAddOrEditDto dto)
  274. {
  275. try
  276. {
  277. Pm_WageSheet pm_WageSheet = new Pm_WageSheet();
  278. pm_WageSheet = _mapper.Map<Pm_WageSheet>(dto);
  279. pm_WageSheet.LastUpdateUserId = dto.CreateUserId;
  280. #region 计算工资
  281. //月工资
  282. decimal salary = pm_WageSheet.Basic + pm_WageSheet.Floats + pm_WageSheet.PostAllowance + pm_WageSheet.InformationSecurityFee + pm_WageSheet.OtherSubsidies;
  283. //扣款合计
  284. decimal totalDeduction = pm_WageSheet.SickLeave + pm_WageSheet.SomethingFalse + pm_WageSheet.LateTo + pm_WageSheet.LeaveEarly + pm_WageSheet.Absenteeism + pm_WageSheet.NotPunch +
  285. pm_WageSheet.ReservedFunds + pm_WageSheet.WithholdingInsurance + pm_WageSheet.OtherDeductions + pm_WageSheet.OtherDeductions;
  286. //实发合计 不含个税
  287. if (pm_WageSheet.RegularDays >= pm_WageSheet.WorkDays )
  288. {
  289. pm_WageSheet.RegularDays = pm_WageSheet.WorkDays;
  290. salary = salary + pm_WageSheet.Mealsupplement;
  291. }
  292. else
  293. {
  294. if (dto.UserId == 21) //21==张海麟
  295. {
  296. salary = salary + pm_WageSheet.Mealsupplement;
  297. }
  298. else
  299. {
  300. salary = salary = (PayrollComputation.ConvertToDecimal(salary / pm_WageSheet.WorkDays) * pm_WageSheet.RegularDays) + pm_WageSheet.Mealsupplement;
  301. }
  302. }
  303. decimal actualTotal = salary - totalDeduction;
  304. pm_WageSheet.Should = salary;
  305. pm_WageSheet.TotalDeductions = totalDeduction;
  306. pm_WageSheet.TotalRealHair = actualTotal;
  307. pm_WageSheet.AfterTax = actualTotal - pm_WageSheet.WithholdingTax;
  308. #endregion
  309. _result = await _wageSheetRep.Post_WageSheet_AddOrEditAsync(dto, pm_WageSheet);
  310. if (_result.Code != 0)
  311. {
  312. return Ok(JsonView(false, _result.Msg));
  313. }
  314. }
  315. catch (Exception ex)
  316. {
  317. return Ok(JsonView(false, ex.Message));
  318. }
  319. return Ok(JsonView(true, _result.Msg, _result.Data));
  320. }
  321. /// <summary>
  322. /// 计算工资
  323. /// </summary>
  324. /// <returns></returns>
  325. [HttpPost]
  326. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  327. public async Task<IActionResult> SalaryCalculatorAsync(SalaryCalculatorDto dto)
  328. {
  329. Result result = new Result();
  330. Stopwatch sw = new Stopwatch();
  331. sw.Start();
  332. //参数处理
  333. string ymFormat = "yyyy-MM";
  334. string dtFormat = "yyyy-MM-dd";
  335. DateTime yearMonthDt,startDt,endDt;
  336. bool yearMonthDtIsValid = DateTime.TryParseExact(dto.yearMonth, ymFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out yearMonthDt);
  337. bool startDtIsValid = DateTime.TryParseExact(dto.startDt, dtFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out startDt);
  338. bool endDtIsValid = DateTime.TryParseExact(dto.endDt, dtFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out endDt);
  339. if (!yearMonthDtIsValid) return Ok(JsonView(false, "年月格式错误!正确时间格式:yyyy-MM "));
  340. if (!startDtIsValid) return Ok(JsonView(false, "开始日期格式错误!正确时间格式:yyyy-MM-dd "));
  341. if (!endDtIsValid) return Ok(JsonView(false, "结束格式错误!正确时间格式:yyyy-MM-dd "));
  342. string thisYearMonth = dto.yearMonth;
  343. string preYearMonth = yearMonthDt.AddMonths(-1).ToString("yyyy-MM");
  344. //计算本月工资起止时间 比如是2月的1号-28号,那就是2月1号的零点到3月1号的零点
  345. DateTime thisStartDt = startDt;
  346. DateTime thisEndDt = endDt; //
  347. //本月工资是否有数据 有数据则不计算
  348. result = await _wageSheetRep.Get_WageSheet_ListByYearMonthAsync(thisYearMonth);
  349. if (result.Code == 0 )
  350. {
  351. return Ok(JsonView(false, thisYearMonth + " 工资数据已存在,若无人员工资请手动添加!"));
  352. }
  353. //获取上个月工资信息
  354. List<Pm_WageSheet> preWageSheetItems = await _wageSheetRep._sqlSugar.Queryable<Pm_WageSheet>().Where(it => it.IsDel == 0 && it.YearMonth == preYearMonth).ToListAsync();
  355. preWageSheetItems = preWageSheetItems.OrderBy(it => it.UserId).ToList();
  356. if (preWageSheetItems.Count <= 0)
  357. {
  358. return Ok(JsonView(false, thisYearMonth + " 上月工资数据不存在,请手动添加!"));
  359. }
  360. //处理上个月同月同人 多条数据
  361. List<Pm_WageSheet> preWageSheetItems1 = new List<Pm_WageSheet>();
  362. preWageSheetItems1 = preWageSheetItems.GroupBy(it => new { it.YearMonth,it.UserId })
  363. .Select(it => it.FirstOrDefault(item => item.Basic !=0))
  364. .ToList();
  365. //获取OA系统内所有用户
  366. var nameData = await _usersRep.GetUserNameList(1);
  367. List<UserNameView>? userNames = nameData.Data;
  368. List<Pm_WageSheet> wageSheets = new List<Pm_WageSheet>();
  369. _result = await PayrollComputation.SalaryCalculatorAsync(preWageSheetItems1, userNames,dto.UserId, thisYearMonth, thisStartDt,thisEndDt);
  370. #region 批量添加
  371. if (_result.Code != 0)
  372. {
  373. return Ok(JsonView(false, _result.Msg));
  374. }
  375. wageSheets = _result.Data;
  376. var add = await _wageSheetRep._sqlSugar.Insertable(wageSheets).ExecuteCommandAsync();
  377. if (add <= 0)
  378. {
  379. return Ok(JsonView(false, "操作失败!"));
  380. }
  381. #endregion
  382. #region 处理返回数据
  383. //List <WageSheetItemInfoView> wageSheetItems = new List<WageSheetItemInfoView>();
  384. //wageSheetItems = _mapper.Map<List<WageSheetItemInfoView>>(wageSheets);
  385. //wageSheetItems = wageSheetItems.Select(it =>
  386. // {
  387. // UserNameView? uName1 = new UserNameView();
  388. // UserNameView? uName2 = new UserNameView();
  389. // uName1 = userNames.Where(it1 => it.UserId == it1.Id).FirstOrDefault();
  390. // if (uName1 != null) it.Name = uName1.CnName;
  391. // uName2 = userNames.Where(it1 => it.LastUpdateUserId == it1.Id).FirstOrDefault();
  392. // if (uName2 != null) it.LastUpdateUserName = uName2.CnName;
  393. // return it; }
  394. // ).ToList();
  395. #endregion
  396. sw.Stop();
  397. return Ok(JsonView(true, "操作成功! 耗时:" + (sw.ElapsedMilliseconds/1000) + "s"));
  398. }
  399. /// <summary>
  400. /// 计算工资 By YearMonth And UserId
  401. /// </summary>
  402. /// <returns></returns>
  403. [HttpPost]
  404. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  405. public async Task<IActionResult> SalaryCalculatorSingleAsync(SalaryCalculatorSingleDto dto)
  406. {
  407. Result result = new Result();
  408. Stopwatch sw = new Stopwatch();
  409. sw.Start();
  410. //参数处理
  411. string ymFormat = "yyyy-MM";
  412. string ymdFormat = "yyyy-MM-dd";
  413. DateTime yearMonthDt,startDt,endDt;
  414. bool yearMonthDtIsValid = DateTime.TryParseExact(dto.YearMonth, ymFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out yearMonthDt);
  415. bool startDtIsValid = DateTime.TryParseExact(dto.StartDate, ymdFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out startDt);
  416. bool endDtIsValid = DateTime.TryParseExact(dto.EndDate, ymdFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out endDt);
  417. if (!yearMonthDtIsValid) return Ok(JsonView(false, "年月格式错误!正确时间格式:yyyy-MM "));
  418. if (!startDtIsValid) return Ok(JsonView(false, "开始时间格式错误!正确时间格式:yyyy-MM-dd "));
  419. if (!yearMonthDtIsValid) return Ok(JsonView(false, "结束时间格式错误!正确时间格式:yyyy-MM-dd "));
  420. List<Pm_WageSheet> wageSheets = new List<Pm_WageSheet>();
  421. Pm_WageSheet wageSheet = _mapper.Map<Pm_WageSheet>(dto);
  422. wageSheets.Add(wageSheet);
  423. //获取OA系统内所有用户
  424. var nameData = await _usersRep.GetUserNameList(1);
  425. List<UserNameView>? userNames = nameData.Data;
  426. _result = await PayrollComputation.SalaryCalculatorAsync(wageSheets, userNames, dto.UserId, dto.YearMonth, startDt, endDt);
  427. if (_result.Code != 0)
  428. {
  429. return Ok(JsonView(false, _result.Msg));
  430. }
  431. List<Pm_WageSheet> wageSheets1 = new List<Pm_WageSheet>();
  432. wageSheets1 = _result.Data;
  433. #region 处理返回数据
  434. List<WageSheetInfoView> wageSheetItems = new List<WageSheetInfoView>();
  435. wageSheetItems = _mapper.Map<List<WageSheetInfoView>>(wageSheets1);
  436. wageSheetItems = wageSheetItems.Select(it =>
  437. {
  438. UserNameView? uName1 = new UserNameView();
  439. UserNameView? uName2 = new UserNameView();
  440. uName1 = userNames.Where(it1 => it.UserId == it1.Id).FirstOrDefault();
  441. if (uName1 != null) it.Name = uName1.CnName;
  442. uName2 = userNames.Where(it1 => it.LastUpdateUserId == it1.Id).FirstOrDefault();
  443. if (uName2 != null) it.LastUpdateUserName = uName2.CnName;
  444. return it;
  445. }
  446. ).ToList();
  447. #endregion
  448. sw.Stop();
  449. return Ok(JsonView(true, "操作成功!耗时:" + (sw.ElapsedMilliseconds / 1000) + "s", wageSheetItems[0]));
  450. }
  451. /// <summary>
  452. /// 导出工资单
  453. /// </summary>
  454. /// <returns></returns>
  455. [HttpPost]
  456. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  457. public async Task<IActionResult> ExportWageCard(string yearMonth)
  458. {
  459. Result result = new Result();
  460. Stopwatch sw = new Stopwatch();
  461. sw.Start();
  462. //参数处理
  463. string ymFormat = "yyyy-MM";
  464. DateTime yearMonthDt;
  465. bool yearMonthDtIsValid = DateTime.TryParseExact(yearMonth, ymFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out yearMonthDt);
  466. if (!yearMonthDtIsValid) return Ok(JsonView(false, "年月格式错误!正确时间格式:yyyy-MM "));
  467. //公司部门
  468. string sql = string.Format(@"Select row_number() over(order by pm_ws.Id) as Row_Number,
  469. sc.Id as CompanyId,sc.CompanyName,sd.Id as DepId,sd.DepName,
  470. sys_u1.CnName Name,sys_u2.CnName LastUpdateUserName,pm_ws.*
  471. From Pm_WageSheet pm_ws
  472. Left Join Sys_Users sys_u1 On pm_ws.UserId = sys_u1.Id
  473. Left Join Sys_Users sys_u2 On pm_ws.LastUpdateUserId = sys_u2.Id
  474. Left Join Sys_Company sc On sys_u1.companyId = sc.Id
  475. Left Join Sys_Department sd On sys_u1.DepId = sd.Id
  476. Where pm_ws.IsDel = 0 And pm_ws.YearMonth = '{0}'", yearMonth);
  477. var wageSheetList = await _wageSheetRep._sqlSugar.SqlQueryable<ExportWageSheetItemView>(sql).ToListAsync();
  478. if (wageSheetList.Count <= 0)
  479. {
  480. return Ok(JsonView(false, yearMonth + "暂无工资数据!"));
  481. }
  482. decimal SumPrice = 0.00M;
  483. foreach (var item in wageSheetList)
  484. {
  485. SumPrice += item.AfterTax;
  486. }
  487. WorkbookDesigner designer = new WorkbookDesigner();
  488. designer.Workbook = new Workbook(AppSettingsHelper.Get("ExcelBasePath") + "Template/工资详细清单.xlsx");
  489. designer.Workbook.Worksheets[0].Name = yearMonth +" 工资单";
  490. designer.SetDataSource("WageSheet", wageSheetList);
  491. designer.SetDataSource("YearMonth", yearMonth);
  492. designer.SetDataSource("StartEndDt", wageSheetList[0].StartDate +" - "+ wageSheetList[0].EndDate);
  493. designer.SetDataSource("WorkDays", wageSheetList[0].WorkDays);
  494. designer.SetDataSource("SumPrice", SumPrice);
  495. designer.SetDataSource("WageSheetTitle", "工资单");//
  496. designer.Process();
  497. string fileName = "WageCard/" + yearMonth + "_工资单_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xlsx";
  498. string path = AppSettingsHelper.Get("ExcelBasePath");
  499. designer.Workbook.Save(path + fileName);
  500. designer = null;
  501. string excelPath = AppSettingsHelper.Get("ExcelFtpPath") + fileName;
  502. string url = AppSettingsHelper.Get("ExcelBaseUrl");
  503. string fileUrl = url + excelPath;
  504. sw.Stop();
  505. return Ok(JsonView(true, "操作成功!耗时:" + (sw.ElapsedMilliseconds / 1000) + "s", new { FileUrl = fileUrl }));
  506. }
  507. #endregion
  508. }
  509. }