一)项目背景
二)项目需求说明
三)项目开发过程
四)项目成果演示
五)项目补充说明
正文:
一)项目背景由于某公司实行新的费用制度,涉及部门的年终考核事项,考核部门需要根据各个部门的费用实际使用情况做预算,分析,统计,指标评估,作为公司降本节支的重要依据,最大限度的降低公司的运营成本。费用分摊项目应运而生,由于人力不足,一切简单从简,以满足最基本的需求为目标,遵循流程简化,界面简洁,操作简单为基本原则,进行小型系统开发。
二)项目需求说明
项目需求主要来源于XXX部的实际工作需要,简单介绍如下:
1)总体需要:能登记各个部门的实际发生的费用明细,具体如:商品的基本资料(名称,规格,品牌,单价,数量,金额,承担部门等等);招待费用,车辆派遣(车牌号,车型,司机,公里数,费用发生额等);录入时指定特定部门或者人员,可以查询,需要经过相关审核(部门审核,上级领导审核)。
2)费用录入要求如下:
表 2-1 费用录入说明
说明:公司费用大致分为这四大类,即:日常费用,招待费用,物流日常费用(指物流部门的日常费用),商务车费用,录入时根据此分类对应录入系统即可。
3)费用分类资料细则说明:(部分,样式表)
表 2-2 费用分类资料细则
说明:费用分类统一编号由录入部门决定,例如:人力资源部录入费用编号以10开头,财务部录入费用编号以20开头……等。
4)费用明细如下:
表 2-3 费用细则说明
说明:录入的时候,需要存储,如:人力资源部登记福利费的时候需要说明是什么?妇女节,生日福利,……做查询的时候,只需要看到福利费,以费用编号为最小单位统计依据,不再进行细分。
5)录入和审核需求如下:
表 2-4 录入与审核要求说明
说明:任何费用必须由部门领导审核,分管领导审核需要满足一定条件,如某笔费用发生额超过规定额时,才需要上级领导审核。有些费用需要指定某部门某专员录入,如商务车费用只能由物流事业部相关人士录入等。
三)项目开发过程
分析相关需求,与提供相关需要的人员进行多次多次沟通,进行简单的相关的设计。
1)逻辑分析:
哪些人属于哪个部门,是否拥有系统的使用权限,系统的权限分哪些等级?==>人员,部门,人员与部门关系等基础资料;可以在给人员分配部门的同时分配系统使用权限;
哪些费用有哪些部门哪些人录入,需要什么相关审核?==>费用明细的基础资料,费用录入生成相关单据,审核流水确定需要考虑部门的相关负责人等。
生成的单据的编号,新增用户,部门的相关编号怎么产生?单据审核节点判断?==>存储过程,标量值函数实现。
哪些人可以查询什么费用?==>费用的相关查询,暂定只能普通用户看到本部门的费用信息。
2 )数据库设计:有逻辑分析不难得出本系统需要的基础表及其相关存储过程,函数。
图 3-1 数据库设计
详细说明,此处略去。
3)模块设计,如图所示:
图 3-2 模块设计
相关说明:基础资料维护(1)包括:
人员维护:新增,查询,保存,修改,修改用户密码,删除,关闭等基本功能;
部门维护:新增,查询,保存,修改,删除,关闭等基本功能;
人员部门维护:新增,查询,保存,修改,删除,关闭等基本功能;
费用项目维护:新增,查询,保存,修改,删除,关闭等基本功能;
费用项目登记(2)包括:
日常费用录入:新增,保存,修改,删除,关闭等基本功能;
招待费用录入:新增,保存,修改,删除,关闭等基本功能;
物流日常费用录入:新增,保存,修改,删除,关闭等基本功能;
商务车费用录入:新增,保存,修改,删除,关闭等基本功能;
特别说明:所有单据一旦被审核,均不能被修改或者删除。
费用审核审核流程(3)包括:
部门审核:查询,审核通过,审核不通过,退出等基本功能;
分管领导审核:查询,审核通过,审核不通过,退出等基本功能;
总经理审核:查询,审核通过,审核不通过,退出等基本功能;
费用查询(4),主要用于查询,可以看到费用明细,审核进度等,有待进一步细分,本系统只是初稿,后期会有扩充。
退出(5):退出本系统并关闭;
关于(6):计算器功能,属于辅助功能扩展。
说明:本系统分四个角色,分别拥有不同的模块,介绍如下:
a)管理员:权限最大,拥有系统的全部功能(1)--(6);(说明:(1)代表模块基础资料维护)
b)审核:拥有模块(2)(3)(4)(5)(6);
c)录入:拥有模块(2)(4)(5)(6);
d)查询:权限最小,拥有模块(4)(5)(6);
总体设计图如下:
图 3-3 总体设计
4)代码设计(略)(列几个比较常用的,希望对初学者有所帮助)
SQL基本操作:(SQLHelper.cs)
参见:http://zhangbc.blog.51cto.com/6066576/1401228
EXEel导出功能:(untCommon.cs)
参见:http://zhangbc.blog.51cto.com/6066576/1401234
treeNode相关用法(这是本次写代码的一次重要收获):
private void getBm(TreeNode treenode) { treenode.Text = "组织机构 "; treenode.NodeFont = new Font("楷体", 14, FontStyle.Underline | FontStyle.Bold); DataSet ds = new DataSet(); jc_bmdoc bm = new jc_bmdoc(); ds = bm.getList(" and beactive='是'"); DataTable dt=ds.Tables[0]; for (int i = 0; i < dt.Rows.Count; i++) { treenode.Nodes.Add(dt.Rows[i][2].ToString().Trim()); } } private void hr_Bmzhygw_Load(object sender, EventArgs e) { this.tvBM.LabelEdit = true; TreeNode node = new TreeNode(); getBm(node); tvBM.Nodes.Add(node); tvBM.ExpandAll(); } private void tvBM_AfterSelect(object sender, TreeViewEventArgs e) { jc_bmzhygx bmzg = new jc_bmzhygx(); DataSet ds = new DataSet(); dvZhiydoc.DataSource = null; ds = bmzg.getList(e.Node.Text.ToString().Trim(),1); //MessageBox.Show(e.Node.Text);//获取选择中节点的内容 dvZhiydoc.DataSource = ds.Tables[0]; }
获得汉字的助记码:(SQL标量值函数)
参见:http://zhangbc.blog.51cto.com/6066576/1401258
单据录入功能:(事务处理,这是本次写代码的又一次重要收获)
private void djSave_Click(object sender, EventArgs e) { using (System.Transactions.TransactionScope TranSop = new System.Transactions.TransactionScope())//开始事务 { try { getDjhz(); try { for (int i = 0; i < dvRcfy.Rows.Count - 1; i++) { #region djmx.djbh = djhz.djbh; djmx.dj_sort = dvRcfy.Rows[i].Cells["dj_sort"].Value.ToString(); djmx.fylx = ""; djmx.is_zx = "否"; try { djmx.fybh = dvRcfy.Rows[i].Cells["fybh"].Value.ToString(); } catch { ut.InfoMsg("费用编号不能为空!"); return; } try { djmx.fymch = dvRcfy.Rows[i].Cells["fymch"].Value.ToString(); } catch { ut.InfoMsg(dvRcfy.Rows[i].Cells["fymch"].Value.ToString() + "费用名称不能为空!"); return; } try { djmx.shpgg = dvRcfy.Rows[i].Cells["shpgg"].Value.ToString(); } catch { ut.InfoMsg("规格不能为空!"); return; } try { djmx.zrbm = dvRcfy.Rows[i].Cells["zrbm"].Value.ToString(); } catch { ut.InfoMsg("费用承担部门不能为空!"); return; } if ((decimal)dvRcfy.Rows[i].Cells["dj"].Value == 0) { ut.InfoMsg("单价不能为0!"); return; } else { djmx.dj = (decimal)dvRcfy.Rows[i].Cells["dj"].Value; } if ((decimal)dvRcfy.Rows[i].Cells["shl"].Value == 0) { ut.InfoMsg("数量不能为0!"); return; } else { djmx.shl = (decimal)dvRcfy.Rows[i].Cells["shl"].Value; } djmx.je = (decimal)dvRcfy.Rows[i].Cells["je"].Value; try { djmx.pinp = dvRcfy.Rows[i].Cells["pinp"].Value.ToString(); } catch { djmx.pinp = ""; } djmx.chph = ""; djmx.chex = ""; djmx.yongt = ""; djmx.days = 0; djmx.distance = 0; djmx.chlr = ""; djmx.gangw = ""; try { djmx.beizhu = dvRcfy.Rows[i].Cells["beizhu"].Value.ToString(); } catch { djmx.beizhu = ""; } #endregion dj_mx.Insert(djmx); } if(djhz.app_bm==""||djhz.shenqr==""||djhz.lyr=="") { ut.InfoMsg("抬头不能有空项!"); return; } if (dvRcfy.Rows.Count <= 1 || dj_hz.Insert(djhz) == 0) { ut.InfoMsg("保存失败!"); return; } dj_hz.Insert(djhz); ut.InfoMsg("保存成功!"); } catch (Exception ex) { ut.ErrorMsg("新增失败,请检查!" + ex.ToString()); } TranSop.Complete(); } catch (Exception ex) { MessageBox.Show("错误原因:\n"+ex.ToString()); TranSop.Dispose(); } } clear(); }
1)系统登陆界面相关:
图 4-1 登陆入口
图 4-2 登陆信息
2)系统主界面相关:
图 4-3 部门职员信息维护
图 4-4 单据录入界面
图 4-5 单据审核
图 4-6 费用查询
五)项目补充说明本小系统基本达到预定目标,新手上路,历时将近一个月,收获颇多,后期将有许多需求都很在此基础扩展(如统计报表等),但仍有很多有待改进之处,欢迎各位指正,不甚感激!
完整demo及其代码不便分享,敬请谅解!