收藏 分销(赏)

ADempiere编程开发者手册.pdf

上传人:曲**** 文档编号:9217937 上传时间:2025-03-17 格式:PDF 页数:92 大小:2.64MB 下载积分:12 金币
下载 相关 举报
ADempiere编程开发者手册.pdf_第1页
第1页 / 共92页
ADempiere编程开发者手册.pdf_第2页
第2页 / 共92页


点击查看更多>>
资源描述
开发者手册The Adempiere Bazaar开发者手册The ADempiere Bazaar9s Sourcecode Expose2/5/2009Kevin D.J White,Mario Calderon,Norbert Wessel and others(from the Spanish account of Victor Perez,then into Genman)Developers GuideThe ADempiere Bazaars Sourcecode Expose1/9/2008Mario Calderon,Norbert Wessel and others(from the Spanish account of Victor Perez,then into German)Copyright 2009 Kevin D.J White Mario Calderon,Victor Perez,Norbert Wessel et alPagel开发者手册 The Adempiere Bazaar内容目录Class piere.util.GenerateModel.4Java-Beans.6持久化弓I擎(Persistency-Engine).7piere.model.PO.7类 POInfb.11类 POInfbColumn.13业务对象类.14Doc Action 接口.17MDocType 类.19X_C_DocType 类.20单据工作流(公文流转)Documents Workflow.21DocumentEngine 类.21MWFActivity(Workflow Activity 工作流活动)类.23MWorkflow 类.23MWorkflow 类.28ModelValidationEngine 类.29Vdoc Action 类.30菜单操作显示一个窗口.32APanel 类.34类 processModalDialog.34MWFprocess 类.37类 Workflowprocessor.38类 MWFNode.39类 processCtl.40发货清单Invoice预览.42PrintFormat.58类 PrintData.59工作流窗口.61窗 口 Report&Process(Window Report&Process).64Callouts.69上下文值的验证.72会计处理机制.74Doc 类.74类 Fact.77类 FactLine.78DocTypes 和 DocBaseTypes.79应用程序字典:账务报告.80Price lists(价格表).83价格计算.84支付条款.86视图 RV_C_INVOICE,RV_OPENITEM.86Db中关于仓库结构说明.89属性集实例.91Copyright 2009 Kevin D.J White Mario Calderon,Victor Perez,Norbert Wessel et alPage2开发者手册 The Adempiere BazaarIf you teCC the truth you dont have to remember anything.-Mark TwainIt is not enoughjust to earn and now,6utyou ought to possess and own it-AristotleI hope to free my followers from clinging to styles,patterns,or molds-Bruce Lee,commenting on his Kung Fu J?question may 6e in the future tense,and so it cannot 6e answered just yet-Redl,when asked why things arent doneADEMPIERE开发者文档前言本文主要内容是ADempiere类是如何组织的,这些类之间又是如何交互从而实现设 计功能的。文章安排比较随意,只是尽力做到每一个章节为一个完整的内容,理解 上不需要太多其他章节内容的支持。本文不是完整的单据,只是ADempiere的基础单据,我们希望社区里广泛使用本文,欢迎修正与加强。本文目的是使一个具备JAVA基础知识并理解ADempiere基础功能的开发人员在读后 可以开发、定制自己的系统,并为ADempiere的改进做出贡献。本文写于2007年8月,在我游览厄瓜多尔后。在那里,Victor Petez在一次7天 ADempiere核心研究会上告诉我。在本文中增加了我写的ADempiere其他方面的内容,最后成文德语80余页,感谢 Metas协会的Norbert Wessel和Mor itz Weber将本文原稿翻译为英文版)感谢 Karsten Thiemann的备注,也感谢制作Doc Wiki Book的人。真诚希望本文成为适用于开发人员指导手册的根据。Mario Calderon圣萨尔瓦多,2007年11月26日译者序说到ADempiere,不得不先说Compiere,Compiere ERP&CRM为全球范围内的中小型 企业提供综合型解决方案,覆盖从客户管理、供应链到财务管理的全部领域,支持 多组织、多币种、多会计模式、多成本计算、多语种、多税制等国际化特性。易于 安装、易于实施、易于使用。只需要短短几个小时,您就可以使用申购-采购-发票-付款、报价-订单-发票-收款、产品与定价、资产管理、客户关系、供应商关系、员工关系、经营业绩分析等强大功能了。Copyright 2009 Kevin D.J White Mario Calderon,Victor Perez,Norbert Wessel et alPage3开发者手册The Adempiere BazaarCompiere目前已经不完全开源)官方更新比较慢,ADempiere从Compiete发展而来,目前是Sourceforge开源项目组织排名第一的开源项目,设计规范,更新快,是中 小型企业ERP系统用户的非常好的选择,相对Compiere来说,Adempiere开放了更 多的文档,使得开发者更容易上手,相信这也是ADempiere为什么受到越来越多人 关注的关键之一。笔者有多年0A系统的开发经验,主要是基于Lotus ND系统,几年前转入J2EE做中 小型专业搜索引擎,对ERP的研究并不多,此次翻译ADempiete系统的部分单据,主要是为了学习。本文档从德文翻译成英文,笔者又从英文译为中文,加之笔者经 验不足,译文中不足之处请大家批评指正,Kevin D.J WhiteClass piere.util.GenerateModel包 package org.adempiere.utilpublic class GenerateModelAdempiere持久层主要类是PO.java,在这个抽象类中定义了 load(),save(),delete(),get_ID()等方法。每个持久对象(数据库中的一个表)都是P0.java的扩展,这样做是为了让每个持 久对象包含全部持久化功能(虽然在有些情况下不需要这样做,但是这样做并没有 坏的影响)。针对扩展P0.java的X_*类(定义在应用程序字典AD中的所有表)ADempiere提供一个类来生成这些类的代码,这样做一方面是便于扩展,另一方面 X.*类的大多数方法只是setter与getter,在ADempiere 3.3.0前由piere.ut i 1.GenerateModel()实现,在 3.3.0 版本后由 org.adempiere.util.GenerateModel 实现,现在 ADempiere 不只是生成 X_*类的代码,还可以生成X_*类实现的屋*接口的代码。要实现全功能(仅持久化方面)的持久x 对象,ADempiere提供了这些方法。在最新的Adempiere wiki教程中的有这样一个实例,创建一个表存储原材料信息,如果只需要store/load数据到一个ADempiere窗口,我们不需要创建一个M_*类,只是生成一个X_XX_Mater ial.java就足够了。给定的实例中,MMater-ial.java 增加了通过给定的mater ialno和colorno获取一个MMaterial x对象的一些功能,给定一组属性值从数据库中读取x对象或所有x对象在M_*类中仅仅是一个最普通 的功能。这只是一个例子,我们不需要为我们的x对象实现这一类的功能。GenerateModel.java 中如果不输入或输入错误路径会报错,所以最好是改写GenerateModel.javaCopyright 2009 Kevin D.J White Mario Calderon,Victor Perez,Norbert Wessel et alPage4开发者手册The Adempiere Bazaar1)缺省路径改为我们用的路径2)可选-改写包名字3)可选-在97行增加实体类型如“D”(Dictionary字典)无参数运行GenerateModel main()方法生成 java beans(X.xxxxxx,java 如 e.g.e.g.X_C_Invoice.Java)o main。方法从AD_Table表中读取数据表数据,并为每个表的每个列 生成get-与set-代码。也可以生成单一 beans Adempiere源代码中这些文件保存在piere.model中 编译过的 GenerateModel.class 文件保存在./adempiere.trunk/base/build/org/compiere/util 可以使用参数配置输出在eclipse中选中main。方法,点击鼠标右键,点击上下文菜单中的“run”在弹出的窗口中输入参数 参数0:文件夹(Folder)生成的文件要拷贝到的位置,缺省值为aC:WAdempiereW adempiere-al lextendsrcadempieremodel55svn trunk 41/adempiere.trunk/extend/src/compiere/model/参数1:Package包名字)生成的java bean文件的包名字,缺省 为 compiere.model”参数2:实体类型(用户自定义,Adempiere,Dietionaty等等),GenerateModel 中只定义 了 User 与 Application,象 Adempiere 需 要在这里输入,注意:用户自定义(User-def ined)在今后的版 本上将保持。缺省值为“,U,A 参数3:tabelle,要生成的java bean相关的表的名字,缺省为加 表示所有数据库表也可以改写代码来改变参数缺省值当应用程序字典中的数据库表变化时X-files 一定要重新生成从版本 3.3.0 开始,/Adempiere/adempiere_trunk/base/src/org/adempiere/util/GenerateModelJPA.java类来完成上述任务,这个类生成的JAVA文件没有X.Copyright 2009 Kevin D.J White Mario Calderon,Victor Perez,Norbert Wessel et alPage5开发者手册 The Adempiere Bazaar前缀,在部署前必须重命名。Java-BeansBean特点:都是POJOs 每个业务对象对应一个java bean bean连接源代码与数据库数据,帮助开发者避免直接访问数据,或者说 保证Table Ids或列名称信息写死在系统里,如:bp.getM_Pr iceList_ID(),Bus inessPartner 对象返回价格清单的 id 都放在piere.model包内,这个包放置所有javabean类和业务 逻辑类 javabean类声明如:public class X-C-Invoice extends PO一些方法在PO(持久化对象定义piere.model.PO)类中实现如 所有继承的构造器调用javabean类P0的构造器(super(ctx,rs,trxName)或 super(ctx5 C_Invoice_ID,trxName)s鳍江c小加1属性TableJD保存数据库表的ID,如:public sta tic final int Table_ID=MTable.getTable-ID(Table-Name);protected static属性 Modeh 如:protected sta tic KeyNamePair Model=new KeyNamePair(Table.ID,Table-Name);static final accessLevel,在数据库表创建时定义的值(Client,Organisation,Client+Organisation,等等)如:protected BigDecimal accessLevel=BigDecimal.ValueOf(1);AD.ORGTRX.ID_AD.Reference.ID,字典中的 ID 方法:initPO由调用链上一个PO构造器调用(PO(Properties ctx,int ID,Copyright 2009 Kevin D.J White Mario Calderon,Victor Perez,Norbert Wessel et alPage6开发者手册The Adempiere BazaarString trxName,ResultSet rs)toString(返回类字符串如 CLInvoice:X.C.Invoice)compare。或 log.info(toString()调用 数据库表所有列的get-与set-方法例夕卜:processing,processed,Created,Created孙等歹在 PO 类的load方法中创建,load方法调用loadDefaults()/setStandradDefaul ts 0 o getDocSta tus()setDocSta tus()Mise 所有基类和bean都是同一个包的一部分,这样可以通过调用构造 器创建一个对象 Date日期由Timestamp控制 Boolean值是长度为1的字符串(Y=TRUE,N=FALSE),查询布尔 值时,没有get方法,请使用象isApptovedO的方法 不同的包内还有更多的bean,本文将逐步介绍如MWFActivi-ty,MWFNode,MWFprocess,MDocType,MWorkflow0 也有部分 javabean并没有与业务对象相关联,如:public class X_AD_WF_Activity extends PO此类为MWFActivity的帮助类public class MWFActivity extends X_AD_WF_Activity implements Runnable Adempiere中Beans和PO 一起实现持久化 Beans保存数据 P0提供持久化机制支持持久 化引擎(Pers i stency-Engine)piere.model.POAdempiere.PO持久化类提供DB迁移方法同时调用触发器和模型有效性验证(Triggers model validators)public abstract class PO implements Serializable,Comparator,EvaluateeCopyright 2009 Kevin D.J White Mario Calderon,Victor Perez,Norbert Wessel et alPage7开发者手册 The Adempiere Bazaar Serializable对象流输出 ComparatorPO 实现了 compare()与 equals()方法 Evaluate实现 get.ValueAsString()方法,此方法被 piere.util.Evaluator.evaluateLogicTuple()调用,tupels Sxxxx可定义在应用程序字典(AD)中,可评估。类继承:Adempiere 类如 Minvoice 继承 X_C_Invoice5 X_C.Invoice 类继承 PO public class Minvoice extends X-C-Invoice implements DocAct ion public class X-C-Invoice extends PO重要的构造器:根构造器最后调用public PO(Properties ctx,int ID,String trxName,ResultSet rs)若参数ID值为0,创建一个新的实例。若事务(transaction)为null,创建一个新的piere.util.Trx类中的static方法控制事务 新事务创建时Trx设置一个随机名称Trx.createTrxName()创建一个新的事务Trx.createTrxName(“Cost”)获取当前事务名称Trx.get(trxName,True)若名称为trxName的事务不存在且第二个参数为True,创建一个 事务Trx.get(trxName,True)在trx.get中创建一个新的事务retValue=new Trx(trxName)Copyright 2009 Kevin D.J White Mario Calderon,Victor Perez,Norbert Wessel et alPage8开发者手册 The Adempiere Bazaar 设置事务名称保证所有DB保存的同样名称的事务在提交和 rollback操作时作为同一个事务来控制根构造器调用:load(int ID,String trxName)若ID和事务已知 ID0通过SQL语句检索所有列值并写入实例 ID=0新对象创建私有属性m_createNew获取值True,对象知道这是创建一个新对 象歹1 processing,processed,Created,CreatedBy 等通过调用 loadDefaults()创建若需要子类中可以定义loadComplete(boolean success),目前没用 load(ResultSet rs)load(int ID,String trxName)的最后调用 load(ResultSet rs)这种情况使用一个结果集创建对象,取结果集的当前位置,无导航指针 构造器 PO(Properties ctx,int ID,String trxName)MBPartner bp=new MBPar tner(1 ine.getCtx()5 1 ine.getC.BPar tner-ID(),1 ine.get.TrxName();构造器 PO(Properties ctx,ResultSet rs,String trxName)Po中的其他方法 public final Object get.Value(String columnName)检查列是否激活若列激活,调用get_Value(int index),该方法返回nunewValues indexo参考 Propert iex set.ValueNoCheck(String ColumnName,Object Value)不经过检查获取列ColumnName值Copyright 2009 Kevin D.J White Mario Calderon,Victor Perez,Norbert Wessel et alPage9开发者手册 The Adempiere BazaarValue可以截取,在这种情况下,用户输入到程序中的值会被缩短保存,长度 定义在Adempiere的AD(应用程序字典)中下面的方法只在本章介绍,在继承P0的子类中不再说明 delete()删除一个对象,特定情况下,使用ModelValidationEngine确认events delete.Tree()删除 ID-Trees save()子类实例保存检查是否是新对象,组织在save。中还调用另外的一些方法:beforeSave()多数情况下由业务类象Minvoice,Mproduct等等实现 saveNew()保存新对象 saveUpdate()保存已有的对象变化跟踪创建一个session变量Msession session=MSession.get(p.ctx,false)若值变更)数据库表MChangeLog保存变更前后的状态:MchangeLog cLog=session.changeLogAdempiere中必须做一些配置:定义一个数据库表保存日志,Adempiere可以在数据库表显示的窗口显示变更日志,双击窗口右 下方(右键点击显示数据库的窗口的右下角)系统显示如下内容:数据库表名称 创建表的时间与人员 修改表的时间与人员 变更日志 saveNewO 与 saveUpdate()最后调用 saveFinish(),saveFinish()调用 af terSave()。Copyright 2009 Kevin D.J White Mario Calderon,Victor Perez,Norbert Wessel et alPage10开发者手册 The Adempiere BazaarbeforeSave()与 af terSave()方法通常在业务类如 Minvoice,Mproduce 等中 实现Po的属性 POInfo p.info()列信息由p-info提供p.info值由根构造器提取p_info=initPO(ctx)子类实现initPO(),查看POInfo类列信息:调用 get_Value(Columnname”),该方法调用 get_V用ue(intindex);该方法返回 m.newValues index o(若 m_newValues=nul 1,则返回 m_oldValues index)protected transient Clogger log=CLogger.getCLogger(getClass()显示子类在系统控制台输出使用private static Clogger s_log=CLogger.getCLogger(PO.class);显示PO类在系统控制台输出 private Doc m_doc private Object m.IDs=new Object 口 I_ZER0/数据集的 ID private Object m_oldValues=nul 1;/旧值 private Object m_newValues=nul 1;/新值 private Mattachment m_attachment=nul1;等等类 POInfoPackage piere.modelpublic class POInfo implements SerializablePOInfo类提供访问POInfoColumn实例的方法 包含业务对象列信息 可序列化(导出功能用)属性(不完整列表)m_AD.Table.ID m_TableNameCopyright 2009 Kevin D.J White Mario Calderon,Victor Perez,Norbert Wessel et alPage11开发者手册The Adempiere Bazaar m_AccessLevel POInfoColumn m_columns private Properties m_ctx=nul1方法(不完整列表)使用索引处理m_column属性构造器POInfo(Propertiex ctx,int AD_Table_ID5 boolean baseLanguage-Only)调用loadinfo(),该方法做一些转换:使用构成数据库表的SQL语句 AD.Table t AD_Column c AD_Val_rule vr AD.Element eSQL:m_AD_TableD 的参数为每个列创建POInfoColumn实例,并用SQL数据填充 t.TableName c.ColumnName c.AD.Ref erence.ID c.IsMandatory c.IsYpdateable c.DefaultValue e.Name,e.Description c.AD_Column_ID c.IsKey c.IsParent c.AD.Reference_Value_ID vr.Code c.FiIdLength c.ValueMinCopyright 2009 Kevin D.J White Mario Calderon,Victor Perez,Norbert Wessel et alPage12开发者手册The Adempiere Bazaarc.ValueMax c.IsTranslated t.AccessLevel c.ColumnSQL c.IsEncrypted所有列信息拷贝到m_columns数据库表AD_Element_TRL用于事务和选择语言 public static POInfo getPOInfo(Properties ctx,int AD_Table_ ID)调用构造器,getPOInf。()本身在in造P0()(在JAVABEAN内部)中被调用,P0构造器调用initPO()o getColumnName(int index)isColumnMandatory(int index)String getColumnDescription(int index)getColumnCount()Class getColumnClass(int index)类 POInfoColumnpackage piere.modelpublic class POInfoColumn implements Serializable包含业务对象一个列的信息属性(公共)AD.Column.ID ColumnName ColumnSQL DisplayType ColumnClass IsMandatory Def aultLogic IsUpdateable ColumnLabelCopyright 2009 Kevin D.J White Mario Calderon,Victor Perez,Norbert Wessel et alPage13开发者手册The Adempiere Bazaar ColumnDescription AD.Reference_Value_ID VaiidationCode FieldLength ValueMin ValueMax ValueMin.BD ValueMax.BD方法 IsKey IsParent IsTranslated isUpdateable toString IsEncrypted POInfoColumn,Po 与 beans(X_*类)的关系 POInfoColumn实例包含业务对象属性信息(列)BEANS(业务对象类)包含数据 P0管理数据获取与存储业务对象类Package piere.modelAdempiere包含两类业务对象类工作流业务对象类业务对象类在工作流(workflow)中调用,因此这些类一定要满足工作流的 需求,同时还要满足业务需求如:Minvoice,Morder类定义public class Minvoice extends X_C_Invoice implements DocActionDocAction接口使得类实现realize(识别)一个工作流的方法,这些Copyright 2009 Kevin D.J White Mario Calderon,Victor Perez,Norbert Wessel et alPage14开发者手册The Adempiere Bazaar方法从按钮触发,按钮定义在窗口里数据库表与列信息定义在Adempiere的AD(应用程序字典)中,根据 DocAction的当前状态和下一个状态来调用相关的方法。更多信息参考工作流章节下列方法查询状态设置actions preparelt()ModelVal idationEngine 进行 Events 的有效性验证类ModelVal idat ionEngine用于识别常规业务(buss iness)逻辑 这里同时捕捉并执行监听events,定义相关的单据状态和单据类 型,并调用其他方法常规类定义在客户端窗口(client window),Field验证类有效 性,Libero中可以找到一个自验证有效性的类的例子。Completelt()通过ModelValidationEngine,Events 可以被其他 Events 验证 approve!t()等等公文工作流类定义了属性private String m.processMsg,该属性在相 关窗口的左下方显示信息如PeriodClosed实现实际业务逻辑交互的方法,如在Minvoice中:val idat ePay Schedule()testAl location()getOpenAmt()等等业务对象主要(Master)数据,如在MProduct中 public class Mproduct extends X_M_Product 无实现部分 识别实际业务逻辑的方法,如在MProduct中 isProductStocked()isOneAssetPerUOM()getAttributeSet()等根据类用途来定义类的属性Copyright 2009 Kevin D.J White Mario Calderon,Victor Perez,Norbert Wessel et alPage15开发者手册The Adempiere Bazaar所有业务对象实现触发方法 beforeSave()数据存储前的动作 af terSave()数据存储后的动作 beforeDelete()数据删除前的动作 af terDelete()数据删除后的动作根据用途不同业务类实现不同的构造器如:标准构造器MlnvoiceLine(Properties ctx,int C_InvoiceLine_ID5 String trxName)Minvoice to=new Minvoice(f rom.getCtx()5 0,nul 1);public MProduct(X_I_Product impP)Mproduct类支持产品导入时使用的构造器,对象impP的值用于设 置产品的属性。类 importProduct 与 X_I_Product 或 VaiidateModel 类影响导入功 能 业务类通常实现静态方法get(),返回其类对象数组如:public static MProduct get(Properties ctx,String whereClause,String trxName)业务类中实现一个属性记录日志,输出到系统控制台private static Clogger s.log=CLogger.getCLogger(Mproduct.class);业务各实现一个对象cache private static CCache s_cache=new CCache(-Invoice11,20,2);/2minutes cache中对象数据(20)与生存周期(2分钟)对每个对象来说都 不同 piere.util.CacheMgt 通过应用服务器管理 CacheCopyright 2009 Kevin D.J White Mario Calderon,Victor Perez,Norbert Wessel et alPage16开发者手册The Adempiere Bazaar业务逻辑下面介绍基于Minvoice,preparelt()的功能步骤:Model验证(如果有)参考 ModelValidation 章节 基于 C_DocTypeTarget_ID”获取 DocumentType 的一个实例 基于DocBaseType检查是否打开 行验证 检查 cashbooks 检查或设置DocType BOM扩展 Tax(税务)计算 每行 Landed Costs 首先添加所有成本,分布到所有行 在一行中所有成本分配给产品 MinvoiceLine al locateLandedCosts()调用 MlnvoiceLine getBase(),这里没有实现计算 LANDEDCOSTDISTRIBUTION-Costs验证 set DocActionDocAct ion 接 口Package piere.processpublic interface DocAction 工作流业务对象实现方法定义在DocAction,如:public class Minvoice extends X_C_Invoice implements DocAct ion.实现 DocAct ion 接口的 BO(业务对象)称为Document(单据),最终情况依赖于对象 approvel t()isApproved属性设置为true closelt()此操作后没有其他活动Copyright 2009 Kevin D.J White Mario Calderon,Victor Perez,Norbert Wessel et alPage17开发者手册The Adempiere Bazaar inval idatel t()preparelt()执行前准备 processlt()执行业务逻辑 reActivatelt()调用closelt()后的单据可以通过reActivatelt()重新激活这依赖于对象类型:一个订单可以重新激活,而一份发货清单不可以 reject11()reverseAccrulIt()reverseCorrectlt()在会计模块中生成条目(entries),要实现此功能,需要一份原始单 据的拷贝 unlocklt()没有locklto方法,通常是单据在工作流中出现故障,由系统管理员通 过按钮或菜单解锁,将单据的状态退回前一个状态或重新启动单据工作 流 voidlt()定义静态属性(String常量)活动与状态(actions与states)ACTION.Complete ACTION.Close STATUS-Drafted STATUS-Completed 等各种各样的方法 getApprovalamt()getCtx()记录的ID getDocAct ion()getDocStatus()返回定义在static f inal Property中的状态Copyright 2009 Kevin D.J White Mario Calderon,Victor Perez,Norbert Wessel et alPage18开发者手册The Adempiere Bazaar getDocumentlnfo()单据类型名称与单据数量 getDocumentNo()getDoc_User_ID()控制序列如:Selling-Purchase-Payment-No.getprocessMsg()返回属性m_processMsg的值 get.TrxName()save()setDocStatus()设置单据状态)单据状态定义在static
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服