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.endow.document.validation.impl;
017
018 import java.sql.Date;
019 import java.text.ParseException;
020 import java.util.ArrayList;
021 import java.util.HashMap;
022 import java.util.List;
023 import java.util.Map;
024
025 import org.kuali.kfs.coa.document.validation.impl.MaintenancePreRulesBase;
026 import org.kuali.kfs.module.endow.EndowParameterKeyConstants;
027 import org.kuali.kfs.module.endow.businessobject.KEMID;
028 import org.kuali.kfs.module.endow.businessobject.KemidAgreement;
029 import org.kuali.kfs.module.endow.businessobject.KemidAuthorizations;
030 import org.kuali.kfs.module.endow.businessobject.KemidBenefittingOrganization;
031 import org.kuali.kfs.module.endow.businessobject.KemidCombineDonorStatement;
032 import org.kuali.kfs.module.endow.businessobject.KemidDonorStatement;
033 import org.kuali.kfs.module.endow.businessobject.KemidFee;
034 import org.kuali.kfs.module.endow.businessobject.KemidPayoutInstruction;
035 import org.kuali.kfs.module.endow.businessobject.KemidReportGroup;
036 import org.kuali.kfs.module.endow.businessobject.KemidSourceOfFunds;
037 import org.kuali.kfs.module.endow.businessobject.KemidSpecialInstruction;
038 import org.kuali.kfs.module.endow.businessobject.KemidUseCriteria;
039 import org.kuali.kfs.module.endow.document.service.KEMService;
040 import org.kuali.kfs.sys.context.SpringContext;
041 import org.kuali.rice.kns.document.MaintenanceDocument;
042 import org.kuali.rice.kns.service.DateTimeService;
043 import org.kuali.rice.kns.service.ParameterService;
044 import org.kuali.rice.kns.util.KNSConstants;
045 import org.kuali.rice.kns.util.KualiInteger;
046 import org.kuali.rice.kns.util.ObjectUtils;
047
048 /**
049 * This KemidPreRule class implements the pre rules for the Kemid BO.
050 */
051 public class KemidPreRule extends MaintenancePreRulesBase {
052
053 private KEMID oldKemid;
054 private KEMID newKemid;
055
056 /**
057 * @see org.kuali.kfs.coa.document.validation.impl.MaintenancePreRulesBase#doCustomPreRules(org.kuali.rice.kns.document.MaintenanceDocument)
058 */
059 protected boolean doCustomPreRules(MaintenanceDocument maintenanceDocument) {
060 boolean preRulesOK = true;
061 ParameterService parameterService = SpringContext.getBean(ParameterService.class);
062
063 String kemidValueSystemParam = parameterService.getParameterValue(KEMID.class, EndowParameterKeyConstants.KEMID_VALUE);
064
065 setupConvenienceObjects(maintenanceDocument);
066
067 setAgreementsIds();
068 setSourceOfFundsSeq();
069 updateBenefittingOrgs(maintenanceDocument);
070 updateAuthorizations(maintenanceDocument);
071 setPayoutInstructionsSeq();
072 setUseCriteriaSeq();
073 setFeeMethodSequence();
074 setReportGroupSequence();
075 setSpecialInstructionSeq();
076 setDonorStatementsSeq();
077 setCombineDonorSeq();
078
079 return preRulesOK;
080 }
081
082 /**
083 * Sets the ID for all the new agreements as the next sequencial number.
084 */
085 private void setAgreementsIds() {
086 List<KemidAgreement> oldAgreements = new ArrayList<KemidAgreement>();
087 List<KemidAgreement> newAgreements = new ArrayList<KemidAgreement>();
088
089
090 for (KemidAgreement kemidAgreement : newKemid.getKemidAgreements()) {
091 if (kemidAgreement.isNewCollectionRecord()) {
092 newAgreements.add(kemidAgreement);
093 }
094 else {
095 oldAgreements.add(kemidAgreement);
096 }
097 }
098
099 int sequenceStart = oldAgreements.size();
100
101 for (KemidAgreement agreement : newAgreements) {
102 agreement.setAgreementId(new KualiInteger(++sequenceStart));
103 }
104
105 }
106
107 /**
108 * Sets the source of fund sequence number for all the new sources of funds.
109 */
110 private void setSourceOfFundsSeq() {
111 List<KemidSourceOfFunds> oldKemidSourcesOfFunds = new ArrayList<KemidSourceOfFunds>();
112 List<KemidSourceOfFunds> newKemidSourcesOfFunds = new ArrayList<KemidSourceOfFunds>();
113
114
115 for (KemidSourceOfFunds kemidSourceOfFunds : newKemid.getKemidSourcesOfFunds()) {
116 if (kemidSourceOfFunds.isNewCollectionRecord()) {
117 newKemidSourcesOfFunds.add(kemidSourceOfFunds);
118 }
119 else {
120 oldKemidSourcesOfFunds.add(kemidSourceOfFunds);
121 }
122 }
123
124 int sequenceStart = oldKemidSourcesOfFunds.size();
125
126 for (KemidSourceOfFunds kemidSourceOfFunds : newKemidSourcesOfFunds) {
127 kemidSourceOfFunds.setKemidFundSourceSequenceNumber(new KualiInteger(++sequenceStart));
128 }
129
130 }
131
132 /**
133 * Sets the benefitting organization sequence number for all the new benefitting organizations.
134 */
135 private void setBenefittingOrgsSeq() {
136 List<KemidBenefittingOrganization> oldKemidBenefittingOrgs = new ArrayList<KemidBenefittingOrganization>();
137 List<KemidBenefittingOrganization> newKemidBenefittingOrgs = new ArrayList<KemidBenefittingOrganization>();
138
139
140 for (KemidBenefittingOrganization kemidBenefittingOrg : newKemid.getKemidBenefittingOrganizations()) {
141 if (kemidBenefittingOrg.isNewCollectionRecord()) {
142 newKemidBenefittingOrgs.add(kemidBenefittingOrg);
143 }
144 else {
145 oldKemidBenefittingOrgs.add(kemidBenefittingOrg);
146 }
147 }
148
149 int sequenceStart = oldKemidBenefittingOrgs.size();
150
151 for (KemidBenefittingOrganization kemidBenefittingOrg : newKemidBenefittingOrgs) {
152 kemidBenefittingOrg.setBenefittingOrgSeqNumber(new KualiInteger(++sequenceStart));
153 }
154
155 }
156
157 /**
158 * Sets the benefitting organization last change date to the current date if the benefit percent changed. This method should
159 * only be called after the setBenefittingOrgsSeq method is called.
160 *
161 * @param maintenanceDocument
162 */
163 private void setBenefittingOrgsLastChangeDate(MaintenanceDocument maintenanceDocument) {
164
165 KEMService kemService = SpringContext.getBean(KEMService.class);
166 DateTimeService dateTimeService = SpringContext.getBean(DateTimeService.class);
167
168 if (KNSConstants.MAINTENANCE_EDIT_ACTION.equals(maintenanceDocument.getNewMaintainableObject().getMaintenanceAction())) {
169 if (newKemid.getKemidBenefittingOrganizations().size() != 0) {
170
171 Map<KualiInteger, KemidBenefittingOrganization> oldKemidBenefittingOrganizations = new HashMap<KualiInteger, KemidBenefittingOrganization>();
172
173 if (oldKemid.getKemidBenefittingOrganizations().size() != 0) {
174 for (KemidBenefittingOrganization benefittingOrganization : oldKemid.getKemidBenefittingOrganizations()) {
175 oldKemidBenefittingOrganizations.put(benefittingOrganization.getBenefittingOrgSeqNumber(), benefittingOrganization);
176 }
177
178 }
179
180 for (KemidBenefittingOrganization benefittingOrganization : newKemid.getKemidBenefittingOrganizations()) {
181 KemidBenefittingOrganization oldBenefittingOrg = oldKemidBenefittingOrganizations.get(benefittingOrganization.getBenefittingOrgSeqNumber());
182
183 boolean isBenefitPctChanged = false;
184 if (ObjectUtils.isNotNull(oldBenefittingOrg)) {
185 isBenefitPctChanged = (benefittingOrganization.getBenefitPrecent() == null && oldBenefittingOrg.getBenefitPrecent() != null) || (benefittingOrganization.getBenefitPrecent() != null && oldBenefittingOrg.getBenefitPrecent() == null) || (benefittingOrganization.getBenefitPrecent() != null && oldBenefittingOrg.getBenefitPrecent() != null && benefittingOrganization.getBenefitPrecent().compareTo(oldBenefittingOrg.getBenefitPrecent()) != 0);
186
187
188 }
189
190 if (isBenefitPctChanged || benefittingOrganization.isNewCollectionRecord()) {
191 Date lastChangeDate;
192 try {
193 lastChangeDate = dateTimeService.convertToSqlDate(kemService.getCurrentSystemProcessDate());
194 benefittingOrganization.setLastChangeDate(lastChangeDate);
195 }
196 catch (ParseException ex) {
197 // do nothing
198 }
199
200 }
201 }
202 }
203 }
204
205 }
206
207 /**
208 * Updates the necessary fields on the Benefitting organizations like the sequence numbers and the last change date.
209 *
210 * @param maintenanceDocument
211 */
212 private void updateBenefittingOrgs(MaintenanceDocument maintenanceDocument) {
213 // the order in which these methods are called should be preserved
214 setBenefittingOrgsSeq();
215 setBenefittingOrgsLastChangeDate(maintenanceDocument);
216 }
217
218 /**
219 * Sets the Authorizations sequence number for all the new Authorizations.
220 */
221 private void setAuthorizationsSeqNbr() {
222 List<KemidAuthorizations> oldKemidAuthorizations = new ArrayList<KemidAuthorizations>();
223 List<KemidAuthorizations> newKemidAuthorizations = new ArrayList<KemidAuthorizations>();
224
225
226 for (KemidAuthorizations kemidAuthorizations : newKemid.getKemidAuthorizations()) {
227 if (kemidAuthorizations.isNewCollectionRecord()) {
228 newKemidAuthorizations.add(kemidAuthorizations);
229 }
230 else {
231 oldKemidAuthorizations.add(kemidAuthorizations);
232 }
233 }
234
235 int sequenceStart = oldKemidAuthorizations.size();
236
237 for (KemidAuthorizations kemidAuthorizations : newKemidAuthorizations) {
238 kemidAuthorizations.setRoleSequenceNumber(new KualiInteger(++sequenceStart));
239 }
240
241 }
242
243 /**
244 * Updates the necessary fields on the Authorizations like the sequence numbers and the role termination date.
245 *
246 * @param maintenanceDocument
247 */
248 private void updateAuthorizations(MaintenanceDocument maintenanceDocument) {
249 // the order in which these methods are called should be preserved
250 setAuthorizationsSeqNbr();
251 setAuthorizationsTerminationDate(maintenanceDocument);
252 }
253
254 /**
255 * Sets the role termination date to current date if authorization has been inactivated.
256 *
257 * @param maintenanceDocument
258 */
259 private void setAuthorizationsTerminationDate(MaintenanceDocument maintenanceDocument) {
260 KEMService kemService = SpringContext.getBean(KEMService.class);
261 DateTimeService dateTimeService = SpringContext.getBean(DateTimeService.class);
262
263 if (KNSConstants.MAINTENANCE_EDIT_ACTION.equals(maintenanceDocument.getNewMaintainableObject().getMaintenanceAction())) {
264 if (newKemid.getKemidAuthorizations().size() != 0) {
265
266 Map<KualiInteger, KemidAuthorizations> oldKemidAuthorizations = new HashMap<KualiInteger, KemidAuthorizations>();
267
268 if (oldKemid.getKemidAuthorizations().size() != 0) {
269 for (KemidAuthorizations authorization : oldKemid.getKemidAuthorizations()) {
270 oldKemidAuthorizations.put(authorization.getRoleSequenceNumber(), authorization);
271 }
272 }
273
274 for (KemidAuthorizations authorization : newKemid.getKemidAuthorizations()) {
275 KemidAuthorizations oldAuthorization = oldKemidAuthorizations.get(authorization.getRoleSequenceNumber());
276
277 boolean isActiveIndChanged = false;
278 if (ObjectUtils.isNotNull(oldAuthorization)) {
279 isActiveIndChanged = (!authorization.isActive() && oldAuthorization.isActive());
280
281 }
282
283 if (isActiveIndChanged) {
284 authorization.setRoleTerminationDate(kemService.getCurrentDate());
285 }
286 }
287 }
288 }
289 }
290
291 /**
292 * Sets the payout instructions sequence number for all the new payout instructions.
293 */
294 private void setPayoutInstructionsSeq() {
295 List<KemidPayoutInstruction> oldKemidPayoutInstructions = new ArrayList<KemidPayoutInstruction>();
296 List<KemidPayoutInstruction> newKemidPayoutInstructions = new ArrayList<KemidPayoutInstruction>();
297
298
299 for (KemidPayoutInstruction kemidPayoutInstruction : newKemid.getKemidPayoutInstructions()) {
300 if (kemidPayoutInstruction.isNewCollectionRecord()) {
301 newKemidPayoutInstructions.add(kemidPayoutInstruction);
302 }
303 else {
304 oldKemidPayoutInstructions.add(kemidPayoutInstruction);
305 }
306 }
307
308 int sequenceStart = oldKemidPayoutInstructions.size();
309
310 for (KemidPayoutInstruction kemidPayoutInstruction : newKemidPayoutInstructions) {
311 kemidPayoutInstruction.setPayoutIncomeSequenceNumber(new KualiInteger(++sequenceStart));
312 }
313
314 }
315
316 /**
317 * Sets the use criteria sequence number for all the new sources of funds.
318 */
319 private void setUseCriteriaSeq() {
320 List<KemidUseCriteria> oldKemidUseCriteria = new ArrayList<KemidUseCriteria>();
321 List<KemidUseCriteria> newKemidUseCriteria = new ArrayList<KemidUseCriteria>();
322
323
324 for (KemidUseCriteria useCriteria : newKemid.getKemidUseCriteria()) {
325 if (useCriteria.isNewCollectionRecord()) {
326 newKemidUseCriteria.add(useCriteria);
327 }
328 else {
329 oldKemidUseCriteria.add(useCriteria);
330 }
331 }
332
333 int sequenceStart = oldKemidUseCriteria.size();
334
335 for (KemidUseCriteria useCriteria : newKemidUseCriteria) {
336 useCriteria.setUseCriteriaSeq(new KualiInteger(++sequenceStart));
337 }
338
339 }
340
341 /**
342 * Sets the fee method sequence for all the new fees as the next sequencial number.
343 */
344 private void setFeeMethodSequence() {
345 List<KemidFee> oldFees = new ArrayList<KemidFee>();
346 List<KemidFee> newFees = new ArrayList<KemidFee>();
347
348
349 for (KemidFee kemidFee : newKemid.getKemidFees()) {
350 if (kemidFee.isNewCollectionRecord()) {
351 newFees.add(kemidFee);
352 }
353 else {
354 oldFees.add(kemidFee);
355 }
356 }
357
358 int sequenceStart = oldFees.size();
359
360 for (KemidFee fee : newFees) {
361 fee.setFeeMethodSeq(new KualiInteger(++sequenceStart));
362 }
363
364 }
365
366 /**
367 * Sets the fee method sequence for all the new fees as the next sequencial number.
368 */
369 private void setReportGroupSequence() {
370 List<KemidReportGroup> oldReportGroups = new ArrayList<KemidReportGroup>();
371 List<KemidReportGroup> newReportGroups = new ArrayList<KemidReportGroup>();
372
373
374 for (KemidReportGroup kemidReportGroup : newKemid.getKemidReportGroups()) {
375 if (kemidReportGroup.isNewCollectionRecord()) {
376 newReportGroups.add(kemidReportGroup);
377 }
378 else {
379 oldReportGroups.add(kemidReportGroup);
380 }
381 }
382
383 int sequenceStart = oldReportGroups.size();
384
385 for (KemidReportGroup reportGroup : newReportGroups) {
386 reportGroup.setCombineGroupSeq(new KualiInteger(++sequenceStart));
387 }
388
389 }
390
391 /**
392 * Sets the special instruction sequence for all the new special instructions as the next sequencial number.
393 */
394 private void setSpecialInstructionSeq() {
395 List<KemidSpecialInstruction> oldSpecialInstructions = new ArrayList<KemidSpecialInstruction>();
396 List<KemidSpecialInstruction> newSpecialInstructions = new ArrayList<KemidSpecialInstruction>();
397
398
399 for (KemidSpecialInstruction kemidSpecialInstruction : newKemid.getKemidSpecialInstructions()) {
400 if (kemidSpecialInstruction.isNewCollectionRecord()) {
401 newSpecialInstructions.add(kemidSpecialInstruction);
402 }
403 else {
404 oldSpecialInstructions.add(kemidSpecialInstruction);
405 }
406 }
407
408 int sequenceStart = oldSpecialInstructions.size();
409
410 for (KemidSpecialInstruction specialInstruction : newSpecialInstructions) {
411 specialInstruction.setInstructionSeq(new KualiInteger(++sequenceStart));
412 }
413
414 }
415
416 /**
417 * Sets the donor sequence for all the new donor statements as the next sequencial number.
418 */
419 private void setDonorStatementsSeq() {
420 List<KemidDonorStatement> oldDonorStatement = new ArrayList<KemidDonorStatement>();
421 List<KemidDonorStatement> newDonorStatement = new ArrayList<KemidDonorStatement>();
422
423
424 for (KemidDonorStatement donorStatement : newKemid.getKemidDonorStatements()) {
425 if (donorStatement.isNewCollectionRecord()) {
426 newDonorStatement.add(donorStatement);
427 }
428 else {
429 oldDonorStatement.add(donorStatement);
430 }
431 }
432
433 int sequenceStart = oldDonorStatement.size();
434
435 for (KemidDonorStatement donorStatement : newDonorStatement) {
436 donorStatement.setDonorSeq(new KualiInteger(++sequenceStart));
437 }
438
439 }
440
441 /**
442 * Sets the combine donor sequence for all the new combine donor statements as the next sequencial number.
443 */
444 private void setCombineDonorSeq() {
445 List<KemidCombineDonorStatement> oldCombineDonorStatement = new ArrayList<KemidCombineDonorStatement>();
446 List<KemidCombineDonorStatement> newCombineDonorStatement = new ArrayList<KemidCombineDonorStatement>();
447
448
449 for (KemidCombineDonorStatement combineDonorStatement : newKemid.getKemidCombineDonorStatements()) {
450 if (combineDonorStatement.isNewCollectionRecord()) {
451 newCombineDonorStatement.add(combineDonorStatement);
452 }
453 else {
454 oldCombineDonorStatement.add(combineDonorStatement);
455 }
456 }
457
458 int sequenceStart = oldCombineDonorStatement.size();
459
460 for (KemidCombineDonorStatement combineDonorStatement : newCombineDonorStatement) {
461 combineDonorStatement.setCombineDonorSeq(new KualiInteger(++sequenceStart));
462 }
463
464 }
465
466 /**
467 * Sets the old and new Kemid values.
468 *
469 * @param document
470 */
471 private void setupConvenienceObjects(MaintenanceDocument document) {
472
473 // setup newSecurity convenience objects, make sure all possible sub-objects are populated
474 newKemid = (KEMID) document.getNewMaintainableObject().getBusinessObject();
475 oldKemid = (KEMID) document.getOldMaintainableObject().getBusinessObject();
476 newKemid.refreshNonUpdateableReferences();
477 }
478
479 }