<?php

/**
 * This is the model class for table "reporte_haberes".
 *
 * The followings are the available columns in table 'reporte_haberes':
 *
 * @property int    $cedula
 * @property string $nombre
 * @property string $apellidos
 * @property string $fecha_registro
 * @property int    $id_unidad
 * @property string $nombre_estatus
 * @property string $aporte_extra_socio
 * @property string $aporte_extra_patrono
 * @property float  $aporte_patrono
 * @property float  $aporte_asociado
 * @property float  $aporte_total
 * @property float  $retiro_parcial
 * @property float  $monto_liquidado
 * @property float  $nombre_estatus
 */
class ReporteHaberes extends CActiveRecord
{
    public $desdeA;
    public $fecha_ingreso;
    public $hastaA;
    public $desdeH;
    public $hastaH;
    public $id_estatus;
    public $estatus_aporte;
    public $porcentaje_disponible;
    public $nombre_unidad;
    public $columnas;
    public $id_porcentaje_interes;
    public $interes_calculado;

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

    /**
     * @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 [
            ['cedula, id_unidad, id_porcentaje_interes', 'numerical', 'integerOnly' => true],
            ['aporte_patrono, aporte_asociado, aporte_total, retiro_parcial, monto_liquidado', 'numerical'],
            ['nombre, apellidos', 'length', 'max' => 100],
            [
                'fecha_registro,fechaingreso, aporte_extra_socio, aporte_extra_patrono,id_estatus,aprobado,pagado,idtipotrabajador,tipo_trabajador',
                'safe',
            ],
            // The following rule is used by search().
            // @todo Please remove those attributes that should not be searched.
            [
                'cedula, nombre, apellidos, fecha_registro,fechaingreso, id_unidad, aporte_extra_socio,idtipotrabajador,tipo_trabajador, aporte_extra_patrono,
             aporte_patrono, aporte_asociado, aporte_total, retiro_parcial, monto_liquidado, desdeA, hastaA, desdeH, hastaH,id_estatus,aprobado,pagado,
             id_porcentaje_interes',
                'safe',
                'on' => 'search',
            ],
        ];
    }

    public function primaryKey()
    {
        return 'cedula';
    }

    /**
     * @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 [
            'unidad' => [self::BELONGS_TO, 'Unidad', 'id_unidad'],
        ];
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return [
            'cedula' => 'Cedula',
            'nombre' => 'Nombre',
            'apellidos' => 'Apellidos',
            'fecha_registro' => 'Fecha ingreso',
            'fechaingreso' => 'Fecha ingreso',
            'id_unidad' => 'Unidad',
            'aporte_extra_socio' => 'Aporte extra socio',
            'aporte_extra_patrono' => 'Aporte extra patrono',
            'aporte_patrono' => 'Aporte patrono',
            'aporte_asociado' => 'Aporte asociado',
            'idtipotrabajador' => 'Tipo trabajador',
            'tipo_trabajador' => 'Tipo trabajador',
            'aporte_total' => 'Aporte total',
            'retiro_parcial' => 'Retiro parcial',
            'monto_liquidado' => 'Monto liquidado',
            'desdeA' => 'Desde',
            'desdeH' => 'Desde',
            'hastaA' => 'Hasta',
            'hastaH' => 'Hasta',
            'id_estatus' => 'Estatus del asociado',
            'porcentaje_disponible' => '80% disponible',
            'nombre_banco' => 'Banco',
            'numero_cuenta' => 'Número de cuenta',
            'id_porcentaje_interes' => 'Porcentaje de intéres',
        ];
    }

    public function getColumns($all = false)
    {
        $columnas = [
            'cedula' => [
                'label' => 'Cédula',
                'color' => 'C00000',
                'alineacion' => 'PHPExcel_Style_Alignment::HORIZONTAL_LEFT',
                'total' => false,
                'visible' => true,
            ],
            'nombre' => [
                'label' => 'Nombre',
                'color' => 'C00000',
                'alineacion' => 'PHPExcel_Style_Alignment::HORIZONTAL_LEFT',
                'total' => false,
                'visible' => true,
            ],
            'apellidos' => [
                'label' => 'Apellidos',
                'color' => 'C00000',
                'alineacion' => 'PHPExcel_Style_Alignment::HORIZONTAL_LEFT',
                'total' => false,
                'visible' => true,
            ],
            'fecha_registro' => [
                'label' => 'Fecha ingreso',
                'color' => 'C00000',
                'alineacion' => 'PHPExcel_Style_Alignment::HORIZONTAL_LEFT',
                'total' => false,
                'visible' => true,
            ],
            'id_unidad' => [
                'label' => 'Unidad',
                'color' => 'C00000',
                'alineacion' => 'PHPExcel_Style_Alignment::HORIZONTAL_LEFT',
                'total' => false,
                'visible' => true,
            ],
            'tipo_trabajador' => [
                'label' => 'Tipo de trabajador',
                'color' => 'C00000',
                'alineacion' => 'PHPExcel_Style_Alignment::HORIZONTAL_LEFT',
                'total' => false,
                'visible' => true,
            ],
            'estatus_asociado' => [
                'label' => 'Estatus asociado',
                'color' => 'C00000',
                'alineacion' => 'PHPExcel_Style_Alignment::HORIZONTAL_LEFT',
                'total' => false,
                'visible' => true,
            ],
            'nombre_banco' => [
                'label' => 'Banco',
                'color' => 'C00000',
                'alineacion' => 'PHPExcel_Style_Alignment::HORIZONTAL_LEFT',
                'total' => false,
                'visible' => true,
            ],
            'numero_cuenta' => [
                'label' => 'Número de cuenta',
                'color' => 'C00000',
                'alineacion' => 'PHPExcel_Style_Alignment::HORIZONTAL_LEFT',
                'total' => false,
                'raw' => true,
                'visible' => true,
            ],
            'aporte_extra_socio' => [
                'label' => 'Aporte extra asociado',
                'color' => 'C00000',
                'alineacion' => 'PHPExcel_Style_Alignment::HORIZONTAL_LEFT',
                'formato' => '#,##0.00',
                'total' => true,
                'visible' => true,
            ],
            'aporte_extra_patrono' => [
                'label' => 'Aporte extra patrono',
                'color' => 'C00000',
                'alineacion' => 'PHPExcel_Style_Alignment::HORIZONTAL_LEFT',
                'formato' => '#,##0.00',
                'total' => true,
                'visible' => true,
            ],
            'aporte_patrono' => [
                'label' => 'Aporte patrono',
                'color' => 'C00000',
                'alineacion' => 'PHPExcel_Style_Alignment::HORIZONTAL_LEFT',
                'formato' => '#,##0.00',
                'total' => true,
                'visible' => true,
            ],
            'aporte_asociado' => [
                'label' => 'Aporte asociado',
                'color' => 'C00000',
                'alineacion' => 'PHPExcel_Style_Alignment::HORIZONTAL_LEFT',
                'formato' => '#,##0.00',
                'total' => true,
                'visible' => true,
            ],
            'aporte_total' => [
                'label' => 'Aporte total',
                'color' => 'C00000',
                'alineacion' => 'PHPExcel_Style_Alignment::HORIZONTAL_LEFT',
                'formato' => '#,##0.00',
                'total' => true,
                'visible' => true,
            ],
            'asignacion_monto_patrono' => [
                'label' => 'Asignación monto patrono',
                'color' => 'C00000',
                'alineacion' => 'PHPExcel_Style_Alignment::HORIZONTAL_LEFT',
                'formato' => '#,##0.00',
                'total' => true,
                'visible' => true,
            ],
            'asignacion_monto_asociado' => [
                'label' => 'Asignación monto asociado',
                'color' => 'C00000',
                'alineacion' => 'PHPExcel_Style_Alignment::HORIZONTAL_LEFT',
                'formato' => '#,##0.00',
                'total' => true,
                'visible' => true,
            ],
            'descuento_monto_patrono' => [
                'label' => 'Descuento monto patrono',
                'color' => 'C00000',
                'alineacion' => 'PHPExcel_Style_Alignment::HORIZONTAL_LEFT',
                'formato' => '#,##0.00',
                'total' => true,
                'visible' => true,
            ],
            'descuento_monto_asociado' => [
                'label' => 'Descuento monto asociado',
                'color' => 'C00000',
                'alineacion' => 'PHPExcel_Style_Alignment::HORIZONTAL_LEFT',
                'formato' => '#,##0.00',
                'total' => true,
                'visible' => true,
            ],
            'dividendos' => [
                'label' => 'Dividendos',
                'color' => 'C00000',
                'alineacion' => 'PHPExcel_Style_Alignment::HORIZONTAL_LEFT',
                'formato' => '#,##0.00',
                'total' => true,
                'visible' => true,
            ],
            'retiro_parcial' => [
                'label' => 'Retiro parcial',
                'color' => 'C00000',
                'alineacion' => 'PHPExcel_Style_Alignment::HORIZONTAL_LEFT',
                'formato' => '#,##0.00',
                'total' => true,
                'visible' => true,
            ],
            'monto_liquidado' => [
                'label' => 'Monto liquidado',
                'color' => 'C00000',
                'alineacion' => 'PHPExcel_Style_Alignment::HORIZONTAL_LEFT',
                'formato' => '#,##0.00',
                'total' => true,
                'visible' => true,
            ],
            'total_haberes' => [
                'label' => 'Total haberes',
                'color' => '0B610B',
                'alineacion' => 'PHPExcel_Style_Alignment::HORIZONTAL_LEFT',
                'formato' => '#,##0.00',
                'total' => true,
                'visible' => true,
            ],
        ];

        if ($all) {
            $columnas['interes_calculado'] = [
                'label' => 'Intéres calculado',
                'color' => '0B610B',
                'alineacion' => 'PHPExcel_Style_Alignment::HORIZONTAL_LEFT',
                'formato' => '#,##0.00',
                'total' => true,
                'visible' => false,
            ];
        }

        return $columnas;
    }

    public function hasColumn($column)
    {
        return array_key_exists($column, $this->getColumnsKeys());
    }

    public function getColumnsKeys()
    {
        return (new Warp($this->columnas))->flatMap(function ($columna) {
            return $columna;
        });
    }

    public function configuracionCampo($path = null)
    {
        return (new Warp($this->getColumns(true)))->get($path, false);
    }

    /**
     * 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()
    {
        // @todo Please modify the following code to remove attributes that should not be searched.

        $criteria = new CDbCriteria();

        $criteria->compare('cedula', $this->cedula);
        $criteria->compare('nombre', $this->nombre, true);
        $criteria->compare('apellidos', $this->apellidos, true);
        $criteria->compare('fecha_registro', $this->fecha_registro, true);
        $criteria->compare('fechaingreso', $this->fechaingreso, true);
        $criteria->compare('id_unidad', $this->id_unidad);
        $criteria->compare('idtipotrabajador', $this->idtipotrabajador);
        $criteria->compare('aporte_extra_socio', $this->aporte_extra_socio, true);
        $criteria->compare('aporte_extra_patrono', $this->aporte_extra_patrono, true);
        $criteria->compare('aporte_patrono', $this->aporte_patrono);
        $criteria->compare('aporte_asociado', $this->aporte_asociado);
        $criteria->compare('aporte_total', $this->aporte_total);
        $criteria->compare('retiro_parcial', $this->retiro_parcial);
        $criteria->compare('monto_liquidado', $this->monto_liquidado);
        $criteria->compare('total_haberes', $this->total_haberes);

        return new CActiveDataProvider($this, [
            'criteria' => $criteria,
        ]);
    }

    public function getReporteHaberesSQL()
    {
        return ReporteHaberes::model()->findAllBySql((new RHQuery($this))->make());
    }

    public function getReporteHaberes()
    {
        // @todo Please modify the following code to remove attributes that should not be searched.

        $criteria = new CDbCriteria();

        $criteria->compare('cedula', $this->cedula);
        $criteria->compare('nombre', $this->nombre, true);
        $criteria->compare('apellidos', $this->apellidos, true);
        //$criteria->compare('fecha_registro',$this->fecha_registro,true);
        $from = $to = '';
        if (isset($this->desde)) {
            $from = $this->desde;
        }
        if (isset($this->hasta)) {
            $to = $this->hasta;
        }
        if ($from != '' || $to != '') {
            if ($from != '' && $to != '') {
                $from = date('d-m-Y', strtotime($from));
                $to = date('d-m-Y', strtotime($to));
                $criteria->compare('fecha_registro', ">= ${from}", false);
                $criteria->compare('fecha_registro', "<= ${to}", false);
            } else {
                if ($from != '') {
                    $creation_time = $from;
                }
                if ($to != '') {
                    $creation_time = $to;
                }
                $creation_time = date('d-m-Y', strtotime($creation_time));
                $criteria->compare('fecha_registro', "${creation_time}", false);
            }
        }
        $criteria->compare('id_unidad', $this->id_unidad);
        $criteria->compare('idtipotrabajador', $this->idtipotrabajador);
        $criteria->compare('aporte_extra_socio', $this->aporte_extra_socio, true);
        $criteria->compare('aporte_extra_patrono', $this->aporte_extra_patrono, true);
        $criteria->compare('aporte_patrono', $this->aporte_patrono);
        $criteria->compare('aporte_asociado', $this->aporte_asociado);
        $criteria->compare('aporte_total', $this->aporte_total);
        $criteria->compare('retiro_parcial', $this->retiro_parcial);
        $criteria->compare('monto_liquidado', $this->monto_liquidado);

        return self::model()->findAll($criteria);
    }

    public function formatearFormula($formula)
    {
        // Si el valor de P es negativo y se tiene una fórmula donde el valor de P es restado (- P), se evaluará de la
        // siguiente forma: --0.3. Lo que ocaciona que `eval` no pueda evaluar correctamente la expresión arrojando
        // error de sintaxis. Se añadiran espacios al rededor del operador -, para que `eval` pueda hacer la
        // correcta evaluación, obteniendo: - - 0.03.
        return preg_replace(['/(?=.\+|\-|\*|\/)/', '/(?<=.\-)/'], ' ', $formula);
    }

    public function haberDisponible($id, $porcentajeDisponibilidad = '')
    {
        $modelBasica = Basica::model()->find([
            'select' => 'formula_disponibilidad_haberes, monto_disponibilidad_solicitudes',
        ]);

        if ($porcentajeDisponibilidad == '') {
            $porcentaje = $modelBasica->porcentaje_disponibilidad;
        } else {
            $porcentaje = $porcentajeDisponibilidad;
        }

        if ($porcentaje < 1) {
            $porcentaje = 80;
        }

        $haberes = (object) Yii::app()
            ->db->createCommand(
                '
            SELECT aporte_total, asignacion_monto_asociado, asignacion_monto_patrono, descuento_monto_asociado, descuento_monto_patrono, retiro_parcial, total_haberes
            FROM reporte_haberes
            WHERE idasociado=:id
            LIMIT 1
        '
            )
            ->bindValue('id', $id)
            ->queryRow();

        if (! $haberes) {
            $haberes = new self();
        }

        $bloqueoTemporal = (new BloqueoTemporal($id))->run();
        $modelMontoTotalDeuda = ReporteCreditos::model()->getTotalMontoDeudaConBloqueo($id);
        $total =
            $haberes->aporte_total +
            $haberes->asignacion_monto_asociado +
            $haberes->asignacion_monto_patrono -
            ($haberes->descuento_monto_asociado + $haberes->descuento_monto_patrono);

        if ($total > 0) {
            $haberBloqueado = $this->haberBloqueado();
        } else {
            $haberBloqueado = 0;
        }

        if ($modelBasica->formula_disponibilidad_haberes != '') {
            $busqueda = ['H', 'R', 'X', 'P'];
            $reemplazar = [
                $total - $haberBloqueado - $bloqueoTemporal,
                $haberes->retiro_parcial,
                $porcentaje / 100,
                $modelMontoTotalDeuda,
            ];
            $formula = $this->formatearFormula(str_replace($busqueda, $reemplazar, $modelBasica->formula_disponibilidad_haberes));

            eval("\$res = ${formula};");
            $montoTotalSolicitud = round($res, 2);
        } else {
            $montoTotalSolicitud = round($haberes->total_haberes * ($porcentaje / 100) - $modelMontoTotalDeuda, 2);
        }

        return $montoTotalSolicitud;
    }

    public function haberDisponibleRetiroParcialPrestamo($id, $porcentajeDisponibilidad = '')
    {
        $modelBasica = Basica::model()->find([
            'select' => 'formula_disponibilidad_haberes, monto_disponibilidad_solicitudes',
        ]);

        if ($porcentajeDisponibilidad == '') {
            $porcentaje = $modelBasica->porcentaje_disponibilidad;
        } else {
            $porcentaje = $porcentajeDisponibilidad;
        }

        if ($porcentaje < 1) {
            $porcentaje = 80;
        }

        $haberes = (object) Yii::app()
            ->db->createCommand(
                '
            SELECT aporte_total, asignacion_monto_asociado, asignacion_monto_patrono, descuento_monto_asociado, descuento_monto_patrono, retiro_parcial, total_haberes
            FROM reporte_haberes
            WHERE idasociado=:id
            LIMIT 1
        '
            )
            ->bindValue('id', $id)
            ->queryRow();

        if (! $haberes) {
            $haberes = new self();
        }

        $bloqueoTemporal = (new BloqueoTemporal($id))->run();
        $modelMontoTotalDeuda = 0;
        $total =
            $haberes->aporte_total +
            $haberes->asignacion_monto_asociado +
            $haberes->asignacion_monto_patrono -
            ($haberes->descuento_monto_asociado + $haberes->descuento_monto_patrono);

        if ($total > 0) {
            $haberBloqueado = $this->haberBloqueado();
        } else {
            $haberBloqueado = 0;
        }

        if ($modelBasica->formula_disponibilidad_haberes != '') {
            $busqueda = ['H', 'R', 'X', 'P'];
            $reemplazar = [
                $total - $haberBloqueado - $bloqueoTemporal,
                $haberes->retiro_parcial,
                $porcentaje / 100,
                $modelMontoTotalDeuda,
            ];
            $formula = $this->formatearFormula(str_replace($busqueda, $reemplazar, $modelBasica->formula_disponibilidad_haberes));
            eval("\$res = ${formula};");
            $montoTotalSolicitud = round($res, 2);
        } else {
            $montoTotalSolicitud = round($haberes->total_haberes * ($porcentaje / 100) - $modelMontoTotalDeuda, 2);
        }

        return $montoTotalSolicitud;
    }

    public function totalAsignacion()
    {
        if (! $this) {
            return 0;
        }

        return $this->asignacion_monto_patrono + $this->asignacion_monto_asociado;
    }

    public function totalDeduccion()
    {
        if (! $this) {
            return 0;
        }

        return $this->descuento_monto_patrono + $this->descuento_monto_asociado;
    }

    public function totalAporte()
    {
        if (! $this) {
            return 0;
        }

        return $this->aporte_total +
            ($this->asignacion_monto_patrono + $this->asignacion_monto_asociado) -
            ($this->descuento_monto_patrono + $this->descuento_monto_asociado);
    }

    public function haberBloqueado()
    {
        if (! $this) {
            return null;
        }

        $totalHaberes = Yii::app()
            ->db->createCommand(
                '
            SELECT (aporte_total + asignacion_monto_asociado + asignacion_monto_patrono) - (descuento_monto_asociado + descuento_monto_patrono)
            FROM reporte_haberes rh
            INNER JOIN asociado a ON a.idasociado=rh.idasociado
            WHERE rh.idasociado=:id
                AND a.id_estatus<>2
            LIMIT 1
        '
            )
            ->bindValue('id', $this->idasociado)
            ->queryScalar();

        if (! $totalHaberes || $totalHaberes == 0) {
            return 0;
        }

        $modelBasica = Basica::model()->find(['select' => 'monto_disponibilidad_solicitudes']);

        if (! $modelBasica) {
            return null;
        }

        if ($modelBasica->opcion_haberes == 1 && $modelBasica->monto_bloqueo_haberes != '') {
            return $modelBasica->monto_bloqueo_haberes;
        }

        if ($modelBasica->porcentaje_bloqueo_haberes == '') {
            return null;
        }

        return self::model()->haberDisponible($this->idasociado, $modelBasica->porcentaje_bloqueo_haberes);
    }

    public function montoDisponibilidad()
    {
        if (! $this) {
            return null;
        }

        $modelBasica = Basica::model()->find([
            'select' => 'formula_disponibilidad_haberes, monto_disponibilidad_solicitudes',
        ]);
        if ($modelBasica->porcentaje_disponibilidad != '') {
            $porcentaje = $modelBasica->porcentaje_disponibilidad;
        } else {
            $porcentaje = 80;
        }
        $montoBloqueado = 0;
        if ($modelBasica->opcion_haberes == 1) {
            if ($modelBasica->monto_bloqueo_haberes != '') {
                $montoBloqueado = $modelBasica->monto_bloqueo_haberes;
            }
        } else {
            if ($modelBasica->porcentaje_bloqueo_haberes != '') {
                $montoBloqueado = self::model()->haberDisponible(
                    $this->idasociado,
                    $modelBasica->porcentaje_bloqueo_haberes
                );
            }
        }

        $modelMontoTotalFiador = ReporteCreditos::model()->getTotalMontoFiador($this->idasociado);
        // $modelMontoTotalDeuda = ReporteCreditos::model()->getTotalMontoDeuda($this->idasociado);
        $modelMontoTotalDeuda = ReporteCreditos::model()->getTotalMontoDeudaConBloqueo($this->idasociado);
        $total = $this->totalAporte() - $this->totalDeduccion() - $montoBloqueado;

        if ($modelBasica->formula_disponibilidad_haberes != '') {
            $busqueda = ['H', 'R', 'X', 'P'];
            $reemplazar = [
                $total,
                $this->retiro_parcial,
                $porcentaje / 100,
                $modelMontoTotalDeuda + $modelMontoTotalFiador,
            ];
            $formula = $this->formatearFormula(str_replace($busqueda, $reemplazar, $modelBasica->formula_disponibilidad_haberes));

            eval("\$res = ${formula};");
            $montoTotalSolicitud = round($res, 2);
        } else {
            $montoTotalSolicitud = round(
                $this->total_haberes * ($porcentaje / 100) - ($modelMontoTotalDeuda + $modelMontoTotalFiador),
                2
            );
        }

        return $montoTotalSolicitud;
    }

    public function porcentajeInteres()
    {
        if (! $this->hasPorcentajeInteres()) {
            return false;
        }

        return PorcentajeInteres::model()->findByPk($this->id_porcentaje_interes);
    }

    public function hasPorcentajeInteres()
    {
        return $this->id_porcentaje_interes != null;
    }

    /**
     * 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 ReporteHaberes the static model class
     */
    public static function model($className = __CLASS__)
    {
        return parent::model($className);
    }
}
