/* * 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; } }