1,自定義工資項(xiàng)
定義工資公式的功能是企業(yè)工資計(jì)算中常見(jiàn)的做法,這其實(shí)就像Excel系統(tǒng)中的公式一樣的普通。但某位技術(shù)員在要自己開發(fā)的程序中增加公式系統(tǒng),那就要開發(fā)一個(gè)像樣的公式解釋邏輯了,該工作我們?cè)谥耙呀?jīng)介紹過(guò)。
不過(guò)實(shí)際的工作生活中,工資項(xiàng)目常常不是固定不變的,對(duì)于某個(gè)企業(yè)而言,其考核辦法也是隨時(shí)變化的,如果技術(shù)員沒(méi)理解清楚工資業(yè)務(wù)的變化并進(jìn)行抽象,那常常導(dǎo)致程序反復(fù)修改,客戶也很不滿意。如獎(jiǎng)金發(fā)放這個(gè)業(yè)務(wù)邏輯中,原來(lái)就只有獎(jiǎng)金點(diǎn)數(shù)和每點(diǎn)獎(jiǎng)金兩種部分:
1 | 獎(jiǎng)金點(diǎn)數(shù) | 各個(gè)員工級(jí)別設(shè)置不同的資金點(diǎn)數(shù)。 |
2 | 每點(diǎn)獎(jiǎng)金 | 根據(jù)每個(gè)月的業(yè)績(jī)和資金點(diǎn)數(shù)和落實(shí)的每點(diǎn)獎(jiǎng)金。 |
但某天客戶新制定的獎(jiǎng)金方案要增加部門這個(gè)項(xiàng)目,如部門是銷售部的才發(fā)獎(jiǎng)金,這樣系統(tǒng)就會(huì)有很多變化。
上述例子只是一個(gè)客戶的情況,但軟件開發(fā),一般都想做成產(chǎn)品,要有很多客戶,那變化就更多了。
序號(hào) | 客戶類型 | 說(shuō)明 |
1 | 小單位-銷售類 | 銷售計(jì)提方案復(fù)雜,考勤簡(jiǎn)化。 |
2 | 小單位-研發(fā)類 | 無(wú)多少提成方案,考勤嚴(yán)謹(jǐn)。 |
3 | 大單位-綜合類 | 有研發(fā)式計(jì)提,有銷售式計(jì)提,有復(fù)雜的考勤類生產(chǎn)工資計(jì)算公式。 |
于是,簡(jiǎn)單定義有多少個(gè)工資項(xiàng)目,似乎是非常不明智的做法。讓客戶來(lái)定義工資項(xiàng)目是最好的辦法。這也大大降低了開發(fā)的成本和實(shí)施維護(hù)的工作量。
2,技術(shù)實(shí)現(xiàn)
自定義工資項(xiàng)和公式在技術(shù)上需要做如下設(shè)計(jì):
序號(hào) | 類型 | 設(shè)計(jì)項(xiàng)目 | 說(shuō)明 |
1 | 對(duì)象設(shè)計(jì) | 工資字段定義 | 如月工作天數(shù),周末日加班天數(shù),獎(jiǎng)金點(diǎn)數(shù),病假小時(shí),餐補(bǔ),多種類型補(bǔ)貼等。 |
2 | 對(duì)象設(shè)計(jì) | 實(shí)發(fā)工資項(xiàng)目 | 如實(shí)發(fā)基本工資,實(shí)發(fā)餐補(bǔ),實(shí)扣請(qǐng)假,實(shí)收獎(jiǎng)金等等。 |
3 | 對(duì)象設(shè)計(jì) | 主類 | 能夠引用字段和工資項(xiàng)的內(nèi)容。 |
4 | 邏輯設(shè)計(jì) | 公式解釋 | 解釋器使用CKRule的.Net解釋邏輯。 |
5 | 邏輯設(shè)計(jì) | 調(diào)度模型 | 設(shè)計(jì)業(yè)務(wù)程序與CKRule規(guī)則引擎的調(diào)用邏輯。 |
6 | 數(shù)據(jù)庫(kù)設(shè)計(jì) | 允許工資字段設(shè)置,實(shí)發(fā)工資項(xiàng)目設(shè)置 | 允許在數(shù)據(jù)庫(kù)中定義字段及工資項(xiàng)目。 |
7 | 界面設(shè)計(jì) | 員工工資數(shù)據(jù)加載 | 可以加載員工的基本工資信息和工資字段信息。 |
8 | 界面設(shè)計(jì) | 工資公式編輯 | 允許用戶對(duì)工資公式進(jìn)行編輯。編輯過(guò)程要使用到自定義的字段和工資項(xiàng)。 |
2.1 界面效果圖
工資計(jì)算界面
界面與原來(lái)固定工資項(xiàng)時(shí),有明顯分別,如下內(nèi)容值得注意:
序號(hào) | 項(xiàng)目 | 說(shuō)明 |
1 | 數(shù)據(jù)庫(kù) | 每個(gè)員工的工資字段信息都是從數(shù)據(jù)庫(kù)加載的。 |
2 | 周期性 | 應(yīng)該有一個(gè)地方定義某個(gè)工資周期的字段,如3月份使用這一批字段。 |
3 | 有效性 | 每個(gè)員工使用到的工資字段是不相同的,雖然字段有很多,但該員工使用到的才會(huì)被設(shè)置。 |
注意第2點(diǎn),公式設(shè)置時(shí),也有周期性的問(wèn)題,即有新字段了,就要編輯新的公式。當(dāng)然對(duì)于某個(gè)公司而言,有新工資方案才可以有新的公式的。
工資公式編輯界面
公式設(shè)置界面也與原來(lái)的非常不同,注意如下變化:
序號(hào) | 項(xiàng)目 | 說(shuō)明 |
1 | 數(shù)據(jù)庫(kù) | 計(jì)算名稱那里的信息都是從數(shù)據(jù)庫(kù)加載的。(代碼偷懶了,沒(méi)實(shí)現(xiàn)) |
2 | 資源 | 資源那里基本上沒(méi)什么關(guān)鍵詞了。因?yàn)榛旧险也坏街苯佣x的字段內(nèi)容。 |
3 | 動(dòng)態(tài)取字段 |
2.2代碼
對(duì)象定義
[Serializable] public class SalaryCond { public string Id { get; set; } public double 基本工資 { get; set; } public string 狀態(tài) { get; set; } public string 員工性質(zhì) { get; set; } public string 計(jì)薪方式 { get; set; } public string 姓名 { get; set; } PRivate 結(jié)果定義 _結(jié)果 = new 結(jié)果定義(); public 結(jié)果定義 結(jié)果 { get { return _結(jié)果; } set { _結(jié)果 = value; } } private List<字段定義> _字段集合 = new List<字段定義>(); public List<字段定義> 字段集合 { get { return _字段集合; } set { _字段集合 = value; } } } [Serializable] public class 字段定義 { public string 名稱 { get; set; } public double 值 { get; set; } } [Serializable] public class 工資項(xiàng)定義 { public string 名稱 { get; set; } public bool 正向 { get; set; } public double 值 { get; set; } } [Serializable] public class 結(jié)果定義 { public double 實(shí)發(fā)工資 { get; set; } List<工資項(xiàng)定義> _工資項(xiàng)集合 = new List<工資項(xiàng)定義>(); public List<工資項(xiàng)定義> 工資項(xiàng)集合 { get { return _工資項(xiàng)集合; } set { _工資項(xiàng)集合 = value; } }}
加載設(shè)置數(shù)據(jù)
var _table = _access.GetTable("select * from 工資基本信息 order by id").ToList<SalaryCond>(); var _projs = _access.GetTable("select 名稱,正向,0 as 值 from 工資項(xiàng)").ToList<工資項(xiàng)定義>(); foreach (var item in _table) { var _subList = _access.GetTable("select 名稱,值 from 工資字段 where baseid ='" + item.Id + "'").ToList<字段定義>(); item.字段集合.AddRange(_subList); item.結(jié)果.工資項(xiàng)集合.AddRange(_projs); } dgvLst.DataSource = _table; dgvLst.AllowUserToAddRows = false;
規(guī)則引擎中定義
在本項(xiàng)目中,公式解釋與模型設(shè)計(jì)工作是由CKRule規(guī)則引擎處理的,其調(diào)用關(guān)系圖如下:
(該工具相關(guān)信息請(qǐng)?jiān)L問(wèn):www.ckrule.com)
需要設(shè)置的內(nèi)容如下: