/*
* 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;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.Table;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.kuali.kfs.fp.document.DisbursementVoucherDocument;
import org.kuali.kfs.module.tem.TemConstants;
import org.kuali.kfs.module.tem.TemConstants.TravelParameters;
import org.kuali.kfs.module.tem.TemConstants.TravelRelocationStatusCodeKeys;
import org.kuali.kfs.module.tem.TemParameterConstants;
import org.kuali.kfs.module.tem.TemWorkflowConstants;
import org.kuali.kfs.module.tem.businessobject.JobClassification;
import org.kuali.kfs.module.tem.businessobject.RelocationReason;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.businessobject.AccountingLine;
import org.kuali.kfs.sys.document.AmountTotaling;
import org.kuali.rice.core.api.util.type.KualiDecimal;
import org.kuali.rice.kew.api.document.DocumentStatus;
import org.kuali.rice.kew.api.exception.WorkflowException;
import org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange;
import org.kuali.rice.krad.rules.rule.event.KualiDocumentEvent;
import org.kuali.rice.krad.util.GlobalVariables;
/**
* Travel Relocation Document
*
*/
@Entity
@Table(name="TEM_RELO_DOC_T")
public class TravelRelocationDocument extends TEMReimbursementDocument implements AmountTotaling {
protected static Logger LOG = Logger.getLogger(TravelRelocationDocument.class);
private String fromAddress1;
private String fromAddress2;
private String fromCity;
private String fromStateCode;
private String fromCountryCode;
private String toAddress1;
private String toAddress2;
private String toCity;
private String toStateCode;
private String toCountryCode;
private String reasonCode;
private RelocationReason reason;
private String jobClsCode;
private JobClassification jobClassification;
private String titleCode;
private String comments;
public TravelRelocationDocument() {
}
public void setFromAddress1(String fromAddress1){
this.fromAddress1 = fromAddress1;
}
@Column(name = "FRM_ADDR_LINE1", length = 50, nullable = true)
public String getFromAddress1(){
return this.fromAddress1;
}
public void setFromAddress2(String fromAddress2){
this.fromAddress2 = fromAddress2;
}
@Column(name = "FRM_ADDR_LINE2", length = 50, nullable = true)
public String getFromAddress2(){
return this.fromAddress2;
}
public void setFromCity(String fromCity){
this.fromCity = fromCity;
}
@Column(name = "FRM_CITY_NM", length = 30, nullable = true)
public String getFromCity(){
return this.fromCity;
}
public void setFromStateCode(String fromStateCode){
this.fromStateCode = fromStateCode;
}
@Column(name = "FRM_STATE_CD", length = 40, nullable = true)
public String getFromStateCode(){
return this.fromStateCode;
}
public void setFromCountryCode(String fromCountryCode){
this.fromCountryCode = fromCountryCode;
}
@Column(name = "FRM_COUNTRY_CD", length = 40, nullable = true)
public String getFromCountryCode(){
return this.fromCountryCode;
}
public void setToAddress1(String toAddress1){
this.toAddress1 = toAddress1;
}
@Column(name = "TO_ADDR_LINE1", length = 50, nullable = true)
public String getToAddress1(){
return this.toAddress1;
}
public void setToAddress2(String toAddress2){
this.toAddress2 = toAddress2;
}
@Column(name = "TO_ADDR_LINE2", length = 50, nullable = true)
public String getToAddress2(){
return this.toAddress2;
}
public void setToCity(String toCity){
this.toCity = toCity;
}
@Column(name = "TO_CITY_NM", length = 30, nullable = true)
public String getToCity(){
return this.toCity;
}
public void setToStateCode(String toStateCode){
this.toStateCode = toStateCode;
}
@Column(name = "TO_STATE_CD", length = 40, nullable = true)
public String getToStateCode(){
return this.toStateCode;
}
public void setToCountryCode(String toCountryCode){
this.toCountryCode = toCountryCode;
}
@Column(name = "TO_COUNTRY_CD", length = 40, nullable = true)
public String getToCountryCode(){
return this.toCountryCode;
}
public void setReasonCode(String reasonCode){
this.reasonCode = reasonCode;
}
@Column(name = "REASON_CD", length = 255, nullable = true)
public String getReasonCode(){
return this.reasonCode;
}
public void setReason(RelocationReason reason){
this.reason = reason;
}
@JoinColumn(name="REASON_CD",nullable=true)
public RelocationReason getReason(){
return this.reason;
}
public void setJobClsCode(String jobClsCode){
this.jobClsCode = jobClsCode;
}
@Column(name = "JOB_CLS_CD", length = 255, nullable = true)
public String getJobClsCode(){
return this.jobClsCode;
}
public void setJobClassification(JobClassification jobClassification){
this.jobClassification = jobClassification;
}
@JoinColumn(name="JOB_CLS_CD",nullable=true)
public JobClassification getJobClassification(){
return this.jobClassification;
}
public void setTitleCode(String titleCode){
this.titleCode = titleCode;
}
@Column(name = "TITLE_CD", length = 3, nullable = true)
public String getTitleCode(){
return this.titleCode;
}
public void setComments(String comments){
this.comments = comments;
}
@Column(name = "COMMENTS", length = 255, nullable = true)
public String getComments(){
return this.comments;
}
/**
* @see org.kuali.kfs.module.tem.document.TravelDocumentBase#prepareForSave(org.kuali.rice.kns.rule.event.KualiDocumentEvent)
*/
@Override
public void prepareForSave(KualiDocumentEvent event) {
if(getFromCity() != null){
getPrimaryDestination().setPrimaryDestinationName(getFromCity());
}
super.prepareForSave(event);
getTravelPayment().setCheckStubText(getTravelDocumentIdentifier() + " " + StringUtils.defaultString(getTripDescription()) + " " + getTripBegin());
}
// /**
// * This method updates both the internal travel document status value and the app doc status
// * in the document header of workflow
// *
// * @param status
// */
// @Override
// public boolean updateAppDocStatus(String status) {
// boolean updated = false;
//
// //using the parent's update app doc status logic
// updated = super.updateAppDocStatus(status);
//
// if (!updated && (status.equals(TravelRelocationStatusCodeKeys.RELO_MANAGER_APPROVED))){
// setAppDocStatus(status);
// updated = saveAppDocStatus();
// }
// return updated;
// }
/**
* @see org.kuali.kfs.module.tem.document.TravelDocumentBase#initiateDocument()
*/
@Override
public void initiateDocument() {
super.initiateDocument();
setTripBegin(null);
setTripEnd(null);
setApplicationDocumentStatus(TravelRelocationStatusCodeKeys.IN_PROCESS);
getTravelPayment().setDocumentationLocationCode(getParameterService().getParameterValueAsString(TravelRelocationDocument.class, TravelParameters.DOCUMENTATION_LOCATION_CODE,
getParameterService().getParameterValueAsString(TemParameterConstants.TEM_DOCUMENT.class,TravelParameters.DOCUMENTATION_LOCATION_CODE)));
}
/**
* @see org.kuali.kfs.module.tem.document.TravelDocumentBase#doRouteStatusChange(org.kuali.rice.kew.dto.DocumentRouteStatusChange)
*/
@Override
public void doRouteStatusChange(DocumentRouteStatusChange statusChangeEvent) {
super.doRouteStatusChange(statusChangeEvent);
if (DocumentStatus.PROCESSED.getCode().equals(statusChangeEvent.getNewRouteStatus())) {
LOG.debug("New route status is: " + statusChangeEvent.getNewRouteStatus());
try {
updateAndSaveAppDocStatus(TravelRelocationStatusCodeKeys.RELO_MANAGER_APPROVED);
}
catch (WorkflowException ex) {
// TODO Auto-generated catch block
ex.printStackTrace();
}
}
}
/**
* @see org.kuali.kfs.sys.document.FinancialSystemTransactionalDocumentBase#answerSplitNodeQuestion(java.lang.String)
*/
@Override
public boolean answerSplitNodeQuestion(String nodeName) throws UnsupportedOperationException {
if (nodeName.equals(TemWorkflowConstants.REQUIRES_TRAVELER_REVIEW)) {
return requiresTravelerApprovalRouting();
}
if (nodeName.equals(TemWorkflowConstants.SPECIAL_REQUEST)) {
return requiresSpecialRequestReviewRouting();
}
if (nodeName.equals(TemWorkflowConstants.TAX_MANAGER_APPROVAL_REQUIRED)) {
return requiresTaxManagerApprovalRouting();
}
if (StringUtils.equals(TemWorkflowConstants.REQUIRES_BUDGET_REVIEW, nodeName)) {
return isBudgetReviewRequired();
}
if (nodeName.equals(TemWorkflowConstants.SEPARATION_OF_DUTIES)) {
return requiresSeparationOfDutiesRouting();
}
throw new UnsupportedOperationException("Cannot answer split question for this node you call \"" + nodeName + "\"");
}
/**
*
* This method returns the preparer
* @return
*/
public String getPreparer(){
return GlobalVariables.getUserSession().getPerson().getPrincipalName();
}
/**
* Given the <code>financialObjectCode</code>, determine the total of the
* {@link SourceAccountingLine} instances with that <code>financialObjectCode</code>
*
* @param financialObjectCode to search for total on
* @return @{link KualiDecimal} with total value for {@link AccountingLines} with <code>finanncialObjectCode</code>
*/
@Override
public KualiDecimal getTotalFor(final String financialObjectCode) {
KualiDecimal retval = KualiDecimal.ZERO;
LOG.debug("Getting total for " + financialObjectCode);
for (final AccountingLine line : (List<AccountingLine>) getSourceAccountingLines()) {
LOG.debug("Comparing " + financialObjectCode + " to " + line.getObjectCode().getCode());
if (line.getObjectCode().getCode().equals(financialObjectCode)) {
retval = retval.add(line.getAmount());
}
}
return retval;
}
/**
* @see org.kuali.kfs.module.tem.document.TravelDocument#getReportPurpose()
*/
@Override
public String getReportPurpose() {
return reason != null? reason.getReloReasonName() : null;
}
/**
* @see org.kuali.kfs.module.tem.document.TravelDocumentBase#populateVendorPayment(org.kuali.kfs.fp.document.DisbursementVoucherDocument)
*/
@Override
public void populateVendorPayment(DisbursementVoucherDocument disbursementVoucherDocument) {
super.populateVendorPayment(disbursementVoucherDocument);
String locationCode = getParameterService().getParameterValueAsString(TravelRelocationDocument.class, TravelParameters.DOCUMENTATION_LOCATION_CODE, getParameterService().getParameterValueAsString(TemParameterConstants.TEM_DOCUMENT.class,TravelParameters.DOCUMENTATION_LOCATION_CODE));
String startDate = new SimpleDateFormat("MM/dd/yyyy").format(getTripBegin());
String endDate = new SimpleDateFormat("MM/dd/yyyy").format(getTripEnd());
String checkStubText = getTravelDocumentIdentifier() + ", " + startDate + " - " + endDate + ", " + getToCity() + ", " + getToStateCode();
disbursementVoucherDocument.setDisbVchrPaymentMethodCode(KFSConstants.PaymentSourceConstants.PAYMENT_METHOD_CHECK);
disbursementVoucherDocument.setDisbursementVoucherDocumentationLocationCode(locationCode);
disbursementVoucherDocument.setDisbVchrCheckStubText(checkStubText);
}
/**
* Relocation document always require tax manager approval
*
* @see org.kuali.kfs.module.tem.document.TravelDocumentBase#requiresTaxManagerApprovalRouting()
*/
@Override
protected boolean requiresTaxManagerApprovalRouting() {
boolean requiresTaxManagerApprovalRouting = super.requiresTaxManagerApprovalRouting();
return requiresTaxManagerApprovalRouting || getTraveler().getNonResidentAlien();
}
/**
* @see org.kuali.kfs.module.tem.document.TravelDocumentBase#getDisapprovedAppDocStatusMap()
*/
@Override
public Map<String, String> getDisapprovedAppDocStatusMap() {
return TravelRelocationStatusCodeKeys.getDisapprovedAppDocStatusMap();
}
/**
* Returns RECA
* @see org.kuali.kfs.module.tem.document.TEMReimbursementDocument#getAchCheckDocumentType()
*/
@Override
public String getAchCheckDocumentType() {
return TemConstants.TravelDocTypes.RELOCATION_CHECK_ACH_DOCUMENT;
}
/**
* Returns REWF
* @see org.kuali.kfs.module.tem.document.TEMReimbursementDocument#getWireTransferOrForeignDraftDocumentType()
*/
@Override
public String getWireTransferOrForeignDraftDocumentType() {
return TemConstants.TravelDocTypes.RELOCATION_WIRE_OR_FOREIGN_DRAFT_DOCUMENT;
}
/**
* Returns "R-"
* @see org.kuali.kfs.module.tem.document.TravelDocumentBase#getTripIdPrefix()
*/
@Override
protected String getTripIdPrefix() {
return TemConstants.TripIdPrefix.RELOCATION_PREFIX;
}
/**
* The trip type code for a RELO is always "All"
* @see org.kuali.kfs.module.tem.document.TravelDocumentBase#getTripTypeCode()
*/
@Override
public String getTripTypeCode() {
return TemConstants.ALL_EXPENSE_TYPE_OBJECT_CODE_TRIP_TYPE;
}
}