CostDefinition.java

package com.tradecloud.domain.costing;

import com.tradecloud.common.base.PersistenceBase;
import com.tradecloud.domain.common.Incoterm;
import com.tradecloud.domain.configuration.CountryGroup;
import com.tradecloud.domain.model.organisationalunit.OrganisationalUnit;
import com.tradecloud.domain.model.shipment.ShippingMode;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.hibernate.annotations.ForeignKey;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.xml.bind.annotation.*;
import java.util.Set;

/**
 * <p>
 * This defines the <em>costing</em> behaviour of a particular set of cost lines.
 * </p>
 */
@Entity
@Table(name = "costdefinition")
@Inheritance(strategy = InheritanceType.JOINED)
@NamedQueries({
        @NamedQuery(name = "costDefinition.byIncotermAndContext",
                query = "from CostDefinition where incoterm = :incoterm and costingContextType = :costingContextType and active = 't'" +
                        " and costableCostDefinition = 'f' and countryGroup is null"),
        @NamedQuery(name = "costDefinition.byIncoterm", query = "from CostDefinition where incoterm = :incoterm and active = 't'" +
                " and costableCostDefinition = 'f' and countryGroup is null"),
        @NamedQuery(name = "costDefinition.byOrgUnit", query = "from CostDefinition where organisationalUnit = :organisationalUnit" +
                " and active = 't' and costableCostDefinition = 'f' and countryGroup is null"),
        @NamedQuery(name = "costDefinition.byOrgUnits",
                query = "from CostDefinition where organisationalUnit in (:organisationalUnits) and incoterm = :incoterm and" +
                        " costingContextType = :costingContextType and active = 't' and costableCostDefinition = 'f' and countryGroup is null"),
        @NamedQuery(name = "costDefinition.byOrgUnitsOnly",
                query = "from CostDefinition where organisationalUnit in (:organisationalUnits) and" +
                        " active = 't' and costableCostDefinition = 'f' and countryGroup is null"),
        @NamedQuery(name = "costDefinition.allWithIncotermAndNullOrgUnit",
                query = "from CostDefinition cd where incoterm is not null and organisationalUnit is null and active = 't'" +
                        " and costableCostDefinition = 'f' and countryGroup is null"),
        @NamedQuery(name = "costDefinition.allActive", query = "from CostDefinition cd where active = 't' and costableCostDefinition = 'f'"),
        @NamedQuery(name = "costDefinition.all", query = "from CostDefinition cd where costableCostDefinition = 'f'")})

@Access(AccessType.FIELD)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "CostDefinition")
@XmlSeeAlso({CostableCostDefinition.class})
@Getter
@Setter
@SuperBuilder
public class CostDefinition extends PersistenceBase implements Cloneable {

    private static final long serialVersionUID = 1L;
    @XmlAttribute
    protected Boolean active = Boolean.TRUE;
    @ManyToOne
    @XmlElement
    private Incoterm incoterm;

    @ManyToOne
    @XmlElement
    private CountryGroup countryGroup;

    @ManyToOne
    @XmlElement
    private OrganisationalUnit organisationalUnit;
    @XmlElementWrapper(name = "CostLines")
    @XmlElement(name = "CostLine")
    @OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @ForeignKey(name = "fk_costdefinition", inverseName = "fk_costline")
    @JoinTable(name = "costdefinition_costlines",
            joinColumns = {@JoinColumn(name = "costdefinition_id", unique = false)},
            inverseJoinColumns = {@JoinColumn(name = "costline_id", unique = true)})
    private Set<CostLine> costLines;
    @XmlAttribute
    @Enumerated(EnumType.STRING)
    @NotNull
    private CostingContextType costingContextType;

    @Enumerated(value = EnumType.STRING)
    @XmlAttribute
    private ShippingMode shippingMode;

    @Enumerated(EnumType.STRING)
    private ShippingMode multiModalShippingMode;

    private boolean costableCostDefinition;

    public CostDefinition() {
    }

    public Incoterm getIncoterm() {
        return incoterm;
    }

    public void setIncoterm(Incoterm incoterm) {
        this.incoterm = incoterm;
    }

    public OrganisationalUnit getOrganisationalUnit() {
        return organisationalUnit;
    }

    public void setOrganisationalUnit(OrganisationalUnit organisationalUnit) {
        this.organisationalUnit = organisationalUnit;
    }

    public Set<CostLine> getCostLines() {
        return costLines;
    }

    public void setCostLines(Set<CostLine> costLines) {
        this.costLines = costLines;
    }

    public CostingContextType getCostingContextType() {
        return costingContextType;
    }

    public void setCostingContextType(CostingContextType costingContextType) {
        this.costingContextType = costingContextType;
    }

    public CountryGroup getCountryGroup() {
        return countryGroup;
    }

    public void setCountryGroup(CountryGroup countryGroup) {
        this.countryGroup = countryGroup;
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this).append("incoterm", incoterm).append("organisationalUnit", organisationalUnit).append("costingContextType",
                costingContextType).toString();
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder().append(incoterm).append(organisationalUnit)
                .append(costingContextType).append(shippingMode)
                .append(multiModalShippingMode).toHashCode();
    }

    /**
     * Each of the field comparisons in thicostdes equals implementation
     * are done via the getter methods.
     *
     * The reason being that sometimes it is possible that we are
     * dealing with Hibernate proxied objects and therefore the field
     * values aren't populated until accessed via the getter method
     * for that field.
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof CostDefinition)) {
            return false;
        }
        CostDefinition other = (CostDefinition) obj;
        return new EqualsBuilder().append(incoterm, other.incoterm).append(organisationalUnit, other.organisationalUnit).
                append(shippingMode, other.shippingMode).append(multiModalShippingMode, other.multiModalShippingMode).
                append(costingContextType, other.costingContextType).isEquals();
    }

    public boolean isCostableCostDefinition() {
        return costableCostDefinition;
    }

    public void setCostableCostDefinition(boolean costableCostDefinition) {
        this.costableCostDefinition = costableCostDefinition;
    }

    @Override
    public Boolean getActive() {
        return active;
    }

    public void setActive(Boolean active) {
        this.active = active;
    }
}