class CheckoutServiceFacadeImpl implements CheckoutServiceFacade {

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

        final Total grandTotal = getOrderTotal(customerOrder);

        final boolean hasTax = MoneyUtils.isPositive(grandTotal.getTotalTax());
        final boolean showTax = hasTax; // Total amount always must show tax if it has it
        final boolean showTaxAmount = showTax && cart.getShoppingContext().isTaxInfoShowAmount();

        final boolean hasDiscounts = MoneyUtils.isFirstBiggerThanSecond(grandTotal.getListTotalAmount(), grandTotal.getTotalAmount());

        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);

            return new PriceModelImpl(
                    ORDER_TOTAL_REF,
                    customerOrder.getCurrency(),
                    BigDecimal.ONE,
                    false,
                    false,
                    hasDiscounts ? grandTotal.getListTotalAmount() : grandTotal.getTotalAmount(),
                    hasDiscounts ? grandTotal.getTotalAmount() : null,
                    showTax, false, showTaxAmount,
                    firstTaxCode,
                    taxRate,
                    false, // TotalAmount always includes taxes
                    grandTotal.getTotalTax()
            );


        }

        if (hasDiscounts) {

            return new PriceModelImpl(
                    ORDER_TOTAL_REF,
                    customerOrder.getCurrency(),
                    BigDecimal.ONE,
                    false,
                    false,
                    grandTotal.getListTotalAmount(),
                    grandTotal.getTotalAmount()
            );

        }

        return new PriceModelImpl(
                ORDER_TOTAL_REF,
                customerOrder.getCurrency(),
                BigDecimal.ONE,
                false,
                false,
                grandTotal.getTotalAmount(),
                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);

}