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.service.impl; 017 018 import java.math.BigDecimal; 019 import java.util.ArrayList; 020 import java.util.List; 021 022 import org.kuali.kfs.module.endow.businessobject.EndowmentTransactionLine; 023 import org.kuali.kfs.module.endow.businessobject.EndowmentTransactionSecurity; 024 import org.kuali.kfs.module.endow.businessobject.EndowmentTransactionTaxLotLine; 025 import org.kuali.kfs.module.endow.businessobject.HoldingTaxLot; 026 import org.kuali.kfs.module.endow.businessobject.Security; 027 import org.kuali.kfs.module.endow.document.EndowmentUnitShareAdjustmentDocument; 028 import org.kuali.kfs.module.endow.document.service.HoldingTaxLotService; 029 import org.kuali.kfs.module.endow.document.service.SecurityService; 030 import org.kuali.kfs.module.endow.document.service.UpdateUnitShareAdjustmentDocumentTaxLotsService; 031 import org.kuali.kfs.module.endow.util.KEMCalculationRoundingHelper; 032 import org.kuali.rice.kns.util.ObjectUtils; 033 034 public class UpdateUnitShareAdjustmentDocumentTaxLotsServiceImpl implements UpdateUnitShareAdjustmentDocumentTaxLotsService { 035 036 private HoldingTaxLotService taxLotService; 037 private SecurityService securityService; 038 039 /** 040 * @see org.kuali.kfs.module.endow.document.service.UpdateUnitShareAdjustmentDocumentTaxLotsService#updateTransactionLineTaxLots(boolean, 041 * org.kuali.kfs.module.endow.document.EndowmentUnitShareAdjustmentDocument, 042 * org.kuali.kfs.module.endow.businessobject.EndowmentTransactionLine, boolean) 043 */ 044 public void updateTransactionLineTaxLots(boolean isUpdate, EndowmentUnitShareAdjustmentDocument unitShareAdjustmentDocument, EndowmentTransactionLine transLine, boolean isSource) { 045 EndowmentTransactionSecurity endowmentTransactionSecurity = unitShareAdjustmentDocument.getSourceTransactionSecurity(); 046 047 Security security = securityService.getByPrimaryKey(endowmentTransactionSecurity.getSecurityID()); 048 if (ObjectUtils.isNotNull(security)) { 049 050 List<HoldingTaxLot> holdingTaxLots = new ArrayList<HoldingTaxLot>(); 051 052 if (isUpdate) { 053 List<EndowmentTransactionTaxLotLine> existingTransactionLines = transLine.getTaxLotLines(); 054 for (EndowmentTransactionTaxLotLine endowmentTransactionTaxLotLine : existingTransactionLines) { 055 HoldingTaxLot holdingTaxLot = taxLotService.getByPrimaryKey(transLine.getKemid(), endowmentTransactionSecurity.getSecurityID(), endowmentTransactionSecurity.getRegistrationCode(), endowmentTransactionTaxLotLine.getTransactionHoldingLotNumber(), transLine.getTransactionIPIndicatorCode()); 056 057 if (ObjectUtils.isNotNull(holdingTaxLot)) { 058 holdingTaxLots.add(holdingTaxLot); 059 } 060 } 061 062 transLine.getTaxLotLines().clear(); 063 } 064 else { 065 transLine.getTaxLotLines().clear(); 066 holdingTaxLots = taxLotService.getAllTaxLotsWithPositiveUnits(transLine.getKemid(), endowmentTransactionSecurity.getSecurityID(), endowmentTransactionSecurity.getRegistrationCode(), transLine.getTransactionIPIndicatorCode()); 067 } 068 069 BigDecimal taxLotsTotalUnits = BigDecimal.ZERO; 070 071 if (holdingTaxLots != null) { 072 for (HoldingTaxLot holdingTaxLot : holdingTaxLots) { 073 EndowmentTransactionTaxLotLine endowmentTransactionTaxLotLine = new EndowmentTransactionTaxLotLine(); 074 endowmentTransactionTaxLotLine.setDocumentNumber(unitShareAdjustmentDocument.getDocumentNumber()); 075 endowmentTransactionTaxLotLine.setDocumentLineNumber(transLine.getTransactionLineNumber()); 076 endowmentTransactionTaxLotLine.setTransactionHoldingLotNumber(holdingTaxLot.getLotNumber().intValue()); 077 endowmentTransactionTaxLotLine.setKemid(transLine.getKemid()); 078 endowmentTransactionTaxLotLine.setSecurityID(holdingTaxLot.getSecurityId()); 079 endowmentTransactionTaxLotLine.setRegistrationCode(holdingTaxLot.getRegistrationCode()); 080 endowmentTransactionTaxLotLine.setIpIndicator(holdingTaxLot.getIncomePrincipalIndicator()); 081 endowmentTransactionTaxLotLine.setLotAcquiredDate(holdingTaxLot.getAcquiredDate()); 082 // set it just for future computation 083 endowmentTransactionTaxLotLine.setLotUnits(holdingTaxLot.getUnits()); 084 transLine.getTaxLotLines().add(endowmentTransactionTaxLotLine); 085 086 taxLotsTotalUnits = taxLotsTotalUnits.add(holdingTaxLot.getUnits()); 087 088 // set the new lot indicator 089 endowmentTransactionTaxLotLine.setNewLotIndicator(false); 090 } 091 } 092 093 if (transLine.getTaxLotLines() != null) { 094 BigDecimal totalUnits = BigDecimal.ZERO; 095 096 EndowmentTransactionTaxLotLine oldestTaxLot = null; 097 for (EndowmentTransactionTaxLotLine endowmentTransactionTaxLotLine : transLine.getTaxLotLines()) { 098 if (endowmentTransactionTaxLotLine.getTransactionHoldingLotNumber().compareTo(1) != 0) { 099 oldestTaxLot = endowmentTransactionTaxLotLine; 100 } 101 BigDecimal percentage = KEMCalculationRoundingHelper.divide(endowmentTransactionTaxLotLine.getLotUnits(), taxLotsTotalUnits, 5); 102 endowmentTransactionTaxLotLine.setLotUnits(KEMCalculationRoundingHelper.multiply(percentage, transLine.getTransactionUnits().bigDecimalValue(), 0)); 103 104 totalUnits = totalUnits.add(endowmentTransactionTaxLotLine.getLotUnits()); 105 106 if (isSource) { 107 endowmentTransactionTaxLotLine.setLotUnits(endowmentTransactionTaxLotLine.getLotUnits().negate()); 108 } 109 } 110 111 BigDecimal transLineUnits = transLine.getTransactionUnits().bigDecimalValue(); 112 adjustTaxLotsUnits(totalUnits, transLineUnits, oldestTaxLot, isSource); 113 } 114 } 115 } 116 117 118 /** 119 * Adjusts the oldest tax lot units if the transaction line units do not match the total of the tax lot units. 120 * 121 * @param totalTaxLotsUnits 122 * @param transLineUnits 123 * @param oldestTaxLot 124 * @param isSource 125 */ 126 private void adjustTaxLotsUnits(BigDecimal totalTaxLotsUnits, BigDecimal transLineUnits, EndowmentTransactionTaxLotLine oldestTaxLot, boolean isSource) { 127 128 if (totalTaxLotsUnits.compareTo(transLineUnits) != 0 && oldestTaxLot != null) { 129 BigDecimal diff = transLineUnits.subtract(totalTaxLotsUnits); 130 131 if (isSource) { 132 oldestTaxLot.setLotUnits(oldestTaxLot.getLotUnits().add(diff.negate())); 133 } 134 else { 135 oldestTaxLot.setLotUnits(oldestTaxLot.getLotUnits().add(diff)); 136 } 137 } 138 139 } 140 141 /** 142 * Gets the taxLotService. 143 * 144 * @return taxLotService 145 */ 146 public HoldingTaxLotService getTaxLotService() { 147 return taxLotService; 148 } 149 150 /** 151 * Sets the taxLotService. 152 * 153 * @param taxLotService 154 */ 155 public void setTaxLotService(HoldingTaxLotService taxLotService) { 156 this.taxLotService = taxLotService; 157 } 158 159 /** 160 * Gets the securityService. 161 * 162 * @return securityService 163 */ 164 public SecurityService getSecurityService() { 165 return securityService; 166 } 167 168 /** 169 * Sets the securityService. 170 * 171 * @param securityService 172 */ 173 public void setSecurityService(SecurityService securityService) { 174 this.securityService = securityService; 175 } 176 177 }