CostLine.java

package com.tradecloud.domain.costing;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.tradecloud.common.base.HibernateUtils;
import com.tradecloud.common.base.PersistenceBase;
import com.tradecloud.domain.common.Currency;
import com.tradecloud.domain.model.payment.PaymentTerm;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.hibernate.annotations.ForeignKey;

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

/**
 * Entity for cost line details.
 */
@Entity
@Table(name = "costline")
@NamedQueries({@NamedQuery(name = "costLine.byCostGroup", query = "from CostLine where costLineTemplate.costGroup = :costGroup")})
@Access(AccessType.FIELD)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "CostLine")
public class CostLine extends PersistenceBase implements Serializable, Comparable<CostLine> {

    private static final long serialVersionUID = 1L;

    @ManyToOne
    @ForeignKey(name = "fk_costlinetemplate")
    @NotNull
    @XmlElement(name = "CostLineTemplate")
    @JsonIgnore
    private CostLineTemplate costLineTemplate;

    @ManyToOne
    @ForeignKey(name = "fk_transactioncurrency")
    @XmlElement(name = "TransactionCurrency")
    private Currency transactionCurrency;

    /**
     * How the unit costs are allocated from the total. By value, weight or
     * volume.
     */
    @NotNull
    @Enumerated(value = EnumType.STRING)
    @XmlAttribute
    private CostAllocationMethod costAllocationMethod;

    @XmlAttribute
    private boolean treasuryIntegrated;

    @XmlAttribute
    private String overRideCostLineName;

    private boolean clcMinimumCostRequired;

    private boolean alcMinimumCostRequired;
    /**
     * Flag to indicate if this cost line is editable (to change the cost line
     * transaction amount or currency) on the Estimate Cost Summary page (CLC) e.g.
     * Supply direct costs are not editable and most/all other cost lines are
     * editable {@link https://jira.devstream.net/browse/BTM-466 On cost sheet
     * the amount should be editable}
     */
    @XmlAttribute
    private boolean clcEditableCost;
    /**
     * Represents the party responsible for the payment of this cost line.
     * Defaults to {@link CostLinePayerType#EXPORTER}.
     */
    @NotNull
    @Enumerated(value = EnumType.STRING)
    @XmlAttribute
    private CostLinePayerType costLinePayerType;
    /**
     * Determines if VAT is applicable to this cost line or not.
     */
    @NotNull
    @Enumerated(value = EnumType.STRING)
    @XmlAttribute
    private VatType vatType;
    private boolean excludeFromCostTotal;
    private boolean dutiable;
    private boolean excludeFromUnitPerCost;
    private boolean customsWorksheet;
    private boolean customsInvoice;
    @ManyToOne(fetch = FetchType.LAZY)
    private PaymentTerm paymentTerm;
    private String costLineDescription;

    public CostLine() {
    }

    public CostLine(CostLineTemplate costLineTemplate) {
        this.costLineTemplate = costLineTemplate;
    }

    public CostLine(CostLineTemplate costLineTemplate, CostLinePayerType costLinePayerType) {
        this(costLineTemplate);
        this.costLinePayerType = costLinePayerType;
    }

    public String getOverRideCostLineName() {
        return overRideCostLineName;
    }

    public void setOverRideCostLineName(String overRideCostLineName) {
        this.overRideCostLineName = overRideCostLineName;
    }

    public CostLineTemplate getCostLineTemplate() {
        return costLineTemplate;
    }

    public void setCostLineTemplate(CostLineTemplate costLineTemplate) {
        this.costLineTemplate = costLineTemplate;
    }

    public Currency getTransactionCurrency() {
        return transactionCurrency;
    }

    public void setTransactionCurrency(Currency transactionCurrency) {
        this.transactionCurrency = transactionCurrency;
    }

    public CostAllocationMethod getCostAllocationMethod() {
        return costAllocationMethod;
    }

    public void setCostAllocationMethod(CostAllocationMethod costAllocationMethod) {
        this.costAllocationMethod = costAllocationMethod;
    }

    public boolean isTreasuryIntegrated() {
        return treasuryIntegrated;
    }

    public void setTreasuryIntegrated(boolean treasuryIntegrated) {
        this.treasuryIntegrated = treasuryIntegrated;
    }

    public CostLinePayerType getCostLinePayerType() {
        return costLinePayerType;
    }

    public void setCostLinePayerType(CostLinePayerType costLinePayerType) {
        this.costLinePayerType = costLinePayerType;
    }

    public VatType getVatType() {
        return vatType;
    }

    public void setVatType(VatType vatType) {
        this.vatType = vatType;
    }

    public boolean showVat() {
        return vatType == VatType.VAT;
    }

    public boolean isClcEditableCost() {
        return clcEditableCost;
    }

    public void setClcEditableCost(boolean clcEditableCost) {
        this.clcEditableCost = clcEditableCost;
    }

    /**
     * Query method to return flag to indicate if this cost line is a discount
     * cost line, this means the value will be displayed as a negative one on
     * the Estimate Cost Summary page e.g. Explicitly only the EXWorks :
     * Discount cost line is a discount at time of implementation - request to
     * not be configurable. {@link https://jira.devstream.net/browse/BTM-863}
     * Costing: Discount should be a negative value} Hard-coded check based on
     * the cost line name as requested
     * {@link https://jira.devstream.net/browse/BTM-863?focusedCommentId=58751}
     *
     * @return true if cost line is EXWorks : Discount cost line return true.
     * Otherwise, false.
     */
    public boolean isDiscountCost() {
        return costLineTemplate.isDiscount();
    }

    /**
     * Query method to return flag to indicate if this cost line is an editable
     * cost line, this means the transaction amount value can be edited on
     * the Actual Cost Summary page e.g. Explicitly only the Internal Provisions
     * Cost Group cost lines can be edited at time of implementation - request to
     * not be configurable.
     * {@link https://jira.devstream.net/browse/BTM-1011 ALC screen}
     * "editing of the transaction amounts of cost lines under the Internal Provisions cost group only"
     * Hard-coded check based on the cost line name as requested
     * {@link https://jira.devstream.net/browse/BTM-1011?focusedCommentId=59869}
     *
     * @return true if cost line is in the Internal Provisions cost group return true.
     * Otherwise, false.
     */
    public boolean isAlcEditableCost() {
        if (costLineTemplate == null || costLineTemplate.getCostGroup() == null) {
            return false;
        }

        return Set.of(
                CostGroup.INTERNAL_PROVISIONS,
                CostGroup.TRADE_FINANCE,
                CostGroup.FINANCE
        ).contains(costLineTemplate.getCostGroup());
    }

    public boolean isExcludeFromCostTotal() {
        return excludeFromCostTotal;
    }

    public void setExcludeFromCostTotal(boolean excludeFromCostTotal) {
        this.excludeFromCostTotal = excludeFromCostTotal;
    }

    @Override
    public String toString() {
        StringBuilder sb =
                new StringBuilder("costLineTemplate=").append(costLineTemplate).append("," + "" + "" + "transactionCurrency=")
                        .append(transactionCurrency).append(",costAllocationMethod=").append(costAllocationMethod)
                        .append("," + "" + "treasuryIntegrated=").append(treasuryIntegrated).append(",costLinePayerType=").append(costLinePayerType)
                        .append("," + "" + "" + "vatType=").append(vatType);
        return sb.toString();
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder().append(getCostLineTemplate()).append(getCostAllocationMethod()).append(getTransactionCurrency()).toHashCode();
    }

    /**
     * Each of the field comparisons in this 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 (obj == null) {
            return false;
        }
        if (!(obj instanceof CostLine)) {
            return false;
        }
        if (this == obj) {
            return true;
        }
        if (!HibernateUtils.proxyClassEquals(this, obj)) {
            return false;
        }
        CostLine other = (CostLine) obj;

        return new EqualsBuilder().append(getCostLineTemplate(), other.getCostLineTemplate())
                .append(getCostAllocationMethod(), other.getCostAllocationMethod()).append(getTransactionCurrency(), other.getTransactionCurrency())
                .isEquals();
    }

    @Override
    public int compareTo(CostLine costLine) {
        return getCostLineTemplate().compareTo(costLine.getCostLineTemplate());
    }

    public boolean isDutiable() {
        return dutiable;
    }

    public void setDutiable(boolean dutiable) {
        this.dutiable = dutiable;
    }

    public boolean isBaseSupply() {

        return this.costLineTemplate.isBaseSupply();
    }

    public boolean isNameOverridden() {
        return overRideCostLineName != null;
    }

    public boolean isClcMinimumCostRequired() {
        return clcMinimumCostRequired;
    }

    public void setClcMinimumCostRequired(boolean clcMinimumCostRequired) {
        this.clcMinimumCostRequired = clcMinimumCostRequired;
    }

    public boolean isAlcMinimumCostRequired() {
        return alcMinimumCostRequired;
    }

    public void setAlcMinimumCostRequired(boolean alcMinimumCostRequired) {
        this.alcMinimumCostRequired = alcMinimumCostRequired;
    }

    public boolean isExcludeFromUnitPerCost() {
        return excludeFromUnitPerCost;
    }

    public void setExcludeFromUnitPerCost(boolean excludeFromUnitPerCost) {
        this.excludeFromUnitPerCost = excludeFromUnitPerCost;
    }

    public boolean isCustomsWorksheet() {
        return customsWorksheet;
    }

    public void setCustomsWorksheet(boolean customsWorksheet) {
        this.customsWorksheet = customsWorksheet;
    }

    public boolean isCustomsInvoice() {
        return customsInvoice;
    }

    public void setCustomsInvoice(boolean customsInvoice) {
        this.customsInvoice = customsInvoice;
    }

    public PaymentTerm getPaymentTerm() {
        return paymentTerm;
    }

    public void setPaymentTerm(PaymentTerm paymentTerm) {
        this.paymentTerm = paymentTerm;
    }

    public String getCostLineDescription() {
        return costLineDescription;
    }

    public void setCostLineDescription(String costLineDescription) {
        this.costLineDescription = costLineDescription;
    }
}