/**
   * HW2110-0019(base product): 381.64 Euro, and HW2200-0561(partner product): 86.80 Euro. The
   * ProductOneToOnePerfectPartnerPromotion will be fired if both of them are in the cart and the
   * price is 700 Euro.
   *
   * <ul>
   *   <li>adds the HW2110-0019 in cart, and tests the total price,
   *   <li>updates with the ProductOneToOnePerfectPartnerPromotion, and checks the total price,
   *   <li>now adds the HW2200-0561, and checks the total price,
   *   <li>updates with the ProductOneToOnePerfectPartnerPromotion that should be fired now, and
   *       checks the total price.
   * </ul>
   */
  @Test
  public void testProductOneToOnePerfectPartnerPromotion() throws CalculationException {
    cart = cartService.getSessionCart();
    cartService.addNewEntry(cart, baseProduct, 1, baseProduct.getUnit());
    modelService.save(cart);
    calculationService.calculate(cart);
    assertEquals(
        "before updatePromotions(ProductOneToOnePerfectPartnerPromotion)",
        381.64d,
        cart.getTotalPrice().doubleValue(),
        0.01);

    promotionGroup = promotionsService.getPromotionGroup("prGroup5");
    final Collection<PromotionGroupModel> promotionGroups = new ArrayList<PromotionGroupModel>();
    promotionGroups.add(promotionGroup);
    promotionsService.updatePromotions(
        promotionGroups, cart, false, AutoApplyMode.APPLY_ALL, AutoApplyMode.APPLY_ALL, new Date());
    modelService.refresh(cart);
    assertEquals("without partner product", 381.64d, cart.getTotalPrice().doubleValue(), 0.01);

    cartService.addNewEntry(cart, partnerProduct, 1, partnerProduct.getUnit());
    modelService.saveAll();
    calculationService.calculate(cart);
    assertEquals(
        "with partner product, but without promotion",
        468.44d,
        cart.getTotalPrice().doubleValue(),
        0.01);

    promotionsService.updatePromotions(
        promotionGroups, cart, false, AutoApplyMode.APPLY_ALL, AutoApplyMode.APPLY_ALL, new Date());
    modelService.refresh(cart);
    assertEquals("with partner product now", 400.00d, cart.getTotalPrice().doubleValue(), 0.01);
  }
  private void applyVouchersAndPromotions(
      final String[] voucherCodes,
      final List<PromotionGroupModel> groups,
      final double expectedTotal)
      throws JaloPriceFactoryException {
    for (final String voucherCode : voucherCodes) {
      voucherService.redeemVoucher(voucherCode, cart);
    }
    modelService.save(cart);

    promotionsService.updatePromotions(
        groups,
        cart,
        false,
        AutoApplyMode.APPLY_ALL,
        AutoApplyMode.APPLY_ALL,
        new java.util.Date());
    modelService.refresh(cart);

    assertEquals(expectedTotal, cart.getTotalPrice().doubleValue(), 0.001);

    for (final String voucherCode : voucherCodes) {
      voucherService.releaseVoucher(voucherCode, cart);
    }
  }
  /**
   * Tests promotion with voucher that has product restriction. (currency is Euro)
   *
   * <ul>
   *   <li>product(HW1230-0001) price = 769.00 --> 2x = 1538.00
   *   <li>product(HW2110-0012) price = 81.08 --> 2x = 162.16
   *   <li>so the cart contains products that cost 1700.16 Euro without promotion/voucher.
   *   <li>redeems the voucher that is 10% discount with product restriction: only valid for
   *       [HW1230-0001]
   *   <li>applies the fixed price promotion that is only valid for [HW1230-0001], and the fixed
   *       price is 500
   *   <li>update promotions, and the total discount should be (500 * 2) * 10% = 100
   *   <li>total price of the cart: (500 * 2 + 81.08 * 2) - 100 = 1062.16
   * </ul>
   */
  @Test
  public void testPromotionWithProductRestrictionVoucher()
      throws CalculationException, JaloPriceFactoryException {
    // PRO-70
    promotionGroup = promotionsService.getPromotionGroup("prGroup20");
    final ProductModel productSony = productService.getProductForCode(catVersion, "HW1230-0001");

    cartService.addNewEntry(cart, productSony, 2, productSony.getUnit());
    cartService.addNewEntry(cart, product1, 2, product1.getUnit());
    modelService.save(cart);
    calculationService.calculate(cart);
    modelService.refresh(cart);
    assertEquals(
        "should be 1700.16 euro without promotion/voucher",
        1700.16,
        cart.getTotalPrice().doubleValue(),
        0.01);

    voucherService.redeemVoucher(restrictionProductVoucher, cart);
    modelService.save(cart);

    final List<PromotionGroupModel> groups = new ArrayList<PromotionGroupModel>();
    groups.add(promotionGroup);
    promotionsService.updatePromotions(
        groups,
        cart,
        false,
        AutoApplyMode.APPLY_ALL,
        AutoApplyMode.APPLY_ALL,
        new java.util.Date());
    modelService.refresh(cart);
    assertEquals(
        "should be 100 euro for fixed price discount",
        100.0,
        cart.getTotalDiscounts().doubleValue(),
        0.01);
    assertEquals(
        "should be 1062.16 euro for total", 1062.16, cart.getTotalPrice().doubleValue(), 0.01);
  }
  /*
   * (non-Javadoc)
   *
   * @see in.com.v2kart.ccavenuepaymentintegration.services.CreateCCAvenuePaymentRequestStrategy#createPaymentRequest (java.lang.String,
   * java.lang.String, java.lang.String, de.hybris.platform.core.model.user.CustomerModel, java.lang.String, java.lang.String,
   * de.hybris.platform.commercefacades.user.data.AddressData, java.lang.String, java.lang.String, java.lang.String)
   */
  @Override
  public CCAvenuePaymentRequest createPaymentRequest(
      final String requestUrl,
      final String successUrl,
      final String cancelUrl,
      final CustomerModel customer,
      final String merchantKey,
      final String enforcedPaymentMethod,
      final AddressData addressData,
      final String currency,
      final String language,
      final String phoneNumber) {
    final CartModel cartModel = getCartService().getSessionCart();
    if (cartModel == null) {
      return null;
    }

    final CCAvenuePaymentRequest request = new CCAvenuePaymentRequest();
    request.setRequestUrl(requestUrl);
    request.setCancelUrl(cancelUrl);
    request.setRedirectUrl(successUrl);
    request.setAmount(String.valueOf(cartModel.getTotalPrice()));
    request.setCurrency(currency);
    request.setLanguage(language);
    request.setMerchantId(merchantKey);
    request.setOrderId(cartModel.getCode() + "_" + System.currentTimeMillis());
    request.setPaymentOption(paymentOptionMappings.get(enforcedPaymentMethod));

    if (addressData != null) {
      request.setCustomerBillToData(getCustomerBillToData(addressData));
    } else {
      final AddressModel address = cartModel.getDeliveryAddress();
      request.setCustomerBillToData(getCustomerBillToDataConverter().convert(address));
    }
    request
        .getCustomerBillToData()
        .setBillToEmail(getCustomerEmailResolutionService().getEmailForCustomer(customer));
    request.getCustomerBillToData().setBillToPhoneNumber(phoneNumber);
    final CountryModel countryModel =
        getCommonI18NService().getCountry(PaymentProperties.INDIA_COUNTRY_ISO);
    request.getCustomerBillToData().setBillToCountry(countryModel.getName());
    return request;
  }