代码改变世界

多租户计件系统实现工资项公式动态计算与调整

2020-03-27 14:11  迷你小飞机  阅读(329)  评论(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}");
                    }
                   
                }