001    /**
002     * Copyright 2004-2013 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.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/ecl2.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.hr.lm.leaveCalendar.validation;
017    
018    import java.math.BigDecimal;
019    import java.util.ArrayList;
020    import java.util.Calendar;
021    import java.util.Date;
022    import java.util.HashMap;
023    import java.util.List;
024    import java.util.Map;
025    import java.util.Set;
026    
027    import org.apache.commons.lang.StringUtils;
028    import org.junit.After;
029    import org.junit.Assert;
030    import org.junit.Before;
031    import org.junit.Test;
032    import org.kuali.hr.lm.balancetransfer.BalanceTransfer;
033    import org.kuali.hr.lm.leaveSummary.LeaveSummary;
034    import org.kuali.hr.lm.leaveSummary.LeaveSummaryRow;
035    import org.kuali.hr.lm.leaveblock.LeaveBlock;
036    import org.kuali.hr.lm.leavecalendar.validation.LeaveCalendarValidationUtil;
037    import org.kuali.hr.test.KPMETestCase;
038    import org.kuali.hr.time.service.base.TkServiceLocator;
039    import org.kuali.hr.time.util.TKUtils;
040    import org.kuali.rice.kew.api.document.DocumentContentUpdate;
041    import org.kuali.rice.kew.api.exception.WorkflowException;
042    import org.kuali.rice.kim.api.identity.principal.EntityNamePrincipalName;
043    import org.kuali.rice.kim.api.services.KimApiServiceLocator;
044    import org.kuali.rice.krad.maintenance.MaintenanceDocument;
045    import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
046    import org.kuali.rice.krad.util.KRADConstants;
047    
048    public class LeaveCalendarValidationServiceTest extends KPMETestCase {
049            
050            @Before
051            public void setUp() throws Exception {
052                    super.setUp();
053            }
054            
055            @After
056            public void tearDown() throws Exception {
057                    super.tearDown();
058            }
059            
060            @Test
061            public void testValidateAvailableLeaveBalance() throws Exception {
062                    LeaveSummary ls = new LeaveSummary();
063                    LeaveSummaryRow lsr = new LeaveSummaryRow();
064                    lsr.setAccrualCategory("testAC");
065                    lsr.setAccrualCategoryId("5000");
066                    lsr.setLeaveBalance(new BigDecimal(5));
067                    List<LeaveSummaryRow> lsrList = new ArrayList<LeaveSummaryRow>();
068                    lsrList.add(lsr);
069                    ls.setLeaveSummaryRows(lsrList);
070                    
071                    // adding brand new leave blocks
072                    // earn code "EC" does not allow negative accrual balance
073                    List<String> errors = LeaveCalendarValidationUtil.validateAvailableLeaveBalanceForUsage("EC", "02/15/2012", "02/15/2012", new BigDecimal(8), null);
074                    Assert.assertEquals("Incorrect number of error messages", 1, errors.size());
075                    String anError = errors.get(0);
076                    Assert.assertTrue("error message not correct" , anError.equals("Requested leave amount 8 is greater than available leave balance 0.00"));
077                    
078                    // earn code "EC1" allows negative accrual balance
079                    errors = LeaveCalendarValidationUtil.validateAvailableLeaveBalanceForUsage("EC1", "02/15/2012", "02/15/2012", new BigDecimal(8), null);
080                    Assert.assertTrue("There should NOT be error message(s)" , errors.isEmpty());
081                    
082                    //updating an existing leave block
083                    LeaveBlock aLeaveBlock = new LeaveBlock();
084                    aLeaveBlock.setEarnCode("EC");
085                    aLeaveBlock.setLeaveAmount(new BigDecimal(-10));
086                    
087                    errors = LeaveCalendarValidationUtil.validateAvailableLeaveBalanceForUsage("EC", "02/15/2012", "02/15/2012", new BigDecimal(3), aLeaveBlock);
088                    Assert.assertTrue("There should NOT be error message(s)" , errors.isEmpty());
089                    
090                    aLeaveBlock.setLeaveAmount(new BigDecimal(-2));
091                    errors = LeaveCalendarValidationUtil.validateAvailableLeaveBalanceForUsage("EC", "02/15/2012", "02/15/2012", new BigDecimal(10), aLeaveBlock);
092                    anError = errors.get(0);
093                    Assert.assertTrue("error message not correct" , anError.equals("Requested leave amount 10 is greater than available leave balance 2.00"));
094            }
095            
096            @Test
097            public void testValidateLeaveSpanOverMaxUsageRule() throws Exception {
098                    LeaveSummary ls = new LeaveSummary();
099                    LeaveSummaryRow lsr = new LeaveSummaryRow();
100                    lsr.setAccrualCategory("testAC");
101                    lsr.setUsageLimit(new BigDecimal(39));
102                    List<LeaveSummaryRow> lsrList = new ArrayList<LeaveSummaryRow>();
103                    lsrList.add(lsr);
104                    ls.setLeaveSummaryRows(lsrList);
105                    // adding brand new leave blocks
106                    List<String> errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/19/2012", new BigDecimal(8), null);
107                    Assert.assertEquals("There should be 1 error message" , 1, errors.size());
108                    String anError = errors.get(0);
109                    Assert.assertTrue("error message not correct" , anError.equals("This leave request would exceed the usage limit for " + lsr.getAccrualCategory()));
110            }
111            
112            @Test
113            public void testValidateLeaveSpanUnderMaxUsageRule() throws Exception {
114                    LeaveSummary ls = new LeaveSummary();
115                    LeaveSummaryRow lsr = new LeaveSummaryRow();
116                    lsr.setAccrualCategory("testAC");
117                    lsr.setUsageLimit(new BigDecimal(41));
118                    List<LeaveSummaryRow> lsrList = new ArrayList<LeaveSummaryRow>();
119                    lsrList.add(lsr);
120                    ls.setLeaveSummaryRows(lsrList);
121                    // adding brand new leave blocks
122                    List<String> errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/19/2012", new BigDecimal(8), null);
123                    Assert.assertEquals("There should be no error message" , 0, errors.size());
124            }
125            
126            @Test
127            public void testValidateLeaveSpanEqualMaxUsageRule() throws Exception {
128                    LeaveSummary ls = new LeaveSummary();
129                    LeaveSummaryRow lsr = new LeaveSummaryRow();
130                    lsr.setAccrualCategory("testAC");
131                    lsr.setUsageLimit(new BigDecimal(40));
132                    List<LeaveSummaryRow> lsrList = new ArrayList<LeaveSummaryRow>();
133                    lsrList.add(lsr);
134                    ls.setLeaveSummaryRows(lsrList);
135                    // adding brand new leave blocks
136                    List<String> errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/19/2012", new BigDecimal(8), null);
137                    Assert.assertEquals("There should be no error message" , 0, errors.size());
138            }
139            
140            @Test
141            public void testValidateLeaveNonSpanOverMaxUsageRule() throws Exception {
142                    LeaveSummary ls = new LeaveSummary();
143                    LeaveSummaryRow lsr = new LeaveSummaryRow();
144                    lsr.setAccrualCategory("testAC");
145                    lsr.setUsageLimit(new BigDecimal(5));
146                    List<LeaveSummaryRow> lsrList = new ArrayList<LeaveSummaryRow>();
147                    lsrList.add(lsr);
148                    ls.setLeaveSummaryRows(lsrList);
149                    // adding brand new leave blocks
150                    List<String> errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/15/2012", new BigDecimal(8), null);
151                    Assert.assertEquals("There should be 1 error message" , 1, errors.size());
152                    String anError = errors.get(0);
153                    Assert.assertTrue("error message not correct" , anError.equals("This leave request would exceed the usage limit for " + lsr.getAccrualCategory()));
154            }
155            
156            @Test
157            public void testValidateLeaveNonSpanEqualsMaxUsageRule() throws Exception {
158                    LeaveSummary ls = new LeaveSummary();
159                    LeaveSummaryRow lsr = new LeaveSummaryRow();
160                    lsr.setAccrualCategory("testAC");
161                    lsr.setUsageLimit(new BigDecimal(5));
162                    List<LeaveSummaryRow> lsrList = new ArrayList<LeaveSummaryRow>();
163                    lsrList.add(lsr);
164                    ls.setLeaveSummaryRows(lsrList);
165    
166                    List<String> errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/15/2012", new BigDecimal(5), null);
167                    Assert.assertEquals("There should be no error message" , 0, errors.size());
168    
169            }
170            
171            @Test
172            public void testValidateEditLeaveBlockMaxUsageRuleCaseOne() throws Exception {
173                    //Leave Amount increases, Earn Code unchanged
174                    LeaveSummary ls = new LeaveSummary();
175                    LeaveSummaryRow lsr = new LeaveSummaryRow();
176                    lsr.setAccrualCategory("testAC");
177                    lsr.setUsageLimit(new BigDecimal(50));
178                    lsr.setPendingLeaveRequests(new BigDecimal(25));
179                    lsr.setYtdApprovedUsage(new BigDecimal(15));
180                    List<LeaveSummaryRow> lsrList = new ArrayList<LeaveSummaryRow>();
181                    lsrList.add(lsr);
182                    ls.setLeaveSummaryRows(lsrList);
183                    
184                    //updating an existing leave block
185                    LeaveBlock aLeaveBlock = new LeaveBlock();
186                    aLeaveBlock.setEarnCode("EC");
187                    aLeaveBlock.setLeaveAmount(new BigDecimal(-10)); //this amount, multiplied by the days in the span, is considered to be part of the pending leave requests.
188                    List<String> errors = new ArrayList<String>();
189    
190                    // EC1 belongs to the accrual category testAC
191                    // should still be under 50 effective difference is +9, over 1 days = 9 -> 40+12 < 50
192                    errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/15/2012", new BigDecimal(19), aLeaveBlock);
193                    Assert.assertTrue("There should be no error message test 1" , errors.size()== 0);
194                    
195                    // should be right at 50 effective difference is +10, over 1 days = 10 -> 40+10 = 50
196                    errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/15/2012", new BigDecimal(20), aLeaveBlock);
197                    Assert.assertTrue("There should be no error message test 2" , errors.size()== 0);
198                    
199                    // should be over 50 effective difference is +11, over 1 day = 11 -> 40+11 > 50
200                    errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/15/2012", new BigDecimal(21), aLeaveBlock);
201                    Assert.assertTrue("There should be 1 error message test 3" , errors.size()== 1);
202                    
203                    // should be over 50 effective difference is +2, over 6 days = 12 -> 40+12 > 50
204                    errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/20/2012", new BigDecimal(12), aLeaveBlock);
205                    Assert.assertTrue("There should be 1 error message test 5" , errors.size()== 1);
206                    
207                    // should be under effective difference is +2, over 4 days = 8 -> 40+8 < 50
208                    errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/18/2012", new BigDecimal(12), aLeaveBlock);
209                    Assert.assertTrue("There should be 1 error message test 6" , errors.size()== 1);
210            }
211            
212            @Test
213            public void testValidateEditLeaveBlockMaxUsageRuleCaseTwo() throws Exception {
214                    //Leave Amount decreases, earn code remains the same.
215                    LeaveSummary ls = new LeaveSummary();
216                    LeaveSummaryRow lsr = new LeaveSummaryRow();
217                    lsr.setAccrualCategory("testAC");
218                    lsr.setUsageLimit(new BigDecimal(50));
219                    lsr.setPendingLeaveRequests(new BigDecimal(25));
220                    lsr.setYtdApprovedUsage(new BigDecimal(30));
221                    List<LeaveSummaryRow> lsrList = new ArrayList<LeaveSummaryRow>();
222                    lsrList.add(lsr);
223                    ls.setLeaveSummaryRows(lsrList);
224                    
225                    //updating an existing leave block
226                    //Somehow a block enters the system that exceeds max_usage. The only way for it to be saved
227                    //is if the net change drops below the usage limit.
228                    LeaveBlock aLeaveBlock = new LeaveBlock();
229                    aLeaveBlock.setEarnCode("EC");
230                    aLeaveBlock.setLeaveAmount(new BigDecimal(-10));
231                    List<String> errors = new ArrayList<String>();
232    
233                    // effective difference is (-2), over 1 days = -2 -> 55+(-2) > 50
234                    errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/15/2012", new BigDecimal(8), aLeaveBlock);
235                    Assert.assertTrue("There should be 1 error message" , errors.size()== 1);
236                    
237                    // should be equal effective difference is (-0.5), over 5 days = -2.5 -> 55+(-2.5) > 50
238                    errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/19/2012", new BigDecimal(9.5), aLeaveBlock);
239                    Assert.assertTrue("There should be 1 error message" , errors.size()== 1);
240            }
241    
242            @Test
243            public void testValidateEditLeaveBlockMaxUsageRuleCaseThree() throws Exception {
244                    //Leave Amount static, earn code changes.
245                    LeaveSummary ls = new LeaveSummary(); 
246                    LeaveSummaryRow lsr = new LeaveSummaryRow();
247                    lsr.setAccrualCategory("testAC");
248                    lsr.setUsageLimit(new BigDecimal(50));
249                    lsr.setPendingLeaveRequests(new BigDecimal(25));
250                    lsr.setYtdApprovedUsage(new BigDecimal(15));
251    
252                    LeaveSummaryRow lsr2 = new LeaveSummaryRow();
253                    lsr2.setAccrualCategory("testAC2");
254                    lsr2.setUsageLimit(new BigDecimal(15));
255                    lsr2.setPendingLeaveRequests(new BigDecimal(5));
256                    lsr2.setYtdApprovedUsage(new BigDecimal(4));
257                    
258                    List<LeaveSummaryRow> lsrList = new ArrayList<LeaveSummaryRow>();
259                    lsrList.add(lsr);
260                    lsrList.add(lsr2);
261                    ls.setLeaveSummaryRows(lsrList);
262                    
263                    //updating an existing leave block
264                    LeaveBlock aLeaveBlock = new LeaveBlock();
265                    aLeaveBlock.setEarnCode("EC");
266                    aLeaveBlock.setAccrualCategory("testAC");
267                    aLeaveBlock.setLeaveAmount(new BigDecimal(-10));
268                    List<String> errors = new ArrayList<String>();
269    
270                    //Changing to an earn code with different accrual category, testAC2
271                    errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC2", "02/15/2012", "02/15/2012", new BigDecimal(6), aLeaveBlock);
272                    Assert.assertTrue("There should be no error message. reached usage limit." , errors.size()== 0);
273                    
274                    //Changing to an earn code with different accrual category, testAC2
275                    errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC2", "02/15/2012", "02/15/2012", new BigDecimal(7), aLeaveBlock);
276                    Assert.assertTrue("There should be 1 error message, there were " + errors.size() + " errors" , errors.size()== 1);
277                    
278                    //Changing to an earn code with different accrual category, testAC2 with spanning days.
279                    errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC2", "02/15/2012", "02/19/2012", new BigDecimal(1), aLeaveBlock);
280                    Assert.assertTrue("There should be no error message, there were " + errors.size() + " errors" , errors.size()== 0);
281                    
282                    //Changing to an earn code with different accrual category, testAC2 with spanning days.
283                    errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC2", "02/15/2012", "02/20/2012", new BigDecimal(1), aLeaveBlock);
284                    Assert.assertTrue("There should be no error message, there were " + errors.size() + " errors" , errors.size()== 0);
285                    
286                    //Changing to an earn code with different accrual category, testAC2 with spanning days.
287                    errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC2", "02/15/2012", "02/21/2012", new BigDecimal(1), aLeaveBlock);
288                    Assert.assertTrue("There should be 1 error message, there were " + errors.size() + " errors" , errors.size()== 1);
289                    
290                    //Changing to an earn code within same accrual category, testAC
291                    errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC1", "02/15/2012", "02/15/2012", new BigDecimal(10), aLeaveBlock);
292                    Assert.assertTrue("There should be no error message, there were " + errors.size() + " errors" , errors.size()== 0);
293                    
294                    //Changing to an earn code within same accrual category, testAC with spanning days.
295                    errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC1", "02/15/2012", "02/19/2012", new BigDecimal(2), aLeaveBlock);
296                    Assert.assertTrue("There should be 0 error message, there were " + errors.size() + " errors" , errors.size()== 0);
297                    
298                    //Changing to an earn code within same accrual category, testAC with spanning days.
299                    errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC2", "02/15/2012", "02/25/2012", new BigDecimal(1), aLeaveBlock);
300                    Assert.assertTrue("There should be 1 error message, there were " + errors.size() + " errors" , errors.size()== 1);
301                                    
302            }
303            @Test
304            public void testGetWarningTextForLeaveBlocks() throws Exception {
305                    // create two leave blocks with two different earn codes
306                    // earn code "ECA" has fmla=Y, has earn code group with warning messages
307                    // earn Code "ECB" has fmla = N, has earn code group with warning messages
308                    // earn code "ECC" does not have earn code group with warning messages
309    
310                    List<LeaveBlock> leaveBlocs = new ArrayList<LeaveBlock>();
311                    LeaveBlock lbA = new LeaveBlock();
312                    lbA.setEarnCode("ECA");
313                    lbA.setLeaveDate(TKUtils.getCurrentDate());
314                    leaveBlocs.add(lbA);
315    
316                    LeaveBlock lbB = new LeaveBlock();
317                    lbB.setEarnCode("ECB");
318                    lbB.setLeaveDate(TKUtils.getCurrentDate());
319                    leaveBlocs.add(lbB);
320    
321                    LeaveBlock lbC = new LeaveBlock();
322                    lbC.setEarnCode("ECC");
323                    lbC.setLeaveDate(TKUtils.getCurrentDate());
324                    leaveBlocs.add(lbC);
325    
326                    Map<String, Set<String>> allMessages = LeaveCalendarValidationUtil.getWarningMessagesForLeaveBlocks(leaveBlocs);
327            int numberOfMessages = 0;
328            for (Set<String> msgs : allMessages.values()){
329                numberOfMessages += msgs.size();
330            }
331                    Assert.assertTrue("There should be 2 warning messages, not " + numberOfMessages, numberOfMessages== 2);
332    
333            for (Set<String> msgs : allMessages.values()){
334                for (String message : msgs) {
335                    Assert.assertTrue("Warning message should be 'Test Message' or 'Test Message1'", message.equals("Test Message") || message.equals("Test Message1"));
336                }
337            }
338            }
339            
340            /* In order for tests of the following form to work, need to change status of a document to enroute/approved
341             * without actually routing / approving the document. OR, set up a context within which these actions can be performed.
342             */
343    /*      @Test
344            public void testValidatePendingTransactions() throws Exception {
345                    Assert.assertNull(null);
346                    BalanceTransfer bt = new BalanceTransfer();
347                    bt.setAmountTransferred(new BigDecimal(1.0));
348                    bt.setTransferAmount(new BigDecimal(1.0));
349                    bt.setForfeitedAmount(new BigDecimal(1.0));
350                    bt.setAccrualCategoryRule("");
351                    bt.setEffectiveDate(TKUtils.getCurrentDate());
352                    bt.setFromAccrualCategory("testAC");
353                    bt.setToAccrualCategory("testAC2");
354                    bt.setPrincipalId("admin");
355                    
356                    mockSubmitToWorkflow(bt);
357    
358                    Calendar cal = Calendar.getInstance();
359                    cal.setTime(TKUtils.getCurrentDate());
360                    cal.add(Calendar.MONTH, -1);
361                    Date from = cal.getTime();
362                    cal.add(Calendar.MONTH, 2);
363                    Date to = cal.getTime();
364                    Map<String,Set<String>> allMessages = new HashMap<String, Set<String>>();
365                    allMessages.putAll(LeaveCalendarValidationUtil.validatePendingTransactions("admin", new java.sql.Date(from.getTime()), new java.sql.Date(to.getTime())));
366                    
367                    Assert.assertTrue(allMessages.get("actionMessages").size() > 0);
368                    Set<String> actionMessages = allMessages.get("actionMessage");
369                    
370                    Assert.assertTrue("Should contain warning message for pending transaction", actionMessages.contains("A pending balance transfer exists on this calendar. " + 
371                                    "It must be finalized before this calendar can be approved"));
372            }
373    
374            private void mockSubmitToWorkflow(BalanceTransfer balanceTransfer) {
375                    // TODO Auto-generated method stub
376                    //balanceTransfer.setStatus(TkConstants.ROUTE_STATUS.ENROUTE);
377            EntityNamePrincipalName principalName = null;
378            if (balanceTransfer.getPrincipalId() != null) {
379                principalName = KimApiServiceLocator.getIdentityService().getDefaultNamesForPrincipalId(balanceTransfer.getPrincipalId());
380            }
381    
382                    MaintenanceDocument document = KRADServiceLocatorWeb.getMaintenanceDocumentService().setupNewMaintenanceDocument(BalanceTransfer.class.getName(),
383                                    "BalanceTransferDocumentType",KRADConstants.MAINTENANCE_NEW_ACTION);
384    
385            String personName = (principalName != null  && principalName.getDefaultName() != null) ? principalName.getDefaultName().getCompositeName() : StringUtils.EMPTY;
386            String date = TKUtils.formatDate(new java.sql.Date(balanceTransfer.getEffectiveDate().getTime()));
387            document.getDocumentHeader().setDocumentDescription(personName + " (" + balanceTransfer.getPrincipalId() + ")  - " + date);
388                    Map<String,String[]> params = new HashMap<String,String[]>();
389                    
390                    KRADServiceLocatorWeb.getMaintenanceDocumentService().setupMaintenanceObject(document, KRADConstants.MAINTENANCE_NEW_ACTION, params);
391                    BalanceTransfer btObj = (BalanceTransfer) document.getNewMaintainableObject().getDataObject();
392                    
393                    btObj.setAccrualCategoryRule(balanceTransfer.getAccrualCategoryRule());
394                    btObj.setEffectiveDate(balanceTransfer.getEffectiveDate());
395                    btObj.setForfeitedAmount(balanceTransfer.getForfeitedAmount());
396                    btObj.setFromAccrualCategory(balanceTransfer.getFromAccrualCategory());
397                    btObj.setPrincipalId(balanceTransfer.getPrincipalId());
398                    btObj.setToAccrualCategory(balanceTransfer.getToAccrualCategory());
399                    btObj.setTransferAmount(balanceTransfer.getTransferAmount());
400                    btObj.setAmountTransferred(balanceTransfer.getAmountTransferred());
401                    btObj.setSstoId(balanceTransfer.getSstoId());
402                    btObj.setDocumentHeaderId(document.getDocumentHeader().getWorkflowDocument().getDocumentId());
403            //TkServiceLocator.getBalanceTransferService().saveOrUpdate(btObj);
404                    document.getNewMaintainableObject().setDataObject(btObj);
405                    try {
406                            KRADServiceLocatorWeb.getDocumentService().saveDocument(document);
407                    } catch (WorkflowException e) {
408                            // TODO Auto-generated catch block
409                            Assert.fail("Caught workflow exception while saving document");
410                    }
411                    document.getDocumentHeader().getWorkflowDocument().saveDocument("");
412                    
413                    balanceTransfer = TkServiceLocator.getBalanceTransferService().transfer(btObj);
414    
415            }*/
416                    
417    }