CostLineCostingComparator.java

package com.tradecloud.domain.costing.utils;

import com.tradecloud.domain.costing.CostGroup;
import com.tradecloud.domain.costing.CostLine;
import com.tradecloud.domain.costing.CostLinePayerType;

import java.util.Comparator;

/**
 * First compare by cost line payer type (direct / indirect)
 * Secondly compare by cost group.
 * Thirdly compare by cost line evaluation priority.
 * If there is no evaluation priority, evaluationPriority = null, then it will be sorted to be at the end of the list.
 * <p>
 * This was introduced as a solution to cost lines that rely on other cost lines' cost value.
 */
public class CostLineCostingComparator implements Comparator<CostLine> {
    @Override
    public int compare(CostLine costLine1, CostLine costLine2) {
        if (isExporterPayerType(costLine1) && isImporterPayerType(costLine2)) {
            return -1;
        } else if (isImporterPayerType(costLine1) && isExporterPayerType(costLine2)) {
            return 1;
        }
        return compareByCostGroup(costLine1, costLine2);
    }

    private int compareByCostGroup(CostLine costLine1, CostLine costLine2) {
        CostGroup costGroup1 = costLine1.getCostLineTemplate().getCostGroup();
        CostGroup costGroup2 = costLine2.getCostLineTemplate().getCostGroup();

        /*
         * Java spec on Enum compareTo:
         * ...The natural order implemented by this method is the order in which the constants are declared...
         */
        int compareTo = costGroup1.compareTo(costGroup2);
        if (compareTo == 0) {
            return compareByEvaluationPriority(costLine1, costLine2);
        }
        return compareTo;
    }

    private int compareByEvaluationPriority(CostLine costLine1, CostLine costLine2) {
        // Want the nulls to be last
        Integer i1 = costLine1.getCostLineTemplate().getEvaluationPriority();
        Integer i2 = costLine2.getCostLineTemplate().getEvaluationPriority();
        if (i1 != null && i2 != null) {
            return i1.compareTo(i2);
        } else if (i1 == null && i2 == null) {
            return 0;
        } else if (i1 != null) {
            return -1;
        } else if (i2 != null) {
            return 1;
        }
        return 0;
    }

    private boolean isImporterPayerType(CostLine costLine) {
        return CostLinePayerType.IMPORTER.equals(costLine.getCostLinePayerType());
    }

    private boolean isExporterPayerType(CostLine costLine) {
        return CostLinePayerType.EXPORTER.equals(costLine.getCostLinePayerType());
    }
}