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.cg.service.impl;
017:
018: import static org.kuali.test.fixtures.UserNameFixture.KHUNTLEY;
019:
020: import java.sql.Date;
021: import java.text.DateFormat;
022: import java.util.Vector;
023:
024: import org.kuali.core.document.Document;
025: import org.kuali.core.exceptions.ValidationException;
026: import org.kuali.core.service.DateTimeService;
027: import org.kuali.core.service.DocumentService;
028: import org.kuali.core.util.GlobalVariables;
029: import org.kuali.core.util.KualiDecimal;
030: import org.kuali.kfs.context.KualiTestBase;
031: import org.kuali.kfs.context.SpringContext;
032: import org.kuali.module.cg.bo.Award;
033: import org.kuali.module.cg.bo.Close;
034: import org.kuali.module.cg.bo.Proposal;
035: import org.kuali.module.cg.lookup.valuefinder.NextProposalNumberFinder;
036: import org.kuali.module.cg.service.AwardService;
037: import org.kuali.module.cg.service.CloseService;
038: import org.kuali.module.cg.service.ProposalService;
039: import org.kuali.test.ConfigureContext;
040: import org.kuali.test.DocumentTestUtils;
041:
042: import edu.iu.uis.eden.exception.WorkflowException;
043:
044: @ConfigureContext(session=KHUNTLEY)
045: public class CloseServiceTest extends KualiTestBase {
046:
047: private static final String VALID_AWARD_STATUS_CODE = "R";
048: private static final String INVALID_AWARD_STATUS_CODE = "U";
049:
050: private DateFormat dateFormat;
051: private Date today;
052:
053: private int timeout = 0;
054:
055: @Override
056: protected void setUp() throws Exception {
057: super .setUp();
058: dateFormat = DateFormat.getDateInstance();
059: today = SpringContext.getBean(DateTimeService.class)
060: .getCurrentSqlDateMidnight();
061: }
062:
063: public void testClose_awardEntryDateLessThanCloseOnOrBeforeDate()
064: throws Exception {
065: Date closeInitiatedDate = today; // must be today, close will abort if not
066:
067: Date closeCloseOnOrBeforeDate = new Date(dateFormat.parse(
068: "Jun 1, 2000").getTime());
069: Date awardEntryDate = new Date(dateFormat.parse("May 20, 2000")
070: .getTime()); // must be <= closeCloseOnOrBeforeDate
071: Date proposalSubmissionDate = new Date(dateFormat.parse(
072: "May 2, 1999").getTime()); // must be less than
073: // closeCloseOnOrBeforeDate
074:
075: Date proposalBeginningDate = new Date(dateFormat.parse(
076: "Jul 1, 1999").getTime()); // not relevant
077: Date proposalEndingDate = new Date(dateFormat.parse(
078: "Aug 1, 1999").getTime()); // not relevant
079:
080: Date proposalClosingDate = null; // must be null
081: Date awardClosingDate = null; // must be null
082:
083: //
084:
085: Proposal proposal = createProposal(proposalBeginningDate,
086: proposalEndingDate, proposalSubmissionDate,
087: proposalClosingDate);
088: SpringContext.getBean(ProposalService.class).save(proposal);
089:
090: Award award = createAward(proposal, awardEntryDate,
091: awardClosingDate, VALID_AWARD_STATUS_CODE);
092: SpringContext.getBean(AwardService.class).save(award);
093:
094: Close close = createClose(closeCloseOnOrBeforeDate);
095: saveAndRoute(close);
096: // SpringContext.getBean(CloseService.class).save(close);
097:
098: // Verify that everything should be OK for the close.
099:
100: // Be sure that the award should be closed.
101: verifyAwardWillBeIncludedInClose(award, close);
102:
103: // Be sure that the proposal should be closed.
104: verifyProposalWillBeIncludedInClose(proposal, close);
105:
106: // Run the close.
107: SpringContext.getBean(CloseService.class).close();
108:
109: // Verify.
110: Long one = new Long(1);
111: assertEquals("Awards were not closed properly.", one, close
112: .getAwardClosedCount());
113: assertEquals("Proposals were not closed properly.", one, close
114: .getProposalClosedCount());
115: }
116:
117: public void testClose_awardEntryDateEqualToCloseOnOrBeforeDate()
118: throws Exception {
119: Date closeInitiatedDate = today; // must be today, close will abort if not
120:
121: Date closeCloseOnOrBeforeDate = new Date(dateFormat.parse(
122: "Jun 1, 2000").getTime());
123: Date awardEntryDate = new Date(dateFormat.parse("June 1, 2000")
124: .getTime()); // must be <= closeCloseOnOrBeforeDate
125: Date proposalSubmissionDate = new Date(dateFormat.parse(
126: "May 2, 1999").getTime()); // must be less than
127: // closeCloseOnOrBeforeDate
128:
129: Date proposalBeginningDate = new Date(dateFormat.parse(
130: "Jul 1, 1999").getTime()); // not relevant
131: Date proposalEndingDate = new Date(dateFormat.parse(
132: "Aug 1, 1999").getTime()); // not relevant
133:
134: Date proposalClosingDate = null; // must be null
135: Date awardClosingDate = null; // must be null
136:
137: //
138:
139: Proposal proposal = createProposal(proposalBeginningDate,
140: proposalEndingDate, proposalSubmissionDate,
141: proposalClosingDate);
142: SpringContext.getBean(ProposalService.class).save(proposal);
143:
144: Award award = createAward(proposal, awardEntryDate,
145: awardClosingDate, VALID_AWARD_STATUS_CODE);
146: SpringContext.getBean(AwardService.class).save(award);
147:
148: Close close = createClose(closeCloseOnOrBeforeDate);
149: saveAndRoute(close);
150: // SpringContext.getBean(CloseService.class).save(close);
151:
152: // Verify that everything should be OK for the close.
153:
154: // Be sure that the award should be closed.
155: verifyAwardWillBeIncludedInClose(award, close);
156:
157: // Be sure that the proposal should be closed.
158: verifyProposalWillBeIncludedInClose(proposal, close);
159:
160: // Run the close.
161: SpringContext.getBean(CloseService.class).close();
162:
163: // Verify.
164: Long one = new Long(1);
165: assertEquals("Awards were not closed properly.", one, close
166: .getAwardClosedCount());
167: assertEquals("Proposals were not closed properly.", one, close
168: .getProposalClosedCount());
169: }
170:
171: public void testClose_awardClosingDateNotNull() throws Exception {
172: Date closeInitiatedDate = today; // must be today, close will abort if not
173:
174: Date closeCloseOnOrBeforeDate = new Date(dateFormat.parse(
175: "Jun 1, 2000").getTime());
176: Date awardEntryDate = new Date(dateFormat.parse("June 1, 2000")
177: .getTime());
178: Date proposalSubmissionDate = new Date(dateFormat.parse(
179: "May 2, 1999").getTime()); // must be less than
180: // closeCloseOnOrBeforeDate
181:
182: Date proposalBeginningDate = new Date(dateFormat.parse(
183: "Jul 1, 1999").getTime()); // not relevant
184: Date proposalEndingDate = new Date(dateFormat.parse(
185: "Aug 1, 1999").getTime()); // not relevant
186:
187: Date proposalClosingDate = null; // must be null
188: Date awardClosingDate = today;
189:
190: // Create and save objects for closing.
191:
192: Proposal proposal = createProposal(proposalBeginningDate,
193: proposalEndingDate, proposalSubmissionDate,
194: proposalClosingDate);
195: SpringContext.getBean(ProposalService.class).save(proposal);
196:
197: Award award = createAward(proposal, awardEntryDate,
198: awardClosingDate, VALID_AWARD_STATUS_CODE);
199: SpringContext.getBean(AwardService.class).save(award);
200:
201: Close close = createClose(closeCloseOnOrBeforeDate);
202: saveAndRoute(close);
203: // SpringContext.getBean(CloseService.class).save(close);
204:
205: // Verify that everything should be OK for the close.
206:
207: // Be sure that the award should be closed.
208: verifyAwardWillBeIncludedInClose(award, close, false, true,
209: true);
210:
211: // Be sure that the proposal should be closed.
212: verifyProposalWillBeIncludedInClose(proposal, close);
213:
214: // Run the close.
215: SpringContext.getBean(CloseService.class).close();
216:
217: Long zero = new Long(0);
218: Long one = new Long(1);
219: assertEquals("Awards were not closed properly.", zero, close
220: .getAwardClosedCount());
221: assertEquals("Proposals were not closed properly.", one, close
222: .getProposalClosedCount());
223: }
224:
225: public void testClose_awardStatusCodeInvalid() throws Exception {
226: Date closeInitiatedDate = today; // must be today, close will abort if not
227:
228: Date closeCloseOnOrBeforeDate = new Date(dateFormat.parse(
229: "Jun 1, 2000").getTime());
230: Date awardEntryDate = new Date(dateFormat.parse("June 1, 2000")
231: .getTime());
232: Date proposalSubmissionDate = new Date(dateFormat.parse(
233: "May 2, 1999").getTime()); // must be less than
234: // closeCloseOnOrBeforeDate
235:
236: Date proposalBeginningDate = new Date(dateFormat.parse(
237: "Jul 1, 1999").getTime()); // not relevant
238: Date proposalEndingDate = new Date(dateFormat.parse(
239: "Aug 1, 1999").getTime()); // not relevant
240:
241: Date proposalClosingDate = null;
242: Date awardClosingDate = null;
243:
244: // Create and save objects for closing.
245:
246: Proposal proposal = createProposal(proposalBeginningDate,
247: proposalEndingDate, proposalSubmissionDate,
248: proposalClosingDate);
249: SpringContext.getBean(ProposalService.class).save(proposal);
250:
251: Award award = createAward(proposal, awardEntryDate,
252: awardClosingDate, INVALID_AWARD_STATUS_CODE);
253: SpringContext.getBean(AwardService.class).save(award);
254:
255: Close close = createClose(closeCloseOnOrBeforeDate);
256: saveAndRoute(close);
257: // SpringContext.getBean(CloseService.class).save(close);
258:
259: // Verify that everything should be OK for the close.
260:
261: // Be sure that the award should be closed.
262: verifyAwardWillBeIncludedInClose(award, close, true, false,
263: true);
264:
265: // Be sure that the proposal should be closed.
266: verifyProposalWillBeIncludedInClose(proposal, close);
267:
268: // Run the close.
269: SpringContext.getBean(CloseService.class).close();
270:
271: Long zero = new Long(0);
272: Long one = new Long(1);
273: assertEquals("Awards were not closed properly.", zero, close
274: .getAwardClosedCount());
275: assertEquals("Proposals were not closed properly.", one, close
276: .getProposalClosedCount());
277: }
278:
279: public void testClose_awardEntryDateGreaterThanCloseOnOrBeforeDate()
280: throws Exception {
281: Date closeInitiatedDate = today; // must be today, close will abort if not
282:
283: Date closeCloseOnOrBeforeDate = new Date(dateFormat.parse(
284: "Jun 1, 2000").getTime());
285: Date awardEntryDate = new Date(dateFormat.parse("June 2, 2000")
286: .getTime());
287: Date proposalSubmissionDate = new Date(dateFormat.parse(
288: "May 2, 1999").getTime()); // must be less than
289: // closeCloseOnOrBeforeDate
290:
291: Date proposalBeginningDate = new Date(dateFormat.parse(
292: "Jul 1, 1999").getTime()); // not relevant
293: Date proposalEndingDate = new Date(dateFormat.parse(
294: "Aug 1, 1999").getTime()); // not relevant
295:
296: Date proposalClosingDate = null; // must be null
297: Date awardClosingDate = null; // must be null
298:
299: // Create and save objects for closing.
300:
301: Proposal proposal = createProposal(proposalBeginningDate,
302: proposalEndingDate, proposalSubmissionDate,
303: proposalClosingDate);
304: SpringContext.getBean(ProposalService.class).save(proposal);
305:
306: Award award = createAward(proposal, awardEntryDate,
307: awardClosingDate, VALID_AWARD_STATUS_CODE);
308: SpringContext.getBean(AwardService.class).save(award);
309:
310: Close close = createClose(closeCloseOnOrBeforeDate);
311: saveAndRoute(close);
312: // SpringContext.getBean(CloseService.class).save(close);
313:
314: // Verify that everything should be OK for the close.
315:
316: // Be sure that the award should be closed.
317: verifyAwardWillBeIncludedInClose(award, close, true, true,
318: false);
319:
320: // Be sure that the proposal should be closed.
321: verifyProposalWillBeIncludedInClose(proposal, close);
322:
323: // Run the close.
324: SpringContext.getBean(CloseService.class).close();
325:
326: Long zero = new Long(0);
327: Long one = new Long(1);
328: assertEquals("Awards were not closed properly.", zero, close
329: .getAwardClosedCount());
330: assertEquals("Proposals were not closed properly.", one, close
331: .getProposalClosedCount());
332: }
333:
334: public void testClose_proposalClosingDateNotNull() throws Exception {
335: Date closeInitiatedDate = today; // must be today, close will abort if not
336:
337: Date closeCloseOnOrBeforeDate = new Date(dateFormat.parse(
338: "Jun 1, 2000").getTime());
339: Date awardEntryDate = new Date(dateFormat.parse("June 1, 2000")
340: .getTime());
341: Date proposalSubmissionDate = new Date(dateFormat.parse(
342: "May 2, 1999").getTime()); // must be less than
343: // closeCloseOnOrBeforeDate
344:
345: Date proposalBeginningDate = new Date(dateFormat.parse(
346: "Jul 1, 1999").getTime()); // not relevant
347: Date proposalEndingDate = new Date(dateFormat.parse(
348: "Aug 1, 1999").getTime()); // not relevant
349:
350: Date proposalClosingDate = today;
351: Date awardClosingDate = null;
352:
353: // Create and save objects for closing.
354:
355: Proposal proposal = createProposal(proposalBeginningDate,
356: proposalEndingDate, proposalSubmissionDate,
357: proposalClosingDate);
358: SpringContext.getBean(ProposalService.class).save(proposal);
359:
360: Award award = createAward(proposal, awardEntryDate,
361: awardClosingDate, VALID_AWARD_STATUS_CODE);
362: SpringContext.getBean(AwardService.class).save(award);
363:
364: Close close = createClose(closeCloseOnOrBeforeDate);
365: saveAndRoute(close);
366: // SpringContext.getBean(CloseService.class).save(close);
367:
368: // Verify that everything should be OK for the close.
369:
370: // Be sure that the award should be closed.
371: verifyAwardWillBeIncludedInClose(award, close);
372:
373: // Be sure that the proposal should be closed.
374: verifyProposalWillBeIncludedInClose(proposal, close, false,
375: true);
376:
377: // Run the close.
378: SpringContext.getBean(CloseService.class).close();
379:
380: Long zero = new Long(0);
381: Long one = new Long(1);
382: assertEquals("Awards were not closed properly.", one, close
383: .getAwardClosedCount());
384: assertEquals("Proposals were not closed properly.", zero, close
385: .getProposalClosedCount());
386: }
387:
388: public void testClose_proposalSubmissionDateGreaterThanCloseCloseOnOrBeforeDate()
389: throws Exception {
390: Date closeInitiatedDate = today; // must be today, close will abort if not
391:
392: Date closeCloseOnOrBeforeDate = new Date(dateFormat.parse(
393: "Jun 1, 2000").getTime());
394: Date awardEntryDate = new Date(dateFormat.parse("June 1, 2000")
395: .getTime());
396: Date proposalSubmissionDate = new Date(dateFormat.parse(
397: "June 2, 2000").getTime());
398:
399: Date proposalBeginningDate = new Date(dateFormat.parse(
400: "Jul 1, 1999").getTime());
401: Date proposalEndingDate = new Date(dateFormat.parse(
402: "Aug 1, 1999").getTime());
403:
404: Date proposalClosingDate = null;
405: Date awardClosingDate = null;
406:
407: // Create and save objects for closing.
408:
409: Proposal proposal = createProposal(proposalBeginningDate,
410: proposalEndingDate, proposalSubmissionDate,
411: proposalClosingDate);
412: SpringContext.getBean(ProposalService.class).save(proposal);
413:
414: Award award = createAward(proposal, awardEntryDate,
415: awardClosingDate, VALID_AWARD_STATUS_CODE);
416: SpringContext.getBean(AwardService.class).save(award);
417:
418: Close close = createClose(closeCloseOnOrBeforeDate);
419: saveAndRoute(close);
420: // SpringContext.getBean(CloseService.class).save(close);
421:
422: // Verify that everything should be OK for the close.
423:
424: // Be sure that the award should be closed.
425: verifyAwardWillBeIncludedInClose(award, close);
426:
427: // Be sure that the proposal should be closed.
428: verifyProposalWillBeIncludedInClose(proposal, close, true,
429: false);
430:
431: // Run the close.
432: SpringContext.getBean(CloseService.class).close();
433:
434: Long zero = new Long(0);
435: Long one = new Long(1);
436: assertEquals("Awards were not closed properly.", one, close
437: .getAwardClosedCount());
438: assertEquals("Proposals were not closed properly.", zero, close
439: .getProposalClosedCount());
440: }
441:
442: private void verifyAwardWillBeIncludedInClose(Award award,
443: Close close) {
444: verifyAwardWillBeIncludedInClose(award, close, true, true, true);
445: }
446:
447: private void verifyAwardWillBeIncludedInClose(Award award,
448: Close close, boolean verifyAwardClosingDate,
449: boolean verifyAwardStatusCode, boolean verifyAwardEntryDate) {
450: if (verifyAwardClosingDate) {
451: assertNull(
452: "Award closing date must be null to be included in closing.",
453: award.getAwardClosingDate());
454: }
455: if (verifyAwardStatusCode) {
456: assertNotSame(
457: "Award status code must not be 'U' to be included in closing.",
458: award.getAwardStatusCode(), "U");
459: }
460: if (verifyAwardEntryDate) {
461: assertTrue(
462: "Award entry date must be less than or equal to the close last closed date.",
463: award.getAwardEntryDate().getTime() <= close
464: .getCloseOnOrBeforeDate().getTime());
465: }
466: }
467:
468: private void verifyProposalWillBeIncludedInClose(Proposal proposal,
469: Close close) {
470: verifyProposalWillBeIncludedInClose(proposal, close, true, true);
471: }
472:
473: private void verifyProposalWillBeIncludedInClose(Proposal proposal,
474: Close close, boolean verifyProposalClosingDate,
475: boolean verifyProposalSubmissionDate) {
476: if (verifyProposalClosingDate) {
477: assertNull(
478: "Proposal closing date must be null to be included in closing.",
479: proposal.getProposalClosingDate());
480: }
481: if (verifyProposalSubmissionDate) {
482: assertTrue(
483: "Proposal submission date must be less than or equal to closing last closed date.",
484: proposal.getProposalSubmissionDate().getTime() <= close
485: .getCloseOnOrBeforeDate().getTime());
486: }
487: }
488:
489: private Proposal createProposal(Date proposalBeginningDate,
490: Date proposalEndingDate, Date proposalSubmissionDate,
491: Date proposalClosingDate) {
492: // Create and save a proposal
493: Proposal proposal = new Proposal();
494: proposal.setProposalNumber(NextProposalNumberFinder
495: .getLongValue());
496: // set required fields
497: proposal.setAgencyNumber("12851");
498: proposal.setProposalProjectTitle("Testing CG Close Process");
499: proposal.setProposalBeginningDate(proposalBeginningDate);
500: proposal.setProposalEndingDate(proposalEndingDate);
501: proposal
502: .setProposalDirectCostAmount(new KualiDecimal("3840.00"));
503: proposal.setProposalIndirectCostAmount(new KualiDecimal(
504: "2016.00"));
505: proposal.setProposalTotalAmount(proposal
506: .getProposalDirectCostAmount().add(
507: proposal.getProposalIndirectCostAmount()));
508: proposal.setProposalSubmissionDate(proposalSubmissionDate);
509: proposal.setProposalClosingDate(proposalClosingDate);
510: proposal.setProposalAwardTypeCode("N");
511: proposal.setProposalPurposeCode("C");
512: return proposal;
513: }
514:
515: private Award createAward(Proposal proposal, Date awardEntryDate,
516: Date awardClosingDate, String awardStatusCode) {
517: // Create and save an award
518: Award award = new Award(proposal);
519: award.setAwardEntryDate(awardEntryDate);
520: award.setAwardClosingDate(awardClosingDate);
521: award.setAwardStatusCode(awardStatusCode);
522: return award;
523: }
524:
525: private Close createClose(Date closeCloseOnOrBeforeDate)
526: throws WorkflowException {
527: Document document = DocumentTestUtils.createDocument(
528: SpringContext.getBean(DocumentService.class),
529: Close.class);
530: Close close = (Close) document;// SpringContext.getBean(DocumentService.class).getNewDocument(Close.class);
531: close.setUserInitiatedCloseDate(today);
532: close.setCloseOnOrBeforeDate(closeCloseOnOrBeforeDate);
533: return close;
534: }
535:
536: private void saveAndRoute(Close close) throws Exception {
537: DocumentService documentService = SpringContext
538: .getBean(DocumentService.class);
539: saveDocument(close, documentService);
540: routeDocument(close, documentService);
541: }
542:
543: public static void routeDocument(Document document,
544: DocumentService documentService) throws Exception {
545: final String ENROUTE_STATUS = "R";
546: final String FINAL_STATUS = "F";
547:
548: // Verify that the doc isn't yet routed.
549: assertFalse(ENROUTE_STATUS.equals(document.getDocumentHeader()
550: .getWorkflowDocument().getRouteHeader()
551: .getDocRouteStatus()));
552:
553: // Route the doc.
554: documentService.routeDocument(document, "routing test doc",
555: new Vector());
556:
557: // Routing should be configured to go straight to final.
558: assertTrue(FINAL_STATUS.equals(document.getDocumentHeader()
559: .getWorkflowDocument().getRouteHeader()
560: .getDocRouteStatus()));
561: }
562:
563: public static void saveDocument(Document document,
564: DocumentService documentService) throws WorkflowException {
565: try {
566: documentService.saveDocument(document);
567: } catch (ValidationException e) {
568: // If the business rule evaluation fails then give us more info for debugging this test.
569: fail(e.getMessage() + ", " + GlobalVariables.getErrorMap());
570: }
571: }
572: }
|