<?php

/*
 * ejemplos:
 $o_VTA_OrdenDetalleBN = new VTA_OrdenDetalleBN();
 $o_VTA_OrdenDetalleBN->setOrdenId( ( int ) $i_Id );
 $o_VTA_OrdenDetalleBN->setOrdenDetalleNum( $i_SecuenciaPFinal );
 $o_VTA_OrdenDetalleBN->setItemCod( $s_IdItem );
 $o_VTA_OrdenDetalleBN->setAlmacenCod( $this->o_VTA_OrdenBN->getAlmacenCod() );
 $o_VTA_OrdenDetalleBN->setItemTipo( "F" );
 $o_VTA_OrdenDetalleBN->setOrdenDetalleCantidad( $f_OrdenDetalleCantidad );
 $o_VTA_OrdenDetalleBN->setPrecioUnidadIncImpuesto( $this->f_MontoTotalDetalle );
 
 $o_CotizacionesDetalleBL = new CotizacionesDetalleBL();
 $o_CotizacionesDetalleBL->iniciarProceso( $o_VTA_OrdenDetalleBN );
 
 $o_VTA_OrdenDetalleBN->setOrdenDetalleNum( $o_VTA_OrdenDetalleBN->getOrdenDetalleNum() );
 $o_VTA_OrdenDetalleBN->setOrdenDetallePrecioNivel( "P" );
 $o_VTA_OrdenDetalleBN->setPrecioUnidadIncImpuesto( $this->f_MontoTotalDetalle );
 
 $o_CotizacionesDetalleBL->iniciarCambioPrecio( $o_VTA_OrdenDetalleBN );
 */

class CotizacionesDetalleBL
{
    public function iniciarProcesoPromocionGrupal( VTA_OrdenDetalleBN $o_VTA_OrdenDetalleBN )
    {
        $con = Conexion::getConexion();
        $con->begin();
        try
        {
            myUser::getUser()->validar_session();

            if( $o_VTA_OrdenDetalleBN->getTipoProcPromo() == "INSERT" )
            {
                if( !$o_VTA_OrdenDetalleBN->getDocRefId() )
                {
                    throw new Exception( "La Promocion en Referencia no existe." );
                }

                //aqui el id de referencia es crucial
                $o_MKT_PromocionCabFN = new MKT_PromocionCabFN();
                $o_MKT_PromocionCabBN = $o_MKT_PromocionCabFN->selectByPK( $o_VTA_OrdenDetalleBN->getDocRefId() );
                if( !$o_MKT_PromocionCabBN )
                {
                    throw new Exception( "La Promocion en Referencia no existe." );
                }

                //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                //validacion de registro doble
                $o_VTA_OrdenDetalleFN = new VTA_OrdenDetalleFN();
                //$o_VTA_DocumentoDetalleFN->setIdCompania( $o_VTA_DocumentoDetalleBN->getIdCompania() );
                //$o_VTA_DocumentoDetalleFN->setIdTipoDocumento( $o_VTA_DocumentoDetalleBN->getIdTipoDocumento() );
                $o_VTA_OrdenDetalleFN->setOrdenId( $o_VTA_OrdenDetalleBN->getOrdenId() );
                //$o_VTA_DocumentoDetalleFN->setTipoDetalle( VTA_DocumentoDetalleBN::TIPO_DETALLE );
                //$o_VTA_OrdenDetalleFN->setItemCod( $o_MKT_PromocionCabBN->getCodigoPromo() );
                $o_VTA_OrdenDetalleFN->setDocRefId( $o_MKT_PromocionCabBN->getIdPromoCab() );
                //$o_VTA_DocumentoDetalleFN->setLote( ALM_ItemAlmacenStockBN::LOTE_POR_DEFECTO );
                $a_VTA_DocumentoDetalle = $o_VTA_OrdenDetalleFN->select();
                if( $a_VTA_DocumentoDetalle )
                {
                    throw new Exception( "La promcion ".$o_MKT_PromocionCabBN->getDescripcionPromo()." ya se encuentra registrada. " );

                    /*$o_Tmp_VTA_DocumentoDetalleBN = $a_VTA_DocumentoDetalle[0];

                    $i_Secuencia      = $o_Tmp_VTA_DocumentoDetalleBN->getSecuencia();
                    $s_Lote           = $o_Tmp_VTA_DocumentoDetalleBN->getLote();
                    $f_CantidadPedida = $o_Tmp_VTA_DocumentoDetalleBN->getCantidadPedida();
                    $f_CantidadPedida = $f_CantidadPedida + 1;
                    $o_VTA_DocumentoDetalleBN->setSecuencia( $i_Secuencia );
                    $o_VTA_DocumentoDetalleBN->setCantidadPedida( $f_CantidadPedida );
                    $o_VTA_DocumentoDetalleBN->setLote( $s_Lote );

                    goto GOTO_UPDATE;*/
                }
                //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

                $s_OrdenMonedaCod = $o_VTA_OrdenDetalleBN->getObjectOrdenBN()->getMonedaCod();
                $f_TipoCob = $o_VTA_OrdenDetalleBN->getObjectOrdenBN()->getMonedaCambioValor();
                //////////////////////////////////////////////////////////////////////////////////////////
                //SE RECUPERA VALOR DE IGV ACTUAL
                $f_ValorIGV       = GSS_ParametroMastFN::getValorPorTipo( "AL", "IGV" ); //0.18
                $f_ValorIGVMasUno = $f_ValorIGV + 1;  //1.18
                //////////////////////////////////////////////////////////////////////////////////////////

                if( $s_OrdenMonedaCod == "EX" )
                {
                    if( !$f_TipoCob )
                    {
                        throw new Exception( "El Tipo de Cambio no esta ingresado." );
                    }
                }

                $s_IdItemTipo  = $o_MKT_PromocionCabBN->getIdItemTipo();
                $i_IdPromoCab  = $o_MKT_PromocionCabBN->getIdPromoCab();
                $s_CodigoPromo = $o_MKT_PromocionCabBN->getCodigoPromo();
                $s_Comentario  = $o_MKT_PromocionCabBN->getDescripcionPromo();

                //submit, se agrega el comentario
                $i_Id = VTA_OrdenDetalleDP::recuperarId( $o_VTA_OrdenDetalleBN->getObjectOrdenBN()->getOrdenId() );

                $o_Tmp_VTA_OrdenDetalleBN = new VTA_OrdenDetalleBN();
                $o_Tmp_VTA_OrdenDetalleBN->setOrdenId( $o_VTA_OrdenDetalleBN->getObjectOrdenBN()->getOrdenId() );
                $o_Tmp_VTA_OrdenDetalleBN->setOrdenDetalleNum( $i_Id );
                $o_Tmp_VTA_OrdenDetalleBN->setItemTipo( VTA_OrdenDetalleBN::TIPO_COMENTARIO );
                $o_Tmp_VTA_OrdenDetalleBN->setOrdenDetalleDescripcion( $s_Comentario );
                $o_Tmp_VTA_OrdenDetalleBN->setDocRefTipoCod( $s_IdItemTipo );
                $o_Tmp_VTA_OrdenDetalleBN->setDocRefId( $i_IdPromoCab );
                $o_Tmp_VTA_OrdenDetalleBN->setDocRefNum( $s_CodigoPromo );
                $o_Tmp_VTA_OrdenDetalleBN->setUsuarioModificacion( myUser::getUser()->getUserId() );
                $o_Tmp_VTA_OrdenDetalleBN->setFechaModificacion( date( "Y-m-d H:i:s" ) );
                $o_Tmp_VTA_OrdenDetalleBN->setUsuarioCreacion( myUser::getUser()->getUserId() );
                $o_Tmp_VTA_OrdenDetalleBN->setFechaCreacion( date( "Y-m-d H:i:s" ) );

                $o_VTA_OrdenDetalleDP = new VTA_OrdenDetalleDP( $o_Tmp_VTA_OrdenDetalleBN );
                $o_VTA_OrdenDetalleDP->save();

                //ahora actualizamos los detalles de la promocion
                $o_MKT_ItemPromocionFN = new MKT_ItemPromocionFN();
                $o_MKT_ItemPromocionFN->setIdPromoCab( $i_IdPromoCab );
                $a_MKT_ItemPromocion = $o_MKT_ItemPromocionFN->select();

                //pr( $a_MKT_ItemPromocion ); exit;

                foreach ( $a_MKT_ItemPromocion as $o_MKT_ItemPromocionBN )
                {
                    //submit, se agrega el comentario
                    $i_Id = VTA_OrdenDetalleDP::recuperarId( $o_VTA_OrdenDetalleBN->getObjectOrdenBN()->getOrdenId() );

                    $o_Tmp_VTA_OrdenDetalleBN = new VTA_OrdenDetalleBN();
                    $o_Tmp_VTA_OrdenDetalleBN->setOrdenId( $o_VTA_OrdenDetalleBN->getObjectOrdenBN()->getOrdenId() );
                    $o_Tmp_VTA_OrdenDetalleBN->setOrdenDetalleNum( $i_Id );
                    $o_Tmp_VTA_OrdenDetalleBN->setItemCod( $o_MKT_ItemPromocionBN->getIdItem() );
                    $o_Tmp_VTA_OrdenDetalleBN->setOrdenDetalleCantidad( $o_MKT_ItemPromocionBN->getCantidad() );
                    $o_Tmp_VTA_OrdenDetalleBN->setAlmacenCod( $o_VTA_OrdenDetalleBN->getObjectOrdenBN()->getAlmacenCod() );
                    $o_Tmp_VTA_OrdenDetalleBN->setOrdenDetallePrecioNivel( "1" );
                    $o_Tmp_VTA_OrdenDetalleBN->setOrdenDetalleAfectoImpuesto( "Y" );
                    $o_Tmp_VTA_OrdenDetalleBN->setItemTipo( VTA_OrdenDetalleBN::TIPO_PRODUCTO );
                    $o_Tmp_VTA_OrdenDetalleBN->setIdItemTipo( "01" );
                    $o_Tmp_VTA_OrdenDetalleBN->setIdUnidad( 58 );
                    $o_Tmp_VTA_OrdenDetalleBN->setOrdenDetalleDescripcion( $o_MKT_ItemPromocionBN->getDescripcionItem() );
                    $o_Tmp_VTA_OrdenDetalleBN->setDocRefTipoCod( $s_IdItemTipo );
                    $o_Tmp_VTA_OrdenDetalleBN->setDocRefId( $i_IdPromoCab );
                    $o_Tmp_VTA_OrdenDetalleBN->setDocRefNum( $s_CodigoPromo );
                    $o_Tmp_VTA_OrdenDetalleBN->setUsuarioModificacion( myUser::getUser()->getUserId() );
                    $o_Tmp_VTA_OrdenDetalleBN->setFechaModificacion( date( "Y-m-d H:i:s" ) );
                    $o_Tmp_VTA_OrdenDetalleBN->setUsuarioCreacion( myUser::getUser()->getUserId() );
                    $o_Tmp_VTA_OrdenDetalleBN->setFechaCreacion( date( "Y-m-d H:i:s" ) );

                    //$f_CostoUnidadIncImpuesto = round( $o_MKT_ItemPromocionBN->getCostoConIGVCalculado() / $f_ValorIGVMasUno, 2 );
                    //$f_CostoUnidadIncImpuestoMN = $f_CostoUnidadIncImpuesto;
                    $f_CostoUnidadIncImpuesto = round( $o_MKT_ItemPromocionBN->getCostoConIGVTotal() / $f_ValorIGVMasUno, 2 );
                    $f_CostoUnidadIncImpuestoMN = $f_CostoUnidadIncImpuesto;

                    $f_PrecioUnidadIncImpuesto = $o_MKT_ItemPromocionBN->getPrecioConIGVCalculado();
                    $f_PrecioUnidadIncImpuestoMN = $o_MKT_ItemPromocionBN->getPrecioConIGVCalculado();
                    $f_OrdenDetallePrecioUnidad = round( $o_MKT_ItemPromocionBN->getPrecioConIGVCalculado() / $f_ValorIGVMasUno, 2 );
                    $f_OrdenDetallePrecioUnidadMN = $f_OrdenDetallePrecioUnidad;
                    $f_OrdenDetalleImpuestoUnidad = $f_PrecioUnidadIncImpuesto - $f_OrdenDetallePrecioUnidad;
                    $f_OrdenDetalleImpuestoUnidadMN = $f_PrecioUnidadIncImpuestoMN - $f_OrdenDetallePrecioUnidadMN;

                    if( $s_OrdenMonedaCod == "EX" )
                    {
                        $f_CostoUnidadIncImpuesto = round( $f_CostoUnidadIncImpuesto / $f_TipoCob, 2 );
                        //$f_CostoUnidadIncImpuestoMN = $f_CostoUnidadIncImpuesto;
                        $f_PrecioUnidadIncImpuesto = round( $f_PrecioUnidadIncImpuesto / $f_TipoCob, 2 );
                        //$f_PrecioUnidadIncImpuestoMN = $o_MKT_ItemPromocionBN->getPrecioConIGVCalculado();
                        $f_OrdenDetallePrecioUnidad = round( $f_OrdenDetallePrecioUnidad / $f_TipoCob, 2 );
                        //$f_OrdenDetallePrecioUnidadMN = $f_OrdenDetallePrecioUnidad;
                        $f_OrdenDetalleImpuestoUnidad = $f_PrecioUnidadIncImpuesto - $f_OrdenDetallePrecioUnidad;
                        //$f_OrdenDetalleImpuestoUnidadMN = $f_PrecioUnidadIncImpuestoMN - $f_OrdenDetallePrecioUnidadMN;
                    }

                    $o_Tmp_VTA_OrdenDetalleBN->setCostoUnidadIncImpuesto( $f_CostoUnidadIncImpuesto );
                    $o_Tmp_VTA_OrdenDetalleBN->setCostoUnidadIncImpuestoMN( $f_CostoUnidadIncImpuestoMN );
                    $o_Tmp_VTA_OrdenDetalleBN->setPrecioUnidadIncImpuesto( $f_PrecioUnidadIncImpuesto );
                    $o_Tmp_VTA_OrdenDetalleBN->setPrecioUnidadIncImpuestoMN( $f_PrecioUnidadIncImpuestoMN );
                    $o_Tmp_VTA_OrdenDetalleBN->setOrdenDetallePrecioUnidad( $f_OrdenDetallePrecioUnidad );
                    $o_Tmp_VTA_OrdenDetalleBN->setOrdenDetallePrecioUnidadMN( $f_OrdenDetallePrecioUnidadMN );
                    $o_Tmp_VTA_OrdenDetalleBN->setOrdenDetalleImpuestoUnidad( $f_OrdenDetalleImpuestoUnidad );
                    $o_Tmp_VTA_OrdenDetalleBN->setOrdenDetalleImpuestoUnidadMN( $f_OrdenDetalleImpuestoUnidadMN );

                    $this->validarValoresxDefecto( $o_Tmp_VTA_OrdenDetalleBN ); //asigna precio final con impuestos

                    $o_VTA_OrdenDetalleDP = new VTA_OrdenDetalleDP( $o_Tmp_VTA_OrdenDetalleBN );
                    $o_VTA_OrdenDetalleDP->save();
                }
            }

            if( $o_VTA_OrdenDetalleBN->getTipoProcPromo() == "DELETE" )
            {
                $o_VTA_OrdenDetalleFN = new VTA_OrdenDetalleFN();
                $o_VTA_OrdenDetalleFN->setOrdenId( $o_VTA_OrdenDetalleBN->getOrdenId() );
                $o_VTA_OrdenDetalleFN->setDocRefId( $o_VTA_OrdenDetalleBN->getDocRefId() );
                $a_VTA_OrdenDetalle = $o_VTA_OrdenDetalleFN->select();
                foreach( $a_VTA_OrdenDetalle as $o_TMP_VTA_OrdenDetalleBN )
                {
                    $o_VTA_OrdenDetalleDP = new VTA_OrdenDetalleDP();
                    $o_VTA_OrdenDetalleDP->setOrdenId( $o_TMP_VTA_OrdenDetalleBN->getOrdenId() );
                    $o_VTA_OrdenDetalleDP->setOrdenDetalleNum( $o_TMP_VTA_OrdenDetalleBN->getOrdenDetalleNum() );
                    $o_VTA_OrdenDetalleDP->delete();
                }
            }

            if( $o_VTA_OrdenDetalleBN->getTipoProcPromo() == "UPDATE" )
            {
                GOTO_UPDATE:

                $i_CantidadPedida = $o_VTA_OrdenDetalleBN->getOrdenDetalleCantidad();

                $o_VTA_OrdenDetalleFN = new VTA_OrdenDetalleFN();
                $o_TMP_VTA_OrdenDetalleBN = $o_VTA_OrdenDetalleFN->selectByPK( $o_VTA_OrdenDetalleBN->getOrdenId(), $o_VTA_OrdenDetalleBN->getOrdenDetalleNum() );

                //aqui el id de referencia es crucial
                $o_MKT_PromocionCabFN = new MKT_PromocionCabFN();
                $o_MKT_PromocionCabBN = $o_MKT_PromocionCabFN->selectByPK( $o_TMP_VTA_OrdenDetalleBN->getDocRefId() );
                if( !$o_MKT_PromocionCabBN )
                {
                    throw new Exception( "La Promocion en Referencia no existe." );
                }

                $o_VTA_OrdenDetalleFN = new VTA_OrdenDetalleFN();
                $o_VTA_OrdenDetalleFN->setOrdenId( $o_TMP_VTA_OrdenDetalleBN->getOrdenId() );
                $o_VTA_OrdenDetalleFN->setDocRefId( $o_TMP_VTA_OrdenDetalleBN->getDocRefId() );
                $a_VTA_OrdenDetalle = $o_VTA_OrdenDetalleFN->select();
                foreach( $a_VTA_OrdenDetalle as $o_TMP2_VTA_OrdenDetalleBN )
                {
                    if( $o_TMP2_VTA_OrdenDetalleBN->getItemTipo() == VTA_OrdenDetalleBN::TIPO_COMENTARIO )
                    {
                        continue;
                    }
                    //pr( $o_TMP2_VTA_OrdenDetalleBN ); exit;

                    $o_MKT_ItemPromocionFN = new MKT_ItemPromocionFN();
                    //$o_MKT_ItemPromocionFN->setDebug( true );
                    $o_MKT_ItemPromocionFN->setIdPromoCab( $o_TMP2_VTA_OrdenDetalleBN->getDocRefId() );
                    $o_MKT_ItemPromocionFN->setIdItem( $o_TMP2_VTA_OrdenDetalleBN->getItemCod() );
                    $a_MKT_ItemPromocion = $o_MKT_ItemPromocionFN->select();
                    if( $a_MKT_ItemPromocion )
                    {
                        $o_MKT_ItemPromocionBN = $a_MKT_ItemPromocion[0];
                        $o_TMP2_VTA_OrdenDetalleBN->setOrdenDetalleCantidad( $i_CantidadPedida * $o_MKT_ItemPromocionBN->getCantidad() );
                    }
                    else
                    {
                        throw new Exception( "La Promocion en Referencia no existe." );
                    }

                    $this->validarValoresxDefecto( $o_TMP2_VTA_OrdenDetalleBN ); //asigna precio final con impuestos

                    $o_VTA_OrdenDetalleDP = new VTA_OrdenDetalleDP( $o_TMP2_VTA_OrdenDetalleBN );
                    $o_VTA_OrdenDetalleDP->setUsuarioModificacion( myUser::getUser()->getUserId() );
                    $o_VTA_OrdenDetalleDP->setFechaModificacion( date( "Y-m-d H:i:s" ) );
                    $o_VTA_OrdenDetalleDP->setUsuarioCreacion( null );
                    $o_VTA_OrdenDetalleDP->setFechaCreacion( null );
                    $o_VTA_OrdenDetalleDP->update();
                }

                /*
                $o_VTA_DocumentoDetalleFN = new VTA_DocumentoDetalleFN();
                $o_VTA_DocumentoDetalleFN->setIdTipoDocumento( $o_VTA_DocumentoDetalleBN->getIdTipoDocumento() );
                $o_VTA_DocumentoDetalleFN->setIdCompania( $o_VTA_DocumentoDetalleBN->getIdCompania() );
                $o_VTA_DocumentoDetalleFN->setNumeroDocumento( $o_VTA_DocumentoDetalleBN->getNumeroDocumento() );
                $o_VTA_DocumentoDetalleFN->setNumeroPromocion( $o_Tmp_VTA_DocumentoDetalleBN->getNumeroPromocion() );
                $a_VTA_DocumentoDetalle = $o_VTA_DocumentoDetalleFN->select();
                foreach ( $a_VTA_DocumentoDetalle as $o_VTA_DocumentoDetalleBN )
                {
                    $b_Control = false;
                    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                    //validacion para no exeder la cantidad de la promocion
                    if ( substr( $o_VTA_DocumentoDetalleBN->getItemCodigo(), 0, 1 ) == "#" || substr( $o_VTA_DocumentoDetalleBN->getItemCodigo(), 0, 2 ) == "PK" || substr( $o_VTA_DocumentoDetalleBN->getItemCodigo(), 0, 2 ) == "PR"  )  //promocion grupal
                    {
                        $f_StockDisponible = $o_VTA_DocumentoDetalleBN->getStockDisponiblePromocionGrupal();
                        if( $i_CantidadPedida > $f_StockDisponible )
                        {
                            throw new Exception( "La Promocion no tiene la cantidad sufiente." );
                        }
                        $b_Control = true;
                    }
                    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                    if( $b_Control )
                    {
                        $o_VTA_DocumentoDetalleBN->setCantidadPedida( $i_CantidadPedida );
                    }
                    else
                    {
                        $o_MKT_ItemPromocionFN = new MKT_ItemPromocionFN();
                        //$o_MKT_ItemPromocionFN->setDebug( true );
                        $o_MKT_ItemPromocionFN->setIdPromoCab( $o_Tmp_VTA_DocumentoDetalleBN->getRefParent() );
                        $o_MKT_ItemPromocionFN->setIdItem( $o_VTA_DocumentoDetalleBN->getItemCodigo() );
                        $a_MKT_ItemPromocion = $o_MKT_ItemPromocionFN->select();
                        if( $a_MKT_ItemPromocion )
                        {
                            $o_MKT_ItemPromocionBN = $a_MKT_ItemPromocion[0];
                            $o_VTA_DocumentoDetalleBN->setCantidadPedida( $i_CantidadPedida * $o_MKT_ItemPromocionBN->getCantidad() );
                        }
                    }

                    $this->validarValoresxDefecto( $o_VTA_DocumentoDetalleBN ); //asigna precio final con impuestos

                    $o_VTA_DocumentoDetalleDP = new VTA_DocumentoDetalleDP( $o_VTA_DocumentoDetalleBN );
                    $o_VTA_DocumentoDetalleDP->setFechaModificacion( date( "Y-m-d H:i:s" ) );
                    $o_VTA_DocumentoDetalleDP->setUsuarioModificacion( myUser::getUser()->getUserId() );
                    $o_VTA_DocumentoDetalleDP->update();

                    if( $o_VTA_DocumentoDetalleBN->getTipoDetalle() == VTA_DocumentoDetalleBN::TIPO_DETALLE )
                    {
                        if( $o_VTA_DocumentoDetalleBN->getObjectItem()->SiUsarReservableStock() )
                        {
                            $this->iniciarReservaStockAlmacen( $o_VTA_DocumentoDetalleBN, "U" );
                        }
                    }
                }*/
            }

            $this->actualizarMontosCabcecera( $o_VTA_OrdenDetalleBN );

            $con->commit();
        }
        catch ( Exception $o_Exception )
        {
            //pr( $o_Exception );
            $con->rollback();
            throw new Exception( "O|V-IPPG: ".$o_Exception->getMessage() );
        }
        return true;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    protected $o_VTA_OrdenDetalleBN;
    private function setOrdenDetalleHisBN( $v )
    {
        $this->o_VTA_OrdenDetalleBN = $v;
    }
    private function getOrdenDetalleHisBN()
    {
        return $this->o_VTA_OrdenDetalleBN;
    }
    
    private function registrarHistorial( $TipoProc, VTA_OrdenDetalleBN $o_VTA_OrdenDetalleBN )
    {
        //se agrega el procedimiento del log
        $o_RegistroHistorialDP = new RegistroHistorialDP();
        $o_RegistroHistorialDP->setTabla( "VTA_OrdenDetalleBN" );
        $o_RegistroHistorialDP->setIdDocumento( ( string ) $o_VTA_OrdenDetalleBN->getOrdenId() );                  //id del registro cabecera
        $o_RegistroHistorialDP->setIdCampo( ( string ) $o_VTA_OrdenDetalleBN->getOrdenDetalleNum() );   //puede ser el id de los detalles
        $o_RegistroHistorialDP->setCampoValor( $o_VTA_OrdenDetalleBN->getItemCod()." - ".$o_VTA_OrdenDetalleBN->getOrdenDetalleDescripcion() );                   //valor que se muestra al usuario
        $o_RegistroHistorialDP->setModulo( "COTIZACION" );                                              //modulo donde se ralizo la accion
        switch ( $TipoProc ) 
        {
            case "I":
                $o_RegistroHistorialDP->setCampoDescripcion( "NUEVO ITEM" );                            //descripcion de la accion a realizar
                $o_RegistroHistorialDP->setValorAnterior( "0" );
                $o_RegistroHistorialDP->setValorNuevo( "0" );
            break;
            case "U":
                $o_Tmp_VTA_DocumentoDetalleBN = $this->getOrdenDetalleHisBN();

                if( $o_Tmp_VTA_DocumentoDetalleBN->getOrdenDetalleCantidad() != $o_VTA_OrdenDetalleBN->getOrdenDetalleCantidad() )
                {
                    $o_RegistroHistorialDP->setCampoDescripcion( "ACT CANTIDAD" );
                    $o_RegistroHistorialDP->setValorAnterior( ( string ) $o_Tmp_VTA_DocumentoDetalleBN->getOrdenDetalleCantidad() );
                    $o_RegistroHistorialDP->setValorNuevo( ( string ) $o_VTA_OrdenDetalleBN->getOrdenDetalleCantidad() );
                }

                if( $o_Tmp_VTA_DocumentoDetalleBN->getPrecioUnidadIncImpuesto() != $o_VTA_OrdenDetalleBN->getPrecioUnidadIncImpuesto() )
                {
                    $o_RegistroHistorialDP->setCampoDescripcion( "ACT PRECIO" );
                    $o_RegistroHistorialDP->setValorAnterior( ( string ) $o_Tmp_VTA_DocumentoDetalleBN->getPrecioUnidadIncImpuesto() );
                    $o_RegistroHistorialDP->setValorNuevo( ( string ) $o_VTA_OrdenDetalleBN->getPrecioUnidadIncImpuesto() );
                }
            break;
            case "D":
                $o_Tmp_VTA_DocumentoDetalleBN = $this->getOrdenDetalleHisBN();

                $o_RegistroHistorialDP->setCampoDescripcion( "ELIMINAR ITEM" );
                $o_RegistroHistorialDP->setValorAnterior( "0" );
                $o_RegistroHistorialDP->setValorNuevo( "0" );
            break;
        }
        $o_RegistroHistorialDP->save();
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public function iniciarCambioPrecio( VTA_OrdenDetalleBN $o_VTA_OrdenDetalleBN )
    {
        if( $o_VTA_OrdenDetalleBN->getItemTipo() == VTA_OrdenDetalleBN::TIPO_COMENTARIO )
        {
            return true;
        }
        
        $con = Conexion::getConexion();
        $con->begin();
        try
        {
            myUser::getUser()->validar_session();

            $f_TipoCambio = GSS_TipoCambioFN::getStaticTipoCambioCobranza();
            if( !$f_TipoCambio )
            {
                throw new Exception( "Debe de registrar el Tipo de Cambio de hoy." );
            }

            $o_VTA_OrdenFN = new VTA_OrdenFN();
            $o_VTA_OrdenBN = $o_VTA_OrdenFN->selectByPK( $o_VTA_OrdenDetalleBN->getOrdenId() );

            $o_VTA_OrdenDetalleFN = new VTA_OrdenDetalleFN();
            $o_Tmp_VTA_DocumentoDetalleBN = $o_VTA_OrdenDetalleFN->selectByPK( $o_VTA_OrdenDetalleBN->getOrdenId(), $o_VTA_OrdenDetalleBN->getOrdenDetalleNum() );

            $o_ALM_ItemMastFN = new ALM_ItemMastFN();
            $o_ALM_ItemMastBN = $o_ALM_ItemMastFN->selectByPK( $o_Tmp_VTA_DocumentoDetalleBN->getItemCod() );

            //POR EL PROCEDIMIENTO DEL DESCUENTO Y PARA QUE NO SAQUEN LA VUELTA AL SISTEMA, SE TIENE QUE TENER EL PRECIO UNITARIO SEGUN LA CANTIDAD ACTUAL
            $o_TMP2_VTA_OrdenDetalleBN = new VTA_OrdenDetalleBN();
            $o_TMP2_VTA_OrdenDetalleBN->setOrdenId( $o_Tmp_VTA_DocumentoDetalleBN->getOrdenId() );
            $o_TMP2_VTA_OrdenDetalleBN->setItemCod( $o_Tmp_VTA_DocumentoDetalleBN->getItemCod() );
            $o_TMP2_VTA_OrdenDetalleBN->setAlmacenCod( $o_Tmp_VTA_DocumentoDetalleBN->getAlmacenCod() );
            $o_TMP2_VTA_OrdenDetalleBN->setOrdenDetalleCantidad( $o_Tmp_VTA_DocumentoDetalleBN->getOrdenDetalleCantidad() );
            //$o_TMP2_VTA_OrdenDetalleBN->setItemTipo( "1" );
            $o_TMP2_VTA_OrdenDetalleBN->setCambioPrecio( true );

            $o_CotizacionesDetalleBL = new CotizacionesDetalleBL();
            $b_Result = $o_CotizacionesDetalleBL->iniciarProceso( $o_TMP2_VTA_OrdenDetalleBN );


            $f_OrdenDetPrecioUni = $o_TMP2_VTA_OrdenDetalleBN->getOrdenDetallePrecioUnidad();

            $this->setOrdenDetalleHisBN( $o_Tmp_VTA_DocumentoDetalleBN );

            $o_VTA_OrdenDetalleBN->setOrdenDetalleCantidad( $o_Tmp_VTA_DocumentoDetalleBN->getOrdenDetalleCantidad() );
            $o_VTA_OrdenDetalleBN->setAlmacenCod( $o_Tmp_VTA_DocumentoDetalleBN->getAlmacenCod() );
            $o_VTA_OrdenDetalleBN->setIdItemTipo( $o_Tmp_VTA_DocumentoDetalleBN->getIdItemTipo() );
            $o_VTA_OrdenDetalleBN->setItemTipo( $o_Tmp_VTA_DocumentoDetalleBN->getItemTipo() );
            $o_VTA_OrdenDetalleBN->setCambioPrecio( true );

            //se pregunta el control de impuesto por cabecera de la cotizacion
            $b_ControlImpuesto = $o_VTA_OrdenBN->esGravadaConImpuesto();
            /*if( !$o_MST_ListaPrecioDetalleBN->getAfectoIGV() )
            {
                $b_ControlImpuesto = false;
            }*/
            if( !$o_ALM_ItemMastBN->EsAfectoaIGV() )
            {
                $b_ControlImpuesto = false;
            }

            //AHORA PREGUNTAMOS SI ESTA EXONERADO POR LA ZONA
            $b_ControlExonerado = $o_VTA_OrdenBN->esExoneradodeIGV();
            if( $b_ControlExonerado )
            {
                $b_ControlImpuesto = false;
            }

            if( $o_VTA_OrdenDetalleBN->getOrdenDetallePrecioNivel() == "P" )
            {
                //////////////////////////////////////////////////////////////////////////////////////////
                //SE RECUPERA VALOR DE IGV ACTUAL
                /*
                $o_GSS_ParametroMastFN = new GSS_ParametroMastFN();
                $o_GSS_ParametroMastBN = $o_GSS_ParametroMastFN->selectByPK( -1, 'AL', 'IGV' );
                $f_ValorIGV = floatval( $o_GSS_ParametroMastBN->getNumero() ); //0.18
                $f_ValorIGVMasUno = floatval( $o_GSS_ParametroMastBN->getNumero() ) + 1;  //1.18
                */
                $f_ValorIGV       = GSS_ParametroMastFN::getValorPorTipo( "AL", "IGV" ); //0.18
                $f_ValorIGVMasUno = $f_ValorIGV + 1;  //1.18
                //////////////////////////////////////////////////////////////////////////////////////////

                $o_MST_ListaPrecioCabeceraFN = new MST_ListaPrecioCabeceraFN();
                $o_MST_ListaPrecioCabeceraBN = $o_MST_ListaPrecioCabeceraFN->selectByPK( myUser::getUser()->getIdBusiness(), myUser::getUser()->getIdSucursal() );
                if( !$o_MST_ListaPrecioCabeceraBN )
                {
                    $o_MST_ListaPrecioCabeceraBN = $o_MST_ListaPrecioCabeceraFN->buscaListaPrecioAlternativo();
                }

                if( $b_ControlImpuesto )
                {
                    $f_MontoIncImpuestoUnidad = $o_VTA_OrdenDetalleBN->getPrecioUnidadIncImpuesto();
                    $f_PrecioUnitario         = round( $f_MontoIncImpuestoUnidad / $f_ValorIGVMasUno, 2 );
                    $f_MontoImpuestoUnidad    = round( $f_MontoIncImpuestoUnidad - $f_PrecioUnitario, 2 );
                }
                else
                {
                    $f_MontoIncImpuestoUnidad = $o_VTA_OrdenDetalleBN->getPrecioUnidadIncImpuesto();
                    $f_PrecioUnitario         = $f_MontoIncImpuestoUnidad;
                    $f_MontoImpuestoUnidad    = 0;
                }

                if( $o_MST_ListaPrecioCabeceraBN->getIdMoneda() == "LO" ) //MONEDA DE LA LISTA DE PRECIOS ES SOLES
                {
                    if( $o_VTA_OrdenBN->getMonedaCod() == 'LO' )
                    {
                        $f_MontoIncImpuestoUnidadMN = $f_MontoIncImpuestoUnidad;
                        $f_MontoImpuestoUnidadMN    = $f_MontoImpuestoUnidad;
                        $f_PrecioUnitarioMN         = $f_PrecioUnitario;
                    }
                    if( $o_VTA_OrdenBN->getMonedaCod() == "EX" )
                    {
                        $f_MontoIncImpuestoUnidadMN = round( $f_MontoIncImpuestoUnidad * $f_TipoCambio, 2 ) ;
                        $f_PrecioUnitarioMN         = round( $f_PrecioUnitario * $f_TipoCambio, 2 );
                        $f_MontoImpuestoUnidadMN    = round( $f_MontoIncImpuestoUnidadMN - $f_PrecioUnitarioMN, 2 );
                    }
                }

                /*
                //AHORA SE RECUPERA EL LISTADO DE PRECIOS PARA UNA VALIDACION IMPORTANTE, EL PRECIO INGRESADO NO DEBE SER MENOR QUE EL COSTO
                $o_MST_ListaPrecioDetalleBN = MST_ListaPrecioDetalleFN::buscarPorCostoGeneral( $o_Tmp_VTA_DocumentoDetalleBN->getItemCod() );
                if( $o_MST_ListaPrecioDetalleBN )
                {
                    if( $f_PrecioUnitarioMN <= $o_MST_ListaPrecioDetalleBN->getPrecioCosto() )
                    {
                        throw new Exception( "El Precio ingresado no puede ser menor o igual que el costo." );
                    }
                }
                */

                //SE AGREGA VALIDACION, EL VENDEDOR SOLO TIENE PERMITIDO UN PORCENTAJE QUE LE ASIGNA EL ADMINISTRADOR - 2021-10-01
                if( trim( $o_VTA_OrdenDetalleBN->getContrasenia() ) == "" ) //SIN CONTRASEÑA, PORCENTAJE DEL VENDEDOR
                {
                    //PRIMERA VALIDACION ES QUE PARA UN VENDEDOR SOLO TIENE PERMITIDO HASTA UN PORCENTAJE QUE LE DESIGNE EL JEFE DE VENTAS
                    //ahora el porcentaje es dinamico, desde el maestro de personas
                    $o_VTA_VendedorFN = new VTA_VendedorFN();
                    $o_VTA_VendedorFN->setIdUsuario( myUser::getUser()->getUserId() );
                    $a_VTA_Vendedor = $o_VTA_VendedorFN->select();
                    if( $a_VTA_Vendedor )
                    {
                        //es vendedor
                        $o_VTA_VendedorBN   = $a_VTA_Vendedor[0];
                        $f_PorcentajeDscto  = $o_VTA_VendedorBN->getPorcentajeDscto();
                        $f_PorcDsctoDecimal = round( ( $f_PorcentajeDscto / 100 ), 2 );
                        $f_TotalDescuento   = round( $f_PorcDsctoDecimal * $f_OrdenDetPrecioUni, 2 );
                        $f_SumaUniDescuento = $f_OrdenDetPrecioUni - $f_TotalDescuento;
                        if( $f_PrecioUnitario < $f_SumaUniDescuento )
                        {
                            throw new Exception( "Solo tiene permitido hasta un $f_PorcentajeDscto% de Descuento." );
                        }
                    }
                    else
                    {
                        throw new Exception( "No tiene permiso para realizar descuentos." );
                    }
                }
                else
                {
                    //AQUI ES PARA LA VALIDACION DE QUE SI SE INGRESA CONTRASEÑA Y ES VALIDA PUEDE USAR MAS PORCENTAJE DE DESCUENTO SEGUN COMO EL ADMIN LE HAYA ASIGNADO
                    $o_SEG_UsuarioFN = new SEG_UsuarioFN();
                    $o_SEG_UsuarioFN->setPermisoAdPwd( 1 );
                    $o_SEG_UsuarioFN->setUsuarioContrasenia( trim( $o_VTA_OrdenDetalleBN->getContrasenia() ) );
                    $a_SEG_Usuario = $o_SEG_UsuarioFN->select();
                    if( $a_SEG_Usuario )
                    {
                        $o_SEG_UsuarioBN = $a_SEG_Usuario[0];
                        $s_TMP_IdUsuario = $o_SEG_UsuarioBN->getIdUsuario();

                        $o_VTA_VendedorFN = new VTA_VendedorFN();
                        $o_VTA_VendedorFN->setIdUsuario( $s_TMP_IdUsuario );
                        $a_VTA_Vendedor = $o_VTA_VendedorFN->select();
                        if( $a_VTA_Vendedor )
                        {
                            //es vendedor pero como jefe
                            $o_VTA_VendedorBN  = $a_VTA_Vendedor[0];
                            $f_PorcentajeDscto = $o_VTA_VendedorBN->getPorcentajeDscto();
                            $f_PorcDsctoDecimal = round( ( $f_PorcentajeDscto / 100 ), 2 );
                            $f_TotalDescuento   = round( $f_PorcDsctoDecimal * $f_OrdenDetPrecioUni, 2 );
                            $f_SumaUniDescuento = $f_OrdenDetPrecioUni - $f_TotalDescuento;
                            if( $f_PrecioUnitario < $f_SumaUniDescuento )
                            {
                                throw new Exception( "El Administrador solo tiene permitido colocar hasta un $f_PorcentajeDscto%" );
                            }
                        }
                        else
                        {
                            throw new Exception( "No tiene permiso para realizar descuentos." );
                        }
                    }
                    else
                    {
                        throw new Exception( "El Password ingresado no obtuvo coincidencia." );
                    }
                }

                /*if( $o_MST_ListaPrecioCabeceraBN->getIdMoneda() == "EX" ) //MONEDA DE LA LISTA DE PRECIOS ES DOLARES
                {
                    if( $o_VTA_OrdenBN->getMonedaCod() == "EX" )
                    {
                        $f_MontoIncImpuestoUnidadMN = round( $f_MontoIncImpuestoUnidad * $f_TipoCambio, 6 ) ;
                        $f_MontoImpuestoUnidadMN    = round( $f_MontoImpuestoUnidad * $f_TipoCambio, 6 );
                        $f_PrecioUnitarioMN         = round( $f_PrecioUnitario * $f_TipoCambio, 6 );
                    }
                    if( $o_VTA_OrdenBN->getMonedaCod() == 'LO' )
                    {
                        $f_MontoIncImpuestoUnidadMN = $f_MontoIncImpuestoUnidad;
                        $f_MontoImpuestoUnidadMN    = $f_MontoImpuestoUnidad;
                        $f_PrecioUnitarioMN         = $f_PrecioUnitario;
                    }
                }*/

                $o_VTA_OrdenDetalleBN->setPrecioUnidadIncImpuesto( $f_MontoIncImpuestoUnidad );
                $o_VTA_OrdenDetalleBN->setPrecioUnidadIncImpuestoMN( $f_MontoIncImpuestoUnidadMN );
                $o_VTA_OrdenDetalleBN->setOrdenDetalleImpuestoUnidad( round( $f_MontoImpuestoUnidad, 4 ) );
                $o_VTA_OrdenDetalleBN->setOrdenDetalleImpuestoUnidadMN( round( $f_MontoImpuestoUnidadMN, 4 ) );
                $o_VTA_OrdenDetalleBN->setOrdenDetallePrecioUnidad( $f_PrecioUnitario );
                $o_VTA_OrdenDetalleBN->setOrdenDetallePrecioUnidadMN( $f_PrecioUnitarioMN );
            }

            $this->iniciarProceso( $o_VTA_OrdenDetalleBN );

            $con->commit();
            
        }
        catch ( Exception $o_Exception )
        {
            $con->rollback();
            throw new Exception( "CT/D/CP: ".$o_Exception->getMessage() );
        }
        
        return true;
    }
    
    public function iniciarProceso( VTA_OrdenDetalleBN $o_VTA_OrdenDetalleBN )
    {
        //VALIDACION POR ESTADO
        if( $o_VTA_OrdenDetalleBN->getObjectOrdenBN()->getOrdenEstado() != VTA_OrdenBN::ESTADO_ABIERTO )
        {
            throw new Exception( "La Orden tiene un estado ".$o_VTA_OrdenDetalleBN->getObjectOrdenBN()->getOrdenEstadoDesc() );
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //procedimiento especial para promociones
        if( $o_VTA_OrdenDetalleBN->TieneNumeroPromocion() )
        {
            $o_VTA_OrdenDetalleBN->setTipoProcPromo( "UPDATE" );
            return $this->iniciarProcesoPromocionGrupal( $o_VTA_OrdenDetalleBN );
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //pr( $o_VTA_OrdenDetalleBN ); exit;
        $con = Conexion::getConexion();
        $con->begin();
        try
        {
            myUser::getUser()->validar_session();

            $b_Result = $this->validarDetalleExisteItem( $o_VTA_OrdenDetalleBN );

            if( $b_Result )
            {
                //ACTUALIZAR DETALLE
                $this->actualizarLinea( $o_VTA_OrdenDetalleBN );
            }
            else
            {
                //AGREGAR NUEVO DETALLE
                $this->agregarLinea( $o_VTA_OrdenDetalleBN );
            }

            $this->actualizarMontosCabcecera( $o_VTA_OrdenDetalleBN );

            $con->commit();
        }
        catch ( Exception $o_Exception )
        {
            $con->rollback();
            throw new Exception( "CT/D/IP: ".$o_Exception->getMessage() );
        }
        return true;
    }

    public function agregarLinea( VTA_OrdenDetalleBN $o_VTA_OrdenDetalleBN )
    {
        try
        {
            $this->validarValoresxDefecto( $o_VTA_OrdenDetalleBN );
            //$this->validacionesPorDetalles( $o_VTA_OrdenDetalleBN );

            if( !$o_VTA_OrdenDetalleBN->getOrdenDetalleNum() )
            {
                $i_Id = VTA_OrdenDetalleDP::recuperarId( $o_VTA_OrdenDetalleBN->getOrdenId() );
                $o_VTA_OrdenDetalleBN->setOrdenDetalleNum( $i_Id );
            }
            $o_VTA_OrdenDetalleBN->setUsuarioCreacion( myUser::getUser()->getUserId() );
            $o_VTA_OrdenDetalleBN->setFechaCreacion( date( "Y-m-d H:i:s" ) );

            $o_VTA_OrdenDetalleDP = new VTA_OrdenDetalleDP( $o_VTA_OrdenDetalleBN );
            $o_VTA_OrdenDetalleDP->save();
            
            $this->iniciarReservaStockAlmacen( $o_VTA_OrdenDetalleBN, "I" );
            
            $this->registrarHistorial( "I", $o_VTA_OrdenDetalleBN );
        }
        catch ( Exception $o_Exception )
        {
            throw new Exception( "CT/V-INS: ".$o_Exception->getMessage() );
        }
        return true;
    }
    
    public function actualizarLinea( VTA_OrdenDetalleBN $o_VTA_OrdenDetalleBN )
    {
        try
        {
            $o_VTA_OrdenDetalleBN->setUsuarioModificacion( myUser::getUser()->getUserId() );
            $o_VTA_OrdenDetalleBN->setFechaModificacion( date( "Y-m-d H:i:s" ) );
            //$this->validacionesPorDetalles( $o_VTA_OrdenDetalleBN );
            $this->validarValoresxDefecto( $o_VTA_OrdenDetalleBN );

            $o_VTA_OrdenDetalleDP = new VTA_OrdenDetalleDP( $o_VTA_OrdenDetalleBN );
            $o_VTA_OrdenDetalleDP->update();
            
            $this->iniciarReservaStockAlmacen( $o_VTA_OrdenDetalleBN, "U" );
            
            $this->registrarHistorial( "U", $o_VTA_OrdenDetalleBN );
        }
        catch ( Exception $o_Exception )
        {
            throw new Exception( "CT/V-ACT: ".$o_Exception->getMessage() );
        }
        return true;
    }
    
    public function eliminarLinea( VTA_OrdenDetalleBN $o_VTA_OrdenDetalleBN )
    {
        $con = Conexion::getConexion();
        $con->begin();
        try
        {
            $o_VTA_OrdenDetalleFN = new VTA_OrdenDetalleFN();
            $o_Tmp_VTA_OrdenDetalleBN = $o_VTA_OrdenDetalleFN->selectByPK( $o_VTA_OrdenDetalleBN->getOrdenId(), $o_VTA_OrdenDetalleBN->getOrdenDetalleNum() );
            if( !$o_Tmp_VTA_OrdenDetalleBN )
            {
                throw new Exception( "No se encontro referencia de la linea de la Orden." );
            }

            $this->setOrdenDetalleHisBN( $o_Tmp_VTA_OrdenDetalleBN );

            if( $o_Tmp_VTA_OrdenDetalleBN->TieneNumeroPromocion() )
            {
                $o_Tmp_VTA_OrdenDetalleBN->setTipoProcPromo( "DELETE" );
                $this->iniciarProcesoPromocionGrupal( $o_Tmp_VTA_OrdenDetalleBN );
                $con->commit();
                return true;
            }
            
            $o_VTA_OrdenDetalleDP = new VTA_OrdenDetalleDP();
            $o_VTA_OrdenDetalleDP->setOrdenId( ( int ) $o_VTA_OrdenDetalleBN->getOrdenId() );
            $o_VTA_OrdenDetalleDP->setOrdenDetalleNum( ( int ) $o_VTA_OrdenDetalleBN->getOrdenDetalleNum() );
            $o_VTA_OrdenDetalleDP->delete();
            
            VTA_OrdenDP::actualizarCabaceraMontos( $o_VTA_OrdenDetalleBN->getOrdenId() );
            
            $this->iniciarReservaStockAlmacen( $o_Tmp_VTA_OrdenDetalleBN, "D" );
            
            $this->registrarHistorial( "D", $o_Tmp_VTA_OrdenDetalleBN );
            
            $con->commit();
        }
        catch ( Exception $o_Exception )
        {
            $con->rollback();
            throw new Exception( "CT/V-DLT: ".$o_Exception->getMessage() );
        }
        return true;
    }

    public function cambiarEstadoLineas( VTA_OrdenDetalleBN $o_VTA_OrdenDetalleBN )
    {
        $o_VTA_OrdenBN = $o_VTA_OrdenDetalleBN->getObjectOrdenBN();

        $o_VTA_OrdenDetalleFN = new VTA_OrdenDetalleFN();
        $o_VTA_OrdenDetalleFN->setOrdenId( $o_VTA_OrdenDetalleBN->getOrdenId() );
        $a_VTA_OrdenDetalle = $o_VTA_OrdenDetalleFN->select();
        
        if( $a_VTA_OrdenDetalle )
        {
            foreach ( $a_VTA_OrdenDetalle as $o_TMP_VTA_OrdenDetalleBN )
            {
                //se coloca una validacion
                if( $o_TMP_VTA_OrdenDetalleBN->getItemTipo() ==  VTA_OrdenDetalleBN::TIPO_PRODUCTO )
                {
                    if( $o_VTA_OrdenDetalleBN->getOrdenDetalleEstado() == VTA_OrdenBN::ESTADO_REVISADO || $o_VTA_OrdenDetalleBN->getOrdenDetalleEstado() == VTA_OrdenBN::ESTADO_CERRADO )
                    {
                        if( $o_TMP_VTA_OrdenDetalleBN->getOrdenDetallePrecioUnidad() <= 0 )
                        {
                            throw new Exception( "El siguiente Producto [".$o_TMP_VTA_OrdenDetalleBN->getItemCod()."] no tiene un precio." );
                        }
                    }
                }
                //////////////////////////
                $o_VTA_OrdenDetalleDP = new VTA_OrdenDetalleDP();
                $o_VTA_OrdenDetalleDP->setOrdenId( $o_TMP_VTA_OrdenDetalleBN->getOrdenId() );
                $o_VTA_OrdenDetalleDP->setOrdenDetalleNum( $o_TMP_VTA_OrdenDetalleBN->getOrdenDetalleNum() );
                $o_VTA_OrdenDetalleDP->setOrdenDetalleEstado( $o_VTA_OrdenDetalleBN->getOrdenDetalleEstado() );
                $o_VTA_OrdenDetalleDP->setUsuarioModificacion( myUser::getUser()->getUserId() );
                $o_VTA_OrdenDetalleDP->setFechaModificacion( date( "Y-m-d H:i:s" ) );
                $o_VTA_OrdenDetalleDP->update();
                
                if( $o_VTA_OrdenBN->getOrdenTipoId() == VTA_OrdenBN::ORDEN_ESTANDAR )
                {
                    if( $o_VTA_OrdenDetalleBN->getOrdenDetalleEstado() == VTA_OrdenBN::ESTADO_ANULADO )
                    {
                        if( $o_VTA_OrdenBN->getOrdenEstado() != VTA_OrdenBN::ESTADO_FACTURA )
                        {
                            $this->iniciarReservaStockAlmacen( $o_TMP_VTA_OrdenDetalleBN, "D" );
                        }
                    }
                    //AQUI SE AGREGA UN PROCEDIMIENTO, QUE ACTUALMENTE ESTE F LA ORDEN, Y QUIERE CAMBIAR A O LAS LINEAS, ES UNA ANULACION DE DOCUMENTO, POR LO TANTO SE RESERVA LAS LINEAS - 2020-10-11
                    if( $o_VTA_OrdenDetalleBN->getOrdenDetalleEstado() == VTA_OrdenBN::ESTADO_ABIERTO && $o_VTA_OrdenBN->getOrdenEstado() == VTA_OrdenBN::ESTADO_FACTURA )
                    {
                        $this->iniciarReservaStockAlmacen( $o_TMP_VTA_OrdenDetalleBN, "I" );
                    }
                }
            }
        }
    }
    
    public function validarDetalleExisteItem( VTA_OrdenDetalleBN $o_VTA_OrdenDetalleBN )
    {
        if( $o_VTA_OrdenDetalleBN->getItemTipo() == VTA_OrdenDetalleBN::TIPO_COMENTARIO )
        {
            return false;
        }
        
        $b_ExisItem       = false;
        $s_TmpNivelPrecio = "";
        $s_ItemCod        = $o_VTA_OrdenDetalleBN->getItemCod();

        //POR POLITICA, SI SE ENCUENTRA ITEM SE SUMA
        if( $o_VTA_OrdenDetalleBN->getOrdenDetalleNum() )
        {
            $o_VTA_OrdenDetalleFN = new VTA_OrdenDetalleFN();
            $o_Tmp_VTA_DocumentoDetalleBN = $o_VTA_OrdenDetalleFN->selectByPK( $o_VTA_OrdenDetalleBN->getOrdenId(), $o_VTA_OrdenDetalleBN->getOrdenDetalleNum() );

            $this->setOrdenDetalleHisBN( $o_Tmp_VTA_DocumentoDetalleBN );
            //$o_VTA_OrdenDetalleBN->setItemTipo( "P" );
            //$o_VTA_OrdenDetalleBN->setItemCod( $o_Tmp_VTA_DocumentoDetalleBN->getItemCod() );
            $o_VTA_OrdenDetalleBN->setLoteNum( $o_Tmp_VTA_DocumentoDetalleBN->getLoteNum() );
            //$o_VTA_OrdenDetalleBN->setOrdenDetallePrecioUnidad( $o_Tmp_VTA_DocumentoDetalleBN->getOrdenDetallePrecioUnidad() );
            //$o_VTA_OrdenDetalleBN->setOrdenDetallePrecioUnidadMN( $o_Tmp_VTA_DocumentoDetalleBN->getOrdenDetallePrecioUnidadMN() );
            $s_TmpNivelPrecio = $o_Tmp_VTA_DocumentoDetalleBN->getOrdenDetallePrecioNivel();
            $s_ItemCod        = $o_Tmp_VTA_DocumentoDetalleBN->getItemCod();
            
            if( !$o_VTA_OrdenDetalleBN->getOrdenDetalleCantidad() )
            {
                $o_VTA_OrdenDetalleBN->setOrdenDetalleCantidad( $o_Tmp_VTA_DocumentoDetalleBN->getOrdenDetalleCantidad() );
            }

            if( !$o_VTA_OrdenDetalleBN->getIdUnidad() )
            {
                $o_VTA_OrdenDetalleBN->setIdUnidad( $o_Tmp_VTA_DocumentoDetalleBN->getIdUnidad() );
            }

            if( !$o_VTA_OrdenDetalleBN->getCambioPrecio() )
            {
                if( $o_Tmp_VTA_DocumentoDetalleBN->getOrdenDetallePrecioNivel() == "P" )
                {
                    /*$o_VTA_OrdenDetalleBN->setOrdenDetallePrecioNivel( $o_Tmp_VTA_DocumentoDetalleBN->getOrdenDetallePrecioNivel() );
                    $o_VTA_OrdenDetalleBN->setOrdenDetallePrecioUnidad( $o_Tmp_VTA_DocumentoDetalleBN->getOrdenDetallePrecioUnidad() );
                    $o_VTA_OrdenDetalleBN->setOrdenDetallePrecioUnidadMN( $o_Tmp_VTA_DocumentoDetalleBN->getOrdenDetallePrecioUnidadMN() );*/

                    $o_VTA_OrdenDetalleBN->setPrecioUnidadIncImpuesto( $o_Tmp_VTA_DocumentoDetalleBN->getPrecioUnidadIncImpuesto() );
                    $o_VTA_OrdenDetalleBN->setPrecioUnidadIncImpuestoMN( $o_Tmp_VTA_DocumentoDetalleBN->getPrecioUnidadIncImpuestoMN() );
                    $o_VTA_OrdenDetalleBN->setOrdenDetalleImpuestoUnidad( $o_Tmp_VTA_DocumentoDetalleBN->getOrdenDetalleImpuestoUnidad() );
                    $o_VTA_OrdenDetalleBN->setOrdenDetalleImpuestoUnidadMN( $o_Tmp_VTA_DocumentoDetalleBN->getOrdenDetalleImpuestoUnidadMN() );
                    $o_VTA_OrdenDetalleBN->setOrdenDetallePrecioUnidad( $o_Tmp_VTA_DocumentoDetalleBN->getOrdenDetallePrecioUnidad() );
                    $o_VTA_OrdenDetalleBN->setOrdenDetallePrecioUnidadMN( $o_Tmp_VTA_DocumentoDetalleBN->getOrdenDetallePrecioUnidadMN() );
                }
            }
            
            $b_ExisItem = true;
        }
        else
        {
            //AHORA SE BUSCA EL ITEM EN EL DETALLE, SI SE ENCUENTRA SE SUMA MAS 1, ES COMO UNA VALIDACION DE QUE NO SE REPITA EL ITEM
            $o_VTA_OrdenDetalleFN = new VTA_OrdenDetalleFN();
            $o_VTA_OrdenDetalleFN->setOrdenId( $o_VTA_OrdenDetalleBN->getOrdenId() );
            //$o_VTA_OrdenDetalleFN->setItemTipo( "P" );
            $o_VTA_OrdenDetalleFN->setItemCod( $o_VTA_OrdenDetalleBN->getItemCod() );
            $o_VTA_OrdenDetalleFN->setAlmacenCod( $o_VTA_OrdenDetalleBN->getAlmacenCod() );
            $a_VTA_OrdenDetalle = $o_VTA_OrdenDetalleFN->select();
            if( $a_VTA_OrdenDetalle )
            {
                
                $o_Tmp_VTA_OrdenDetalleBN = $a_VTA_OrdenDetalle[0];
                
                $this->setOrdenDetalleHisBN( $o_Tmp_VTA_OrdenDetalleBN );
                
                $o_VTA_OrdenDetalleBN->setOrdenDetalleNum( $o_Tmp_VTA_OrdenDetalleBN->getOrdenDetalleNum() );
                $o_VTA_OrdenDetalleBN->setLoteNum( $o_Tmp_VTA_OrdenDetalleBN->getLoteNum() );
                
                $f_CantidadPedida = $o_Tmp_VTA_OrdenDetalleBN->getOrdenDetalleCantidad();
                if( $o_VTA_OrdenDetalleBN->getObjectItem()->getObjectTipoItem()->getTransacciondelSistemaFlag() )
                {
                    $f_CantidadPedida = $f_CantidadPedida + 1;
                }
                
                $o_VTA_OrdenDetalleBN->setOrdenDetalleCantidad( $f_CantidadPedida );

                $s_TmpNivelPrecio = $o_Tmp_VTA_OrdenDetalleBN->getOrdenDetallePrecioNivel();
                $s_ItemCod        = $o_Tmp_VTA_OrdenDetalleBN->getItemCod();
                if( $o_VTA_OrdenDetalleBN->getItemTipo() )
                {
                    $s_TmpNivelPrecio = $o_VTA_OrdenDetalleBN->getItemTipo();
                }

                if( !$o_VTA_OrdenDetalleBN->getIdUnidad() )
                {
                    $o_VTA_OrdenDetalleBN->setIdUnidad( $o_Tmp_VTA_OrdenDetalleBN->getIdUnidad() );
                }
                
                if( !$o_VTA_OrdenDetalleBN->getCambioPrecio() )
                {
                    if( $o_Tmp_VTA_OrdenDetalleBN->getOrdenDetallePrecioNivel() == "P" )
                    {
                        /*$o_VTA_OrdenDetalleBN->setOrdenDetallePrecioNivel( $o_Tmp_VTA_OrdenDetalleBN->getOrdenDetallePrecioNivel() );
                        $o_VTA_OrdenDetalleBN->setOrdenDetallePrecioUnidad( $o_Tmp_VTA_OrdenDetalleBN->getOrdenDetallePrecioUnidad() );
                        $o_VTA_OrdenDetalleBN->setOrdenDetallePrecioUnidadMN( $o_Tmp_VTA_OrdenDetalleBN->getOrdenDetallePrecioUnidadMN() );*/

                        $o_VTA_OrdenDetalleBN->setPrecioUnidadIncImpuesto( $o_Tmp_VTA_OrdenDetalleBN->getPrecioUnidadIncImpuesto() );
                        $o_VTA_OrdenDetalleBN->setPrecioUnidadIncImpuestoMN( $o_Tmp_VTA_OrdenDetalleBN->getPrecioUnidadIncImpuestoMN() );
                        $o_VTA_OrdenDetalleBN->setOrdenDetalleImpuestoUnidad( $o_Tmp_VTA_OrdenDetalleBN->getOrdenDetalleImpuestoUnidad() );
                        $o_VTA_OrdenDetalleBN->setOrdenDetalleImpuestoUnidadMN( $o_Tmp_VTA_OrdenDetalleBN->getOrdenDetalleImpuestoUnidadMN() );
                        $o_VTA_OrdenDetalleBN->setOrdenDetallePrecioUnidad( $o_Tmp_VTA_OrdenDetalleBN->getOrdenDetallePrecioUnidad() );
                        $o_VTA_OrdenDetalleBN->setOrdenDetallePrecioUnidadMN( $o_Tmp_VTA_OrdenDetalleBN->getOrdenDetallePrecioUnidadMN() );
                    }
                }

                $b_ExisItem = true;
            }
        }
        
        /////////////////////////////////////////////////////////////////////
        //SE ASIGNA UNA CANTIDAD POR DEFECTO
        if( !$o_VTA_OrdenDetalleBN->getOrdenDetalleCantidad() )
        {
            $o_VTA_OrdenDetalleBN->setOrdenDetalleCantidad( 1 );
        }
        /////////////////////////////////////////////////////////////////////
        
        //INFORMACION DE LA CABECERA
        $o_VTA_OrdenBN = $o_VTA_OrdenDetalleBN->getObjectOrdenBN();
        
        //se recupera el costo
        $o_ALM_ItemMastFN = new ALM_ItemMastFN();
        $o_ALM_ItemMastBN = $o_ALM_ItemMastFN->selectByPK( $o_VTA_OrdenDetalleBN->getItemCod() );

        if( !$o_VTA_OrdenDetalleBN->getOrdenDetalleNum() )
        {
            //es un detalle nuevo
            $o_VTA_OrdenDetalleBN->setIdUnidad( ( int ) $o_ALM_ItemMastBN->getUnidadVenta() ); //UNIDAD POR DEFECTO
            $o_VTA_OrdenDetalleBN->setIdItemTipo( $o_ALM_ItemMastBN->getIdItemTipo() ); //MERCADERIA POR DEFECTO
        }

        /*$f_CantidadConversion = $o_ALM_ItemMastBN->getCantidadUnidad(); //es la cantidad de conversion por la unidad de medida
        $i_ItemIdUnidadVenta  = $o_ALM_ItemMastBN->getUnidadVenta();
        $i_IdUnidadSelecion   = $o_VTA_OrdenDetalleBN->getIdUnidad();
        $b_ControlConversion  = false;

        if( $i_ItemIdUnidadVenta != $i_IdUnidadSelecion )
        {
            $b_ControlConversion  = true;
        }*/

        //aqui se agrega la condicion de q si es alquiler: se antepone en la descripcion del producto -> ALQUILER -     [SERMAQUI]2021-03-04
        if( $o_VTA_OrdenBN->getOrdenTipoComercialId() == VTA_OrdenBN::TIPO_COMERCIAL_ALQUILER )
        {
            $o_VTA_OrdenDetalleBN->setOrdenDetalleDescripcion( "ALQUILER - ".addslashes( $o_ALM_ItemMastBN->getDescripcionCompleta() ) );
        }
        else
        {
            $o_VTA_OrdenDetalleBN->setOrdenDetalleDescripcion( addslashes( $o_ALM_ItemMastBN->getDescripcionCompleta() ) );
        }

        //AHORA SE BUSCA EL PRECIO
        $i_IdTipoPrecio = '1';

        if( $o_VTA_OrdenDetalleBN->getOrdenDetallePrecioNivel() )
        {
            $i_IdTipoPrecio = $o_VTA_OrdenDetalleBN->getOrdenDetallePrecioNivel();
        }
        else 
        {
            if( $b_ExisItem )
            {
                $i_IdTipoPrecio = $s_TmpNivelPrecio;
            }
            else
            {
                $i_IdTipoPrecio = $o_VTA_OrdenDetalleBN->getNivelPrecioAsignado(); //ES EL NIVEL DE PRECIO ASIGNADO POR EL CLIENTE POR DEFECTO
            }
        }
        
        if( !$i_IdTipoPrecio )
        {
            throw new Exception( "No se encontro IdTipo de Precio para el Cliente." );
        }

        $o_VTA_OrdenDetalleBN->setOrdenDetallePrecioNivel( $i_IdTipoPrecio );

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //se pregunta el control de impuesto por cabecera de la cotizacion
        $b_ControlImpuesto = $o_VTA_OrdenBN->esGravadaConImpuesto();
        /*if( !$o_MST_ListaPrecioDetalleBN->getAfectoIGV() )
        {
            $b_ControlImpuesto = false;
        }*/
        if( !$o_ALM_ItemMastBN->EsAfectoaIGV() )
        {
            $b_ControlImpuesto = false;
        }

        //AHORA PREGUNTAMOS SI ESTA EXONERADO POR LA ZONA
        $b_ControlExonerado = $o_VTA_OrdenBN->esExoneradodeIGV();
        if( $b_ControlExonerado )
        {
            $b_ControlImpuesto = false;
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        $o_VTA_OrdenDetalleBN->setOrdenDetalleAfectoImpuesto( "Y" );
        if( !$b_ControlImpuesto )
        {
            $o_VTA_OrdenDetalleBN->setOrdenDetalleAfectoImpuesto( "N" );
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        if( $i_IdTipoPrecio == "P" ){ return $b_ExisItem; } //si el precio es personalizado, no se busca el precio por nivel del cliente
        
        //AHORA SE ASIGNA EL PRECIO
        $PrecioUnitarioSoles = 0.00;
        $PrecioUnitarioME    = 0.00;
        
        //para recuperar la moneda del sistema
        $o_MST_ListaPrecioCabeceraFN = new MST_ListaPrecioCabeceraFN();
        $o_MST_ListaPrecioCabeceraBN = $o_MST_ListaPrecioCabeceraFN->selectByPK( myUser::getUser()->getIdBusiness(), myUser::getUser()->getIdSucursal() );

        if( !$o_MST_ListaPrecioCabeceraBN )
        {
            $o_MST_ListaPrecioCabeceraBN = $o_MST_ListaPrecioCabeceraFN->buscaListaPrecioAlternativo();
        }

        //se busca el precio
        $b_ControlPrecios = false;
        if( $o_ALM_ItemMastBN->getEsParaVenta() == "SI" )
        {
            $b_ControlPrecios = true;
        }
        if( $o_ALM_ItemMastBN->getEsParaAlquiler() == "SI" )
        {
            $b_ControlPrecios = true;
        }
        
        $o_MST_ListaPrecioDetalleFN = new MST_ListaPrecioDetalleFN();
        
        //ahora recuperamos que precio recupera
        $o_MST_ListaPrecioDetalleBN = null;
        if( $b_ControlPrecios )
        {
            $o_MST_ListaPrecioDetalleFN->setIdTipoLista( $o_VTA_OrdenBN->getOrdenTipoComercialId() );
            $o_MST_ListaPrecioDetalleFN->setIdCompania( $o_MST_ListaPrecioCabeceraBN->getIdCompania() );
            $o_MST_ListaPrecioDetalleFN->setIdSucursal( $o_MST_ListaPrecioCabeceraBN->getIdSucursal() );
            
            if( $o_VTA_OrdenDetalleBN->getForzarIdTipoLista() )
            {
                //$o_MST_ListaPrecioDetalleFN->setIdTipoLista( $o_VTA_OrdenDetalleBN->getForzarIdTipoLista() );
                $o_VTA_OrdenBN->setOrdenTipoComercialId( $o_VTA_OrdenDetalleBN->getForzarIdTipoLista() );
                $o_MST_ListaPrecioDetalleFN->setIdTipoLista( $o_VTA_OrdenBN->getOrdenTipoComercialId() );
            }
             
            if( $o_VTA_OrdenBN->getOrdenTipoComercialId() == 1 )
            {
                $o_MST_ListaPrecioDetalleFN->setIdRango( $o_ALM_ItemMastBN->getIdRangoVenta() );
            }
            if( $o_VTA_OrdenBN->getOrdenTipoComercialId() == 2 )
            {
                $o_MST_ListaPrecioDetalleFN->setIdRango( $o_ALM_ItemMastBN->getIdRangoAlquiler() );
            }
            
            $o_MST_ListaPrecioDetalleFN->setIdItem( $o_VTA_OrdenDetalleBN->getItemCod() );

            $a_MST_ListaPrecioDetalle = $o_MST_ListaPrecioDetalleFN->select();
            foreach ( $a_MST_ListaPrecioDetalle as $o_TMP_MST_ListaPrecioDetalleBN )
            {
                $o_MST_RangoDetalleBN = $o_TMP_MST_ListaPrecioDetalleBN->getObjectRangoDetalle();
                if( $o_VTA_OrdenDetalleBN->getOrdenDetalleCantidad() >= $o_MST_RangoDetalleBN->getMinimo() && $o_VTA_OrdenDetalleBN->getOrdenDetalleCantidad() <= $o_MST_RangoDetalleBN->getMaximo() )
                {
                    $o_MST_ListaPrecioDetalleBN = $o_TMP_MST_ListaPrecioDetalleBN;
                    break;
                }
            }
        }
        else
        {
            $o_MST_ListaPrecioDetalleBN = $o_MST_ListaPrecioDetalleFN->selectByPK( myUser::getUser()->getIdBusiness(), myUser::getUser()->getIdSucursal(), $s_ItemCod, $i_IdTipoPrecio );
            if( !$o_MST_ListaPrecioDetalleBN )
            {
                $o_MST_ListaPrecioDetalleBN = MST_ListaPrecioDetalleFN::buscarPrecioGeneral( $s_ItemCod );
            }
        }
        
        if( !$o_MST_ListaPrecioDetalleBN )
        {
            $o_MST_ListaPrecioDetalleBN = new MST_ListaPrecioDetalleBN();
            $o_MST_ListaPrecioDetalleBN->setPrecioCostoIGV( 0 );
            $o_MST_ListaPrecioDetalleBN->setPrecioVentaIGV( 0 );
        }
//pr( $o_MST_ListaPrecioDetalleBN ); exit;
        //el tipo de cambio
        //$f_TipoCob = GSS_TipoCambioFN::getStaticTipoCambioCobranza(); //EN EL FUTURO PODRIA SER EL TIPO DE CAMBIO GUARDADO EN LA ORDEN CABECERA
        //$f_TipoCon = GSS_TipoCambioFN::getStaticTipoCambioCompra(); //EN EL FUTURO PODRIA SER EL TIPO DE CAMBIO GUARDADO EN LA ORDEN CABECERA
        $f_TipoCob = $o_VTA_OrdenBN->getMonedaCambioValor();

        //////////////////////////////////////////////////////////////////////////////////////////
        //SE RECUPERA VALOR DE IGV ACTUAL
        /*
        $o_GSS_ParametroMastFN = new GSS_ParametroMastFN();
        $o_GSS_ParametroMastBN = $o_GSS_ParametroMastFN->selectByPK( -1, 'AL', 'IGV' );
        $f_ValorIGV = floatval( $o_GSS_ParametroMastBN->getNumero() ); //0.18
        $f_ValorIGVMasUno = floatval( $o_GSS_ParametroMastBN->getNumero() ) + 1;  //1.18
        */
        $f_ValorIGV       = GSS_ParametroMastFN::getValorPorTipo( "AL", "IGV" ); //0.18
        $f_ValorIGVMasUno = $f_ValorIGV + 1;  //1.18
        //////////////////////////////////////////////////////////////////////////////////////////
        
        //ahora recupero la moneda de la Orden de Venta
        $s_OrdenMonedaCod = $o_VTA_OrdenDetalleBN->getObjectOrdenBN()->getMonedaCod();
        
        if( $s_OrdenMonedaCod == "EX" )
        {
            if( !$f_TipoCob )
            {
                throw new Exception( "El Tipo de Cambio no esta ingresado." );
            }
        }
        
        if( $o_VTA_OrdenDetalleBN->getObjectOrdenBN()->getOrdenTipoObject()->getOrdenTipoPrefijo() != "M" )
        {
            if( !$o_MST_ListaPrecioDetalleBN->getPrecioCosto() )
            {
                throw new Exception( "El Costo no puede ser menor o igual a 0." );
            }
        }

        if( $o_MST_ListaPrecioDetalleBN )
        {
            if( $o_MST_ListaPrecioCabeceraBN->getIdMoneda() == "LO" ) //MONEDA DE LA LISTA DE PRECIOS ES SOLES
            {
                if( $s_OrdenMonedaCod == "LO" )
                {
                    if( $b_ControlImpuesto )
                    {
                        //moneda por la seleccion de la orden
                        $f_MontoIncImpuestoUnidad  = $o_MST_ListaPrecioDetalleBN->getPrecioVentaIGV();
                        /*if( $b_ControlConversion )
                        {
                            $f_MontoIncImpuestoUnidad = round( $f_MontoIncImpuestoUnidad / $f_CantidadConversion, 2 );
                            //$f_MontoIncImpuestoUnidad  = $o_MST_ListaPrecioDetalleBN->getPrecioVentaIGV();
                        }*/
                        $f_PrecioUnitario          = round( $f_MontoIncImpuestoUnidad / $f_ValorIGVMasUno, 2 );
                        $f_MontoImpuestoUnidad     = round( $f_MontoIncImpuestoUnidad - $f_PrecioUnitario, 2 );
                        
                        //se convierte a la moneda nacional
                        $f_MontoIncImpuestoUnidadMN  = $f_MontoIncImpuestoUnidad;
                        $f_PrecioUnitarioMN          = round( $f_MontoIncImpuestoUnidadMN / $f_ValorIGVMasUno, 2 );
                        $f_MontoImpuestoUnidadMN     = round( $f_MontoIncImpuestoUnidadMN - $f_PrecioUnitarioMN, 2 );
                        
                        $o_VTA_OrdenDetalleBN->setCostoUnidadIncImpuesto( utilMath::fnround( $o_MST_ListaPrecioDetalleBN->getPrecioCosto(), 2 ) );
                        $o_VTA_OrdenDetalleBN->setCostoUnidadIncImpuestoMN( utilMath::fnround( $o_MST_ListaPrecioDetalleBN->getPrecioCosto(), 2 ) );
                    }
                    else 
                    {
                        //moneda por la seleccion de la orden
                        $f_MontoIncImpuestoUnidad  = $o_MST_ListaPrecioDetalleBN->getPrecioVentaIGV();
                        $f_PrecioUnitario          = $f_MontoIncImpuestoUnidad;
                        $f_MontoImpuestoUnidad     = 0;
                        
                        //se convierte a la moneda nacional
                        $f_MontoIncImpuestoUnidadMN  = $f_MontoIncImpuestoUnidad;
                        $f_PrecioUnitarioMN          = $f_MontoIncImpuestoUnidad;
                        $f_MontoImpuestoUnidadMN     = 0;
                        
                        $o_VTA_OrdenDetalleBN->setCostoUnidadIncImpuesto( utilMath::fnround( $o_MST_ListaPrecioDetalleBN->getPrecioCosto(), 2 ) );
                        $o_VTA_OrdenDetalleBN->setCostoUnidadIncImpuestoMN( utilMath::fnround( $o_MST_ListaPrecioDetalleBN->getPrecioCosto(), 2 ) );
                    }
                    
                }
                if( $s_OrdenMonedaCod == "EX" )
                {
                    if( $b_ControlImpuesto )
                    {
                        //moneda por la seleccion de la orden
                        $f_MontoIncImpuestoUnidad  = utilMath::fnround( $o_MST_ListaPrecioDetalleBN->getPrecioVentaIGV() / $f_TipoCob, 2 );
                        $f_PrecioUnitario          = round( $f_MontoIncImpuestoUnidad / $f_ValorIGVMasUno, 2 );
                        $f_MontoImpuestoUnidad     = round( $f_MontoIncImpuestoUnidad - $f_PrecioUnitario, 2 );
                        
                        //se convierte a la moneda nacional
                        $f_MontoIncImpuestoUnidadMN  = $o_MST_ListaPrecioDetalleBN->getPrecioVentaIGV();
                        $f_PrecioUnitarioMN          = round( $f_MontoIncImpuestoUnidadMN / $f_ValorIGVMasUno, 2 );
                        $f_MontoImpuestoUnidadMN     = round( $f_MontoIncImpuestoUnidadMN - $f_PrecioUnitarioMN, 2 );
                        
                        $o_VTA_OrdenDetalleBN->setCostoUnidadIncImpuesto( utilMath::fnround( $o_MST_ListaPrecioDetalleBN->getPrecioCosto() / $f_TipoCob, 2 ) );
                        $o_VTA_OrdenDetalleBN->setCostoUnidadIncImpuestoMN( utilMath::fnround( $o_MST_ListaPrecioDetalleBN->getPrecioCosto(), 2 ) );
                    }
                    else
                    {
                        //moneda por la seleccion de la orden
                        $f_MontoIncImpuestoUnidad  = utilMath::fnround( $o_MST_ListaPrecioDetalleBN->getPrecioVentaIGV() / $f_TipoCob, 2 );
                        $f_PrecioUnitario          = $f_MontoIncImpuestoUnidad;
                        $f_MontoImpuestoUnidad     = 0;
                        
                        //se convierte a la moneda nacional
                        $f_MontoIncImpuestoUnidadMN  = $o_MST_ListaPrecioDetalleBN->getPrecioVentaIGV();
                        $f_PrecioUnitarioMN          = $f_MontoIncImpuestoUnidadMN;
                        $f_MontoImpuestoUnidadMN     = 0;
                        
                        $o_VTA_OrdenDetalleBN->setCostoUnidadIncImpuesto( utilMath::fnround( $o_MST_ListaPrecioDetalleBN->getPrecioCosto() / $f_TipoCob, 2 ) );
                        $o_VTA_OrdenDetalleBN->setCostoUnidadIncImpuestoMN( utilMath::fnround( $o_MST_ListaPrecioDetalleBN->getPrecioCosto(), 2 ) );
                    }
                }
            }
            /*
            if( $o_MST_ListaPrecioCabeceraBN->getIdMoneda() == "EX" ) //MONEDA DE LA LISTA DE PRECIOS ES DOLARES
            {
                if( $s_OrdenMonedaCod == "LO" )
                {
                    if( $b_ControlImpuesto )
                    {
                        //moneda por la seleccion de la orden
                        $f_MontoIncImpuestoUnidad  = utilMath::fnround( $o_MST_ListaPrecioDetalleBN->getPrecioVentaIGV() * $f_TipoCob, 2 );
                        $f_PrecioUnitario          = round( $f_MontoIncImpuestoUnidad / $f_ValorIGVMasUno, 2 );
                        $f_MontoImpuestoUnidad     = round( $f_MontoIncImpuestoUnidad - $f_PrecioUnitario, 2 );
                        
                        //se convierte a la moneda nacional
                        $f_MontoIncImpuestoUnidadMN  = $f_MontoIncImpuestoUnidad;
                        $f_PrecioUnitarioMN          = round( $f_MontoIncImpuestoUnidadMN / $f_ValorIGVMasUno, 2 );
                        $f_MontoImpuestoUnidadMN     = round( $f_MontoIncImpuestoUnidadMN - $f_PrecioUnitarioMN, 2 );
                        
                        $o_VTA_OrdenDetalleBN->setCostoUnidadIncImpuesto( utilMath::fnround( $o_MST_ListaPrecioDetalleBN->getPrecioCostoIGV() * $f_TipoCob, 2 ) );
                        $o_VTA_OrdenDetalleBN->setCostoUnidadIncImpuestoMN( utilMath::fnround( $o_MST_ListaPrecioDetalleBN->getPrecioCostoIGV() * $f_TipoCob, 2 ) );
                    }
                    else
                    {
                        //moneda por la seleccion de la orden
                        $f_MontoIncImpuestoUnidad  = utilMath::fnround( $o_MST_ListaPrecioDetalleBN->getPrecioVenta() * $f_TipoCob, 2 );
                        $f_PrecioUnitario          = $f_MontoIncImpuestoUnidad;
                        $f_MontoImpuestoUnidad     = 0;
                        
                        //se convierte a la moneda nacional
                        $f_MontoIncImpuestoUnidadMN  = $f_MontoIncImpuestoUnidad;
                        $f_PrecioUnitarioMN          = $f_MontoIncImpuestoUnidadMN;
                        $f_MontoImpuestoUnidadMN     = 0;
                        
                        $o_VTA_OrdenDetalleBN->setCostoUnidadIncImpuesto( utilMath::fnround( $o_MST_ListaPrecioDetalleBN->getPrecioCosto() * $f_TipoCob, 2 ) );
                        $o_VTA_OrdenDetalleBN->setCostoUnidadIncImpuestoMN( utilMath::fnround( $o_MST_ListaPrecioDetalleBN->getPrecioCosto() * $f_TipoCob, 2 ) );
                    }
                }
                if( $s_OrdenMonedaCod == "EX" )
                {
                    if( $b_ControlImpuesto )
                    {
                        //moneda por la seleccion de la orden
                        $f_MontoIncImpuestoUnidad  = $o_MST_ListaPrecioDetalleBN->getPrecioVentaIGV();
                        $f_PrecioUnitario          = round( $f_MontoIncImpuestoUnidad / $f_ValorIGVMasUno, 2 );
                        $f_MontoImpuestoUnidad     = round( $f_MontoIncImpuestoUnidad - $f_PrecioUnitario, 2 );
                        
                        //se convierte a la moneda nacional
                        $f_MontoIncImpuestoUnidadMN  = utilMath::fnround( $f_MontoIncImpuestoUnidad * $f_TipoCob, 2 );
                        $f_PrecioUnitarioMN          = round( $f_MontoIncImpuestoUnidadMN / $f_ValorIGVMasUno, 2 );
                        $f_MontoImpuestoUnidadMN     = round( $f_MontoIncImpuestoUnidadMN - $f_PrecioUnitarioMN, 2 );
                        
                        $o_VTA_OrdenDetalleBN->setCostoUnidadIncImpuesto( utilMath::fnround( $o_VTA_OrdenDetalleBN->getCostoUnidadIncImpuesto(), 2 ) );
                        $o_VTA_OrdenDetalleBN->setCostoUnidadIncImpuestoMN( utilMath::fnround( $o_VTA_OrdenDetalleBN->getCostoUnidadIncImpuestoMN() * $f_TipoCob, 2 ) );
                    }
                    else
                    {
                        //moneda por la seleccion de la orden
                        $f_MontoIncImpuestoUnidad  = $o_MST_ListaPrecioDetalleBN->getPrecioVenta();
                        $f_PrecioUnitario          = $f_MontoIncImpuestoUnidad;
                        $f_MontoImpuestoUnidad     = 0;
                        
                        //se convierte a la moneda nacional
                        $f_MontoIncImpuestoUnidadMN  = utilMath::fnround( $f_MontoIncImpuestoUnidad * $f_TipoCob, 2 );
                        $f_PrecioUnitarioMN          = $f_MontoIncImpuestoUnidadMN;
                        $f_MontoImpuestoUnidadMN     = 0;
                        
                        $o_VTA_OrdenDetalleBN->setCostoUnidadIncImpuesto( utilMath::fnround( $o_MST_ListaPrecioDetalleBN->getPrecioCosto(), 2 ) );
                        $o_VTA_OrdenDetalleBN->setCostoUnidadIncImpuestoMN( utilMath::fnround( $o_MST_ListaPrecioDetalleBN->getPrecioCosto(), 2 ) );
                    }
                }
            }*/
        }
        else
        {
            if( $o_VTA_OrdenDetalleBN->getObjectOrdenBN()->getOrdenTipoObject()->getOrdenTipoCod() != "OM" )
            {
                throw new Exception( "No se encontro un precio asociado al Item." );
            }
        }

        $o_VTA_OrdenDetalleBN->setPrecioUnidadIncImpuesto( $f_MontoIncImpuestoUnidad );
        $o_VTA_OrdenDetalleBN->setPrecioUnidadIncImpuestoMN( $f_MontoIncImpuestoUnidadMN );
        $o_VTA_OrdenDetalleBN->setOrdenDetalleImpuestoUnidad( round( $f_MontoImpuestoUnidad, 2 ) );
        $o_VTA_OrdenDetalleBN->setOrdenDetalleImpuestoUnidadMN( round( $f_MontoImpuestoUnidadMN, 2 ) );
        $o_VTA_OrdenDetalleBN->setOrdenDetallePrecioUnidad( $f_PrecioUnitario );
        $o_VTA_OrdenDetalleBN->setOrdenDetallePrecioUnidadMN( $f_PrecioUnitarioMN );

        return $b_ExisItem;
    }

    public function validarValoresxDefecto( VTA_OrdenDetalleBN $o_VTA_OrdenDetalleBN )
    {
        //ANTES DE SALIR
        if( !$o_VTA_OrdenDetalleBN->getOrdenDetalleNum() )
        {
            //se asgina el lote con la fecha de vencimiento mas proximo
            $a_ALM_ItemAlmacenStock = ALM_ItemAlmacenStockFN::recuperarLotes( $o_VTA_OrdenDetalleBN->getObjectOrdenBN()->getIdCompania(), $o_VTA_OrdenDetalleBN->getAlmacenCod(), $o_VTA_OrdenDetalleBN->getItemCod(), false );
            foreach ( $a_ALM_ItemAlmacenStock as $i_Key => $o_ALM_ItemAlmacenStockBN )
            {
                $f_StockDisponible  = $o_ALM_ItemAlmacenStockBN->getStockDisponible();
                $IdLote             = $o_ALM_ItemAlmacenStockBN->getIdLote();
                $FechaVencimiento   = $o_ALM_ItemAlmacenStockBN->getFechaVencimiento();

                $o_VTA_OrdenDetalleBN->setLoteNum( $IdLote );
                $o_VTA_OrdenDetalleBN->setFechaVencimiento( $FechaVencimiento );

                break;
            }
        }

        if( $o_VTA_OrdenDetalleBN->getItemTipo() == VTA_OrdenDetalleBN::TIPO_COMENTARIO )
        {
            return true;
        }
        
        //VALIDACIONES
        if( $o_VTA_OrdenDetalleBN->getOrdenDetalleCantidad() < 0 )
        {
            throw new Exception( "La cantidad 0 no esta permitido." );
        }

        //INFORMACION DE LA CABECERA
        //$o_VTA_OrdenBN = $o_VTA_OrdenDetalleBN->getObjectOrdenBN();
        
        //$b_ControlImpuesto = $o_VTA_OrdenBN->esGravadaConImpuesto();
        /*
        if( !$o_VTA_OrdenDetalleBN->getLoteNum() )
        {
            $o_VTA_OrdenDetalleBN->setLoteNum( "000" );
        }
        */
        if( !$o_VTA_OrdenDetalleBN->getItemTipo() )
        {
            $o_VTA_OrdenDetalleBN->setItemTipo( "P" );
            if( $o_VTA_OrdenDetalleBN->getObjectItem()->getIdItemTipo() == "02" ) //servicios
            {
                $o_VTA_OrdenDetalleBN->setItemTipo( "S" );
            }
        }

        $o_VTA_OrdenDetalleBN->setOrdenDetalleEstado( "O"); //por defecto
        //$o_VTA_OrdenDetalleBN->setOrdenDetalleAfectoImpuesto( "N" );

        $f_CantidadPedida = $o_VTA_OrdenDetalleBN->getOrdenDetalleCantidad();
        if( $o_VTA_OrdenDetalleBN->getOrdenDetalleAfectoImpuesto() == "Y" )
        {
            //$o_VTA_OrdenDetalleBN->setOrdenDetalleAfectoImpuesto( "Y" );
            
            //////////////////////////////////////////////////////////////////////////////////////////
            //SE RECUPERA VALOR DE IGV ACTUAL
            /*
            $o_GSS_ParametroMastFN = new GSS_ParametroMastFN();
            $o_GSS_ParametroMastBN = $o_GSS_ParametroMastFN->selectByPK( -1, 'AL', 'IGV' );
            $f_ValorIGV            = floatval( $o_GSS_ParametroMastBN->getNumero() );
            $f_ValorIGVMasUno      = floatval( $o_GSS_ParametroMastBN->getNumero() ) + 1;
            */
            $f_ValorIGV       = GSS_ParametroMastFN::getValorPorTipo( "AL", "IGV" ); //0.18
            $f_ValorIGVMasUno = $f_ValorIGV + 1;  //1.18
            //////////////////////////////////////////////////////////////////////////////////////////

            $f_MontoIncImpuestoUnidad   = $o_VTA_OrdenDetalleBN->getPrecioUnidadIncImpuesto();
            $f_MontoIncImpuestoUnidadMN = $o_VTA_OrdenDetalleBN->getPrecioUnidadIncImpuestoMN();

            $f_MontoTotalNeto   = round( $f_MontoIncImpuestoUnidad * $f_CantidadPedida, 2 );
            $f_MontoTotalNetoMN = round($f_MontoIncImpuestoUnidadMN * $f_CantidadPedida, 2 );
            
            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            
            $f_MontoSubTotal   = round( $f_MontoTotalNeto / $f_ValorIGVMasUno, 2 );
            $f_MontoSubTotalMN = round( $f_MontoTotalNetoMN / $f_ValorIGVMasUno, 2 );
            
            $f_MontoSubTotalImpuesto   = round( $f_MontoTotalNeto - $f_MontoSubTotal, 2 );
            $f_MontoSubTotalImpuestoMN = round( $f_MontoTotalNetoMN - $f_MontoSubTotalMN, 2 );

            $o_VTA_OrdenDetalleBN->setOrdenDetalleSubTotalVenta( $f_MontoSubTotal );
            $o_VTA_OrdenDetalleBN->setOrdenDetalleSubTotalVentaMN( $f_MontoSubTotalMN );
            $o_VTA_OrdenDetalleBN->setOrdenDetalleSubTotalImpuesto( $f_MontoSubTotalImpuesto );
            $o_VTA_OrdenDetalleBN->setOrdenDetalleSubTotalImpuestoMN( $f_MontoSubTotalImpuestoMN );
            $o_VTA_OrdenDetalleBN->setOrdenDetalleSubTotalNeto( $f_MontoTotalNeto );
            $o_VTA_OrdenDetalleBN->setOrdenDetalleSubTotalNetoMN( round( $f_MontoTotalNetoMN, 2 ) );
        }
        else
        {
            $o_VTA_OrdenDetalleBN->setOrdenDetalleSubTotalVenta( round( $f_CantidadPedida * $o_VTA_OrdenDetalleBN->getOrdenDetallePrecioUnidad(), 2 ) );
            $o_VTA_OrdenDetalleBN->setOrdenDetalleSubTotalVentaMN( round( $f_CantidadPedida * $o_VTA_OrdenDetalleBN->getOrdenDetallePrecioUnidadMN(), 2 ) );
            $o_VTA_OrdenDetalleBN->setOrdenDetalleSubTotalImpuesto( 0.00 );
            $o_VTA_OrdenDetalleBN->setOrdenDetalleSubTotalImpuestoMN( 0.00 );
            $o_VTA_OrdenDetalleBN->setOrdenDetalleSubTotalNeto( round( $f_CantidadPedida * $o_VTA_OrdenDetalleBN->getOrdenDetallePrecioUnidad(), 2 ) );
            $o_VTA_OrdenDetalleBN->setOrdenDetalleSubTotalNetoMN( round( $f_CantidadPedida * $o_VTA_OrdenDetalleBN->getOrdenDetallePrecioUnidadMN(), 2 ) );
        }
        //pr( $o_VTA_OrdenDetalleBN ); exit;
    }

    public function validacionesPorDetalles( VTA_OrdenDetalleBN $o_VTA_OrdenDetalleBN )
    {
        //si es orden master no importa el stock
        if( $o_VTA_OrdenDetalleBN->getObjectOrdenBN()->getOrdenTipoObject()->getOrdenTipoCod() == "OM" )
        {
            return true;
        }
        
        //Parametros:
        $IdCompania     = myUser::getUser()->getIdBusiness();
        $IdItem         = $o_VTA_OrdenDetalleBN->getItemCod();
        $IdAlmacen      = $o_VTA_OrdenDetalleBN->getAlmacenCod();
        $IdCondicion    = ALM_ItemAlmacenStockBN::CONDICION_POR_DEFECTO;
        $IdLote         = $o_VTA_OrdenDetalleBN->getLoteNum();
        $CantidadPedida = $o_VTA_OrdenDetalleBN->getOrdenDetalleCantidad();
        $StockReservado  = 0;

        $o_ALM_ItemAlmacenStockFN = new ALM_ItemAlmacenStockFN();
        $o_ALM_ItemAlmacenStockValBN = $o_ALM_ItemAlmacenStockFN->selectByPK( $IdCompania, $IdItem, $IdAlmacen, $IdCondicion, $IdLote );
        if( !$o_ALM_ItemAlmacenStockValBN )
        {
            
            throw new Exception( "No se encontro Stock para Item." );
        }
        $StockDisponible = $o_ALM_ItemAlmacenStockValBN->getStockDisponible();

        if( $o_VTA_OrdenDetalleBN->getOrdenDetalleNum() )
        {
            $o_ALM_ReservaItemStockBN = ALM_ReservaItemStockFN::getObjectReservaItemxDocOrdDetalle( $o_VTA_OrdenDetalleBN );
            if( $o_ALM_ReservaItemStockBN )
            {
                $StockReservado = $o_ALM_ReservaItemStockBN->getReservaCantidad();
            }
        }
        $StockDispoTotal = $StockDisponible + $StockReservado;

        //VALIDACIONES:
        //POR PRECIO
        if( $o_VTA_OrdenDetalleBN->getOrdenDetallePrecioUnidad() <= 0 || $o_VTA_OrdenDetalleBN->getOrdenDetallePrecioUnidadMN() <= 0 )
        {
            throw new Exception( "No se puede Agregar un detalle sin precio." );
        }

        if( $o_VTA_OrdenDetalleBN->getOrdenDetalleCantidad() <= 0 )
        {
            throw new Exception( "La Cantidad 0 no esta permitido Item [$IdItem]." );
        }

        //POR STOCK
        if( Constantes::CONS_VTA_VALIDAR_STOCK )
        {
            if( $CantidadPedida > $StockDispoTotal )
            {
                if( $o_VTA_OrdenDetalleBN->getObjectItem()->SiUsarDisponibleStock() )
                {
                    throw new Exception( "El Codigo $IdItem tiene una Cantidad mayor al Stock." );
                }
            }
        }
        return true;
    }
    
    public function actualizarMontosCabcecera( VTA_OrdenDetalleBN $o_VTA_OrdenDetalleBN )
    {
        VTA_OrdenDP::actualizarCabaceraMontos( $o_VTA_OrdenDetalleBN->getOrdenId() );
    }
    
    public function iniciarReservaStockAlmacen( VTA_OrdenDetalleBN $o_VTA_OrdenDetalleBN, $TipoProc = null )
    {
        if( $o_VTA_OrdenDetalleBN->getItemTipo() == VTA_OrdenDetalleBN::TIPO_COMENTARIO )
        {
            return true;
        }
        
        if( $o_VTA_OrdenDetalleBN->getObjectOrdenBN()->getOrdenTipoObject()->getOrdenTipoPrefijo() == "M" )
        {
            return true;
        }
        
        $o_ALM_ReservaItemStockBN = new ALM_ReservaItemStockBN();
        $o_ALM_ReservaItemStockBN->setTipoOperacion( $TipoProc );
        $o_ALM_ReservaItemStockBN->setIdCompania( $o_VTA_OrdenDetalleBN->getObjectOrdenBN()->getCiaCod() );
        $o_ALM_ReservaItemStockBN->setIdAlmacen( $o_VTA_OrdenDetalleBN->getObjectOrdenBN()->getAlmacenCod() );
        $o_ALM_ReservaItemStockBN->setIdCondicion( "0" );
        $o_ALM_ReservaItemStockBN->setIdItem( $o_VTA_OrdenDetalleBN->getItemCod() );
        $o_ALM_ReservaItemStockBN->setIdLote( $o_VTA_OrdenDetalleBN->getLoteNum() );
        $o_ALM_ReservaItemStockBN->setReservaDocTipo( "ORD" );
        $o_ALM_ReservaItemStockBN->setReservaDocNumero( $o_VTA_OrdenDetalleBN->getObjectOrdenBN()->getOrdenNum() );
        $o_ALM_ReservaItemStockBN->setReservaRefNumero( ( string ) $o_VTA_OrdenDetalleBN->getObjectOrdenBN()->getOrdenId() );
        $o_ALM_ReservaItemStockBN->setReservaSecuencia( $o_VTA_OrdenDetalleBN->getOrdenDetalleNum() );
        $o_ALM_ReservaItemStockBN->setReservaCantidad( $o_VTA_OrdenDetalleBN->getOrdenDetalleCantidad() );
        $o_ALM_ReservaItemStockBN->setUsuarioCreacion( myUser::getUser()->getUserId() );
        $o_ALM_ReservaItemStockBN->setFechaCreacion( date( "Y-m-d H:i:s" ) );
        $o_ALM_ReservaItemStockBN->setUsuarioActualizacion( myUser::getUser()->getUserId() );
        $o_ALM_ReservaItemStockBN->setFechaActualizacion( date( "Y-m-d H:i:s" ) );
        
        $o_ReservaItemStockBL = new ReservaItemStockBL();
        $o_ReservaItemStockBL->inincarProcesoReservaItemStock( $o_ALM_ReservaItemStockBN );

        return true;
    }
}