<?php
/**
 * IMPORTANT NOTE
 * The code of this system is closed and a private proprietary of Flex Solutions.
 * A written authorization/license from Flex Solutions is required before using or modifying this code.
 * Email: sales@flexsolution.biz, Phone: +962795342585, Website: http://www.flexsolutions.biz
 */
 

/**
 * This is the model class for table "badge".
 *
 * The followings are the available columns in table 'badge':
 * @property integer $id
 * @property integer $number
 * @property integer $type_id
 * @property integer $person_id
 * @property string $activation_start_date
 * @property string $activation_end_date
 * @property integer $max_served_meals
 * @property string $status
 * @property integer $created_by
 * @property string $created_date
 * @property integer $last_edited_by
 * @property string $last_edited_date
 *
 * The followings are the available model relations:
 * @property BadgeType $type
 * @property Person $person
 * @property Ticket[] $tickets
 */
class Badge extends LsmsActiveRecord
{


    /**
     * Returns the static model of the specified AR class.
     * @param string $className active record class name.
     * @return Badge the static model class
     */
    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return 'badge';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('number, type_id, status', 'required'),
            array('type_id, person_id, max_served_meals', 'numerical', 'integerOnly' => true),
            array('status', 'length', 'max' => 8),
            array('activation_start_date, activation_end_date', 'safe'),
            array('number', 'unique', 'message' => yii::t('dafault', 'Badge Number ({value}) already exists.')),
            //Check If assignment is available
            array('person_id, max_served_meals,activation_start_date, activation_end_date', 'required', 'on' => 'assignment'),
            /*
             * The following validation is responsible to check if there is a rule for the assignee badge to person
             * and check if the person have all badges wich have right to assiged to him or there is chance to
             * assigne to new one
             */
            array('person_id', 'assigneValidate', 'on' => 'assignment'),
            //The following validation is responsible for check max Served Meals is in range that limited at badge type
            array('max_served_meals', 'maxServedMealsValidate', 'on' => 'assignment'),
            //The following validation is responsible for check if the Activation period is true
            array('activation_end_date', 'activationEndDateValidate', 'on' => 'assignment'),
            // The following rule is used by search().
            // Please remove those attributes that should not be searched.
            array('id, number, type_id, person_id, activation_start_date, activation_end_date, max_served_meals, status', 'safe', 'on' => 'search'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations()
    {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
            'type' => array(self::BELONGS_TO, 'BadgeType', 'type_id'),
            'person' => array(self::BELONGS_TO, 'Person', 'person_id'),
            'tickets' => array(self::HAS_MANY, 'Ticket', 'badge_id'),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'number' => yii::t('default', 'Badge Number'),
            'type_id' => yii::t('default', 'Badge Type'),
            'person_id' => yii::t('default', 'Person Name'),
            'activation_start_date' => yii::t('default', 'Activation Start Date'),
            'activation_end_date' => yii::t('default', 'Activation End Date'),
            'max_served_meals' => yii::t('default', 'Max Served Meals'),
            'status' => yii::t('default', 'Status'),
        );
    }

    /**
     * @return array customized attribute labels Tooltips (name=>label tooltips)
     */
    public function attributeLabelsPopover()
    {
        return array(
            'number' => yii::t('default', 'tooltip_number'),
            'type_id' => yii::t('default', 'Badge Type'),
            'person_id' => yii::t('default', 'tooltip_person_id'),
            'activation_start_date' => yii::t('default', 'tooltip_activation_start_date'),
            'activation_end_date' => yii::t('default', 'tooltip_activation_end_date'),
            'max_served_meals' => yii::t('default', 'tooltip_max_served_meals'),
            'status' => yii::t('default', 'Status'),
        );
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function search($person_compare=true)
    {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.

        $criteria = new CDbCriteria;

        $criteria->compare('t.number', $this->number, true);
        $criteria->compare('t.type_id', $this->type_id);
        if ($person_compare == true)
            $criteria->compare('Person.name', $this->person_id, true);
        else
            $criteria->compare('person_id', $this->person_id, $person_compare);
        $criteria->compare('activation_start_date', $this->activation_start_date, true);
        $criteria->compare('activation_end_date', $this->activation_end_date, true);
        $criteria->compare('max_served_meals', $this->max_served_meals, true);
        $criteria->compare('t.status', $this->status);

        $pageSize = $this->yiiparam('pageSize');
        return new CActiveDataProvider($this, array(
            'pagination' => array('pageSize' => $pageSize,),
            'criteria' => $criteria,
        ));
    }

    /*
     * The follwoing function return all Badges
     */

    public static function getAll($status=null)
    {
        if ($status == "Active")
        {
            return Badge::model()->active()->findAll(array('order' => 'Number'));
        }
        else
        {
            return Badge::model()->findAll(array('order' => 'Number'));
        }
    }

    /*
     * The follwoing function return all Free Badges
     */

    public static function getArrayOfBadges($status)
    {
        if (($status != null ) && ($status != 'All'))
        {
            $all_Badge = Badge::model()->findAllByAttributes(array('status' => $status));
        }
        else
        {
            $all_Badge = Badge::model()->findAll();
        }
        $result = array();
        foreach ($all_Badge as $badge)
        {
            $result[$badge->id] = $badge->number;
        }
        return $result;
    }

    /*
     * The following validation is responsible to check if there is a rule for the assignee badge to person
     * and check if the person have all badges wich have right to assiged to him or there is chance to
     * assigne to new one
     */

    public function assigneValidate($attribute, $params)
    {
        if (isset($this->person_id) && ($this->person_id != "" ))
        {
            $person = Person::model()->findByPk($this->person_id);
            $badge = Badge::model()->findByPk($this->id);
            //Checking if the operation is assigned to a new different person
            if ($badge->person_id != $this->person_id)
            {
                $badge_type_id = $this->type_id;

                $max_badges_allowed = BadgeAssignmentRule::getMaxBadgeAllowed($person, $badge_type_id);

                //There is no rule for this type of assignment
                if ($max_badges_allowed == -1)
                {
                    $this->addError($attribute, Yii::t('default', 'There is no badge assignment rule that permits the assignment of this badge to the selected person type, please contact the system administrator'));
                }
                //check available badge can be assigned for person
                else if ($max_badges_allowed > 0)
                {
                    $assaigned_badges_array = Badge::getCountAssignedBadgesToPerson($person, $this);
                    if ($assaigned_badges_array >= $max_badges_allowed)
                    {
                        $this->addError($attribute, Yii::t('default', 'You have already assigned the maximum allowed number of badges to the selected person.'));
                    }
                }
            }
        }
    }

    /*
     * The following validation is responsible for check max Served Meals is in range that limited at badge type
     *
     */

    public function maxServedMealsValidate($attribute, $params)
    {
        if (isset($this->max_served_meals) && ($this->max_served_meals != "" ))
        {
            if ($this->max_served_meals <= 0)
            {
                $this->addError($attribute, Yii::t('default', 'The Max Served Meals cannot be less than one'));
                return;
            }
            $person = Person::model()->findByPk($this->person_id);
            if ($person != null)
            {
                $max_served_meals = Badge::getMaxServedMeals($person, $this);
                if ($this->max_served_meals > $max_served_meals)
                {
                    $this->addError($attribute, Yii::t('default', 'The Max Served Meals cannot exceed {n} Meal(s)', $max_served_meals));
                    return;
                }
            }
        }
    }

    /*
     *  The following validation is responsible for check if the Activation period is true
     */

    public function activationEndDateValidate($attribute, $params)
    {
        if (isset($this->activation_end_date) && ($this->activation_end_date != "" ))
        {
            $activation_end_date = date($this->activation_end_date);
            $activation_start_date = date($this->activation_start_date);
            if ($activation_end_date < $activation_start_date)
            {
                $this->addError($attribute, Yii::t('default', 'The Activation Start Date must precede the Activation End Date'));
                return;
            }
            $activation_period = $this->type->activation_period;
            $date = date("Y-m-d", strtotime(date("Y-m-d", strtotime($activation_start_date)) . " +$activation_period month"));
            if ($date < $activation_end_date)
            {
                $this->addError($attribute, Yii::t('default', 'The Activation Period cannot exceed {n} month(s)', $activation_period));
            }

	    $date_format = DateTime::createFromFormat('Y-m-d', $activation_end_date);
	    if ($date_format && $date_format->format('Y-m-d') != $activation_end_date)
		$this->addError($attribute, Yii::t('default', 'The Activation End Date is not a valid date {n}', $activation_period));

	    $date_format = DateTime::createFromFormat('Y-m-d', $activation_start_date);
	    if ($date_format && $date_format->format('Y-m-d') != $activation_start_date)
		$this->addError($attribute, Yii::t('default', 'The Activation Start Date is not a valid date {n}', $activation_start_date));
        }
    }

    /*
     * Ther Following function is responsible for counting the number of badges have specific type which assigned to a person
     * Input: $person
     *        $badge
     * Output: The number of assigned badges to this person
     *          0 : if there are no badges assigned to him
     */

    public static function getCountAssignedBadgesToPerson($person=null, $badge=null)
    {
        $assaigned_badges_array = Badge::model()->findAllByAttributes(array('type_id' => $badge->type_id, 'person_id' => $person->id), array(
                    'condition' => 'status=:status or status=:status2',
                    'params' => array(':status' => 'Active', ':status2' => 'Inactive')
                ));
        if (isset($assaigned_badges_array) && ($assaigned_badges_array != null))
        {
            return count($assaigned_badges_array);
        }
        return 0;
    }

    /*
     * Ther Following function is responsible for Getting the max served meals to badge based on badge type and person type
     * Input: $person
     *        $badge
     * Output: The number of Max Served Meals
     */

    public static function getMaxServedMeals($person=null, $badge=null)
    {
        $max_served_meals = 0;
        if (($badge != null) && ($person != null))
        {
            $badge_manager_meals = $badge->type->manager_meals;
            $badge_food_manager_meals = $badge->type->food_manager_meals;
            if (($person->is_manager == 1) && ($person->is_food_manager == 1))
            {
                $max_served_meals = $badge_manager_meals > $badge_food_manager_meals ? $badge_manager_meals : $badge_food_manager_meals;
            }
            else
            if ($person->is_manager == 1)
            {
                $max_served_meals = $badge->type->manager_meals;
            }
            else if ($person->is_food_manager == 1)
            {
                $max_served_meals = $badge->type->food_manager_meals;
            }
            else
            {
                $max_served_meals = $badge->type->non_manager_meals;
            }
        }
        return $max_served_meals;
    }

    /*
     * the following function is responsible for check the badge if expired or not 
     */

    public function isExpired()
    {
        $now_date = date("Y-m-d");
        $activation_end_date = date($this->activation_end_date);
        if ($activation_end_date < $now_date)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public static function getNotifiedBadges()
    {
        $badges = Badge::model()->with('type')->findAllByAttributes(array('notify_before_badge_expire' => 0));
    }

    /*
     * the following function is responsible for adding and assign badge to person or just assign badge to person
     * input:
     *         1-$badge_number: the number of badges which will be adding to system if not exist
     *                          and if it has been added , it will assign to a person
     *         2-$badge_type_name: specified the type to add badge we need its type  for adding
     *         3-$person_model: the person who assigns badge to him
     * output:
     *         1-$error: if there is error in process will assign for error as output parameter
     *         2- the function returns true if don't happen any error and false else that
     *
     */

    public static function addAndAssignBadge($badge_number, $badge_type_name, $person_model, &$error)
    {
        if (($badge_number != null ) && ($badge_number != 'N/A') && ($badge_number != '') && is_numeric($badge_number))
        {
            //Check if Badge have been added to system
            $Badge_model = Badge::model()->findByAttributes(array('number' => $badge_number));
            if ($Badge_model == null)
            {
                //Check if badge type is null
                if (($badge_type_name != null ) && ($badge_type_name != ''))
                {
                    $badge_type_id = BadgeType::getID($badge_type_name);
                    if ($badge_type_id != -1)
                    {
                        $Badge_model = new Badge;
                        $Badge_model->number = $badge_number;
                        $Badge_model->type_id = $badge_type_id;
                        $Badge_model->status = 'Free';
                        if (!$Badge_model->save())
                        {
                            $error = CHtml::errorSummary($Badge_model);
                            return false;
                        }
                    }
                    else
                    {
                        $error = yii::t('default', 'The Badge Type ({n}) has not been added to the system', $badge_type_name);
                        return false;
                    }
                }
                else
                {
                    $error = yii::t('default', 'The Badge Type name is empty');
                    return false;
                }
            }
            //Assign Badge to person
            if (($Badge_model->status == 'Free') && ($person_model != null))
            {
                $Badge_model->setScenario('assignment');
                $Badge_model->status = 'Active';
                $Badge_model->person_id = $person_model->id;
                $Badge_model->max_served_meals = Badge::getMaxServedMeals($person_model, $Badge_model);
                $activation_period = $Badge_model->type->activation_period;
                $activation_start_date = date("Y-m-d");
                $Badge_model->activation_start_date = $activation_start_date;
                $Badge_model->activation_end_date = date("Y-m-d", strtotime(date("Y-m-d", strtotime($activation_start_date)) . " +$activation_period month"));
                if (!$Badge_model->save())
                {
                    $error = yii::t('default', 'There is no badge assignment rule that permits the assignment of badge type (badge_type) to the person type (person_type), the error ', array('badge_type' => $Badge_model->type->name, 'person_type' => $person_model->type->name));
                    return false;
                }
                else
                    return true;
            }
            else// the person not found or the badge isn't free for assigning
            {
                $error = '';
                return false;
            }
        }
        else // There is no badge assignto person at Active directory
        {
            $error = '';
            return false;
        }
    }

}