<?php

class HistorialAportesReembolso extends CActiveRecord
{
    public $extra;
    public $cedula;
    public $nombre;
    public $apellidos;
    public $id_asociado;
    public $descripcion = '';

    public function tableName()
    {
        return 'retenciones.historial_aporte_reembolso';
    }

    public function rules()
    {
        return [
            ['id_aporte, id_txt, fecha_operacion', 'required'],
            ['id_tipo_aporte, estatus_aporte', 'numerical', 'integerOnly' => true],
            ['monto_asociado_reembolso, monto_patrono_reembolso, reembolso_no_recibido_asociado, reembolso_no_recibido_patrono', 'length', 'max' => 24],
            ['actual, fecha_registro, nro_pago', 'safe'],
        ];
    }

    public function relations()
    {
        return [
        ];
    }

    public function attributeLabels()
    {
        return [
            'id' => 'ID',
        ];
    }

    public function nombreCompleto()
    {
        return $this->nombre.' '.$this->apellidos.' C.I.: '.$this->cedula;
    }

    public function asociado()
    {
        return Asociado::model()->find([
            'condition' => 'cedula=:cedula',
            'order' => 'fechaingreso DESC',
            'params' => [
                'cedula' => $this->cedula,
            ],
        ]);
    }

    public function totalReembolso()
    {
        return $this->monto_asociado_reembolso + $this->monto_patrono_reembolso;
    }

    public function getDescripcion()
    {
        return $this->descripcion;
    }

    public function setDescripcion($archivo, $referencia)
    {
        $this->descripcion = vsprintf("Archivo: %s %s Monto asociado: %s Monto patrono: %s Total: %s", [
            $archivo,
            $referencia,
            Yii::app()->format->number($this->monto_asociado_reembolso),
            Yii::app()->format->number($this->monto_patrono_reembolso),
            Yii::app()->format->number($this->totalReembolso()),
        ]);
    }

    public static function model($className = __CLASS__)
    {
        return parent::model($className);
    }

    public static function getReembolso($id)
    {
        return self::model()->find([
            'condition' => 'id_txt=:id',
            'order' => 'reembolso_no_recibido_asociado DESC, reembolso_no_recibido_patrono DESC',
            'params' => [
                'id' => $id,
            ],
        ]);
    }

    public static function aplicarDiferencia($idTxt, $diferencia, $tipo = 1)
    {
        $diferencia = self::truncate($diferencia);

        $aporte = self::getReembolso($idTxt);

        if ($diferencia < 0) {
            return self::restarDecimales($aporte, abs($diferencia), $tipo);
        }

        return self::sumarDecimales($aporte, $diferencia, $tipo);
    }

    public static function diferenciaMontoPagado($idTxt, $diferencia)
    {
        $diferencia = self::truncate($diferencia);

        $aporte = self::getReembolso($idTxt);

        if ($diferencia < 0) {
            return self::restarDiferenciaMontoPagado($aporte, abs($diferencia));
        }

        return self::sumarDiferenciaMontoPagado($aporte, $diferencia);
    }

    public static function diferenciaMontoFaltante($idTxt, $diferencia)
    {
        $diferencia = self::truncate($diferencia);

        $aporte = self::getReembolso($idTxt);

        if ($diferencia < 0) {
            return self::restarDiferenciaMontoFaltante($aporte, abs($diferencia));
        }

        return self::sumarDiferenciaMontoFaltante($aporte, $diferencia);
    }

    private static function sumarDiferenciaMontoPagado($aporte, $diferencia)
    {
        if ($aporte->monto_asociado_reembolso > 0) {
            $aporte->monto_asociado_reembolso += $diferencia;

            return $aporte->save(false);
        }

        if ($aporte->monto_patrono_reembolso > 0) {
            $aporte->monto_patrono_reembolso += $diferencia;

            return $aporte->save(false);
        }
    }

    private static function restarDiferenciaMontoPagado($aporte, $diferencia)
    {
        if ($aporte->monto_asociado_reembolso > 0) {
            $aporte->monto_asociado_reembolso -= $diferencia;

            return $aporte->save(false);
        }

        if ($aporte->monto_patrono_reembolso > 0) {
            $aporte->monto_patrono_reembolso -= $diferencia;

            return $aporte->save(false);
        }
    }

    private static function sumarDiferenciaMontoFaltante($aporte, $diferencia)
    {
        if ($aporte->reembolso_no_recibido_asociado > 0) {
            $aporte->reembolso_no_recibido_asociado += $diferencia;

            return $aporte->save(false);
        }

        if ($aporte->reembolso_no_recibido_patrono > 0) {
            $aporte->reembolso_no_recibido_patrono += $diferencia;

            return $aporte->save(false);
        }
    }

    private static function restarDiferenciaMontoFaltante($aporte, $diferencia)
    {
        if ($aporte->reembolso_no_recibido_asociado > 0) {
            $aporte->reembolso_no_recibido_asociado -= $diferencia;

            return $aporte->save(false);
        }

        if ($aporte->reembolso_no_recibido_patrono > 0) {
            $aporte->reembolso_no_recibido_patrono -= $diferencia;

            return $aporte->save(false);
        }
    }

    public static function truncate($number, $digitos = 2)
    {
        return round($number, 2);
    }

    public static function eliminarAnteriores($id)
    {
        return self::model()->updateAll(['actual' => false], 'id_txt=:id AND actual=true', [':id' => $id]);
    }

    public static function numeroPago($id)
    {
        return Yii::app()->getDb()->createCommand('
            SELECT nro_pago + 1 AS nro_pago
            FROM retenciones.historial_aportes_diferidos
            WHERE id_txt=:id
                AND actual IS TRUE
                AND nro_pago IS NOT NULL
            LIMIT 1;
        ')->bindValue('id', $id)->queryRow()['nro_pago'];
    }

    public static function generarMontosPagadoInicial($id)
    {
        return Yii::app()->getDb()->createCommand('
            UPDATE retenciones.historial_aporte_reembolso
            SET aporte_pago_patrono=ao.total_p,
                aporte_pago_asociado=ao.total_a
            FROM (
                SELECT
                    har.id as id_har,
                    aod.aporte_patrono,
                    har.monto_patrono_reembolso,
                    har.reembolso_no_recibido_patrono,
                    aod.aporte_patrono - har.monto_patrono_reembolso total_p,
                    aod.aporte_asociado,
                    har.monto_asociado_reembolso,
                    har.reembolso_no_recibido_asociado,
                    aod.aporte_asociado - har.monto_asociado_reembolso total_a,
                    nro_pago
                FROM retenciones.historial_aporte_reembolso har
                INNER JOIN retenciones.aporte_ordinario_diferido aod ON har.id_aporte=aod.id
                WHERE har.id_txt=:id
                    AND actual IS TRUE
                    AND coalesce(aod.aporte_patrono, 0) > 0
                    AND coalesce(aod.aporte_asociado, 0) > 0
            ) AS ao
            WHERE id=ao.id_har and actual is true;
        ')->bindValues([
            'id' => $id,
        ])->execute();
    }

    public static function generarMontosPagadosFaltante($id, $numeroPago)
    {
        return Yii::app()->getDb()->createCommand('
            UPDATE retenciones.historial_aportes_diferidos
            SET aporte_pago_patrono=ao.aporte_pago_patrono,
                aporte_pago_asociado=ao.aporte_pago_asociado
            FROM (SELECT
                    id_aporte as id,
                    coalesce((SELECT aporte_pago_patrono
                    FROM retenciones.historial_aportes_diferidos
                    WHERE id_aporte=had.id_aporte AND nro_pago=:nro_pago
                    ), 0) - coalesce(monto_pagado_patrono, 0) as aporte_pago_patrono,
                    coalesce((SELECT aporte_pago_asociado
                    FROM retenciones.historial_aportes_diferidos
                    WHERE id_aporte=had.id_aporte AND nro_pago=:nro_pago
                    ), 0) - coalesce(monto_pagado_socio, 0) as aporte_pago_asociado,
                    nro_pago
                FROM retenciones.historial_aportes_diferidos had
                WHERE id_txt=:id AND actual IS TRUE
            ) AS ao
            WHERE id_aporte=ao.id AND actual IS TRUE;
        ')->bindValues([
            'id' => $id,
            'nro_pago' => $numeroPago - 1,
        ])->execute();
    }
}
