EstimateCostSummary.java
package com.tradecloud.domain.costing.clean;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.tradecloud.domain.base.utils.MathUtils;
import com.tradecloud.domain.common.Currency;
import com.tradecloud.domain.costing.CostGroup;
import com.tradecloud.domain.costing.CostLine;
import com.tradecloud.domain.costing.utils.CostingUtils;
import com.tradecloud.domain.document.invoice.ActualConsignment;
import com.tradecloud.domain.document.invoice.ActualLineItem;
import com.tradecloud.domain.document.invoice.UnitPricePerItem;
import com.tradecloud.domain.model.ordermanagement.Consignment;
import com.tradecloud.domain.model.ordermanagement.Order;
import com.tradecloud.domain.model.organisationalunit.OrganisationalUnit;
import com.tradecloud.domain.party.ServiceProvider;
import com.tradecloud.domain.shipment.Shipment;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.math.BigDecimal;
import java.util.*;
@Entity
@DiscriminatorValue("ESTIMATE_COST_SUMMARY")
@Table(name = "estimatecostsummary")
@Access(AccessType.FIELD)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "EstimateCostSummary")
@NamedQueries({@NamedQuery(name = "findByIdWithCostLineCostingCellsLoaded",
query = "from EstimateCostSummary ecs left join fetch ecs.costedConsignment.costLineCosting.costLineCostingCells where ecs.id=:id")})
public class EstimateCostSummary extends CostingSummary<CostedConsignment, Consignment> {
/**
* UID.
*/
private static final long serialVersionUID = 1L;
/**
* Original consignment used for retrieval of the EstimateCostSummary only and not for the costing.
*/
@NotNull
@XmlElement(name = "OriginalCostable")
@OneToOne(optional = false)
@JsonIgnore
private Consignment originalCostable;
/**
* The estimate cost 'snapshot' of a Consignment at a point in time.
*/
@NotNull
@XmlElement(name = "CostedConsignment")
@OneToOne(optional = false, cascade = CascadeType.ALL)
@JsonIgnore
private CostedConsignment costedConsignment;
private String number;
private boolean primaryCosting;
@Embedded
private CostSummaryAdditionalInfo costSummaryAdditionalInfo = new CostSummaryAdditionalInfo();
private transient List<CostLine> elcCostLines = new ArrayList<>();
@Override
public CostedConsignment getCostable() {
return getCostedConsignment();
}
@Override
public void setCostable(CostedConsignment costable) {
setCostedConsignment((CostedConsignment) costable);
}
public CostedConsignment getCostedConsignment() {
return costedConsignment;
}
public void setCostedConsignment(CostedConsignment costedConsignmentParam) {
this.costedConsignment = costedConsignmentParam;
}
@Override
@JsonIgnore
public Consignment getOriginalCostable() {
return originalCostable;
}
@Override
public void setOriginalCostable(Consignment originalCostable) {
this.originalCostable = originalCostable;
}
/**
* Returns the costedConsignment which reflects the CLC costed structure.
*
* @return
*/
@Override
public Costed<? extends Costed, ? extends Costed> getCostedStructure() {
return costedConsignment;
}
public BigDecimal lookupCostingResult(String costLineCode, Order order) {
final List<CostedOrder> costedOrdersList = getCostedConsignment().getCostedOrdersList();
for (CostedOrder costedOrder : costedOrdersList) {
if (CostingStructureMatcher.match(order, costedOrder)) {
//if (order.match(costedOrder)) {
return CostingUtils.getCostLineAmount(costLineCode, costedOrder);
}
}
return null;
}
@Override
public int hashCode() {
return new HashCodeBuilder().append(originalCostable).append(costedConsignment).toHashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof EstimateCostSummary)) {
return false;
}
EstimateCostSummary other = (EstimateCostSummary) obj;
return new EqualsBuilder().append(originalCostable, other.originalCostable).append(costedConsignment, other.costedConsignment).isEquals();
}
@Override
public Set<ActualConsignment> getActualConsignmentSet() {
return null;
}
@Override
@JsonIgnore
public Shipment getShipment() {
return null;
}
@Override
public boolean isTotalUnitPrice(Costed costed) {
if (costed instanceof CostedLineItem) {
//UnitPricePerItem unitPricePerItem = ((CostedLineItem) costed).getLineItem().getOrder().getUnitPricePerItem();
//return UnitPricePerItem.TOTAL_UNIT_PRICE.equals(unitPricePerItem);
return UnitPricePerItem.TOTAL_UNIT_PRICE.equals(((CostedLineItem) costed).getCostedOrder().getUnitPricePerItem());
}
return false;
}
@Override
public void clearCostApplicationBasisAmounts() {
throw new UnsupportedOperationException("Not supported yet.");
}
public List<CostLine> getElcCostlines(CostGroup costGroup) {
if (elcCostLines.isEmpty() && !costedConsignment.getElcGlcVarianceMap().isEmpty()) {
elcCostLines = (List<CostLine>) CostingUtils.addElcCostlines(costGroup);
}
return elcCostLines;
}
public boolean isElcCostingConsignment() {
return !getCostedConsignment().getElcGlcVarianceMap().isEmpty();
}
public CostSummaryAdditionalInfo getCostSummaryAdditionalInfo() {
if (costSummaryAdditionalInfo == null) {
costSummaryAdditionalInfo = new CostSummaryAdditionalInfo();
}
return costSummaryAdditionalInfo;
}
public void setCostSummaryAdditionalInfo(CostSummaryAdditionalInfo costSummaryAdditionalInfo) {
this.costSummaryAdditionalInfo = costSummaryAdditionalInfo;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
@Override
public OrganisationalUnit findStdRateOrgUnit() {
Order order = getOriginalCostable().getOrders().stream().findFirst().orElse(null);
return order != null ? order.getOrganisationalUnit() : null;
}
@Override
public BigDecimal lookupMatchingItemAmount(ActualLineItem actual, String costLineCode) {
CostedLineItem costedLineItem = costedConsignment.getAllCostedLineItems().stream()
.filter(c -> c.getLineItem().getId().equals(actual.getOriginalId())).findFirst()
.orElseThrow(() -> new IllegalStateException("cannot find matching estimate costed lineitem for actual item: " +
"" + actual.getCode() + " order: " + actual.getActualOrder().getReference()));
return costedLineItem.getCostLineCosting().getCostingCell(costLineCode).getTransactionAmount();
}
@Override
public boolean isPrimaryCosting() {
return primaryCosting;
}
@Override
public void setPrimaryCosting(boolean primaryCosting) {
this.primaryCosting = primaryCosting;
}
public ServiceProvider getFreightForwarder() {
return getCostSummaryAdditionalInfo().getFreightForwarder();
}
public void setFreightForwarder(ServiceProvider freightForwarder) {
getCostSummaryAdditionalInfo().setFreightForwarder(freightForwarder);
}
public BigDecimal getCostGroupExchangeRateClcELC(com.tradecloud.domain.costing.CostGroup costGroup,
Currency costingCurrency) {
BigDecimal costGroupRate = BigDecimal.ONE;
Map<Currency, BigDecimal> currencyExchanges = new HashMap<>();
BigDecimal totalAmountForeign = BigDecimal.ZERO;
BigDecimal totalAmountCosting = BigDecimal.ZERO;
for (CostLineSummary costLineSummary : this.getCostLineSummaries()) {
if (isValidCostLine(costLineSummary, costingCurrency, costGroup)) {
Currency transactionCurrency = costLineSummary.getTransactionCurrency();
currencyExchanges.putIfAbsent(transactionCurrency, costLineSummary.getForwardRate());
totalAmountForeign = totalAmountForeign.add(costLineSummary.getTransactionCurrencyTotal());
totalAmountCosting = totalAmountCosting.add(getCostingAmount(costLineSummary));
}
}
if (currencyExchanges.size() == 1) {
return currencyExchanges.values().iterator().next();
} else if (currencyExchanges.size() > 1) {
return MathUtils.divideVA(totalAmountCosting, totalAmountForeign);
}
return costGroupRate;
}
private boolean isValidCostLine(CostLineSummary costLineSummary, Currency costingCurrency, com.tradecloud.domain.costing.CostGroup costGroup) {
return costLineSummary.getCostLine().getCostLineTemplate().getCostGroup()
.equals(costGroup)
&& MathUtils.isNonZero(costLineSummary.getTransactionCurrencyTotal())
&& !costingCurrency.equals(costLineSummary.getTransactionCurrency());
}
private BigDecimal getCostingAmount(CostLineSummary costLineSummary) {
return costLineSummary.getTransactionCurrencyTotal().multiply(costLineSummary.getForwardRate());
}
}