/**
* This file is part of Pau's Asset Manager Project.
*
* Pau's Asset Manager Project 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
* (at your option) any later version.
*
* Pau's Asset Manager Project 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 Pau's Asset Manager Project. If not, see <http://www.gnu.org/licenses/>.
*/
package org.pau.assetmanager.entities;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Transient;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.pau.assetmanager.business.TimeDependentConstantsBusiness;
import org.pau.assetmanager.utils.AssetManagerRuntimeException;
import org.pau.assetmanager.viewmodel.type.TimeDependentConstantType;
import org.zkoss.bind.annotation.NotifyChange;
/**
* This class represents expenses annotations for a property book
*
* @author Pau Carré Cardona
*
*/
@Entity
@DiscriminatorValue("PROPERTY_EXPENSES")
public class PropertyExpensesAnnotation extends ExpensesAnnotation implements
EntityInterface, Serializable {
private static final Logger logger = LogManager
.getLogger(PropertyExpensesAnnotation.class);
private static final long serialVersionUID = 1L;
public static final Long DEFAULT_DEDUCTIBLE_PERCENTAGE = 100L * 100L; // 100%
public static final Boolean DEFAULT_USE_QUARTERLY = true;
public static final Boolean DEFAULT_COMUNNITY = false;
public PropertyExpensesAnnotation() {
super();
}
/**
* This class represents the default values retrieved by the database It is
* not possible to include that part of the code directly in the constructor
* as it will generate a 'recursive dependency' in the initialization of JPA
* which will generate an infinite recursive loop. When creating brand new
* PropertyExpensesAnnotation, it is necessary to call this method if one
* wants to fill the fields with default values.
*/
@Transient
public void setUpDefaults() {
community = DEFAULT_COMUNNITY;
useQuarterly = DEFAULT_USE_QUARTERLY;
deductiblePercentage = DEFAULT_DEDUCTIBLE_PERCENTAGE;
vat = TimeDependentConstantsBusiness
.getTimeDependentConstantValueByTimeDependentConstantType(
TimeDependentConstantType.DEFAULT_VAT)
.getNumericalValue();
}
/**
* The VAT value payed for this annotation (usually it is the DEFAULT_VAT,
* but not always).
*/
protected Long vat;
/**
* Percentage of the annotation that can be deduced in the annotation for
* the Spanish fiscal system
*/
@Column(name = "deductible_percentage", nullable = false)
private Long deductiblePercentage;
/**
* Whether the annotation should be applied to the quarterly payment in the
* Spanish fiscal system
*/
@Column(name = "use_quarterly", nullable = false, columnDefinition = "TINYINT(1)")
private Boolean useQuarterly;
/**
* Whether this annotation is 'building community' related expense which has
* a different treatment in the Spanish fiscal system.
*/
@Column(name = "community", nullable = false, columnDefinition = "TINYINT(1)")
private Boolean community;
@Transient
public PropertyBook getPropertyBook() {
Book book = this.getBook();
if (book instanceof PropertyBook) {
PropertyBook propertyBook = (PropertyBook) book;
return propertyBook;
}
String message = "The PropertyExpensesAnnotation '" + this.toString()
+ "' has a Book which is not a PropertyBook.";
logger.error(message);
throw new AssetManagerRuntimeException(message);
}
/**
* @return the amount of money that should be declared for the yearly
* payment in the Spanish fiscal system
*/
@Transient
public Double getDeclaredYearly() {
return this.getBaseImponibleYearly()
* (this.getDeductiblePercentage() / 100.0);
}
/**
* @return the VAT related to the annotation (zero in case the VAT does not
* applies to the annotation)
*/
@Transient
public Double getVat() {
if (getAppliesVAT()) {
return new Double(this.vat) / 100.0;
} else {
return 0.0; // default value in case there is no VAT
}
}
@Override
public void setConcept(String concept) {
super.setConcept(concept);
if (concept != null) {
if (this.getCommunity() == null) {
// set the default community by checking the concept name
Boolean seemsToBeComunity = concept.toUpperCase().contains(
"COMUNIDAD");
this.setCommunity(seemsToBeComunity);
}
}
}
@NotifyChange(".")
public void setVat(Double vat) {
if (vat == null) {
this.vat = 0L;
} else {
if (vat < 0.0) {
vat *= -1.0;
}
if (vat > 100.0) {
vat = 100.0;
}
this.vat = Math.round(vat * 100.0);
}
}
/**
* @return the tax base for the yearly payment in the Spanish fiscal
* system.
*/
@Transient
public Double getBaseImponibleYearly() {
Double baseImponible = 0.0;
if (getAppliesToQuarterly()) {
// it has been used in the quarterly, so in the yearly we skip the VAT
baseImponible = this.getBaseImponibleQuarterly();
}else{
// it has not been used in the quarterly, so we add the whole value (VAT included)
baseImponible = this.getAmount();
}
return baseImponible;
}
/**
* @return whether the VAT applies to the annotation or not.
*/
@Transient
public Boolean getAppliesVAT() {
return !getCommunity();
}
/**
* @return the general tax base of the annotation
*/
@Transient
public Double getBaseImponibleQuarterly() {
if (getAppliesToQuarterly()) {
// if the vat can be applied and the quarterly is active, then remove the VAT to the amount
Double amountFacturado = getAmount();
Double factor = (100.0 + this.getVat()) / 100.0;
return amountFacturado / factor;
} else {
// if the amount can not be applied for the quarterly, just return zero
return 0.0;
}
}
@Transient
public boolean getAppliesToQuarterly(){
return getAppliesVAT() && this.getUseQuarterly();
}
public Boolean getCommunity() {
return community;
}
public Double getDeductiblePercentage() {
if (this.deductiblePercentage == null) {
return 0.0;
} else {
return new Double(this.deductiblePercentage) / 100.0;
}
}
@NotifyChange(".")
public void setDeductiblePercentage(Double deductiblePercentage) {
if (deductiblePercentage == null) {
this.deductiblePercentage = 0L;
} else {
if (deductiblePercentage < 0.0) {
deductiblePercentage *= -1.0;
}
if (deductiblePercentage > 100.0) {
deductiblePercentage = 100.0;
}
this.deductiblePercentage = Math.round(deductiblePercentage * 100L);
}
}
@NotifyChange(".")
public void setCommunity(Boolean community) {
if (community) {
this.useQuarterly = false;
}
this.community = community;
}
public Boolean getUseQuarterly() {
return useQuarterly;
}
@NotifyChange(".")
public void setUseQuarterly(Boolean useQuarterly) {
this.useQuarterly = useQuarterly;
}
}