1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.kuali.kfs.module.tem.batch.service.impl;
20
21 import java.util.ArrayList;
22 import java.util.List;
23
24 import org.apache.commons.lang.StringUtils;
25 import org.apache.commons.lang.builder.ReflectionToStringBuilder;
26 import org.apache.commons.lang.builder.ToStringStyle;
27 import org.apache.log4j.Logger;
28 import org.kuali.kfs.coa.businessobject.ObjectCode;
29 import org.kuali.kfs.coa.service.ObjectCodeService;
30 import org.kuali.kfs.module.tem.TemConstants;
31 import org.kuali.kfs.module.tem.TemConstants.AgencyMatchProcessParameter;
32 import org.kuali.kfs.module.tem.TemParameterConstants;
33 import org.kuali.kfs.module.tem.batch.service.ImportedExpensePendingEntryService;
34 import org.kuali.kfs.module.tem.businessobject.AgencyServiceFee;
35 import org.kuali.kfs.module.tem.businessobject.AgencyStagingData;
36 import org.kuali.kfs.module.tem.businessobject.ImportedExpense;
37 import org.kuali.kfs.module.tem.businessobject.TemSourceAccountingLine;
38 import org.kuali.kfs.module.tem.businessobject.TripAccountingInformation;
39 import org.kuali.kfs.module.tem.document.TravelDocument;
40 import org.kuali.kfs.module.tem.document.service.TravelDocumentService;
41 import org.kuali.kfs.sys.KFSConstants;
42 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntry;
43 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper;
44 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail;
45 import org.kuali.kfs.sys.document.validation.impl.AccountingDocumentRuleBaseConstants.GENERAL_LEDGER_PENDING_ENTRY_CODE;
46 import org.kuali.kfs.sys.service.GeneralLedgerPendingEntryService;
47 import org.kuali.kfs.sys.service.UniversityDateService;
48 import org.kuali.rice.core.api.datetime.DateTimeService;
49 import org.kuali.rice.core.api.util.type.KualiDecimal;
50 import org.kuali.rice.coreservice.framework.parameter.ParameterService;
51 import org.kuali.rice.krad.service.DataDictionaryService;
52 import org.kuali.rice.krad.util.ObjectUtils;
53
54 @SuppressWarnings("deprecation")
55 public class ImportedExpensePendingEntryServiceImpl implements ImportedExpensePendingEntryService{
56
57 private static Logger LOG = org.apache.log4j.Logger.getLogger(ImportedExpensePendingEntryServiceImpl.class);
58
59 DateTimeService dateTimeService;
60 UniversityDateService universityDateService;
61 ParameterService parameterService;
62 GeneralLedgerPendingEntryService generalLedgerPendingEntryService;
63 TravelDocumentService travelDocumentService;
64 ObjectCodeService objectCodeService;
65 DataDictionaryService dataDictionaryService;
66
67
68
69
70
71 @Override
72 public boolean checkAndAddPendingEntriesToList(List<GeneralLedgerPendingEntry> pendingEntries, List<GeneralLedgerPendingEntry> entryList, AgencyStagingData agencyData, boolean isCredit, boolean generateOffset){
73 boolean result = true;
74
75 int expectedEntrySize = generateOffset? 2 : 1;
76
77 if (pendingEntries.size() != expectedEntrySize){
78 LOG.error("Failed to create a " + (isCredit? " CREDIT" : "DEBIT") + " GLPE for agency: " + agencyData.getId() + " tripId: " + agencyData.getTripId());
79 result = false;
80 }else{
81
82 entryList.addAll(pendingEntries);
83 }
84
85 return result;
86 }
87
88
89
90
91 @Override
92 public GeneralLedgerPendingEntry buildGeneralLedgerPendingEntry(AgencyStagingData agencyData, TripAccountingInformation info, GeneralLedgerPendingEntrySequenceHelper sequenceHelper,
93 String chartCode, String objectCode, KualiDecimal amount, String glCredtiDebitCode){
94
95 ObjectCode objectCd = getObjectCodeService().getByPrimaryIdForCurrentYear(chartCode, objectCode);
96 if (ObjectUtils.isNull(objectCd)) {
97 LOG.error("ERROR: Could not get an ObjectCode for chart code: " + chartCode + " object code: " + objectCode);
98 return null;
99 }
100
101 GeneralLedgerPendingEntry glpe = buildBasicDistributionPendingEntry(sequenceHelper);
102
103 glpe.setDocumentNumber(getImportExpenseDocumentNumber(agencyData));
104
105 glpe.setChartOfAccountsCode(chartCode);
106 glpe.setFinancialObjectCode(objectCode);
107 glpe.setFinancialSubObjectCode(StringUtils.defaultIfEmpty(info.getSubObjectCode(), GENERAL_LEDGER_PENDING_ENTRY_CODE.getBlankFinancialSubObjectCode()));
108 glpe.setFinancialObjectTypeCode(objectCd.getFinancialObjectTypeCode());
109 glpe.setProjectCode(StringUtils.defaultIfEmpty(info.getProjectCode(), GENERAL_LEDGER_PENDING_ENTRY_CODE.getBlankProjectCode()));
110 glpe.setTransactionLedgerEntryAmount(amount);
111 glpe.setTransactionDebitCreditCode(glCredtiDebitCode);
112 glpe.setTransactionDate(agencyData.getTransactionPostingDate());
113 glpe.setOrganizationDocumentNumber(StringUtils.isNotEmpty(agencyData.getTravelerId())? agencyData.getTravelerId() : agencyData.getTripId());
114 glpe.setFinancialDocumentApprovedCode(KFSConstants.PENDING_ENTRY_APPROVED_STATUS_CODE.APPROVED);
115
116 return glpe;
117 }
118
119
120
121
122
123
124 protected GeneralLedgerPendingEntry buildBasicDistributionPendingEntry(GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
125 GeneralLedgerPendingEntry glpe = new GeneralLedgerPendingEntry();
126 final String DIST_INCOME_DOC_TYPE = KFSConstants.FinancialDocumentTypeCodes.DISTRIBUTION_OF_INCOME_AND_EXPENSE;
127
128
129 glpe.setVersionNumber(new Long(1));
130 glpe.setUniversityFiscalYear(universityDateService.getCurrentFiscalYear());
131 glpe.setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_ACTUAL);
132 glpe.setFinancialDocumentTypeCode(DIST_INCOME_DOC_TYPE);
133 glpe.setFinancialSystemOriginationCode(TemConstants.TEM_IMPORTED_SYS_ORIG_CD);
134 glpe.setTransactionLedgerEntryDescription(TemConstants.TEM_IMPORTED_GLPE_DESC);
135 glpe.setTransactionLedgerEntrySequenceNumber(new Integer(sequenceHelper.getSequenceCounter()));
136 glpe.setOrganizationReferenceId(DIST_INCOME_DOC_TYPE +TemConstants.IMPORTED_FLAG);
137
138 sequenceHelper.increment();
139
140 return glpe;
141 }
142
143
144
145
146 @Override
147 public List<GeneralLedgerPendingEntry> buildDebitPendingEntry(AgencyStagingData agencyData, TripAccountingInformation info, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, String objectCode, KualiDecimal amount, boolean generateOffset){
148
149 List<GeneralLedgerPendingEntry> entryList = new ArrayList<GeneralLedgerPendingEntry>();
150
151 GeneralLedgerPendingEntry pendingEntry = buildGeneralLedgerPendingEntry(agencyData, info, sequenceHelper, info.getTripChartCode(), objectCode, amount, KFSConstants.GL_DEBIT_CODE);
152 if(ObjectUtils.isNotNull(pendingEntry )) {
153 pendingEntry.setAccountNumber(info.getTripAccountNumber());
154 pendingEntry.setSubAccountNumber(StringUtils.defaultIfEmpty(info.getTripSubAccountNumber(), GENERAL_LEDGER_PENDING_ENTRY_CODE.getBlankSubAccountNumber()));
155
156 LOG.info("Created DEBIT GLPE: " + pendingEntry.getDocumentNumber() + " for AGENCY Import Expense: " + agencyData.getId() + " TripId: " + agencyData.getTripId()
157 + "\n\n" + ReflectionToStringBuilder.reflectionToString(pendingEntry, ToStringStyle.MULTI_LINE_STYLE));
158
159
160 entryList.add(pendingEntry);
161
162 if (generateOffset){
163 generateOffsetPendingEntry(entryList, sequenceHelper, pendingEntry);
164 }
165 }
166 return entryList;
167 }
168
169
170
171
172 @Override
173 public List<GeneralLedgerPendingEntry> buildCreditPendingEntry(AgencyStagingData agencyData, TripAccountingInformation info, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, String objectCode, KualiDecimal amount, boolean generateOffset){
174 List<GeneralLedgerPendingEntry> entryList = new ArrayList<GeneralLedgerPendingEntry>();
175
176
177 String chartCode = parameterService.getParameterValueAsString(TemParameterConstants.TEM_ALL.class, AgencyMatchProcessParameter.TRAVEL_CREDIT_CARD_CLEARING_CHART);
178
179 GeneralLedgerPendingEntry pendingEntry = buildGeneralLedgerPendingEntry(agencyData, info, sequenceHelper, chartCode, objectCode, amount, KFSConstants.GL_CREDIT_CODE);
180 if(ObjectUtils.isNotNull(pendingEntry )) {
181 pendingEntry.setAccountNumber(parameterService.getParameterValueAsString(TemParameterConstants.TEM_ALL.class, AgencyMatchProcessParameter.TRAVEL_CREDIT_CARD_CLEARING_ACCOUNT));
182 pendingEntry.setSubAccountNumber(GENERAL_LEDGER_PENDING_ENTRY_CODE.getBlankSubAccountNumber());
183 }
184
185 LOG.info("Created CREDIT GLPE: " + pendingEntry.getDocumentNumber() + " for AGENCY Import Expense: " + agencyData.getId() + " TripId: " + agencyData.getTripId()
186 + "\n\n" + ReflectionToStringBuilder.reflectionToString(pendingEntry, ToStringStyle.MULTI_LINE_STYLE));
187
188
189 if (ObjectUtils.isNotNull(pendingEntry)) {
190 entryList.add(pendingEntry);
191
192 if (generateOffset){
193 generateOffsetPendingEntry(entryList, sequenceHelper, pendingEntry);
194 }
195 }
196 return entryList;
197 }
198
199
200
201
202 @Override
203 public List<GeneralLedgerPendingEntry> buildDistributionEntriesForCTSExpense(ImportedExpense expense, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, String travelDocumentIdentifier){
204 List<GeneralLedgerPendingEntry> entries = new ArrayList<GeneralLedgerPendingEntry>();
205
206 final String chartCode = parameterService.getParameterValueAsString(TemParameterConstants.TEM_ALL.class, AgencyMatchProcessParameter.TRAVEL_CREDIT_CARD_CLEARING_CHART);
207 final String accountNumber = parameterService.getParameterValueAsString(TemParameterConstants.TEM_ALL.class, AgencyMatchProcessParameter.TRAVEL_CREDIT_CARD_CLEARING_ACCOUNT);
208 final String creditObjectCode = parameterService.getParameterValueAsString(TemParameterConstants.TEM_ALL.class, AgencyMatchProcessParameter.TRAVEL_CREDIT_CARD_CLEARING_OBJECT_CODE);
209
210 ObjectCode objectCd = getObjectCodeService().getByPrimaryIdForCurrentYear(chartCode, creditObjectCode);
211 if (ObjectUtils.isNull(objectCd)) {
212 LOG.error("ERROR: Could not get an ObjectCode for chart code: " + chartCode + " object code: " + creditObjectCode);
213 return null;
214 }
215
216 GeneralLedgerPendingEntry explicitEntry = buildBasicDistributionPendingEntry(sequenceHelper);
217
218 explicitEntry.setDocumentNumber(expense.getDocumentNumber());
219
220 explicitEntry.setChartOfAccountsCode(chartCode);
221 explicitEntry.setAccountNumber(accountNumber);
222 explicitEntry.setFinancialObjectCode(creditObjectCode);
223 explicitEntry.setFinancialObjectTypeCode(objectCd.getFinancialObjectTypeCode());
224 explicitEntry.setTransactionLedgerEntryAmount(expense.getConvertedAmount());
225 explicitEntry.setTransactionDebitCreditCode(KFSConstants.GL_CREDIT_CODE);
226 explicitEntry.setTransactionDate(dateTimeService.getCurrentSqlDate());
227 explicitEntry.setOrganizationDocumentNumber(travelDocumentIdentifier);
228
229 entries.add(explicitEntry);
230
231 generateOffsetPendingEntry(entries, sequenceHelper, explicitEntry);
232
233 return entries;
234 }
235
236
237
238
239
240 @Override
241 public List<GeneralLedgerPendingEntry> buildServiceFeeCreditPendingEntry(AgencyStagingData agencyData, TripAccountingInformation info, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, AgencyServiceFee serviceFee, KualiDecimal amount, boolean generateOffset){
242 List<GeneralLedgerPendingEntry> entryList = new ArrayList<GeneralLedgerPendingEntry>();
243
244 GeneralLedgerPendingEntry pendingEntry = buildGeneralLedgerPendingEntry(agencyData, info, sequenceHelper, serviceFee.getCreditChartCode(), serviceFee.getCreditObjectCode(), amount, KFSConstants.GL_CREDIT_CODE);
245 if(ObjectUtils.isNotNull(pendingEntry )) {
246 pendingEntry.setAccountNumber(serviceFee.getCreditAccountNumber());
247 pendingEntry.setSubAccountNumber(GENERAL_LEDGER_PENDING_ENTRY_CODE.getBlankSubAccountNumber());
248 }
249
250 LOG.info("Created ServiceFee CREDIT GLPE: " + pendingEntry.getDocumentNumber() + " for AGENCY Import Expense: " + agencyData.getId() + " TripId: " + agencyData.getTripId()
251 + "\n\n" + ReflectionToStringBuilder.reflectionToString(pendingEntry, ToStringStyle.MULTI_LINE_STYLE));
252
253
254 if (ObjectUtils.isNotNull(pendingEntry)) {
255 entryList.add(pendingEntry);
256
257 if (generateOffset){
258 generateOffsetPendingEntry(entryList, sequenceHelper, pendingEntry);
259 }
260 }
261 return entryList;
262 }
263
264
265
266
267
268
269
270
271 private void generateOffsetPendingEntry(List<GeneralLedgerPendingEntry> entryList, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, GeneralLedgerPendingEntry pendingEntry){
272 GeneralLedgerPendingEntry offsetEntry = new GeneralLedgerPendingEntry(pendingEntry);
273 boolean success = generalLedgerPendingEntryService.populateOffsetGeneralLedgerPendingEntry(universityDateService.getCurrentFiscalYear(), pendingEntry, sequenceHelper, offsetEntry);
274 sequenceHelper.increment();
275 if (success){
276 LOG.info("Created OFFSET GLPE: " + pendingEntry.getDocumentNumber() + "\n" + ReflectionToStringBuilder.reflectionToString(pendingEntry, ToStringStyle.MULTI_LINE_STYLE));
277 entryList.add(offsetEntry);
278 }
279 }
280
281
282
283
284 @Override
285 public boolean generateDocumentImportedExpenseGeneralLedgerPendingEntries(TravelDocument travelDocument, GeneralLedgerPendingEntrySourceDetail glpeSourceDetail, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, boolean isCredit, String docType){
286 LOG.debug("processGenerateGeneralLedgerPendingEntries(TravelDocument, AccountingLine, GeneralLedgerPendingEntrySequenceHelper, boolean) - start");
287
288 glpeSourceDetail.getObjectCode().setChartOfAccountsCode(glpeSourceDetail.getChartOfAccountsCode());
289 glpeSourceDetail.getObjectCode().setFinancialObjectCode(glpeSourceDetail.getFinancialObjectCode());
290 glpeSourceDetail.getObjectCode().setUniversityFiscalYear(glpeSourceDetail.getPostingYear());
291
292 ((TemSourceAccountingLine)glpeSourceDetail).getObjectTypeCode();
293
294
295
296 GeneralLedgerPendingEntry explicitEntry = new GeneralLedgerPendingEntry();
297 processExplicitGeneralLedgerPendingEntry(travelDocument, sequenceHelper, glpeSourceDetail, explicitEntry);
298
299 explicitEntry.setFinancialDocumentTypeCode(docType);
300 explicitEntry.setTransactionLedgerEntryDescription(TemConstants.TEM_IMPORTED_GLPE_DESC);
301 explicitEntry.setOrganizationDocumentNumber(travelDocument.getTravelDocumentIdentifier());
302 explicitEntry.setDocumentNumber(getImportExpenseDocumentNumber(travelDocument));
303 explicitEntry.setOrganizationReferenceId(travelDocument.getFinancialDocumentTypeCode()+TemConstants.IMPORTED_FLAG);
304 final String transactionCode = isCredit ? KFSConstants.GL_CREDIT_CODE : KFSConstants.GL_DEBIT_CODE;
305 explicitEntry.setTransactionDebitCreditCode(transactionCode);
306
307
308 sequenceHelper.increment();
309
310
311 GeneralLedgerPendingEntry offsetEntry = new GeneralLedgerPendingEntry(explicitEntry);
312 explicitEntry.setOrganizationReferenceId(travelDocument.getFinancialDocumentTypeCode()+TemConstants.IMPORTED_FLAG);
313 boolean success = processOffsetGeneralLedgerPendingEntry(travelDocument, sequenceHelper, glpeSourceDetail, explicitEntry, offsetEntry);
314 sequenceHelper.increment();
315
316 LOG.debug("processGenerateGeneralLedgerPendingEntries(TravelDocument, AccountingLine, GeneralLedgerPendingEntrySequenceHelper, boolean) - end");
317 return success;
318 }
319
320
321
322
323
324
325
326
327 private void processExplicitGeneralLedgerPendingEntry(TravelDocument travelDocument, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, GeneralLedgerPendingEntrySourceDetail glpeSourceDetail, GeneralLedgerPendingEntry explicitEntry) {
328 LOG.debug("processExplicitGeneralLedgerPendingEntry(TravelDocument, GeneralLedgerPendingEntrySequenceHelper, AccountingLine, GeneralLedgerPendingEntry) ");
329
330 generalLedgerPendingEntryService.populateExplicitGeneralLedgerPendingEntry(travelDocument, glpeSourceDetail, sequenceHelper, explicitEntry);
331 travelDocument.addPendingEntry(explicitEntry);
332 }
333
334
335
336
337
338
339
340
341
342
343 private boolean processOffsetGeneralLedgerPendingEntry(TravelDocument travelDocument, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, GeneralLedgerPendingEntrySourceDetail postable, GeneralLedgerPendingEntry explicitEntry, GeneralLedgerPendingEntry offsetEntry) {
344 LOG.debug("processOffsetGeneralLedgerPendingEntry(TravelDocument, GeneralLedgerPendingEntrySequenceHelper, AccountingLine, GeneralLedgerPendingEntry, GeneralLedgerPendingEntry) ");
345
346
347 boolean success = generalLedgerPendingEntryService.populateOffsetGeneralLedgerPendingEntry(travelDocument.getPostingYear(), explicitEntry, sequenceHelper, offsetEntry);
348 travelDocument.addPendingEntry(offsetEntry);
349 return success;
350 }
351
352
353
354
355
356
357
358 protected String getImportExpenseDocumentNumber(TravelDocument travelDocument) {
359 if (ObjectUtils.isNotNull(travelDocument)) {
360 return travelDocument.getDocumentNumber();
361 }
362 else {
363 return null;
364 }
365 }
366
367
368
369
370
371
372
373 protected String getImportExpenseDocumentNumber(AgencyStagingData agencyData) {
374 TravelDocument travelDocument = getTravelDocumentService().getParentTravelDocument(agencyData.getTripId());
375 return getImportExpenseDocumentNumber(travelDocument);
376 }
377
378 public void setDateTimeService(DateTimeService dateTimeService) {
379 this.dateTimeService = dateTimeService;
380 }
381
382 public void setUniversityDateService(UniversityDateService universityDateService) {
383 this.universityDateService = universityDateService;
384 }
385
386 public void setParameterService(ParameterService parameterService) {
387 this.parameterService = parameterService;
388 }
389
390 public void setGeneralLedgerPendingEntryService(GeneralLedgerPendingEntryService generalLedgerPendingEntryService) {
391 this.generalLedgerPendingEntryService = generalLedgerPendingEntryService;
392 }
393
394 public TravelDocumentService getTravelDocumentService() {
395 return travelDocumentService;
396 }
397
398 public void setTravelDocumentService(TravelDocumentService travelDocumentService) {
399 this.travelDocumentService = travelDocumentService;
400 }
401
402 public ObjectCodeService getObjectCodeService() {
403 return objectCodeService;
404 }
405
406 public void setObjectCodeService(ObjectCodeService objectCodeService) {
407 this.objectCodeService = objectCodeService;
408 }
409
410 public DataDictionaryService getDataDictionaryService() {
411 return dataDictionaryService;
412 }
413
414 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
415 this.dataDictionaryService = dataDictionaryService;
416 }
417 }