工资表
组织数据看似简单问题,如果设计的奇妙可以简化程序编程。
本能设计工资记录
当初我设计的工资表记录是根据用户提供的工资条进行设计,工资条设计如下:
姓名 | 实发 | 应发 | 基本资 | 扣税 | 请假扣 | 加班费 | 交通补 | 扣养老 | 扣失业 |
张三 |
|
|
|
|
|
|
|
|
|
而我的第一印象也就是设计了工资明细表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 | .. |
不论凭证产生在什么地方,都能正确表达,例如:发生人事调用,但请假单发生在“技术支持” 部门,凭证都能正确表达。如果单据需要产生多条凭证,这样的设计都能满足。
通过凭证记录,就可以产生各种需要的报表,例如工资单(工资单的项目不论怎么变化,本质是一个统计合计值并合并项)。
总之凭证记载的是企业的真实活动,只要合理的设计关键字,奠定好基础,统计也就简单并且容易。