为保证ERP系统的信息流准确快速的传递,需要给系统设计一个消息盒子机制。当系统中发生业务操作后,需要提醒下一个环节的操作人员,以保证ERP信息流快速准确传递。比如生产任务单(工作单,加工单,制单)过帐完成后,需要通知仓库准备材料供车间领料生产。消息盒子的界面大致如下所示:
消息盒子包含业务通知(Messages)和工作流审批(Workflow)。业务通知比如采购人员下达采购订单PO后,需要通知仓库人员准备收货。工作流审批是以审批为基础的单据流程控制。
在实现消息盒子过程中,遇到一个客户需要将消息同时发送到电子邮件系统中,于是撰此文以分享实现过程。
客户的目的很简单,发送消息的同时,也将此消息抄送到相应的邮件帐户中:
实施部分
1 搭建电子邮件服务器
有以下几种选择
1 与Outlook搭配的邮件服务器Exchange Server是一个很好的邮件服务器,只是配置稍微复杂一点。
2 Magic WinMail ,WinWebMail 免费版可发布50-100个帐户,超过此限制需要购买授权。
3 hMailServer 开源,免费,无限制。提供COM接口可供二次开发。
最终选择hMailServer作为ERP系统的邮件服务器。配置过程此处略过。
安装好hMailServer后,创建域名EnterpriseSolution.com,并启用它。
2 同步帐户邮件
打开同步程序,如下图所示,输入管理员密码后连接到邮件服务器中。这是我调用COM接口完成的程序。
在这个程序中, 可以将ERP用户的邮件同步到hMailServer的帐户表中。
点击同步按钮,打开ERP帐户选择窗体,再点击确认之后,ERP中的帐户就同步到hMailServer邮件系统中。
查看hMailServer的帐户:
开发部分
下面详细讲解一下上面的同步程序是如何实现的,它是一个简单的C#调用C++ COM接口的程序。hMailServer官方给出的COM帮助文档地址在这里:https://www.hmailserver.com/documentation/v5.6/?page=com_objects
1 读取邮件系统帐户
先创建连接到hMailSever服务器
private Domain HMailServerConnection()
{
string hMailDomain = txtDomain.Text;
string HMailUsername = "Administrator";
string HMailPassword = txtPassword.Text;
var objGlobal = new ApplicationClass();
objGlobal.Authenticate(HMailUsername, HMailPassword);
return objGlobal.Domains.get_ItemByName(hMailDomain);
}
大部分时间我们都是与接口对象Domain交互。
然后读取帐户表数据绑定到界面网格控件中。
DataTable table = new DataTable("Table");
table.Columns.Add("Address", typeof (string));
table.Columns.Add("Password", typeof (string));
table.Columns.Add("PersonFirstName", typeof (string));
table.Columns.Add("PersonLastName", typeof (string));
_domain = HMailServerConnection();
Accounts accounts = _domain.Accounts;
for (int i = 0; i < accounts.Count; i++)
{
Account account = accounts[i];
DataRow dataRow = table.NewRow();
dataRow["Address"] = account.Address;
dataRow["Password"] = account.Password;
dataRow["PersonFirstName"] = account.PersonFirstName;
dataRow["PersonLastName"] = account.PersonLastName;
table.Rows.Add(dataRow);
}
gridAccount.AutoGenerateColumns = false;
gridAccount.DataSource = table;
2 添加邮件帐户
参考下面的代码调用
Domain domain = HMailServerConnection();
Accounts accounts = domain.Accounts;
Account mailbox = accounts.Add();
mailbox.Address = email;
mailbox.Password = password;
mailbox.Save();
3 清除邮件帐户
参考下面的代码
Accounts accounts = _domain.Accounts;
int count = accounts.Count;
while (count > 0)
{
_domain.Accounts.Delete(0);
count--;
}
_domain.Accounts.Refresh();
hMailSever提供的COM接口是x86架构的,所以这个项目我只能设x86编译平台。
4 多国语言
这个项目还有涉及到多语言实现,我采用的是一个公共方法翻译界面上的控件,参考下面的代码。
public static void TranslateForm(Form form)
{
string labelText = string.Empty;
DataRow dataRow = null;
string translation = string.Empty;
switch (Application.CurrentCulture.LCID)
{
case 2052:
translation = "CHS";
break;
case 1028:
case 3076:
case 5124:
translation = "CHT";
break;
}
foreach (var label in GetAllControlsRecusrvive<Label>(form))
{
labelText = label.Text.Trim().TrimEnd(':');
dataRow = Shared.TranslationTable.Rows.Find(labelText);
if (dataRow != null)
label.Text = Convert.ToString(dataRow[translation]);
}
我只需要在每个界面的窗体加载事件中调用上面的方法即可完成多语言功能。
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
Shared.TranslateForm(this);
}
界面翻译项来自于项目嵌入的Xml资源文件。
项目源代码文件:http://files.cnblogs.com/files/JamesLi2015/Synchronization.zip
随笔分类 - ERP 设计与实施
主要致力于中小企业离散制造业的ERP系统的实施、优化与二次开发。有着丰富的ERP开发和实施经验,主营产品Enterprise Solution包含进销存,工程,生产,财务模块,可有效地帮助企业进行营运策划、减低成本、如期付运和提高产品质量。
摘要: 为保证ERP系统的信息流准确快速的传递,需要给系统设计一个消息盒子机制。当系统中发生业务操作后,需要提醒下一个环节的操作人员,以保证ERP信息流快速准确传递。比如生产任务单(工作单,加工单,制单)过帐完成后,需要通知仓库准备材料供车间领料生产。消息盒子的界面大致如下所示: 消息盒子包含业务通知(Messages)和工作流审批(Workflow)。业务通知比如采购人员下达采购订单PO后,需要...
阅读全文
posted @
2016-05-24 21:49 James Li 阅读(418) |
评论 (0)
编辑
摘要: 当ERP的财务模块与生产,供应链模块集成时,这些模块过帐时会产生会计凭证。如果能在产生会计凭证前可预览一下凭证,那对用户而言是一个很友好的设计。如下图所示,贷项通知单过帐前,可通过预览凭证,知晓即将产生的会计凭证。 点击预览凭证按钮,可看到即将产生的会计凭证: 为达到此目的,分享一下对系统的修改。 首先是业务单据重写按钮事件, protected override void O...
阅读全文
posted @
2016-05-10 23:02 James Li 阅读(60) |
评论 (0)
编辑
摘要: 以微软的WF为基础,为达到ERP中的批核与通知目的,参考现有系统中的技术,在此分享其中的技巧。 先来看最终的结果,也就是下图中的工作流宿主。 在上面的工作流定义中,除工作流宿主(rehost)技术外,还需要解决规则表达式的解析难题。 .NET WF提供的规则编辑器是基于代码的,但对于一个无代码的开发环境,需要找到一种表达式的设计,解析规范。 比如,在运行时,我们需要根据当前的运行参数解析出以上...
阅读全文
posted @
2016-05-09 23:30 James Li 阅读(46) |
评论 (0)
编辑
摘要: 在物料清单功能中,常常需要借助于外部形象的解释来更深刻的了解物料清单。比如我们在介绍物料清单时,会用下面的图表来辅助说明: 这样一来就很容易理解。而这样的图片又和ERP中物料清单本身关联不多,于是这些形象的解释性功能被放进附件中。 在新发布的ERP系统中,有以下附件管理功能改善 1 增加DWG格式的附件浏览功能。可在线查看Auto CAD 格式的附件。 在一些行业,物料清单的来...
阅读全文
posted @
2016-05-08 23:03 James Li 阅读(38) |
评论 (0)
编辑
摘要: 在不联网的情况下,一台物理电脑安装数据库服务,VMware创建多个虚拟机,虚拟机中多个客户端并发连接到物理主机。可共用同一个物理主机的数据库,也可以测试多用户并发等问题。 1 安装微软虚拟网卡。在控制面板中打开设备管理器,选择网络适配器,点菜单栏的操作菜单项,选择添加过时硬件菜单。在英文环境下的菜单项是Action-> Add legacy hardware。 从类别中选择网络适配器,再选择...
阅读全文
posted @
2015-08-26 08:05 James Li 阅读(155) |
评论 (0)
编辑
摘要: 查找 Lookup 窗体是一个容器,也可以把TextBox,Button也看成是一个容器,可以往容器里面添加按钮。 参考下面的实现代码,给TextBox增加查找按钮。 var btn = new Button(); btn.Size = new Size(25, txtOutputPath.ClientSize.Height + 2); btn.Location = new Point(t...
阅读全文
posted @
2015-08-25 08:46 James Li 阅读(234) |
评论 (0)
编辑
摘要: 数据库版本控制1) 开发版本控制。控制多人同时修改数据库产生的冲突,使用SQL Source Control 工具做版本管理。SQL Server Management Studio支持VSS和TFS等作为数据库脚本的版本控制工具。关于SQL Source Control,参考以下地址 http:/...
阅读全文
posted @
2015-08-24 08:03 James Li 阅读(1438) |
评论 (0)
编辑
摘要: C/S架构的应用程序需要支持自动更新功能,当新版本程序发布后,正在运行的客户端能检测到新版本的程序,通知用户是否下载更新。工作以来参与过几个自动更新模块的设计与维护,撰文总结自动更新模块设计与实现。自动更新组件主要内容1 版本比较。旧版本如何检测到新版本,版本信息是程序集自描述的,还是用单独的文件保...
阅读全文
posted @
2015-08-22 08:01 James Li 阅读(1668) |
评论 (0)
编辑
摘要: 权限模块是ERP系统的核心模块之一,完善的权限控制机制给系统增色不少。总结我接触过的权限模块,以享读者。1 权限的简明定义ERP权限管理用一句简单的话来说就是:谁 能否 做 那些 事。文句含义说明谁部门+岗位职责也可以不与部门岗位绑定,省略角色定义。能否能(True) 否(False)用0或1,tr...
阅读全文
posted @
2015-08-21 08:04 James Li 阅读(2406) |
评论 (5)
编辑
摘要: 单据编码是ERP系统中必备的功能,用于生成各种单据的流水号,常常借助于日期时间等字符来生成一个唯一的单据号码。从软件的角度来说,就是为生成数据表的主键值(参考编号),从用户的角度来说,就是给业务单据制定编码规范。之后做到见名知意,比如销售订单号是SO201508190001,采购订单号码是PO201...
阅读全文
posted @
2015-08-19 09:47 James Li 阅读(1779) |
评论 (5)
编辑
摘要: ERP系统的单据具备标准的功能,这里的单据可翻译为Bill,Document,Entry,具备相似的工具条操作界面。通过设计可复用的基类,子类只需要继承基类窗体即可完成单据功能的程序设计。先看标准的销售合同单据界面:本篇通过销售合同单据功能,依次讲解编程要点,供参考。1 新增 Insert窗体有二种...
阅读全文
posted @
2015-08-18 07:54 James Li 阅读(2709) |
评论 (5)
编辑
摘要: Windows 10正式版发布以后,新操作系统带来了许多的变化。现在新购买的电脑安装的系统应该是Windows 10。与当初用户不习惯Windows 7,购买新电脑后第一个想做的事情就是重装成XP,估计现在的Windows 10新用户也有这种冲动(安装Windows 7)。界面方面的变化需要一些时间...
阅读全文
posted @
2015-08-18 07:53 James Li 阅读(349) |
评论 (1)
编辑
摘要: 异常处理模块是大型系统必备的一个组件,精心设计的异常处理模块可提高系统的健壮性。下面从我理解的角度,谈谈异常处理的方方面面。我的设计仅仅限定于Windows Forms,供参考。1 定义异常类型.NET 框架定义很多异常类型,ERP系统中根据实际的需要,我们再增加一些自定义的异常类型。数据库访问异常...
阅读全文
posted @
2015-08-14 07:58 James Li 阅读(430) |
评论 (1)
编辑
摘要: 根据近几年的制造业软件开发经验,以我开发人员的理解角度,简要说明功能(Feature)是如何设计与实现的,供参考。因架构的不同,技术实现上会有所差异,我的经验仅限定于Windows Form程序。总体功能1 系统支持多用户。创建一个单实例(Singleton)的会话管理器SessionManager...
阅读全文
posted @
2015-08-13 08:24 James Li 阅读(1865) |
评论 (2)
编辑
摘要: 实现多国语言有许多种实现方案,无外乎是一种字符串替换技术,将界面控件的文本标签替换成相应语言的文字。.NET Windows Forms实现多国语言的方法有以下几种:1 .NET的方案,使用资源文件分别做三个语言的资源文件,比如String.resx,String.zh-cn.resx,String...
阅读全文
posted @
2015-08-12 07:52 James Li 阅读(2338) |
评论 (7)
编辑
摘要: 1 定义模块和功能执行系统功能(SAUTSF),在系统主文件(System Master File SAMF)模块中增加功能SAMFEM,Employee Master。给有权限的用户组分配功能SAMFEM的权限,包含新增,删除,修改,打印,过帐权限,这是功能权限。如果需要增加字段权限,比如可以编辑...
阅读全文
posted @
2015-08-11 07:54 James Li 阅读(1097) |
评论 (0)
编辑
摘要: 数据审计,英语表达是Audit,是追踪数据变化的过程,记录数据变化前后的值,供参考分析。通过设置,ERP可以追踪一个表的所有字段的变化,也可以只记录指定的字段的值变化。欧美企业每年都有独立的审计部门,从总经理到下层部门员工,逐个审查过去发生的经济业务的帐面数据与实际是否一致。ERP中的审计功能,通常...
阅读全文
posted @
2015-08-10 07:56 James Li 阅读(330) |
评论 (0)
编辑
摘要: 成熟的ERP系统的界面应该都是从模板中拷贝出来的,各类功能的界面有规律可遵循。软件界面设计模式化或是艺术性的创作,我认可前者,模式化的界面客户容易举一反三,降低学习门槛。除了一些小部分的功能界面设计特殊一些,ERP绝大部分的功能的界面都相似。以我接触和设计的ERP系统,总结常见的界面设计模式,供读者...
阅读全文
posted @
2015-08-08 07:55 James Li 阅读(2658) |
评论 (5)
编辑
摘要: 1. 变更记录功能: 对PO,SO,JO,BOM都采用"审核"后变更模式,可记录操作者的变更历史。2. 系统内置简单的文件管理系统.各种基本资料,单据,均可上传下载对应的文档.3. 定义10个备用字段:内置20个备用字段,可以根据企业实际管理需求,来定义它的名称,比如定义备用字段1:材料; 备用字段...
阅读全文
posted @
2015-08-07 17:34 James Li 阅读(268) |
评论 (0)
编辑
摘要: Windows Forms程序实现界面与逻辑分离的关键是数据绑定技术(Data Binding),这与微软推出的ASP.NET MVC的原理相同,分离业务代码与界面层,提高系统的可维护性。数据绑定 Data Binding数据绑定技术的主要内容:数据源(Data Source),控件(Control...
阅读全文
posted @
2015-08-07 08:04 James Li 阅读(2667) |
评论 (3)
编辑
摘要: C/S架构的应用程序,将一些复杂的计算逻辑由客户端转移到服务器端可以改善性能,同时也为了其它方面的控制。.NET Remoting在局域网内调用的性能相当不错。ERP系统中基于.NET Remoting和WCF构建一个应用程序服务器(Application Server)。分布式应用设计目标:1 客...
阅读全文
posted @
2015-08-06 07:54 James Li 阅读(1868) |
评论 (6)
编辑
摘要: 做企业管理软件很难避免与Microsoft Excel打交道,常常是软件做好了,客户要求说再做一个Excel导入功能。导入Excel数据的功能的难度不大,从Excel列数据栏位的取值,验证值,再导入到数据库表中。然而一直是在做重复工作,写过不计其数的Excel导入程序,每次只是满足于问题解决,后来终...
阅读全文
posted @
2015-08-04 07:57 James Li 阅读(2200) |
评论 (5)
编辑
摘要: 大型系统具备一个通用的附件管理功能,对于单据中无法清晰表达的字段,用一个附件图片或附件文档表示是最好的方法了。比如物料清单附加一张CAD图纸,销售订单评审功能中附加客户的各种表格,通用附件功能对系统起到画龙点睛的作用。一图解千言,先来看一下界面设计模式,看起来和一般的数据输入功能相同。首先是设计附件...
阅读全文
posted @
2015-08-03 07:55 James Li 阅读(2412) |
评论 (7)
编辑
摘要: Infragistics 是.NET平台优秀的控件供应商,囊括了WinForms,ASP.NET,Silverlight,WPF,Windows Phone等所有关于微软.NET技术的界面控件。借助于这些功能复杂的控件,为ERP的界面提供了灵活的操作能力。本篇不谈控件开发,只详细说明ERP系统如何使...
阅读全文
posted @
2015-07-31 07:57 James Li 阅读(2561) |
评论 (6)
编辑
摘要: LLBL Gen Pro是一个为.NET开发人员设计的的对象关系映射(ORM)框架,与NHibernate,Entity Framework等框架一样,通过实体与数据表的映射,实现关系数据库持久化。1 LLBL Gen Pro 入门 LLBL Gen Pro Basic打开LLBL Gen Pro程...
阅读全文
posted @
2015-07-29 18:14 James Li 阅读(993) |
评论 (0)
编辑
摘要: 1 对用户输入做过多的约定和假设配置文件App.config中有一个设定报表路径的配置节:在程序中有一个销售报表文件SalesReport.rpt,用代码调用这个报表,可能会写成:string salesReport=ReportPath + "SalesReport.rpt";因为路径末尾没有加反...
阅读全文
posted @
2015-07-29 07:53 James Li 阅读(2987) |
评论 (18)
编辑
摘要: 企业管理软件包含一些公共的组件,这些基础的组件在每个新项目立项阶段就必须考虑。核心的稳定不变功能,方便系统开发与维护,也为系统二次开发提供了诸多便利。比如通用权限管理系统,通用附件管理,通用查询等组件,若是在项目开发前就准备好了这些组件,为项目如期交付提供了保证。查询设计器 Query Design...
阅读全文
posted @
2015-07-27 08:01 James Li 阅读(3584) |
评论 (8)
编辑
摘要: 1 缓存 Cache系统中大量的用到缓存设计模式,对系统登入之后不变的数据进行缓存,不从数据库中直接读取。耗费一些内存,相比从SQL Server中再次读取数据要划算得多。缓存的基本设计模式参考下面代码:private static ConcurrentDictionary _cachedLooku...
阅读全文
posted @
2015-07-25 07:56 James Li 阅读(2617) |
评论 (7)
编辑
摘要: 数据库设计规范是个技术含量相对低的话题,只需要对标准和规范的坚持即可做到。当系统越来越庞大,严格控制数据库的设计人员,并且有一份规范书供执行参考。在程序框架中,也有一份强制性的约定,当不遵守规范时报错误。以下20个条款是我从一个超过1000个数据库表的大型ERP系统中提炼出来的设计约定,供参考。1 ...
阅读全文
posted @
2015-07-23 07:59 James Li 阅读(12209) |
评论 (77)
编辑
摘要: 1 第一次实施会议当签订合同之后,软件公司与客户约定好会议时间,双方召开第一次实施会议,确定实施的小组人员名单,项目实施周期,培训计划表,实施主计划,系统预备主文件数据准备,软件公司技术支持联系方式。2 项目实施主计划系统安装和测试:业务调研,需求匹配分析,讨论、并确定主档数据编码方案(物料编码、B...
阅读全文
posted @
2015-07-22 11:32 James Li 阅读(766) |
评论 (0)
编辑
摘要: 我对大型系统的理解,从数量上面来讲,源代码超过百万行以上,系统有超过300个以上的功能,从质量上来讲系统应该具备良好的可扩展性和可维护性,系统中的功能紧密关联。除去业务上的复杂性,如何设计这样的一个协作良好的系统,搭建开发人员基础平台,一直是我研究的方向。SouceCounter(版本3.3.91....
阅读全文
posted @
2015-07-20 07:48 James Li 阅读(4686) |
评论 (4)
编辑
摘要: 详细介绍Enterprise Solution 二次开发的流程步骤,主要包括数据输入窗体(Entry Form),查询(Query/Enquiry),报表(Report)三个重要的二次开发项目。数据输入窗体开发 Entry Form当涉及到字段的增加或增加数据库表时,开发新功能界面有以下几个主要步骤...
阅读全文
posted @
2015-07-10 11:00 James Li 阅读(356) |
评论 (0)
编辑
摘要: 列举工作以来遇到的各种类型的软件所采用的代码保护技术,只讲原理不涉及技术细节实现,以避免产生法律问题。有些朋友说直接把代码放在Github开源下载,开源可以促进技术交流与进步,然而值钱的代码都积压在硬盘里面,即使很烂的代码都卖了很多钱,赢得了许多客户与市场。珍惜爱护自己写的代码,他们都是宝贵的财富。...
阅读全文
posted @
2015-07-07 07:32 James Li 阅读(6596) |
评论 (30)
编辑
摘要: 1. 能反映企业管理的各个方面和解决企业实际的问题,不限于一般问题的解决,而是深入企业的业务过程2. 在此软件的背后有真正的管理思想(不是泛泛而言)和对管理的精髓理解 和归纳,有一个整体的较详细的规划和设计思路,能讲清楚3. 医药版 批次跟踪、效期(近效期跟踪报警)跟踪、医药库房库位管理、国家限价政...
阅读全文
posted @
2015-06-27 14:58 James Li 阅读(512) |
评论 (0)
编辑