Package org.multibit.mbm.client.domain.model.pricing

Source Code of org.multibit.mbm.client.domain.model.pricing.PriceBuilder

package org.multibit.mbm.client.domain.model.pricing;

import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import com.xeiam.xchange.currency.MoneyUtils;
import org.joda.money.BigMoney;
import org.joda.time.DateTime;
import org.multibit.mbm.client.domain.model.model.Customer;
import org.multibit.mbm.client.domain.model.model.PricingRule;
import org.multibit.mbm.client.domain.model.model.Supplier;
import org.multibit.mbm.client.common.utils.DateUtils;

import java.util.List;

/**
* <p>Business object to provide the following to {@link org.multibit.mbm.client.domain.model.model.Item}:</p>
* <ul>
* <li>Calculation of price based on purchase order</li>
* </ul>
* <p>A price can only be determined as a result of the application of rules against
* and original value.</p>
*
* @since 0.0.1
*         
*/
public class PriceBuilder {

  private int quantity = 0;
  private DateTime start = DateUtils.nowUtc();
  private DateTime end = DateUtils.nowUtc();
  private BigMoney startingPrice = MoneyUtils.parse("GBP 0.0");
  private Optional<Customer> customer = Optional.absent();
  private Optional<Supplier> supplier = Optional.absent();

  private List<PricingRule> pricingRules = Lists.newArrayList();

  private boolean isBuilt = false;

  /**
   * @return A new instance of the builder
   */
  public static PriceBuilder newInstance() {
    return new PriceBuilder();
  }

  public PriceBuilder() {
  }

  /**
   * Handles the building process. No further configuration is possible after this.
   */
  public BigMoney build() {
    validateState();

    // Price is not a DTO
    BigMoney price = startingPrice;

    for (PricingRule pricingRule : pricingRules) {
      pricingRule.setCustomer(customer);
      pricingRule.setSupplier(supplier);
      pricingRule.setQuantity(quantity);
      // TODO Consider date ranges (use discriminator value e.g. R(A,B], R(o,o))
      // Test filtering rules
      if (pricingRule.skip()) {
        continue;
      }
      if (pricingRule.halt()) {
        break;
      }
      price = pricingRule.applyTo(price);
    }

    isBuilt = true;

    return price;
  }

  private void validateState() {
    if (isBuilt) {
      throw new IllegalStateException("The entity has been built");
    }
  }

  public PriceBuilder withPricingRule(PricingRule pricingRule) {
    pricingRules.add(pricingRule);
    return this;
  }

  /**
   * Add the Customer in case it affects the price (one permitted)
   *
   * @return The builder
   */
  public PriceBuilder withCustomer(Customer customer) {
    this.customer = Optional.fromNullable(customer);
    return this;
  }

  /**
   * Add the Supplier in case it affects the price (one permitted)
   *
   * @return The builder
   */
  public PriceBuilder withSupplier(Supplier supplier) {
    this.supplier = Optional.fromNullable(supplier);
    return this;
  }

  /**
   * @param startingPrice The starting price (default is GBP0.0)
   *
   * @return The builder
   */
  public PriceBuilder withStartingPrice(BigMoney startingPrice) {
    this.startingPrice = startingPrice;
    return this;
  }
}
TOP

Related Classes of org.multibit.mbm.client.domain.model.pricing.PriceBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.