001: /*
002: * Copyright 2007 The Kuali Foundation.
003: *
004: * Licensed under the Educational Community License, Version 1.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.opensource.org/licenses/ecl1.php
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.kuali.module.gl.batch.collector;
017:
018: import java.io.Serializable;
019: import java.sql.Date;
020: import java.util.ArrayList;
021: import java.util.List;
022:
023: import org.kuali.core.service.BusinessObjectDictionaryService;
024: import org.kuali.core.service.BusinessObjectService;
025: import org.kuali.core.service.DataDictionaryService;
026: import org.kuali.core.service.DateTimeService;
027: import org.kuali.core.util.KualiDecimal;
028: import org.kuali.kfs.KFSPropertyConstants;
029: import org.kuali.kfs.context.SpringContext;
030: import org.kuali.module.chart.bo.Chart;
031: import org.kuali.module.chart.bo.Org;
032: import org.kuali.module.gl.bo.CollectorDetail;
033: import org.kuali.module.gl.bo.CollectorHeader;
034: import org.kuali.module.gl.bo.OriginEntryFull;
035: import org.kuali.module.gl.bo.OriginEntryGroup;
036: import org.kuali.module.gl.bo.OriginEntrySource;
037: import org.kuali.module.gl.service.CollectorDetailService;
038: import org.kuali.module.gl.service.OriginEntryService;
039: import org.kuali.module.gl.util.CollectorReportData;
040:
041: /**
042: * Object representation of collector xml input.
043: */
044: public class CollectorBatch implements Serializable {
045: // way to distinguish this batch from others
046: private String batchName;
047:
048: // header records
049: private String chartOfAccountsCode;
050: private String organizationCode;
051: private Date transmissionDate;
052: private String personUserID;
053: private Integer batchSequenceNumber;
054: private String workgroupName;
055:
056: private String campusCode;
057: private String phoneNumber;
058: private String mailingAddress;
059: private String departmentName;
060:
061: private List<OriginEntryFull> originEntries;
062: private List<CollectorDetail> collectorDetails;
063:
064: // trailer records
065: private Integer totalRecords;
066: private KualiDecimal totalAmount;
067:
068: /**
069: * Constructs a CollectorBatch
070: */
071: public CollectorBatch() {
072: originEntries = new ArrayList();
073: collectorDetails = new ArrayList();
074: }
075:
076: /**
077: * Gets the batchSequenceNumber attribute.
078: */
079: public Integer getBatchSequenceNumber() {
080: return batchSequenceNumber;
081: }
082:
083: /**
084: * Sets the batchSequenceNumber attribute value.
085: */
086: public void setBatchSequenceNumber(Integer batchSequenceNumber) {
087: this .batchSequenceNumber = batchSequenceNumber;
088: }
089:
090: /**
091: * Gets the chartOfAccountsCode attribute.
092: */
093: public String getChartOfAccountsCode() {
094: return chartOfAccountsCode;
095: }
096:
097: /**
098: * Sets the chartOfAccountsCode attribute value.
099: */
100: public void setChartOfAccountsCode(String chartOfAccountsCode) {
101: this .chartOfAccountsCode = chartOfAccountsCode;
102: }
103:
104: /**
105: * Gets the organizationCode attribute.
106: */
107: public String getOrganizationCode() {
108: return organizationCode;
109: }
110:
111: /**
112: * Sets the organizationCode attribute value.
113: */
114: public void setOrganizationCode(String organizationCode) {
115: this .organizationCode = organizationCode;
116: }
117:
118: /**
119: * Gets the totalAmount attribute.
120: */
121: public KualiDecimal getTotalAmount() {
122: return totalAmount;
123: }
124:
125: /**
126: * Sets the totalAmount attribute value.
127: */
128: public void setTotalAmount(KualiDecimal totalAmount) {
129: this .totalAmount = totalAmount;
130: }
131:
132: /**
133: * Sets the total amount from the String.
134: */
135: public void setTotalAmount(String totalAmount) {
136: this .totalAmount = new KualiDecimal(totalAmount);
137: }
138:
139: /**
140: * Sets the total amount field to null.
141: */
142: public void clearTotalAmount() {
143: this .totalAmount = null;
144: }
145:
146: /**
147: * Gets the totalRecords attribute.
148: */
149: public Integer getTotalRecords() {
150: return totalRecords;
151: }
152:
153: /**
154: * Sets the totalRecords attribute value.
155: */
156: public void setTotalRecords(Integer totalRecords) {
157: this .totalRecords = totalRecords;
158: }
159:
160: /**
161: * Gets the transmissionDate attribute.
162: */
163: public Date getTransmissionDate() {
164: return transmissionDate;
165: }
166:
167: /**
168: * Sets the transmissionDate attribute value.
169: */
170: public void setTransmissionDate(Date transmissionDate) {
171: this .transmissionDate = transmissionDate;
172: }
173:
174: /**
175: * Gets the workgroupName attribute.
176: */
177: public String getWorkgroupName() {
178: return workgroupName;
179: }
180:
181: /**
182: * Sets the workgroupName attribute value.
183: */
184: public void setWorkgroupName(String workgroupName) {
185: this .workgroupName = workgroupName;
186: }
187:
188: /**
189: * Gets the personUserID attribute.
190: */
191: public String getPersonUserID() {
192: return personUserID;
193: }
194:
195: /**
196: * Sets the personUserID attribute value.
197: */
198: public void setPersonUserID(String personUserID) {
199: this .personUserID = personUserID;
200: }
201:
202: /**
203: * Gets the idBillings attribute.
204: */
205: public List<CollectorDetail> getCollectorDetails() {
206: return collectorDetails;
207: }
208:
209: /**
210: * Sets the idBillings attribute value.
211: */
212: public void setCollectorDetails(List<CollectorDetail> idDetails) {
213: this .collectorDetails = idDetails;
214: }
215:
216: /**
217: * Gets the originEntries attribute.
218: */
219: public List<OriginEntryFull> getOriginEntries() {
220: return originEntries;
221: }
222:
223: /**
224: * Sets the originEntries attribute value.
225: */
226: public void setOriginEntries(List<OriginEntryFull> batchOriginEntry) {
227: this .originEntries = batchOriginEntry;
228: }
229:
230: /**
231: * Adds a processed origin entry to the list.
232: */
233: public void addOriginEntry(OriginEntryFull orginEntry) {
234: this .originEntries.add(orginEntry);
235: }
236:
237: /**
238: * Adds a processed id billing to the list.
239: */
240: public void addCollectorDetail(CollectorDetail collectorDetail) {
241: this .collectorDetails.add(collectorDetail);
242: }
243:
244: /**
245: * Attempts to retrieve a collector header already exists with the primary key values given for this object
246: *
247: * @return the CollectorHeader found in the database
248: */
249: public CollectorHeader retrieveDuplicateHeader() {
250: // checkHeader is used to check whether a record with the same PK values exist already (i.e. only PK values are filled in).
251: CollectorHeader checkHeader = createCollectorHeaderWithPKValuesOnly();
252:
253: CollectorHeader foundHeader = (CollectorHeader) SpringContext
254: .getBean(BusinessObjectService.class).retrieve(
255: checkHeader);
256: return foundHeader;
257: }
258:
259: /**
260: * Sets defaults for fields not populated from file. Store an origin entry group, all gl entries and id billing entries from the
261: * processed file. Also write the header for the duplicate file check.
262: *
263: * @param originEntryGroup the group into which to store the origin entries
264: * @param collectorReportData report data
265: */
266: public void setDefaultsAndStore(OriginEntryGroup originEntryGroup,
267: CollectorReportData collectorReportData) {
268: // persistHeader is used to persist a collector header record into the DB
269: CollectorHeader persistHeader = createCollectorHeaderForStorage();
270: CollectorHeader foundHeader = retrieveDuplicateHeader();
271:
272: if (foundHeader != null) {
273: // update the version number to prevent OptimisticLockingExceptions
274: persistHeader.setVersionNumber(foundHeader
275: .getVersionNumber());
276: }
277: SpringContext.getBean(BusinessObjectService.class).save(
278: persistHeader);
279:
280: OriginEntryService originEntryService = SpringContext
281: .getBean(OriginEntryService.class);
282: for (OriginEntryFull entry : this .originEntries) {
283: entry.setGroup(originEntryGroup);
284: if (entry.getFinancialDocumentReversalDate() == null) {
285: entry.setFinancialDocumentReversalDate(SpringContext
286: .getBean(DateTimeService.class)
287: .getCurrentSqlDate());
288: }
289: // don't need to worry about previous origin entries existing in the DB because there'll never be a
290: // duplicate record because a sequence # is a key
291:
292: originEntryService.save(entry);
293: }
294:
295: CollectorDetailService collectorDetailService = SpringContext
296: .getBean(CollectorDetailService.class);
297: int numSavedDetails = 0;
298: for (CollectorDetail idDetail : this .collectorDetails) {
299: setDefaultsCollectorDetail(idDetail);
300: CollectorDetail foundIdDetail = (CollectorDetail) SpringContext
301: .getBean(BusinessObjectService.class).retrieve(
302: idDetail);
303: if (foundIdDetail != null) {
304: idDetail.setVersionNumber(foundIdDetail
305: .getVersionNumber());
306: }
307: numSavedDetails++;
308: collectorDetailService.save(idDetail);
309: }
310: collectorReportData.setNumSavedDetails(this , numSavedDetails);
311: }
312:
313: /**
314: * Uppercases the appropriate fields in the batch, if told to do so by the data dictionary
315: */
316: public void prepareDataForStorage() {
317: BusinessObjectDictionaryService businessObjectDictionaryService = SpringContext
318: .getBean(BusinessObjectDictionaryService.class);
319: DataDictionaryService dataDictionaryService = SpringContext
320: .getBean(DataDictionaryService.class);
321:
322: // uppercase the data used to generate the collector header
323: if (dataDictionaryService.getAttributeForceUppercase(
324: Chart.class,
325: KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE)) {
326: setChartOfAccountsCode(getChartOfAccountsCode()
327: .toUpperCase());
328: }
329: if (dataDictionaryService.getAttributeForceUppercase(Org.class,
330: KFSPropertyConstants.ORGANIZATION_CODE)) {
331: setOrganizationCode(getOrganizationCode().toUpperCase());
332: }
333:
334: // now uppercase all of the origin entry data
335: for (OriginEntryFull entry : originEntries) {
336: businessObjectDictionaryService
337: .performForceUppercase(entry);
338: }
339:
340: // uppercase the id billing entries
341: for (CollectorDetail collectorDetail : collectorDetails) {
342: businessObjectDictionaryService
343: .performForceUppercase(collectorDetail);
344: }
345: }
346:
347: /**
348: * Creates origin entry group from header fields.
349: *
350: * @return OriginEntryGroup
351: */
352: private OriginEntryGroup createOriginEntryGroup() {
353: OriginEntryGroup group = new OriginEntryGroup();
354:
355: group.setSourceCode(OriginEntrySource.COLLECTOR);
356: group.setDate(new java.sql.Date(SpringContext.getBean(
357: DateTimeService.class).getCurrentDate().getTime()));
358: group.setProcess(new Boolean(true));
359: group.setScrub(new Boolean(true));
360: group.setValid(new Boolean(true));
361:
362: return group;
363: }
364:
365: /**
366: * Creates a CollectorHeader from the batch to be used for storage
367: *
368: * @return CollectorHeader
369: */
370: public CollectorHeader createCollectorHeaderForStorage() {
371: CollectorHeader header = new CollectorHeader();
372:
373: header.setChartOfAccountsCode(getChartOfAccountsCode());
374: header.setOrganizationCode(getOrganizationCode());
375: header.setProcessTransmissionDate(getTransmissionDate());
376: header.setProcessBatchSequenceNumber(getBatchSequenceNumber());
377: header.setProcessTotalRecordCount(getTotalRecords());
378: header.setProcessTotalAmount(getTotalAmount());
379: header.setContactCampusCode(getCampusCode());
380: header.setContactPersonPhoneNumber(getPhoneNumber());
381: header.setContactMailingAddress(getMailingAddress());
382: header.setContactDepartmentName(getDepartmentName());
383:
384: return header;
385: }
386:
387: /**
388: * Creates an origin entry record with the PK values filled in only. This is useful to check for duplicate headers.
389: *
390: * @return CollectorHeader with chart of accounts code, organization code, process transmission date, batch sequence number
391: * total record count, and process total amount from this CollectorBatch
392: */
393: public CollectorHeader createCollectorHeaderWithPKValuesOnly() {
394: CollectorHeader header = new CollectorHeader();
395:
396: header.setChartOfAccountsCode(getChartOfAccountsCode());
397: header.setOrganizationCode(getOrganizationCode());
398: header.setProcessTransmissionDate(getTransmissionDate());
399: header.setProcessBatchSequenceNumber(getBatchSequenceNumber());
400: header.setProcessTotalRecordCount(getTotalRecords());
401: header.setProcessTotalAmount(getTotalAmount());
402:
403: return header;
404: }
405:
406: /**
407: * Sets defaults for missing id billing fields.
408: *
409: * @param idDetail CollectorDetail object which has its create date being set
410: */
411: private void setDefaultsCollectorDetail(CollectorDetail idDetail) {
412: // TODO: Get current fiscal year and period if blank?
413: // idBilling.setUniversityFiscalPeriodCode(String.valueOf(RandomUtils.nextInt(2)));
414: // idBilling.setCreateSequence(String.valueOf(RandomUtils.nextInt(2)));
415: // idBilling.setInterDepartmentalBillingSequenceNumber(String.valueOf(RandomUtils.nextInt(2)));
416: idDetail.setCreateDate(new Date(SpringContext.getBean(
417: DateTimeService.class).getCurrentDate().getTime()));
418: }
419:
420: /**
421: * Gets the campusCode attribute.
422: *
423: * @return Returns the campusCode.
424: */
425: public String getCampusCode() {
426: return campusCode;
427: }
428:
429: /**
430: * Sets the campusCode attribute value.
431: *
432: * @param campusCode The campusCode to set.
433: */
434: public void setCampusCode(String campusCode) {
435: this .campusCode = campusCode;
436: }
437:
438: /**
439: * Gets the departmentName attribute.
440: *
441: * @return Returns the departmentName.
442: */
443: public String getDepartmentName() {
444: return departmentName;
445: }
446:
447: /**
448: * Sets the departmentName attribute value.
449: *
450: * @param departmentName The departmentName to set.
451: */
452: public void setDepartmentName(String departmentName) {
453: this .departmentName = departmentName;
454: }
455:
456: /**
457: * Gets the mailingAddress attribute.
458: *
459: * @return Returns the mailingAddress.
460: */
461: public String getMailingAddress() {
462: return mailingAddress;
463: }
464:
465: /**
466: * Sets the mailingAddress attribute value.
467: *
468: * @param mailingAddress The mailingAddress to set.
469: */
470: public void setMailingAddress(String mailingAddress) {
471: this .mailingAddress = mailingAddress;
472: }
473:
474: /**
475: * Gets the phoneNumber attribute.
476: *
477: * @return Returns the phoneNumber.
478: */
479: public String getPhoneNumber() {
480: return phoneNumber;
481: }
482:
483: /**
484: * Sets the phoneNumber attribute value.
485: *
486: * @param phoneNumber The phoneNumber to set.
487: */
488: public void setPhoneNumber(String phoneNumber) {
489: this .phoneNumber = phoneNumber;
490: }
491:
492: /**
493: * Gets the batchName attribute.
494: *
495: * @return Returns the batchName.
496: */
497: public String getBatchName() {
498: return batchName;
499: }
500:
501: /**
502: * Sets the batchName attribute value.
503: *
504: * @param batchName The batchName to set.
505: */
506: public void setBatchName(String batchName) {
507: this.batchName = batchName;
508: }
509: }
|