PricingRule.php 7.38 KB
<?php namespace MeowCrew\RoleAndCustomerBasedPricing\Entity;

use Exception;
use MeowCrew\RoleAndCustomerBasedPricing\Core\ServiceContainerTrait;
use WC_Product;

class PricingRule {

	use ServiceContainerTrait;

	/**
	 * Product id
	 *
	 * @var int
	 */
	private $productId;

	/**
	 * Pricing Type
	 *
	 * @var string
	 */
	private $priceType;

	/**
	 * Regular price
	 *
	 * @var float
	 */
	private $regularPrice;

	/**
	 * Sale price
	 *
	 * @var float
	 */
	private $salePrice;

	/**
	 * Discount
	 *
	 * @var float
	 */
	private $discount;

	/**
	 * Product minimum purchase quantity
	 *
	 * @var int
	 */
	private $minimum;

	/**
	 * Product maximum purchase quantity
	 *
	 * @var int|null
	 */
	private $maximum;

	/**
	 * Group of product quantity
	 *
	 * @var int|null
	 */
	private $groupOf;

	/**
	 * Original product price
	 *
	 * @var float
	 */
	private $originalProductPrice;

	/**
	 * PricingRule constructor.
	 *
	 * @param string $priceType
	 * @param string $regularPrice
	 * @param string $salePrice
	 * @param int $discount
	 * @param int $minimum
	 * @param int $maximum
	 * @param int $groupOf
	 * @param null $productId
	 */
	public function __construct( $priceType, $regularPrice = null, $salePrice = null, $discount = null, $minimum = null, $maximum = null, $groupOf = null, $productId = null ) {
		$this->setPriceType( $priceType );

		$this->setRegularPrice( $regularPrice );
		$this->setSalePrice( $salePrice );
		$this->setDiscount( $discount );

		$this->setMinimum( $minimum );
		$this->setMaximum( $maximum );
		$this->setGroupOf( $groupOf );
		$this->setProductId( $productId );
	}

	public function isPurchasable() {
		return $this->getPrice();
	}

	/**
	 * Set original product price
	 *
	 * @param $price
	 */
	public function setOriginalProductPrice( $price ) {
		$this->originalProductPrice = $price;
	}

	public function getOriginalProductPrice() {

		if ( is_null( $this->originalProductPrice ) ) {
			$this->originalProductPrice = $this->getProduct()->get_price( 'edit' );
		}

		return $this->originalProductPrice;
	}

	public function getPrice( WC_Product $product = null ) {

		if ( $this->getPriceType() === 'percentage' ) {

			$discount = $this->getDiscount();

			$productPrice = $this->getOriginalProductPrice();

			$price = ( $productPrice * ( ( 100 - $discount ) / 100 ) );
		} else {
			$price = $this->getRegularPrice();

			if ( $this->getSalePrice() ) {
				$price = $this->getSalePrice();
			}
		}

		return apply_filters( 'role_customer_specific_pricing/pricing_rule/price', $price, $this );
	}

	/**
	 * Get discount
	 *
	 * @return int
	 */
	public function getDiscount() {
		return $this->discount;
	}

	/**
	 * Set discount
	 *
	 * @param int $discount
	 */
	public function setDiscount( $discount ) {
		$this->discount = $discount ? min( 100, floatval( $discount ) ) : null;
	}

	/**
	 * Get product id
	 *
	 * @return int
	 */
	public function getProductId() {
		return $this->productId;
	}

	/**
	 * Set product id
	 *
	 * @param int $productId
	 */
	public function setProductId( $productId ) {
		$this->productId = $productId ? intval( $productId ) : null;
	}

	/**
	 * Get price type
	 *
	 * @return string
	 */
	public function getPriceType() {
		return $this->priceType;
	}

	/**
	 * Set price type
	 *
	 * @param string $priceType
	 */
	public function setPriceType( $priceType ) {

		if ( ! racbpfw_fs()->is_premium() ) {
			$priceType = 'flat';
		}

		$this->priceType = in_array( $priceType, array( 'percentage', 'flat' ) ) ? $priceType : 'flat';
	}

	/**
	 * Get regular price
	 *
	 * @return string
	 */
	public function getRegularPrice() {
		return $this->regularPrice;
	}

	/**
	 * Set regular price
	 *
	 * @param string $regularPrice
	 */
	public function setRegularPrice( $regularPrice ) {
		$this->regularPrice = $regularPrice ? floatval( $regularPrice ) : null;
	}

	/**
	 * Get sale price
	 *
	 * @return string
	 */
	public function getSalePrice() {
		return $this->salePrice;
	}

	/**
	 * Set sale price
	 *
	 * @param string $salePrice
	 */
	public function setSalePrice( $salePrice ) {
		$this->salePrice = $salePrice ? floatval( $salePrice ) : null;
	}

	public function asArray() {
		return array(
			'pricing_type'  => $this->getPriceType(),
			'regular_price' => $this->getRegularPrice(),
			'sale_price'    => $this->getSalePrice(),
			'discount'      => $this->getDiscount(),
			'minimum'       => $this->getMinimum(),
			'maximum'       => $this->getMaximum(),
			'group_of'      => $this->getGroupOf(),
			'product_id'    => $this->getProductId(),
		);
	}

	/**
	 * Create instance from array
	 *
	 * @param array $data
	 * @param null|int $productId
	 *
	 * @return static
	 */
	public static function fromArray( $data, $productId = null ) {

		$pricingType = isset( $data['pricing_type'] ) ? $data['pricing_type'] : 'flat';
		$pricingType = in_array( $pricingType, array( 'flat', 'percentage' ) ) ? $pricingType : 'flat';

		$regularPrice = isset( $data['regular_price'] ) ? $data['regular_price'] : null;
		$salePrice    = isset( $data['sale_price'] ) ? (string) $data['sale_price'] : false;
		$discount     = isset( $data['discount'] ) ? $data['discount'] : null;

		$minimum = isset( $data['minimum'] ) ? $data['minimum'] : null;
		$maximum = isset( $data['maximum'] ) ? $data['maximum'] : null;
		$groupOf = isset( $data['group_of'] ) ? $data['group_of'] : null;

		$productId = $productId ? $productId : ( isset( $data['product_id'] ) ? (int) $data['product_id'] : null );

		return new static( $pricingType, $regularPrice, $salePrice, $discount, $minimum, $maximum, $groupOf, $productId );
	}

	public function calculateDiscount() {

		if ( $this->getPriceType() === 'percentage' ) {
			return $this->getDiscount();
		}

		$product = $this->getProduct();

		if ( $product ) {
			$price        = $this->getPrice();
			$productPrice = $product->get_price();

			if ( $productPrice > $price ) {
				return 100 - ( $price / $productPrice * 100 );
			}
		}

		return 0;
	}

	/**
	 * Validate
	 *
	 * @throws Exception
	 */
	public function validatePricing() {

		if ( $this->getPriceType() === 'flat' && ! $this->getPrice() ) {
			throw new Exception( __( 'The pricing fields must be filled.', 'role-and-customer-based-pricing-for-woocommerce' ) );
		}

		if ( $this->getPriceType() === 'percentage' && ! $this->getDiscount() ) {
			throw new Exception( __( 'The discount is not set.', 'role-and-customer-based-pricing-for-woocommerce' ) );
		}
	}

	public function isValidPricing() {
		try {
			$this->validatePricing();
		} catch ( Exception $e ) {
			return false;
		}

		return true;
	}

	/**
	 * Get minimum
	 *
	 * @return int
	 */
	public function getMinimum() {
		return $this->minimum;
	}

	/**
	 * Set minimum
	 *
	 * @param int $minimum
	 */
	public function setMinimum( $minimum ) {
		$this->minimum = $minimum ? intval( $minimum ) : null;
	}

	/**
	 * Get maximum
	 *
	 * @return int|null
	 */
	public function getMaximum() {
		return $this->maximum;
	}

	/**
	 * Set maximum
	 *
	 * @param int|null $maximum
	 */
	public function setMaximum( $maximum ) {
		$this->maximum = $maximum ? intval( $maximum ) : null;
	}

	/**
	 * Get group of
	 *
	 * @return int|null
	 */
	public function getGroupOf() {
		return $this->groupOf;
	}

	/**
	 * Set group of
	 *
	 * @param int|null $groupOf
	 */
	public function setGroupOf( $groupOf ) {
		$this->groupOf = $groupOf ? intval( $groupOf ) : null;
	}

	/**
	 * Get product
	 *
	 * @return false|WC_Product
	 */
	public function getProduct() {
		return wc_get_product( $this->getProductId() );
	}
}