Sponsored Development:Data Import Validator

From ADempiere
Revision as of 10:26, 7 May 2009 by Teo sarca (Talk) (Vote for inclusion in Trunk)

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

Proposal

We need to define import validators which will be called during data import process. This functionality is really needed in case you added more fields to target model (e.g. C_BPartner, AD_User) and you want to import them from your import model (e.g. I_BPartner).

Project Team

Sponsors

Teo Sarca, http://www.arhipac.ro

Tutorial

Here is an example about how to import more fields for C_BPartner model. We introduced C_BPartner.LRO_CAEN_ID which is a classification code specific to Romania. We also have the LRO_CAEN table where we store all codes. In out import table (I_BPartner) we introduced following columns: LRO_CAEN_ID (the ID) and LRO_CAEN_Value (the CAEN Key) which will be imported from CSV file. Now we want to fill I_BPartner.LRO_CAEN_ID field based on LRO_CAEN_Value and then BPartner import, we want to set C_BPartner.LRO_CAEN_ID. For this, we need to do following steps...

Define ImportValidator

 public class MyBPartnerImportValidator implements ImportValidator
 {
 	public static final String ImportTableName = X_I_BPartner.Table_Name;
 
 	@Override
 	public void validate(ImportProcess process, Object importModel, Object targetModel, int timing)
 	{
 		X_I_BPartner impBP = (X_I_BPartner)importModel;
 		if (timing == TIMING_AFTER_VALIDATE)
 		{
 			StringBuffer sql = new StringBuffer ("UPDATE I_BPartner i "
 				+ "SET LRO_CAEN_ID=(SELECT LRO_CAEN_ID FROM LRO_CAEN c"
 				+ " WHERE i.LRO_CAEN_Value=c.Value AND c.AD_Client_ID=i.AD_Client_ID) "
 				+ "WHERE LRO_CAEN_ID IS NULL"
 				+ " AND I_IsImported<>'Y'").append(process.getWhereClause());
 			no = DB.executeUpdate(sql.toString(), process.get_TrxName());
 			log.fine("Update LRO_CAEN #" + no);
 		}
 		else if (targetModel instanceof MBPartner && TIMING_AFTER_IMPORT == timing)
 		{
 			MBPartner bp = (MBPartner)targetModel;
 			bp.setCustomField1(impBP.getCustomField1());
 		}
 		else if (targetModel instanceof MBPartnerLocation && TIMING_AFTER_IMPORT == timing)
 		{
 			MBPartnerLocation bpl = (MBPartnerLocation)targetModel;
 			bpl.setCustomField2(impBP.getCustomField2());
 		}
 		else if (targetModel instanceof MUser && TIMING_AFTER_IMPORT == timing)
 		{
 			MUser user = (MUser)targetModel;
 			user.setCustomField3(impBP.getCustomField3());
 		}
 	}
 }

Register your import validator

public class MyValidator implements ModelValidator
{
	...
	@Override
	public void initialize(ModelValidationEngine engine, MClient client)
	{
		...
		// Register Import Validators
		engine.addImportValidate(MyBPartnerImportValidator.ImportTableName, new MyBPartnerImportValidator());
	}
	...
}

The End

Ready! Your import process is customized.

Functional Specs

We introduced following interfaces:

  • ImportValidator - all import validator whould implement this interface. This interface also defines the import timings:
    • TIMING_BEFORE_VALIDATE - Event triggered before all import records are validated
    • TIMING_AFTER_VALIDATE - Event triggered after all import records are validated
    • TIMING_BEFORE_IMPORT - Event triggered before an import record is processed
    • TIMING_AFTER_IMPORT - Event triggered after an import record is processed
  • ImportProcess - all processes that are doing import jobs (e.g. ImportBPartner) should implement this interface. Main enforced methods are:
    • getImportTableName - return the name of the targeted import table (e.g. I_BPartner)
    • getWhereClause - SQL where clause which filters only candidated import records (e.g. AD_Client_ID=11)
    • getCtx - get context - we already have this method in SvrProcess
    • get_TrxName - get transaction name - we already have this method in SvrProcess

We extended ModelValidationEngine and added following methods:

  • addImportValidate (String importTableName, ImportValidator listener)
  • fireImportValidate (ImportProcess process, PO importModel, PO targetModel, int timing)

We alterned import processes to implement ImportProcess interface AND to fire proper events using ModelValidationEngine.fireImportValidate .


References

Vote for inclusion in Trunk