001 /*
002 * Copyright 2011 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.kfs.module.ld.document;
017
018 import java.util.ArrayList;
019 import java.util.List;
020
021 import org.apache.commons.lang.StringUtils;
022 import org.kuali.kfs.fp.document.JournalVoucherDocument;
023 import org.kuali.kfs.integration.ld.LaborLedgerPendingEntryForSearching;
024 import org.kuali.kfs.module.ld.LaborConstants;
025 import org.kuali.kfs.module.ld.LaborConstants.JournalVoucherOffsetType;
026 import org.kuali.kfs.module.ld.businessobject.LaborJournalVoucherAccountingLineParser;
027 import org.kuali.kfs.module.ld.businessobject.LaborJournalVoucherDetail;
028 import org.kuali.kfs.module.ld.businessobject.LaborLedgerPendingEntry;
029 import org.kuali.kfs.module.ld.service.LaborLedgerPendingEntryService;
030 import org.kuali.kfs.sys.KFSConstants;
031 import org.kuali.kfs.sys.ObjectUtil;
032 import org.kuali.kfs.sys.businessobject.AccountingLine;
033 import org.kuali.kfs.sys.businessobject.AccountingLineParser;
034 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper;
035 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail;
036 import org.kuali.kfs.sys.context.SpringContext;
037 import org.kuali.kfs.sys.document.AmountTotaling;
038 import org.kuali.kfs.sys.service.GeneralLedgerPendingEntryService;
039 import org.kuali.kfs.sys.service.HomeOriginationService;
040 import org.kuali.rice.kew.doctype.bo.DocumentTypeEBO;
041 import org.kuali.rice.kew.dto.DocumentRouteStatusChangeDTO;
042 import org.kuali.rice.kew.service.impl.KEWModuleService;
043 import org.kuali.rice.kns.exception.ValidationException;
044 import org.kuali.rice.kns.rule.event.KualiDocumentEvent;
045
046 // @latex.ClassSignatureStart
047 /**
048 * Labor Document class for the Labor Ledger Journal Voucher.
049 */
050 public class LaborJournalVoucherDocument extends JournalVoucherDocument implements LaborLedgerPostingDocument, AmountTotaling {
051 // @latex.ClassSignatureStop
052 protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(LaborJournalVoucherDocument.class);
053 protected String offsetTypeCode = JournalVoucherOffsetType.NO_OFFSET.typeCode;
054 protected List<LaborLedgerPendingEntry> laborLedgerPendingEntries;
055 protected DocumentTypeEBO financialSystemDocumentTypeCode;
056
057 /**
058 * Constructs a LaborJournalVoucherDocument.java.
059 */
060 public LaborJournalVoucherDocument() {
061 super();
062 setLaborLedgerPendingEntries(new ArrayList<LaborLedgerPendingEntry>());
063 }
064
065 /**
066 * @see org.kuali.kfs.sys.document.AccountingDocumentBase#getSourceAccountingLineClass()
067 */
068 @Override
069 public Class getSourceAccountingLineClass() {
070 return LaborJournalVoucherDetail.class;
071 }
072
073 /**
074 * @see org.kuali.kfs.module.ld.document.LaborLedgerPostingDocument#getLaborLedgerPendingEntry(int)
075 */
076 public LaborLedgerPendingEntry getLaborLedgerPendingEntry(int index) {
077 while (laborLedgerPendingEntries.size() <= index) {
078 laborLedgerPendingEntries.add(new LaborLedgerPendingEntry());
079 }
080 return laborLedgerPendingEntries.get(index);
081 }
082
083 /**
084 * Gets the offsetTypeCode attribute.
085 *
086 * @return Returns the offsetTypeCode.
087 */
088 public String getOffsetTypeCode() {
089 return offsetTypeCode;
090 }
091
092 /**
093 * Sets the offsetTypeCode attribute value.
094 *
095 * @param offsetTypeCode The offsetTypeCode to set.
096 */
097 public void setOffsetTypeCode(String offsetTypeCode) {
098 this.offsetTypeCode = offsetTypeCode;
099 }
100
101 /**
102 * Gets the laborLedgerPendingEntries attribute.
103 *
104 * @return Returns the laborLedgerPendingEntries.
105 */
106 public List<LaborLedgerPendingEntry> getLaborLedgerPendingEntries() {
107 return laborLedgerPendingEntries;
108 }
109
110 /**
111 * Sets the laborLedgerPendingEntries attribute value.
112 *
113 * @param laborLedgerPendingEntries The laborLedgerPendingEntries to set.
114 */
115 public void setLaborLedgerPendingEntries(List<LaborLedgerPendingEntry> laborLedgerPendingEntries) {
116 this.laborLedgerPendingEntries = laborLedgerPendingEntries;
117 }
118
119 /**
120 * Gets the financialSystemDocumentTypeCode attribute.
121 *
122 * @return Returns the financialSystemDocumentTypeCode.
123 */
124 public DocumentTypeEBO getFinancialSystemDocumentTypeCode() {
125 return financialSystemDocumentTypeCode = SpringContext.getBean(KEWModuleService.class).retrieveExternalizableBusinessObjectIfNecessary(this, financialSystemDocumentTypeCode, "financialSystemDocumentTypeCode");
126 }
127
128 /**
129 * Used to get the appropriate <code>{@link AccountingLineParser}</code> for the <code>Document</code>
130 *
131 * @return AccountingLineParser
132 */
133 @Override
134 public AccountingLineParser getAccountingLineParser() {
135 return new LaborJournalVoucherAccountingLineParser(getBalanceTypeCode());
136 }
137
138 /**
139 * Override to call super and then iterate over all GLPEs and update the approved code appropriately.
140 *
141 * @see Document#doRouteStatusChange()
142 */
143 @Override
144 public void doRouteStatusChange(DocumentRouteStatusChangeDTO statusChangeEvent) {
145 super.doRouteStatusChange(statusChangeEvent);
146 if (getDocumentHeader().getWorkflowDocument().stateIsProcessed()) {
147 changeLedgerPendingEntriesApprovedStatusCode();
148 }
149 else if (getDocumentHeader().getWorkflowDocument().stateIsCanceled() || getDocumentHeader().getWorkflowDocument().stateIsDisapproved()) {
150 removeLedgerPendingEntries();
151 }
152 }
153
154 /**
155 * This method iterates over all of the pending entries for a document and sets their approved status code to APPROVED "A".
156 */
157 protected void changeLedgerPendingEntriesApprovedStatusCode() {
158 for (LaborLedgerPendingEntry pendingEntry : laborLedgerPendingEntries) {
159 pendingEntry.setFinancialDocumentApprovedCode(KFSConstants.DocumentStatusCodes.APPROVED);
160 }
161 }
162
163 /**
164 * This method calls the service to remove all of the pending entries associated with this document
165 */
166 protected void removeLedgerPendingEntries() {
167 LaborLedgerPendingEntryService laborLedgerPendingEntryService = SpringContext.getBean(LaborLedgerPendingEntryService.class);
168 laborLedgerPendingEntryService.delete(getDocumentHeader().getDocumentNumber());
169 }
170
171 /**
172 * @see org.kuali.kfs.module.ld.document.LaborLedgerPostingDocument#generateLaborLedgerBenefitClearingPendingEntries(org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper)
173 */
174 public boolean generateLaborLedgerBenefitClearingPendingEntries(GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
175 return true;
176 }
177
178 /**
179 * @see org.kuali.kfs.module.ld.document.LaborLedgerPostingDocument#generateLaborLedgerPendingEntries(org.kuali.kfs.sys.businessobject.AccountingLine,
180 * org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper)
181 */
182 public boolean generateLaborLedgerPendingEntries(AccountingLine accountingLine, GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
183 LOG.debug("processGenerateLaborLedgerPendingEntries() started");
184
185 try {
186 LaborLedgerPendingEntry pendingLedgerEntry = new LaborLedgerPendingEntry();
187
188 // populate the explicit entry
189 ObjectUtil.buildObject(pendingLedgerEntry, accountingLine);
190
191 GeneralLedgerPendingEntryService pendingEntryService = SpringContext.getBean(GeneralLedgerPendingEntryService.class);
192 pendingEntryService.populateExplicitGeneralLedgerPendingEntry(this, accountingLine, sequenceHelper, pendingLedgerEntry);
193
194 // apply the labor JV specific information
195 this.customizeExplicitGeneralLedgerPendingEntry(accountingLine, pendingLedgerEntry);
196 pendingLedgerEntry.setFinancialDocumentTypeCode(this.getOffsetTypeCode());
197
198 if (StringUtils.isBlank(((LaborJournalVoucherDetail) accountingLine).getEmplid())) {
199 pendingLedgerEntry.setEmplid(LaborConstants.getDashEmplId());
200 }
201
202 if (StringUtils.isBlank(((LaborJournalVoucherDetail) accountingLine).getPositionNumber())) {
203 pendingLedgerEntry.setPositionNumber(LaborConstants.getDashPositionNumber());
204 }
205
206 String originationCode = SpringContext.getBean(HomeOriginationService.class).getHomeOrigination().getFinSystemHomeOriginationCode();
207 pendingLedgerEntry.setFinancialSystemOriginationCode(originationCode);
208
209 pendingLedgerEntry.setTransactionLedgerEntrySequenceNumber(sequenceHelper.getSequenceCounter());
210
211 this.getLaborLedgerPendingEntries().add(pendingLedgerEntry);
212
213 sequenceHelper.increment();
214 }
215 catch (Exception e) {
216 LOG.error("Cannot add a Labor Ledger Pending Entry into the list");
217 return false;
218 }
219
220 return true;
221 }
222
223 /**
224 * If the document has a total amount, call method on document to get the total and set in doc header.
225 *
226 * @see org.kuali.rice.kns.document.Document#prepareForSave()
227 */
228 @Override
229 public void prepareForSave() {
230 if (!SpringContext.getBean(LaborLedgerPendingEntryService.class).generateLaborLedgerPendingEntries(this)) {
231 logErrors();
232 throw new ValidationException("labor ledger LLPE generation failed");
233 }
234
235 super.prepareForSave();
236 }
237
238 /**
239 * @see org.kuali.kfs.sys.document.AccountingDocumentBase#prepareForSave(org.kuali.rice.kns.rule.event.KualiDocumentEvent)
240 */
241 @Override
242 public void prepareForSave(KualiDocumentEvent event) {
243 this.prepareForSave();
244 super.prepareForSave(event);
245 }
246
247 /**
248 * This is a "do nothing" version of the method - it just won't create GLPEs
249 *
250 * @see org.kuali.kfs.sys.document.AccountingDocumentBase#generateGeneralLedgerPendingEntries(org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail,
251 * org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper)
252 */
253 @Override
254 public boolean generateGeneralLedgerPendingEntries(GeneralLedgerPendingEntrySourceDetail glpeSourceDetail, GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
255 return true;
256 }
257
258 /**
259 * Labor docs never generate general ledger pending entries, and therefore, this method is never called, but we always return
260 * true, since we're required to have a concrete representation
261 *
262 * @see org.kuali.kfs.sys.document.AccountingDocumentBase#isDebit(org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail)
263 */
264 @Override
265 public boolean isDebit(GeneralLedgerPendingEntrySourceDetail postable) {
266 return true;
267 }
268
269 public List getLaborLedgerPendingEntriesForSearching() {
270 return getLaborLedgerPendingEntries();
271 }
272 }