/**
   * 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);
  }
  /**
   * 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);
  }
 @Test
 public void testBasicProduct() throws Exception {
   final ProductModel product = processFile(productId, "base_product-", new ProductContent());
   Assert.assertEquals("name", product.getName(Locale.ENGLISH));
   Assert.assertNull("name", product.getName(Locale.GERMAN));
   Assert.assertEquals("description", product.getDescription(Locale.ENGLISH));
   Assert.assertNull("description", product.getDescription(Locale.GERMAN));
   Assert.assertEquals("ean", product.getEan());
   Assert.assertEquals("manufacturer", product.getManufacturerName());
   Assert.assertEquals("manufacturerAID", product.getManufacturerAID());
   Assert.assertEquals("pieces", product.getUnit().getName());
   Assert.assertEquals("approved", product.getApprovalStatus().getCode());
   Assert.assertEquals("eu-vat-half", product.getEurope1PriceFactory_PTG().getCode());
   Assert.assertEquals(sequenceId, product.getSequenceId());
   Assert.assertEquals("Staged", product.getCatalogVersion().getVersion());
   Assert.assertEquals("apparelProductCatalog", product.getCatalogVersion().getCatalog().getId());
 }
  /**
   * Puts two products in the cart, applies one 10% product promotion, and redeems
   *
   * <ul>
   *   <li>1. one voucher without free shipping or
   *   <li>2. one voucher with free shipping or
   *   <li>3. two vouchers, one with free shipping and the other one without.
   * </ul>
   */
  @Test
  public void testPromotionWithVoucher() throws JaloPriceFactoryException {
    // PRO-64
    promotionGroup = promotionsService.getPromotionGroup("prGroup10");
    final List<PromotionGroupModel> groups = new ArrayList<PromotionGroupModel>();
    groups.add(promotionGroup);

    cartService.addNewEntry(cart, product1, 2, product1.getUnit());
    deliveryModeDhl = deliveryModeService.getDeliveryModeForCode("dhl");
    cart.setDeliveryMode(deliveryModeDhl);
    cart.setDeliveryAddress(user.getDefaultShipmentAddress());

    /**
     * General information:
     *
     * <ul>
     *   <li>product(HW2110-0012) price = 81.08 --> 2x = 162.16, delivery cost 8.0, totally 170.16
     *   <li>applied 10% ProductPercentageDiscountPromotion, 162.16 * 0.9 = 145.94
     * </ul>
     *
     * Three different situations with vouchers:
     *
     * <ul>
     *   <li>1. 5% voucher without free shipping, 145.94 * 0.95 = 138.64, delivery cost 8.0, totally
     *       146.64
     *   <li>2. 20% voucher with free shipping, 145.94 * 0.8 = 116.75, free shipping, totally 116.75
     *   <li>3. both the vouchers above, 145.94 * (1 - 0.05 - 0.20) = 109.45, free shipping, totally
     *       109.45
     * </ul>
     */
    applyVouchersAndPromotions(new String[] {voucherCode}, groups, 146.64);

    applyVouchersAndPromotions(new String[] {freeShippingVoucherCode}, groups, 116.75);

    applyVouchersAndPromotions(new String[] {voucherCode, freeShippingVoucherCode}, groups, 109.45);
  }