package is.idega.idegaweb.egov.bpm.cases.board;
import is.idega.idegaweb.egov.bpm.IWBundleStarter;
import is.idega.idegaweb.egov.bpm.business.TaskViewerHelper;
import is.idega.idegaweb.egov.bpm.cases.CaseProcessInstanceRelationImpl;
import is.idega.idegaweb.egov.bpm.cases.actionhandlers.CaseHandlerAssignmentHandler;
import is.idega.idegaweb.egov.bpm.cases.manager.BPMCasesRetrievalManager;
import is.idega.idegaweb.egov.bpm.cases.presentation.beans.BPMProcessVariablesBean;
import is.idega.idegaweb.egov.cases.business.BoardCasesComparator;
import is.idega.idegaweb.egov.cases.business.BoardCasesManager;
import is.idega.idegaweb.egov.cases.data.GeneralCase;
import is.idega.idegaweb.egov.cases.data.GeneralCaseBMPBean;
import is.idega.idegaweb.egov.cases.presentation.CasesBoardViewCustomizer;
import is.idega.idegaweb.egov.cases.presentation.CasesBoardViewer;
import is.idega.idegaweb.egov.cases.presentation.beans.CaseBoardBean;
import is.idega.idegaweb.egov.cases.presentation.beans.CaseBoardTableBean;
import is.idega.idegaweb.egov.cases.presentation.beans.CaseBoardTableBodyRowBean;
import is.idega.idegaweb.egov.cases.util.CasesConstants;
import java.io.Serializable;
import java.math.BigDecimal;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.exe.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.idega.block.process.business.ProcessConstants;
import com.idega.block.process.data.Case;
import com.idega.block.process.data.CaseBMPBean;
import com.idega.block.process.data.CaseHome;
import com.idega.bpm.xformsview.converters.ObjectCollectionConverter;
import com.idega.builder.bean.AdvancedProperty;
import com.idega.business.IBOLookup;
import com.idega.core.contact.data.Email;
import com.idega.data.IDOLookup;
import com.idega.data.IDOLookupException;
import com.idega.idegaweb.IWBundle;
import com.idega.idegaweb.IWMainApplication;
import com.idega.idegaweb.IWResourceBundle;
import com.idega.jbpm.bean.VariableByteArrayInstance;
import com.idega.jbpm.bean.VariableInstanceInfo;
import com.idega.jbpm.data.VariableInstanceQuerier;
import com.idega.jbpm.data.dao.BPMDAO;
import com.idega.jbpm.utils.JBPMConstants;
import com.idega.presentation.IWContext;
import com.idega.user.business.NoEmailFoundException;
import com.idega.user.business.UserBusiness;
import com.idega.user.data.User;
import com.idega.util.ArrayUtil;
import com.idega.util.CoreConstants;
import com.idega.util.CoreUtil;
import com.idega.util.ListUtil;
import com.idega.util.StringHandler;
import com.idega.util.StringUtil;
import com.idega.util.WebUtil;
import com.idega.util.datastructures.map.MapUtil;
import com.idega.util.expression.ELUtil;
@Service(BoardCasesManager.BEAN_NAME)
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class BoardCasesManagerImpl implements BoardCasesManager {
protected static final List<String> GRADING_VARIABLES = Collections.unmodifiableList(Arrays.asList(
"string_ownerInnovationalValue", // 0
"string_ownerCompetitionValue", // 1
"string_ownerEntrepreneursValue", // 2
"string_ownerPossibleDevelopments", // 3
"string_ownerNatureStatus", // 4
"string_ownerApplication", // 5
"string_ownerOverturn", // 6
"string_ownerProceeds", // 7
"string_ownerEconomist", // 8
"string_ownerEmployees", // 9
"string_ownerForsvarsmenn", // 10
"string_ownerConstant", // 11
"string_ownerNewConstant", // 12
"string_ownerBusiness", // 13
"string_ownerProject", // 14
"string_ownerCostValue", // 15
"string_ownerProjectedSize", // 16
"string_ownerEntrepreneurCompany", // 17
"string_expectedResultDescriptionValue", // 18
"string_possibleImpactValue", // 19
"string_financeDescriptionValue", // 20
"string_costAndMainTasksGrade", // 21
"string_planForFundingGrade", // 22
"string_evaluationOfOtherGrantsGrade", // 23
"string_specialProjectValue", // 24
"string_estimatedSaleValue" // 25
));
protected static final Logger LOGGER = Logger.getLogger(BoardCasesManagerImpl.class.getName());
public static final String BOARD_CASES_LIST_SORTING_PREFERENCES = "boardCasesListSortingPreferencesAttribute";
@Autowired
private BPMCasesRetrievalManager caseManager;
@Autowired
private CaseProcessInstanceRelationImpl caseProcessInstanceRelation;
@Autowired
private VariableInstanceQuerier variablesQuerier;
@Autowired
private TaskViewerHelper taskViewer;
private List<String> variables;
private CaseHome caseHome = null;
@Autowired
private BPMDAO bpmDAO;
protected BPMDAO getBPMDAO() {
if (this.bpmDAO == null) {
ELUtil.getInstance().autowire(this);
}
return this.bpmDAO;
}
protected CaseHome getCaseHome() {
if (this.caseHome == null) {
try {
this.caseHome = (CaseHome) IDOLookup.getHome(Case.class);
} catch (IDOLookupException e) {
java.util.logging.Logger.getLogger(getClass().getName()).log(
Level.WARNING, "Failed to get home for " + Case.class, e);
}
}
return this.caseHome;
}
@Override
public List<CaseBoardBean> getAllSortedCases(
Collection<String> caseStatuses,
String processName,
String uuid,
boolean isSubscribedOnly,
boolean backPage,
String taskName,
Date dateFrom,
Date dateTo) {
// Getting cases by the configuration
Collection<GeneralCase> cases = getCases(
caseStatuses,
processName,
isSubscribedOnly,
ProcessConstants.BPM_CASE,
dateFrom,
dateTo);
if (ListUtil.isEmpty(cases))
return null;
// Filling beans with info
List<CaseBoardBean> boardCases = getFilledBoardCaseWithInfo(
cases,
uuid,
backPage,
taskName);
if (ListUtil.isEmpty(boardCases))
return null;
sortBoardCases(boardCases);
return boardCases;
}
protected List<CaseBoardBean> getFilledBoardCaseWithInfo(
Collection<? extends GeneralCase> casesIdsAndHandlers,
String uuid,
boolean backPage,
String taskName) {
List<String> variablesToQuery = new ArrayList<String>(getVariables(uuid));
if (variablesToQuery.contains(CasesBoardViewCustomizer.FINANCING_TABLE_COLUMN)) {
variablesToQuery.remove(CasesBoardViewCustomizer.FINANCING_TABLE_COLUMN);
variablesToQuery.add(ProcessConstants.FINANCING_OF_THE_TASKS);
}
variablesToQuery.add(ProcessConstants.BOARD_FINANCING_SUGGESTION);
variablesToQuery.add(ProcessConstants.BOARD_FINANCING_DECISION);
List<String> allVariables = new ArrayList<String>(variablesToQuery);
allVariables.addAll(getGradingVariables());
List<CaseBoardView> boardViews = getVariablesValuesByNamesForCases(casesIdsAndHandlers, allVariables);
if (ListUtil.isEmpty(boardViews))
return null;
List<String> numberVariables = Arrays.asList(
CaseBoardBean.CASE_OWNER_TOTAL_COST,
CasesConstants.APPLIED_GRANT_AMOUNT_VARIABLE,
ProcessConstants.BOARD_FINANCING_SUGGESTION,
ProcessConstants.BOARD_FINANCING_DECISION
);
/* Formatting links */
Map<Long, ProcessInstance> relations = new HashMap<Long, ProcessInstance>();
for (CaseBoardView view: boardViews) {
relations.put(Long.valueOf(view.getCaseId()), view.getProcessInstance());
}
Map<Long, String> links = getTaskViewer().getLinksToTheTaskRedirector(
CoreUtil.getIWContext(), relations, backPage, taskName);
/* Filling board cases */
List<CaseBoardBean> boardCases = new ArrayList<CaseBoardBean>();
for (CaseBoardView view: boardViews) {
CaseBoardBean boardCase = new CaseBoardBean(view.getCaseId(), view.getProcessInstanceId());
boardCase.setApplicantName(view.getValue(CaseBoardBean.CASE_OWNER_FULL_NAME));
boardCase.setCaseIdentifier(view.getValue(ProcessConstants.CASE_IDENTIFIER));
boardCase.setCategory(view.getValue(CaseBoardBean.CASE_CATEGORY));
boardCase.setHandler(view.getHandler());
boardCase.setFinancingOfTheTasks(view.getFinancingOfTheTasks());
boardCase.setLinkToCase(links.get(Long.valueOf(view.getCaseId())));
long boardDecision = getNumberValue(view.getValue(ProcessConstants.BOARD_FINANCING_DECISION), false);
boardCase.setBoardAmount(boardDecision);
long boardSuggestion = getNumberValue(view.getValue(ProcessConstants.BOARD_FINANCING_SUGGESTION), false);
boardCase.setGrantAmountSuggestion(boardSuggestion);
boardCase.addValues(getGradingSum(view, getGradingVariables()));
for (String variable: variablesToQuery) {
String value = view.getValue(variable);
if (numberVariables.contains(variable)) {
if (variable.equals(ProcessConstants.BOARD_FINANCING_DECISION) || variable.equals(ProcessConstants.BOARD_FINANCING_SUGGESTION))
value = String.valueOf(getNumberValue(value, false));
else
value = String.valueOf(getNumberValue(value, true));
}
boardCase.addValue(variable, value);
}
boardCases.add(boardCase);
}
return boardCases;
}
private CaseBoardView getCaseView(List<CaseBoardView> views, Long processInstanceId) {
if (ListUtil.isEmpty(views) || processInstanceId == null)
return null;
for (CaseBoardView view: views) {
if (processInstanceId.longValue() == view.getProcessInstanceId().longValue()) {
return view;
}
}
return null;
}
@Transactional(readOnly = true, propagation = Propagation.REQUIRED)
protected List<CaseBoardView> getVariablesValuesByNamesForCases(
Collection<? extends GeneralCase> cases,
List<String> variablesNames
) {
/* Getting relations between cases and process instances */
Map<ProcessInstance, Case> casesAndProcesses = getCaseProcessInstanceRelation()
.getCasesAndProcessInstances(cases);
/* Getting variables */
Collection<VariableInstanceInfo> variables = getVariablesQuerier().getVariables(
variablesNames, casesAndProcesses.keySet(), Boolean.TRUE, Boolean.FALSE, Boolean.FALSE);
if (ListUtil.isEmpty(variables)) {
LOGGER.warning("Didn't find any variables values for processes " + casesAndProcesses.values() + " and variables names " + variablesNames);
return null;
}
List<CaseBoardView> views = new ArrayList<CaseBoardView>();
for (VariableInstanceInfo variable: variables) {
Serializable value = variable.getValue();
if (variable.getName() != null && value != null && variable.getProcessInstanceId() != null) {
Long processInstanceId = variable.getProcessInstanceId();
CaseBoardView view = getCaseView(views, processInstanceId);
if (view == null) {
GeneralCase theCase = getCaseProcessInstanceRelation().getCase(casesAndProcesses, processInstanceId);
if (theCase == null) {
LOGGER.warning("Case ID was not found in " + casesAndProcesses + " for process instance ID: " + processInstanceId);
LOGGER.warning("Couldn't get view bean for process: " + processInstanceId + ": " + casesAndProcesses);
continue;
}
view = new CaseBoardView(theCase.getPrimaryKey().toString(), processInstanceId);
view.setHandler(theCase.getHandledBy());
view.setProcessInstance(
getCaseProcessInstanceRelation().getProcessInstance(
casesAndProcesses, processInstanceId));
views.add(view);
}
if (variable instanceof VariableByteArrayInstance) {
if (ProcessConstants.FINANCING_OF_THE_TASKS.equals(variable.getName())) {
List<Map<String, String>> obValue = getObjectValue((VariableByteArrayInstance) variable);
List<Map<String, String>> financing = view.getFinancingOfTheTasks();
if (financing == null)
view.setFinancingOfTheTasks(obValue);
else {
int taskIndex = 0;
for (Map<String, String> taskInfo: obValue) {
if (MapUtil.isEmpty(taskInfo))
continue;
String taskName = taskInfo.get("task");
if (StringUtil.isEmpty(taskName))
continue;
String estimatedCost = taskInfo.get("cost_estimate");
Map<String, String> taskInfoFromBoard = taskIndex < financing.size() ? financing.get(taskIndex) : null;
if (taskInfoFromBoard == null) {
taskInfoFromBoard = new HashMap<String, String>();
financing.add(taskInfoFromBoard);
}
taskInfoFromBoard.put(CasesBoardViewer.WORK_ITEM, taskName);
taskInfoFromBoard.put(CasesBoardViewer.ESTIMATED_COST, estimatedCost);
String tmp = taskInfoFromBoard.get(ProcessConstants.BOARD_FINANCING_SUGGESTION);
if (StringUtil.isEmpty(tmp))
taskInfoFromBoard.put(ProcessConstants.BOARD_FINANCING_SUGGESTION, CoreConstants.MINUS);
tmp = taskInfoFromBoard.get(ProcessConstants.BOARD_FINANCING_DECISION);
if (StringUtil.isEmpty(tmp))
taskInfoFromBoard.put(ProcessConstants.BOARD_FINANCING_DECISION, CoreConstants.MINUS);
taskIndex++;
}
}
} else if (ProcessConstants.BOARD_FINANCING_SUGGESTION.equals(variable.getName())) {
fillWithBoardInfoOnTheTasks(variable, view, CasesBoardViewer.BOARD_SUGGESTION);
} else if (ProcessConstants.BOARD_FINANCING_DECISION.equals(variable.getName())) {
fillWithBoardInfoOnTheTasks(variable, view, CasesBoardViewer.BOARD_DECISION);
}
} else if (ProcessConstants.BOARD_FINANCING_SUGGESTION.equals(variable.getName())) {
fillWithBoardInfoOnTheTasks(variable, view, CasesBoardViewer.BOARD_SUGGESTION);
view.addVariable(variable.getName(), value.toString());
} else if (ProcessConstants.BOARD_FINANCING_DECISION.equals(variable.getName())) {
fillWithBoardInfoOnTheTasks(variable, view, CasesBoardViewer.BOARD_DECISION);
view.addVariable(variable.getName(), value.toString());
} else
view.addVariable(variable.getName(), value.toString());
} else {
LOGGER.warning(variable + " can not be added to board view!");
}
}
return views;
}
private void fillWithBoardInfoOnTheTasks(VariableInstanceInfo variable, CaseBoardView view, String key) {
if (variable instanceof VariableByteArrayInstance) {
Object tmpValue = variable.getValue();
if (tmpValue instanceof Collection<?>) {
List<Map<String, String>> financing = view.getFinancingOfTheTasks();
if (!ListUtil.isEmpty(financing)) {
Collection<?> info = (Collection<?>) tmpValue;
int index = 0;
for (Object infoItem: info) {
Map<String, String> cells = financing.get(index);
if (cells == null)
continue;
cells.put(key, infoItem.toString());
index++;
}
}
}
return;
}
Serializable value = variable.getValue();
if (value == null)
return;
List<Map<String, String>> financing = view.getFinancingOfTheTasks();
if (financing == null) {
financing = new ArrayList<Map<String,String>>();
view.setFinancingOfTheTasks(financing);
}
String[] amounts = value.toString().split(CoreConstants.HASH);
if (ArrayUtil.isEmpty(amounts))
return;
int index = 0;
for (String amount: amounts) {
Map<String, String> cells = index < financing.size() ? financing.get(index) : null;
if (cells == null) {
cells = new HashMap<String, String>();
financing.add(index, cells);
}
cells.put(key, amount);
index++;
}
}
private List<Map<String, String>> getObjectValue(VariableByteArrayInstance variable) {
Serializable value = variable.getValue();
if (value == null)
return Collections.emptyList();
List<Map<String, String>> object = new ArrayList<Map<String,String>>();
if (value instanceof Collection<?>) {
Collection<?> jsonParts = (Collection<?>) value;
for (Object jsonPart: jsonParts) {
Map<String, String> genericValue = ObjectCollectionConverter.JSONToObj(jsonPart.toString());
if (genericValue != null)
object.add(genericValue);
}
}
return object;
}
@Override
public Long getNumberValue(String value) {
return getNumberValue(value, false);
}
protected Long getNumberValue(String value, boolean dropThousands) {
if (StringUtil.isEmpty(getStringValue(value)))
return Long.valueOf(0);
String originalValue = value;
value = value.replaceAll(CoreConstants.SPACE, CoreConstants.EMPTY);
value = value.replace(CoreConstants.DOT, CoreConstants.EMPTY);
value = value.replace("þús", CoreConstants.EMPTY);
value = value.replaceAll("kr", CoreConstants.EMPTY);
value = StringHandler.replace(value, "d", CoreConstants.EMPTY);
value = StringHandler.replace(value, CoreConstants.QOUTE_SINGLE_MARK, CoreConstants.EMPTY);
if (StringUtil.isEmpty(value))
return Long.valueOf(0);
long total = 0;
String amounts[] = value.split(CoreConstants.HASH);
boolean logInfo = amounts.length > 2;
for (String amount: amounts) {
amount = StringHandler.replace(amount, CoreConstants.HASH, CoreConstants.EMPTY);
Double numberValue = null;
try {
numberValue = Double.valueOf(amount);
if (dropThousands)
numberValue = Double.valueOf(numberValue.doubleValue() / 1000);
total += numberValue.longValue();
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Error getting number value from: " + value);
return Long.valueOf(0);
}
}
if (logInfo) {
LOGGER.info("Computed total value " + total + " from '" + originalValue + "'");
}
return total;
}
@SuppressWarnings("unchecked")
private void sortBoardCases(List<CaseBoardBean> boardCases) {
if (ListUtil.isEmpty(boardCases))
return;
List<String> sortingPreferences = null;
Object o = CoreUtil.getIWContext().getSessionAttribute(BOARD_CASES_LIST_SORTING_PREFERENCES);
if (o instanceof List)
sortingPreferences = (List<String>) o;
Collections.sort(boardCases, new BoardCasesComparator(
CoreUtil.getCurrentLocale(), sortingPreferences));
}
/**
*
* @param caseStatuses is {@link Collection} of {@link Case#getStatus()},
* skipped if <code>null</code>;
* @param processName is {@link ProcessDefinition#getName()},
* skipped if <code>null</code>
* @param subscribedOnly
* @param caseManagerType
* @param dateCreatedFrom is floor of {@link Case#getCreated()},
* skipped if <code>null</code>;
* @param dateCreatedTo is ceiling of {@link Case#getCreated()},
* skipped if <code>null</code>;
* @return entities by criteria or {@link Collections#emptyList()} on failure;
*/
protected Collection<GeneralCase> getCases(
Collection<String> caseStatuses,
String processName,
boolean subscribedOnly,
String caseManagerType,
Date dateCreatedFrom,
Date dateCreatedTo) {
Collection<Case> allCases = getCaseManager().getCases(
Arrays.asList(processName),
null,
caseStatuses,
subscribedOnly ? Arrays.asList(getIWContext().getCurrentUser()): null,
Arrays.asList(caseManagerType),
dateCreatedFrom,
dateCreatedTo);
if (ListUtil.isEmpty(allCases)) {
return null;
}
Collection<GeneralCase> bpmCases = new ArrayList<GeneralCase>();
for (Case theCase: allCases) {
if (!(theCase instanceof GeneralCase) || theCase.isClosed()) {
continue;
}
bpmCases.add((GeneralCase) theCase);
}
return bpmCases;
}
/**
*
* <p>Checks if {@link GeneralCaseBMPBean} and {@link CaseBMPBean}
* has same primary keys, if so, then <code>true</code> is returned.</p>
* @param cases where to search for specified {@link Case} in,
* not <code>null</code>;
* @param theCase to search for, not <code>null</code>;
* @return <code>true</code> if {@link Case} found, <code>false</code>
* otherwise.
* @author <a href="mailto:martynas@idega.is">Martynas Stakė</a>
*/
protected boolean contains(Collection<Case> cases, Case theCase) {
if (ListUtil.isEmpty(cases) || theCase == null) {
return Boolean.FALSE;
}
for (Case c : cases) {
if (theCase.getPrimaryKey().equals(c.getPrimaryKey())) {
return Boolean.TRUE;
}
}
return Boolean.FALSE;
}
protected BPMCasesRetrievalManager getCaseManager() {
if (caseManager == null) {
ELUtil.getInstance().autowire(this);
}
return caseManager;
}
protected List<String> getVariables(String uuid) {
if (variables == null) {
List<String> customColumns = getCustomColumns(uuid);
if (ListUtil.isEmpty(customColumns)) {
variables = new ArrayList<String>(CasesBoardViewer.CASE_FIELDS.size());
for (AdvancedProperty variable : CasesBoardViewer.CASE_FIELDS) {
variables.add(variable.getId());
}
} else
variables = new ArrayList<String>(customColumns);
}
return variables;
}
protected List<String> getGradingVariables() {
return GRADING_VARIABLES;
}
/**
*
* @return {@link Map} of variable name and sum of grading values;
*/
public Map<String, BigDecimal> getGradingSum(
CaseBoardView view,
List<String> variables) {
Map<String, BigDecimal> gradings = new HashMap<String, BigDecimal>();
List<String> gradingValues = view.getValues(variables);
if (ListUtil.isEmpty(gradingValues))
return gradings;
BigDecimal sum = new BigDecimal(0);
BigDecimal negativeSum = new BigDecimal(0);
for (String value: gradingValues) {
if (StringUtil.isEmpty(getStringValue(value))) {
continue;
}
if (value.contains("_")) {
value = value.substring(0, value.indexOf("_"));
}
if (value.contains("a")) {
value = value.substring(0, value.indexOf("a"));
}
if (value.contains("b")) {
value = value.substring(0, value.indexOf("b"));
}
if (value.contains("c")) {
value = value.substring(0, value.indexOf("c"));
}
Long gradeValue = null;
try {
gradeValue = Long.valueOf(value.trim());
} catch (Exception e) {
LOGGER.warning("Unable to convert '" + value + "' to number!");
}
if (gradeValue != null) {
sum = sum.add(BigDecimal.valueOf(gradeValue));
if (gradeValue < 0) {
negativeSum = negativeSum.add(BigDecimal.valueOf(gradeValue));
}
}
}
gradings.put(CaseBoardBean.CASE_SUM_ALL_GRADES, sum);
gradings.put(CaseBoardBean.CASE_SUM_OF_NEGATIVE_GRADES, negativeSum);
return gradings;
}
@Override
public boolean isEqual(String currentColumn, String columnOfDomain) {
return !StringUtil.isEmpty(currentColumn) &&
!StringUtil.isEmpty(columnOfDomain) &&
currentColumn.equals(columnOfDomain);
}
@Override
public CaseBoardTableBean getTableData(
Date dateFrom,
Date dateTo,
Collection<String> caseStatuses,
String processName,
String uuid,
boolean isSubscribedOnly,
boolean useBasePage,
String taskName) {
CaseBoardTableBean data = new CaseBoardTableBean();
List<CaseBoardBean> boardCases = getAllSortedCases(
caseStatuses,
processName,
uuid,
isSubscribedOnly,
useBasePage,
taskName,
dateFrom,
dateTo);
if (ListUtil.isEmpty(boardCases)) {
data.setErrorMessage(localize("cases_board_viewer.no_cases_found", "There are no cases!"));
return data;
}
// Header
data.setHeaderLabels(getTableHeaders(uuid));
// Body
Map<Integer, List<AdvancedProperty>> columns = getColumns(uuid);
BigDecimal boardAmountTotal = new BigDecimal(0);
BigDecimal grantAmountSuggestionTotal = new BigDecimal(0);
boolean financingTableAdded = false;
String uniqueCaseId = "uniqueCaseId";
List<CaseBoardTableBodyRowBean> bodyRows = new ArrayList<CaseBoardTableBodyRowBean>(boardCases.size());
for (CaseBoardBean caseBoard: boardCases) {
CaseBoardTableBodyRowBean rowBean = new CaseBoardTableBodyRowBean(
caseBoard.getCaseId(),
caseBoard.getProcessInstanceId());
rowBean.setId(new StringBuilder(uniqueCaseId).append(caseBoard.getCaseId()).toString());
rowBean.setCaseIdentifier(caseBoard.getCaseIdentifier());
rowBean.setHandler(caseBoard.getHandler());
rowBean.setLinkToCase(caseBoard.getLinkToCase());
// Table of financing
updateTasksInfo(caseBoard);
int index = 0;
Map<Integer, List<AdvancedProperty>> rowValues = new TreeMap<Integer, List<AdvancedProperty>>();
for (Integer key: columns.keySet()) {
List<AdvancedProperty> columnLabels = columns.get(key);
for (AdvancedProperty column: columnLabels) {
if (isEqual(column.getId(), ProcessConstants.CASE_IDENTIFIER))
// Link to grading task
rowValues.put(index, Arrays.asList(new AdvancedProperty(column.getId(), caseBoard.getCaseIdentifier())));
else if (column.getId().equals(CaseHandlerAssignmentHandler.handlerUserIdVarName)) {
// Handler
rowValues.put(index,
Arrays.asList(new AdvancedProperty(
CaseHandlerAssignmentHandler.handlerUserIdVarName,
caseBoard.getHandler() == null ? String.valueOf(-1) : caseBoard.getHandler().getId())));
// Financing table
} else if (isEqual(column.getId(), CasesBoardViewer.WORK_ITEM)) {
financingTableAdded = true;
rowBean.setFinancingInfo(caseBoard.getFinancingOfTheTasks());
rowValues.put(index, Arrays.asList(new AdvancedProperty(
ProcessConstants.FINANCING_OF_THE_TASKS,
CoreConstants.EMPTY)));
} else if (isEqual(column.getId(), CasesBoardViewer.ESTIMATED_COST)) {
} else if (isEqual(column.getId(), CasesBoardViewer.BOARD_SUGGESTION)) {
} else if (isEqual(column.getId(), CasesBoardViewer.BOARD_DECISION)) {
} else if (isEqual(column.getId(), CasesBoardViewer.BOARD_PROPOSAL_FOR_GRANT)) {
} else if (isEqual(column.getId(), CaseBoardBean.CASE_OWNER_GENDER)) {
String value = caseBoard.getValue(CaseBoardBean.CASE_OWNER_GENDER);
rowValues.put(index, Arrays.asList(new AdvancedProperty(
CaseBoardBean.CASE_OWNER_GENDER, localize(value, value))));
// Other value
} else
rowValues.put(index, Arrays.asList(new AdvancedProperty(
column.getId(), caseBoard.getValue(column.getId()))));
// Calculations
if (isEqual(column.getId(), ProcessConstants.BOARD_FINANCING_DECISION))
// Calculating board amounts
boardAmountTotal = boardAmountTotal.add(caseBoard.getBoardAmount());
else if (isEqual(column.getId(), ProcessConstants.BOARD_FINANCING_SUGGESTION))
// Calculating grant amount suggestions
grantAmountSuggestionTotal = grantAmountSuggestionTotal.add(caseBoard.getGrantAmountSuggestion());
}
index++;
}
rowBean.setValues(rowValues);
bodyRows.add(rowBean);
}
data.setBodyBeans(bodyRows);
// Footer
data.setFooterValues(getFooterValues(data.getBodyBeans().get(0).getValues().keySet().size() + (financingTableAdded ? 3 : 0),
grantAmountSuggestionTotal, boardAmountTotal, uuid));
// Everything is OK
data.setFilledWithData(Boolean.TRUE);
return data;
}
/*
* (non-Javadoc)
* @see is.idega.idegaweb.egov.cases.business.BoardCasesManager#getTableData(com.idega.presentation.IWContext, java.util.Collection, java.lang.String, java.lang.String, boolean, boolean, java.lang.String)
*/
@Override
public CaseBoardTableBean getTableData(
Collection<String> caseStatuses,
String processName,
String uuid,
boolean isSubscribedOnly,
boolean backPage,
String taskName) {
return getTableData(null, null, caseStatuses, processName, uuid, isSubscribedOnly, backPage, taskName);
}
@Override
public AdvancedProperty getHandlerInfo(IWContext iwc, User handler) {
if (handler == null)
return null;
UserBusiness userBusiness = null;
try {
userBusiness = IBOLookup.getServiceInstance(iwc, UserBusiness.class);
} catch(RemoteException e) {
LOGGER.log(Level.WARNING, "Error getting " + UserBusiness.class, e);
}
if (userBusiness == null)
return null;
AdvancedProperty info = new AdvancedProperty(handler.getName());
Email email = null;
try {
email = userBusiness.getUsersMainEmail(handler);
} catch (RemoteException e) {
LOGGER.log(Level.WARNING, "Error getting email for user: " + handler, e);
} catch (NoEmailFoundException e) {}
if (email != null)
info.setValue(new StringBuilder("mailto:").append(email.getEmailAddress()).toString());
return info;
}
protected static final String LOCALIZATION_PREFIX = "case_board_viewer.";
@Override
public List<String> getCustomColumns(String uuid) {
if (StringUtil.isEmpty(uuid))
return Collections.emptyList();
IWContext iwc = CoreUtil.getIWContext();
Object customColumns = iwc.getSessionAttribute(CasesBoardViewer.PARAMETER_CUSTOM_COLUMNS + uuid);
if (customColumns instanceof List<?>) {
@SuppressWarnings("unchecked")
List<String> columns = (List<String>) customColumns;
return columns;
}
return null;
}
@Override
public Map<Integer, List<AdvancedProperty>> getColumns(String uuid) {
Map<Integer, List<AdvancedProperty>> columns = new TreeMap<Integer, List<AdvancedProperty>>();
int index = 1;
List<String> customColumns = getCustomColumns(uuid);
if (ListUtil.isEmpty(customColumns)) {
for (AdvancedProperty header: CasesBoardViewer.CASE_FIELDS) {
if (index == 15) {
columns.put(index, Arrays.asList(
new AdvancedProperty(CasesBoardViewer.WORK_ITEM,
localize(CasesBoardViewer.WORK_ITEM, "Work item")),
new AdvancedProperty(CasesBoardViewer.ESTIMATED_COST,
localize(CasesBoardViewer.ESTIMATED_COST, "Estimated cost")),
new AdvancedProperty(CasesBoardViewer.BOARD_PROPOSAL_FOR_GRANT,
localize(CasesBoardViewer.BOARD_PROPOSAL_FOR_GRANT, "Proposed funding")),
new AdvancedProperty(CasesBoardViewer.BOARD_SUGGESTION,
localize(CasesBoardViewer.BOARD_SUGGESTION.toLowerCase(), "Handler suggestions")),
new AdvancedProperty(CasesBoardViewer.BOARD_DECISION,
localize(CasesBoardViewer.BOARD_DECISION.toLowerCase(), "Board decision"))
));
} else {
columns.put(index, Arrays.asList(new AdvancedProperty(header.getId(),
localize(new StringBuilder(LOCALIZATION_PREFIX).append(header.getId()).toString(), header.getValue()))));
}
index++;
}
columns.put(index, Arrays.asList(new AdvancedProperty(CaseHandlerAssignmentHandler.handlerUserIdVarName,
localize(LOCALIZATION_PREFIX + CaseHandlerAssignmentHandler.handlerUserIdVarName, "Case handler"))));
} else {
String localized = null;
IWContext iwc = CoreUtil.getIWContext();
IWResourceBundle bpmIWRB = iwc.getIWMainApplication().getBundle(IWBundleStarter.IW_BUNDLE_IDENTIFIER).getResourceBundle(iwc);
for (String column: customColumns) {
if (CasesBoardViewCustomizer.FINANCING_TABLE_COLUMN.equals(column)) {
columns.put(index, Arrays.asList(
new AdvancedProperty(CasesBoardViewer.WORK_ITEM, localize(CasesBoardViewer.WORK_ITEM, "Work item")),
new AdvancedProperty(CasesBoardViewer.ESTIMATED_COST, localize(CasesBoardViewer.ESTIMATED_COST,
"Estimated cost")),
new AdvancedProperty(CasesBoardViewer.BOARD_SUGGESTION, localize(CasesBoardViewer.BOARD_SUGGESTION,
"Board suggestion")),
new AdvancedProperty(CasesBoardViewer.BOARD_DECISION, localize(CasesBoardViewer.BOARD_DECISION,
"Board decision"))
));
} else if (CasesBoardViewer.ESTIMATED_COST.equals(column) || CasesBoardViewer.BOARD_SUGGESTION.equals(column) ||
CasesBoardViewer.BOARD_DECISION.equals(column) || CasesBoardViewer.BOARD_PROPOSAL_FOR_GRANT.equals(column))
continue;
else {
localized = localize(LOCALIZATION_PREFIX.concat(column), column);
if (column.equals(localized))
localized = bpmIWRB.getLocalizedString(JBPMConstants.VARIABLE_LOCALIZATION_PREFIX.concat(column), column);
if (column.equals(localized)) {
LOGGER.warning("Variable " + column + " is not localized");
continue;
}
columns.put(index, Arrays.asList(new AdvancedProperty(column, localized)));
}
index++;
}
}
return columns;
}
protected Map<Integer, List<AdvancedProperty>> getTableHeaders(String uuid) {
return getColumns(uuid);
}
protected List<String> getFooterValues(
int numberOfColumns,
BigDecimal grantAmountSuggestionTotal,
BigDecimal boardAmountTotal,
String uuid) {
List<String> values = new ArrayList<String>();
int indexOfTotal = getIndexOfColumn(ProcessConstants.FINANCING_OF_THE_TASKS, uuid);
if (indexOfTotal < 0)
indexOfTotal = getIndexOfColumn(CasesBoardViewCustomizer.FINANCING_TABLE_COLUMN, uuid);
int indexOfSuggestion = indexOfTotal + 3;
int indexOfDecision = indexOfSuggestion + 1;
String total = localize("case_board_viewer.total_sum", "Total").concat(CoreConstants.COLON).toString();
for (int i = 0; i < numberOfColumns; i++) {
if (indexOfTotal > -1 && indexOfTotal == i) {
// SUMs label
values.add(total);
} else if (i == indexOfSuggestion) {
// Grant amount suggestions
values.add(String.valueOf(grantAmountSuggestionTotal));
} else if (i == indexOfDecision) {
// Board amount
values.add(String.valueOf(boardAmountTotal));
} else
values.add(CoreConstants.EMPTY);
}
if (values.size() <= indexOfTotal)
values.add(total);
if (values.size() <= indexOfSuggestion)
values.add(String.valueOf(grantAmountSuggestionTotal));
if (values.size() <= indexOfDecision)
values.add(String.valueOf(boardAmountTotal));
values.add(CoreConstants.EMPTY);
return values;
}
@Override
public int getIndexOfColumn(String column, String uuid) {
List<String> columns = getVariables(uuid);
return columns.indexOf(column);
}
protected CaseProcessInstanceRelationImpl getCaseProcessInstanceRelation() {
return caseProcessInstanceRelation;
}
private String getStringValue(String value) {
if (StringUtil.isEmpty(value) || "no_value".equals(value) || CoreConstants.MINUS.equals(value))
return CoreConstants.EMPTY;
return value;
}
protected class CaseBoardView {
private String caseId;
private Long processInstanceId;
private ProcessInstance processInstance;
private User handler;
private List<AdvancedProperty> variables = new ArrayList<AdvancedProperty>();
private List<Map<String, String>> financingOfTheTasks;
private CaseBoardView(String caseId, Long processInstanceId) {
this.caseId = caseId;
this.processInstanceId = processInstanceId;
}
public ProcessInstance getProcessInstance() {
return processInstance;
}
public void setProcessInstance(ProcessInstance processInstance) {
this.processInstance = processInstance;
}
public String getCaseId() {
return caseId;
}
public Long getProcessInstanceId() {
return processInstanceId;
}
public List<AdvancedProperty> getVariables() {
return variables;
}
public void addVariable(String name, String value) {
if (StringUtil.isEmpty(name) || StringUtil.isEmpty(value)) {
LOGGER.warning("Variable value or name (name=" + name + ", value=" +value+ ", case=" + caseId + ", piId=" + processInstanceId +
") is undefined!");
return;
}
AdvancedProperty variable = getVariable(getVariables(), name);
if (variable == null) {
getVariables().add(new AdvancedProperty(name, value));
return;
}
if (value.equals(variable.getValue())) {
return;
}
variable.setValue(value);
return;
}
public String getValue(String variableName) {
AdvancedProperty variable = getVariable(getVariables(), variableName);
return getStringValue(variable == null ? null : variable.getValue());
}
public List<String> getValues(List<String> variablesNames) {
if (ListUtil.isEmpty(variablesNames)) {
return null;
}
List<String> values = new ArrayList<String>();
for (String variableName: variablesNames) {
values.add(getValue(variableName));
}
return values;
}
public User getHandler() {
return handler;
}
public void setHandler(User handler) {
this.handler = handler;
}
public List<Map<String, String>> getFinancingOfTheTasks() {
return financingOfTheTasks;
}
public void setFinancingOfTheTasks(List<Map<String, String>> financingOfTheTasks) {
this.financingOfTheTasks = financingOfTheTasks;
}
@Override
public String toString() {
return "CaseBoardView: case ID: " + caseId + ", process instance ID: " + processInstanceId;
}
}
private AdvancedProperty getVariable(List<AdvancedProperty> variables, String name) {
if (StringUtil.isEmpty(name)) {
return null;
}
for (AdvancedProperty variable: variables) {
if (name.equals(variable.getId())) {
return variable;
}
}
return null;
}
public TaskViewerHelper getTaskViewer() {
if (taskViewer == null)
ELUtil.getInstance().autowire(this);
return taskViewer;
}
public void setTaskViewer(TaskViewerHelper taskViewer) {
this.taskViewer = taskViewer;
}
public void setCaseProcessInstanceRelation(CaseProcessInstanceRelationImpl caseProcessInstanceRelation) {
this.caseProcessInstanceRelation = caseProcessInstanceRelation;
}
@Override
public String getLinkToTheTaskRedirector(IWContext iwc, String basePage, String caseId, Long processInstanceId, String backPage,
String taskName) {
return getTaskViewer().getLinkToTheTaskRedirector(iwc, basePage, caseId, processInstanceId, backPage, taskName);
}
public VariableInstanceQuerier getVariablesQuerier() {
if (variablesQuerier == null)
ELUtil.getInstance().autowire(this);
return variablesQuerier;
}
public void setVariablesQuerier(VariableInstanceQuerier variablesQuerier) {
this.variablesQuerier = variablesQuerier;
}
@Override
public List<AdvancedProperty> getAvailableVariables(String processName) {
IWContext iwc = CoreUtil.getIWContext();
if (iwc == null)
return null;
Collection<VariableInstanceInfo> variables = getVariablesQuerier().getVariablesByProcessDefinition(processName);
BPMProcessVariablesBean variablesProvider = ELUtil.getInstance().getBean(BPMProcessVariablesBean.SPRING_BEAN_IDENTIFIER);
return variablesProvider.getAvailableVariables(variables, iwc.getCurrentLocale(), iwc.isSuperAdmin(), false);
}
protected IWContext getIWContext() {
return CoreUtil.getIWContext();
}
protected IWResourceBundle getIWResourceBundle(IWContext iwc) {
if (iwc == null) {
return null;
}
IWMainApplication application = IWMainApplication.getIWMainApplication(iwc);
if (application == null) {
return null;
}
IWBundle bundle = application.getBundle(
getBundleIdentifier()
);
if (bundle == null) {
return null;
}
return bundle.getResourceBundle(iwc);
}
protected String getBundleIdentifier() {
return IWBundleStarter.IW_BUNDLE_IDENTIFIER;
}
protected void updateTasksInfo(CaseBoardBean caseBoard) {
if (caseBoard == null) {
return;
}
List<Map<String, String>> tasksInfo = caseBoard.getFinancingOfTheTasks();
if (!ListUtil.isEmpty(tasksInfo)) {
int tasksIndex = 0;
Map<Integer, Map<String, String>> valuesToReplace = new TreeMap<Integer, Map<String,String>>();
for (Map<String, String> taskInfo: tasksInfo) {
if (MapUtil.isEmpty(taskInfo))
continue;
String taskName = taskInfo.get("task");
if (StringUtil.isEmpty(taskName))
taskName = CoreConstants.MINUS;
Long cost = getNumberValue(taskInfo.get("cost_estimate"), Boolean.FALSE);
Map<String, String> cells = new HashMap<String, String>();
cells.put(CasesBoardViewer.WORK_ITEM, taskName);
cells.put(CasesBoardViewer.ESTIMATED_COST, String.valueOf(cost));
String suggestion = taskInfo.get(CasesBoardViewer.BOARD_SUGGESTION);
cells.put(CasesBoardViewer.BOARD_SUGGESTION,
StringUtil.isEmpty(suggestion) ? CoreConstants.MINUS : suggestion);
String decision = taskInfo.get(CasesBoardViewer.BOARD_DECISION);
cells.put(CasesBoardViewer.BOARD_DECISION,
StringUtil.isEmpty(decision) ? CoreConstants.MINUS : decision);
String proposal = taskInfo.get(CasesBoardViewer.BOARD_PROPOSAL_FOR_GRANT);
cells.put(CasesBoardViewer.BOARD_PROPOSAL_FOR_GRANT,
StringUtil.isEmpty(proposal) ? CoreConstants.MINUS : proposal);
valuesToReplace.put(tasksIndex, cells);
tasksIndex++;
}
tasksInfo = new ArrayList<Map<String,String>>();
for (Map<String, String> infoToReplace: valuesToReplace.values()) {
tasksInfo.add(infoToReplace);
}
caseBoard.setFinancingOfTheTasks(tasksInfo);
}
}
protected String localize(String key, String value) {
return getWebUtil().getLocalizedString(CasesConstants.IW_BUNDLE_IDENTIFIER, key, value);
}
@Autowired
private WebUtil webUtil = null;
protected WebUtil getWebUtil() {
if (this.webUtil == null) {
ELUtil.getInstance().autowire(this);
}
return this.webUtil;
}
}