From a0d69ddc5e4e32a2697a1b76e68baf84295453a9 Mon Sep 17 00:00:00 2001 From: Luis Quijada Date: Sat, 12 Apr 2025 14:58:24 -0700 Subject: [PATCH] Cambios Finalizacion de OP --- App_Code/ClsOP.vb | 11 +- OP/OP.aspx | 117 +++++++++++--- OP/OP.aspx.vb | 384 ++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 426 insertions(+), 86 deletions(-) diff --git a/App_Code/ClsOP.vb b/App_Code/ClsOP.vb index eb34c60ee..624bb0a8a 100644 --- a/App_Code/ClsOP.vb +++ b/App_Code/ClsOP.vb @@ -481,15 +481,16 @@ Public Class ClsOP Return Retorno End Function - Public Function GetEstatusOP(CveEmpresa As Integer, Optional CveEstatusOP As Integer = -1, Optional TipoEstatus As Integer = -1, Optional Estatus As Integer = -1) As Boolean + Public Function GetEstatusOP(CveEmpresa As Integer, Optional CveEstatusOP As Integer = -1, Optional TipoEstatus As Integer = -1, Optional Estatus As Integer = -1, Optional CveUsuario As Integer = -1) As Boolean Dim Retorno As Boolean = False DataAdapter("PA_OP_EstatusOPGet") With SqlAdapter.SelectCommand.Parameters - .Add("@CveEmpresa", SqlDbType.Int).Value = CveEmpresa - .Add("@CveEstatusOP", SqlDbType.Int).Value = CveEstatusOP - .Add("@TipoEstatus", SqlDbType.Int).Value = TipoEstatus - .Add("@Estatus", SqlDbType.Int).Value = Estatus + .Add("@cveEmpresa", SqlDbType.Int).Value = CveEmpresa + .Add("@cveEstatusOP", SqlDbType.Int).Value = CveEstatusOP + .Add("@tipoEstatus", SqlDbType.Int).Value = TipoEstatus + .Add("@estatus", SqlDbType.Int).Value = Estatus + .Add("@cveUsuario", SqlDbType.Int).Value = CveUsuario End With Try SqlAdapter.Fill(Data) diff --git a/OP/OP.aspx b/OP/OP.aspx index 7ca37ef2a..4547e62b8 100644 --- a/OP/OP.aspx +++ b/OP/OP.aspx @@ -279,6 +279,36 @@ padding: 5px; margin-top: 10px; } + + .quantity-control { + position: relative; + display: flex; + align-items: center; + width: 120px; + } + + .quantity-input { + width: 70px !important; + padding-right: 30px; + } + + .quantity-buttons { + position: absolute; + right: 0; + display: flex; + flex-direction: column; + gap: 2px; + } + + .btn-quantity { + padding: 0; + width: 22px; + height: 18px; + line-height: 1; + border: 1px solid #ddd; + background: #f8f9fa; + cursor: pointer; + } @@ -466,7 +496,8 @@
Productos
+ CssClass="table table-striped table-hover" GridLines="None" Width="100%" + OnRowDataBound="GvProductos_RowDataBound"> @@ -754,67 +785,115 @@
+ + diff --git a/OP/OP.aspx.vb b/OP/OP.aspx.vb index 3053d6962..6db555ecf 100644 --- a/OP/OP.aspx.vb +++ b/OP/OP.aspx.vb @@ -41,7 +41,15 @@ Partial Class OP_OP Private Property DtMO As DataTable Get - Return DirectCast(ViewState("DtMO"), DataTable) + If ViewState("DtMO") Is Nothing Then + DtMO = New DataTable() + DtMO.Columns.Add("CvePS", GetType(Integer)) ' Producto asociado + DtMO.Columns.Add("CvePuesto", GetType(Integer)) + DtMO.Columns.Add("Puesto", GetType(String)) + DtMO.Columns.Add("CostoHora", GetType(Decimal)) + DtMO.Columns.Add("Total", GetType(Decimal)) + End If + Return CType(ViewState("DtMO"), DataTable) End Get Set(value As DataTable) ViewState("DtMO") = value @@ -50,13 +58,31 @@ Partial Class OP_OP Private Property DtCI As DataTable Get - Return DirectCast(ViewState("DtCI"), DataTable) + If ViewState("DtCI") Is Nothing Then + DtCI = New DataTable() + DtCI.Columns.Add("CvePS", GetType(Integer)) ' Producto asociado + DtCI.Columns.Add("CvePSMateriaPrima", GetType(Integer)) + DtCI.Columns.Add("productoMateriaPrima", GetType(String)) + DtCI.Columns.Add("Cantidad", GetType(Decimal)) + DtCI.Columns.Add("PU", GetType(Decimal)) + DtCI.Columns.Add("Total", GetType(Decimal)) + End If + Return CType(ViewState("DtCI"), DataTable) End Get Set(value As DataTable) ViewState("DtCI") = value End Set End Property + Private Property TipoEstatus As Integer + Get + Return ViewState("TipoEstatus").ToString.ToEntero + End Get + Set(value As Integer) + ViewState("TipoEstatus") = value + End Set + End Property + Private Property DtMPAgregados As DataTable Get If ViewState("DtMPAgregados") Is Nothing Then @@ -74,12 +100,27 @@ Partial Class OP_OP End Set End Property + Private Property DtDevoluciones As DataTable + Get + If ViewState("DtDevoluciones") Is Nothing Then + DtDevoluciones = New DataTable() + DtDevoluciones.Columns.Add("CvePS", GetType(Integer)) + DtDevoluciones.Columns.Add("Devolucion", GetType(Decimal)) + DtDevoluciones.Columns.Add("CveAlmacenDevolucion", GetType(Integer)) + End If + Return CType(ViewState("DtDevoluciones"), DataTable) + End Get + Set(value As DataTable) + ViewState("DtDevoluciones") = value + End Set + End Property #End Region Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load If Not IsPostBack Then CveOP = If(Request("CveOP") <> "", Request("CveOP").ToString.ToEntero, "-1".ToEntero) + TipoEstatus = -1 CreaPS() SetValues() End If @@ -106,6 +147,7 @@ Partial Class OP_OP DtMP.Columns.Add("UnidadMedida", GetType(String)) DtMP.Columns.Add("Cantidad", GetType(Decimal)) DtMP.Columns.Add("Surtido", GetType(Decimal)) + 'DtMP.Columns.Add("CvePSProducto", GetType(Integer)) 'DtMP.Columns.Add("CveAlmacenDestino", GetType(Integer)) DtMO = New DataTable() @@ -115,15 +157,17 @@ Partial Class OP_OP DtMO.Columns.Add("CvePuesto", GetType(Integer)) DtMO.Columns.Add("Puesto", GetType(String)) DtMO.Columns.Add("Cantidad", GetType(Decimal)) + DtMO.Columns.Add("CostoHora", GetType(Decimal)) + DtMO.Columns.Add("Total", GetType(Decimal)) + DtCI = New DataTable() DtCI.Columns.Add("Tipo", GetType(String)) ' Producto, MP, MO, CI DtCI.Columns.Add("Clave", GetType(Integer)) - 'DtCI.Columns.Add("CveUM", GetType(Integer)) - 'DtCI.Columns.Add("CvePSMateriaPrima", GetType(Integer)) - 'DtCI.Columns.Add("CveUMMateriaPrima", GetType(Integer)) DtCI.Columns.Add("productoMateriaPrima", GetType(String)) DtCI.Columns.Add("Cantidad", GetType(Decimal)) + DtCI.Columns.Add("PU", GetType(Decimal)) + DtCI.Columns.Add("Total", GetType(Decimal)) End Sub @@ -133,24 +177,65 @@ Partial Class OP_OP CargarClientes() CargarCentrosDeCosto(DdlProyecto, DdlSubProyecto, LblProyecto, LblSubProyecto, divProyecto:=DivProyecto, VisualizacionReporte:=1) CargarProductos() + CargaDatos() - If CveOP = -1 Then - - DdlClientes.Enabled = True - DdlProyecto.Enabled = True - DdlSubProyecto.Enabled = True - DdlPS.Enabled = True - LnkSolicitarMP.Visible = False - BtnSimularMP.Visible = True - BtnFinalizarOP.Visible = False + If TipoEstatus = 3 Then + DeshabilitarControles() ' Deshabilita todos los controles relevantes Else - DdlClientes.Enabled = False - DdlPS.Enabled = False - LnkSolicitarMP.Visible = False - BtnSimularMP.Visible = False - BtnFinalizarOP.Visible = True - CargaDatos() + If CveOP = -1 Then ' Nueva OP + DdlClientes.Enabled = True + DdlProyecto.Enabled = True + DdlSubProyecto.Enabled = True + DdlPS.Enabled = True + TxtEstatus.Enabled = True ' Estatus no editable + LnkSolicitarMP.Visible = False + BtnSimularMP.Visible = True + BtnFinalizarOP.Visible = False + Else ' OP existente no finalizada + If TipoEstatus <> 3 Then + DdlClientes.Enabled = True + DdlProyecto.Enabled = True + DdlSubProyecto.Enabled = True + DdlPS.Enabled = True + TxtDescripcion.Enabled = True + Txtfecha.Enabled = True + TxtEstatus.Enabled = True ' Estatus no editable + BtnAgregarProducto.Enabled = True + BtnSimularMP.Visible = False + BtnGuardarOP.Enabled = True + BtnFinalizarOP.Visible = True + imgCalendarioF.Enabled = True + LnkSolicitarMP.Visible = True + End If + End If End If + + UpOP.Update() + UpGvDatosOP.Update() + End Sub + + Private Sub DeshabilitarControles() + ' Deshabilitar DropDownLists + DdlClientes.Enabled = False + DdlProyecto.Enabled = False + DdlSubProyecto.Enabled = False + DdlPS.Enabled = False + + ' Deshabilitar TextBox y Date + TxtDescripcion.Enabled = False + Txtfecha.Enabled = False + imgCalendarioF.Enabled = False + TxtEstatus.Enabled = False + + ' Ocultar Botones + BtnAgregarProducto.Visible = False + BtnSimularMP.Visible = False + BtnGuardarOP.Visible = False + BtnFinalizarOP.Visible = False + LnkSolicitarMP.Visible = False + + UpOP.Update() + UpGvDatosOP.Update() End Sub Private Sub CargaDatos() @@ -169,6 +254,7 @@ Partial Class OP_OP DdlPS.txtValue.Value = dr("CvePS").ToString Txtfecha.Text = dr("Fecha").ToString TxtDescripcion.Text = dr("Descripcion").ToString + TipoEstatus = dr("TipoEstatus").ToString.ToEntero If ObjOP.GetProductosOP(CveOP, UsuarioActual.CveEmpresa) Then @@ -221,7 +307,7 @@ Partial Class OP_OP Dim newRow As DataRow = DtCI.NewRow() newRow("Tipo") = "CI" newRow("productoMateriaPrima") = rowCI("producto").ToString - newRow("Cantidad") = rowCI("Cantidad").ToString.ToDecimal + newRow("Costo") = rowCI("Costo").ToString.ToDecimal DtCI.Rows.Add(newRow) Next @@ -292,6 +378,7 @@ Partial Class OP_OP rowMP("PSCodigo") = drMP("productoMateriaPrima").ToString() rowMP("UnidadMedida") = drMP("UnidadMedidaMateriaPrima").ToString() rowMP("Cantidad") = drMP("Cantidad").ToString().ToDecimal() + 'rowMP("CvePSProducto") = CvePS rowMP("Surtido") = 0 DtMP.Rows.Add(rowMP) Next @@ -306,6 +393,8 @@ Partial Class OP_OP rowMO("Clave") = CvePS rowMO("Puesto") = drMO("Puesto").ToString() rowMO("Cantidad") = drMO("Cantidad").ToString().ToDecimal() + rowMO("CostoHora") = drMO("precioHora").ToString.ToDecimal() + rowMO("Total") = drMO("Cantidad").ToString().ToDecimal() * drMO("precioHora").ToString().ToDecimal() DtMO.Rows.Add(rowMO) Next End If @@ -321,6 +410,8 @@ Partial Class OP_OP 'rowCI("CvePSMateriaPrima") = drCI("CvePSMateriaPrima").ToString().ToEntero() rowCI("productoMateriaPrima") = drCI("productoMateriaPrima").ToString() rowCI("Cantidad") = drCI("Cantidad").ToString().ToDecimal() + rowCI("PU") = drCI("ImporteCostoIndirecto").ToString().ToDecimal() + rowCI("Total") = rowCI("Cantidad").ToString().ToDecimal() * rowCI("PU").ToString().ToDecimal() DtCI.Rows.Add(rowCI) Next End If @@ -329,6 +420,12 @@ Partial Class OP_OP End Sub Protected Sub BtnEliminarProducto_Click(sender As Object, e As EventArgs) + + ' Verificar si la OP está finalizada + If TxtEstatus.Text = "Finalizada" Then + Alert("No se pueden eliminar productos de una OP finalizada.", TipoMensaje.MsgAdvertencia) + Exit Sub + End If Dim btnEliminar As LinkButton = DirectCast(sender, LinkButton) Dim CveProducto As Integer = btnEliminar.CommandArgument.ToEntero() @@ -361,6 +458,13 @@ Partial Class OP_OP Next End Sub + Protected Sub GvProductos_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GvProductos.RowDataBound + If e.Row.RowType = DataControlRowType.DataRow Then + Dim btnEliminar As LinkButton = DirectCast(e.Row.FindControl("BtnEliminar"), LinkButton) + btnEliminar.Visible = (TipoEstatus <> 3) + End If + End Sub + Protected Sub LnkSolicitarMP_Click(sender As Object, e As EventArgs) ' Cargar almacenes DdlAlmacenOrigenMP.DataSource = GlobalDTAlmacen(UsuarioActual.CveEmpresa).FiltraParametros("CveTipoAlmacen = 1") @@ -560,16 +664,16 @@ Partial Class OP_OP Dim MensajeExistencia As New StringBuilder MensajeExistencia.Append("No hay la existencia suficiente de los siguientes productos:
") - '✅ 1. Validar existencias de MP + For Each row As GridViewRow In GvMPAgregados.Rows - '✅ Obtener claves CORRECTAS de la materia prima + Dim CveMP As Integer = GvMPAgregados.DataKeys(row.RowIndex)("CvePSMateriaPrima").ToString().ToEntero() Dim CveUMMP As Integer = GvMPAgregados.DataKeys(row.RowIndex)("CveUMMateriaPrima").ToString().ToEntero() Dim CantidadSolicitada As Decimal = DtMP.Rows(row.RowIndex)("Cantidad").ToString().ToDecimal() - 'DtMP.Rows(row.RowIndex)("CveAlmacenDestino") = DdlAlmacenDestinoMP.SelectedValue.ToEntero() - '✅ Verificar existencias + + Dim Existencia As Decimal = ObjInventario.GetExistenciasPS( CvePS:=CveMP, CveUnidadMedida:=CveUMMP, @@ -596,7 +700,7 @@ Partial Class OP_OP Exit Sub End If - '✅ 2. Crear traspaso si todo está correcto + ObjInventario.IniciaTransacSQL() Dim TieneError As Boolean = False @@ -618,10 +722,10 @@ Partial Class OP_OP TieneError = True End If - '✅ 3. Agregar detalles del traspaso + If Not TieneError Then For Each row As GridViewRow In GvMPAgregados.Rows - '✅ Usar claves de MATERIA PRIMA (CvePSMateriaPrima y CveUMMateriaPrima) + Dim CveMP As Integer = GvMPAgregados.DataKeys(row.RowIndex)("CvePSMateriaPrima").ToString().ToEntero() Dim CveUMMP As Integer = GvMPAgregados.DataKeys(row.RowIndex)("CveUMMateriaPrima").ToString().ToEntero() Dim Cantidad As Decimal = DtMP.Rows(row.RowIndex)("Cantidad").ToString().ToDecimal() @@ -629,8 +733,8 @@ Partial Class OP_OP If Not ObjInventario.AddTrasladoSolicitudDetalle( CveTraspasoSolicitud, Cantidad, - CveUMMP, '✅ Unidad de medida de la MP - CveMP, '✅ Clave de la MP + CveUMMP, + CveMP, 0, "", -1, "-1", "-1", MinFecha ) Then TieneError = True @@ -639,7 +743,7 @@ Partial Class OP_OP Next End If - '✅ 4. Confirmar o cancelar transacción + If Not TieneError Then ObjInventario.Commit() Alert($"Solicitud de Traspaso guardada. Folio: {FolioSolicitud}", TipoMensaje.MsgInformacion) @@ -786,18 +890,35 @@ Partial Class OP_OP End Sub Protected Sub DdlAlmacenOrigenMP_SelectedIndexChanged(sender As Object, e As EventArgs) - ' ✅ Mantener siempre el almacén de producción (tipo 28) en destino + DdlAlmacenDestinoMP.DataSource = GlobalDTAlmacen(UsuarioActual.CveEmpresa).FiltraParametros("CveTipoAlmacen = 28") DdlAlmacenDestinoMP.DataBind() - ' ✅ Opcional: Seleccionar el primer almacén de producción por defecto + If DdlAlmacenDestinoMP.Items.Count > 0 Then DdlAlmacenDestinoMP.SelectedIndex = 0 End If End Sub -#Region "Eventos de Botones" + Protected Sub GvProductoTerminado_RowDataBound(sender As Object, e As GridViewRowEventArgs) + If e.Row.RowType = DataControlRowType.DataRow Then + Dim originalQty As Decimal = Convert.ToDecimal(DataBinder.Eval(e.Row.DataItem, "Cantidad")) + Dim txtCantidad As TextBox = DirectCast(e.Row.FindControl("TxtCantidadPT"), TextBox) + txtCantidad.Attributes("data-original") = originalQty.ToString("0") + End If + End Sub + Protected Sub GvMPUtilizada_RowDataBound(sender As Object, e As GridViewRowEventArgs) + If e.Row.RowType = DataControlRowType.DataRow Then + Dim originalQty As Decimal = Convert.ToDecimal(DataBinder.Eval(e.Row.DataItem, "Cantidad")) + Dim txtDevolucion As TextBox = DirectCast(e.Row.FindControl("TxtDevolucionMP"), TextBox) + txtDevolucion.Attributes("data-original") = originalQty.ToString("0") + End If + End Sub + + + +#Region "Finalizar" Protected Sub BtnFinalizarOP_Click(sender As Object, e As EventArgs) If CveOP = -1 Then Exit Sub @@ -811,6 +932,11 @@ Partial Class OP_OP DdlAlmacenTerminado.DataBind() DdlAlmacenTerminado.Items.Insert(0, New ListItem("Seleccionar almacén", "-1")) + ' Almacén de Devoluciones (Tipo 1) + DdlAlmacenDevolucion.DataSource = GlobalDTAlmacen(UsuarioActual.CveEmpresa).FiltraParametros("CveTipoAlmacen = 1") + DdlAlmacenDevolucion.DataBind() + DdlAlmacenDevolucion.Items.Insert(0, New ListItem("Seleccionar almacén", "-1")) + ' 3. Cargar GridViews GvProductoTerminado.DataSource = DtPS.FiltraParametros("Tipo = 'Producto'") GvProductoTerminado.DataBind() @@ -823,15 +949,42 @@ Partial Class OP_OP End Sub Protected Sub BtnGuardarFinalizarOP_Click(sender As Object, e As EventArgs) + Dim EstatusFinalizar As String = GlobalDTOPEstatus(UsuarioActual.CveEmpresa).FiltroPrimeroValor("EstatusOP", "TipoEstatus=3") + Dim CveEstatusFinalizar As Integer = GlobalDTOPEstatus(UsuarioActual.CveEmpresa).FiltroPrimeroValor("CveEstatusOP", "TipoEstatus=3").ToEntero() + If Not CveEstatusFinalizar > 0 Then + Alert("No se encontró el estatus de finalización de la OP.", TipoMensaje.MsgError) + Exit Sub + End If + If DdlAlmacenOrigenSalidaMP.SelectedValue = "-1" OrElse DdlAlmacenTerminado.SelectedValue = "-1" Then Alert("Selecciona ambos almacenes.", TipoMensaje.MsgAdvertencia) Exit Sub End If - ' Dim TotalCantidad As Decimal = DtMovimientos.SUMD("Cantidad") - 'Inicia la transacción + For Each row As GridViewRow In GvProductoTerminado.Rows + Dim txtCantidad As TextBox = DirectCast(row.FindControl("TxtCantidadPT"), TextBox) + Dim cantidadIngresada As Decimal = txtCantidad.Text.ToDecimal() + Dim cantidadOriginal As Decimal = txtCantidad.Attributes("data-original").ToDecimal() - Dim CveMovimientoSalida As Integer = 0 + If cantidadIngresada > cantidadOriginal Then + Alert("La cantidad del producto terminado no puede superar lo solicitado.", TipoMensaje.MsgAdvertencia) + Exit Sub + End If + Next + + + For Each row As GridViewRow In GvMPUtilizada.Rows + Dim txtDevolucion As TextBox = DirectCast(row.FindControl("TxtDevolucionMP"), TextBox) + Dim devolucionIngresada As Decimal = txtDevolucion.Text.ToDecimal() + Dim cantidadOriginal As Decimal = txtDevolucion.Attributes("data-original").ToDecimal() + + If devolucionIngresada > cantidadOriginal Then + Alert("La devolución no puede superar la cantidad de materia prima solicitada.", TipoMensaje.MsgAdvertencia) + Exit Sub + End If + Next + + Dim CveMovimientoSalida As Integer = 1 Dim CveMovimientoEntrada As Integer = 0 Dim IDPoliza As Integer = 0 Dim FolioSalida As Integer = 0 @@ -844,8 +997,13 @@ Partial Class OP_OP Dim ErrorMovInv As Boolean = False Dim TextoError As String = "" Dim TipoMovimientoSalida As Integer = 8 + Dim TipoMovimientoDev As Integer = 33 Dim CveConceptoEntrada As Integer = 9 Dim TotalCostoMP As Decimal = 0 + 'Dim TotalDevoluciones As Decimal = 0 + Dim CveMovimientoDev As Integer = 0 + Dim CostoDevoluciones As Decimal = 0 + Dim ObjInventario As New ClsInventarios() @@ -855,16 +1013,102 @@ Partial Class OP_OP Try CveMovimientoSalida = ObjInventario.AddMovimiento(DdlAlmacenOrigenSalidaMP.SelectedValue.ToEntero(), TipoMovimientoSalida, 1, Fecha, -1, UsuarioActual.CveUsuario, UsuarioActual.CveEmpresa, -1, -1, -1, -1, Observaciones:="Finalización OP #" & LblFolio.Text, Modulo:="OP/FinalizarOPSalida") - + FolioEntrada = ObjInventario.Folio + Dim DtMPAlmacen As DataTable = Nothing If CveMovimientoSalida > 0 Then - For Each rowMP As DataRow In DtMP.Select("Tipo = 'MP'") - If Not ObjInventario.AddMovimientoDetalle(CveMovimientoSalida, rowMP("Cantidad").ToString.ToDecimal(), rowMP("CveUMMateriaPrima").ToString.ToEntero(), rowMP("CvePSMateriaPrima").ToString.ToEntero(), 1) Then - ErrorMovInv = True : TextoError = "x" : Exit For + For Each rowMP As DataRow In DtMP.Select("Tipo = 'MP'") + Dim CvePS As Integer = rowMP("CvePSMateriaPrima").ToString.ToEntero + Dim CveUM As Integer = rowMP("CveUMMateriaPrima").ToString.ToEntero + Dim Cantidad As Decimal = rowMP("Cantidad").ToString.ToDecimal + + ' Registrar detalle + If Not ObjInventario.AddMovimientoDetalle(CveMovimientoSalida, Cantidad, CveUM, CvePS, 0) Then + ErrorMovInv = True + Exit For End If Next - If ObjInventario.GetMovimientosDetalle(CveMovimientoSalida, UsuarioActual.CveEmpresa) Then - TotalCostoMP = ObjInventario.DtResultados.SUMD("Total") + + If Not ObjInventario.GetMovimientosDetalle(CveMovimientoSalida, UsuarioActual.CveEmpresa) Then + Throw New Exception("Error al cargar detalles del inventario") + End If + DtMPAlmacen = ObjInventario.DtResultados.Copy() + + ' 5. Calcular TotalCostoMP (ya está actualizado) + TotalCostoMP = ObjInventario.DtResultados.SUMD("Total") + + Dim CostosPorProducto As New Dictionary(Of Integer, Decimal) + + ' 1. Recorrer cada Producto Terminado en la OP + For Each rowProducto As DataRow In DtPS.Select("Tipo = 'Producto'") + Dim CvePSProducto As Integer = rowProducto("Clave").ToString.ToEntero() + Dim CantidadProducto As Decimal = rowProducto("Cantidad").ToString.ToDecimal() + Dim TotalMPProducto As Decimal = 0 + Dim TotalMOProducto As Decimal = 0 + Dim TotalCIProducto As Decimal = 0 + + ' 2. Calcular Costo de Materias Primas por Producto + For Each rowMP As DataRow In DtMP.Select($"Clave = {CvePSProducto}") + Dim CvePSMP As Integer = rowMP("CvePSMateriaPrima").ToString.ToEntero() + Dim CveUMMP As Integer = rowMP("CveUMMateriaPrima").ToString.ToEntero() + Dim PU As Decimal = DtMPAlmacen.FiltroPrimeroValor("PU", $"CvePS = {CvePSMP} AND CveUM = {CveUMMP}").ToDecimal() + TotalMPProducto += rowMP("Cantidad").ToString().ToDecimal() * PU + Next + + ' 3. Calcular Mano de Obra por Producto + For Each rowMO As DataRow In DtMO.Select($"Clave = {CvePSProducto}") + TotalMOProducto += rowMO("Total").ToString.ToDecimal() + Next + + ' 4. Calcular Costos Indirectos por Producto + For Each rowCI As DataRow In DtCI.Select($"Clave = {CvePSProducto}") + TotalCIProducto += rowCI("Total").ToString.ToDecimal() + Next + + ' 5. Sumar Total por Producto (MP + MO + CI) + Dim TotalProducto As Decimal = TotalMPProducto + TotalMOProducto + TotalCIProducto + CostosPorProducto.Add(CvePSProducto, TotalProducto) + Next + + ' 2. PROCESAR DEVOLUCIONES SI EXISTEN + If Not ErrorMovInv Then + Dim TotalDevoluciones As Decimal = GvMPUtilizada.Rows.Cast(Of GridViewRow)().Sum(Function(row) DirectCast(row.FindControl("TxtDevolucionMP"), TextBox).Text.ToDecimal()) + + If TotalDevoluciones > 0 Then + If DdlAlmacenDevolucion.SelectedValue = "-1" Then + Alert("Seleccione almacén para devoluciones", TipoMensaje.MsgAdvertencia) + Exit Sub + End If + + CveMovimientoDev = ObjInventario.AddMovimiento(DdlAlmacenDevolucion.SelectedValue.ToEntero(), TipoMovimientoDev, 1, Fecha, -1, UsuarioActual.CveUsuario, UsuarioActual.CveEmpresa, -1, -1, -1, -1, Observaciones:=$"Devolución OP #{LblFolio.Text}", Modulo:="OP/Devoluciones", CveMovimientoRelacionado:=CveMovimientoSalida) + + + If CveMovimientoDev > 0 Then + For Each row As GridViewRow In GvMPUtilizada.Rows + Dim Devolucion As Decimal = row.FCTextBox("TxtDevolucionMP").Text.ToDecimal() + If Devolucion > 0 Then + Dim CvePS As Integer = row.DataKey("CvePSMateriaPrima").ToEntero 'GvMPUtilizada.DataKeys(row.RowIndex)("CvePSMateriaPrima").ToString.ToEntero() + Dim CveUM As Integer = row.DataKey("CveUMMateriaPrima").ToEntero 'GvMPUtilizada.DataKeys(row.RowIndex)("CveUMMateriaPrima").ToString.ToEntero() + + + Dim PU As Decimal = DtMPAlmacen.FiltroPrimeroValor("PU", $"CvePS = {CvePS} AND CveUM = {CveUM}").ToDecimal() + + If Not ObjInventario.AddMovimientoDetalle( + CveMovimientoDev, + Devolucion, + CveUM, + CvePS, + PU + ) Then + ErrorMovInv = True + End If + + CostoDevoluciones += Devolucion * PU + End If + Next + End If + End If + End If If Not ErrorMovInv Then @@ -872,8 +1116,9 @@ Partial Class OP_OP End If If CveMovimientoEntrada > 0 AndAlso Not ErrorMovInv Then - Dim CantidadPT As Decimal = DtPS.AsEnumerable().Sum(Function(row) Convert.ToDecimal(row("Cantidad"))) - Dim PU_PT As Decimal = If(CantidadPT > 0, TotalCostoMP / CantidadPT, 1) + Dim CostoPTAjustado As Decimal = TotalCostoMP - CostoDevoluciones + Dim CantidadPT As Decimal = DtPS.AsEnumerable().Sum(Function(r) r.Field(Of Decimal)("Cantidad")) + Dim PU_PT As Decimal = If(CantidadPT > 0, CostoPTAjustado / CantidadPT, 0) For Each rowPT As DataRow In DtPS.Select("Tipo = 'Producto'") If Not ObjInventario.AddMovimientoDetalle(CveMovimientoEntrada, rowPT("Cantidad").ToString.ToDecimal(), rowPT("CveUM").ToString.ToEntero(), rowPT("Clave").ToString.ToEntero(), PU_PT) Then @@ -889,24 +1134,24 @@ Partial Class OP_OP ErrorMovInv = True End If - If Not ErrorMovInv AndAlso Not ObjConta.AddPrePolizasDetalle(CvePrePoliza, False, TotalCostoMP, TotalCostoMP, 68, "Producción PT OP #" & LblFolio.Text, "Producción PT OP #" & LblFolio.Text, CveMovimientoAlmacen:=CveMovimientoEntrada) Then + If Not ErrorMovInv AndAlso Not ObjConta.AddPrePolizasDetalle(CvePrePoliza, False, CostoPTAjustado, CostoPTAjustado, 68, "Producción PT OP #" & LblFolio.Text, "Producción PT OP #" & LblFolio.Text, CveMovimientoAlmacen:=CveMovimientoEntrada) Then ErrorMovInv = True End If - If Not ErrorMovInv Then - If Not ObjOP.UpdateEstatusOP(CveOP, 3, UsuarioActual.CveEmpresa) Then - ErrorMovInv = True : TextoError = "Error al actualizar estatus de la OP" - End If - End If + + + ObjConta.AddPrePolizasDetalle(CvePrePoliza, False, CostoDevoluciones, CostoDevoluciones, 95, "", $"OP #{LblFolio.Text}", CveMovimientoAlmacen:=CveMovimientoDev) + + 'If Not ErrorMovInv Then - ' If Not ObjConta.ValidacionesPrePoliza(CvePrePoliza, UsuarioActual) Then - ' ErrorMovInv = True : TextoError = "Error en validación de póliza" - ' ElseIf ObjConta.ValorPolizaDescuadre > 0 Then - ' ErrorMovInv = True : TextoError = "Descuadre en póliza contable" - ' End If + 'If Not ObjConta.ValidacionesPrePoliza(CvePrePoliza, UsuarioActual) Then + 'ErrorMovInv = True : TextoError = "Error en validación de póliza" + 'ElseIf ObjConta.ValorPolizaDescuadre > 0 Then + ' ErrorMovInv = True : TextoError = "Descuadre en póliza contable" + 'End If 'End If End If End If @@ -914,16 +1159,32 @@ Partial Class OP_OP If Not ErrorMovInv Then - ObjInventario.Commit() - Alert($"Orden de producción finalizada. -
{ObjInventario.Folio} ", TipoMensaje.MsgInformacion) + If ObjOP.UpdateEstatusOP(CveOP, CveEstatusFinalizar, UsuarioActual.CveEmpresa) Then + ObjInventario.Commit() + TxtEstatus.Text = EstatusFinalizar + DeshabilitarControles() + UpOP.Update() + UpGvDatosOP.Update() + Alert("Orden de producción finalizada.
" & "" & FolioEntrada & "", + TipoMensaje.MsgInformacion) + + + + RegistraScript("$('#DVModalFinalizarOP').modal('hide');") + + + Else + ObjInventario.RollBack() + Alert("Error al actualizar el estatus.", TipoMensaje.MsgError) + End If + Else ObjInventario.RollBack() Alert($"Error contable: {TextoError}", TipoMensaje.MsgError) End If - RegistraScript("$('#DVModalFinalizarOP').modal('hide');") - CargaDatos() + + Catch ex As Exception ObjInventario.RollBack() @@ -933,7 +1194,6 @@ Partial Class OP_OP ObjConta.Dispose() End Try - End Sub #End Region End Class