/*
* 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.module.tem.document.web.struts;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.struts.upload.FormFile;
import org.kuali.kfs.module.tem.TemConstants;
import org.kuali.kfs.module.tem.TemConstants.TravelAuthorizationParameters;
import org.kuali.kfs.module.tem.TemConstants.TravelParameters;
import org.kuali.kfs.module.tem.TemKeyConstants;
import org.kuali.kfs.module.tem.TemParameterConstants;
import org.kuali.kfs.module.tem.TemPropertyConstants;
import org.kuali.kfs.module.tem.businessobject.AccountingDistribution;
import org.kuali.kfs.module.tem.businessobject.TemSourceAccountingLine;
import org.kuali.kfs.module.tem.businessobject.TransportationModeDetail;
import org.kuali.kfs.module.tem.businessobject.TravelerDetail;
import org.kuali.kfs.module.tem.businessobject.TravelerDetailEmergencyContact;
import org.kuali.kfs.module.tem.document.TravelAuthorizationDocument;
import org.kuali.kfs.module.tem.document.TravelDocument;
import org.kuali.kfs.module.tem.document.TravelDocumentBase;
import org.kuali.kfs.module.tem.document.service.TravelReimbursementService;
import org.kuali.kfs.module.tem.document.web.bean.TravelAuthorizationMvcWrapperBean;
import org.kuali.kfs.module.tem.service.TravelService;
import org.kuali.kfs.module.tem.util.MessageUtils;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.businessobject.SourceAccountingLine;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.kfs.sys.document.AccountingDocument;
import org.kuali.rice.core.web.format.CurrencyFormatter;
import org.kuali.rice.kew.api.WorkflowDocument;
import org.kuali.rice.kew.api.doctype.DocumentType;
import org.kuali.rice.kew.api.doctype.DocumentTypeService;
import org.kuali.rice.kns.web.ui.ExtraButton;
import org.kuali.rice.kns.web.ui.HeaderField;
import org.kuali.rice.krad.bo.DocumentHeader;
import org.kuali.rice.krad.service.DataDictionaryService;
import org.kuali.rice.krad.util.ObjectUtils;
public class TravelAuthorizationForm extends TravelFormBase implements TravelAuthorizationMvcWrapperBean{
private TravelerDetailEmergencyContact newEmergencyContactLine;
private TravelerDetail newTraveler;
private boolean canCloseTA;
private boolean canAmend;
private boolean canCancelTA;
private boolean canHold;
private boolean canRemoveHold;
private boolean canUnmask = false;
private boolean travelArranger;
private boolean allowIncidentals = true;
private String policyURL;
private Boolean multipleAdvances;
private boolean showPolicy;
private boolean waitingOnTraveler;
private Boolean showCorporateCardTotal;
private boolean showTravelAdvancesForTrip;
protected transient FormFile advanceAccountingFile;
private TemSourceAccountingLine newAdvanceAccountingLine;
// parameters that affect the UI
private List<String> tempSelectedTransportationModes = new ArrayList<String>();
/**
* Constructs a TravelAuthorizationForm.java.
*/
public TravelAuthorizationForm() {
super();
this.setShowPerDiem(false);
}
/**
* @see org.kuali.kfs.module.tem.document.web.bean.TravelMvcWrapperBean#setDistribution(java.util.List)
*/
@Override
public void setDistribution(final List<AccountingDistribution> distribution) {
super.setDistribution(distribution);
TravelDocument travelDocument = (TravelDocument)getDocument();
//TA doc - always deselected the expense type (ENCUMBRANCE) so it does not get distributed automatically
for (AccountingDistribution accountdistribution : this.distribution){
if (accountdistribution.getCardType().equals(travelDocument.getDefaultCardTypeCode())){
accountdistribution.setSelected(Boolean.FALSE);
accountdistribution.setDisabled(Boolean.TRUE);
}
}
}
@Override
public boolean isDisplayAccountingLines() {
boolean display = super.isDisplayAccountingLines();
TravelAuthorizationDocument document = (TravelAuthorizationDocument) getTravelDocument();
display = document.isTripGenerateEncumbrance() ; // trips which do not generate encumbrances won't have accounting lines
return display;
}
/**
* Display imported expense related tab base on Travel Authorization document base on system parameter
*
* @return
*/
public boolean isDisplayImportedExpenseRelatedTab(){
boolean display = getParameterService().getParameterValueAsBoolean(TravelAuthorizationDocument.class, TravelAuthorizationParameters.DISPLAY_IMPORTED_EXPENSE_IND);
return display;
}
/**
* @see org.kuali.kfs.module.tem.document.web.struts.TravelFormBase#getPerDiemLabel()
*/
@Override
public String getPerDiemLabel(){
return TemConstants.ENCUMBRANCE_PREFIX + super.getPerDiemLabel();
}
/**
* @see org.kuali.kfs.module.tem.document.web.struts.TravelFormBase#getExpenseLabel()
*/
@Override
public String getExpenseLabel(){
return TemConstants.ENCUMBRANCE_PREFIX + StringUtils.substringAfter(super.getExpenseLabel(), " ");
}
/**
* @see org.kuali.kfs.module.tem.document.web.struts.TravelFormBase#getExpenseTabLabel()
*/
@Override
public String getExpenseTabLabel(){
return TemConstants.GENERAL_EXPENSES_LABEL;
}
/**
* Gets the newEmergencyContactLine attribute.
*
* @return Returns the newEmergencyContactLine.
*/
@Override
public TravelerDetailEmergencyContact getNewEmergencyContactLine() {
return newEmergencyContactLine;
}
/**
* Sets the newEmergencyContactLine attribute value.
*
* @param newEmergencyContactLine The newEmergencyContactLine to set.
*/
@Override
public void setNewEmergencyContactLine(TravelerDetailEmergencyContact newEmergencyContactLine) {
this.newEmergencyContactLine = newEmergencyContactLine;
}
/**
* @return new accounting line associated with travel advance
*/
public TemSourceAccountingLine getNewAdvanceAccountingLine() {
if (getTravelAuthorizationDocument() == null) {
throw new IllegalArgumentException("TravelAuthorizationDocument cannot be null when creating new accounting line for advance");
}
if (newAdvanceAccountingLine == null) {
newAdvanceAccountingLine = getTravelAuthorizationDocument().createNewAdvanceAccountingLine();
}
return newAdvanceAccountingLine;
}
/**
* Sets new accounting line associated with travel advance
* @param newTravelAdvanceAccountingLine new accounting line associated with travel advance
*/
public void setNewAdvanceAccountingLine(TemSourceAccountingLine newTravelAdvanceAccountingLine) {
this.newAdvanceAccountingLine = newTravelAdvanceAccountingLine;
}
/**
* Gets the selectedTransportationModes attribute.
*
* @return Returns the selectedTransportationModes.
*/
@Override
public List<String> getSelectedTransportationModes() {
List<String> mySelectedTransportationModes = new ArrayList<String>();
List<TransportationModeDetail> details = this.getTravelAuthorizationDocument().getTransportationModes();
for (TransportationModeDetail detail : details) {
mySelectedTransportationModes.add(detail.getTransportationModeCode());
}
return mySelectedTransportationModes;
}
/**
* Sets the selectedTransportationModes attribute value.
*
* @param selectedTransportationModes The selectedTransportationModes to set.
*/
@Override
public void setSelectedTransportationModes(List<String> selectedTransportationModes) {
this.tempSelectedTransportationModes = selectedTransportationModes;
}
@Override
public List<String> getTempSelectedTransporationModes() {
return this.tempSelectedTransportationModes;
}
/**
* Retrieve the name of the document identifier field for data dictionary queries
*
* @return String with the field name of the document identifier
*/
@Override
protected String getDocumentIdentifierFieldName() {
return "travelDocumentIdentifier";
}
/**
* @return TravelAuthorizationDocument
*/
@Override
public TravelAuthorizationDocument getTravelAuthorizationDocument() {
return (TravelAuthorizationDocument) getDocument();
}
@Override
public void setNewTraveler(final TravelerDetail traveler) {
this.newTraveler = traveler;
}
@Override
public TravelerDetail getNewTraveler() {
return this.newTraveler;
}
@Override
protected String getDefaultDocumentTypeName() {
return "TA";
}
/**
* Creates a MAP for all the buttons to appear on the Travel Authorization Form, and sets the attributes of these buttons.
*
* @return the button map created.
*/
protected Map<String, ExtraButton> createButtonsMap() {
HashMap<String, ExtraButton> result = new HashMap<String, ExtraButton>();
// Amend button
ExtraButton amendButton = new ExtraButton();
amendButton.setExtraButtonProperty("methodToCall.amendTa");
amendButton.setExtraButtonSource("${" + KFSConstants.EXTERNALIZABLE_IMAGES_URL_KEY + "}buttonsmall_amend.gif");
amendButton.setExtraButtonAltText("Amend");
// Hold button
ExtraButton holdButton = new ExtraButton();
holdButton.setExtraButtonProperty("methodToCall.holdTa");
holdButton.setExtraButtonSource("${" + KFSConstants.EXTERNALIZABLE_IMAGES_URL_KEY + "}buttonsmall_hold.gif");
holdButton.setExtraButtonAltText("Hold");
// Remove Hold button
ExtraButton removeHoldButton = new ExtraButton();
removeHoldButton.setExtraButtonProperty("methodToCall.removeHoldTa");
removeHoldButton.setExtraButtonSource("${" + KFSConstants.EXTERNALIZABLE_IMAGES_URL_KEY + "}buttonsmall_removehold.gif");
removeHoldButton.setExtraButtonAltText("Remove Hold");
// Cancel Travel button
ExtraButton cancelTravelButton = new ExtraButton();
cancelTravelButton.setExtraButtonProperty("methodToCall.cancelTa");
cancelTravelButton.setExtraButtonSource("${" + KFSConstants.EXTERNALIZABLE_IMAGES_URL_KEY + "}buttonsmall_cancelta.gif");
cancelTravelButton.setExtraButtonAltText("Cancel Travel Authorization");
// Close Travel button
ExtraButton closeTAButton = new ExtraButton();
closeTAButton.setExtraButtonProperty("methodToCall.closeTa");
closeTAButton.setExtraButtonSource("${" + KFSConstants.EXTERNALIZABLE_IMAGES_URL_KEY + "}buttonsmall_closeta.gif");
closeTAButton.setExtraButtonAltText("Close Travel Authorization");
result.put(amendButton.getExtraButtonProperty(), amendButton);
result.put(holdButton.getExtraButtonProperty(), holdButton);
result.put(removeHoldButton.getExtraButtonProperty(), removeHoldButton);
result.put(cancelTravelButton.getExtraButtonProperty(), cancelTravelButton);
result.put(closeTAButton.getExtraButtonProperty(), closeTAButton);
result.putAll(createNewReimbursementButtonMap());
result.putAll(createPaymentExtraButtonMap());
return result;
}
@Override
public List<ExtraButton> getExtraButtons() {
super.getExtraButtons();
Map<String, ExtraButton> buttonsMap = createButtonsMap();
if (getDocumentActions().keySet().contains(TemConstants.TravelAuthorizationActions.CAN_AMEND)) {
extraButtons.add(buttonsMap.get("methodToCall.amendTa"));
}
if (getDocumentActions().keySet().contains(TemConstants.TravelAuthorizationActions.CAN_HOLD)) {
extraButtons.add(buttonsMap.get("methodToCall.holdTa"));
}
if (getDocumentActions().keySet().contains(TemConstants.TravelAuthorizationActions.CAN_REMOVE_HOLD)) {
extraButtons.add(buttonsMap.get("methodToCall.removeHoldTa"));
}
if (getDocumentActions().keySet().contains(TemConstants.TravelAuthorizationActions.CAN_CLOSE_TA)) {
extraButtons.add(buttonsMap.get("methodToCall.closeTa"));
}
if (getDocumentActions().keySet().contains(TemConstants.TravelAuthorizationActions.CAN_CANCEL_TA)) {
extraButtons.add(buttonsMap.get("methodToCall.cancelTa"));
}
if (getDocumentActions().keySet().contains(TemConstants.TravelAuthorizationActions.CAN_NEW_REIMBURSEMENT)) {
extraButtons.add(buttonsMap.get("methodToCall.newReimbursement"));
}
if (getDocumentActions().keySet().contains(TemConstants.TravelAuthorizationActions.CAN_PAY_VENDOR)) {
extraButtons.add(buttonsMap.get("methodToCall.payDVToVendor"));
}
return extraButtons;
}
@Override
public boolean isCanUnmask() {
return canUnmask;
}
@Override
public void setCanUnmask(boolean canUnmask) {
this.canUnmask = canUnmask;
}
protected TravelReimbursementService getTravelReimbursementService() {
return SpringContext.getBean(TravelReimbursementService.class);
}
protected TravelService getTravelService() {
return SpringContext.getBean(TravelService.class);
}
public boolean isAllowIncidentals() {
return allowIncidentals;
}
public void setAllowIncidentals(boolean allowIncidentals) {
this.allowIncidentals = allowIncidentals;
}
/**
* Gets the policyURL attribute.
* @return Returns the policyURL.
*/
public String getPolicyURL() {
if (policyURL == null) {
policyURL = getParameterService().getParameterValueAsString(TravelAuthorizationDocument.class, TravelAuthorizationParameters.TRAVEL_ADVANCES_POLICY_URL);
}
return MessageUtils.getMessage(TemKeyConstants.MESSAGE_TA_ADVANCE_POLICY, policyURL);
}
/**
* @return true if travel advances for trip should be shown, false otherwise
*/
public boolean isShowTravelAdvancesForTrip() {
return showTravelAdvancesForTrip;
}
/**
* Sets whether the travel advances for the rest of the trip (ie, not this document's travel advance, but other completed advances related to this trip)
* should be shown
* @param showTravelAdvancesForTrip true if travel advances for trip should be shown, false otherwise
*/
public void setShowTravelAdvancesForTrip(boolean showTravelAdvancesForTrip) {
this.showTravelAdvancesForTrip = showTravelAdvancesForTrip;
}
/**
* Gets the waitingOnTraveler attribute.
* @return Returns the waitingOnTraveler.
*/
public boolean isWaitingOnTraveler() {
return waitingOnTraveler;
}
/**
* Sets the waitingOnTraveler attribute value.
* @param waitingOnTraveler The waitingOnTraveler to set.
*/
public void setWaitingOnTraveler(boolean waitingOnTraveler) {
this.waitingOnTraveler = waitingOnTraveler;
}
/**
* Gets the showCorporateCardTotal attribute.
* @return Returns the showCorporateCardTotal.
*/
public boolean getShowCorporateCardTotal() {
if (showCorporateCardTotal == null) {
showCorporateCardTotal = Boolean.valueOf(getParameterService().getParameterValueAsBoolean(TemParameterConstants.TEM_DOCUMENT.class, TravelParameters.AMOUNT_DUE_CORPORATE_CARD_TOTAL_LINE_IND, false));
}
return showCorporateCardTotal.booleanValue();
}
/**
* Gets the showPolicy attribute.
* @return Returns the showPolicy.
*/
public boolean isShowPolicy() {
return showPolicy;
}
/**
* Sets the showPolicy attribute value.
* @param showPolicy The showPolicy to set.
*/
public void setShowPolicy(boolean showPolicy) {
this.showPolicy = showPolicy;
}
protected DataDictionaryService getDataDictionaryService() {
return SpringContext.getBean(DataDictionaryService.class);
}
/**
* @see org.kuali.kfs.module.tem.document.web.struts.TravelFormBase#getTravelPaymentFormAction()
*/
@Override
public String getTravelPaymentFormAction() {
return TemConstants.TRAVEL_AUTHORIZATION_ACTION_NAME;
}
/**
* @return the encapsulation of an uploaded file of accounting lines to associate with the travel advance
*/
public FormFile getAdvanceAccountingFile() {
return advanceAccountingFile;
}
/**
* Sets the form file for advance accounting line uploads
* @param advanceFile a file of accounting lines to associate with paying for a travel advance
*/
public void setAdvanceAccountingFile(FormFile advanceFile) {
this.advanceAccountingFile = advanceFile;
}
/**
* Retrieves the advance accounting lines total in a currency format with commas.
* @return the currency formatted total
*/
public String getCurrencyFormattedAdvanceTotal() {
return (String) new CurrencyFormatter().format(getTravelAuthorizationDocument().getAdvanceTotal());
}
public boolean isAdvancePdpStatusTabShown() {
if (getTravelDocument() != null) {
return getTravelAuthorizationDocument().shouldProcessAdvanceForDocument();
}
return false;
}
public boolean isDefaultTravelAdvanceTab() {
if (getTravelDocument() != null && getTravelAuthorizationDocument().shouldProcessAdvanceForDocument()) {
if( TemConstants.TravelAuthorizationStatusCodeKeys.IN_PROCESS.equals(getTravelDocument().getAppDocStatus()) ||
TemConstants.TravelAuthorizationStatusCodeKeys.AWAIT_TRVLR.equals(getTravelDocument().getAppDocStatus()) ||
TemConstants.TravelAuthorizationStatusCodeKeys.AWAIT_FISCAL.equals(getTravelDocument().getAppDocStatus()) ||
TemConstants.TravelAuthorizationStatusCodeKeys.AWAIT_TRVL_MGR.equals(getTravelDocument().getAppDocStatus())) {
return true;
}
}
return false;
}
/**
* Overridden to pull the object code from the trip type if possible
* @see org.kuali.kfs.module.tem.document.web.struts.TravelFormBase#createNewSourceAccountingLine(org.kuali.kfs.sys.document.AccountingDocument)
*/
@Override
protected SourceAccountingLine createNewSourceAccountingLine(AccountingDocument financialDocument) {
TemSourceAccountingLine accountingLine = (TemSourceAccountingLine)super.createNewSourceAccountingLine(financialDocument);
TravelDocumentBase travelDoc = (TravelDocumentBase) financialDocument;
travelDoc.refreshReferenceObject(TemPropertyConstants.TRIP_TYPE);
if (ObjectUtils.isNotNull(travelDoc.getTripType())) {
// set object code based on trip type
accountingLine.setFinancialObjectCode(travelDoc.getTripType().getEncumbranceObjCode());
}
return accountingLine;
}
@Override
public void populateHeaderFields(WorkflowDocument workflowDocument) {
super.populateHeaderFields(workflowDocument);
boolean vendorPaymentAllowedBeforeFinal = getParameterService().getParameterValueAsBoolean(TravelAuthorizationDocument.class, TemConstants.TravelAuthorizationParameters.VENDOR_PAYMENT_ALLOWED_BEFORE_FINAL_APPROVAL_IND);
String travelDocumentIdentifier = getTravelDocument().getTravelDocumentIdentifier();
String organizationDocumentNumber = getTravelDocument().getDocumentHeader().getOrganizationDocumentNumber();
TravelAuthorizationDocument document = (TravelAuthorizationDocument)getTravelDocument();
if(document.maskTravelDocumentIdentifierAndOrganizationDocNumber()) {
DataDictionaryService dataDictionaryService = SpringContext.getBean(DataDictionaryService.class);
if (ObjectUtils.isNotNull(travelDocumentIdentifier)) {
travelDocumentIdentifier = "";
int strLength = dataDictionaryService.getAttributeMaxLength(TravelAuthorizationDocument.class.getName(), TemPropertyConstants.TRAVEL_DOCUMENT_IDENTIFIER);
for (int i = 0; i < strLength; i++) {
travelDocumentIdentifier = travelDocumentIdentifier.concat("*");
}
}
if (ObjectUtils.isNotNull(organizationDocumentNumber)) {
organizationDocumentNumber = "";
int strLength = dataDictionaryService.getAttributeMaxLength(DocumentHeader.class.getName(), "organizationDocumentNumber");
for (int i = 0; i < strLength; i++) {
organizationDocumentNumber = organizationDocumentNumber.concat("*");
}
}
for (HeaderField headerField : getDocInfo()) {
String ddAttributeEntryName = headerField.getDdAttributeEntryName();
if (ObjectUtils.isNotNull(ddAttributeEntryName) && ddAttributeEntryName.equals("DataDictionary.TravelAuthorizationDocument.attributes.travelDocumentIdentifier")) {
headerField.setDisplayValue(travelDocumentIdentifier);
}
if (ObjectUtils.isNotNull(ddAttributeEntryName) && ddAttributeEntryName.equals("DataDictionary.DocumentHeader.attributes.organizationDocumentNumber")) {
headerField.setDisplayValue(organizationDocumentNumber);
}
}
}
}
}