<?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 "invoice".
 *
 * The followings are the available columns in table 'invoice':
 * @property integer $id
 * @property integer $tid_id
 * @property string $number
 * @property string $value
 * @property string $description
 * @property string $comments
 * @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 Asset[] $assets
 * @property Tid $tid
 *
 * @author Amaney
 * @package application.models
 */
class Invoice extends TidansActiveRecord {

    public $from_tid, $warning_msg, $tid_identifier, $old_tid;
    /*
     * Asset Information
     */
    public $segment_name, $serial_number, $asset_number, $part_number,
    $type_of_asset_name, $asset_status, $plate_number, $chassis_number,
    $radioactive_license_number;

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

    /**
     * @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('tid_id, number', 'required'),
	    //array('tid_id', 'numerical', 'integerOnly' => true),
	    array('value', 'validateValue'),
	    array('number', 'length', 'max' => 50),
	    array('value', 'length', 'max' => 15),
	    array('number', 'uniqueNotification'),
	    array('tid_id', 'validateTIDIdentifier'),
	    array('description, comments', 'length', 'max' => 255),
	    // The following rule is used by search().
	    // @todo Please remove those attributes that should not be searched.
	    array('from_tid,id, tid_id, number, value, description, comments,
		   segment_name,serial_number,asset_number,part_number,
		   type_of_asset_name,asset_status,plate_number,chassis_number,radioactive_license_number', '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(
	    'assets' => array(self::HAS_MANY, 'Asset', 'invoice_id'),
	    'tid' => array(self::BELONGS_TO, 'Tid', 'tid_id'),
	);
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels() {
	return array(
	    'tid_id' => Yii::t('default', 'TID No'),
	    'number' => Yii::t('default', 'Invoice Number'),
	    'value' => Yii::t('default', 'Invoice Value'),
	    'description' => Yii::t('default', 'Description'),
	    'comments' => Yii::t('default', 'Comments'),
	    'last_edited_by' => Yii::t('default', 'Last Updated By'),
	    'segment_name' => Yii::t('default', 'Asset Segment'),
	    'serial_number' => Yii::t('default', 'Asset Serial Number'),
	    'asset_number' => Yii::t('default', 'Asset Number'),
	    'part_number' => Yii::t('default', 'Asset Part Number'),
	    'type_of_asset_name' => Yii::t('default', 'Asset Type'),
	    'asset_status' => Yii::t('default', 'Asset Status'),
	    'plate_number' => Yii::t('default', 'Plate Number'),
	    'chassis_number' => Yii::t('default', 'Chassis Number'),
	    'radioactive_license_number' => Yii::t('default', 'Radioactive License Number'),
	);
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     *
     * Typical usecase:
     * - Initialize the model fields with values from filter form.
     * - Execute this method to get CActiveDataProvider instance which will filter
     * models according to data in model fields.
     * - Pass data provider to CGridView, CListView or any similar widget.
     *
     * @return CActiveDataProvider the data provider that can return the models
     * based on the search/filter conditions.
     */
    public function search($tid_id = null) {
	// @todo Please modify the following code to remove attributes that should not be searched.

	$criteria = $this->ModelCriteria($tid_id);

	$sort = new CSort();

	$sort->attributes = array(
	    'tid_id' => array(
		'asc' => 'tid.tid_no',
		'desc' => 'tid.tid_no desc',
	    ),
	    '*',
	);

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

    /**
     * Get the query used to get the current model information to be used in export to excel action
     * @return CDbCriteria the criteria used to get the current model information
     */
    public function ModelCriteria($tid_id = null, $with_assets = null) { // @todo Please modify the following code to remove attributes that should not be searched.
	$criteria = new CDbCriteria;

	$criteria->compare('t.id', $this->id);
	$criteria->compare('tid.tid_no', $this->tid_id, true);
	$criteria->compare('t.number', $this->number, true);
	$criteria->compare('t.value', $this->value, true);
	$criteria->compare('t.description', $this->description, true);
	$criteria->compare('t.comments', $this->comments, true);
	$criteria->join = 'inner join tid on tid.id = t.tid_id
			 left join user on user.id = t.last_edited_by';

	if ($tid_id != null)
	    $criteria->addCondition('t.tid_id=' . $tid_id);
	else
	    $criteria->compare('t.tid_id', $this->from_tid);

	//assets & invoice
	$ids = $this->setAssetConditions($criteria);
	if ($ids != '')
	    $criteria->addCondition('t.id in (' . $ids . ')');

	if ($with_assets != null) {
	    $criteria->join .= ' left join v_asset on v_asset.invoice_id = t.id';
	}


	return $criteria;
    }

    /**
     * Returns the static model of the specified AR class.
     * Please note that you should have this exact method in all your CActiveRecord descendants!
     * @param string $className active record class name.
     * @return Invoice the static model class
     */
    public static function model($className=__CLASS__) {
	return parent::model($className);
    }

    /**
     * The Following function is responsible for return array of all Invoices
     *
     * @return Invoice[] array of Invoice model .
     */
    public static function getNumberForView() {
	$result = Invoice::getNumberLists();
	$names = array();
	foreach ($result as $res) {
	    $names[$res] = $res;
	}
	return $names;
    }

    /**
     * The Following function is responsible for return array of all Invoices
     *
     * @return Invoice[] array of Invoice model .
     */
    public static function getNumberLists() {
	$model = Invoice::model();
	$criteria = new CDbCriteria;
	$criteria->select = 'number';
	$criteria->order = 'number';
	return $model->commandBuilder->createFindCommand($model->tableName(), $criteria)->queryColumn();
    }

    /**
     * The Following function is responsible for return array of all Invoices to display in drop dwon
     *
     * @return Invoice[] array of Invoice model .
     */
    public static function getNumbersForDropDown($tid_id, $invoice_id = null) {
	$model = Invoice::model();
	$criteria = new CDbCriteria;
	$criteria->select = 't.id,t.number';
	$criteria->order = 't.number';
	if ($tid_id != null && $tid_id != '') {
	    $criteria->join = 'inner join tid on t.tid_id = tid.id';
	    $criteria->condition = "tid_no ='" . $tid_id . "'";
	}
	if ($invoice_id != null && $invoice_id != '')
	    $criteria->condition = "t.id =" . $invoice_id;

	$result = $model->commandBuilder->createFindCommand($model->tableName(), $criteria)->queryAll();
	$names = array();
	foreach ($result as $res) {
	    $names[$res['id']] = $res['number'];
	}
	return $names;
    }

    /**
     * check if asset and invoice info is applied in the seach query and build the query for it
     * @param string $error_msg the error msg if query failed
     * @return String the ids of Invoices seperated by comma that satisfy the conditions
     */
    public function setAssetConditions() {
	$ids = "";
	if ($this->serial_number != null ||
		$this->asset_number != null || $this->part_number != null ||
		$this->asset_status != null || $this->plate_number != null ||
		$this->chassis_number != null || $this->radioactive_license_number != null ||
		$this->segment_name != null || $this->type_of_asset_name != null) {

	    $criteria = new CDbCriteria();
	    $criteria->select = 't.invoice_id';
	    $criteria->compare('serial_number', $this->serial_number, true);
	    $criteria->compare('asset_number', $this->asset_number, true);
	    $criteria->compare('part_number', $this->part_number, true);
	    $criteria->compare('asset_status', $this->asset_status, true);
	    $criteria->compare('plate_number', $this->plate_number, true);
	    $criteria->compare('chassis_number', $this->chassis_number, true);
	    $criteria->compare('radioactive_license_number', $this->radioactive_license_number, true);
	    $criteria->compare('segment_name', $this->segment_name, true);
	    $criteria->compare('type_of_asset_name', $this->type_of_asset_name, true);


	    $model = new VAsset();
	    $result = $model->commandBuilder->createFindCommand(
			    $model->tableName(), $criteria)->queryAll();


	    foreach ($result as $res) {
		$ids .= $res['invoice_id'] . ",";
	    }
	    $ids = substr($ids, 0, -1);
	    if ($ids == '')
		$ids = '-1';
	}
	return $ids;
    }

    /**
     * The following validation is responsible for checking if the invoice number are unique
     */
    public function uniqueNotification($attribute, $params) {
	if ($this->$attribute != '') {
	    $criteria = new CDbCriteria;
	    $criteria->select = $attribute;
	    $criteria->condition = $attribute . "='" . $this->$attribute . "'";
	    if (!$this->isNewRecord)
		$criteria->condition .= " and id !=" . $this->id;
	    $result = $this->commandBuilder->createFindCommand($this->tableName(), $criteria)->queryAll();
	    if ($result != null && count($result) > 0) {
		$this->warning_msg .= Yii::t('default', 'The ' . $attribute . ' (' . $this->$attribute . ') has already been taken.') . "Do you want to use the same value for " . $attribute . '?';
		;
		return false;
	    }
	}
    }

    /**
     * The following validation is responsible for checking if the value has this format #.# where # means any number
     */
    public function validateValue($attribute, $params) {
	if ($this->value != null && $this->value != '') {
	    $numbers = explode('.', $this->value);
	    if (count($numbers) > 2)
		$this->addError('value', Yii::t('default', 'The value should be a valid real number.'));
	    else {
		if (count($numbers) == 1) {
		    if (!is_numeric($numbers[0]))
			$this->addError('value', Yii::t('default', 'The value should be a valid real number.'));
		}
		else {
		    if (!is_numeric($numbers[0]) || !is_numeric($numbers[1]))
			$this->addError('value', Yii::t('default', 'The value should be a valid real number.'));
		}
	    }
	}
    }

    /**
     * Check for warning msg attribute and set falsh msg if exist
     */
    public function setWarningMsg() {
	if ($this->warning_msg != '') {
	    Yii::app()->user->setFlash('warning', $this->warning_msg);
	}
    }

    /**
     * The following validation is responsible for checking if tid identifier is in auto complete list or not
     */
    function validateTIDIdentifier($attribute, $params) {

	if (!Tid::checkTidInsideArrayOfTids($this->tid_identifier)) {
	    $this->addError('tid_id', Yii::t('default', "The TID (tid_no) is not valid, just start typing the TID No then select the required TID.", array('tid_no' => $this->tid_id)));
	}
    }

    protected function afterFind() {
	$this->old_tid = $this->tid_id;
	return parent::afterFind();
    }

    protected function beforeSave() {
	if ($this->old_tid != $this->tid_id && $this->assets != null && count($this->assets) > 0)
	{
	    $this->addError('tid_id', Yii::t('default', 'You cannot change tid because the invoice has assets'));
	    return false;
	}
	return parent::beforeSave();
    }

}
