1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  package org.kuali.kfs.coa.document;
20  
21  import java.util.ArrayList;
22  import java.util.HashMap;
23  import java.util.List;
24  import java.util.Map;
25  
26  import org.kuali.kfs.coa.businessobject.ObjectCode;
27  import org.kuali.kfs.coa.businessobject.ObjectCodeGlobal;
28  import org.kuali.kfs.coa.businessobject.ObjectCodeGlobalDetail;
29  import org.kuali.kfs.coa.service.ObjectCodeService;
30  import org.kuali.kfs.coa.service.SubObjectTrickleDownInactivationService;
31  import org.kuali.kfs.sys.KFSConstants;
32  import org.kuali.kfs.sys.context.SpringContext;
33  import org.kuali.kfs.sys.document.FinancialSystemGlobalMaintainable;
34  import org.kuali.rice.krad.bo.GlobalBusinessObject;
35  import org.kuali.rice.krad.bo.PersistableBusinessObject;
36  import org.kuali.rice.krad.maintenance.MaintenanceLock;
37  import org.kuali.rice.krad.service.BusinessObjectService;
38  import org.kuali.rice.krad.util.KRADConstants;
39  import org.kuali.rice.krad.util.ObjectUtils;
40  
41  
42  
43  
44  
45  
46  public class ObjectCodeGlobalMaintainableImpl extends FinancialSystemGlobalMaintainable {
47      private static String CHANGE_DETAIL_COLLECTION = "objectCodeGlobalDetails";
48  
49      
50      
51      
52      
53      
54      
55      
56      
57      
58      
59      
60      
61      
62      
63  
64      
65      
66  
67      
68      
69      
70      
71      
72      
73      
74      
75      
76  
77      
78      
79      
80      
81      
82      
83      
84      
85      
86      
87  
88      
89  
90  
91      @Override
92      protected void prepareGlobalsForSave() {
93          
94          ObjectCodeGlobal objectCodeGlobal = (ObjectCodeGlobal) getBusinessObject();
95  
96          for (ObjectCodeGlobalDetail detail : objectCodeGlobal.getObjectCodeGlobalDetails()) {
97              detail.setFinancialObjectCode(objectCodeGlobal.getFinancialObjectCode());
98          }
99          super.prepareGlobalsForSave();
100     }
101 
102     
103 
104 
105 
106 
107     @Override
108     public List<MaintenanceLock> generateMaintenanceLocks() {
109         ObjectCodeGlobal objectCodeGlobal = (ObjectCodeGlobal) getBusinessObject();
110         List<MaintenanceLock> maintenanceLocks = new ArrayList();
111         SubObjectTrickleDownInactivationService subObjectTrickleDownInactivationService = SpringContext.getBean(SubObjectTrickleDownInactivationService.class);
112         
113         for (ObjectCodeGlobalDetail detail : objectCodeGlobal.getObjectCodeGlobalDetails()) {
114             MaintenanceLock maintenanceLock = new MaintenanceLock();
115             StringBuffer lockrep = new StringBuffer();
116 
117             lockrep.append(ObjectCode.class.getName() + KFSConstants.Maintenance.AFTER_CLASS_DELIM);
118             lockrep.append("universityFiscalYear" + KFSConstants.Maintenance.AFTER_FIELDNAME_DELIM);
119             lockrep.append(detail.getUniversityFiscalYear() + KFSConstants.Maintenance.AFTER_VALUE_DELIM);
120             lockrep.append("chartOfAccountsCode" + KFSConstants.Maintenance.AFTER_FIELDNAME_DELIM);
121             lockrep.append(detail.getChartOfAccountsCode() + KFSConstants.Maintenance.AFTER_VALUE_DELIM);
122             lockrep.append("financialObjectCode" + KFSConstants.Maintenance.AFTER_FIELDNAME_DELIM);
123             lockrep.append(detail.getFinancialObjectCode());
124 
125             maintenanceLock.setDocumentNumber(objectCodeGlobal.getDocumentNumber());
126             maintenanceLock.setLockingRepresentation(lockrep.toString());
127             maintenanceLocks.add(maintenanceLock);
128             
129             ObjectCode objectCode = new ObjectCode();
130             objectCode.setUniversityFiscalYear(detail.getUniversityFiscalYear());
131             objectCode.setChartOfAccountsCode(detail.getChartOfAccountsCode());
132             objectCode.setFinancialObjectCode(detail.getFinancialObjectCode());
133             objectCode.setActive(objectCodeGlobal.isFinancialObjectActiveIndicator());
134             
135             if (isInactivatingObjectCode(objectCode)) {
136                 
137                 
138                 maintenanceLocks.addAll(subObjectTrickleDownInactivationService.generateTrickleDownMaintenanceLocks(objectCode, getDocumentNumber()));
139             }
140         }
141         return maintenanceLocks;
142     }
143     
144     
145 
146 
147     @Override
148     public void saveBusinessObject() {
149         BusinessObjectService boService = SpringContext.getBean(BusinessObjectService.class);
150         
151         GlobalBusinessObject gbo = (GlobalBusinessObject) businessObject;
152 
153         
154         List<PersistableBusinessObject> bosToDeactivate = gbo.generateDeactivationsToPersist();
155         if (bosToDeactivate != null) {
156             if (!bosToDeactivate.isEmpty()) {
157                 boService.save(bosToDeactivate);
158             }
159         }
160         
161         
162         
163         
164         
165         Map<String, Boolean> objectCodeActiveStatusCache = buildObjectCodeActiveStatusCache((ObjectCodeGlobal) gbo);
166         
167         SubObjectTrickleDownInactivationService subObjectTrickleDownInactivationService = SpringContext.getBean(SubObjectTrickleDownInactivationService.class);
168         
169         List<PersistableBusinessObject> bosToPersist = gbo.generateGlobalChangesToPersist();
170         if (bosToPersist != null) {
171             if (!bosToPersist.isEmpty()) {
172                 for (PersistableBusinessObject bo : bosToPersist) {
173                     ObjectCode objectCode = (ObjectCode) bo;
174                     
175                     boService.save(objectCode);
176                     
177                     if (isInactivatingObjectCode(objectCode, objectCodeActiveStatusCache)) {
178                         subObjectTrickleDownInactivationService.trickleDownInactivateSubObjects(objectCode, getDocumentNumber());
179                     }
180                 }
181             }
182         }
183     }
184     
185     protected boolean isInactivatingObjectCode(ObjectCode objectCode) {
186         ObjectCodeService objectCodeService = SpringContext.getBean(ObjectCodeService.class);
187         if (!objectCode.isActive()) {
188             ObjectCode objectCodeFromDB = objectCodeService.getByPrimaryId(objectCode.getUniversityFiscalYear(), objectCode.getChartOfAccountsCode(), objectCode.getFinancialObjectCode());
189             if (objectCodeFromDB != null && objectCodeFromDB.isActive()) {
190                 return true;
191             }
192         }
193         return false;
194     }
195     
196     protected boolean isInactivatingObjectCode(ObjectCode objectCode, Map<String, Boolean> objectCodeActiveStatusCache) {
197         if (!objectCode.isActive()) {
198             if (Boolean.TRUE.equals(objectCodeActiveStatusCache.get(buildObjectCodeCachingKey(objectCode)))) {
199                 return true;
200             }
201         }
202         return false;
203     }
204     
205     protected String buildObjectCodeCachingKey(ObjectCode objectCode) {
206         return objectCode.getUniversityFiscalYear() + KRADConstants.Maintenance.LOCK_AFTER_VALUE_DELIM + objectCode.getChartOfAccountsCode() + 
207                 KRADConstants.Maintenance.LOCK_AFTER_VALUE_DELIM + objectCode.getFinancialObjectCode(); 
208     }
209     
210     protected Map<String, Boolean> buildObjectCodeActiveStatusCache(ObjectCodeGlobal objectCodeGlobal) {
211         ObjectCodeService objectCodeService = SpringContext.getBean(ObjectCodeService.class);
212         Map<String, Boolean> cache = new HashMap<String, Boolean>();
213         for (ObjectCodeGlobalDetail detail : objectCodeGlobal.getObjectCodeGlobalDetails()) {
214             ObjectCode objectCodeFromDB = objectCodeService.getByPrimaryId(detail.getUniversityFiscalYear(), detail.getChartOfAccountsCode(), objectCodeGlobal.getFinancialObjectCode());
215             if (ObjectUtils.isNotNull(objectCodeFromDB)) {
216                 cache.put(buildObjectCodeCachingKey(objectCodeFromDB), Boolean.valueOf(objectCodeFromDB.isActive()));
217             }
218         }
219         return cache;
220     }
221 
222     @Override
223     public Class<? extends PersistableBusinessObject> getPrimaryEditedBusinessObjectClass() {
224         return ObjectCode.class;
225     }
226 }