解析大型.NET ERP系统 单据标准(新增,修改,删除,复制,打印)功能程序设计
ERP系统的单据具备标准的功能,这里的单据可翻译为Bill,Document,Entry,具备相似的工具条操作界面。通过设计可复用的基类,子类只需要继承基类窗体即可完成单据功能的程序设计。先看标准的销售合同单据界面:

本篇通过销售合同单据功能,依次讲解编程要点,供参考。
1 新增 Insert
窗体有二种状态,一种是编辑状态,别一种是数据浏览状态,区别在于编辑状态的窗体数据被修改(dirty),在窗体关闭时需要保存数据。点击工具条的新增(Insert)按钮,窗体进入编辑状态。新增状态需要对窗体所编辑的单据设置默认值。一般我们在实体映射文件中设置默认值,参考下面的例子代码:
public partial class SalesContractEntity
{
protected override void OnInitialized()
{
base.OnInitialized(); // Assign default value for new entity
if (Fields.State == EntityState.New)
{
#region DefaultValue
// __LLBLGENPRO_USER_CODE_REGION_START DefaultValue
this.Fields[(int) SalesContractFieldIndex.Closed].CurrentValue = false;
// __LLBLGENPRO_USER_CODE_REGION_END
#endregion
}
}
}
也可以考虑在窗体中做默认值设定。当遇到这样一种场景,两个功能对应同一个实体类型,则需要在界面中根据需要初始化值,参考下面的程序片段。
protected override EntityBase2 Add()
{
base.Add();
this._inventoryMovement = new InventoryMovementEntity();
this._inventoryMovement.TranType = GetStringValue(InventoryTransactionType.Movement); return this._inventoryMovement;
}
2 保存 Save
窗体基类检测到界面中的控件值被修改过,窗体状态变为编辑状态,点击保存按钮执行保存方法。保存方法的主要内容是将数据源控件(BindingSource)所绑定的控件值更新到它映射的实体中,再调用窗体保存方法保存实体。
protected override EntityBase2 Save(EntityBase2 entityToSave, EntityCollection entitiesToDelete)
{
SalesContractEntity SalesContractEntity = (SalesContractEntity)entityToSave;
this._salesContractEntity = this._salesContractEntityManager.SaveSalesContract( SalesContractEntity, entitiesToDelete, SeriesCode);
return this._salesContractEntity;
}
entityToSave是数据源控件绑定的实体类型,在保存完成后,这个值再次绑定到数据源控件中。
3 删除 Delete
窗体只有在浏览状态时,才可以点击删除按钮,删除按钮的内容是获取窗体数据源控件绑定的实体,调用窗体删除方法。
protected override void Delete(EntityBase2 entityToDelete)
{
base.Delete(entityToDelete);
SalesContractEntity SalesContractEntity = (SalesContractEntity)entityToDelete;
this._salesContractEntityManager.DeleteSalesContract(SalesContractEntity);
}
对实体的任何操作,都会跑实体验证类型,比如在保存时,需要验证主键值是否已经保存过,参考下面的代码。
public override void ValidateEntityBeforeSave(IEntityCore involvedEntity)
{
base.ValidateEntityBeforeSave(involvedEntity);
SalesContractEntity salesContract = (SalesContractEntity)involvedEntity;
if (string.IsNullOrEmpty(salesContract.ContractNo))
throw new EntityValidationException("Contract No. is required");
if (string.IsNullOrEmpty(salesContract.CustomerNo))
throw new EntityValidationException("Customer No. is required"); if (salesContract.IsNew)
{
ISalesContractManager salesContractManager = CreateProxyInstance<ISalesContractManager>();
if (salesContractManager.IsSalesContractExist(salesContract.ContractNo))
throw new RecordDuplicatedException(salesContract.ContractNo, "Cotract No. is already used");
}
}
4 复制 Clone
窗体支持两种复制方法,复制当前加载的值,复制其它对象的值。对象值复制完成后,需用重置新的对象的主键值,让它为空或是为默认值,供用户修改。复制其它对象的值需要弹出对象选择窗体。这两种复制都需要注意复制完后,重置对象初始化默认值。因为复制时采用的是深拷贝,没有跑对象初始化值。
protected override object Clone(Dictionary<string, string> refNo)
{
base.Clone(refNo); string receiptRefNo;
refNo.TryGetValue("ContractNo", out receiptRefNo); if (string.IsNullOrEmpty(receiptRefNo))
{
using (ILookupForm lookup = GetLookupForm("SalesContractLookup"))
{ if (!AllowViewAllTransaction)
lookup.PredicateBucket = new RelationPredicateBucket(SalesContractFields.CreatedBy == Shared.CurrentUser.UserId); lookup.SetCurrentValue(CurrentRefNo); if (lookup.ShowDialog() != DialogResult.OK)
return null;
receiptRefNo = lookup.GetFirstSelectionValue();
}
} if (!string.IsNullOrEmpty(receiptRefNo))
{
this._salesContractEntity = this._salesContractEntityManager.CloneSalesContract(receiptRefNo);
return this._salesContractEntity;
} return null;
}
注意到这些方法全部是以override重写的方式出现,被基类调用。每个方法都运行在后台线程控件BackgroundWorker线程中,所以都不能操作界面控件。
5 记录浏览 Record Navigator
主要用于工具条的前四个按钮,分别对应第一笔数据,前一笔数据,下一笔数据,最后一笔数据。工具条浏览需要设定窗体的NavigateBindingSource属性,传入一个空白的BindingSource控件或是一个装载页面所有数据的BindingSource控件,工具条浏览方法重写参考下面的程序片段。
protected override void InitNavigator(InitNavigatorArgs args)
{
base.InitNavigator(args);
args.SortExpression.Add(SalesContractFields.ContractNo | SortOperator.Ascending);
args.PredicateBucket.PredicateExpression.Add(SalesContractFields.Closed == false);
}
6 记录过帐 Record Post
主要用于业务单据过帐逻辑,基类的方法为空方法,不同的业务单据有不同的逻辑定义,没有可复用的代码。
protected override void Post(EntityBase2 entityToPost)
{
base.Post(entityToPost);
SalesContractEntity resignEntity = entityToPost as SalesContractEntity;
_salesContractEntityManager.PostSalesContract(resignEntity);
}
这里的过帐可以理解为确认,批核,不可更改的意思。在有些系统中叫送审,审核。
7 打印 Print
一般在设计视图绑定当前窗体对应的水晶报表文件以及要传入的参数。也可以通过重写打印方法传入传数值。
protected override void Print(ref Dictionary<string, SelectionFormula> selectionFormulas, ref List<FormulaField> formulaFields, ref List<ParameterField> parameterFields)
{
base.Print(ref selectionFormulas, ref formulaFields, ref parameterFields);
}
重写方法常用于动态指定报表文件,或是动态的参数值。不推荐在代码中这样写,这样做导致每次都需要重新编译和分发程序,推荐在水晶报表中做公式,在分发时只需要拷贝文件即可。
解析大型.NET ERP系统 单据标准(新增,修改,删除,复制,打印)功能程序设计的更多相关文章
- 解析大型.NET ERP系统 单据编码功能实现
单据编码是ERP系统中必备的功能,用于生成各种单据的流水号,常常借助于日期时间等字符来生成一个唯一的单据号码.从软件的角度来说,就是为生成数据表的主键值(参考编号),从用户的角度来说,就是给业务单据制 ...
- 解析大型.NET ERP系统 十三种界面设计模式
成熟的ERP系统的界面应该都是从模板中拷贝出来的,各类功能的界面有规律可遵循.软件界面设计模式化或是艺术性的创作,我认可前者,模式化的界面客户容易举一反三,降低学习门槛.除了一些小部分的功能界面设计特 ...
- 解析大型.NET ERP系统核心组件 查询设计器 报表设计器 窗体设计器 工作流设计器 任务计划设计器
企业管理软件包含一些公共的组件,这些基础的组件在每个新项目立项阶段就必须考虑.核心的稳定不变功能,方便系统开发与维护,也为系统二次开发提供了诸多便利.比如通用权限管理系统,通用附件管理,通用查询等组件 ...
- 解析大型.NET ERP系统架构设计 Framework+ Application 设计模式
我对大型系统的理解,从数量上面来讲,源代码超过百万行以上,系统有超过300个以上的功能,从质量上来讲系统应该具备良好的可扩展性和可维护性,系统中的功能紧密关联.除去业务上的复杂性,如何设计这样的一个协 ...
- 解析大型.NET ERP系统 权限模块设计与实现
权限模块是ERP系统的核心模块之一,完善的权限控制机制给系统增色不少.总结我接触过的权限模块,以享读者. 1 权限的简明定义 ERP权限管理用一句简单的话来说就是:谁 能否 做 那些 事. 文句 含义 ...
- 解析大型.NET ERP系统 20条数据库设计规范
数据库设计规范是个技术含量相对低的话题,只需要对标准和规范的坚持即可做到.当系统越来越庞大,严格控制数据库的设计人员,并且有一份规范书供执行参考.在程序框架中,也有一份强制性的约定,当不遵守规范时报错 ...
- 解析大型.NET ERP系统 设计异常处理模块
异常处理模块是大型系统必备的一个组件,精心设计的异常处理模块可提高系统的健壮性.下面从我理解的角度,谈谈异常处理的方方面面.我的设计仅仅限定于Windows Forms,供参考. 1 定义异常类型 . ...
- 解析大型.NET ERP系统 业务逻辑设计与实现
根据近几年的制造业软件开发经验,以我开发人员的理解角度,简要说明功能(Feature)是如何设计与实现的,供参考. 因架构的不同,技术实现上会有所差异,我的经验仅限定于Windows Form程序. ...
- 解析大型.NET ERP系统 通用附件管理功能
大型系统具备一个通用的附件管理功能,对于单据中无法清晰表达的字段,用一个附件图片或附件文档表示是最好的方法了.比如物料清单附加一张CAD图纸,销售订单评审功能中附加客户的各种表格,通用附件功能对系统起 ...
随机推荐
- Mapreduce的文件和hbase共同输入
Mapreduce的文件和hbase共同输入 package duogemap; import java.io.IOException; import org.apache.hadoop.co ...
- SQL Server2014 SP2新增的数据库克隆功能
SQL Server2014 SP2新增的数据库克隆功能 创建测试库 --创建测试数据库 create database testtest use testtest go --创建表 )) --插入数 ...
- 如何在ASP.Net创建各种3D图表
我们都知道,图表在ASP.NET技术中是一种特别受欢迎而又很重要的工具.图表是表示数据的图形,一般含有X和Y两个坐标轴.我们可以用折线,柱状,块状来表示数据.通过图表控件,我们即能表示数据又能比较各种 ...
- jsp页面无法识别el表达式的解决方案
今天在写一个springmvc的小demo时,碰到一个问题,在jsp页面中书写为${user.username}的表达式语言,在浏览器页面中仍然显示为${user.username},说明jsp根本不 ...
- ASP.NET Core 中文文档 第四章 MVC(3.7 )局部视图(partial)
原文:Partial Views 作者:Steve Smith 翻译:张海龙(jiechen).刘怡(AlexLEWIS) 校对:许登洋(Seay).何镇汐.魏美娟(初见) ASP.NET Core ...
- NPM如何更新到最新版
参考文章--npm更新到最新版本的方法 其实我们可以这样,随便新建一个文件夹例如:F:\test.按着"shift"键,右键该文件夹,选择"在此处打开命令窗口(W)&qu ...
- [转载]敏捷开发之Scrum扫盲篇
现在敏捷开发是越来越火了,人人都在谈敏捷,人人都在学习Scrum和XP... 为了不落后他人,于是我也开始学习Scrum,今天主要是对我最近阅读的相关资料,根据自己的理解,用自己的话来讲述S ...
- mysql数据库主从同步
环境: Mater: CentOS7.1 5.5.52-MariaDB 192.168.108.133 Slave: CentOS7.1 5.5.52-MariaDB 192.168. ...
- 开源发布:VS代码段快捷方式及可视化调试快速部署工具
前言: 很久前,我发过两篇文章,分别介绍自定义代码版和可视化调试: 1:Visual Studio 小技巧:自定义代码片断 2:自定义可视化调试工具(Microsoft.VisualStudio.De ...
- Visual Studio Code v0.9.1 发布
微软的跨平台编辑器 Visual Studio Code v0.9.1 已经发布,官方博客上发布文章Visual Studio Code – October Update (0.9.1):http:/ ...