/* * eGov suite of products aim to improve the internal efficiency,transparency, * accountability and the service delivery of the government organizations. * * Copyright (C) <2015> eGovernments Foundation * * The updated version of eGov suite of products as by eGovernments Foundation * is available at http://www.egovernments.org * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/ or * http://www.gnu.org/licenses/gpl.html . * * In addition to the terms of the GPL license to be adhered to in using this * program, the following additional terms are to be complied with: * * 1) All versions of this program, verbatim or modified must carry this * Legal Notice. * * 2) Any misrepresentation of the origin of the material is prohibited. It * is required that all modified versions of this material be marked in * reasonable ways as different from the original version. * * 3) This license does not grant any rights to any user of the program * with regards to rights under trademark law for use of the trade names * or trademarks of eGovernments Foundation. * * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. */ package org.egov.demand.model; import org.egov.commons.EgwStatus; import org.egov.infra.exception.ApplicationRuntimeException; import java.io.Serializable; import java.math.BigDecimal; import java.util.Date; import java.util.HashSet; import java.util.Set; /** * EgDemandDetails entity. * * @author Sathish Reddy K */ public class EgDemandDetails implements Serializable, Cloneable { private Long id; private EgDemandReason egDemandReason; private EgwStatus egwStatus; private String fileReferenceNo; private String remarks; private BigDecimal amount = BigDecimal.ZERO; private Date modifiedDate; private Date createDate; private BigDecimal amtCollected = BigDecimal.ZERO; private Set<EgdmCollectedReceipt> egdmCollectedReceipts = new HashSet<EgdmCollectedReceipt>(); private BigDecimal amtRebate = BigDecimal.ZERO; private EgDemand egDemand; private static final BigDecimal ONE_PAISA_TOLERANCE_FOR_ADDCOLLECTED = new BigDecimal("0.01"); @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((id == null) ? 0 : id.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } EgDemandDetails other = (EgDemandDetails) obj; if (id == null) { return false; } if (other.id == null) { return false; } if (id.equals(other.id)) { return true; } return false; } /** * Returns a copy that can be associated with another EgDemand. The copy has * the same amounts, reason, time stamp and (cloned) receipts if any. (Note: * making it public instead of protected to allow any class to use it.) */ @Override public Object clone() { EgDemandDetails clone = null; try { clone = (EgDemandDetails) super.clone(); } catch (CloneNotSupportedException e) { // this should never happen throw new InternalError(e.toString()); } clone.setId(null); clone.setEgwStatus(null); clone.setEgdmCollectedReceipts(new HashSet<EgdmCollectedReceipt>()); //Commented as it is trying to update the actual EgdmCollectedReceipt while persisting the cloned demand details /*for (EgdmCollectedReceipt receipt : getEgdmCollectedReceipts()) { EgdmCollectedReceipt cloneCollectedReceipt = (EgdmCollectedReceipt) receipt.clone(); cloneCollectedReceipt.setEgdemandDetail(clone); clone.addEgdmCollectedReceipt(cloneCollectedReceipt); }*/ return clone; } /** * Returns <code>true</code> if demand exceeds collection, * <code>false</code> otherwise. */ public boolean hasOutstandingCollection() { if (getAmtCollected() == null || getAmount().compareTo(getAmtCollected()) > 0) { return true; } else { return false; } } public Long getId() { return this.id; } public void setId(Long id) { this.id = id; } public EgDemandReason getEgDemandReason() { return egDemandReason; } public void setEgDemandReason(EgDemandReason egDemandReason) { this.egDemandReason = egDemandReason; } public EgwStatus getEgwStatus() { return egwStatus; } public void setEgwStatus(EgwStatus egwStatus) { this.egwStatus = egwStatus; } public String getFileReferenceNo() { return this.fileReferenceNo; } public void setFileReferenceNo(String fileReferenceNo) { this.fileReferenceNo = fileReferenceNo; } public String getRemarks() { return this.remarks; } public void setRemarks(String remarks) { this.remarks = remarks; } public BigDecimal getAmount() { return this.amount; } public void setAmount(BigDecimal amount) { this.amount = amount; } public BigDecimal getAmtCollected() { return amtCollected; } public void setAmtCollected(BigDecimal amtCollected) { this.amtCollected = amtCollected; } public Set<EgdmCollectedReceipt> getEgdmCollectedReceipts() { return egdmCollectedReceipts; } public void setEgdmCollectedReceipts(Set<EgdmCollectedReceipt> egdmCollectedReceipt) { this.egdmCollectedReceipts = egdmCollectedReceipt; } public void addEgdmCollectedReceipt(EgdmCollectedReceipt egdmCollectedReceipt) { getEgdmCollectedReceipts().add(egdmCollectedReceipt); } public void removeEgdmCollectedReceipt(EgdmCollectedReceipt egdmCollectedReceipt) { getEgdmCollectedReceipts().remove(egdmCollectedReceipt); } public String toString() { StringBuilder sb = new StringBuilder(); sb.append("").append(amount).append("*").append(amtCollected).append("*").append( egDemandReason).append("*").append(amtRebate); return sb.toString(); } public Date getModifiedDate() { return modifiedDate; } public void setModifiedDate(Date modifiedDate) { this.modifiedDate = modifiedDate; } public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; } /** * Factory method for convenient creation. */ public static EgDemandDetails fromReasonAndAmounts(BigDecimal demandAmount, EgDemandReason egDemandReason, BigDecimal collectedAmount) { EgDemandDetails dd = new EgDemandDetails(); dd.setAmount(demandAmount); dd.setEgDemandReason(egDemandReason); dd.setAmtCollected(collectedAmount); dd.setModifiedDate(new Date()); dd.setCreateDate(new Date()); return dd; } /** * Add an amount to the existing collected amount, allowing a "tolerance" of exceeding the balance. */ public void addCollectedWithTolerance(BigDecimal amount, BigDecimal tolerance) { BigDecimal collected = getAmtCollected() != null ? getAmtCollected() : BigDecimal.ZERO; if (amount.compareTo( getAmount().subtract(collected).add(tolerance) ) > 0) { throw new ApplicationRuntimeException("Amount being added " + amount + " is greater than " + getAmount() + " - " + collected + " + tolerance " + tolerance + ", for demand detail " + this.toString()); } else { setAmtCollected(collected.add(amount)); } } /** * Add an amount to the existing collected amount, with zero tolerance i.e. balance cannot be exceeded. */ public void addCollected(BigDecimal amount) { addCollectedWithTolerance(amount, BigDecimal.ZERO); } /** * Add an amount to the existing collected amount, with a tolerance of one paisa i.e. balance can be * exceeded by 1 paisa. This can be used when split amounts are being calculated by MoneyUtils.allocate(), where * amounts may be off by 1 paisa. */ public void addCollectedWithOnePaisaTolerance(BigDecimal amount) { addCollectedWithTolerance(amount, ONE_PAISA_TOLERANCE_FOR_ADDCOLLECTED); } public BigDecimal getAmtRebate() { return amtRebate; } public void setAmtRebate(BigDecimal amtRebate) { this.amtRebate = amtRebate; } public void addRebateAmt(BigDecimal rebateAmt) { if (getAmtRebate() != null) { setAmtRebate(getAmtRebate().add(rebateAmt != null ? rebateAmt : BigDecimal.ZERO)); } else { setAmtRebate(rebateAmt); } } public EgDemand getEgDemand() { return egDemand; } public void setEgDemand(EgDemand egDemand) { this.egDemand = egDemand; } public BigDecimal getBalance() { return getAmount().subtract(getAmtCollected() != null ? getAmtCollected() : BigDecimal.ZERO); } public Date getInstallmentStartDate() { return getEgDemandReason().getEgInstallmentMaster().getFromDate(); } public Date getInstallmentEndDate() { return getEgDemandReason().getEgInstallmentMaster().getToDate(); } public String getReasonCategory() { return getEgDemandReason().getEgDemandReasonMaster().getEgReasonCategory().getCode(); } }