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.cam.document;
017    
018    import java.util.ArrayList;
019    import java.util.HashMap;
020    import java.util.Iterator;
021    import java.util.List;
022    import java.util.Map;
023    
024    import org.apache.log4j.Logger;
025    import org.kuali.kfs.integration.cam.CapitalAssetManagementModuleService;
026    import org.kuali.kfs.module.cam.CamsConstants;
027    import org.kuali.kfs.module.cam.CamsPropertyConstants;
028    import org.kuali.kfs.module.cam.businessobject.Asset;
029    import org.kuali.kfs.module.cam.businessobject.AssetFabrication;
030    import org.kuali.kfs.module.cam.businessobject.AssetPayment;
031    import org.kuali.kfs.module.cam.businessobject.defaultvalue.NextAssetNumberFinder;
032    import org.kuali.kfs.module.cam.document.service.AssetLocationService;
033    import org.kuali.kfs.module.cam.document.service.AssetService;
034    import org.kuali.kfs.module.cam.document.service.EquipmentLoanOrReturnService;
035    import org.kuali.kfs.module.cam.document.service.PaymentSummaryService;
036    import org.kuali.kfs.module.cam.document.service.RetirementInfoService;
037    import org.kuali.kfs.module.cam.service.AssetLockService;
038    import org.kuali.kfs.module.cam.util.MaintainableWorkflowUtils;
039    import org.kuali.kfs.sys.KFSConstants;
040    import org.kuali.kfs.sys.context.SpringContext;
041    import org.kuali.kfs.sys.document.FinancialSystemMaintainable;
042    import org.kuali.rice.kew.exception.WorkflowException;
043    import org.kuali.rice.kns.bo.DocumentHeader;
044    import org.kuali.rice.kns.document.MaintenanceDocument;
045    import org.kuali.rice.kns.document.MaintenanceLock;
046    import org.kuali.rice.kns.maintenance.Maintainable;
047    import org.kuali.rice.kns.service.BusinessObjectService;
048    import org.kuali.rice.kns.service.DateTimeService;
049    import org.kuali.rice.kns.service.DocumentService;
050    import org.kuali.rice.kns.service.ParameterService;
051    import org.kuali.rice.kns.util.GlobalVariables;
052    import org.kuali.rice.kns.web.ui.Section;
053    import org.kuali.rice.kns.workflow.service.KualiWorkflowDocument;
054    import org.kuali.rice.kns.workflow.service.KualiWorkflowInfo;
055    
056    /**
057     * This class implements custom data preparation for displaying asset edit screen.
058     */
059    
060    public class AssetMaintainableImpl extends FinancialSystemMaintainable {
061        
062        private static final Logger LOG = Logger.getLogger(AssetMaintainableImpl.class);
063        
064        private Asset asset;
065        private Asset copyAsset;
066        private boolean fabricationOn;
067    
068        private static final Map<String, String> FINANCIAL_DOC_NAME_MAP = new HashMap<String, String>();
069        static {
070            FINANCIAL_DOC_NAME_MAP.put(KFSConstants.FinancialDocumentTypeCodes.CASH_RECEIPT, KFSConstants.FinancialDocumentTypeNames.CASH_RECEIPT);
071            FINANCIAL_DOC_NAME_MAP.put(KFSConstants.FinancialDocumentTypeCodes.DISTRIBUTION_OF_INCOME_AND_EXPENSE, KFSConstants.FinancialDocumentTypeNames.DISTRIBUTION_OF_INCOME_AND_EXPENSE);
072            FINANCIAL_DOC_NAME_MAP.put(KFSConstants.FinancialDocumentTypeCodes.GENERAL_ERROR_CORRECTION, KFSConstants.FinancialDocumentTypeNames.GENERAL_ERROR_CORRECTION);
073            FINANCIAL_DOC_NAME_MAP.put(KFSConstants.FinancialDocumentTypeCodes.INTERNAL_BILLING, KFSConstants.FinancialDocumentTypeNames.INTERNAL_BILLING);
074            FINANCIAL_DOC_NAME_MAP.put(KFSConstants.FinancialDocumentTypeCodes.SERVICE_BILLING, KFSConstants.FinancialDocumentTypeNames.SERVICE_BILLING);
075            FINANCIAL_DOC_NAME_MAP.put(KFSConstants.FinancialDocumentTypeCodes.YEAR_END_DISTRIBUTION_OF_INCOME_AND_EXPENSE, KFSConstants.FinancialDocumentTypeNames.YEAR_END_DISTRIBUTION_OF_INCOME_AND_EXPENSE);
076            FINANCIAL_DOC_NAME_MAP.put(KFSConstants.FinancialDocumentTypeCodes.YEAR_END_GENERAL_ERROR_CORRECTION, KFSConstants.FinancialDocumentTypeNames.YEAR_END_GENERAL_ERROR_CORRECTION);
077            FINANCIAL_DOC_NAME_MAP.put(KFSConstants.FinancialDocumentTypeCodes.PROCUREMENT_CARD, KFSConstants.FinancialDocumentTypeNames.PROCUREMENT_CARD);
078        }
079    
080        /**
081         * We are using a substitute mechanism for asset locking which can lock on assets when rule check passed. Return empty list from
082         * this method.
083         * 
084         * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#generateMaintenanceLocks()
085         */
086        @Override
087        public List<MaintenanceLock> generateMaintenanceLocks() {
088            return new ArrayList<MaintenanceLock>();
089        }
090    
091        /**
092         * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#doRouteStatusChange(org.kuali.rice.kns.bo.DocumentHeader)
093         */
094        @Override
095        public void doRouteStatusChange(DocumentHeader documentHeader) {
096            super.doRouteStatusChange(documentHeader);
097            KualiWorkflowDocument workflowDoc = documentHeader.getWorkflowDocument();
098            // release lock for asset edit...
099            if ((this.getBusinessObject() instanceof Asset && !(this.getBusinessObject() instanceof AssetFabrication)) && (workflowDoc.stateIsCanceled() || workflowDoc.stateIsDisapproved() || workflowDoc.stateIsProcessed() || workflowDoc.stateIsFinal())) {
100                this.getCapitalAssetManagementModuleService().deleteAssetLocks(documentNumber, null);
101            }
102        }
103    
104        protected CapitalAssetManagementModuleService getCapitalAssetManagementModuleService() {
105            return SpringContext.getBean(CapitalAssetManagementModuleService.class);
106        }
107    
108        /**
109         * @see org.kuali.rice.kns.maintenance.Maintainable#processAfterEdit(org.kuali.rice.kns.document.MaintenanceDocument,
110         *      java.util.Map)
111         * @param document Maintenance Document used for editing
112         * @param parameters Parameters available
113         */
114        public void processAfterEdit(MaintenanceDocument document, Map parameters) {
115            initializeAttributes(document);
116            // Identifies the latest location information
117            getAssetLocationService().setOffCampusLocation(copyAsset);
118            getAssetLocationService().setOffCampusLocation(asset);
119    
120            // Calculates payment summary and depreciation summary based on available payment records
121            PaymentSummaryService paymentSummaryService = SpringContext.getBean(PaymentSummaryService.class);
122            paymentSummaryService.calculateAndSetPaymentSummary(copyAsset);
123            paymentSummaryService.calculateAndSetPaymentSummary(asset);
124    
125            // Identifies the merge history and separation history based on asset disposition records
126            getAssetService().setSeparateHistory(copyAsset);
127            getAssetService().setSeparateHistory(asset);
128    
129            // Finds out the latest retirement info, is asset is currently retired.
130            RetirementInfoService retirementInfoService = SpringContext.getBean(RetirementInfoService.class);
131            retirementInfoService.setRetirementInfo(copyAsset);
132            retirementInfoService.setRetirementInfo(asset);
133    
134            retirementInfoService.setMergeHistory(copyAsset);
135            retirementInfoService.setMergeHistory(asset);
136    
137            // Finds out the latest equipment loan or return information if available
138            EquipmentLoanOrReturnService equipmentLoanOrReturnService = SpringContext.getBean(EquipmentLoanOrReturnService.class);
139            equipmentLoanOrReturnService.setEquipmentLoanInfo(copyAsset);
140            equipmentLoanOrReturnService.setEquipmentLoanInfo(asset);
141    
142            super.processAfterEdit(document, parameters);
143        }
144    
145        /**
146         * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#refresh(java.lang.String, java.util.Map,
147         *      org.kuali.rice.kns.document.MaintenanceDocument)
148         */
149        @Override
150        public List<Section> getCoreSections(MaintenanceDocument document, Maintainable oldMaintainable) {
151            List<Section> sections = super.getCoreSections(document, oldMaintainable);
152    
153            Asset asset = (Asset) getBusinessObject();
154            if (asset.getAssetPayments().size() == 0) {
155                for (Section section : sections) {
156                    if (CamsConstants.Asset.SECTION_ID_PAYMENT_INFORMATION.equals(section.getSectionId())) {
157                        section.setSectionTitle(section.getSectionTitle() + CamsConstants.Asset.SECTION_TITLE_NO_PAYMENT + asset.getCapitalAssetNumber());
158                    }
159                }
160            }
161            
162            return sections;
163        }
164    
165        /**
166         * This method gets old and new maintainable objects and creates convenience handles to them
167         * 
168         * @param document Asset Edit Document
169         */
170        private void initializeAttributes(MaintenanceDocument document) {
171            if (asset == null) {
172                asset = (Asset) document.getNewMaintainableObject().getBusinessObject();
173                asset.setTagged();
174            }
175            if (copyAsset == null) {
176                copyAsset = (Asset) document.getOldMaintainableObject().getBusinessObject();
177            }
178    
179            setFabricationOn(document.getNewMaintainableObject().getBusinessObject() instanceof AssetFabrication);
180        }
181        
182        /**
183         * KFSMI-5964: added refresh to Asset object after retrieve to prevent updated depreciation data from
184         * wiped on existing saved/enrouted maint. doc
185         * 
186         * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#processAfterRetrieve()
187         */
188        @Override
189        public void processAfterRetrieve() {
190            
191            //Asset only
192            if (this.getBusinessObject() instanceof Asset && MaintainableWorkflowUtils.isDocumentSavedOrEnroute(documentNumber)) {
193    
194                Asset asset = (Asset)getBusinessObject();
195                asset.refreshReferenceObject(CamsPropertyConstants.Asset.ASSET_PAYMENTS);
196                
197                PaymentSummaryService paymentSummaryService = SpringContext.getBean(PaymentSummaryService.class);
198                paymentSummaryService.calculateAndSetPaymentSummary(asset);
199            }
200        }
201    
202        @Override
203        public void saveBusinessObject() {
204            Asset asset = ((Asset) businessObject);
205            if (asset.getCapitalAssetNumber() == null) {
206                asset.setCapitalAssetNumber(NextAssetNumberFinder.getLongValue());
207            }
208            asset.refreshReferenceObject(CamsPropertyConstants.Asset.ASSET_LOCATIONS);
209            // update and save asset location
210            if (getAssetLocationService().isOffCampusLocationExists(asset.getOffCampusLocation())) {
211                getAssetLocationService().updateOffCampusLocation(asset);
212            }
213            super.saveBusinessObject();
214        }
215    
216    
217        @Override
218        public void processAfterNew(MaintenanceDocument document, Map<String, String[]> parameters) {
219            super.processAfterNew(document, parameters);
220            initializeAttributes(document);
221            // document.getNewMaintainableObject().setGenerateDefaultValues(false);
222            if (asset.getCreateDate() == null) {
223                asset.setCreateDate(SpringContext.getBean(DateTimeService.class).getCurrentSqlDate());
224                asset.setAcquisitionTypeCode(CamsConstants.Asset.ACQUISITION_TYPE_CODE_C);
225                asset.setVendorName(CamsConstants.Asset.VENDOR_NAME_CONSTRUCTED);
226                asset.setInventoryStatusCode(CamsConstants.InventoryStatusCode.CAPITAL_ASSET_UNDER_CONSTRUCTION);
227                asset.setPrimaryDepreciationMethodCode(CamsConstants.Asset.DEPRECIATION_METHOD_STRAIGHT_LINE_CODE);
228                asset.setCapitalAssetTypeCode(SpringContext.getBean(ParameterService.class).getParameterValue(Asset.class, CamsConstants.Parameters.DEFAULT_FABRICATION_ASSET_TYPE_CODE));
229                getAssetService().setFiscalPeriod(asset);
230            }
231            // setup offCampusLocation
232            getAssetLocationService().setOffCampusLocation(asset);
233        }
234    
235        @Override
236        public void setGenerateDefaultValues(String docTypeName) {
237    
238        }
239    
240        public List<String> getFpLinks() {
241            Asset asset = (Asset) getBusinessObject();
242            List<Long> assetNumbers = new ArrayList<Long>();
243            assetNumbers.add(asset.getCapitalAssetNumber());
244            return SpringContext.getBean(AssetLockService.class).getAssetLockingDocuments(assetNumbers, CamsConstants.DocumentTypeName.ASSET_FP_INQUIRY, "");
245        }
246    
247        public List<String> getPreqLinks() {
248            Asset asset = (Asset) getBusinessObject();
249            List<Long> assetNumbers = new ArrayList<Long>();
250            assetNumbers.add(asset.getCapitalAssetNumber());
251            return SpringContext.getBean(AssetLockService.class).getAssetLockingDocuments(assetNumbers, CamsConstants.DocumentTypeName.ASSET_PREQ_INQUIRY, "");
252        }
253    
254        public List<String> getFpLinkedDocumentInfo() {
255            List<String> documentInfo = new ArrayList<String>();
256            Iterator<String> fpDocumentNumbers = getFpLinks().iterator();
257            while (fpDocumentNumbers.hasNext()) {
258                String aDocumentNumber = fpDocumentNumbers.next();
259                KualiWorkflowInfo kualiWorkflowInfo = SpringContext.getBean(KualiWorkflowInfo.class);
260                try {
261                    String docTypeName = SpringContext.getBean(DocumentService.class).getByDocumentHeaderId(aDocumentNumber).getDocumentHeader().getWorkflowDocument().getDocumentType();
262                    documentInfo.add(FINANCIAL_DOC_NAME_MAP.get(docTypeName) + "-" + aDocumentNumber);
263                }
264                catch (WorkflowException e) {
265                    throw new RuntimeException("Caught WorkflowException trying to get document type name", e);
266                }
267            }
268            return documentInfo;
269        }
270    
271        public boolean isFabricationOn() {
272            return fabricationOn;
273        }
274    
275        public void setFabricationOn(boolean fabricationOn) {
276            this.fabricationOn = fabricationOn;
277        }
278    
279        private AssetService getAssetService() {
280            return SpringContext.getBean(AssetService.class);
281        }
282    
283        private AssetLocationService getAssetLocationService() {
284            return SpringContext.getBean(AssetLocationService.class);
285        }
286    }