中小型超市管理系统.docx
《中小型超市管理系统.docx》由会员分享,可在线阅读,更多相关《中小型超市管理系统.docx(20页珍藏版)》请在冰豆网上搜索。
中小型超市管理系统
秦皇岛广播电视大学
毕业设计说明书(论文)
作者:
汪天伟
系(部):
计算机系
专业班级:
11春计算机信息管理
学号1113001405540
题目:
中小型超市管理系统
指导教师:
刘光孟繁伟
2012年12月
一需求分析.........................................................2
(1)行业概念的理解...............................................2
(2)业务流程说明.................................................3
(3)问题解决方案..................................................3
(4)数据流图.....................................................3
二系统设计.........................................................3
二系统设计.........................................................5
(1)系统模块的划分................................................5
(2)数据字典.....................................................5
3、程序的设计与编码................................................9
(1)POS系统的开发................................................9
1.功能及实现方法...................................................9
2.问题讨论:
交易流水号的确定.......................................10
(二)管理信息系统的设计...........................................10
1.界面设计.........................................................10
2.各个功能模块实现的要点和技术....................................11
2.1类继承与重载...................................................1
2.2windows消息机制................................................12
2.3关于权限设置...................................................13
2.4应用Delphi显式事务控制........................................14
2.5存储过程的使用.................................................14
参考书录...........................................................24
中小型超市管理系统
内容摘要:
《中小型超市管理信息系统》是一个比较复杂和全面的管理系统,可以完成中小型超市的大部分业务。
总的来说包括进货管理,物价管理,库存管理,销售管理,供货厂商管理,POS收款机子系统等。
该系统界面朴素一致,但不失美观大方;操作方便,查询功能强大;数据全面、准确。
系统采用了目前比较流行而技术非常成熟地客户机/服务器结构(C/S),前台应用程序用Delphi开发,后台数据库是MicrosoftSQLServer2000。
关键字:
面向对象的程序设计,继承,WINDOWS消息,存储过程,事务。
一、需求分析
(一)行业概念的理解
POS:
PointOfSells,电子收款机系统,也就是直接与顾客打交道的收银机系统。
定单状态:
用来描述商品进货方式,一般分为定单、日配、自采等。
定单:
表示该商品进货必须先向供货商发出定单,供货商按定单上的商品明细发货,超市则按定单上的商品明细收货。
日配:
指那些每天都要进货的商品或者补货期较短的商品,例如水果,生鲜蔬菜等。
如果按定单,时间不允许而且工作重复烦琐。
自采:
顾名思义,超市自己负责商品的进货。
销售状态:
用来描述某种商品当前的销售状态,一般定义为正常、促销、折扣等,正常表示商品处于正常的售价状态,即按正常的售价销售。
促销:
表示超市把某种商品让利销售,以此来吸引跟多的消费者。
一般低于正常售价甚至成本价。
折扣:
表示某种商品销售情况不好,或者商品有瑕疵,或者保质期快到等情况发生时,使尽快商品销售出去的一种手段。
库存调整:
当非因正常销售发生而实物数量变动时,通过调整库存使其帐面数量与实物数量相符。
日处理:
当一天的销售结束后,开始做日处理。
把当天的销售数据汇总,调整商品库存。
损益:
商品出现损坏,变质,被盗等情况发生时,商品发生损益。
损益通过调整库存得到体现。
商品变价:
商品变价与促销/折扣调整价格是两个不同的概念。
商品变价是指修改商品的正常售价,调整后在一定的时间内不会在发生改变。
价格可能是升高也可能是降低,一般都是由于进价变动引起的。
促销/折扣期:
每一种商品促销/折扣都有一定的期限,即有一定的时间限制。
一种商品不可能无期限的促销/折扣。
当期限超过,商品自动恢复正常售价。
毛利、毛利百分比:
毛利=商品售价-商品进价毛利百分比=(商品售价-商品进价)÷商品售价
商品进价及成本核算:
在成本核算中,商品成本价的确定一般有最后进价,移动加权平均,按商品批次定价等几种方式,由于后两种核算方式较复杂,本系统采用简单的最后进价方式。
(2)业务流程说明
在实际管理中,有三种信息流动,即资金流,单据流和商品实物流。
系统围绕实物流展开,对商品从供应商那里进货到商品销售到顾客手中整个流程进行管理。
简单来说,就是商品的进销存管理。
每个环节通过相应的单据来连接,同时资金发生流动。
在商品管理方面,我们提出部门和商品分类的概念,这种分级管理方式简洁高效。
所谓部门,就是按照商品的基本属性进行分类管理。
例如,超市一般可分为食品部,生鲜部,日用品部等。
部门下面再分类,所谓商品分类,指按商品的具体属性划分,例如,食品部下面可以有糖果饼干类,饮料类等,每个部门和每个商品类别都有相应的负责人负责。
《中小型超市管理信息系统》完全体现了这种管理思想,商品的销售和商品库存都可以按部门级和分类级完成查询等其他操作。
作为一个超市的管理人员,及时了解销售情况是非常必要的,以便及时调整进货或者安排营销策略,把握商机。
而《中小型超市管理信息系统》正好满足了这一要求,可以实时查询前台的销售情况,并且数据准确可信。
(三)问题解决方案
超市系统在运行过程中数据流量是非常巨大的。
有时候会因数据流量过大而使网络发生阻塞,使POS系统发生断网,直接影响销售活动的进行。
这种情况是应该坚决避免的,应该尽量减少网络的数据流量。
这一思想在本系统中的直接体现就是采用日处理和运用本地缓存技术。
日处理的主要目的就是把当天的销售数据整理汇总,更新商品库存表,为第二天的销售做准备。
与日处理不同的另一种处理方式就是每次商品销售完成以后就立即更新库存。
但这样会使得服务器的负荷非常的重,经常会使POS系统发生断网。
POS系统销售商品时所取的商品信息是服务器上的数据,有效的保证了数据的一致性和集中控制。
虽然商品信息来自服务器,但我们使用了本地缓存。
POS系统会把取得的数据暂时的存放在本地的内存,当要读取商品信息时,会先在本地缓存里查找,如果成功的话,就不必访问服务器。
这样一来就有效的减少了网络的数据流量和服务器的负荷。
此外,系统充分利用了客户机/服务器结构的特点,比较复杂的查询更新等操作都用存储过程来实现。
存储过程在服务器端执行完毕仅返回执行结果,能有效的减少网络的通讯流。
(4)数据流图
对整个业务活动进行分析归纳后,我得出如下的数据流图:
数据流程图
二系统设计
(一)系统模块的划分
根据前面所作的需求分析,我把整个系统分为如下几个模块
3、程序的设计与编码
4、有了前面的工作,我们选择就进入编码阶段了。
(一)POS系统的开发系统的开发系统的开发系统的开发
1.功能及实现方法功
POS系统是作为一个单独的程序开发的,主要在POS机上运行,完成商品的交易任务。
销售的商品信息存储在POS_SALE表中。
我们把一次交易放在一个事务提交,保证了数据的完整性和数据的正确性。
界面以灰色调为主,使得收银员长时间工作眼睛不感到疲劳。
收银的操作也很简单方便。
交易流水号自动增加。
当某种商品处于促销或折扣销售状态时,POS系统自动取商品的促销或折扣售价,无需人工干预,并且促销或折扣期结束时,系统能自动识别恢复正常售价。
这一个功能的实现是通过商品视图来完成的。
请看商品视图源码。
前台POS销售时取商品信息时用到的视图:
CREATEVIEWV_SPXX
AS
SELECTNAME,A.GOODS_ID,A.BAR_ID,A.GUIGE,
BUY_PRICE=CASE
WHEN(GETDATE()>B.END_DATEANDGETDATE()WHEN(GETDATE()B.BEGIN_DATE)ANDA.FLAG='促销'THENA.BUY_PRICE2
WHEN(GETDATE()B.BEGIN_DATE)AND
A.FLAG='折扣'THENA.BUY_PRICE2
ELSEA.BUY_PRICE1
END
FROMGOODS_INFOA,GOODS_PROMOTE_LOGB
WHEREA.GOODS_ID*=B.GOODS_ID
交易是在一个事务里完成的,请看交易完成数据提交的代码:
ifform_pos.Database1.InTransactionthen
try
form_pos.query1.ApplyUpdates;把本地缓存修改的操作提交服务器
form_pos.Database1.Commit;事务提交
form_pos.query1.CommitUpdates;清空本地缓存
Ifform_pos.Database1.InTransaction=falsethen
form_pos.Database1.StartTransaction;
except
form_pos.Database1.Rollback;事务回滚
end;
2.问题讨论问题讨论:
交易流水号的确定
在实际运用中,可能十几台甚至几十台POS机同时工作,也就是存在大量的数据库并发操作。
怎样使交易流水号唯一呢?
我是这样实现的,在每次事务提交之前,比较本机的流水号是否在后台数据库交易流水号中已经存在,如果存在,也就是说已经被别人占用,则重新取出最大交易流水号,然后提交整个事务。
事务提交成功以后还要更新本地交易流水号。
这是取最大流水号selectmax(P_NO)asp_nofrompos_sale的SQL语句。
(二)管理信息系统的设计
1.界面设计
本系统采用了带导航栏的多文档窗体设计风格,使操作变的简单直观。
当使用某一个功能模块时,只显示相应的菜单,使人不会觉得眼花缭乱。
系统完全摈弃那种界面花哨,色彩绚丽等华而不实做法,但和传统的风格有有所区别,传统的风格显得过于呆板。
本系统的界面色调一致,简单朴素,但不失美观大方。
窗体界面一致,操作也大同小异,丝毫没有杂乱无章的感觉。
我首先定义了几个重要的窗体基类,其他的窗体基本上这几个基类的派生类。
在使用时在对窗体进行重载。
所有的窗体都是在运行时动态加载的。
需要运行那个窗体时,程序才加载该窗体,用完后立即释放,这样使用户计算机系统资源得以最少得占用。
请看一个窗体得创建例子:
enter_dan:
=Tenter_dan.Create(Self);入库单录入窗体得创建form_show(enter_dan,555,360,10,2);form_show为自定义函数
对所有子窗体显示我自定义了一个函数form_show,减少了工作量和代码量。
procedureform_show(form:
TForm;fwidth,fheight,fleft,ftop:
integer);begin
withformdo
begin
height:
=fheight;
width:
=fwidth;
Left:
=fleft;
top:
=ftop;
Show;
end;end;
窗体的释放实现,例如释放入库单录入界面窗体:
procedureTenter_dan.FormClose(Sender:
TObject;varAction:
TCloseAction);begin
action:
=cafree;在内存中释放掉窗体
end;
2.各个功能模块实现的要点和技术
这里我只把我在编码过程中比较重要或者比较有代表性的技术和部分源码阐述一下。
详情查看系统的源代码。
2.1类继承与重载
在编码过程中,我充分利用了面向对象编程的特定——代码的重用,具体实现起来依靠的是重载和继承。
把具有相同或相似属性的类抽象出来作为一个基类。
我定义了几个重要的窗体基类,基类窗体包含了需要的公有控件和共有事件方法。
其他的窗体基本上这几个基类的派生类。
在使用时在对窗体的控件的属性和方法进行继承或者重载。
关于在DELPHI方法的重载,例如:
procedureAction7Execute(Sender:
TObject);OVERRIDE:
procedureTenter_goods_info.Action7Execute(Sender:
TObject);begintry
if(dbedit1.Text<>'')and(dbedit2.Text<>'')and(dbedit3.Text<>'')and(dbedit4.Text<>'')then
begin
query1.Post;
addbutton.Enabled:
=true;
delbutton.Enabled:
=true;
savebutton.Enabled:
=false;
end
else
showmessage('你的输入不完整!
');
except
showmessage('代码重复!
');
end;
end;
2.windows消息机制
当查询窗体要返回结果时,我们用到了windows消息机制。
首先定义一个全局的自定义消息常量。
ConstMy_WM_USER=WM_USER+100;//自定义消息
向指定的窗体发送自定义消息,传递查询结果。
例如:
procedureTgoods_info_search.searchbuttonClick(Sender:
TObject);begin
try
price_adjust.Query1.Close;price_adjust.Query1.SQL.Clear;price_adjust.Query1.SQL:
=query1.SQL;sendmessage(price_adjust.Handle,My_WM_USER,0,0);except
beep;
end;
close;
end;
接收消息,并且处理它,例如:
定义消息响应的方法proceduremy_wm_user100(varmsg:
Tmessage);messageMy_WM_USER:
处理消息:
procedureTgoods_promote.my_wm_user100(varmsg:
Tmessage);
begin
withquery1doclose;sql.clear;sql.add(sql语句);open;end;
2.3关于权限设置
权限设置是一个管理系统非常重要的一部分,直接关系到公司业务和财务安全性。
因此,本系统在这方面的功能是较完善的。
操作人员的权限可以定义到每级子菜单。
对没有赋权限的菜单项不予显示。
也就是说,系统能根据登陆人员的权限自动显示具有权限的功能菜单。
我们把人员的权限信息存放在MENU_FLAG表中,在系统启动时加载相关的权限设置信息。
权限设置这一功能只有高级管理人员和系统管理员才能使用。
根据权限显示菜单算法
withdamo.query1do//query1关联MENU_FLAG表begin
close;
sql.Clear;
sql.Add('select*frommenu_flagwhereid=:
id');ParamByName('id').AsInteger:
=person_id;
open;
end;
fori:
=1to42do
begin
flag:
=damo.query1.fields[i].AsInteger;//flag为每项菜单的权限标志forj:
=0tomain_form.ComponentCount-1do
begin
if(main_form.Components[j]isTMenuItem)and((main_form.Components[j]asTMenuItem).Tag=i-1)
then
ifflag=0then
(main_form.Components[j]asTMenuItem).Visible:
=falseelse
(main_form.Components[j]asTMenuItem).Visible:
=true;end;
end;
2.4应用Delphi显式事务控制
事务控制是一种能够把数据库的一组修改作为整体提交给数据库以保证数据的一致性和完整性的机制。
如果其中有一个操作失败,则所有操作失败。
2.5储过程的使用
在程序设计中,系统主要的复杂的操作我都都是通过存储过程来实现的。
例如:
使用库存调整操作时,我们用P_ADJUST_STORE来完成。
procedureTadjust_store.okbuttonClick(Sender:
TObject);
Begin
ifnotdamo.Database1.InTransactionthendamo.Database1.StartTransaction;开始一个事务
withP_ADJUST_STOREdo//P_ADJUST_STORE为存储过程
begin
Params[1].AsInteger:
=strtoint(edit_id.Text);Params[2].AsFloat:
=strtofloat(edit_adjust.Text);Params[3].AsInteger:
=table1.Fields[0].AsInteger;Params[4].AsInteger:
=person_id;//person_id为全局变量人员IDPrepare;execproc;
end;
try
damo.Database1.Commit;事务提交
except
begin
damo.Database1.Rollback;事务回滚showmessage('数据提交失败!
');
end;
end;
以下是几种典型存储过程。
日处理存储过程:
CREATEPROCEDUREP_DIALY_DO
@dialy_datechar(12),@person_idsmallint
AS
DECLARE@goods_idint
DECLARE@quantityfloat
DECLARE@amountmoney
DECLAREtemp_cursorCURSORFOR
SELECTA.GOODS_ID,SUM(A.QUANTITY),SUM(A.QUANTITY*B.COST_PRICE)FROMPOS_SALEA,GOODS_INFOB
WHERE
convert(char(12),WORK_DATE,102)=@dialy_date
ANDA.GOODS_ID=B.GOODS_IDGROUPBYA.GOODS_IDOPENtemp_cursorFETCHNEXTFROMtemp_cursorINTO@goods_id,@quantity,@amountWHILE(@@FETCH_STATUS=0)
BEGIN
ifEXISTS(SELECT*FROMSTORE_DETAILWHEREGOODS_ID=@goods_id)
BEGIN
UPDATE
STORE_DETAILSETQUANTITY=QUANTITY-@quantity,AMOUNT=AMOUNT-@amountWHEREGOODS_ID=@goods_idEND
FETCHNEXTFROMtemp_cursorINTO@goods_id,@quantity,@amount
END
INSERTDIALY_DAN
VALUES(@dialy_date,'已做',@person_id)
CLOSEtemp_cursor
DEALLOCATEtemp_cursor
查询每日商品销售汇总的存储过程:
CREATEPROCEDUREP_DIALY_SALE
AS
CREATETABLE#temp_table
(
amountfloat,
work_datechar(12),s
ale_costfloat,gain
float
)
INSERTINTO#temp_table
SELECTa.amount,convert(char(12),a.work_date,102)ASwork_date,(c.cost_price*a.quantity)ASsale_cost,(a.amount-c.cost_price*a.quant