Last active
August 25, 2021 11:19
-
-
Save ykurnia/4468fd9ee187b887a1f4d4c02082ceb6 to your computer and use it in GitHub Desktop.
Controller to upload data in CSV format to Contact and Custom object (Cases__c) as child of Contact. This example uses mapping fields, to make this programme generate and easily adopted to another object just modify the mapping.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Used to read a delimited file. | |
* https://gist.github.com/ngaller/858086 | |
*/ | |
public class SSSCsvReader { | |
private String delim = ','; | |
// the input data | |
private String[] buffer; | |
public SSSCsvReader(String data){ | |
data = data.replaceAll('(\r\n|\r)','\n'); | |
this.buffer = data.split('\n'); | |
} | |
public SSSCsvReader(String data, String delim){ | |
this.buffer = data.split('\n'); | |
this.delim = delim; | |
} | |
/** | |
* Read and parse next available line. Return null if end of stream. | |
*/ | |
public String[] readLine(){ | |
if(buffer.size() == 0) | |
return null; | |
String line = this.buffer.remove(0); | |
String[] parts = new String[] {}; | |
while(line != ''){ | |
Integer next = 0; | |
if(line.startsWith('"')){ | |
line = line.substring(1); // strip initial | |
Integer quoteIndex = findQuote(line, 0); | |
while(quoteIndex == -1){ | |
if(buffer.size() == 0){ | |
// EOT! | |
quoteIndex = line.length(); | |
} else { | |
// grab the next line | |
Integer skip = line.length(); | |
line += '\n' + this.buffer.remove(0); | |
quoteIndex = findQuote(line, skip); | |
} | |
} | |
// advance to comma | |
next = quoteIndex + 1; | |
parts.add(line.substring(0, quoteIndex).replace('""', '"')); | |
} else { | |
next = line.indexOf(this.delim, next); | |
if(next == -1) | |
next = line.length(); | |
// NB in Substring, "endindex" is the index of the character AFTER the last index to get | |
parts.add(line.substring(0, next)); | |
} | |
if(next == line.length() - 1) | |
// case of a terminating comma. | |
parts.add(''); | |
line = next < line.length() ? line.substring(next+1) : ''; | |
} | |
if(parts.size() == 0) | |
// empty string - we still want to return something... | |
parts.add(''); | |
return parts; | |
} | |
static private Pattern quotePattern = Pattern.compile('(?<!")"(?!")'); | |
/** | |
* Find next quote in the line | |
*/ | |
private Integer findQuote(String line, Integer skip){ | |
Matcher m = quotePattern.matcher(line); | |
m.region(skip, m.regionEnd()); | |
if(!m.find()) | |
return -1; | |
return m.start(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@isTest | |
public class UploadContactCaseTest { | |
static String getSampleCsv(){ | |
String strTmp; | |
strTmp = 'SN,Client Name,"Client ID Type","Client ID",Name of SSO,Date Last Known to SSO,Last Known Assistance Period at SSO,Enquiry ID,Date of Enquiry,Rate of Response,Mode of Enquiry,Enquiry Worker,Source of Referral,Outcome of Enquiry,Duration of Contact for Enquiry (mins),Intake ID,Date of Intake,Presenting Issue,Age,Gender,Ethnicity,Marital Status,Household Dwelling Type,Family Type,Education Level,Residential Status,Religion,Occupation,Employment Status,Gross Household Income,Disability/Special Needs,Assessed Risk of Recurrence at Intake Assessment,"Suicidal Risk at Intake Assessment","Risk of Harm to Others at Intake Assessment",Recommendation at Intake,Duration of Contact for Intake (mins),Outcome Plan ID,Case Manager,CSWP Classification at 1st Assessment,CSWP Classification at 1st Review,CSWP Classification at 2nd Review,CSWP Classification at 3rd Review,Agencies Family known to,Outcome Plan Status,CSWP Classification at Case Closure,Case Open Date ,Case Closure Date,Reason for Case Closure,No. of Sessions (Outcome Plan + Intervention),No. of Goals Achieved (Goals Met / Total No. of Goals),Milestones Met at Case Closure (No. of Milestones Met / Total No. of Milestones),Duration of Case (Days)'; | |
strTmp += '\n'; | |
strTmp += '1,Testing,Singapore Pink Identification Card,S000005J,SSO Bukit Merah,01/12/2020,July 2020 - December 2020,,,,,,,,,,,,60,M,Malay,Divorced,HDB 2 Room,,Pre-School,Singapore Citizen,Muslim,,Not Working (Temporarily Medically Unfit less than 3 months),0,,,,,,,OTPC30003009196,"Aasfafsd",2,2,4,,,Open,,16/10/2008,,,55,,,'; | |
strTmp += '\n'; | |
strTmp += '2,test2,Singapore Pink Identification Card,S000000G,SSO Bukit Merah,05/09/2020,May 2020 - October 2020,,,,,,,,,,,,46,M,Malay,Married,HDB 2 Room,,Polytechnic Diploma,Singapore Citizen,Muslim,"Plant and Machine Operators and Assemblers (Taxi, Bus drivers)",Working,0,,,,,,,OTPC30003009475,Asdfsdfsd,2,2,2,,,Open,,30/05/2013,,,20,,,'; | |
return strTmp; | |
} | |
@isTest static void myTest1() { | |
Blob fileCsv = Blob.valueOf(getSampleCsv()); | |
List<Contact> lsContacts = new List<Contact>(); | |
ApexPages.StandardSetController pg1 = new ApexPages.StandardSetController(lsContacts); | |
UploadContactCaseController cnt1 = new UploadContactCaseController(pg1); | |
cnt1.fileCsv = fileCsv; | |
cnt1.upload(); | |
cnt1.next(); | |
cnt1.back(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<apex:page standardController="Contact" tabStyle="Contact" extensions="UploadContactCaseController" recordSetVar="contacts" lightningStylesheets="true"> | |
<apex:form > | |
<apex:pageBlock title="UPLOAD MEMBER"> | |
<apex:pageBlockButtons id="commandBlock"> | |
<apex:commandButton value="Upload" action="{!upload}" rendered="{!totalData = totalProceed}" status="status1" /> | |
<apex:commandButton value="Proceed Next" action="{!next}" rendered="{!totalData > totalProceed}" status="status1" /> | |
<apex:commandButton value="Back" action="{!back}" immediate="true" /> | |
</apex:pageBlockButtons> | |
<apex:messages style="border: 1px solid red;padding:5px;" /> | |
<apex:pageBlockSection columns="3"> | |
<apex:outputText ></apex:outputText> | |
<apex:outputLabel >Please select a csv file <apex:inputFile value="{!fileCsv}" title="CSV File" /> </apex:outputLabel> | |
<apex:actionStatus id="status1" startStyle="text-align:center;font-weight:bold;color: blue;" startText="Processing, please wait ... " stopText=""></apex:actionStatus> | |
</apex:pageBlockSection> | |
</apex:pageBlock> | |
<apex:pageBlock rendered="{!totalData > 0}" id="resultBlock"> | |
<apex:pageBlockSection title="Result" columns="2"> | |
<apex:outputText value="{!totalData}" label="Total Data"></apex:outputText> | |
<apex:outputText value="{!totalSuccess}" label="Total Success"></apex:outputText> | |
<apex:outputText value="{!totalProceed}" label="Total Proceed"></apex:outputText> | |
<apex:outputText value="{!totalFailed}" label="Total Failed"></apex:outputText> | |
</apex:pageBlockSection> | |
<apex:pageBlockSection columns="1" title="Error"> | |
<apex:outputText value="{!strInfo}" label="" style="" escape="false" ></apex:outputText> | |
</apex:pageBlockSection> | |
</apex:pageBlock> | |
</apex:form> | |
</apex:page> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Controller for VF page to upload CSV file for Contact and Case | |
*/ | |
public class UploadContactCaseController { | |
public List<Contact> contacts{get;set;} | |
public Blob fileCsv {get;set;} | |
public String strInfo {get;set;} | |
public String strWarning {get;set;} | |
Map<String, Integer> mapContactField {get;set;} | |
Map<String, Integer> mapCaseField {get;set;} | |
Set<String> stDateField {get;set;} | |
Set<String> stIntegerField {get;set;} | |
Set<String> stDoubleField {get;set;} | |
List<List<String>> dataAll {get;set; } | |
public Integer totalData {get;set;} | |
public Integer totalProceed {get;set;} | |
public Integer totalSuccess {get;set;} | |
public Integer totalFailed {get;set;} | |
public Integer intCurrent {get;set;} | |
public Integer totalProceedCase {get;set;} // just for tracking | |
Map<String, Integer> mapSNRow {get;set;} // map of SN with Row number | |
public UploadContactCaseController(ApexPages.StandardSetController controller) | |
{ | |
contacts = New List<Contact>(); | |
totalData = totalSuccess = totalFailed = totalProceed = 0; | |
strInfo = ''; | |
strWarning = ''; | |
intCurrent = totalProceedCase = 0; | |
initMapFields(); | |
dataAll = new List<List<String>>(); | |
mapSNRow = new Map<String, Integer>(); | |
} | |
/* initiate mapping field with column in csv */ | |
private void initMapFields() | |
{ | |
mapContactField = new Map<String, Integer>(); | |
mapCaseField = new Map<String, Integer>(); | |
stDateField = new Set<String>{'Date_of_Enquiry__c', 'Date_of_Intake__c', 'Date_Client_was_Last_Known_to_SSO__c', 'Case_Closure_Date__c', 'Case_Open_Date__c'}; | |
stDoubleField = new Set<String> {'Household_income__c'}; | |
stIntegerField = new Set<String> {'Age1__c', 'Sessions_Outcome_Plan_Intervention__c', 'No_of_Goals_Achieved__c', 'Milestones_Met_at_Case_Closure__c', | |
'Duration_of_Case_Days__c', 'Duration_of_Contact_for_Intake_mins__c', 'Duration_of_Contact_for_Enquiry_mins__c'}; | |
mapContactField.put('LastName',1); // Client Name (Only for FSCs) | |
mapContactField.put('ID_Type__c',2); // Client ID Type (Only for FSCs) | |
mapContactField.put('ID_No__c',3); // Client ID (Only for FSCs) | |
mapContactField.put('Enquiry_ID__c',7); // Enquiry ID | |
mapContactField.put('Date_of_Enquiry__c',8); // Date of Enquiry | |
mapContactField.put('Rate_of_Response__c',9); // Rate of Response | |
mapContactField.put('Mode_of_Enquiry__c',10); // Mode of Enquiry | |
mapContactField.put('Enquiry_Worker__c',11); // Enquiry Worker | |
mapContactField.put('Source_of_Referral__c',12); // Source of Referral | |
mapContactField.put('Outcome_of_Enquiry__c',13); // Outcome of Enquiry | |
mapContactField.put('Duration_of_Contact_for_Enquiry_mins__c',14); // Duration of Contact for Enquiry (mins) | |
mapContactField.put('Intake_ID__c',15); // Intake ID | |
mapContactField.put('Date_of_Intake__c',16); // Date of Intake | |
mapContactField.put('Presenting_Issue__c',17); // Presenting Issue | |
mapContactField.put('Age1__c',18); // Age | |
mapContactField.put('Gender__c',19); // Gender | |
mapContactField.put('Ethnicity__c',20); // Ethnicity | |
mapContactField.put('Marital_Status__c',21); // Marital Status | |
mapContactField.put('Household_Dwelling_Type__c',22); // Household Dwelling Type | |
mapContactField.put('Family_Type__c',23); // Family Type | |
mapContactField.put('Highest_Education_Level__c',24); // Education Level | |
mapContactField.put('Citizenship__c',25); // Residential Status | |
mapContactField.put('Religion__c',26); // Religion | |
mapContactField.put('Occupation_Volunteer__c',27); // Occupation | |
mapContactField.put('Employment_Status__c',28); // Employment Status | |
mapContactField.put('Household_income__c',29); // Gross Household Income | |
mapContactField.put('Special_Needs_Disabilities__c',30); // Disability/Special Needs | |
mapContactField.put('Recommendation_at_Intake__c',34); // Recommendation at Intake | |
mapContactField.put('Duration_of_Contact_for_Intake_mins__c',35); // Duration of Contact for Intake (mins) | |
mapContactField.put('Outcome_Plan_Status__c',43); // Outcome Plan Status | |
if (mapContactField.containskey('')) mapContactField.remove(''); | |
// CASE | |
mapCaseField.put('Name_of_SSO_if_know_to_SSO__c',4); // Name of SSO (If known to SSO) | |
mapCaseField.put('Date_Client_was_Last_Known_to_SSO__c',5); // Date on which Client was Last Known to SSO | |
mapCaseField.put('Last_Known_Assistance_Period_at_SSO__c',6); // Last Known Assistance Period at SSO | |
mapCaseField.put('Assessed_Risk_of_Recurrence_at_Intake__c',31); // Assessed Risk of Recurrence at Intake Assessment(L/M/H/Unable to assess) | |
mapCaseField.put('Suicidal_Risk_at_Intake_Assessment__c',32); // Suicidal Risk at Intake Assessment (L/M/H/Unable to assess) | |
mapCaseField.put('Risk_of_Harm_to_Others_at_Intake_Assessm__c',33); // Risk of Harm to Others at Intake Assessment (L/M/H/Unable to assess) | |
mapCaseField.put('Name',36); // Outcome Plan ID | |
mapCaseField.put('Case_Manager_Name_of_Social_Worker__c',37); // Case Manager | |
mapCaseField.put('CSWP_Classification_1st_Assessment__c',38); // CSWP Classification at 1st Assessment | |
mapCaseField.put('CSWP_Classification_1st_Assement_Date__c',39); // CSWP Classification at 1st Review | |
mapCaseField.put('CSWP_Classification_2nd_Review_Date__c',40); // CSWP Classification at 2nd Review | |
mapCaseField.put('CSWP_Classification_3rd_Review_Date__c',41); // CSWP Classification at 3rd Review | |
mapCaseField.put('Agencies_Family_known_to__c',42); // Agencies Family known to | |
mapCaseField.put('Outcome_Plan_Status__c',43); // Outcome Plan Status | |
mapCaseField.put('CSWP_Classification_at_Case_Closure__c',44); // CSWP Classification at Case Closure | |
mapCaseField.put('Case_Open_Date__c',45); // Case Open Date | |
mapCaseField.put('Case_Closure_Date__c',46); // Case Closure Date | |
mapCaseField.put('Reason_for_Case_Closure__c',47); // Reason for Case Closure | |
mapCaseField.put('Sessions_Outcome_Plan_Intervention__c',48); // No. of Sessions (Outcome Plan + Intervention) | |
mapCaseField.put('No_of_Goals_Achieved__c',49); // No. of Goals Achieved (Goals Met / Total No. of Goals) | |
mapCaseField.put('Milestones_Met_at_Case_Closure__c',50); // Milestones Met at Case Closure (No. of Milestones Met / Total No. of Milestones) | |
mapCaseField.put('Duration_of_Case_Days__c',51); // Duration of Case (Days) | |
if (mapCaseField.containskey('')) mapCaseField.remove(''); | |
} | |
/* generate string of field for Contact */ | |
private String getObjectFields(String strObj) | |
{ | |
String str = 'Id'; | |
if (strObj == 'Contact') { | |
for(String s: mapContactField.keySet()) { | |
str += ', ' + s; | |
} | |
} | |
else if (strObj == 'Cases__c') { | |
for(String s: mapCaseField.keySet()) { | |
str += ', ' + s; | |
} | |
} | |
return str; | |
} | |
// handle csv upload, load to dataAll | |
public PageReference upload() | |
{ | |
// mapping | |
Integer iTmp, iTmp2, iContact, iCase; | |
String strTmp, strTmp2; | |
// check csv | |
if (fileCsv != null) | |
{ | |
// extract csv | |
SSSCsvReader objCsv = new SSSCsvReader(fileCsv.toString()); | |
List<String> dataLine = new List<String>(); | |
Set<String> lsClientID = new Set<String>(); // list of client ID | |
Set<String> lsCaseID = new Set<String>(); // id of case | |
dataLine = objCsv.readLine(); | |
if (dataLine != null) { | |
dataLine = objCsv.readLine(); // ignore first row | |
} | |
while (dataLine != null) | |
{ | |
dataAll.add(dataLine); | |
// validation, check if duplicate row (based on unique column) | |
iTmp = getCol('Contact', 'ID_No__c'); | |
if (dataLine.size() > iTmp && dataLine[iTmp] != null && dataLine[iTmp] != '') { | |
strTmp = dataLine[iTmp]; | |
if (lsClientID.contains(strTmp)) { | |
// duplicate | |
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR,'Error: Duplicate Client ID ' + strTmp)); | |
totalData = 0; | |
return null; | |
} | |
else { | |
lsClientID.add(strTmp); | |
} | |
} | |
iTmp = getCol('Cases__c', 'Name'); | |
if (dataLine.size() > iTmp && dataLine[iTmp] != null && dataLine[iTmp] != '') { | |
strTmp = dataLine[iTmp]; | |
if (lsCaseId.contains(strTmp)) | |
{ | |
// duplicate | |
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR,'Error: Duplicate Output Plan ID ' + strTmp)); | |
return null; | |
} | |
else { | |
lsCaseID.add(dataLine[iTmp]); | |
} | |
} | |
// get SN information | |
if (dataLine[0] != null && dataLine[0] != '') { | |
mapSNRow.put(dataLine[0], totalData); | |
} | |
totalData++; | |
dataLine = objCsv.readLine(); | |
} | |
} | |
proceed(); | |
return null; | |
} | |
// procceed data in dataAll to DB | |
public void proceed() | |
{ | |
List<String> dataLine = new List<String>(); | |
List<String> lsClientID = new List<String>(); // list of client ID | |
List<String> lsCaseID = new List<String>(); // id of case | |
Integer maxProceed = 100; // max record per proceed | |
Integer startP = 0; | |
Integer endP = 0; | |
Integer i, j, k, iTmp, iTmp2, iTmp3; | |
String strTmp, strTmp2; | |
Boolean bolNew; | |
Id RTContactMember = Schema.SObjectType.Contact.getRecordTypeInfosByName().get('Member').getRecordTypeId(); | |
Integer iCase, iContact; | |
Integer intRow; | |
String strErr; | |
if (totalData > 0 && totalProceed < totalData) | |
{ | |
startP = totalProceed; // index | |
endP = totalData - 1; | |
if ((endP - startP) > maxProceed) { | |
endP = startP + maxProceed - 1; | |
} | |
system.debug('DEBUG: process from ' + startP + ' to ' + endP); | |
for (i = startP; i <= endP; i++) | |
{ | |
dataLine = dataAll[i]; | |
iTmp = getCol('Contact', 'ID_No__c'); | |
if (dataLine.size() > iTmp) lsClientID.add(dataLine[iTmp]); | |
iTmp = getCol('Cases__c', 'Name'); | |
if (dataLine.size() > iTmp) lsCaseID.add(dataLine[iTmp]); | |
} // for | |
// get existing contact and case | |
system.debug('DEBUG: client id ' + lsClientID); | |
system.debug('DEBUG: case id ' + lsCaseID); | |
Map<String, Contact> mapContacts = new Map<String, Contact>(); | |
Map<String, Cases__c> mapCases = new Map<String, Cases__c>(); | |
List<Contact> lsContactRecord = new List<Contact>(); | |
List<Cases__c> lsCaseRecord = new List<Cases__c>(); | |
Set<Id> stContactSuccess = new Set<Id>(); | |
Contact objCnt; | |
Cases__c objCase; | |
strTmp = 'SELECT ' + getObjectFields('Contact') + ', RecordTypeId FROM Contact WHERE ID_No__c IN :lsClientID '; | |
system.debug('DEBUG Query ' + strTmp); | |
for(SObject cnt : Database.query(strTmp)) | |
{ | |
objCnt = (Contact)cnt; | |
mapContacts.put(objCnt.ID_No__c, objCnt); | |
} | |
strTmp = 'SELECT ' + getObjectFields('Cases__c') + ', Contact__c FROM Cases__c WHERE Name IN :lsCaseID '; | |
system.debug('DEBUG Query ' + strTmp); | |
for(SObject css : Database.query(strTmp)) | |
{ | |
objCase = (Cases__c)css; | |
mapCases.put(objCase.Name, objCase); | |
} | |
// create/update data for Contact | |
Integer iData = 0; | |
String strSN = ''; | |
Map<Integer, String> mapRowSN = new Map<Integer, String>(); // index -> SN | |
iContact = getCol('Contact', 'ID_No__c'); | |
for (i = startP; i <= endP; i++) | |
{ | |
dataLine = dataAll[i]; | |
totalProceed++; | |
intCurrent++; | |
if (dataLine.size() > 51) { // make sure correct data | |
strSN = dataLine[0]; // get serial number | |
mapRowSN.put(iData, strSN); | |
intRow = 0; | |
if (mapSNRow.get(strSN) != null) { | |
intRow = mapSNROw.get(strSN); | |
} | |
strErr = ''; // for skipped error | |
strTmp = dataLine[iContact]; | |
bolNew = true; | |
objCnt = new Contact(); | |
system.debug('DEBUG: ID No ' + strTmp); | |
if (strTmp != null && strTmp != '' && mapContacts.get(strTmp) != null) { | |
objCnt = mapContacts.get(strTmp); | |
bolNew = false; | |
system.debug('DEBUG: NOT NEW ' + objCnt.Id); | |
} | |
objCnt.RecordTypeId = RTContactMember; | |
// update fields | |
try { | |
for (String strF: mapContactField.keySet()) { | |
iTmp = getCol('Contact', strF); | |
if (dataLine[iTmp] != null && dataLine[iTmp] != '' ) | |
{ | |
system.debug('DEBUG: ' + strF + ' = ' + dataLine[iTmp]); | |
if (stIntegerField.contains(strF)) { | |
if (isValidNumber(dataLine[iTmp], true)) { | |
objCnt.put(strF, Integer.valueOf(dataLine[iTmp])); | |
} | |
else { | |
strErr += 'Invalid number ' + dataLine[iTmp] + ' ;'; | |
} | |
} | |
else if (stDoubleField.contains(strF)) { | |
if (isValidNumber(dataLine[iTmp], false)) { | |
objCnt.put(strF, Double.valueOf(dataLine[iTmp])); | |
} | |
else { | |
strErr += 'Invalid number ' + dataLine[iTmp] + ' ;'; | |
} | |
} | |
else if (stDateField.contains(strF)) { | |
objCnt.put(strF, Date.valueOf(convertDate(dataLine[iTmp]))); | |
} | |
else { | |
objCnt.put(strF, dataLine[iTmp]); | |
} | |
} | |
else { | |
objCnt.put(strF, null); | |
} | |
} | |
} | |
catch (Exception e) { | |
//ApexPages.addMessages(e); | |
strWarning += 'Row ' + String.valueOf(i+2) + ': ' + e.getMessage() + ' <br/>\n'; | |
} | |
iData++; | |
if (strErr != '') { | |
strWarning += 'Row ' + String.valueOf(i+2) + ': ' + strErr + ' <br/>\n'; | |
} | |
lsContactRecord.add(objCnt); | |
} | |
} | |
Database.UpsertResult[] srList; | |
Database.Error[] listErr; | |
// save | |
try { | |
// srList = Database.upsert(lsContactRecord, 'ID_No__c', false); | |
srList = Database.upsert(lsContactRecord, false); | |
} | |
catch(DmlException e) { | |
ApexPages.addMessages(e); | |
strWarning += 'ERR on Contact ' + e.getMessage() + '<br/>\n'; | |
} | |
if (srList != null) { | |
iTmp = 1; | |
iTmp2 = 0; | |
for(Database.UpsertResult sr: srList) { | |
iTmp++; | |
if (listErr != null) listErr.clear(); | |
if (sr.isSuccess()) { | |
stContactSuccess.add(sr.getId()); | |
totalSuccess++; | |
} | |
else { | |
listErr = sr.getErrors(); | |
// check row number | |
strTmp = strTmp2 = ''; | |
if (mapRowSN.get(iTmp2) != null) { | |
strTmp = mapRowSN.get(iTmp2); // SN | |
if (mapSNRow.get(strTmp) != null) { | |
strTmp2 = String.valueOf(mapSNRow.get(strTmp) + 2); // actual row (+2 because index start with 0, but data start at row 2) | |
} | |
} | |
for(j = 0; j < listErr.size();j++) { | |
// strInfo += 'Row ' + String.valueOf(iTmp) + ': ' + listErr[j].getMessage() + '<br/>\n'; | |
strInfo += 'Row ' + strTmp2 + ' [' + strTmp + ']: ' + listErr[j].getMessage() + '<br/>\n'; | |
} | |
totalFailed++; | |
} | |
iTmp2++; | |
} | |
} | |
for(Contact C: lsContactRecord) { | |
if (C.ID_No__c != null && stContactSuccess.contains(C.Id)) { | |
mapContacts.put(C.ID_No__c, C); | |
} | |
} | |
iCase = getCol('Cases__c', 'Name'); | |
iData = 0; | |
strSN = ''; | |
mapRowSN = new Map<Integer, String>(); | |
for (i = startP; i <= endP; i++) | |
{ | |
dataLine = dataAll[i]; | |
if (dataLine.size() > 51 && dataLine[iCase] != null && dataLine[iCase] != '') { // make sure correct data, only if case | |
strTmp = dataLine[iContact]; | |
if (strTmp != null && mapContacts.get(strTmp) != null) // only if contact success | |
{ | |
strSN = dataLine[0]; // get serial number | |
mapRowSN.put(iData, strSN); | |
intRow = 0; | |
if (mapSNRow.get(strSN) != null) { | |
intRow = mapSNROw.get(strSN); | |
} | |
strErr = ''; // for skipped error | |
strTmp2 = dataLine[iCase]; | |
bolNew = true; | |
objCase = new Cases__c(); | |
if (strTmp2 != null && strTmp2 != '' && mapCases.get(strTmp2) != null) { | |
objCase = mapCases.get(strTmp2); | |
bolNew = false; | |
} | |
objCase.Contact__c = mapContacts.get(strTmp).Id; | |
// update fields | |
try { | |
for (String strF: mapCaseField.keySet()) { | |
iTmp = getCol('Cases__c', strF); | |
if (dataLine[iTmp] != null && dataLine[iTmp] != '' ) | |
{ | |
system.debug('DEBUG: ' + strF + ' = ' + dataLine[iTmp]); | |
if (stIntegerField.contains(strF)) { | |
if (isValidNumber(dataLine[iTmp], true)) { | |
objCase.put(strF, Integer.valueOf(dataLine[iTmp])); | |
} | |
else { | |
strErr += 'Invalid number ' + dataLine[iTmp] + ' ;'; | |
} | |
} | |
else if (stDoubleField.contains(strF)) { | |
if (isValidNumber(dataLine[iTmp], false)) { | |
objCase.put(strF, Double.valueOf(dataLine[iTmp])); | |
} | |
else { | |
strErr += 'Invalid number ' + dataLine[iTmp] + ' ;'; | |
} | |
} | |
else if (stDateField.contains(strF)) { | |
system.debug('DEBUG: date ' + dataLine[iTmp]); | |
objCase.put(strF, Date.valueOf(convertDate(dataLine[iTmp]))); | |
} | |
else { | |
objCase.put(strF, dataLine[iTmp]); | |
} | |
} | |
else { | |
objCase.put(strF, null); | |
} | |
} | |
} | |
catch (Exception e) { | |
// ApexPages.addMessages(e); | |
strWarning += 'Row ' + String.valueOf(i+2) + ' : ' + e.getMessage() + ' <br/>\n'; | |
} | |
lsCaseRecord.add(objCase); | |
iData++; | |
if (strErr != '') { | |
strWarning += 'Row ' + String.valueOf(i+2) + ' : ' + strErr + ' <br/>\n'; | |
} | |
} | |
} | |
} | |
// save cases | |
srList = null; | |
try { | |
srList = Database.upsert(lsCaseRecord); | |
// totalProceedCase += lsCaseRecord.size(); | |
} | |
catch(DmlException e) { | |
ApexPages.addMessages(e); | |
strWarning += 'ERR on Case ' + e.getMessage() + '<br/>\n'; | |
} | |
// todo, inform error when save case | |
if (srList != null) { | |
iTmp = 1; | |
iTmp2 = 0; | |
for(Database.UpsertResult sr: srList) { | |
iTmp++; | |
if (listErr != null) listErr.clear(); | |
if (sr.isSuccess()) { | |
// stContactSuccess.add(sr.getId()); | |
totalProceedCase++; | |
} | |
else { | |
listErr = sr.getErrors(); | |
// check row number | |
strTmp = strTmp2 = ''; | |
if (mapRowSN.get(iTmp2) != null) { | |
strTmp = mapRowSN.get(iTmp2); // SN | |
if (mapSNRow.get(strTmp) != null) { | |
strTmp2 = String.valueOf(mapSNRow.get(strTmp) + 2); // actual row (+2 because index start with 0, but data start at row 2) | |
} | |
} | |
for(j = 0; j < listErr.size();j++) { | |
// strInfo += 'Row ' + String.valueOf(iTmp) + ': ' + listErr[j].getMessage() + '<br/>\n'; | |
strInfo += 'Row (Case) ' + strTmp2 + ' [' + strTmp + ']: ' + listErr[j].getMessage() + '<br/>\n'; | |
} | |
// totalFailed++; | |
} | |
iTmp2++; | |
} | |
} | |
} // if totalData | |
} | |
public PageReference next() | |
{ | |
proceed(); | |
return null; | |
} | |
// check if a string is numeric (integer or double) | |
public Boolean isValidNumber(String str, Boolean isInteger) | |
{ | |
Decimal decTmp; | |
Integer intTmp; | |
Boolean bolOK = true; | |
try { | |
if (isInteger){ | |
intTmp = Integer.valueOf(str); | |
} | |
else { | |
decTmp = Decimal.valueOf(str); | |
} | |
} | |
catch (Exception e) { | |
bolOK = false; | |
} | |
return bolOK; | |
} | |
// get column number from code | |
public Integer getCol(String strObj, String strField) | |
{ | |
Integer iResult = null; | |
if (strObj == 'Contact' && mapContactField.get(strField) != null) { | |
iResult = mapContactField.get(strField); | |
} | |
else if (strObj == 'Cases__c' && mapCaseField.get(strField) != null) { | |
iResult = mapCaseField.get(strField); | |
} | |
return iResult; | |
} | |
// convert date from DD/MM/YYYY to YYYY-MM-DD | |
public String convertDate(String strDate) | |
{ | |
String strResult = strDate; | |
String strYear; | |
if (strDate != null && strDate != '') | |
{ | |
String[] arrStr = strDate.split('/'); | |
if (arrStr.size() >= 3) { | |
strYear = arrStr[2]; | |
if (strYear.length() == 2) strYear = '20' + strYear; | |
strResult = strYear + '-' + arrStr[1] + '-' + arrStr[0]; | |
} | |
} | |
return strResult; | |
} | |
// to handle back button to return to Contact List | |
public PageReference back(){ | |
return new ApexPages.Action('{!List}').invoke(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment