ASP.NET - Insertar cabecera y lineas de pedido a la vez

   
Vista:
Imágen de perfil de nano

Insertar cabecera y lineas de pedido a la vez

Publicado por nano (14 intervenciones) el 19/02/2016 12:59:57
Muy buenas a todos, amigos!!
Tengo creado un formulario web para insertar pedidos en un SQL SERVER. Mi procedimiento me está dando problemas a la hora de que otro usuario meta también pedidos. Os comento:
Con un botón genero el proximo numero de pedido libre, y relleno o selecciono los datos de la cabecera del pedido que con un boton validar me los lleva a unos textbox. Esos datos deben de ir en una tabla llamada pedidos junto con el total de importe que generan las lineas de pedido.
En otra tabla diferente llamada lineas_pedidos selecciono los articulos y sus precios cuyos datos saco del propio SQL y agrego lineas individuales que ya inserto en esta tabla con el numero de pedido antes generado.
El problema reside en el caso de que mientras genero los datos de la cabecera el número de pedido que yo tengo en mi formulario lo han cogido y ya no es el siguiente registro vacío con lo que al insertar una linea de pedido me aparece un error de primary_key pues estoy intentando insertar un numero que ya esta creado.
En resumidas cuentas, lo idóneo sería generar las líneas de pedido e insertarlas todas de golpe junto con la cabecera de pedido haciendo antes una comprobación de cual es el último pedido. Alguien me puede orientar como puedo guardar las linea de pedido y luego insertarlas todas en la tabla como diferentes registros de un mismo pedido.
Un saludo y gracias de antemano!!
Nano.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

Insertar cabecera y lineas de pedido a la vez

Publicado por Khristian (80 intervenciones) el 19/02/2016 19:22:55
Este tema es archi... Repetido.
Usa el buscador..

Yo tengo un procedimiento almacenado que genera números de folio, lo uso en el momento exacto... Esto es... Al insertar el registro... NO antes.
El procedimiento almacenado incluye un bloqueo de tabla para evitar 2 usuarios a la vez.
Al segundo usuario lo haces esperar una milesima de segundo en un Try y listo
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Javier

Insertar cabecera y lineas de pedido a la vez

Publicado por Javier (7 intervenciones) el 20/02/2016 05:50:29
Como ya te comentaron cuando hagas la insercion puedes generar el ID, no entiendo para que hacerlo antes, ahora que si lo haces antes pues tienes algunas opciones, puedes generar el registro y al guardar hacer un UPDATE y con eso no tienes el problema que mencionas, ese es un de varias posibles respuestas, la otra, como lo comentamos, que tomes o generes el ID al momento de guardar los datos, lo mejor es que hagas un "bloqueo" para que no tengas problemas, creo que esta es la mejor opcion.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de nano

Insertar cabecera y lineas de pedido a la vez

Publicado por nano (14 intervenciones) el 20/02/2016 20:33:02
Gracias por vuestras respuestas amigos!! Pero aun no he dado con la solución!!
Para mas datos deciros que la otra forma de inserción de pedidos se hace desde una aplicación windows desarrollada hace años que lógicamente se conecta al SLQ SERVER y yo lo que he generado es un formulario web en asp.net C# para agilizar este proceso y porque se genera una orden de pedido en pdf que la aplicación anterior no hace.
No puedo modificar ni alterar las tablas de la base de datos original de SQL SERVER pues son tablas genericas que pueden usar otros usuarios.
Lo primero que hago con un boton es generar el ultimo pedido emitido y sumarle 1 en un label:

lblulpedido.Text = Convert.ToString(DDulpedido.SelectedValue);
txtCodPedido.Text = lblulpedido.Text;


Luego genero con varios DD los datos de la cabecera del cliente que debo insertar en la tabla pedidos_venta donde hay un campo llamado importe_final que no puedo informar hasta que genere las lineas de pedido. Estos datos los guardo en una serie de textbox ocultos.

txtNomAlmacen.Text = Convert.ToString(DDAlmacen.SelectedItem);
txtCodAlmacen.Text = Convert.ToString(DDAlmacen.SelectedValue);
txtCodFormaPago.Text = Convert.ToString(DDFormaPago.SelectedValue);
txtCodMedioPago.Text = Convert.ToString(DDMedioPago.SelectedValue);
txtCodProveedor.Text = Convert.ToString(DDProveedor.SelectedValue);
textNomProveedor.Text = Convert.ToString(DDProveedor.SelectedItem);
txtCodTTe.Text = Convert.ToString(DDTTe.SelectedValue);
txtNomTransportista.Text = Convert.ToString(DDTTe.SelectedItem);
txtcodUser.Text = Convert.ToString(DDUser.SelectedValue);
lblUser.Text = Convert.ToString(DDUser.SelectedItem);


Con estos datos de la cabecera se genera un Gridview con las tarifas de cada producto, inserto las lineas del pedido en la tabla final llamada pedidos_ventas_detalle... y aqui es donde empiezan mis problemas pues si el ID pedido que yo tenía generado lo ha usado otro usuario, al insertar la linea de pedido con ese número me salta el error de primary_Key, lógicamente.
Si el Id pedido está aún libre genero las lineas que inserto en la tabla final y luego con un boton de confirmar_pedido inserto la cabecera con el campo calculado de la suma de importes de las líneas.

Las soluciones que veo, pero que no doy con ellas serían:
- Guardar las líneas de pedido, pero no se donde pues no puedo crera una tabla paralela en SQL SERVER, para luego insertarlas de golpe junto con la cabecera... pero tampoco doy con ello.
- Reservar el id pedido...o como dice Javier un bloqueo pero agradecería me indicaras como hacerlo.

El formulario web funciona perfectamente pero se me ha complicado, cuando ahora hay mas de un usuario que va a generar pedidos y veo que va a resultar mas complejo de lo que pensaba y me veo que voy a tener que modificar gran parte de lo que ya tengo.

Si alguien tiene soluciones, os lo agradecería mucho!!!
Saludos cordiales!!!
Nano.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Javier

Insertar cabecera y lineas de pedido a la vez

Publicado por Javier (7 intervenciones) el 21/02/2016 04:02:28
Creo que desde la logica lo complicaste con la forma en que manejas la informacion, igual sigo pensando para que mostrar el ID de pedido antes de hacer la Insercion a tu BD, no creo esto sea primordial para el cliente o usuario, pero bueno ya lo tienes asi entonces, lo que se me ocurre y creo no seria muy complicado implementar, es que tengas una tabla de "Folios de pedido", donde solo tengas eso, un id que te indique el ultimo folio utilizado, y con esa tabla trabajar, donde, lo primero que tendrias que hacer es tomar el ultimo folio y sumar 1, despues actualizar esta tabla, para que al momento que otro usuario agregue un nuevo pedido tome el ultimo pedido ya actualizado y asi al hacer la insercion a tu Tabla Pedidos_Venta no tengas el problema que mencionas, es lo que se me ocurre asi de primera mano, tomando en cuenta lo que comentas, tal vez otro usuario tenga alguna otra solucion.

Con respecto a lo de bloquear al momento de hacer la insercion, te dejo un ejemplo de codigo, solo que este ejemplo lo use con EntityFramework, pero la logica con una ConnectionString es la misma.

1
2
3
4
5
6
7
using (TuModelodeDatos datos = new TuModelodeDatos())
      {
           using (var trans = datos.Database.BeginTransaction(IsolationLevel.Serializable))
                 {
                       Aqui llevas tu proceso de Insercion y/o Actualizacion a tu BD.
                 }
       }

Esto lo que hace es que, durante la transaccion solo se puedan leer datos de la tabla que utilices pero no se pueda modificar.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de nano

Insertar cabecera y lineas de pedido a la vez

Publicado por nano (14 intervenciones) el 21/02/2016 04:26:05
Muchas gracias, Javier por tu interés!!
Voy a probar a ver que me sale!!!
Tienes toda la razón que lo compliqué desde la pura lógica, pero como era un formulario web que sólo iba a usar una única persona que en su día era la única que metía pedidos, no caí en la cuenta.
Ahora, son varios usuarios los que meterán pedidos y es cuando me he encontrado con el problema...
Llevo toda la tarde probando y he consegido a la hora de confirmar la cabecera guardar ese id_pedido.
Lo siguiente es insertar las líneas de pedido con ese mismo número, pues ya nadie me puede quitar ese numero.
Una vez insertadas las líneas debo actualizar algunos campos de la cabecera y no entiendo porqué no me lo hace:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using (SqlConnection cn2016 = new SqlConnection("Mis_datos_de_conexion"))
        {
            cn2016.Open()
            string ORDEN = "update PEDIDOS_VENTA set IMPORTE_TOTAL = @importe_total, CODIGO_TARIFA = @codigo_tarifa, TIPO_BLOQUEO = @tipo_bloqueo where (CODIGO = @codigo)";
 
            SqlCommand actualizar = new SqlCommand(ORDEN, cn2016);
 
            actualizar.Parameters.AddWithValue("@codigo", int.Parse(txtCodPedido.Text));
            actualizar.Parameters.AddWithValue("@importe_total", decimal.Parse(txtimportefinal.Text));
            actualizar.Parameters.AddWithValue("@codigo_tarifa", int.Parse(txtcodtarop.Text));
            actualizar.Parameters.AddWithValue("@tipo_bloqueo", int.Parse(txtbloqueo.Text));
 
            actualizar.ExecuteNonQuery();
            cn2016.Close();
}

No me aparece ningún error, no se me detiene en ningún proceso, pero los cuatro campos que quiero actualizar no se me cambian!!!
Siguen teniendo los valores iniciales!!!
Algo debo estar poniendo mal, pero tampoco me salta error alguno. Que puedo estar poniendo mal para que no se actualicen?
Si consigo actualizar estos campos, doy por solventado el problema hasta poder dar con otra solución mas lógica e incluso rehacer el planteamiento con mas detenimiento.

Saludos!!!
Nano.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de nano

Insertar cabecera y lineas de pedido a la vez

Publicado por nano (14 intervenciones) el 21/02/2016 14:21:49
Ya lo he conseguido, amigos!!
Después de un par de horas de trasnochar, ya tengo la solución, temporal, para actualizar los datos con el siguiente codigo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SqlConnection Conn = new SqlConnection("datos_conexion");
{
	Conn.Open();
	string sql = "update PEDIDOS_VENTA set IMPORTE_TOTAL = @importe_total, CODIGO_TARIFA  = @codigo_tarifa, TIPO_BLOQUEO = @tipo_bloqueo, AUTORIZADO = @autorizado where CODIGO = @codigo";
	SqlCommand actualizar = new SqlCommand(sql, Conn);
	actualizar.Parameters.AddWithValue("@codigo", int.Parse(txtCodPedido.Text));
	actualizar.Parameters.AddWithValue("@importe_total", decimal.Parse(txtimportefinal.Text));
	actualizar.Parameters.AddWithValue("@codigo_tarifa", int.Parse(txtcodtarop.Text));
	actualizar.Parameters.AddWithValue("@autorizado", int.Parse(txtautorizado.Text));
	actualizar.Parameters.AddWithValue("@tipo_bloqueo", int.Parse(txtbloqueo.Text));
 
	actualizar.ExecuteNonQuery();
	actualizar.Dispose();
	Conn.Close();
	Response.Redirect("listadopedidos.aspx");
}

Con la última línea, redirijo la web a un nueva página con un informe de los pedidos.
Saludos y muchas gracias!!!
Nano.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
Imágen de perfil de xve

Insertar cabecera y lineas de pedido a la vez

Publicado por xve (24 intervenciones) el 21/02/2016 20:01:15
Gracias por compartirlo!!!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de nano

Insertar cabecera y lineas de pedido a la vez

Publicado por nano (14 intervenciones) el 22/02/2016 08:07:35
No hay que darlas, Xve!!
Aquí estamos todos para aportar y compartir conocimientos, los que sabemos menos de programación junto con los que llevan muchos años con ello, pero entendía que era mi obligación, después de "pelearme" con esto durante el fin de semana, que una vez encontré la solución os lo hiciera saber y de este modo ahorrarle a alguien un par de horas de busqueda y quebraderos de cabeza.
A mi, personalmente, me saca del apuro de forma temporal, pues como has podido leeer, yo lo que quiero es guardar lo datos de la tabla de la cabecera junto con los datos de la tabla de las lineas e insertarlas todas a la vez para evitar duplicidad de números de pedido con otros usuarios. Pero como el formulario, en mi caso, lleva ya muchas cosas añadidas y muchos cálculos, necesitaba buscar alguna solución alternativa que no afectara a lo que ya tengo, ni tener qe volver a deshacer media aplicación. La solución mas sencilla es esta: Con los datos iniciales de la cabecera me genero el siguiente número de pedido libre y lo inserto, aunque varios campos necesiten de otra infomación que depende de las lineas del pedido. Ya, en mi caso, ese número de pedido no me lo quita nadie. Y, tranquilamente, genero y voy insertando las líneas de ese pedido en la otra tabla cuyo proceso tiene su tiempo, pues los importes dependen del proveedor, del almacen de donde salga, aplicarle descuentos y sobre todo calcular la suma de las lineas para agregar el importe final a la cabecera que inicialmene inserto con el valor 0. Con lo cual, con el código de arriba, consigo actualizar los campos que me requiere la tabla de la cabecera y soluciono el problema. Con esto solventado, voy a ver si doy con la opción A con mas tranquilidad que no deja de ser la solución más lógica.
Un saludo,
Nano.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar