<?php
class ProcesoCierreBL
{
    public function crearPeriodoAbierto( PRO_CierreMensualBN $o_PRO_CierreMensualBN )
    {
        $con = Conexion::getConexion();
        $con->begin();
        try
        {
            $o_PRO_CierreMensualDP = new PRO_CierreMensualDP( $o_PRO_CierreMensualBN );
            $o_PRO_CierreMensualDP->save();
            
            $con->commit();
            return true;
        }
        catch ( Exception $o_Exception )
        {
            $con->rollback();
            throw new Exception( "PC: ".$o_Exception->getMessage() );
        }
    }
    
    public function realizarCierreMensual( PRO_CierreMensualBN $o_PRO_CierreMensualBN )
    {
        $con = Conexion::getConexion();
        $con->begin();
            
        try
        {
            $i_IdCompania = $o_PRO_CierreMensualBN->getIdCompania();
            $s_Periodo    = $o_PRO_CierreMensualBN->getIdPeriodo();
            
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////
            
            $i_AnioPeriodo = intval( substr( $s_Periodo, 0, 4 ) );
            
            $s_PeriodoAnt = $i_AnioPeriodo.str_pad( ( intval( substr( $s_Periodo, -2 ) ) - 1 ), 2, "0", STR_PAD_LEFT );
            
            //VALIDACION DEL PERIODO SIGUIENTE CORRECTO 
            $i_PeriodoSig = ( intval( substr( $s_Periodo, -2 ) ) + 1 );
            if( $i_PeriodoSig == 13 )
            {
                $i_PeriodoSig = 1;
                $i_AnioPeriodo++;
            }
            $s_PeriodoSig = $i_AnioPeriodo.str_pad( $i_PeriodoSig, 2, "0", STR_PAD_LEFT );
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////
            
            //SE VALIDA SI EXISTE PERIODO SIGUIENTE, Y SI EXISTE SE TIENE QUE PREGUNTAR SI ESTA ABIERTO
            $o_PRO_CierreMensualFN = new PRO_CierreMensualFN();
            $o_PRO_CierreMensualBN_Sig = $o_PRO_CierreMensualFN->selectByPK( $i_IdCompania, $s_PeriodoSig );
            if( $o_PRO_CierreMensualBN_Sig )
            {
                if( $o_PRO_CierreMensualBN_Sig->getEstado() != PRO_CierreMensualBN::ESTADO_ABIERTO )
                {
                    $s_PeriodoSigDesc = substr( $s_PeriodoSig, 0, 4 )."-".substr( $s_PeriodoSig, -2 );
                    throw new Exception( "El Periodo ( $s_PeriodoSigDesc ) tiene que estar Abierto." );
                }
            }
            
            //SE VALIDA SI EXISTE PERIODO ANTERIOR, Y SI EXISTE SE TIENE QUE PREGUNTAR SI ESTA CERRADO
            $o_PRO_CierreMensualFN = new PRO_CierreMensualFN();
            $o_PRO_CierreMensualBN_Ant = $o_PRO_CierreMensualFN->selectByPK( $i_IdCompania, $s_PeriodoAnt );
            if( $o_PRO_CierreMensualBN_Ant )
            {
                if( $o_PRO_CierreMensualBN_Ant->getEstado() != PRO_CierreMensualBN::ESTADO_CERRADO )
                {
                    $s_PeriodoAntDesc = substr( $s_PeriodoAnt, 0, 4 )."-".substr( $s_PeriodoAnt, -2 );
                    throw new Exception( "El Periodo ( $s_PeriodoAntDesc ) tiene que estar Cerrado." );
                }
            }
            
            //SE REALIZA VALIDACION DE ELIMINAR DATOS POR COMPAÑIA Y PERIODO
            /*
            $o_ALM_ItemStockDetHisDP = new ALM_ItemStockDetHisDP();
            $o_ALM_ItemStockDetHisDP->setIdCompania( $i_IdCompania );
            $o_ALM_ItemStockDetHisDP->setIdPeriodo( $s_Periodo );
            $b_Result = $o_ALM_ItemStockDetHisDP->deleteCompPeriodo();
            */
            
            //SE REGISTRA LOS SALDOS INICIALES PARA EL PROXIMO PERIODO
            /*
            $a_Lst = array();

            $o_Rs = ALM_KardexFN::buscarMovimientoxItemyPeriodo( $s_Periodo, $s_PeriodoAnt );
            while ( $o_Row = mysql_fetch_object( $o_Rs ) )
            {
                
                $s_IdItem    = $o_Row->IdItem;
                $s_IdAlmacen = $o_Row->IdAlmacen;
                $s_IdLote    = $o_Row->IdLote;
                
                $f_Saldo = floatval( $o_Row->Cantidad );
                
                $s_KeyArr = $s_IdAlmacen."_".$s_IdLote."_".$s_IdItem;
                
                //$f_Saldo = ALM_KardexFN::buscarStockSaldo( $s_IdAlmacen, $s_IdLote, $s_IdItem, $s_PeriodoAnt );
                $a_SaldoInicialItem[$s_KeyArr] = $f_Saldo;
                
                $a_Lst[$s_KeyArr] = $a_SaldoInicialItem[$s_KeyArr];
                
                $o_RS_ALM_Kardex = ALM_KardexFN::buscarTransaccionDet( $s_IdItem, $s_Periodo, $s_IdAlmacen, $s_IdLote );
                if( mysql_num_rows( $o_RS_ALM_Kardex ) > 0 )
                {
                    while ( $o_RowKardex = mysql_fetch_object( $o_RS_ALM_Kardex ) )
                    {
                        //$s_IdAlm  = $o_ALM_KardexBN->getIdAlmacen();
                        //$s_IdLote = $o_ALM_KardexBN->getIdLote();
                        $s_Ope    = $o_RowKardex->TipoIngreso;
                        $f_Qty    = floatval( $o_RowKardex->Cantidad );

                        if( $s_Ope == ALM_TransaccionCabeceraBN::TIPO_INGRESO )
                        {
                            //SE SUMA
                            $a_Lst[$s_KeyArr] = $a_Lst[$s_KeyArr] + $f_Qty;
                        }
                        else
                        {
                            //SE RESTA
                            $a_Lst[$s_KeyArr] = $a_Lst[$s_KeyArr] - $f_Qty;
                        }
                    }
                }
            }
            */

            //SE REGISTRA LOS SALDOS
            /*
            foreach ( $a_Lst as $s_Key => $f_SaldoFinal )
            {
                list( $s_IdAlm, $s_IdLote, $s_IdItem ) = explode( "_", $s_Key );
                
                $f_CantidadAnterior = 0.00;
                
                $o_ALM_ItemStockDetHisFN = new ALM_ItemStockDetHisFN();
                $o_ALM_ItemStockDetHisBN = $o_ALM_ItemStockDetHisFN->selectByPK( $i_IdCompania, $s_PeriodoAnt, $s_IdAlm, $s_IdLote, $s_IdItem );
                if( $o_ALM_ItemStockDetHisBN )
                {
                    $f_CantidadAnterior = $o_ALM_ItemStockDetHisBN->getCantidad();
                }
                
                $o_ALM_ItemStockDetHisDP = new ALM_ItemStockDetHisDP();
                $o_ALM_ItemStockDetHisDP->setIdCompania( $i_IdCompania );
                $o_ALM_ItemStockDetHisDP->setIdPeriodo( $s_Periodo );
                $o_ALM_ItemStockDetHisDP->setIdAlmacen( $s_IdAlm );
                $o_ALM_ItemStockDetHisDP->setIdLote( $s_IdLote );
                $o_ALM_ItemStockDetHisDP->setIdItem( $s_IdItem );
                $o_ALM_ItemStockDetHisDP->setCantidad( $f_SaldoFinal );
                $o_ALM_ItemStockDetHisDP->setCantidadAnterior( $f_CantidadAnterior );
                $o_ALM_ItemStockDetHisDP->setFechaCreacion( date( "Y-m-d H:i:s" ) );
                $o_ALM_ItemStockDetHisDP->setUsuarioCreacion( myUser::getUser()->getUserId() );
                $o_ALM_ItemStockDetHisDP->setFechaModificacion( date( "Y-m-d H:i:s" ) );
                $o_ALM_ItemStockDetHisDP->setUsuarioModificacion( myUser::getUser()->getUserId() );
                $b_Result = $o_ALM_ItemStockDetHisDP->save();  //TENER EN CUENTA QUE EN ESTE METODO SE TIENE QUE COMENTAR EL SELECT DE BUSQUEDA PARA QUE INSERTE RAPIDO
            }
            */
            //SE CAMBIA EL ESTADO A CERRADO
            $o_PRO_CierreMensualDP = new PRO_CierreMensualDP();
            $o_PRO_CierreMensualDP->setIdCompania( $i_IdCompania );
            $o_PRO_CierreMensualDP->setIdPeriodo( $s_Periodo );
            $o_PRO_CierreMensualDP->setEstado( PRO_CierreMensualBN::ESTADO_CERRADO );
            //$o_PRO_CierreMensualDP->setComentario(  );
            $o_PRO_CierreMensualDP->setFechaModificacion( date( "Y-m-d H:i:s" ) );
            $o_PRO_CierreMensualDP->setUsuarioModificacion( myUser::getUser()->getUserId() );
            $b_Result = $o_PRO_CierreMensualDP->update();
            
            //SE AGREGAR COMENTARIO
            $s_Comentario = "\nFecha Actualizacion [Cierre] ".date( "Y-m-d H:i:s" );
            $b_Result = PRO_CierreMensualDP::agregarComentario( $i_IdCompania, $s_Periodo, $s_Comentario );
            
            //SE CREA UN NUEVO REGISTRO DE CIERRE
            $o_PRO_CierreMensualFN = new PRO_CierreMensualFN();
            $o_PRO_CierreMensualBN_Sig = $o_PRO_CierreMensualFN->selectByPK( $i_IdCompania, $s_PeriodoSig );
            if( !$o_PRO_CierreMensualBN_Sig )
            {
                $o_PRO_CierreMensualBN = new PRO_CierreMensualBN();
                $o_PRO_CierreMensualBN->setIdCompania( $i_IdCompania );
                $o_PRO_CierreMensualBN->setIdPeriodo( $s_PeriodoSig );
                $o_PRO_CierreMensualBN->setEstado( PRO_CierreMensualBN::ESTADO_ABIERTO );
                $o_PRO_CierreMensualBN->setComentario( "Fecha Creacion ".date( "Y-m-d H:i:s" ) );
                $o_PRO_CierreMensualBN->setFechaCreacion( date( "Y-m-d H:i:s" ) );
                $o_PRO_CierreMensualBN->setUsuarioCreacion( myUser::getUser()->getUserId() );
                $o_PRO_CierreMensualBN->setFechaModificacion( date( "Y-m-d H:i:s" ) );
                $o_PRO_CierreMensualBN->setUsuarioModificacion( myUser::getUser()->getUserId() );
                
                $b_Result = $this->crearPeriodoAbierto( $o_PRO_CierreMensualBN );
            }
            $con->commit();
            return true;
        }
        catch ( Exception $o_Exception )
        {
            $con->rollback();
            throw new Exception( "PC: ".$o_Exception->getMessage() );
        }
    }

    public function realizarAbrirPeriodo( PRO_CierreMensualBN $o_PRO_CierreMensualBN )
    {
        $con = Conexion::getConexion();
        $con->begin();
        try
        {
            $i_IdCompania = $o_PRO_CierreMensualBN->getIdCompania();
            $s_Periodo    = $o_PRO_CierreMensualBN->getIdPeriodo();
            
            $s_PeriodoAnt = substr( $s_Periodo, 0, 4 ).str_pad( ( intval( substr( $s_Periodo, -2 ) ) - 1 ), 2, "0", STR_PAD_LEFT );
            $s_PeriodoSig = substr( $s_Periodo, 0, 4 ).str_pad( ( intval( substr( $s_Periodo, -2 ) ) + 1 ), 2, "0", STR_PAD_LEFT );
            
            //SE VALIDA SI EXISTE PERIODO SIGUIENTE, Y SI EXISTE SE TIENE QUE PREGUNTAR SI ESTA ABIERTO
            $o_PRO_CierreMensualFN = new PRO_CierreMensualFN();
            $o_PRO_CierreMensualBN_Sig = $o_PRO_CierreMensualFN->selectByPK( $i_IdCompania, $s_PeriodoSig );
            if( $o_PRO_CierreMensualBN_Sig )
            {
                if( $o_PRO_CierreMensualBN_Sig->getEstado() != PRO_CierreMensualBN::ESTADO_ABIERTO )
                {
                    $s_PeriodoSigDesc = substr( $s_PeriodoSig, 0, 4 )."-".substr( $s_PeriodoSig, -2 );
                    throw new Exception( "El Periodo ( $s_PeriodoSigDesc ) tiene que esta Abierto." );
                }
            }
            //SE VALIDA SI EXISTE PERIODO ANTERIOR, Y SI EXISTE SE TIENE QUE PREGUNTAR SI ESTA CERRADO
            $o_PRO_CierreMensualFN = new PRO_CierreMensualFN();
            $o_PRO_CierreMensualBN_Ant = $o_PRO_CierreMensualFN->selectByPK( $i_IdCompania, $s_PeriodoAnt );
            if( $o_PRO_CierreMensualBN_Ant )
            {
                if( $o_PRO_CierreMensualBN_Ant->getEstado() != PRO_CierreMensualBN::ESTADO_CERRADO )
                {
                    $s_PeriodoAntDesc = substr( $s_PeriodoAnt, 0, 4 )."-".substr( $s_PeriodoAnt, -2 );
                    throw new Exception( "El Periodo ( $s_PeriodoAntDesc ) tiene que esta Cerrado." );
                }
            }
            
            /*
            //SE REALIZA VALIDACION DE ELIMINAR DATOS POR COMPAÑIA Y PERIODO
            $o_ALM_ItemStockDetHisDP = new ALM_ItemStockDetHisDP();
            $o_ALM_ItemStockDetHisDP->setIdCompania( $i_IdCompania );
            $o_ALM_ItemStockDetHisDP->setIdPeriodo( $s_Periodo );
            $b_Result = $o_ALM_ItemStockDetHisDP->deleteCompPeriodo();
            */
            
            $o_PRO_CierreMensualDP = new PRO_CierreMensualDP();
            $o_PRO_CierreMensualDP->setIdCompania( $i_IdCompania );
            $o_PRO_CierreMensualDP->setIdPeriodo( $s_Periodo );
            $o_PRO_CierreMensualDP->setEstado( PRO_CierreMensualBN::ESTADO_ABIERTO );
            //$o_PRO_CierreMensualDP->setComentario(  );
            $o_PRO_CierreMensualDP->setFechaModificacion( date( "Y-m-d H:i:s" ) );
            $o_PRO_CierreMensualDP->setUsuarioModificacion( myUser::getUser()->getUserId() );
            $b_Result = $o_PRO_CierreMensualDP->update();
            
            //SE AGREGAR COMENTARIO
            $s_Comentario = "\nFecha Actualizacion [Abrir] ".date( "Y-m-d H:i:s" );
            $b_Result = PRO_CierreMensualDP::agregarComentario( $i_IdCompania, $s_Periodo, $s_Comentario );
        
            $con->commit();
            return true;
        }
        catch ( Exception $o_Exception )
        {
            $con->rollback();
            throw new Exception( "PC: ".$o_Exception->getMessage() );
        }
    }
}