class CheckoutServiceFacadeImpl implements CheckoutServiceFacade {

    @Override
    public PriceModel getOrderTotalSub(final CustomerOrder customerOrder, final ShoppingCart cart) {

        final Total grandTotal = getOrderTotal(customerOrder);

        final boolean hasTax = MoneyUtils.isPositive(grandTotal.getTotalTax());

        final boolean showTax = hasTax && cart.getShoppingContext().isTaxInfoEnabled();
        final boolean showTaxNet = showTax && cart.getShoppingContext().isTaxInfoUseNet();
        final boolean showTaxAmount = showTax && cart.getShoppingContext().isTaxInfoShowAmount();

        if (showTax) {

            final String firstTaxCode = determineTaxCode(customerOrder);

            final BigDecimal netAmount = grandTotal.getTotalAmount().subtract(grandTotal.getTotalTax());
            final BigDecimal taxPercent = grandTotal.getTotalTax().divide(netAmount, Constants.TAX_SCALE, BigDecimal.ROUND_FLOOR);
            final BigDecimal taxRate = taxPercent.multiply(MoneyUtils.HUNDRED).setScale(Constants.MONEY_SCALE, BigDecimal.ROUND_HALF_UP);

            final boolean priceTaxExclusive = MoneyUtils.isFirstBiggerThanSecond(grandTotal.getTotalAmount(), grandTotal.getTotal());

            // no discounts on sub total
            return new PriceModelImpl(
                    ORDER_SUB_TOTAL_REF,
                    customerOrder.getCurrency(),
                    BigDecimal.ONE,
                    false,
                    false,
                    showTaxNet ? grandTotal.getTotalAmount().subtract(grandTotal.getTotalTax()) : grandTotal.getTotalAmount(),
                    null,
                    showTax, showTaxNet, showTaxAmount,
                    firstTaxCode,
                    taxRate,
                    priceTaxExclusive,
                    grandTotal.getTotalTax()
            );

        }

        // no discounts on sub total
        return new PriceModelImpl(
                ORDER_SUB_TOTAL_REF,
                customerOrder.getCurrency(),
                BigDecimal.ONE,
                false,
                false,
                grandTotal.getTotal(),
                null
        );

    }

    public  CheckoutServiceFacadeImpl(final CustomerOrderService customerOrderService,
                                     final AmountCalculationStrategy amountCalculationStrategy,
                                     final DeliveryTimeEstimationVisitor deliveryTimeEstimationVisitor,
                                     final CustomerOrderPaymentService customerOrderPaymentService,
                                     final CarrierSlaService carrierSlaService,
                                     final PaymentProcessorFactory paymentProcessorFactory,
                                     final PaymentModulesManager paymentModulesManager,
                                     final ReportGenerator reportGenerator);

}