Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

This section describes the importing and exporting mechanism. Importing and exporting are both considered process runs. For more information on implementing process runs, go to Implement Process Run Definition.

Create Import Processes

To create an import process, you need to:

  1. Define the import process in the imports.xml metadata file.
    1. Define import parameters.
  2. Create the template file defined in the imports.xml metadata file for the import process.
  3. Create a process class extending extending the abstract class com.crm.process.CRMImportBeanCRMCustomImportBean, responsible for parsing the file and processing its records and define this process in and implement the three abstract methods of this class. Also, define this class in the modules.xml metadata file.

1. Imports Metadata File

The import process must be defined in the imports.xml metadata file, as shown in the example below. The metadata file can be located under the <custom_project>/src/main/resources/metadatadirectory. Note that all of the information except importdescription and importparameters must be defined in the file.

Code Block
languagejava
themeEclipse
titleimports.xml
collapsetrue
<importsconfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/imports.xsd">
	<imports>
		...
		
		<import>
			<importname>Custom Import</importname>
			<importdescription>Custom Import in CRM.COM.</importdescription>
			<importprocess>CUSTOM_IMPORT</importprocess>
			<importmodule>CUSTOM</importmodule>
			<importtemplatefilepath>imports/customTemplateFile.csv</importtemplatefilepath>
		</import>

		...
	</imports>
</importsconfig>

2. Template File

The template file will be used as an example for the file used by the import process and can be downloaded from the import data entry page. The file must be placed under the directory defined in the imports.xml metadata file, with the importtemplatefilepath tag.

3. Import Process class

A process class must be created for the import process, extending com.crm.process.CRMImportBean. Below, you can see the implementation of an example import process class. It is recommended to use the LogTextFile method to log the import process results for easier debugging of the process.

Code Block
languagejava
themeEclipse
titleEXAMPLEImportBean
collapsetrue
public class EXAMPLEImportBean extends CRMImportBean { 
 
...
 public void import(String processRunLogID) throws Exception{
        
		CallList.LogTextFile(getCRMSession(), "Example Import start processing (" + processRunLogID + ")", "importExample","");

        CRMDOProcessRunLog processRun = (CRMDOProcessRunLog)processRunLogBean.load(processRunLogID);        
        ArrayList<CRMDO> attachments = attachmentBean.load(processRun);
        
        processRun.setStatus(ProcessRunLogStatus.IN_PROGRESS);
        processRun.setStartDate(getCurrentDate());
        processRunLogBean.save(processRun);
        
        Boolean processComplete = new Boolean(false);
    	ProcessRunLogStatus processRunLogStatus = null;

        try
        {
            for (int i=0;i<attachents.size();i++)
            {
                CRMDOAttachment attachment = (CRMDOAttachment)attachments.get(i);
                String[] tokens = StringUtil.split(attachment.getFileName(),".");
                String extension = tokens[tokens.length-1];
                
                SupportedImportFileExtensions[] supportedImportFileExtensions = SupportedImportFileExtensions.values();
                
                for (int j=0; j<supportedImportFileExtensions.length; j++)
                {
                    SupportedImportFileExtensions supportedImportFileExtension = supportedImportFileExtensions[j];
                    if (supportedImportFileExtension.isSupported(extension))
                    {
                        if (supportedImportFileExtension.equals(SupportedImportFileExtensions.EXCEL))
                        {
                            importEXCEL(attachment,processRun,extension);
                        }
                        else if (supportedImportFileExtension.equals(SupportedImportFileExtensions.CSV))
                        {
                            importCSV(attachment,processRun);
                        }
                        else if (supportedImportFileExtension.equals(SupportedImportFileExtensions.XML))
                        {
                            importXML(attachment,processRun);
                        }
                    }
                }
            }
            
            processComplete = new Boolean(true);
        }
        catch (Exception e)
        {
			CallList.LogTextFile(getCRMSession(), "Error on processing import (" + processRunLogID + ")" + ExceptionUtil.getStackTrace(e), "importExample","");
            saveEntityLogRecord(processRun,"", "",ProcessRunLogEntityStatus.FAILED,e.getClass().getSimpleName(),ExceptionUtil.getStackTrace(e));
            processRun.setStatus(ProcessRunLogStatus.FAILED);
            processRunLogBean.save(processRun);
        }
        
        if (processComplete)
        {
            processRun.setStatus(processRunLogStatus);
            processRun.setEndDate(getCurrentDate());
            processRunLogBean.save(processRun);
        }

		CallList.LogTextFile(getCRMSession(), "Example Import end processing (" + processRunLogID + ")", "importExample","");
    }
...
}

Next, you must define this process class and the method that will be called for the import in the modules.xml metadata file, which can be found under the <custom_project>/src/main/resources/metadata/ directory. Note that the <importprocess> and <importmodule> defined in the imports.xml file will be used in the modules.xml metadata file to correcty define the process class. The <importprocess> will be used as the process id and the <importmodule> as the module id, as shown belowThe processes defined in this file will appear in the Imports page, under Foundation > Utilities and you can view and edit their process run definition through this page. The tags that can be used to define an import process are:

  • importname: This is the name of the import process and it is mandatory
  • importdescription: This is the description of the import process and it is optional
  • importprocess: This is the process id, as defined in the modules.xml file and it is mandatory
  • importmodule: This is the module id, as defined in the modules.xml file and it is mandatory
  • importtemplatefilepath: This is the path where the import file template can be found and it is mandatory
  • importfileheaders: This is a string which contains the import file headers, comma separated and it is mandatory
  • importparameters: These are the import parameters and it is optional to define them.

a. Import parameters

The import parameters can be defined in the metadata file to enable the user to give some default values to the respective parameters of the template file. If import parameters are defined, the user will be able to set their values through the import definition data entry page. The import parameters are mapped to the template file's parameters through the <importparametername>, which must be the same as the name of the header of the respective parameter in the template file. So, based on the example below, the template file must have columns with headers custom_parameter1 and custom_parameter2. When defining the import parameters, it is mandatory to define all the information for them. The <importparameterkey> is the label that will appear for the parameter in the data entry page and the <importparametertype> is the type of the parameter and it can be one of the following: java.lang.String, text, java.lang.Integer, java.math.BigDecimal, java.util.Date, password, java.lang.Boolean and enum. If enum is defined as the type, then an additional tag must be defined, the <importparameterclassname>, which indicates the class of the import parameter.

Code Block
languagejava
themeEclipse
titleimports.xml
collapsetrue
<importsconfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/imports.xsd">
	<imports>
		...
		
		<import>
			<importname>Custom Import</importname>
			<importdescription>Custom Import in CRM.COM.</importdescription>
			<importprocess>CUSTOM_IMPORT_PROCESS</importprocess>
			<importmodule>CUSTOM_IMPORT</importmodule>
			<importtemplatefilepath>imports/customTemplateFile.csv</importtemplatefilepath>
			<importfileheaders>header1,header2,etc</importfileheaders>
			<importparameters>
				<importparameter>
					<importparametername>custom_parameter1</importparametername>
					<importparameterkey>key_custom_parameter1</importparameterkey>
					<importparametertype>java.math.BigDecimal</importparametertype>
				</importparameter>
				<importparameter>
					<importparametername>custom_parameter2</importparametername>
					<importparameterkey>key_custom_parameter2</importparameterkey>
					<importparametertype>enum</importparametertype>
					<importparameterclassname>com.crm.dataobject.contactinfo.AddressTypes</importparameterclassname>
				</importparameter>
				...
			</importparameters>
		</import>

		...
	</imports>
</importsconfig>

2. Template File

The template file will be used as an example for the file used by the import process and can be downloaded from the import data entry page. The file must be placed under the directory defined with the importtemplatefilepath tag in the imports.xml metadata file.

3. Import Process class

A process class must be created for the import process, extending com.crm.process.CRMCustomImportBean and the three abstract methods defined in this class must be implemented. These methods are called with the order shown below for each line of the import file and they are used to construct the data object to be imported from the file line, validate that the object's information is correct and save the dataobject. In more detail, the methods are:

  • constructData. This method accepts the import parameters and the record values as parameters and returns a data object. The import parameters are a HashMap containing the parameters defined in the imports.xml metadata file with their values. The record values are a HashMap containing the headers of the import file with their corresponding values. as defined in the file line. The method must construct a dataobject from the given values and return it.
  • validateData. This method accepts a dataobject, validates it and returns it. If the dataobject is not valid the method must throw the relevant Exceptions.
  • saveData. This method accepts a dataobject, saves it and returns it.

  Note that the process class must be bean managed. Below, you can see the implementation of an example import process class.

Code Block
languagejava
themeEclipse
titleEXAMPLEImportBean
collapsetrue
...
@Stateless(mappedName = "ejb/EXAMPLEImport")
@LocalBean
@TransactionManagement(TransactionManagementType.BEAN)
public class EXAMPLEImportBean extends CRMCustomImportBean { 
 
	private static final long serialVersionUID = 1L;

	@EJB private EXAMPLEObjectBean exampleDataObjectBean;

	...

 	@Override
 	public CRMDO constructData(HashMap<String, String> importParameters, HashMap<String, String> recordValues) throws Exception {
    	    
		//get all values either from import parameters or from record values	
    	if (recordValues.get("name")==null) 
		{
    		throw new MandatoryFieldException(getCRMSession(), "name");
		}
    	
    	if (recordValues.get("alt_code")==null) 
		{
    		throw new MandatoryFieldException(getCRMSession(), "alt_code");
		}
    	
    	String type = null;
    	if(importParameters!=null && importParameters.containsKey("type"))
    	{
    		type = importParameters.get("type");
    	}
    	else 
    	{
    		type = recordValues.get("type");
    		
    	}
    	if (type==null) 
		{
    		throw new MandatoryFieldException(getCRMSession(), "type");
		}  

		String name = recordValues.get("name");
		String alt_code = recordValues.get("alt_code"); 	

		...
			
    	  		
		//construct dataobject and set the values on it
		CRMDO exampleDataObject = exampleDataObjectBean.construct();
		exampleDataObject.setName(name);
		exampleDataObject.setAltCode(alt_code);
		exampleDataObject.setType(customerEventType);
		...

		return exampleDataObject;
	}

	@Override
	public CRMDO validateData(CRMDO data) throws Exception {
		return exampleDataObjectBean.validateOnSave(data);
	}


	@Override
	public CRMDO saveData(CRMDO data) throws Exception {
		return exampleDataObjectBean.save(data);
	}  
} 


Next, you must define this process class in the modules.xml metadata file, which can be found under the <custom_project>/src/main/resources/metadata/ directory. Note that the <importprocess> and <importmodule> defined in the imports.xml file will be used in the modules.xml metadata file to correctly define the process class. The <importprocess> will be used as the process id and the <importmodule> as the module id, as shown below. It is mandatory to define the importProcess method, as shown below. This is the method that is called on submitting the import and it is implemented in the abstract CRMCustomImportBean class.

Code Block
languagejava
themeEclipse
titlemodules.xml
collapsetrue
<?xml version="1.0" encoding="UTF-8"?>
<moduleconfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:noNamespaceSchemaLocation="../xsd/modules.xsd">
	<modules>		

	...
		
		<module>
			<moduleid>CUSTOM_IMPORT</moduleid>
			<modulename>key_custom_import</modulename>
			<moduledescription>key_custom_import</moduledescription>
			
			...
						
			<features>		
				<feature>
					...

					<commonprocesses/>
					
					<additionalprocesses>
						<process>
							<id>CUSTOM_IMPORT_PROCESS</id>
							<name>key_custom_import</name>
							<description>key_custom_import</description>
							<methods>
								<method>
									<ejbname>EXAMPLEImportBean</ejbname>
									<methodname>importProcess</methodname>
									<scheduled>false</scheduled>
								</method>
							</methods>
							<batch>true</batch>
							<csrincluded>true</csrincluded>
						</process>
						...
					</additionalprocesses>
				</feature>
			</features>
			
			...
		</module>

		...
	</modules>
</moduleconfig>

Create Export Processes

To create an export process, you need to:

  1. Define the export process in the exports.xml metadata file.
    1. Define export criteria.
  2. Create a process class extending com.crm.process.CRMCustomExportBean, responsible for creating the export file.

1. Exports Metadata File

The export process must be defined in the exports.xml metadata file, as shown in the example below. The metadata file can be located under the <custom_project>/src/main/resources/metadatadirectory. Note that all of the information except exportdescription and exportcriteria must be defined in the file. The processes defined in this file will appear in the Exports page, under Foundation > Utilities and you can view their process run logs and submit them through this page. The tags that can be used to define an export process are:

  • exportname: This is the name of the export process and it is mandatory
  • exportdescription: This is the description of the exportprocess and it is optional
  • exportprocess: This is the process id, as defined in the modules.xml file and it is mandatory
  • exportmodule: This is the module id, as defined in the modules.xml file and it is mandatory
  • importtemplatefilepath: This is the path where the import file template can be found and it is mandatory
  • exportfileheaders: This is a string which contains the headers of the export file that will be created, comma separated and it is mandatory
  • exportcriteria: These are the export criteria and it is optional to define them.

a. Export Criteria

The export criteria can be defined in the metadata file to enable the user to use some criteria that the entities that will be exported must meet. If export criteria are defined in the metadata file, these criteria will appear on the export's data entry page and the user will be able to define values for that criteria. When defining the export criteria, it is mandatory to define all the information for them. The <exportcriterionname> is the criterion name, the <exportcriterionkey> is the label that will appear for the criterion in the data entry page and the <exportcriteriontype> is the type of the criterion and it can be one of the following: java.lang.String, text, java.lang.Integer, java.math.BigDecimal, java.util.Date, password, java.lang.Boolean and enum. If enum is defined as the type, then an additional tag must be defined, the <exportcriterionclassname>, which indicates the class of the export criterion.

Note that the fileFormat export criterion must be defined, as shown below, if you want to enable the user to choose the format of the file that will be exported.

Code Block
languagejava
themeEclipse
titlemodulesexports.xml
collapsetrue
<?xml version="1.0" encoding="UTF-8"?>
<moduleconfig xmlns:xsi="http:<exportsconfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 	xsi:noNamespaceSchemaLocation="../xsd/modulesexports.xsd">
	<modules>	<exports>
	

	...

		<export>
		<module>	<exportname>Custom Export</exportname>
			<moduleid>CUSTOM</moduleid><exportdescription>Custom Export in CRM.COM.</exportdescription>
			<modulename>key<exportprocess>CUSTOM_customEXPORT_import<PROCESS</modulename>exportprocess>
			<moduledescription>key<exportmodule>CUSTOM_custom_import<EXPORT</moduledescription>exportmodule>
			<exportfileheaders>header1,header2,etc</exportfileheaders>
			...<exportcriteria>
						<exportcriterion>
			<features>		<exportcriterionname>fileFormat</exportcriterionname>
				<feature>	<exportcriterionkey>key_file_format</exportcriterionkey>
					...

<exportcriteriontype>enum</exportcriteriontype>
					<commonprocesses/><exportcriterionclassname>com.crm.dataobject.ExportFileFormat</exportcriterionclassname>
				</exportcriterion>	
					<additionalprocesses>
						<process><exportcriterion>
							<id>CUSTOM<exportcriterionname>custom_IMPORT<criterion1</id>exportcriterionname>
							<name>key<exportcriterionkey>key_custom_import<criterion1</name>exportcriterionkey>
							<description>key_custom_import</description><exportcriteriontype>java.lang.String</exportcriteriontype>
				</exportcriterion>
			<methods>	<exportcriterion>
					<exportcriterionname>custom_criterion2</exportcriterionname>
			<method>
		<exportcriterionkey>key_custom_criterion2</exportcriterionkey>
							<ejbname>EXAMPLEImportBean<<exportcriteriontype>enum</ejbname>exportcriteriontype>
					<exportcriterionclassname>com.crm.dataobject.contactinfo.AddressTypes</exportcriterionclassname>
				<methodname>import<</methodname>exportcriterion>
									<scheduled>false</scheduled>
					...
			</method>exportcriteria>
							</methods>
							<batch>true</batch>
							<csrincluded>true</csrincluded>
						</process>
						export>

		...
					</additionalprocesses>
				</feature>
			</features>
			
			<leftmenuoptions>
				<id>CUSTOM_IMPORT_MERCHANT</id>
				<id>CUSTOM_IMPORT_BIN</id>
			</leftmenuoptions>
		</module>

		...
	</modules>
</moduleconfig>

Create Export Processes

To create an export process, you need to create:

...

exports>
</exportsconfig>

2. Export Process class

A process class must be created for the export process, extending com.crm.process.

...

In the following example, we will implement a mechanism to export vouchers. In order to do so, we create CRMExportVoucherBean.java and implement exportVoucher method, which retrieves the vouchers to be exported based on the given lot and writes them to a file of a given type (EXCEL, CSV, XML).

...

CRMCustomExportBean and the two abstract methods defined in this class must be implemented. The methods are:

  • getEntitiesToBeExported. This method accepts the export criteria and returns an ArrayList of the dataObjects to be exported. The export criteria are a HashMap containing the criteria defined in the exports.xml metadata file with their values. The method must retrieve the objects that fulfill these criteria and return them.
  • constructRecord. This method accepts the entity to be exported and returns a String array which represents the values of a line of the export file. The method must construct the String array using the string values of the entity's fields that correspond to the headers of the export file.

Note that the process class must be bean managed. Below, you can see the implementation of an example export process class.

Code Block
languagejava
themeEclipse
titleexportVoucher methodEXAMPLEExportBean
collapsetrue
...

@Stateless(mappedName = "ejb/EXAMPLEExport")
@LocalBean
@TransactionManagement(TransactionManagementType.BEAN)
public class CRMExportVoucherBeanEXAMPLEExportBean extends CRMExportBeanCRMCustomExportBean {   

...
 	public void exportVoucher(String processRunLogID) throws Exception{
        CRMDOProcessRunLog processRun = (CRMDOProcessRunLog)processRunLogBean.load(processRunLogID);
        ExportVoucherDefinition exportVoucherDefinition	private static final long serialVersionUID = 1L;

	@EJB private CRMBOExampleDataObjectBean exampleDataObjectBean;
	
	...

 	@Override
	public ArrayList<CRMDO> getEntitiesToBeExported(HashMap<String, String> exportCriteria) throws Exception {
		
		ArrayList<CRMDO> entitiesToBeExported = new ExportVoucherDefinitionArrayList<CRMDO>();
		ArrayList<Object> criteria =      exportVoucherDefinition.setProcessRunDefinition(processRun.getProcessRunDefinition()new ArrayList<Object>();

		//get the export criteria from the exportCriteria exportVoucherDefinition = exportVoucherXMLUtilBean.loadFromXML(exportVoucherDefinition);
 parameter
		if(exportCriteria!=null && exportCriteria.size()>0)
		{			
	    	if(exportCriteria!=null   
  && exportCriteria.containsKey("criterion1"))
	      processRun.setStatus(ProcessRunLogStatus.IN_PROGRESS);	{
	    		String criterion1 =   processRunexportCriteria.setStartDate(getCurrentDate())get("criterion1");
	        processRunLogBean.save(processRun		criteria.add(criterion1);
	    	}
			
			..
		}
		
		//retrieve the entities that fulfill the export  Boolean processCompletecriteria
		entitiesToBeExported = new Boolean(falseexampleDataObjectBean.load(criteria);
		
		return entitiesToBeExported;
	}

	@Override
	public String[] constructRecord(CRMDO entityToExport) throws Exception {
try		String[] record = new String[]{};
			
		String name  {
            CRMDOLot lot = exportVoucherDefinition.getLot= entityToExport.getName();
		String altCode = entityToExport.getAltCode();
		...
		
		record = new String[] {name, altCode, ...};
		
  VoucherFileFormat fileFormat = exportVoucherDefinition.getVoucherFileFormat();
            
            if (lot != null && fileFormat != null)
            {                
                if (fileFormat.equals(VoucherFileFormat.EXCEL))
                {
                    exportVoucherInExcelFormat(exportVoucherDefinition, lot, processRun);
                }
                else if (fileFormat.equals(VoucherFileFormat.CSV))
                {
                    exportVoucherInCSVFormat(exportVoucherDefinition, lot, processRun);
                }
                else if (fileFormat.equals(VoucherFileFormat.XML))
                {
                    exportVoucherInXMLFormat(exportVoucherDefinition, lot, processRun);
                }
                processComplete = new Boolean(true);
            }
        }
        catch (Exception e)
        {
            processRun.setStatus(ProcessRunLogStatus.FAILED);
            processRunLogBean.save(processRun);
        }
        
        if (processComplete)   
        {
            processRun.setStatus(ProcessRunLogStatus.COMPLETED);
            processRun.setEndDate(getCurrentDate());
            processRunLogBean.save(processRun);
        }
    }

	public void exportVoucherInExcelFormat(ExportVoucherDefinition exportVoucherDefinition, CRMDOLot lot, CRMDOProcessRunLog processRun) throws Exception{
                
        ResultSetUtil vouchers = processVoucherBean.getVouchersToBeExported(lot.getId());
        if (vouchers!=null && vouchers.getRowCount()>0)
        {                
            ArrayList<String[]> excelRecords = new ArrayList<String[]>();
            while(vouchers.next())
            {
                String voucherID = vouchers.getString("VOUCHERID");
                CRMDOVoucher voucher = (CRMDOVoucher) voucherBean.load(voucherID);    
                
                try
                {                    
                    excelRecords.add(constructRecord(voucher));
                }
                catch (Exception e)
                {
                    Entity voucherEntity = MetadataUtil.getEntityByClass(CRMDOVoucher.class.getName(), getCRMSession().getRealPath(), getOrganisationID());
                    processLogBean.createEntityLogRecord(
                            processRun.getId(), 
                            voucher.getId(),
                            voucherEntity.getId(),
                            ProcessRunLogEntityStatus.FAILED.toString(),
                            e.getClass().getSimpleName(), 
                            ExceptionUtil.getStackTrace(e));
                }
            }
            
            storeEXCELRows(excelRecords, processRun, getFileHeaders());
        }
        else
        {
            throw new VoucherNotFoundToBeExportedException(getCRMSession());
        }
    }

...		return record;
	}
	
...
}


Next, you must define this process class in the modules.xml metadata file, which can be found under the <custom_project>/src/main/resources/metadata/ directory. Note that the <exportprocess> and <exportmodule> defined in the exports.xml file will be used in the modules.xml metadata file to correcty define the process class. The <exportprocess> will be used as the process id and the <exportmodule> as the module id. It is mandatory to define the exportProcess method, as shown below. This is the method that is called on submitting the export and it is implemented in the abstract CRMCustomExportBean class.

Code Block
languagejava
themeEclipse
titlemodules.xml
collapsetrue
<?xml version="1.0" encoding="UTF-8"?>
<moduleconfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:noNamespaceSchemaLocation="../xsd/modules.xsd">
	<modules>		

	...
		
		<module>
			<moduleid>CUSTOM_EXPORT</moduleid>
			<modulename>key_custom_export</modulename>
			<moduledescription>key_custom_export</moduledescription>
			
			...
						
			<features>		
				<feature>
					...

					<commonprocesses/>
					
					<additionalprocesses>
						<process>
							<id>CUSTOM_EXPORT_PROCESS</id>
							<name>key_custom_export</name>
							<description>key_custom_export</description>
							<methods>
								<method>
									<ejbname>EXAMPLEExportBean</ejbname>
									<methodname>exportProcess</methodname>
									<scheduled>false</scheduled>
								</method>
							</methods>
							<batch>true</batch>
						</process>
						...
					</additionalprocesses>
				</feature>
			</features>
			
			...
		</module>

		...
	</modules>
</moduleconfig>