<?php

/**
  * Discount class, Discount.php
  * Discounts management
  * @category classes
  *
  * @author PrestaShop <support@prestashop.com>
  * @copyright PrestaShop
  * @license http://www.opensource.org/licenses/osl-3.0.php Open-source licence 3.0
  * @version 1.0
  *
  */
  
class		Discount extends ObjectModel
{
	public		$id;
	
	/** @var integer Customer id only if discount is reserved */
	public		$id_customer;
	
	/** @var integer Discount type ID */
	public		$id_discount_type;
	
	/** @var string Name (the one which must be entered) */
	public 		$name;
	
	/** @var string A short description for the discount */
	public 		$description;
	
	/** @var string Value in percent as well as in euros */
	public 		$value;
	
	/** @var integer Totale quantity available */
	public 		$quantity;
	
	/** @var integer User quantity available */
	public 		$quantity_per_user;
	
	/** @var boolean Indicate if discount is cumulable with others */
	public 		$cumulable;
	
	/** @var integer Indicate if discount is cumulable with already bargained products */
	public 		$cumulable_reduction;
	
	/** @var integer Date from wich discount become active */
	public 		$date_from;
	
	/** @var integer Date from wich discount is no more active */
	public 		$date_to;
	
	/** @var integer Minimum cart total amount required to use the discount */
	public 		$minimal;
	
	/** @var boolean Status */
	public 		$active = true;
	
	protected	$fieldsRequired = array('id_discount_type', 'name', 'value', 'quantity', 'quantity_per_user', 'date_from', 'date_to');
	protected	$fieldsSize = array('name' => '32', 'date_from' => '32', 'date_to' => '32');
	protected	$fieldsValidate = array('id_customer' => 'isUnsignedId', 'id_discount_type' => 'isUnsignedId',
		'name' => 'isDiscountName', 'value' => 'isPrice', 'quantity' => 'isUnsignedInt', 'quantity_per_user' => 'isUnsignedInt',
		'cumulable' => 'isBool', 'cumulable_reduction' => 'isBool', 'date_from' => 'isDate',
		'date_to' => 'isDate', 'minimal' => 'isFloat', 'active' => 'isBool');
	protected	$fieldsRequiredLang = array('description');
	protected	$fieldsSizeLang = array('description' => 128);
	protected	$fieldsValidateLang = array('description' => 'isGenericName');

	protected 	$table = 'discount';
	protected 	$identifier = 'id_discount';
		
	public function getFields()
	{
		parent::validateFields();
		
		$fields['id_customer'] = intval($this->id_customer);
		$fields['id_discount_type'] = intval($this->id_discount_type);
		$fields['name'] = pSQL($this->name);
		$fields['value'] = floatval($this->value);
		$fields['quantity'] = intval($this->quantity);
		$fields['quantity_per_user'] = intval($this->quantity_per_user);
		$fields['cumulable'] = intval($this->cumulable);
		$fields['cumulable_reduction'] = intval($this->cumulable_reduction);
		$fields['date_from'] = pSQL($this->date_from);
		$fields['date_to'] = pSQL($this->date_to);
		$fields['minimal'] = intval($this->minimal);
		$fields['active'] = intval($this->active);

		return $fields;
	}
	
	public function getTranslationsFieldsChild()
	{
		parent::validateFieldsLang();
		return parent::getTranslationsFields(array('description'));
	}
	
	/**
	  * Return discount types list
	  *
	  * @return array Discount types
	  */
	static public function getDiscountTypes($id_lang)
	{
		return Db::getInstance()->ExecuteS('
		SELECT *
		FROM '._DB_PREFIX_.'discount_type dt
		LEFT JOIN `'._DB_PREFIX_.'discount_type_lang` dtl ON (dt.`id_discount_type` = dtl.`id_discount_type` AND dtl.`id_lang` = '.intval($id_lang).')');
	}
    
	/**
	  * Get discount ID from name
	  *
	  * @param string $discountName Discount name
	  * @return integer Discount ID
	  */
	public static function getIdByName($discountName)
	{
	 	if (!Validate::isDiscountName($discountName))
	 		die(Tools::displayError());
	 		
		$result = Db::getInstance()->getRow('
		SELECT `id_discount`
		FROM `'._DB_PREFIX_.'discount`
		WHERE `name` = \''.pSQL($discountName).'\'');
		return isset($result['id_discount']) ? $result['id_discount'] : false;
	}
	
	/**
	  * Return customer discounts
	  *
	  * @param integer $id_lang Language ID
	  * @param boolean $id_customer Customer ID
	  * @return array Discounts
	  */
	static public function getCustomerDiscounts($id_lang, $id_customer, $active = false, $includeGenericOnes = true)
    {
		global $cart;
		
    	$res = Db::getInstance()->ExecuteS('
        SELECT d.*, dtl.`name` AS `type`, dl.`description`
		FROM `'._DB_PREFIX_.'discount` d
		LEFT JOIN `'._DB_PREFIX_.'discount_lang` dl ON (d.`id_discount` = dl.`id_discount` AND dl.`id_lang` = '.intval($id_lang).')
		LEFT JOIN `'._DB_PREFIX_.'discount_type` dt ON dt.`id_discount_type` = d.`id_discount_type`
		LEFT JOIN `'._DB_PREFIX_.'discount_type_lang` dtl ON (dt.`id_discount_type` = dtl.`id_discount_type` AND dtl.`id_lang` = '.intval($id_lang).')
		WHERE (`id_customer` = '.intval($id_customer).($includeGenericOnes ? ' OR `id_customer` = 0' : '').')'.($active ? ' AND d.`active` = 1' : ''));
		
		foreach ($res as &$discount)
			if ($discount['quantity_per_user'])
			{
				$quantity_used = Order::getDiscountsCustomer(intval($id_customer), intval($discount['id_discount']));
				if (isset($cart) AND isset($cart->id))
					$quantity_used += $cart->getDiscountsCustomer(intval($discount['id_discount']));
				$discount['quantity_for_user'] = $discount['quantity_per_user'] - $quantity_used;
			}
			else
				$discount['quantity_for_user'] = 0;
		return $res;
	}
	
	/**
	  * Return discount value
	  *
	  * @param integer $nb_discounts Number of discount currently in cart
	  * @param boolean $order_total_products Total cart products amount
	  * @return mixed Return a float value or '!' if reduction is 'Shipping free'
	  */
	function getValue($nb_discounts = 0, $order_total_products = 0, $shipping_fees = 0)
    {
		$totalAmount = floatval($order_total_products) + floatval($shipping_fees);
        if ($this->minimal > 0 AND $totalAmount < $this->minimal)
			return 0;
        if (!$this->cumulable AND intval($nb_discounts) > 1)
			return 0;
		if (!$this->active)
			return 0;
		if (!$this->quantity)
			return 0;
		
        $date_start = strtotime($this->date_from);
        $date_end = strtotime($this->date_to);
        if (time() < $date_start OR time() > $date_end) return 0;

        switch ($this->id_discount_type)
        {
            case 1:
                // %
                $percentage = $this->value / 100;
                return $percentage * $totalAmount;
            case 2:
                // amount
                return $this->value;
            case 3:
                // Shipping is free
                return '!';
        }
		return 0;
    }

	static public function discountExists($discountName, $id_discount = 0)
	{
		return Db::getInstance()->getRow('SELECT `id_discount` FROM '._DB_PREFIX_.'discount WHERE `name` LIKE \''.$discountName.'\' AND `id_discount` != '.intval($id_discount));
	}

	static public function createOrderDiscount($order, $productList, $qtyList, $name)
	{
		$languages = Language::getLanguages($order);
		$products = $order->getProducts(false, $productList, $qtyList);
		$total = $order->getTotalProductsWithTaxes($products);

		// create discount
		$voucher = new Discount();
		$voucher->id_discount_type = 2;
		foreach ($languages as $language)
			$voucher->description[$language['id_lang']] = strval($name).' '.$order->id;
		$voucher->value = floatval($total);
		$voucher->name = 'V0C'.intval($order->id_customer).'O'.$order->id;
		$voucher->id_customer = intval($order->id_customer);
		$voucher->quantity = 1;
		$voucher->quantity_per_user = 1;
		$voucher->cumulable = 1;
		$voucher->cumulable_reduction = 1;
		$voucher->minimal = $voucher->value;
		$voucher->active = 1;
		$now = time();
		$voucher->date_from = date('Y-m-d H:i:s', $now);
		$voucher->date_to = date('Y-m-d H:i:s', $now + (60 * 60 * 24 * 184));
		//Tools::dieObject($voucher);
		if (!$voucher->validateFieldsLang(false) OR !$voucher->add())
			return false;

		// set correct name
		$voucher->name = 'V'.intval($voucher->id).'C'.intval($order->id_customer).'O'.$order->id;
		if (!$voucher->update())
			return false;
		
		return $voucher;
	}

	static public function display($discountValue, $discountType, $currency=false)
	{
		if (floatval($discountValue) AND intval($discountType))
		{
			if ($discountType == 1)
				return $discountValue.chr(37); // ASCII #37 --> % (percent)
			elseif ($discountType == 2)
				return Tools::displayPrice($discountValue, $currency);
		}
		return ''; // return a string because it's a display method
	}

}

?>