/*
* The Kuali Financial System, a comprehensive financial management system for higher education.
*
* Copyright 2005-2014 The Kuali Foundation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kuali.kfs.coa.identity;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.kuali.kfs.coa.businessobject.Account;
import org.kuali.kfs.coa.businessobject.AccountDelegate;
import org.kuali.kfs.coa.service.AccountDelegateService;
import org.kuali.kfs.coa.service.AccountService;
import org.kuali.kfs.integration.cg.ContractsAndGrantsModuleService;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.KFSKeyConstants;
import org.kuali.kfs.sys.KFSPropertyConstants;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.kfs.sys.document.FinancialSystemMaintainable;
import org.kuali.kfs.sys.identity.KfsKimAttributes;
import org.kuali.rice.core.api.config.property.ConfigurationService;
import org.kuali.rice.core.api.mail.MailMessage;
import org.kuali.rice.core.api.membership.MemberType;
import org.kuali.rice.core.web.format.CurrencyFormatter;
import org.kuali.rice.coreservice.framework.parameter.ParameterService;
import org.kuali.rice.kim.api.KimConstants;
import org.kuali.rice.kim.api.identity.Person;
import org.kuali.rice.kim.api.identity.principal.Principal;
import org.kuali.rice.kim.api.role.RoleMembership;
import org.kuali.rice.kim.api.services.IdentityManagementService;
import org.kuali.rice.kns.kim.role.DerivedRoleTypeServiceBase;
import org.kuali.rice.krad.service.BusinessObjectService;
import org.kuali.rice.krad.service.MailService;
import org.kuali.rice.krad.util.ObjectUtils;
public class AccountDerivedRoleTypeServiceImpl extends DerivedRoleTypeServiceBase {
protected AccountService accountService;
protected ContractsAndGrantsModuleService contractsAndGrantsModuleService;
protected AccountDelegateService accountDelegateService;
protected ConfigurationService configurationService;
protected IdentityManagementService identityManagementService;
protected MailService mailService;
protected ParameterService parameterService;
protected final static String DERIVED_ROLE_MEMBER_INACTIVATION_NOTIFICATION_EMAIL_ADDRESSES_PARAMETER_NAME = "DERIVED_ROLE_MEMBER_INACTIVATION_NOTIFICATION_EMAIL_ADDRESSES";
/**
* Attributes: Chart Code Account Number Requirements: - KFS-COA Account Supervisor: CA_ACCOUNT_T.ACCT_SPVSR_UNVL_ID - KFS-SYS
* Fiscal Officer: CA_ACCOUNT_T.ACCT_FSC_OFC_UID - KFS-SYS Fiscal Officer Primary Delegate: CA_ACCT_DELEGATE_T.ACCT_DLGT_UNVL_ID
* where ACCT_DLGT_PRMRT_CD = Y - KFS-SYS Fiscal Officer Secondary Delegate: CA_ACCT_DELEGATE_T.ACCT_DLGT_UNVL_ID where
* ACCT_DLGT_PRMRT_CD = N - KFS-SYS Award Project Director: use the getProjectDirectorForAccount(String chartOfAccountsCode,
* String accountNumber) method on the contracts and grants module service
*
* @see org.kuali.rice.kns.kim.role.RoleTypeServiceBase#getPrincipalIdsFromApplicationRole(java.lang.String,
* java.lang.String, org.kuali.rice.kim.bo.types.dto.AttributeSet)
*/
@Override
public List<RoleMembership> getRoleMembersFromDerivedRole(String namespaceCode, String roleName, Map<String,String> qualification) {
// validate received attributes
validateRequiredAttributesAgainstReceived(qualification);
List<RoleMembership> members = new ArrayList<RoleMembership>();
if(qualification!=null && !qualification.isEmpty()){
String chartOfAccountsCode = qualification.get(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE);
String accountNumber = qualification.get(KfsKimAttributes.ACCOUNT_NUMBER);
String financialSystemDocumentTypeCodeCode = qualification.get(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME);
String totalDollarAmount = qualification.get(KfsKimAttributes.FINANCIAL_DOCUMENT_TOTAL_AMOUNT);
String fiscalOfficerPrincipalID = qualification.get(KFSPropertyConstants.ACCOUNT_FISCAL_OFFICER_SYSTEM_IDENTIFIER);
String accountSupervisorPrincipalID = qualification.get(KFSPropertyConstants.ACCOUNTS_SUPERVISORY_SYSTEMS_IDENTIFIER);
String principalId = qualification.get(KimConstants.AttributeConstants.PRINCIPAL_ID);
// Default to 0 total amount
if (StringUtils.isEmpty(totalDollarAmount)) {
totalDollarAmount = getDefaultTotalAmount();
}
Map<String,String> roleQualifier = new HashMap<String,String>();
roleQualifier.put(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE, chartOfAccountsCode);
roleQualifier.put(KfsKimAttributes.ACCOUNT_NUMBER, accountNumber);
if (chartOfAccountsCode == null && accountNumber == null && StringUtils.isNotBlank(principalId)) {
RoleMembership roleMembershipInfo = getRoleMembershipWhenAccountInfoUnavailable(roleName, principalId, roleQualifier);
if(ObjectUtils.isNotNull(roleMembershipInfo)) {
members.add(roleMembershipInfo);
}
}
if (KFSConstants.SysKimApiConstants.ACCOUNT_SUPERVISOR_KIM_ROLE_NAME.equals(roleName)) {
Account account = getAccount(chartOfAccountsCode, accountNumber);
if (account != null) {
members.add(RoleMembership.Builder.create(null, null, account.getAccountsSupervisorySystemsIdentifier(), MemberType.PRINCIPAL, roleQualifier).build());
}
// only add the additional approver if they are different
if (StringUtils.isNotBlank(accountSupervisorPrincipalID) && (account == null || !StringUtils.equals(accountSupervisorPrincipalID, account.getAccountsSupervisorySystemsIdentifier()))) {
members.add(RoleMembership.Builder.create(null, null, accountSupervisorPrincipalID, MemberType.PRINCIPAL, roleQualifier).build());
}
}
else if (KFSConstants.SysKimApiConstants.FISCAL_OFFICER_KIM_ROLE_NAME.equals(roleName)) {
Account account = getAccount(chartOfAccountsCode, accountNumber);
if (account != null) {
members.add(RoleMembership.Builder.create(null, null, account.getAccountFiscalOfficerSystemIdentifier(), MemberType.PRINCIPAL, roleQualifier).build());
}
// only add the additional approver if they are different
if (StringUtils.isNotBlank(fiscalOfficerPrincipalID) && (account == null || !StringUtils.equals(fiscalOfficerPrincipalID, account.getAccountFiscalOfficerSystemIdentifier()))) {
members.add(RoleMembership.Builder.create(null, null, fiscalOfficerPrincipalID, MemberType.PRINCIPAL, roleQualifier).build());
}
}
else if (KFSConstants.SysKimApiConstants.FISCAL_OFFICER_PRIMARY_DELEGATE_KIM_ROLE_NAME.equals(roleName)) {
AccountDelegate delegate = getPrimaryDelegate(chartOfAccountsCode, accountNumber, financialSystemDocumentTypeCodeCode, totalDollarAmount);
if (delegate != null) {
roleQualifier.put(KfsKimAttributes.FINANCIAL_SYSTEM_DOCUMENT_TYPE_CODE, delegate.getFinancialDocumentTypeCode());
roleQualifier.put(KfsKimAttributes.FROM_AMOUNT, (delegate.getFinDocApprovalFromThisAmt() == null) ? "0" : delegate.getFinDocApprovalFromThisAmt().toString());
roleQualifier.put(KfsKimAttributes.TO_AMOUNT, (delegate.getFinDocApprovalToThisAmount() == null) ? "NOLIMIT" : delegate.getFinDocApprovalToThisAmount().toString());
members.add(RoleMembership.Builder.create(null, null, delegate.getAccountDelegateSystemId(), MemberType.PRINCIPAL, roleQualifier).build());
}
}
else if (KFSConstants.SysKimApiConstants.FISCAL_OFFICER_SECONDARY_DELEGATE_KIM_ROLE_NAME.equals(roleName)) {
List<AccountDelegate> delegates = getSecondaryDelegates(chartOfAccountsCode, accountNumber, financialSystemDocumentTypeCodeCode, totalDollarAmount);
for (AccountDelegate delegate : delegates) {
roleQualifier.put(KfsKimAttributes.FINANCIAL_SYSTEM_DOCUMENT_TYPE_CODE, delegate.getFinancialDocumentTypeCode());
roleQualifier.put(KfsKimAttributes.FROM_AMOUNT, (delegate.getFinDocApprovalFromThisAmt() == null) ? "0" : delegate.getFinDocApprovalFromThisAmt().toString());
roleQualifier.put(KfsKimAttributes.TO_AMOUNT, (delegate.getFinDocApprovalToThisAmount() == null) ? "NOLIMIT" : delegate.getFinDocApprovalToThisAmount().toString());
members.add(RoleMembership.Builder.create(null, null, delegate.getAccountDelegateSystemId(), MemberType.PRINCIPAL, roleQualifier).build());
}
}
else if (KFSConstants.SysKimApiConstants.AWARD_SECONDARY_DIRECTOR_KIM_ROLE_NAME.equals(roleName)) {
Person person = getProjectDirectorForAccount(chartOfAccountsCode, accountNumber);
if (person != null) {
members.add(RoleMembership.Builder.create(null, null, person.getPrincipalId(), MemberType.PRINCIPAL, roleQualifier).build());
}
}
}
return members;
}
// build memebership information based on the given role name for the given principal when account information is unavailable
protected RoleMembership getRoleMembershipWhenAccountInfoUnavailable(String roleName, String principalId, Map<String,String> roleQualifier) {
BusinessObjectService businessObjectService = SpringContext.getBean(BusinessObjectService.class);
Map<String, Object> fieldValues = new HashMap<String, Object>();
RoleMembership roleMembership = null;
if ((KFSConstants.SysKimApiConstants.FISCAL_OFFICER_KIM_ROLE_NAME.equals(roleName))) {
fieldValues.put(KFSPropertyConstants.ACCOUNT_FISCAL_OFFICER_SYSTEM_IDENTIFIER, principalId);
if (businessObjectService.countMatching(Account.class, fieldValues) > 0) {
roleMembership = RoleMembership.Builder.create(null, null, principalId, MemberType.PRINCIPAL, roleQualifier).build();
}
}
else if (KFSConstants.SysKimApiConstants.FISCAL_OFFICER_PRIMARY_DELEGATE_KIM_ROLE_NAME.equals(roleName)) {
fieldValues.put(KFSPropertyConstants.ACCOUNT_DELEGATE_SYSTEM_ID, principalId);
fieldValues.put(KFSPropertyConstants.ACCOUNTS_DELEGATE_PRMRT_INDICATOR, Boolean.TRUE);
if (businessObjectService.countMatching(AccountDelegate.class, fieldValues) > 0) {
roleMembership = RoleMembership.Builder.create(null, null, principalId, MemberType.PRINCIPAL, roleQualifier).build();
}
}
else if (KFSConstants.SysKimApiConstants.FISCAL_OFFICER_SECONDARY_DELEGATE_KIM_ROLE_NAME.equals(roleName)) {
fieldValues.put(KFSPropertyConstants.ACCOUNT_DELEGATE_SYSTEM_ID, principalId);
fieldValues.put(KFSPropertyConstants.ACCOUNTS_DELEGATE_PRMRT_INDICATOR, Boolean.FALSE);
if (businessObjectService.countMatching(AccountDelegate.class, fieldValues) > 0) {
roleMembership = RoleMembership.Builder.create(null, null, principalId, MemberType.PRINCIPAL, roleQualifier).build();
}
}
return roleMembership;
}
protected Account getAccount(String chartOfAccountsCode, String accountNumber) {
return getAccountService().getByPrimaryId(chartOfAccountsCode, accountNumber);
}
protected AccountDelegate getPrimaryDelegate(String chartOfAccountsCode, String accountNumber, String fisDocumentTypeCode, String totalDollarAmount) {
return getAccountService().getPrimaryDelegationByExample(getDelegateExample(chartOfAccountsCode, accountNumber, fisDocumentTypeCode), totalDollarAmount);
}
protected List<AccountDelegate> getSecondaryDelegates(String chartOfAccountsCode, String accountNumber, String fisDocumentTypeCode, String totalDollarAmount) {
return getAccountService().getSecondaryDelegationsByExample(getDelegateExample(chartOfAccountsCode, accountNumber, fisDocumentTypeCode), totalDollarAmount);
}
protected Person getProjectDirectorForAccount(String chartOfAccountsCode, String accountNumber) {
return getContractsAndGrantsModuleService().getProjectDirectorForAccount(chartOfAccountsCode, accountNumber);
}
// Default to 0 total amount
protected String getDefaultTotalAmount() {
return "0";
}
protected AccountDelegate getDelegateExample(String chartOfAccountsCode, String accountNumber, String fisDocumentTypeCode) {
AccountDelegate delegateExample = new AccountDelegate();
delegateExample.setChartOfAccountsCode(chartOfAccountsCode);
delegateExample.setAccountNumber(accountNumber);
delegateExample.setFinancialDocumentTypeCode(fisDocumentTypeCode);
return delegateExample;
}
/**
* Gets the accountService attribute.
*
* @return Returns the accountService.
*/
protected AccountService getAccountService() {
if (accountService == null) {
accountService = SpringContext.getBean(AccountService.class);
}
return accountService;
}
/**
* Sets the accountService attribute value.
*
* @param accountService The accountService to set.
*/
public void setAccountService(AccountService accountService) {
this.accountService = accountService;
}
/**
* @return an implementation of the AccountDelegateService
*/
protected AccountDelegateService getAccountDelegateService() {
if (accountDelegateService == null) {
accountDelegateService = SpringContext.getBean(AccountDelegateService.class);
}
return accountDelegateService;
}
/**
* Sets the accountDelegateService attribute value.
* @param accountDelegateService The accountDelegateService to set.
*/
public void setAccountDelegateService(AccountDelegateService accountDelegateService) {
this.accountDelegateService = accountDelegateService;
}
/**
* @return an implementation of the ConfigurationService
*/
protected ConfigurationService getConfigurationService() {
if (configurationService == null) {
configurationService = SpringContext.getBean(ConfigurationService.class);
}
return configurationService;
}
/**
* @return an implementation of the IdentityManagementService
*/
protected IdentityManagementService getIdentityManagementService() {
if (identityManagementService == null) {
identityManagementService = SpringContext.getBean(IdentityManagementService.class);
}
return identityManagementService;
}
/**
* @return an implementation of the MailService
*/
protected MailService getMailService() {
if (mailService == null) {
mailService = SpringContext.getBean(MailService.class);
}
return mailService;
}
/**
* @return an implementation of the ParameterService
*/
protected ParameterService getParameterService() {
if (parameterService == null) {
parameterService = SpringContext.getBean(ParameterService.class);
}
return parameterService;
}
protected ContractsAndGrantsModuleService getContractsAndGrantsModuleService() {
if (contractsAndGrantsModuleService == null) {
contractsAndGrantsModuleService = SpringContext.getBean(ContractsAndGrantsModuleService.class);
}
return contractsAndGrantsModuleService;
}
/**
* @see org.kuali.rice.kns.kim.role.RoleTypeServiceBase#principalInactivated(java.lang.String, java.lang.String, java.lang.String)
*/
// @Override
public void principalInactivated(String principalId, String namespaceCode, String roleName) {
// super.principalInactivated(principalId, namespaceCode, roleName);
if (KFSConstants.SysKimApiConstants.ACCOUNT_SUPERVISOR_KIM_ROLE_NAME.equals(roleName)) {
if (getAccountService().isPrincipalInAnyWayShapeOrFormAccountSupervisor(principalId)) {
handleAccountSupervisorInactivation(principalId, namespaceCode, roleName);
}
}
else if (KFSConstants.SysKimApiConstants.FISCAL_OFFICER_KIM_ROLE_NAME.equals(roleName)) {
if (getAccountService().isPrincipalInAnyWayShapeOrFormFiscalOfficer(principalId)) {
handleFiscalOfficerInactivation(principalId, namespaceCode, roleName);
}
}
else if (KFSConstants.SysKimApiConstants.FISCAL_OFFICER_PRIMARY_DELEGATE_KIM_ROLE_NAME.equals(roleName)) {
if (getAccountDelegateService().isPrincipalInAnyWayShapeOrFormPrimaryAccountDelegate(principalId)) {
handlePrimaryAccountDelegateInactivation(principalId, namespaceCode, roleName);
}
}
else if (KFSConstants.SysKimApiConstants.FISCAL_OFFICER_SECONDARY_DELEGATE_KIM_ROLE_NAME.equals(roleName)) {
if (getAccountDelegateService().isPrincipalInAnyWayShapeOrFormSecondaryAccountDelegate(principalId)) {
handleSecondaryAccountDelegateInactivation(principalId, namespaceCode, roleName);
}
}
}
/**
* Notifies the specified list that the given principal is being inactivated, listing any active or expired accounts the principal is fiscal officer of
* @param principalId the principal id of the inactivating person
* @param roleNamespace the namespace of the role the inactivated principal is leaving
* @param roleName the name of the role the inactivated principal is leaving
*/
protected void handleFiscalOfficerInactivation(String principalId, String roleNamespace, String roleName) {
// build the message
final Principal principal = getIdentityManagementService().getPrincipal(principalId);
Iterator<Account> activeAccounts = getAccountService().getActiveAccountsForFiscalOfficer(principalId);
final String joinedActiveAccounts = joinAccounts(activeAccounts);
Iterator<Account> inactiveAccounts = getAccountService().getExpiredAccountsForFiscalOfficer(principalId);
final String joinedExpiredAccounts = joinAccounts(inactiveAccounts);
final String message = getMessage(KFSKeyConstants.MESSAGE_ACCOUNT_DERIVED_ROLE_PRINCIPAL_INACTIVATED_FISCAL_OFFICER_NOTIFICATION, roleNamespace, roleName, principal.getPrincipalName(), joinedActiveAccounts, joinedExpiredAccounts);
// get listserv to mail to
String toAddress = getDeactivationInterestAddress();
try {
// get mail message
MailMessage mailMessage = buildMailMessage(toAddress, message, roleNamespace, roleName, principalId);
// send it
getMailService().sendMessage(mailMessage);
}
catch (Exception iae) {
throw new RuntimeException("Could not mail principal inactivation notification to "+toAddress);
}
}
/**
* Notifies the specified list that the given principal is being inactivated, listing any active or expired accounts the principal is account supervisor of
* @param principalId the principal id of the inactivating person
* @param roleNamespace the namespace of the role the inactivated principal is leaving
* @param roleName the name of the role the inactivated principal is leaving
*/
protected void handleAccountSupervisorInactivation(String principalId, String roleNamespace, String roleName) {
// build the message
final Principal principal = getIdentityManagementService().getPrincipal(principalId);
Iterator<Account> activeAccounts = getAccountService().getActiveAccountsForAccountSupervisor(principalId);
final String joinedActiveAccounts = joinAccounts(activeAccounts);
Iterator<Account> inactiveAccounts = getAccountService().getExpiredAccountsForAccountSupervisor(principalId);
final String joinedExpiredAccounts = joinAccounts(inactiveAccounts);
final String message = getMessage(KFSKeyConstants.MESSAGE_ACCOUNT_DERIVED_ROLE_PRINCIPAL_INACTIVATED_ACCOUNT_SUPERVISOR_NOTIFICATION, roleNamespace, roleName, principal.getPrincipalName(), joinedActiveAccounts, joinedExpiredAccounts);
// get listserv to mail to
String toAddress = getDeactivationInterestAddress();
try {
// get mail message
MailMessage mailMessage = buildMailMessage(toAddress, message, roleNamespace, roleName, principalId);
// send it
getMailService().sendMessage(mailMessage);
}
catch (Exception iae) {
throw new RuntimeException("Could not mail principal inactivation notification to "+toAddress);
}
}
/**
* Does the logic for the inactivation of a secondary delegate
* @param principalId the principal id of the inactivating person
* @param roleNamespace the namespace of the role the inactivated principal is leaving
* @param roleName the name of the role the inactivated principal is leaving
*/
protected void handlePrimaryAccountDelegateInactivation(String principalId, String roleNamespace, String roleName) {
handleAccountDelegateInactivation(principalId, roleNamespace, roleName, true);
}
/**
* Does the logic for the inactivation of a secondary delegate
* @param principalId the principal id of the inactivating person
* @param roleNamespace the namespace of the role the inactivated principal is leaving
* @param roleName the name of the role the inactivated principal is leaving
*/
protected void handleSecondaryAccountDelegateInactivation(String principalId, String roleNamespace, String roleName) {
handleAccountDelegateInactivation(principalId, roleNamespace, roleName, false);
}
/**
* Handles the inactivation of account delegates when their principal is inactivated
* @param principalId the principal id of the inactivating person
* @param roleNamespace the namespace of the role the inactivated principal is leaving
* @param roleName the name of the role the inactivated principal is leaving
* @param primary whether primary delegates should be inactivated, rather than secondary
*/
protected void handleAccountDelegateInactivation(String principalId, String roleNamespace, String roleName, boolean primary) {
List<String> accountDisdelegations = new ArrayList<String>();
List<String> blockedAccountDisdelegations = new ArrayList<String>();
Iterator<AccountDelegate> accountDelegationsToInactivate = getAccountDelegateService().retrieveAllActiveDelegationsForPerson(principalId, primary);
while (accountDelegationsToInactivate.hasNext()) {
final AccountDelegate accountDelegate = accountDelegationsToInactivate.next();
final String blockingDocumentId = lookupDocumentBlockingInactivation(accountDelegate);
if (StringUtils.isBlank(blockingDocumentId)) {
accountDisdelegations.add(getAccountDisdelegationInformationForAccountDelegate(accountDelegate));
inactivateDelegation(accountDelegate);
} else {
blockedAccountDisdelegations.add(getBlockedAccountDisdelegationInformationForAccountDelegate(accountDelegate, blockingDocumentId));
}
}
notifyListAboutAccountDelegateInactivations(principalId, roleNamespace, roleName, accountDisdelegations, blockedAccountDisdelegations, primary);
}
/**
* Returns the document number of a maintenance document which would block the inactivation of the given account delegate
* @param delegate the account delegate to check
* @return the document id of the maintenance document blocking the inactivation of the given account delegate, null otherwise
*/
protected String lookupDocumentBlockingInactivation(AccountDelegate delegate) {
FinancialSystemMaintainable maintainable = getAccountDelegateService().buildMaintainableForAccountDelegate(delegate);
return maintainable.getLockingDocumentId();
}
/**
* Inactivates an account delegate
* @param delegate the account delegate to inactivate
*/
protected void inactivateDelegation(AccountDelegate delegate) {
delegate.setActive(false); // this is deprecated? lame!
getBusinessObjectService().save(delegate);
}
/**
* Converts information from the given AccountDelegate record into an informative String
* @param accountDelegate the account delegate to report on
* @return the report on the given account delegate
*/
protected String getAccountDisdelegationInformationForAccountDelegate(AccountDelegate accountDelegate) {
final CurrencyFormatter formatter = new CurrencyFormatter();
final String message = getMessage(KFSKeyConstants.MESSAGE_ACCOUNT_DERIVED_ROLE_PRINCIPAL_INACTIVATED_ACCOUNT_DELEGATE_INACTIVATED_INFORMATION, accountDelegate.getChartOfAccountsCode(), accountDelegate.getAccountNumber(), accountDelegate.getFinancialDocumentTypeCode(), (String)(accountDelegate.getFinDocApprovalFromThisAmt() != null ? formatter.format(accountDelegate.getFinDocApprovalFromThisAmt()) : ""), (String)(accountDelegate.getFinDocApprovalFromThisAmt() != null ? formatter.format(accountDelegate.getFinDocApprovalFromThisAmt()) : ""));
return message;
}
/**
* Converts information from the given AccountDelegate record into an informative String
* @param accountDelegate the account delegate to report on
* @return the report on the given account delegate
*/
protected String getBlockedAccountDisdelegationInformationForAccountDelegate(AccountDelegate accountDelegate, String blockingDocumentId) {
final CurrencyFormatter formatter = new CurrencyFormatter();
final String message = getMessage(KFSKeyConstants.MESSAGE_ACCOUNT_DERIVED_ROLE_PRINCIPAL_INACTIVATED_ACCOUNT_DELEGATE_BLOCKED_INACTIVATION_INFORMATION, accountDelegate.getChartOfAccountsCode(), accountDelegate.getAccountNumber(), accountDelegate.getFinancialDocumentTypeCode(), (String)(accountDelegate.getFinDocApprovalFromThisAmt() != null ? formatter.format(accountDelegate.getFinDocApprovalFromThisAmt()) : ""), (String)(accountDelegate.getFinDocApprovalFromThisAmt() != null ? formatter.format(accountDelegate.getFinDocApprovalFromThisAmt()) : ""), blockingDocumentId);
return message;
}
/**
* Fires an e-mail off the specified e-mail listserv about the account delegates inactivated by a
* @param principalId the principal being inactivated
* @param roleNamespace the namespace of the role the inactivated principal is leaving
* @param roleName the name of the role the inactivated principal is leaving
* @param accountsDisdelegated the account delegate records which were inactivated
* @param blockedDisdelegations the account delegate records which could not be inactivated because of locking maintenance documents
* @param primary whether the account delegations being reported on were primary delegations, as opposed to secondary delegations
*/
protected void notifyListAboutAccountDelegateInactivations(String principalId, String roleNamespace, String roleName, List<String> accountsDisdelegated, List<String> blockedDisdelegations, boolean primary) {
// build message
final Principal principal = getIdentityManagementService().getPrincipal(principalId);
final String message = getMessage((primary ? KFSKeyConstants.MESSAGE_ACCOUNT_DERIVED_ROLE_PRINCIPAL_INACTIVATED_FISCAL_OFFICER_PRIMARY_DELEGATE_NOTIFICATION : KFSKeyConstants.MESSAGE_ACCOUNT_DERIVED_ROLE_PRINCIPAL_INACTIVATED_FISCAL_OFFICER_SECONARY_DELEGATE_NOTIFICATION), roleNamespace, roleName, principal.getPrincipalName(), StringUtils.join(accountsDisdelegated,'\n'), StringUtils.join(blockedDisdelegations, '\n'));
String toAddress = getDeactivationInterestAddress();
try {
// get mail message
MailMessage mailMessage = buildMailMessage(toAddress, message, roleNamespace, roleName, principalId);
// send it
getMailService().sendMessage(mailMessage);
}
catch (Exception iae) {
throw new RuntimeException("Could not mail principal inactivation notification to "+toAddress);
}
}
/**
* Retrieves message from configuration service and formats it directly
* @param messageConstant the property to find the message under
* @param parameters the parameters to interpolate into the message
* @return a formatted String
*/
protected String getMessage(String messageConstant, String...parameters) {
final String messagePattern = getConfigurationService().getPropertyValueAsString(messageConstant);
return MessageFormat.format(messagePattern, (Object[])parameters);
}
/**
* Joins an Iterator of accounts into a meaningful String
* @param accounts the accounts to join
* @return a String of account information
*/
protected String joinAccounts(Iterator<Account> accounts) {
StringBuilder s = new StringBuilder();
int count = 0;
while (accounts.hasNext()) {
final Account account = accounts.next();
if (count > 0) {
s.append('\n');
}
s.append(account.getChartOfAccountsCode()+"-"+account.getAccountNumber());
count += 1;
}
return s.toString();
}
/**
* Builds a MailMessage to send out a notification e-mail
* @param toAddress the address to send the notification to
* @param message the body of the notification
* @param principalId the principal being inactivated
* @param roleNamespace the namespace of the role the inactivated principal is leaving
* @param roleName the name of the role the inactivated principal is leaving
* @return an appropriately constructed MailMessage
*/
protected MailMessage buildMailMessage(String toAddress, String message, String roleNamespace, String roleName, String principalId) {
MailMessage mailMessage = new MailMessage();
mailMessage.setFromAddress(getFromAddress());
mailMessage.setSubject(getMailMessageSubject(roleNamespace, roleName, principalId));
Set<String> toAddresses = new HashSet<String>();
toAddresses.add(toAddress);
mailMessage.setToAddresses(toAddresses);
mailMessage.setMessage(message);
return mailMessage;
}
/**
* Builds a subject line for an e-mail
* @param principalId the principal being inactivated
* @param roleNamespace the namespace of the role the inactivated principal is leaving
* @param roleName the name of the role the inactivated principal is leaving
* @return a suitable subject line for the notification e-mail
*/
protected String getMailMessageSubject(String roleNamespace, String roleName, String principalId) {
final Principal principal = getIdentityManagementService().getPrincipal(principalId);
return getMessage(KFSKeyConstants.MESSAGE_ACCOUNT_DERIVED_ROLE_PRINCIPAL_INACTIVATED_NOTIFICATION_SUBJECT, roleNamespace, roleName, principal.getPrincipalName());
}
/**
* @return the from address to send mail from; in the default version, the given toAddress (but since this is a method, implementers can override)
*/
protected String getFromAddress() {
return getDeactivationInterestAddress();
}
/**
* @return the e-mail address of those interested in account role principal inactivations
*/
protected String getDeactivationInterestAddress() {
return getParameterService().getParameterValueAsString(Account.class, AccountDerivedRoleTypeServiceImpl.DERIVED_ROLE_MEMBER_INACTIVATION_NOTIFICATION_EMAIL_ADDRESSES_PARAMETER_NAME);
}
}