by Ursego » 01 Nov 2019, 12:49
Just an example how I use comments - taken from a real class I created:
- Code: Select all
package ca.echelon.csv2zoho.reports;
import com.zoho.crm.library.crud.ZCRMModule;
import com.zoho.crm.library.crud.ZCRMRecord;
import com.zoho.crm.library.exception.ZCRMException;
import com.zoho.crm.library.setup.restclient.ZCRMRestClient;
import ca.echelon.csv2zoho.MainApplication;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class YearlyReport implements IReport {
private static final boolean DEBUG_MODE = true; // true - process only the first 15 rows of Excel; false - production mode, process all rows
// Zoho modules: https://crm.zoho.com/crm/org639870014/settings/api/modules
private static final String ZOHO_MODULE_NAME__ACCOUNTS = "Accounts";
private static final String ZOHO_MODULE_NAME__YEARLY_RESULTS = "Yearly_Results";
private static final int EXCEL_CELL_NUM__ACCOUNT_NUMBER = 0;
private static final int EXCEL_CELL_NUM__SOURCE_APPLICATION = 1;
private static final int EXCEL_CELL_NUM__MASTER_BROKER_NUMBER = 2;
private static final int EXCEL_CELL_NUM__MASTER_BROKER_NAME = 3;
private static final int EXCEL_CELL_NUM__BROKER_NUMBER = 4;
private static final int EXCEL_CELL_NUM__BROKER_NAME = 5;
private static final int EXCEL_CELL_NUM__CLASS = 6;
private static final int EXCEL_CELL_NUM__WRITTEN_PREMIUM = 7;
private static final int EXCEL_CELL_NUM__EARNED_PREMIUM = 8;
private static final int EXCEL_CELL_NUM__INCURRED_AMOUNT = 9;
private static final HashMap<Integer, String> zohoFieldNameFirstPartByExcelCellNum = new HashMap<>();
static {
zohoFieldNameFirstPartByExcelCellNum.put(EXCEL_CELL_NUM__WRITTEN_PREMIUM, "Written_Premium_");
zohoFieldNameFirstPartByExcelCellNum.put(EXCEL_CELL_NUM__EARNED_PREMIUM, "Earned_Premium_");
zohoFieldNameFirstPartByExcelCellNum.put(EXCEL_CELL_NUM__INCURRED_AMOUNT, "Incurred_Amount_");
}
// zohoClassByExcelClass maps Excel Classes (as they appear in the Class column of Excel - like "Commercial Property") to Zoho Classes
// (as they appear in Zoho API - like "Commercial_Property"; see all the Zoho API fields here: https://bit.ly/2OXPHxB).
// In most cases (but not always!!!), the Zoho Class is the same as the Excel Class, but with underscores instead of spaces.
// Zoho Classes are used as the 2nd part of some API fields names which are built by the pattern "[field]_[class]", where:
// [field] - the 1st part: one of the three: "Earned_Premium", "Written_Premium" or "Loss_Ratio";
// [class] - the 2nd part: "Commercial_Property", "Personal_Property", etc.
// For example: Earned_Premium_Commercial_Property. In this case, this HashMap will return "Commercial_Property" ready for concatenation with class.
private static final HashMap<String, String> zohoClassByExcelClass = new HashMap<>();
static {
zohoClassByExcelClass.put("Commercial Property", "Commercial_Property");
zohoClassByExcelClass.put("Commercial Liability", "Commercial_Liability");
zohoClassByExcelClass.put("Commercial Auto", "Commercial_Automobile");
zohoClassByExcelClass.put("Personal Property", "Personal_Property");
zohoClassByExcelClass.put("Personal Liability", "Personal_Liability");
zohoClassByExcelClass.put("Motorcycle", "Motorcycle");
zohoClassByExcelClass.put("Long Haul Trucking", "Long_Haul_Trucking");
zohoClassByExcelClass.put("Personal Auto", "Personal_Auto");
zohoClassByExcelClass.put("All Terrain Vehicles", "Non_Standard_Automobile");
zohoClassByExcelClass.put("Antique Auto", "Non_Standard_Automobile");
zohoClassByExcelClass.put("Snow Vehicles", "Non_Standard_Automobile");
zohoClassByExcelClass.put("Motor Homes", "Motorhome_Travel_Trailer");
zohoClassByExcelClass.put("Trailer Homes", "Motorhome_Travel_Trailer");
zohoClassByExcelClass.put("Accident Sickness", "Accident_Sickness");
zohoClassByExcelClass.put("General Liability", "General_Liability");
zohoClassByExcelClass.put("Specialty", "Specialty");
zohoClassByExcelClass.put("Warranty", "Warranty");
zohoClassByExcelClass.put("Surety", "Surety");
zohoClassByExcelClass.put("Legal", "Legal");
}
private static final ZCRMModule accountsModule;
static {
accountsModule = ZCRMRestClient.getInstance().getModuleInstance(ZOHO_MODULE_NAME__ACCOUNTS);
}
/***********************************************************************************************************************************************************/
@Override
public List<ZCRMRecord> convert
(XSSFWorkbook workbook)
{
HashMap<String, ZCRMRecord> zohoRecordByAccountNumberHashMap = new HashMap<>();
XSSFSheet sheet = workbook.getSheetAt(0); // the 1st sheet containing data for report
String reportYear = this.getReportYear(workbook);
int excelRowCount = sheet.getPhysicalNumberOfRows();
for (int i = 2; i < excelRowCount; i++) {
if (DEBUG_MODE && i == 18) break;
XSSFRow excelRow = sheet.getRow(i);
this.convertExcelRow(workbook, excelRow, reportYear, /* into the "values" part of >>> */ zohoRecordByAccountNumberHashMap);
}
ArrayList<ZCRMRecord> recordsArrayList = new ArrayList<ZCRMRecord>(zohoRecordByAccountNumberHashMap.values());
MainApplication.getLogger().info("Converted " + recordsArrayList.size() + " rows from sheet " + sheet.getSheetName());
return recordsArrayList;
}
/***********************************************************************************************************************************************************/
private void convertExcelRow
(XSSFWorkbook workbook
,XSSFRow excelRow
,String reportYear
,HashMap<String, ZCRMRecord> zohoRecordByAccountNumberHashMap)
{
if (excelRow.getCell(0).getCellTypeEnum() == CellType.BLANK) return;
if (excelRow.getCell(0).getStringCellValue().trim().isEmpty()) return;
// For each broker, many rows can exist in Excel (with different Class!!!). But we send each broker as one record.
// The more records (Classes) exist for a broker, the more class-related fields are added to that broker's record.
// If this loop encounters an already processed broker, it adds new Class-related fields to the previously created record of that broker.
// For example: if broker A has 7 rows in Excel, we add 7 fields "Earned_Premium_[class]" to the same record in 7 iterations of this loop.
String accountNumber = excelRow.getCell(EXCEL_CELL_NUM__ACCOUNT_NUMBER).getStringCellValue();
ZCRMRecord zohoRecord = zohoRecordByAccountNumberHashMap.get(accountNumber);
if (zohoRecord == null /* it's first time the loop encounters this broker */) {
zohoRecord = new ZCRMRecord(ZOHO_MODULE_NAME__YEARLY_RESULTS);
zohoRecordByAccountNumberHashMap.put(accountNumber, zohoRecord);
String brokerName = excelRow.getCell(EXCEL_CELL_NUM__BROKER_NAME).getStringCellValue();
String reportName = brokerName + " - " + reportYear + " YTD Results";
zohoRecord.setFieldValue("Name", reportName);
zohoRecord.setFieldValue("Account", accountNumber);
}
// Set Class-related fields - "Earned_Premium_[class]", "Written_Premium_[class]" & "Incurred_Amount_[class]":
String zohoClass = this.getZohoClass(excelRow); // like "Commercial_Property"
if (zohoClass == null) return;
this.setDollarAmountField(excelRow, EXCEL_CELL_NUM__WRITTEN_PREMIUM, zohoRecord, zohoClass);
this.setDollarAmountField(excelRow, EXCEL_CELL_NUM__EARNED_PREMIUM, zohoRecord, zohoClass);
this.setDollarAmountField(excelRow, EXCEL_CELL_NUM__INCURRED_AMOUNT, zohoRecord, zohoClass);
this.setLossRatio(excelRow, zohoRecord, zohoClass); // must be called AFTER setting the dollar amount fields!!!
}
private String getZohoClass
(XSSFRow excelRow)
{
String excelClass = excelRow.getCell(EXCEL_CELL_NUM__CLASS).getStringCellValue(); // like "Commercial Property"
String zohoClass = zohoClassByExcelClass.get(excelClass); // like "Commercial_Property"
if (zohoClass == null) {
MainApplication.getLogger().warn("No Zoho Class defined for Excel Class '" + excelClass + "' in YearlyReport.zohoClassByExcelClassHashMap.");
}
return zohoClass;
}
/**********************************************************************************************************************************************************/
private void setDollarAmountField
(XSSFRow excelRow
,int excelCellNum
,ZCRMRecord zohoRecord
,String zohoClass /* like "Commercial_Property" */)
{
String zohoFieldNameFirstPart = zohoFieldNameFirstPartByExcelCellNum.get(excelCellNum); // "Written_Premium_", "Earned_Premium_" or "Incurred_Amount_"
String zohoFieldName = zohoFieldNameFirstPart + zohoClass; // like "Written_Premium_Commercial_Property"
double valueToSet = 0;
try {
double valueFromExcel = excelRow.getCell(excelCellNum).getNumericCellValue();
// The combination of Account Number, Source Application and Class is unique in the Excel file (logically, it's like a PK).
// That means, that a same combination of Account Number & Class can appear in the Excel more than once - under different Source Applications.
// The processed dollar amount field could already be processed (added to Zoho record) for this Account Number previously,
// under (an)other source Source Application(s) - let's see if an already inserted value exists:
double valueExistingInRecord = (double) zohoRecord.getFieldValue(zohoFieldName);
if (valueExistingInRecord != 0) {
// Don't override the already inserted value. Instead, summarize it with the value we are copying from Excel now:
valueToSet = valueExistingInRecord + valueFromExcel;
}
} catch (IllegalStateException | NumberFormatException e) {
MainApplication.getLogger().warn("Cell: (" + (excelRow.getRowNum() + 1) + ", " + (excelCellNum + 1) + "). Error: " + e.getMessage());
} catch (ZCRMException e) {
String accountNumber = excelRow.getCell(EXCEL_CELL_NUM__ACCOUNT_NUMBER).getStringCellValue();
MainApplication.getLogger().warn("Faild to get value of " + zohoFieldName + " field in record for account #" + accountNumber +
". Error: " + e.getMessage());
}
zohoRecord.setFieldValue(zohoFieldName, valueToSet);
}
/**********************************************************************************************************************************************************/
private void setLossRatio
(XSSFRow excelRow
,ZCRMRecord zohoRecord
,String zohoClass /* like "Commercial_Property" */)
{
double lossRatio = 0;
try {
double earnedPremium = (double) zohoRecord.getFieldValue("Earned_Premium_" + zohoClass);
if (earnedPremium != 0) {
double incurredAmount = (double) zohoRecord.getFieldValue("Incurred_Amount_" + zohoClass);
lossRatio = (incurredAmount / earnedPremium);
lossRatio *= 100; // 0.12345678 >>> 12.345678
lossRatio = Math.round(lossRatio); // 12.345678 >>> 12
}
} catch (ZCRMException e) {
String accountNumber = excelRow.getCell(EXCEL_CELL_NUM__ACCOUNT_NUMBER).getStringCellValue();
MainApplication.getLogger().warn("Faild to get value of Earned_Premium_" + zohoClass + " field in record for account #" + accountNumber +
". Error: " + e.getMessage());
}
zohoRecord.setFieldValue("Loss_Ratio_" + zohoClass, lossRatio);
}
/***********************************************************************************************************************************************************/
private String getReportYear
(XSSFWorkbook workbook)
{
XSSFSheet secondSheet = workbook.getSheetAt(1); // the 2nd sheet contains service info
XSSFRow excelRow = secondSheet.getRow(0);
String reportYear = excelRow.getCell(1).getStringCellValue(); // cell B1
return reportYear;
}