工资表
组织数据看似简单问题,如果设计的奇妙可以简化程序编程。
本能设计工资记录
当初我设计的工资表记录是根据用户提供的工资条进行设计,工资条设计如下:
姓名 |
实发 |
应发 |
基本资 |
扣税 |
请假扣 |
加班费 |
交通补 |
扣养老 |
扣失业 |
张三 |
而我的第一印象也就是设计了工资明细表Salary(表结构):
EmpID |
S01 |
S02 |
S03 |
… |
… |
… |
… |
… |
S99 |
工资项目表SalaryDefine(表定义):
ID |
唯一Id |
ColumnName |
对应S1…S99 |
Column名称 |
汉字描述 |
Enabled |
启用标记 |
这种设计也是常用设计,可以根据定义表动态启用工资字段,并能对工资字段进行描述,同时也很好理解。
存在的问题
从财务的角度分析,工资条其实是一个余额表,余额表式在没有效率和复杂逻辑的情况下可以不用真实的表来表示。
余额表表示存储的数据是合并的,不能反映真实的原貌,为此我们可能需要扩展表记录一些凭证记录,例如请假记录(请假的扣款项是由多条请假记录组成的)。这也就增加了复杂度。
余额表仅反映了数据的一个角度,随着角度的不同,余额表的设计可能就会不同,例如:合并扣养老=扣保险+扣失业,在这种情况下我们不但要加表,并且还要更改逻辑处理方式,这也就说明这种设计很难在底层提供稳定的支撑。由于业务的复杂化,可能有些记录需要和其他系统进行协助,这就更加重了不稳定性。
解决
余额是由凭证产生的,用凭证的概念来改造后的设计:
ID |
唯一Id |
SalaryDay |
工资周期日 |
BllDay |
业务发生日期(日期) |
EmpId |
用户ID |
SalaryItem |
工资项目(实发、应发、扣保险、扣…、加…) |
ForwardValue |
正向记账金额 |
BackwardValue |
反向记账金额 |
Key1,Key2 |
根据需要保存的现场值,例如:所在部门,级别,等等 |
Attend1,Attend2, |
附加信息列,例如:单据编号(存储请假单、加班单的编号,用于追溯) |
每条凭证记录都能详细并准确描述自己。
SalaryDay |
BllDay |
EmpID |
SalaryItem |
Dep (Key1) |
Forward Value |
Backward Value |
Voucher (Attend1) |
2009-9-26 |
2009-9-26 |
1 |
应发工资 |
开发部 |
5000 |
0 |
|
2009-9-26 |
2009-9-6 |
1 |
加班费 |
技术支持 |
100 |
0 |
JB0087 |
2009-9-26 |
2009-9-11 |
1 |
请假扣款 |
开发部 |
0 |
50 |
QJ0034 |
2009-9-26 |
2009-9-26 |
1 |
… |
开发部 |
… |
0 |
.. |
不论凭证产生在什么地方,都能正确表达,例如:发生人事调用,但请假单发生在“技术支持” 部门,凭证都能正确表达。如果单据需要产生多条凭证,这样的设计都能满足。
通过凭证记录,就可以产生各种需要的报表,例如工资单(工资单的项目不论怎么变化,本质是一个统计合计值并合并项)。
总之凭证记载的是企业的真实活动,只要合理的设计关键字,奠定好基础,统计也就简单并且容易。