InvoiceCostingSummary.java

package com.tradecloud.domain.costing.clean;

import com.tradecloud.domain.common.Currency;
import com.tradecloud.domain.costing.CostGroup;
import com.tradecloud.domain.costing.CostLine;
import com.tradecloud.domain.document.DocumentType;
import com.tradecloud.domain.document.invoice.*;
import com.tradecloud.domain.model.ordermanagement.Order;
import com.tradecloud.domain.model.organisationalunit.OrganisationalUnit;
import com.tradecloud.domain.shipment.Shipment;
import org.apache.commons.collections4.keyvalue.MultiKey;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * This class does not get persisted, it just a work around for invoices as they do not have  summary.
 * Created by ds on 4/8/14.
 */

public class InvoiceCostingSummary extends CostingSummary<CostsInvoice, Shipment> {

    private CostsInvoice costsInvoice;
    private Map<Long, CostedOrder> costedOrderMap = new HashMap<>();
    private boolean firstTimeCosting;
    Map<CostLine, BigDecimal> totalsMap;
    Map<MultiKey, BigDecimal> customsTotalsMap;
    Map<CostLine, Currency> currenciesMap;
    Currency invoiceCurrency;
    private boolean validateDuties = true;

    public InvoiceCostingSummary(CostsInvoice costsInvoice) {
        this.costsInvoice = costsInvoice;
    }

    @Override
    public CostsInvoice getCostable() {
        return costsInvoice;
    }

    @Override
    public void setCostable(CostsInvoice costable) {

    }

    @Override
    public void setOriginalCostable(Shipment costable) {

    }

    @Override
    public Shipment getOriginalCostable() {
        return costsInvoice.getShipment();
    }

    @Override
    public Costed getCostedStructure() {
        return costsInvoice;
    }

    public void setCostedStructure(CostsInvoice costsInvoice) {
        this.costsInvoice = costsInvoice;
    }

    @Override
    public Currency getCostingCurrency() {
        return super.getCostingCurrency();
    }

    public CostsInvoice getCostsInvoice() {
        return costsInvoice;
    }

    public void setCostsInvoice(CostsInvoice costsInvoice) {
        this.costsInvoice = costsInvoice;
    }

    @Override
    public Set<ActualConsignment> getActualConsignmentSet() {
        return costsInvoice.getActualConsignments();
    }

    @Override
    public Shipment getShipment() {
        return costsInvoice.getShipment();
    }

    @Override
    public boolean isTotalUnitPrice(Costed costed) {
        Costed rootParent = costed.findRootParent();
        if (rootParent != null && rootParent.isCostsInvoice()) {
            CostsInvoice costsInvoice = (CostsInvoice) rootParent;
            if (costsInvoice.getDocumentType() == DocumentType.COMMERCIAL_INVOICE) {
                UnitPricePerItem unitPricePerItem = ((CommercialInvoice) rootParent).getUnitPricePerItem();
                return UnitPricePerItem.TOTAL_UNIT_PRICE.equals(unitPricePerItem);
            }

            if (costsInvoice.getDocumentType() == DocumentType.CUSTOM_DECLARATION_INVOICE) {
                DeclarationInvoice declarationInvoice = (DeclarationInvoice) rootParent;
                UnitPricePerItem unitPricePerItem = declarationInvoice.getCommercialInvoice().getUnitPricePerItem();
                return UnitPricePerItem.TOTAL_UNIT_PRICE.equals(unitPricePerItem);
            }
        }

        return false;
    }

    @Override
    public void clearCostApplicationBasisAmounts() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public OrganisationalUnit findStdRateOrgUnit() {
        Order order = getCostsInvoice().getShipment().getOrders().stream().findFirst().orElse(null);
        return order != null ? order.getOrganisationalUnit() : null;
    }

    public Map<Long, CostedOrder> getCostedOrderMap() {
        return costedOrderMap;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        if (!super.equals(o)) return false;
        InvoiceCostingSummary that = (InvoiceCostingSummary) o;
        return Objects.equals(costsInvoice, that.costsInvoice);
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), costsInvoice);
    }

    public BigDecimal getTotalDutiableCharges() {
        return costsInvoice.getCostedTotals().getDutiableCost();
    }

    public BigDecimal getTotalNonDutiableCharges() {
        BigDecimal dutiableCost = costsInvoice.getCostedTotals().getDutiableCost();
        BigDecimal totalCost = lookupTotalCost(costsInvoice, false, false, CostGroup.INTERNAL_PROVISIONS, CostGroup.CUSTOMS,
                CostGroup.TRADE_FINANCE);
        return totalCost.subtract(dutiableCost);
    }

    public BigDecimal getTotalNonDutiableChargesExclFreightAndInsurance() {
        BigDecimal dutiableCost = costsInvoice.getCostedTotals().getDutiableCost();
        BigDecimal totalCost = lookupTotalCost(costsInvoice, false, false, CostGroup.INTERNAL_PROVISIONS, CostGroup.CUSTOMS,
                CostGroup.TRADE_FINANCE, CostGroup.FREIGHT, CostGroup.FINANCE);
        return totalCost.subtract(dutiableCost);
    }

    @Override
    public Long getId() {
        return costsInvoice.getId();
    }

    @Override
    public boolean isDeclarationInvoice() {
        return costsInvoice.getDocumentType() == DocumentType.CUSTOM_DECLARATION_INVOICE;
    }

    @Override
    public boolean isSPIInvoice() {
        return costsInvoice.getDocumentType() == DocumentType.SERVICE_PROVIDER_INVOICE;
    }

    @Override
    public BigDecimal lookupMatchingItemAmount(ActualLineItem actual, String costLineCode) {
        ActualLineItem matchedItem = costsInvoice.getActualLineItems().stream().filter(c -> c.getOriginalId().
                        equals(actual.getOriginalId())).findFirst()
                .orElseThrow(() -> new IllegalStateException("cannot find matching actual lineitem for actual item: " +
                        "" + actual.getCode() + " order: " + actual.getActualOrder().getReference()));
        return matchedItem.getCostLineCosting().getCostingCell(costLineCode).getTransactionAmount();
    }

    public boolean isFirstTimeCosting() {
        return firstTimeCosting;
    }

    public void setFirstTimeCosting(boolean firstTimeCosting) {
        this.firstTimeCosting = firstTimeCosting;
    }

    public void setCostedOrderMap(Map<Long, CostedOrder> costedOrderMap) {
        this.costedOrderMap = costedOrderMap;
    }

    public Map<CostLine, BigDecimal> getTotalsMap() {
        return totalsMap;
    }

    public void setTotalsMap(Map<CostLine, BigDecimal> totalsMap) {
        this.totalsMap = totalsMap;
    }

    public Map<CostLine, Currency> getCurrenciesMap() {
        return currenciesMap;
    }

    public void setCurrenciesMap(Map<CostLine, Currency> currenciesMap) {
        this.currenciesMap = currenciesMap;
    }

    public Currency getInvoiceCurrency() {
        return invoiceCurrency;
    }

    public void setInvoiceCurrency(Currency invoiceCurrency) {
        this.invoiceCurrency = invoiceCurrency;
    }

    public boolean isValidateDuties() {
        return validateDuties;
    }

    public void setValidateDuties(boolean validateDuties) {
        this.validateDuties = validateDuties;
    }

    public Map<MultiKey, BigDecimal> getCustomsTotalsMap() {
        return customsTotalsMap;
    }

    public void setCustomsTotalsMap(Map<MultiKey, BigDecimal> customsTotalsMap) {
        this.customsTotalsMap = customsTotalsMap;
    }

    public boolean isInvoice() {
        return true;
    }
}