ZH/Case-Study-01-Journal-23

From ADempiere
Revision as of 01:47, 17 March 2011 by Peanutblake (Talk) (输入框实现可弹出搜索框)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
This Wiki is read-only for reference purposes to avoid broken links.

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

实施日志-23-基于数据字典的二次开发

2010-11-13

关于Boolean数据类型

我有个疑问,ADempiere数据表为什么不用Boolean数据类型,而是用character(1)?

例如C_Order数据表当中的字段isactive:

 isactive character(1) NOT NULL DEFAULT 'Y'::bpchar


2010-12-09

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

2010-12-29

Referece下拉列表与Dynamic Validation

  • 今天把 Dynamic Validation 略为弄懂了一些,之前一直是糊里糊涂的。
  • 通过Referece实现下拉列表,我的总结是 Dynamic Validation 要通过 Reference Key 才起作用。不知道我这样理解是否正确?
  • ADempiere里有一个例子,是采购申请单( Requistion )中的 AD_User_ID 的字段。
  1. 打开 Table and Column 窗口,找到 Requistion 表。在 Column 页签中找到 AD_User_ID 字段:
    1. Reference: Table
    2. Reference Key: AD_User
    3. Dynamic Validation: AD_User - Internal
  2. 打开 Validation窗口 ( 也可以在Dynamic Validation直接Zoom过去):
    1. Name: AD_User - Internal
    2. Type: SQL
    3. Validation code: EXISTS (SELECT * FROM C_BPartner bp WHERE AD_User.C_BPartner_ID=bp.C_BPartner_ID AND (bp.IsEmployee='Y' OR bp.IsSalesRep='Y'))

记录锁定与Processed

  • 在 RfQ(采购申请)窗口中,按下 Close RfQ 按钮后,字段 Processed 就由 'N' 变为 'Y',再接着该记录就变为锁定了。
  • 我很好奇 Processed='Y'后与记录锁定是怎么关联起来的?是否存在必然联系?
  • 接下来我在新建了 C_Department 表及 Department 窗口,
  • SQL语句如下:
-- Create Department Table
CREATE TABLE c_department
(
  ad_client_id numeric(10,0) NOT NULL,
  ad_org_id numeric(10,0) NOT NULL,
  isactive character(1) NOT NULL DEFAULT 'Y'::bpchar,
  created timestamp without time zone NOT NULL DEFAULT now(),
  createdby numeric(10,0) NOT NULL,
  updated timestamp without time zone NOT NULL DEFAULT now(),
  updatedby numeric(10,0) NOT NULL,
  c_department_id numeric(10,0) NOT NULL PRIMARY KEY,
  "name" character varying(60) NOT NULL,
  description character varying(255),
  c_upperdepartment_id numeric(10,0),
  processed character(1) NOT NULL DEFAULT 'N'::bpchar,
);
  • 接着在 Window, Tab & Field 窗口进行测试:
    1. WindowType 无直接关系,选为 TransactionMaintain 均可。
    2. Sales Transaction 无直接关系,是否勾选均可。
    • 备注:每一步都先执行过 Cache Reset 。
  • 于是可以得出结论,Processed 字段是 ADempiere 系统内置的记录锁定标记。如果某些表需要对记录进行锁定,只要在相应的表增加 Processed 字段,通过手工勾选、写脚本或写代码重新编译等方式,将某条记录的Processed 字段设置为'Y',该记录即被锁定。

讨论-关于记录锁定与Processed

一楼-Albert的意见

  • <<台灣支持團隊 Albert Skype: ADempiere/Compiere 建議>>
  • setProcessed(true) 這是每一個 model 都需要去寫的東西 
  • 以下是 Shipment/Receipt completeIt() 成立紀錄的程序片段

		m_processMsg = info.toString();
		setProcessed(true);
		setDocAction(DOCACTION_Close);
		return DocAction.STATUS_Completed;
	}	//completeIt

	/**
	 * 	Set Processed.
	 * 	Propagate to Lines/Taxes
	 *	@param processed processed
	 */
	public void setProcessed (boolean processed)
	{
		super.setProcessed (processed);
		if (get_ID() == 0)
			return;
		String sql = "UPDATE M_InOutLine SET Processed='"
			+ (processed ? "Y" : "N")
			+ "' WHERE M_InOut_ID=" + getM_InOut_ID();
		int noLine = DB.executeUpdate(sql, get_TrxName());
		m_lines = null;
		log.fine(processed + " - Lines=" + noLine);
	}	//	setProcessed
  • 研究軟件:研究學問:要謹慎嚴謹:多方求證.
  • 民雄附近有國立大學外圍關聯機構也有研究要以此幫遠東機械上線
  • 我要幫他忙當他們機構的顧問, 那機構號稱有一群大學研究生跟教授,想自己用猜的想自己空手屠龍
  • 紮實研究讀遍 SourceCode 確保成功

二楼-Peanut的回复

  • Albert大人说的是 ADempiere 具体是怎么把 Processed 字段变成 'Y' 值的。
  • 我之前讨论的是 Processed='Y' 之后 与 记录锁定 是否存在必然联系,即使在新建的表中。大概是我之前的表述不清楚,现在已经略作补充了。 :-)
  • 最后要感谢Albert大人的关心和严格要求!
-- Peanut Blake. Jan 02, 2010.


2010-12-30

Rfq新增记录保存报错

  • 今天测试遇到一个问题:Rfq新增记录保存报错。
  • 在Console终端的报错信息如下:
-----------> MIssue.set_ValueNoCheck: ReleaseNo - Value too long - truncated to length=4 [13]
===========> DB.executeUpdate: INSERT INTO C_RfQ_Trl (AD_Language,C_RfQ_ID, IsRfQResponseAccepted, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.C_RfQ_ID, t.IsRfQResponseAccepted, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, C_RfQ t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.C_RfQ_ID=1000010 AND NOT EXISTS (SELECT * FROM C_RfQ_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.C_RfQ_ID=t.C_RfQ_ID) [POSave_73b8fd54-16b2-439b-9cc7-59064da0b6f4] [13]
org.postgresql.util.PSQLException: ERROR: relation "c_rfq_trl" does not exist
  Position: 13; State=42P01; ErrorCode=0
	at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2062)
	at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1795)
	at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
	... ...

===========> DB.saveError: DBExecuteError - ERROR: relation "c_rfq_trl" does not exist
  Position: 13 [13]


  • 出现 "INSERT INTO C_RfQ_Trl" ,很是莫名其妙。于是仔细检查了一遍 Window 和 Table 设置,发现 IsRfQResponseAccepted 字段的 Translated 项勾选上了。(备注:IsRfQResponseAccepted 是我新增的字段 )
  • 问题可能就在这里,于是去除勾选,进行测试。OK,问题解决。
  • 原因:当Translated 项勾选上了,与此同时相应的翻译表还尚未建立,当你新增纪录并保存时,你就会看到类似这样的报错信息:“错误:关系"c_rfq_trl"不存在”。
  • 报错截图:

Column Translated Checkbox Error.png

  • 设置截图:

Column Translated Checkbox Setting.png


EN:Record Saving Error with Translated Checkbox

  • If "Translated" is checked, but the corresponding translation table has not been created yet, you will get an error like "ERROR: relation "c_rfq_trl" does not exist" when you create and save a new record.


2011-03-17

输入框实现可弹出搜索框

  • 这段时间在为市场部开发询盘跟踪的小功能。
  • 需要新增两个窗体:询盘跟踪窗体、询盘客户信息窗体。
  • 需要新增三个数据表:c_inquiry, c_inquiryline, c_inquirycustomer(询盘客户信息)
  • 另建询盘客户信息窗体是为了简化询盘跟踪的快速录入。而且如果共用c_bpartner表,会导致c_bpartner表中会增加太多的无关数据。
  • 在询盘跟踪窗体中有一个字段是询盘客户,希望能实现搜索功能,也就是像销售订单窗体中业务伙伴字段一样,可以弹出一个搜索窗体。
  • 经过一番设置后,点击搜索时报错:Error: No Info Columns。报错代码如下:
-----------> Msg.translate: NOT found: C_InquiryCustomer [11]
-----------> MIssue.set_ValueNoCheck: ReleaseNo - Value too long - truncated to length=4 [11]
===========> InfoGeneral.initInfoTable: No Info for AD_Table_ID=1000003 - SELECT c.ColumnName, c.AD_Reference_ID, c.IsKey, 
f.IsDisplayed, c.AD_Reference_Value_ID, c.ColumnSql FROM AD_Column c INNER JOIN AD_Table t ON (c.AD_Table_ID=t.AD_Table_ID) 
INNER JOIN AD_Tab tab ON (t.AD_Window_ID=tab.AD_Window_ID) INNER JOIN AD_Field f ON (tab.AD_Tab_ID=f.AD_Tab_ID AND
 f.AD_Column_ID=c.AD_Column_ID) WHERE t.AD_Table_ID=?  AND (c.IsKey='Y' OR  (f.IsEncrypted='N' AND f.ObscureType IS NULL)) 
ORDER BY c.IsKey DESC, f.SeqNo [11]
  • 分析了其中的SQL语句,发现原来是ad_table表中的ad_window_id要设置,也就是Table窗体当中的Window字段要设置。于是进行设置,搜索功能终于实现了。
  • 不过这里发现弹出的搜索框当中,列表标题有一部分是英文,一开始以为是Window窗口Field Translation页签没有设置好,后来发现是在Element窗口里要进行翻译。于是在Element窗口中对各字段逐一设置,终于实现了全中文显示。
  • 后来在wiki上找到两篇关于搜索框的介绍:

链接