ZH/Case-Study-01-Journal-32

From ADempiere
Revision as of 00:34, 14 January 2011 by Hengsin (Talk) (二楼)

Jump to: navigation, search
This Wiki is read-only for reference purposes to avoid broken links.

<返回中文首页> <返回本案例研究首页>

实施日志-32-代码开发

背景说明

  • 从项目实施到现在,我一直坚持只改数据字典(包括Rule引擎脚本代码编写),避免修改ADempiere的代码。
  • 在2011年01月03日~07日这段时间,为了实现从 询价单-RfQ 生成 采购申请单-Requistion 这个功能,我通过Rule引擎编写脚本代码,结合SQL实现。我总结认为这个方法太费劲了。
  • 接下来要实现从 采购申请单-Requistion 生成 采购订单-Purchase Order 这个功能。
    • 原本想利用现有的 org.compiere.process.RequisitionPOCreate ,即 Create PO from Requisition 过程(Process)。但是测试后发现不合适这家公司的业务需求。
    • ADempiere是在每个产品中设置首选供应商,RequisitionPOCreate 将采购申请单中的产品自动分配到相应的供应商上,并生成相应的采购订单。
    • 而这家公司的采购订单是直接使用 采购申请单 上的供应商。
  • 由于采购订单要比询价单要复杂得多,如果继续采用 Rule引擎结合SQL的方式来实现,难度就更大了。于是接受Albert的建议,准备修改代码。
    • 基于原有的类-RequisitionPOCreate,新建类- org.compiere.process.RequisitionPOCreateSimple。
    • 通过 customization.jar 来布署。
  • 由于我是初次涉及 ADempiere 代码,实施过程中不正确的地方请大家加以指正!

2010-01-08

RequisitionPOCreateSimple

  • 基于原有的类-RequisitionPOCreate,新建类- org.compiere.process.RequisitionPOCreateSimple。
  • 去掉的代码:
// 方法.newLine() 原有代码:
//	Get Business Partner
int C_BPartner_ID = rLine.getC_BPartner_ID();
if (C_BPartner_ID != 0)
{
	;
}
else if (rLine.getC_Charge_ID() != 0)
{
	MCharge charge = MCharge.get(getCtx(), rLine.getC_Charge_ID());
	C_BPartner_ID = charge.getC_BPartner_ID();
	if (C_BPartner_ID == 0)
	{
		throw new AdempiereUserError("No Vendor for Charge " + charge.getName());
	}
}
else
{
	// Find Strategic Vendor for Product
	// TODO: refactor
	MProductPO[] ppos = MProductPO.getOfProduct(getCtx(), product.getM_Product_ID(), null);
	for (int i = 0; i < ppos.length; i++)
	{
		if (ppos[i].isCurrentVendor() && ppos[i].getC_BPartner_ID() != 0)
		{
			C_BPartner_ID = ppos[i].getC_BPartner_ID();
			break;
		}
	}
	if (C_BPartner_ID == 0 && ppos.length > 0)
	{
		C_BPartner_ID = ppos[0].getC_BPartner_ID();
	}
	if (C_BPartner_ID == 0)
	{
		throw new NoVendorForProductException(product.getName());
	}
}
  • 增加的代码:
private int	req_C_BPartner_ID = 0;

req_C_BPartner_ID=req.get_ValueAsInt("C_BPartner_ID");  // 在方法 doIt() 中加入

  • 修改的代码:
/* 方法.newLine() 原有代码:
//	New Order - Different Vendor
if (m_order == null 
	|| m_order.getC_BPartner_ID() != C_BPartner_ID
	|| m_order.getDatePromised().compareTo(rLine.getDateRequired()) != 0
	)
{
	newOrder(rLine, C_BPartner_ID);
}
*/ 
// 现改为:
C_BPartner_ID= req_C_BPartner_ID ;
if (m_order == null 
	|| m_order.getDatePromised().compareTo(rLine.getDateRequired()) != 0
	)
{
	newOrder(rLine, C_BPartner_ID);
}

获取当前登录用户的ID

  • 获取当前登录用户的ID,已经测试通过。代码如下:
import org.compiere.util.Env;
...

int cur_user_id = Env.getContextAsInt(Env.getCtx(), "#AD_User_ID");
System.out.println("Get current user id:"+ cur_user_id);

讨论栏

一楼-代码修改是必不可少的

  • 如果真的修改代码,那么就正规点来做,自己建立svn 服务器,将trunk download下来,做自己的版本管理。然后建立测试服务器,利用2pack以及customjar或者ant重新完整编译更新项目,从而形成完备的代码管理。
  • 事实上如果想真正的实施个性化的adempiere,代码修改是必不可少的,call out 的 script编写由于不能跟踪,对复杂的流程编写基本失效,同时由于保存在数据库中导致代码散乱,基本在实际工程中使用的次数不多,应该说真是看上去很美。 --aoslee, 16:23, 12 January 2011.

二楼

  • 谢谢aoslee的建议! 自己建立SVN服务这个建议不错。
  • 同时,我认为script脚本还是有可取之处的。由于脚本不需要 RUN_setup.sh,布署起来更方便一些,对于简单的程序还是可以胜任的。我认为2000个字符以内的程序可以优先考虑用脚本来实现,超过4000字符的就应当采用代码编译。 --Peanut Blake, 16:23, 14 January 2011.
  • Avoid callout script if possible. The problem is not complexity of coding but debugging so it is a typical short term gain, long term loss scenario. You don't need RUN_setup.sh during development so that's not a big deal either. Hengsin 07:34, 14 January 2011 (UTC)

链接

About this page

  • This page is about code development in Case Study 01