CostedBase.java

package com.tradecloud.domain.costing.clean;

import com.tradecloud.common.base.PersistenceBase;
import com.tradecloud.domain.costing.CostGroup;
import com.tradecloud.domain.costing.CostingContextType;
import com.tradecloud.domain.costing.utils.CostingUtils;
import com.tradecloud.domain.item.ItemType;
import org.hibernate.annotations.ForeignKey;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlTransient;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;


/**
 * Base class for costed entities. Holds common functionality required by all subclasses.
 *
 * @param <P>
 * @param <C>
 */
@MappedSuperclass
public abstract class CostedBase<P extends Costed, C extends Costed> extends PersistenceBase implements Costed<P, C> {

    private static final long serialVersionUID = 1L;

    protected boolean distributableByVolume;

    protected boolean distributableByWeight;

    @XmlAttribute
    @Enumerated(EnumType.STRING)
    @NotNull
    private CostingContextType costingContextType = CostingContextType.IMPORT;

    /**
     * Various cost line costings to allow the costing to be broken down at each level.
     */
    @Embedded
    @XmlElement(name = "CostLineCosting")
    private CostLineCosting costLineCosting = new CostLineCosting();

    /**
     * Contains totals for the costed.
     * <p>
     * e.g. costedConsignment.getTotalsDistribution.get(TotalsDistributionType.WEIGHT_KG)
     * gives the total weight for the consignment, excluding tare weight at the moment.
     */
    @XmlTransient
    @ElementCollection
    @ForeignKey(name = "fk_totalsDistribution")
    @MapKeyEnumerated(EnumType.STRING)
    private Map<TotalsDistributionType, BigDecimal> totalsDistribution = new HashMap<TotalsDistributionType, BigDecimal>();

    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
    @XmlElement
    @ForeignKey(name = "fk_costedTotals")
    private CostedTotals costedTotals = new CostedTotals();
    @XmlTransient
    @ElementCollection
    @MapKeyColumn(name = "elcGlcVarianceMap_KEY")
    //key=Costgroup.ElcGlcVarianceType
    private Map<String, ElcGlcVariance> elcGlcVarianceMap = new HashMap<String, ElcGlcVariance>();

    @XmlAttribute
    private BigDecimal sellPriceExclusiveAmount = BigDecimal.ZERO;

    @XmlAttribute
    private BigDecimal sellPriceInclusiveAmount = BigDecimal.ZERO;
    /**
     * costline code will be used.
     */
    @XmlTransient
    @ElementCollection
    private Map<String, BigDecimal> costlineBondedAmount = new HashMap<String, BigDecimal>();

    private boolean primaryCosting;

    @Override
    public CostLineCosting getCostLineCosting() {
        return costLineCosting;
    }

    public void setCostLineCosting(CostLineCosting costLineCosting) {
        this.costLineCosting = costLineCosting;
    }

    @Override
    public Map<TotalsDistributionType, BigDecimal> getTotalsDistribution() {
        return totalsDistribution;
    }

    public void setTotalsDistribution(Map<TotalsDistributionType, BigDecimal> totalsDistribution) {
        this.totalsDistribution = totalsDistribution;
    }

    public abstract CostedConsignment getConsignment();

    @Override
    public String getKey() {
        return new StringBuilder(getClass().getCanonicalName()).append("-").append(toString()).append(hashCode()).toString();
    }

    /**
     * This field will be set to true if 1 of the line items linked to the structure has a volume value.
     *
     * @return
     */
    @Override
    public boolean isDistributableByVolume() {
        return distributableByVolume;
    }

    public void setDistributableByVolume(boolean distributableByVolume) {
        this.distributableByVolume = distributableByVolume;
    }

    /**
     * This field will be set to true if 1 of the line items linked to the structure has a weight value.
     *
     * @return
     */
    @Override
    public boolean isDistributableByWeight() {
        return distributableByWeight;
    }

    public void setDistributableByWeight(boolean distributableByWeight) {
        this.distributableByWeight = distributableByWeight;
    }

    @Override
    public CostedTotals getCostedTotals() {
        return costedTotals;
    }

    @Override
    public void setCostedTotals(CostedTotals costedTotals) {
        this.costedTotals = costedTotals;
    }

    @Override
    public boolean isActual() {
        return false;
    }

    @Override
    public boolean isItem() {
        return false;
    }

    @Override
    public boolean isOrder() {
        return false;
    }

    @Override
    public boolean isConsignment() {
        return false;
    }

    @Override
    public boolean isShipment() {
        return false;
    }

    @Override
    public ItemType getItemType() {
        return null;
    }

    @Override
    public boolean isCostsInvoice() {
        return false;
    }

    @Override
    public Costed findRootParent() {
        return CostingUtils.findRootParent(this);
    }

    @Override
    public String getReferenceWithShippingRef() {
        return null;
    }

    public CostingContextType getCostingContextType() {
        return costingContextType;
    }

    public boolean isImport() {
        return costingContextType == CostingContextType.IMPORT;
    }

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

    @Override
    public BigDecimal getSellPriceExclusiveAmount() {
        return sellPriceExclusiveAmount;
    }

    @Override
    public void setSellPriceExclusiveAmount(BigDecimal sellPriceExclusiveAmount) {
        this.sellPriceExclusiveAmount = sellPriceExclusiveAmount;
    }

    @Override
    public BigDecimal getSellPriceInclusiveAmount() {
        return sellPriceInclusiveAmount;
    }

    @Override
    public void setSellPriceInclusiveAmount(BigDecimal sellPriceInclusiveAmount) {
        this.sellPriceInclusiveAmount = sellPriceInclusiveAmount;
    }

    public ElcGlcVariance getElcGlcVariance(CostGroup costGroup, ElcGlcVarianceType elcGlcVarianceType) {
        return getElcGlcVariance(getElcGLCKey(costGroup, elcGlcVarianceType));
    }

    public void addToElcGlcVarianceMap(CostGroup costGroup, ElcGlcVarianceType elcGlcVarianceType, ElcGlcVariance elcGlcVariance) {
        elcGlcVarianceMap.put(getElcGLCKey(costGroup, elcGlcVarianceType), elcGlcVariance);
    }

    public String getElcGLCKey(CostGroup costGroup, ElcGlcVarianceType elcGlcVarianceType) {
        return costGroup.name() + "." + elcGlcVarianceType.name();
    }

    public Map<String, ElcGlcVariance> getElcGlcVarianceMap() {
        return elcGlcVarianceMap;
    }

    public void setElcGlcVarianceMap(Map<String, ElcGlcVariance> elcGlcVarianceMap) {
        this.elcGlcVarianceMap = elcGlcVarianceMap;
    }

    public ElcGlcVariance getElcGlcVariance(String columnCode) {
        ElcGlcVariance elcGlcVariance = (ElcGlcVariance) this.getElcGlcVarianceMap().get(columnCode);
        if (elcGlcVariance == null) {
            elcGlcVariance = new ElcGlcVariance();
            this.getElcGlcVarianceMap().put(columnCode, elcGlcVariance);
        }
        return elcGlcVariance;
    }

    public void clearElcCosting() {
        this.getElcGlcVarianceMap().clear();
        clearElcCostingTotal();
    }

    public void clearElcCostingTotal() {
        this.getTotalsDistribution().put(TotalsDistributionType.CLC_UNIT_PRICE, BigDecimal.ZERO);
        this.getTotalsDistribution().put(TotalsDistributionType.ELC_CLC_ITEM_VARIANCE, BigDecimal.ZERO);
        this.getTotalsDistribution().put(TotalsDistributionType.ELC_CLC_ITEM_VARIANCE_PERCENTAGE, BigDecimal.ZERO);
        this.getTotalsDistribution().put(TotalsDistributionType.ELC_ITEM_COST, BigDecimal.ZERO);
        this.getTotalsDistribution().put(TotalsDistributionType.ELC_UNIT_COST, BigDecimal.ZERO);
        this.getTotalsDistribution().put(TotalsDistributionType.ELC_CLC_VARIANCE, BigDecimal.ZERO);
    }

    @Override
    public Map<String, BigDecimal> getCostlineBondedAmount() {
        return costlineBondedAmount;
    }

    public boolean isPrimaryCosting() {
        return primaryCosting;
    }

    public void setPrimaryCosting(boolean primaryCosting) {
        this.primaryCosting = primaryCosting;
    }
}