Sponsored Development:Data Import Validator

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


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


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


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;
 	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 "
 				+ " WHERE i.LRO_CAEN_Value=c.Value AND c.AD_Client_ID=i.AD_Client_ID) "
 				+ " 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;
 		else if (targetModel instanceof MBPartnerLocation && TIMING_AFTER_IMPORT == timing)
 			MBPartnerLocation bpl = (MBPartnerLocation)targetModel;
 		else if (targetModel instanceof MUser && TIMING_AFTER_IMPORT == timing)
 			MUser user = (MUser)targetModel;

Register your import validator

public class MyValidator implements ModelValidator
	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 .