多租户计件系统实现工资项公式动态计算与调整
2020-03-27 14:11 迷你小飞机 阅读(333) 评论(0) 编辑 收藏 举报设计目标:满足多租户使用,实现每个租户动态管理工资项及相应的公式,在统计展示工资条时需要跟据有效的工资项进行动态展示。
实践选择:该单元重点在公式动态计算这块,常用的有各种 规则引擎如 CKRule还有些开源的、还有Free等等。这里还有可选择js 计算(听说有点问题)、table.Compute。
我选择用table.Expression 扩展来做,无需集成第三方,也能满足需求。在业务使用环节上不会出现瓶颈或者托后腿,更不需要花时间去了解。
动手干活:先来几个对象关系表
1.工资项表 FD_SalaryItem
2 工资项记录表 FD_SalaryInfo
3.工资记录表 FD_Salary
动手实现:跟据基础数据进行计算并存入【工资记录表】中,为后续工资条展示做准备,也就是行转列处理下就OK啦。
string data = "2020-03"; ///提取某月所有员工资项明细列表 var lst = repo.GetBy(data).Concrete().ToList(); ///分组统计每个周期、工资项、每位员工、工资项结果 var lstSalary = lst.GroupBy(e => new { F_ActDay = e.F_ActDay, F_SalaryItem = e.F_SalaryItem, F_ReadName = e.F_ReadName }) .Select(s => new { F_ActDay = s.Key.F_ActDay, F_SalaryItem = s.Key.F_SalaryItem, F_ReadName = s.Key.F_ReadName, F_SalaryValue = s.Sum(e => e.F_SalaryValue) }).ToList(); //分组获取某月有多少位员工 var lstUser = lst.GroupBy(e => new { e.F_ActDay, e.F_ReadName }).Select(s => new { s.Key.F_ActDay, s.Key.F_ReadName }).ToList(); //var list = RF.ResolveInstance<FD_SalaryRepository>().GetBy(data); ///获取自定义工资项列表 var lstItem = RF.ResolveInstance<FD_SalaryItemRepository>().GetByAct().Concrete().ToList(); DataTable dt = new DataTable(); dt.Columns.Add("F_ActDay", typeof(string)); dt.Columns.Add("F_ReadName",typeof(string)); ///第一次初始化所有列头,注意要带上类型否则变成字符串拼接了 foreach (var item in lstItem) { dt.Columns.Add(item.F_FullName, typeof(decimal)); } ///绑定当前列有表达式的 注:不能同上面一起绑定 有些列还未初始化完,就进行绑定会报错 foreach (var item in lstItem) { if (!string.IsNullOrEmpty(item.F_Expression)) dt.Columns[item.F_FullName].Expression = item.F_Expression; } foreach (var user in lstUser) { DataRow row = dt.Rows.Add(); row["F_ActDay"] = user.F_ActDay; row["F_ReadName"] = user.F_ReadName; foreach (var item in lstItem) { if (string.IsNullOrEmpty(item.F_Expression))//含有表达式的为只读类型 row[item.F_FullName] = 0;//不初始化为0时,有空则无法计算 } var ts = lstSalary.Where(e => e.F_ReadName == user.F_ReadName).ToList(); foreach (var Salary in ts) { row[Salary.F_SalaryItem] = Salary.F_SalaryValue; } } dt.BeginLoadData(); dt.EndLoadData(); foreach(DataRow dr in dt.Rows) { Console.WriteLine("******************************************"); for (int i = 0; i < dt.Columns.Count; i++) { Console.WriteLine($"{dt.Columns[i].ColumnName}={dr[i]},\t{dt.Columns[i].Expression}"); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架