ZH/Case-Study-01-Journal-03
From ADempiere
This Wiki is read-only for reference purposes to avoid broken links.
Contents
实施日志-03
- 本文属于ADempiere ERP现实案例研究之一。
- 本文记录ADempiere ERP项目实施的过程
2010年12月
2010-12-02
JasperReport父子表问题
JasperReport父子表在客户端(Client)上的布署
- 今天用ireport建立父子报表,即包含子报表(subreport)的报表。在ireport上可以正常显示,但是在adempiere客户端却无法显示(系统报错代码附在后面)。
- 第二天把这个问题解决了,发现是iReport的版本问题。
- ADempiere 3.6.0 LTS 集成的JasperReport版本是3.7.3。而我用的iReport版本是3.7.6。今天重新下载了iReport-3.7.3,父子报表经编译后,在客户端(Client)可以正常显示。
JasperReport父子表在Web服务器上的布署
- JasperReport父子表在Web服务器上的布署,在官方文档上发现子报表需要额外编译。Problem_with_subreports
- 看过这篇文档后存在几点疑问:
- 这个是以网页访问(WebApp)为例子的,对于客户端(Client)访问是否有效?
- 第4步复制编译好的Jasper文件。原文摘录如下:
- Step 4: Copy the new subreport compiled file
- Now you must copy the new compiled file to the location as you need. In the example we will copy
- From: C:\Documents and Settings\Alejandro\Configuración local\Temp\
- To : D:\Adempiere\jboss\server\adempiere\deploy\WebApp.ear\webApp.war\
- 对于第4步有三点疑问:
- Windows操作系统下编译好的文件放置在C:\...\Temp\目录下,Linux操作系统下在什么目录?
- 不使用org.compiere.report.ReportStarter,而是使用iReport进行编译,是否可行?
- 文件复制的目标目录Adempiere\jboss\server\adempiere\deploy\WebApp.ear\webApp.war\没有找到。我能找到的相类似的目录是/home/media/adempiere/jboss/server/adempiere/deploy/jboss-web.deployer,我应该放在哪个目录下?我是否应当建立目录../WebApp.ear/webApp.war/?
ADempiere执行JasperReport报错代码
- ADempiere ERP 3.6.0 客户端执行经iReport 3.7.6编译后的父子报表,报错代码如下:
CCache.clear - java.beans.PropertyVetoException: Skip reset for trx entries cache [INFO] Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 2, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> AdempiereDS, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> org.postgresql.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> z8kfsx8c1axcccl1kdzo6b|277b5f00, idleConnectionTestPeriod -> 1200, initialPoolSize -> 1, jdbcUrl -> jdbc:postgresql://localhost:5432/adempiere?encoding=UNICODE, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 900, maxIdleTimeExcessConnections -> 1200, maxPoolSize -> 15, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 1, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> SELECT Version FROM AD_System, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ] Exception in thread "jasper simple-1000069" java.lang.NoClassDefFoundError: org/codehaus/groovy/runtime/callsite/CallSiteArray at salescontract_1291337525218_186281.$createCallSiteArray(calculator_salescontract_1291337525218_186281) at salescontract_1291337525218_186281.$getCallSiteArray(calculator_salescontract_1291337525218_186281) at salescontract_1291337525218_186281.<init>(calculator_salescontract_1291337525218_186281) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:513) at java.lang.Class.newInstance0(Class.java:355) at java.lang.Class.newInstance(Class.java:308) at net.sf.jasperreports.engine.design.JRAbstractJavaCompiler.loadEvaluator(JRAbstractJavaCompiler.java:98) at net.sf.jasperreports.engine.design.JRAbstractCompiler.loadEvaluator(JRAbstractCompiler.java:320) at net.sf.jasperreports.engine.JasperCompileManager.loadEvaluator(JasperCompileManager.java:240) at net.sf.jasperreports.engine.fill.JRFillDataset.createCalculator(JRFillDataset.java:421) at net.sf.jasperreports.engine.fill.JRBaseFiller.<init>(JRBaseFiller.java:428) at net.sf.jasperreports.engine.fill.JRVerticalFiller.<init>(JRVerticalFiller.java:76) at net.sf.jasperreports.engine.fill.JRVerticalFiller.<init>(JRVerticalFiller.java:86) at net.sf.jasperreports.engine.fill.JRVerticalFiller.<init>(JRVerticalFiller.java:56) at net.sf.jasperreports.engine.fill.JRFiller.createFiller(JRFiller.java:142) at net.sf.jasperreports.engine.fill.JRFiller.fillReport(JRFiller.java:52) at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:417) at org.compiere.report.ReportStarter.startProcess(ReportStarter.java:561) at org.adempiere.util.ProcessUtil.startJavaProcess(ProcessUtil.java:160) at org.adempiere.util.ProcessUtil.startJavaProcess(ProcessUtil.java:105) at org.compiere.apps.ProcessCtl.startProcess(ProcessCtl.java:649) at org.compiere.apps.ProcessCtl.run(ProcessCtl.java:432) at java.lang.Thread.run(Thread.java:662) Caused by: java.lang.ClassNotFoundException: org.codehaus.groovy.runtime.callsite.CallSiteArray at java.lang.ClassLoader.findClass(ClassLoader.java:359) at java.lang.ClassLoader.loadClass(ClassLoader.java:307) at java.lang.ClassLoader.loadClass(ClassLoader.java:248) ... 26 more
讨论栏
2010-12-03
JasperReport大写金额的问题
- 父子表的问题解决了之后,今天用iReport来制作报表还算顺利。只是遇到中文大写金额的问题。
- 找到一篇文章在JasperReport报表中加入大写金额,不知道能否在ADempiere下实现。有空再试试。
数据格式问题
今天发现几个问题:
1. 用电子表格向数据库导入数据时,要注意电子表格的字段类型的设定,尤其是以数字表示的字符。今天发现有个reference的其中几下拉选项无法选择,查找发现是电子表格的数字“1”导入到数据库后变成了“1.0”,导致ad_ref_list无法以value来匹配。
2. 在数据库新增字符型字段时,要注意区分固定长度字符和非固定长度字符的设定。比如我之前设定“合同编号”(Contract No)时就设定为固定长度:
ALTER TABLE c_order ADD ContractNo character(12);
结果发现实际输入合同编号不足12位时,数据库会自动补足空格,在报表中很不美观。于是改为:
ALTER TABLE c_order ALTER ContractNo TYPE character varying(12);
讨论栏
2010-12-09
销售订单窗口优化调整
- 对销售订单窗口进行了优化:
- 主要是关闭了不用的选项、设置Field Group、设置默认值。
- 在Document Type里把不需要的Sales Order Type改为禁用。
销售合同的报表格式调整
- 已经把销售合同的报表格式调整到位。
- 主要解决了以下问题:
- 页码问题。需要设置好Page_Number的有效范围。
- 文本框随内容自动调整高度问题;
- sub-report相对路径问题;
- 金额合计问题。需要新建变量,并设置好生效范围;
- ADempiere与JasperReports参数传递问题。
- 避免文本框跨页分断问题。将Band: Detail 1的属性Split Allowed设置为False。
- 文本框NULL值问题。将文本框属性Blank when Null设置为True。
几点发现
- 发现用Import Product窗口不但可以导入产品信息,还可以导入产品价格表,非常方便。
- 发现登录用户名也是大小写敏感的,同时也可以用中文用户名登录。
- Sales Order当中Sales Representative的设置: 要同时设置User和Business Partner,并关联起来。
Address的Country默认值设置
- 在Business Partner窗口的Location页签有个Address字段,点击右侧小图标会弹出一个"Add New Location/Address"或"Update Location/Address"窗口,这窗口找不到设置的地方。
- 我的目的是把Location/Address的Country默认值设置为China。
- 我尝试过通过"Window, Tab & Field"窗口、"Table & Column"窗口,设置Country字段的Default Logic,均告无效。
- 后来发现这是系统内建的,这样处理很不方便。
This window is made manual. This is the class for it: VLocationDialog
讨论栏
Organization设置
疑问:Organization设置为Tongji Org与*有什么区别?感觉会影响到Sales Order里的Price List显示。
2010-12-13
销售订单实施小结
- 这段时间主要进行销售订单窗口和销售合同报表的制作。前后大约花费了15天左右的时间,主要用在:
- 销售订单窗口字段的增减和设置;
- JasperReports的探索;
- 对销售合同进行分析,并进行报表制作。
困难:销售合同没有标准化
- 实施当中最为困难的是该企业的销售合同没有标准化。主要表现在以下几个方面:
- 销售合同格式没有标准化
- 语言不统一。存在纯中文、纯英文、中文+英文三种形式。
- 合同条款数目不固定,增减无常。
- 同一条款在不同合同中写法各不相同,某些内容(即字段)的显示和隐藏没有固定规律。
- 产品型号栏目格式不统一,存在以下三种形式:产品型号+中文名称,产品型号+英文名称, 产品型号+中文名称+英文名称。同时还存在是否添加产品图片的区别,这样一来就有六种形式。
- 销售合同条款内容(或选项)没有标准化
- 许多字段内容变化太多,以下拉列表显示的选项总是存在许多的例外。
- 例如付款条件(Payment Term),除了3:7、3:6:1等方式外,还存在许多其它特殊的付款条件,这样同时还带来财务上的许多麻烦(无论财务模块使用的是ADempiere的还是其它财务软件的)。当然付款条件多变的背后,反映了合同评审缺乏公司财务部门的严格把关。
- 文档标准化是ERP成功实施的基本前提
- 对于变化无常的合同格式,如果花费太多的精力去提供相应的报表格式,是毫无价值的工作。
- 因此该项目实施只提供最基本格式的中文模板。用户如需进行格式或内容上的更改,就导出为*.ODT格式自行修改。
- 对于销售合同的最佳解决方案是:标准的销售订单 + 灵活可变的合同附加条款。当然该企业要采纳这样的方案还需要一段过程。
客户端布署
- 今天在Windows操作系统上进行了客户端布署。
- 客户端数据连接、JasperReports父子报表均测试通过。
- 布署要点:
- 安装JRE 1.6。注意:ADempiere 3.6.0是基于Java 1.6的。
- 设置好系统环境变量:JAVA_HOME, ADEMPIERE_HOME。
讨论栏
2010-12-15
采购及入库实施规划
- 今天开始实施采购及入库。
- 主要目标:
- 采购、入库的流程畅通;
- 采购报表3~5张;
- 主要流程:
- 采购申请 --> 采购 --> 入库。
- 采购外协流程——在ERP的实现 (PDF文件)
主要工作
- 采购及入库的流程梳理和确认。
- 表单格式的标准化及确认。由于采购合同尚未标准化,暂不实施。
- 要求采购部门提前整理数据,包括物料信息、供应商信息、价格表。实施顾问提供数据整理标准格式。
- 考察用友T3仓库模块,并建立数据接口。
实施难点
- 物料编码的问题。
- 物料编码不全面。目前只有自制半成品、成品有物料编码,钢材、机械标准件、电气元件等原材料均无物料编码。
- 技术部门尚无专人负责物料编码。
- 用友T3当中原有物料均以物料名称汉字拼字首字母作物料编码。
- 审批流程。
- 单据转化。
- 采购申请单 --> 采购订单 --> 入库单。
需求调研汇集
- 采购合同一般由供方代拟。约20%的采购合同由需方撰写。
- 现有采购申请单行数太少,不够写。
- 现有入库单没有留出检验员签字的地方。
- 采购订单增加付款方式一栏,可以选择现金、支票、转账等。
- 在入库单上同时显示税前单价和税后单价,以便财务核算。
- 希望增加采购日程表,以便追踪采购进度。
讨论栏
入库单显示价格
> 在入库单上同时显示税前单价和税后单价,以便财务核算。
- 采购发票如果和采购订单价格不一致怎么办? --Robin
- 发票价格是最后实际成交价格,与订单定价不一致很正常啊,就是与入库单价格不一致都应该属正常。 --lcl
- 采购发票如果和采购订单价格不一致,这种情况要看合计金额,如果合计金额不相同,就会打回发票重开。因为采购价格是经过审批的,如果以发票价格为最后实际成交价格,前面的审批就是摆设了。--Peanut
- 如果成交价格<审批价格呢?不知道有没有这种情况? --小卢
- 会有这种情况,但是财务上是不会通过的。 --Peanut
- 据我所知,AD/Compiere 在入库单中是不记录价格的。--Robin
- 入库单不记录价格,但是可以在打印格式中显示价格。--Peanut
- 入库结算后得反写价格在入库单才行,不然出库核算材料成本数据来源哪里? --朱胜利
- 可以依据采购平均价格。在Accounting Schema里的Costing Method设置。--Peanut
采购日程表
> 希望增加采购日程表,以便追踪采购进度。
- 采购日程表是运输公司的日程表吗? -- Robin
- 没有这么复杂,主要是下单日期、预计到货日期之类的。--Peanut
2010-12-16
初步探索
- 把资料采购计划单的导入放在下一步进行,先基于ADempiere的原有功能。
- RfQ(询价单)窗口
- RfQ(询价单)窗口的三个页签分属三个表:C_RfQ, C_RfQLine, C_RfQLineQty。
- 同时Quantity页签是Line的子页签。我考虑把Quantity页签合并到Line页签上,因为这家公司的询价没有这么复杂。
- RfQ Response(询价反馈)窗口
- RfQ Response(询价反馈单)窗口的三个页签也是分属三个表:C_RfQResponse, C_RfQResponseLine, C_RfQResponseLineQty。
- 考虑关闭RfQ Response窗口,将询价反馈并入RfQ窗口。
- Read Only(只读)字段:
- RfQ Response窗口有好几个字段无法填写,包括Response页签的RfQ字段,Response Line页签RfQ Line字段,Response Quantity的RfQ Line Quantity字段。
- 检查发现系统默认设置居然是Read Only。
- 把Read Only去掉之后,发现RfQ Line字段和RfQ Line Quantity字段的下拉选项居然可以跨RfQ。不知道RfQ Response是否尚处测试版本?
Rule Engine与脚本
- 今天开始学习和探索Rule Engine(引擎)的Script(脚本编程)。
- 主要目的:从于从RfQ(询价单)创建Purchase Request(采购申请)。
- 介绍:ADempiere的Rule窗口可以写脚本,集成了BeanShell。
- ADempiere的Rule Engine要用到BeanShell,于是了解了一下BeanShell。
- 相关链接:
讨论栏
2010-12-17
Rule Engine下写脚本
- 今天把Rule Engine(引擎)的Script弄清楚了。
- Script Callout主要用于窗体,Script Process主要用于Process。
- 对于从 询价单 生成 采购申请单,可以利用Script Process执行SQL语句来实现。
org.compiere.util.DB.executeUpdate(sql, A_TrxName);
脚本使用体会
- 优点:脚本的功能很强大。同时脚本既不需要重新编译ADempiere源代码,也不需要重新布署ADempiere服务器,因为脚本规则都存储在数据库中了。
- 缺点:不容易进行错误调试。我今天测试的Script当中有个SQL语句语法错误,居然没有任何报错。
对Rule Engine的疑问
- Rule Engine为什么要区分成不同Event Type?比如Callout与Process,为什么不合并在一起?
- Rule Engine的Rule Type为什么是JSR 223 Scripting APIs,而不是BeanShell官方网站上JSR 274?
- A_TrxName的TrxName是什么意思?
- Rule Engine中能否实现弹出对话框?代码什么?
- 后来找到一段代码,不过尚未测试:
javax.swing.JOptionPane.showMessageDialog(null,"Doing something in Callout!");
价格表查看权限问题
- 今天发现存在价格表查看权限问题
- 系统中主要有两类价格表:一类是销售价格表,另一类是采购价格表;
- 销售价格表一般来说是商业机密,只能让相关的人员查看。
- 应当如何设置才能让不同的角色看不同的价格表?
讨论栏
2010-12-19
采购询价的实施计划
RfQ Response窗口
- 关闭RfQ Response(询价反馈)窗口,并入RfQ(询价)窗口。
RfQ窗口
- RfQ页签:
- Business Partner增加到两个,用于向供应商询价;
- 增加字段:是否有现货,交货期,询价单发送日期,询价反馈单签收日期;
- 增加功能:生成 Requistion(采购申请单);需要新增按钮和编写脚本;
- Line页签:
- 增加数量相关字段:计量单位、数量;
- 增加报价反馈相关字段:报价1、报价备注1、报价2、报价备注2;
- Quantity页签:
- 关闭Quantity页签,并入到Line页签。
- 总体:
- 窗口优化:关闭不用的字段,将常用字段进行合理排布。
RfQ报表
- 制作询价单报表。
- 利用JasperReports制作。