View Javadoc
1   /*
2    * The Kuali Financial System, a comprehensive financial management system for higher education.
3    * 
4    * Copyright 2005-2014 The Kuali Foundation
5    * 
6    * This program is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU Affero General Public License as
8    * published by the Free Software Foundation, either version 3 of the
9    * License, or (at your option) any later version.
10   * 
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU Affero General Public License for more details.
15   * 
16   * You should have received a copy of the GNU Affero General Public License
17   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  package org.kuali.kfs.module.tem.document.service;
20  
21  import java.sql.Date;
22  import java.sql.Timestamp;
23  import java.util.Collection;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.Set;
27  
28  import org.kuali.kfs.integration.ar.AccountsReceivableOrganizationOptions;
29  import org.kuali.kfs.module.tem.businessobject.ActualExpense;
30  import org.kuali.kfs.module.tem.businessobject.ExpenseTypeAware;
31  import org.kuali.kfs.module.tem.businessobject.GroupTraveler;
32  import org.kuali.kfs.module.tem.businessobject.PerDiem;
33  import org.kuali.kfs.module.tem.businessobject.PerDiemExpense;
34  import org.kuali.kfs.module.tem.businessobject.SpecialCircumstances;
35  import org.kuali.kfs.module.tem.businessobject.TemExpense;
36  import org.kuali.kfs.module.tem.businessobject.TemSourceAccountingLine;
37  import org.kuali.kfs.module.tem.businessobject.TransportationModeDetail;
38  import org.kuali.kfs.module.tem.businessobject.TravelAdvance;
39  import org.kuali.kfs.module.tem.businessobject.TripType;
40  import org.kuali.kfs.module.tem.document.TEMReimbursementDocument;
41  import org.kuali.kfs.module.tem.document.TravelAuthorizationDocument;
42  import org.kuali.kfs.module.tem.document.TravelDocument;
43  import org.kuali.kfs.module.tem.document.TravelReimbursementDocument;
44  import org.kuali.rice.core.api.util.KeyValue;
45  import org.kuali.rice.core.api.util.type.KualiDecimal;
46  import org.kuali.rice.kew.api.exception.WorkflowException;
47  import org.kuali.rice.kim.api.identity.Person;
48  import org.kuali.rice.krad.document.Document;
49  import org.kuali.rice.krad.uif.field.LinkField;
50  
51  /**
52   * Travel Document Service
53   */
54  public interface TravelDocumentService {
55  
56      public String getMessageFrom(final String messageType, String... args);
57  
58      List<SpecialCircumstances> findActiveSpecialCircumstances(String documentNumber, String documentType);
59  
60      List<TravelAuthorizationDocument> findAuthorizationDocuments(final String travelDocumentNumber);
61  
62      /**
63       * Retrieves the numbers of any Travel Authorization (or child) documents associated with the given trip id
64       * @param travelDocumentIdentifier the trip id to find authorizations related to
65       * @return a List of TravelAuthorization (or child!) document numbers for authorizations associated with the given trip id
66       */
67      List<String> findAuthorizationDocumentNumbers(final String travelDocumentIdentifier);
68  
69      List<TravelReimbursementDocument> findReimbursementDocuments(final String travelDocumentIdentifier);
70  
71      /**
72       * Updates the perdiem items in a {@link TravelReimbursementDocument}. Can be used on an empty {@link Collection}. This means
73       * that if there are no perdiem items, it will recreate. Perfect do all stupid method.
74       *
75       * @param documentNumber is the original document number for reference to link the {@link Collection} items to
76       * @param perDiemList is the {@link List} that holds the per diem items. Please let this not be null
77       * @param perDiemId is the id of the {@link PerDiem} object used for this item
78       * @param start is the {@link Date} for the start of the trip
79       * @param end is the {@link Date} for the end of the trip
80       */
81      void updatePerDiemItemsFor(final TravelDocument document, final List<PerDiemExpense> perDiemList, final Integer perDiemId, final Timestamp start, final Timestamp end);
82  
83      /**
84       * Wrapper function to retrieve by document number
85       *
86       * @param document
87       * @return
88       * @throws WorkflowException
89       */
90      Map<String, List<Document>> getDocumentsRelatedTo(final TravelDocument document) throws WorkflowException;
91  
92      /**
93       *  Get DV, TA, TAA, TAC, TR, and AV documents related to the given <code>documentNumber</code>. travel document either
94       * have a TEM document number or they have the value of the <code>travelDocumentIdentifier</code> in their organization doc
95       * ids.
96       *
97       * @param documentNumber
98       * @return
99       * @throws WorkflowException
100      */
101     Map<String, List<Document>> getDocumentsRelatedTo(final String documentNumber) throws WorkflowException;
102 
103     /**
104      * Get related document lists filtering by the document type
105      *
106      * @param document
107      * @param documentType
108      * @return
109      */
110     List<Document> getDocumentsRelatedTo(final TravelDocument document, String... documentType);
111 
112 
113     /**
114      * @deprecated This method is no longer called and will be removed in KFS 6.0.
115      *
116      * This method will add fyi notes to initiator when document is cancelled, closed, etc.
117      *
118      * @param document
119      */
120     @Deprecated
121     void addAdHocFYIRecipient(final Document document);
122 
123     /**
124      * This method will add fyi notes to initiator when document is cancelled, closed, etc.
125      *
126      * @param document
127      * @param initiatorUserId
128      */
129     void addAdHocFYIRecipient(final Document document, String initiatorUserId);
130 
131     /**
132      * This method will add notes to initiator when document is cancelled, closed, etc.
133      *
134      * @param document
135      * @param initiatorUserId
136      */
137     void addAdHocRecipient(Document document, String initiatorUserId, String actionRequested);
138 
139     void routeToFiscalOfficer(final TravelDocument document, final String noteText) throws WorkflowException, Exception;
140 
141     /**
142      * This method copies the per diem expense object
143      *
144      * @param perDiemExpense
145      * @return the copied per diem expense
146      */
147     PerDiemExpense copyPerDiemExpense(PerDiemExpense perDiemExpense);
148 
149     /**
150      * This method calculates mileage and returns calculated value
151      *
152      * @param actualExpense
153      * @return mileageAmount
154      */
155     KualiDecimal calculateMileage(ActualExpense actualExpense);
156 
157     /**
158      *
159      */
160     public void handleNewActualExpense(final ActualExpense newActualExpenseLine);
161 
162     /**
163      * This method calculates the daily total for a given per diem mileage expense
164      *
165      * @param perDiemMilaeage
166      * @return a map for each expense (mileage, lodging, per diem)
167      */
168     Map<String, KualiDecimal> calculateDailyTotal(PerDiemExpense perDiemMilaeage);
169 
170     /**
171      * This method calculates the daily totals for a list of per diem mileage expenses
172      *
173      * @param perDiemExpenses
174      * @return a list of mapped totals
175      */
176     List<Map<String, KualiDecimal>> calculateDailyTotals(List<PerDiemExpense> perDiemExpenses);
177 
178     /**
179      * This method copies from one per diem mileage down the rest of the list
180      *
181      * @param travelDocument the travel document (with begin or end dates) to help determine how much of the per diem expense to copy down
182      * @param copyIndex
183      * @param perDiemExpenses
184      * @return the modified list of perDiemExpenses back
185      */
186     void copyDownPerDiemExpense(TravelDocument travelDocument, int copyIndex, List<PerDiemExpense> perDiemExpenses);
187 
188     /**
189      * Determines if an object with an expense type is that of a "hosted" meal. In TEM a hosted meal is a meal that has been
190      * provided by a hosting institution and cannot be taken as a reimbursement.
191      *
192      * @param havingExpenseType has an expense type to check for meal hosting
193      * @return true if the expense is a hosted meal or not
194      */
195     boolean isHostedMeal(final ExpenseTypeAware havingExpenseType);
196 
197     /**
198      * Check to see if the user has the travel manager role assigned to them
199      *
200      * @param user
201      * @return true if the user is a travel manager, false otherwise
202      */
203     public boolean isTravelManager(final Person user);
204 
205     public Integer calculateProratePercentage(PerDiemExpense perDiemExpense, String perDiemCalcMethod, Timestamp tripEnd);
206 
207     public boolean isOpen(TravelDocument document);
208 
209     public boolean isProcessed(TravelDocument document);
210 
211     public boolean isFinal(TravelDocument document);
212 
213     /**
214      * Check if the Travel authorization document has been successfully processed
215      *
216      * @param document
217      * @return
218      */
219     public boolean isTravelAuthorizationProcessed(TravelAuthorizationDocument document);
220 
221     /**
222      * Check if the Travel authroization document is processed AND is open for reimbursement in the app doc status
223      *
224      * @param document
225      * @return
226      */
227     public boolean isTravelAuthorizationOpened(TravelAuthorizationDocument document);
228 
229     public boolean isUnsuccessful(TravelDocument document);
230 
231     public Integer calculatePerDiemPercentageFromTimestamp(PerDiemExpense perDiemExpense, Timestamp tripEnd);
232 
233     public KualiDecimal getAmountDueFromInvoice(String documentNumber, KualiDecimal requestedAmount);
234 
235     public TravelAuthorizationDocument findCurrentTravelAuthorization(TravelDocument document);
236 
237     public TravelDocument findRootForTravelReimbursement(String travelDocumentIdentifier);
238 
239     public KualiDecimal getTotalCumulativeReimbursements(TravelDocument document);
240 
241     public KualiDecimal getTotalAuthorizedEncumbrance(TravelDocument document);
242 
243     public boolean isResponsibleForAccountsOn(final TravelDocument document, String principalId);
244 
245     public boolean checkNonEmployeeTravelerTypeCode(String travelerTypeCode);
246 
247     /**
248      * This is a ajax method, will be used to retrieve all states based on the country code passed
249      *
250      * @param countryCode
251      * @return String
252      */
253     public String getAllStates(final String countryCode);
254 
255     /**
256      * Copies group travelers and sets new document number
257      */
258     public List<GroupTraveler> copyGroupTravelers(List<GroupTraveler> groupTravelers, String documentNumber);
259 
260     /**
261      * Copies other travel expenses and sets new document number
262      */
263     public List<? extends TemExpense> copyActualExpenses(List<? extends TemExpense> actualExpenses, String documentNumber);
264 
265     /**
266      * Copies per diem expenses and sets new document number
267      */
268     public List<PerDiemExpense> copyPerDiemExpenses(List<PerDiemExpense> perDiemExpenses, String documentNumber);
269 
270     /**
271      * Copies travel advances and sets new document number
272      */
273     public List<TravelAdvance> copyTravelAdvances(List<TravelAdvance> travelAdvances, String documentNumber);
274 
275     /**
276      * Copies special circumstances and sets new document number
277      */
278     public List<SpecialCircumstances> copySpecialCircumstances(List<SpecialCircumstances> specialCircumstancesList, String documentNumber);
279 
280     /**
281      * Copies transportation mode details and sets new document number
282      */
283     public List<TransportationModeDetail> copyTransportationModeDetails(List<TransportationModeDetail> transportationModeDetails, String documentNumber);
284 
285     /**
286      *
287      * @param document
288      */
289     public void showNoTravelAuthorizationError(TravelReimbursementDocument document);
290 
291     /**
292      *
293      * This method gets the total of all advances given for the trip relating to the travel document.
294      * @param travelDocument
295      * @return {@linK KualiDecimal} that is the total of all advances
296      */
297     KualiDecimal getAdvancesTotalFor(final TravelDocument travelDocument);
298 
299     /**
300      * get all outstanding travel advances by the given invoice document numbers. The advances must have not been used to generate
301      * taxable ramification
302      *
303      * @param arInvoiceDocNumbers the given AR invoice document numbers
304      * @return a list of outstanding travel advances
305      */
306 
307     List<TravelAdvance> getOutstandingTravelAdvanceByInvoice(Set<String> arInvoiceDocNumber);
308 
309     String retrieveAddressFromLocationCode(String locationCode);
310 
311     /**
312      * Remove the imported expense from the document (though DB)
313      *
314      * @param document
315      */
316     public void detachImportedExpenses(TravelDocument document);
317 
318     /**
319      * Adding the imported expense to the document (in the DB)
320      *
321      * @param document
322      */
323     public void attachImportedExpenses(TravelDocument document);
324 
325     public boolean checkHoldGLPEs(TravelDocument document);
326 
327     public void revertOriginalDocument(TravelDocument travelDocument, String status);
328 
329     /**
330      * find the latest taxable ramification notification date
331      *
332      * @return the latest taxable ramification notification date
333      */
334     Date findLatestTaxableRamificationNotificationDate();
335 
336     /**
337      * Perform validation on accounting lines that have already been entered, but have the potential to have bad data inserted into the db.
338      * @param TravelDocument
339      * @return
340      *      true if valid, false otherwise
341      */
342     public boolean validateSourceAccountingLines(TravelDocument travelDocument, boolean addToErrorPath);
343 
344     /**
345      * Get the Generic document type name of the travel document
346      *
347      * TA(not TAC, TAA), TR, ENT, RELO
348      *
349      * @param document
350      * @return
351      */
352     public String getDocumentType(TravelDocument document);
353 
354     /**
355      *
356      * This method creates a key-value pair of MileageRates that are valid for the searchDate.
357      * @param searchDate
358      * @return
359      */
360     List<KeyValue> getMileageRateKeyValues(Date searchDate);
361 
362     /**
363      * Import {@link GroupTraveler} instances into a {@link TravelDocument} via CSV data
364      *
365      *  @param document to add {@link GroupTraveler} instances to
366      *  @param csvData
367      *  @throws Exception when there's an error parsing the CSV data
368      */
369     List<GroupTraveler> importGroupTravelers(final TravelDocument document, final String csvData) throws Exception;
370 
371     /**
372      *
373      * This method imports the file and convert it to a list of objects (of the class specified in the parameter)
374      * @param formFile
375      * @param c
376      * @param attributeNames
377      * @param tabErrorKey
378      * @return
379      */
380     <T> List<T> importFile(final String fileContents, final Class<T> c, final String[] attributeNames,
381                            final Map<String,List<String>> defaultValues, final Integer[] attributeMaxLength, final String tabErrorKey);
382 
383     /**
384      * Returns all travel advances associated with the passed in trip id
385      * @param travelDocumentIdentifier the trip id of the reimbursement
386      * @return a List of all TravelAdvances associated with that trip
387      */
388     public List<TravelAdvance> getTravelAdvancesForTrip(String travelDocumentIdentifier);
389 
390     /**
391      * @return the default AR organization options for TEM documents
392      */
393     public AccountsReceivableOrganizationOptions getOrgOptions();
394 
395     /**
396      * This method searches to make sure that the expense entered doesn't already exist
397      * If they exist, disable them in the per diem table and notify the user.
398      * @param trDocument
399      *          the current doc.
400      * @param actualExpense
401      *          the expense in question
402      */
403     public void disableDuplicateExpenses(TravelDocument trDocument, ActualExpense actualExpense);
404 
405     /**
406      * Sets the meal and incidental amounts on the given per diem expense
407      * @param expense the expense to set amounts on
408      * @param perDiem the per diem record amounts are based off of
409      * @param tripType the trip type being taken
410      * @param tripEnd the end time of the trip
411      * @param shouldProrate whether this expense should be prorated
412      */
413     public void setPerDiemMealsAndIncidentals(PerDiemExpense expense, PerDiem perDiem, TripType tripType, Timestamp tripEnd, boolean shouldProrate);
414 
415     /**
416      *
417      * This method gets the parent travel document by travel document identifier
418      * This means: the current TA which is the authorization of the trip; or if no TA is present, the root TR, ENT, or RELO document
419      *  @param travelDocumentIdentifier
420      *  @return
421      */
422     public TravelDocument getParentTravelDocument(String travelDocumentIdentifier);
423 
424     /**
425      * Returns the root travel document by the travel document identifier.  This is the progenitor document of the trip - either the first TA,
426      * first TR, first ENT, or first RELO which began the trip
427      * It does not retrieve the workflow document of the associated document
428      * @param travelDocumentIdentifier
429      * @return the root document of the trip
430      */
431     public TravelDocument getRootTravelDocumentWithoutWorkflowDocument(String travelDocumentIdentifier);
432 
433     /**
434      * This method retrieves a list of approved documents related to a travelDocumentIdentifier. It will grab the most current TA (TAA, TAC)
435      * and all TR, ENT, and RELO for the given identifier.
436      *
437      * @param travelDocumentIdentifier
438      * @return
439      */
440     public Collection<String> getApprovedTravelDocumentNumbersByTrip(String travelDocumentIdentifier);
441 
442     /**
443      * This method determines whether a document is in the correct state for reconciling external vendor charges.
444      *
445      * @param travelDocument
446      * @return
447      */
448     public boolean isDocumentStatusValidForReconcilingCharges(TravelDocument travelDocument);
449 
450     /**
451      * find matching trips  for the same traveler, dates
452      *
453      */
454     public List<String> findMatchingTrips(TravelDocument document);
455 
456     /**
457      * If a value on a per diem expense has been zero'd out, this method will restore it to its default value
458      * @param document the document with per diem expenses
459      * @param property the property to restore
460      */
461     public void restorePerDiemProperty(TravelDocument document, String property);
462 
463     /**
464      * This smooshes the accounting lines which will do advance clearing.  Here, since we're replacing the object code, we'll smooth together all accounting lines
465      * which have the same chart - account - sub-acount.
466      * @param originalAccountingLines the List of accounting lines to smoosh
467      * @return the smooshed accounting lines
468      */
469     public List<TemSourceAccountingLine> smooshAccountingLinesToSubAccount(List<TemSourceAccountingLine> originalAccountingLines);
470 
471     /**
472      * Generates a list of agency links for the document.  If property config.document.travelRelocation.agencySites.enable is false,
473      * then an empty list will be returned; otherwise uses values from the url.document.travelRelocation.agencySites, customized by
474      * the customizeAgencyLink method
475      * @param travelDocument the travel document we're currently building a link for
476      * @return a List of links to external agencies
477      */
478     public List<LinkField> getAgencyLinks(TravelDocument travelDocument);
479 
480     /**
481      * A hook which allows implementers to customize an agency link.  Currently, it will just see if the config.document.travelRelocation.agencySites.include.tripId
482      * is set to true; if so, it will append ?tripId= the trip id
483      * @param travelDocument the travel document we are creating agency links for
484      * @param agencyName the name of the agency
485      * @param link the current link text
486      * @return the customized link text
487      */
488     public String customizeAgencyLink(TravelDocument travelDocument, String agencyName, String link);
489 
490     /**
491      * Checks whether the TEMReimbursementDocument require traveler's approval routing based on its travel arranger's profile.
492      * @param trDoc the TEMReimbursementDocument to be checked
493      * @return true if the trDoc requires traveler's approval; false otherwise
494      */
495     public boolean requiresTravelerApproval(TEMReimbursementDocument trDoc);
496 
497     /**
498      * Checks whether the TravelAuthorizationDocument require traveler's approval routing based on its travel arranger's profile.
499      * @param taDoc the TravelAuthorizationDocument to be checked
500      * @return true if the taDoc requires traveler's approval; false otherwise
501      */
502     public boolean requiresTravelerApproval(TravelAuthorizationDocument taDoc);
503 
504     /**
505      * Checks whether the TravelDocument's initiator is the traveler him/herself (if not, then the initiator is one of the arranger).
506      * @param travelDoc the TravelDocument to be checked
507      * @return true if the TravelDocument's initiator is the traveler.
508      */
509     public boolean isInitiatorTraveler(TravelDocument travelDoc);
510 
511 }