多租户计件系统实现工资项公式动态计算与调整
多租户计件系统实现工资项公式动态计算与调整
2020-03-27 14:11
迷你小飞机
阅读(…)
评论(…)
编辑
收藏
设计目标:满足多租户使用,实现每个租户动态管理工资项及相应的公式,在统计展示工资条时需要跟据有效的工资项进行动态展示。
实践选择:该单元重点在公式动态计算这块,常用的有各种 规则引擎如 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}"); } }