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 }