Вы находитесь на странице: 1из 136

, Fecha, IdConcepto, IdBodega

1. En cliente:
- cuando se actualiza y adiciona nuevo un dato no se ve reflejado en la gv
- cuando es persona natural no escribe nombre y aplellido de contacto en el nombre
comercial
- no sirve quitar filtros ni nada de filtros del formulario buscarcliente
- no actuliza gv al borrar
2. en ptos
- debera al guardar limpiar gv
3. en compras
- limpiar proveedor y bodega cuando se agrega

//traslado de bodega copia codigo de compra y vta


Barra (existeBarra, InsertBarra, DeleteBarra, DeleteBarraByIdProducto)
Bodega(ExisteBodega)
BodegaPto(GetBodegaProductoByIdBodegaAndIdProducto,
GetBodegaProductoByIdBodegaAndIdProducto,
UpdateBodegaProducto,
InsertBodegaProducto, AumentarStock, DeleteBodegaProductoByIdProducto)
Cliente(InsertCliente, UpdateCliente, deleteCliente)
Compra(InsertCliente, proveedorTieneCompras
compraDetalle(insertCompraDetalle)
concepto(existeConcepto)
departamento(existeDepartamento)
iva(getiva)
KARDEX(INSERTKARDEX, KARDEXTIENEMOVPORIDPTO, KARDEXTIENEMOVPORIDBODEGA)

PERMISOROL(PUEDEVER, PUEDEMOD, PUEDEBORRAR)


PTO (GETPTOBYIDPTO, GETPTOBYBARRA)
PROVEEDOR(UPDATEPROV, DELETEPROV)
TIPODOC(EXISTETIPODOC
USUARIO(EXISTEUSUARIO, VALIDAUSUARIO, CAMBIOCLAVE, GETUSUARIO)

Se borraron los siguientes proc almacenados

Delete barra

DeleteCliente
ExisteBarra
ExisteConcepto
ExisteDepartamento
ExisteTipoDocumento
ExisteUnidadMedida
GetBodegaProductoByIdBodegaAndIdProducto
InsertBarra
InsertBodegaProducto
InsertCliente
MantenimientoTablas
UpdateBodegaProducto
UpdateCliente

1. Fase 1 creacin de la base de datos.


2. Fase 2 se realizara una aplicacin stand alone con arquitectura cliente servidor: una
aplicacin local que se instala en cada mquina.
3. Fase 3 Aplicacin web comparte capa con la fase 2.
4.
5. Fase 4 aplicacin mvil a travs de un web service por lo que no se comunica
directamente con la base de datos.

1.
2.
3.
4.

Aplicacin stand alone


Video 1 introduccin
Abrir visual
Colocarle nombre AplicacionComercial (capa de presentacin de una aplicacin Windows)
Cambiarle nombre al formulario frmLogin
Crear proyecto capa de datos para as tener aislado siempre la capa de presentacin y la
de datos se agrega un nuevo proyecto biblioteca de clases - CADAplicacionComercial
(proyecto que no tiene ejecucin, no tiene interfaz de usuario, es un proyecto que tiene
una cantidad de clases que pueden utilizar otros proyectos).
Todo lo que es interaccin con el usuario se almacena en el proyecto AplicacionComercial
y lo que sea manipulacin de datos (crud) se hace en el proyecto
CADAplicacionComercial (se reutiliza en aplicacin web)

5. El formulario login lo 1ro al ejecutar la aplicacin es que aparezca una ventana donde el
usuario se autentifique con usuario y contrasea.
6. Propiedad text: ingreso al sistema. Label: llamado &Usuaro(& subraya la u) y el name
lblUsuario
7. Textbox: en el name txtUsuario
8. Lo mismo con clave adicionarle en propiedad passwordChard *
9. Agregar un PictureBox colocarle imagen de ingreso y propiedad sizemode: strechImage
10. Agregar botn llamarlo aceptar y btnAceptar y colocarle propiedad imagen y tambin el
botn cancelar
11. Otra propiedad para el formulario Accept button que es para darle aceptar con enter:
Button Accept y cancel button para cuando se presione esc con btnCancelar y para no
cambiarle el tamao al formulario formBorderStyle: FixedDialog y quitar botn de
minimizar y maximizar

Video 1.1 Iniciando


1. Para quitar minimizar y maximizar propiedades maximeBox y minimeBox en false y
startpositon: centerScreen
2. Ejecutar proyecto.
3. Comenzar a darle funcionalidad primero el botn cancelar doble clic y escribir el siguiente
cdigo
this.Close(); para as cerrar el formulario actual
4. Al presionar aceptar escribiremos lo siguiente
a. Validar que se halla ingresado usuario y contrasea para eso se agrega al formulario un
error provider
b. Lo que se escribe es lo siguiente
if (txtUsuario.Text == "")
{
errorProvider1.SetError(txtUsuario, "Debe ingresar un usuario");
txtUsuario.Focus();
return;
}
errorProvider1.SetError(txtUsuario, "");
if (txtClave.Text == "")
{
errorProvider1.SetError(txtClave, "Debe ingresar una clave");
txtClave.Focus();
return;
}
errorProvider1.SetError(txtClave, "");
5. Ahora si vamos a la base de datos que la toca el CAD agregamos en el proyecto CAD
nuevo elemento datos conjunto de datos llamamos dsAplicacionComercial (ds es la
abreviatura de dataset) es el encargado de conectar a la bd, se activa el explorador de
servidores
6. Hacer clic en el icono de conectar a bd en nombre de servidor en este caso es DIANAPC\SQLEXPRESS (sin instancia seria solo .) en nombre de la bd buscarla en la lista y
probar conexin
7. Arrastrar tabla usuario y tabla rol
8. Crear una consulta crear procedimiento almacenado como se est preguntando si el
usuario es vlido o no eso es un select que devuelve un solo valor y colocar esto
SELECT 1 FROM Usuaro WHERE IdUsuario = @IdUsuario AND Clave = @Clave
9. El nombre del procedimiento y de la consulta es ValidaUsuario y finalizar
10. Se prueba con clic derecho vista previa de datos.
11. Crear una clase para utilizar la consulta la clase llamada class1 la renombramos
CADUsuario (para hacer crud de usuario) y en esa clase escribir lo siguiente
Private static dsAplicacionComercialTableAdapters.UsuarioTableAdapter
Video 1.2 login
1. Continuamos con lo que se escribe en la clase para que no quede tan largo se deja as y
como saca error clic en el cuadrito azul se le da ctrl. y darle en la 1ra opcin

Private static UsuarioTableAdapter (un adaptador es un objeto muy importante en sql en el


lado .net xq l es el que permite manipular la bd) se crea un objeto llamado adaptador
quedando completa as
private static UsuarioTableAdapter adapter = new UsuarioTableAdapter(); (esta instruccin
crea el objeto y se instancia)
2. Vamos a crear la 1er consulta que utiliza ese table adapter
public static bool ValidarUsuario() la cual devuelve true si el usuario y clave son vlidos
quedando as
if (adaptador.ValidaUsuario(IdUsuario, Clave) == null)
{
return false;
}
return true;
3. Necesitamos utilizar el proyecto CAD en el proyecto de interfaz de usuario que es la
aplicacionComercial
4. Se debe compilar el proyecto para que genere las clases en el proyecto de arriba
5. En Solucin clic derecho compilar solucin y as genera las clases
6. Para poder usar el proyecto cad en el otro aunque hagan parte de la misma sln se debe ir
a refences del proyecto ApCom agregar referencia sln chulito en CAD aceptar (Se
necesita es arriba agregar el de abajo)
7. Se agrega el siguiente cdigo en el frmLogin en botn aceptar
errorProvider1.SetError(txtClave, ""); // despus de esto
if (!CADUsuario.ValidaUsuario(txtUsuario.Text, txtClave.Text))
{
MessageBox.Show("Usuario o clave no valido", "Error", MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
txtUsuario.Text = "";
txtClave.Text = "";
txtUsuario.Focus();
return;
}
8. Si llega hasta ah debe entrar en el formulario principal que vamos a crear
9. Se define propiedades text: Sistema Comercial, windowState: Maximized,
IsMdiContainer:true (significa que las dems ventanas pertenecen a esta) colocar lo
siguiente
return;
}
frmPrincipal miForm = new frmPrincipal();
miForm.Show();
this.Hide();
10. Probar

Video 2 Menus
1. Arrastrar la hmienta menustrip que tendr las siguientes opciones con sus diferentes
opciones cada una
&Archivo
- &Bodegas
- &Clientes
- C&onceptos
- &Productos (&Departamentos, &IVA, &Productos, &Unidades de medida)
- Pr&oveedores
- &Tipo de documento
- &Usuarios
Hasta ac son las tablas maestras que son las que se les puede hacer crud (separador
con -)
-

Ca&mbio de Usuario
Cam&bio de clave
Guion

&Salir
&Movimientos (no se pueden modificar, afecta varias tablas mnimo 4 tablas)
&Compras
&Devoluciones (De clientes, A Proveedores
&Traslados
&Ventas
&Consultas
&Kardex
&Reportes
&Inventario
&Ventas
A&yuda
A&cerca de
A&yuda

Antes de todo toca activarle un evento al formulario principal para cuando este se cierre la
aplicacin tambin deje de ejecutarse en eventos formclosing copiar lo siguiente para que
se termine la aplicacin
private void frmPrincipal_FormClosing(object sender, FormClosingEventArgs e)
{
Application.Exit();
}

Video 2.1 CRUD Clientes barra de herramientas


1. Clic en salir del men archivo y copiar el siguiente cdigo
private void salirToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
2. Cuando se est en desarrollo para no estar escribiendo el usuario se quema y despus se
quita en el frm login en la propiedad text del Textbox de usuario y pass copiamos los
respectivos datos de un usuario.
3. Vamos a construir el formulario de clientes
4. Agregar un nuevo Windows form llamado frmClientes
5. Activar propiedad text: Clientes
6. Colocarle una barra de herramientas (toolstret) agregar cuatro botn (1er registre,
anterior registro, siguiente registro y ltimo registro, luego colocar separador y luego seis
botones (modificar, nuevo, , borrar, guardar, cancelar buscar y colocarle sus respectivos
iconos y nombres.
Video 2.2 CRUD, Clientes diseo
1. Llamarlo al darle en cliente en el formulario principal doble clic en clientes y copiar el
siguiente cdigo para que los clientes queden contenidos en el formulario principal
private void clientesToolStripMenuItem_Click(object sender, EventArgs e)

{
frmClientes miForm = new frmClientes();
miForm.MdiParent = this;
miForm.Show();
}
2. Miramos en la table clientes los campos que tienen y de esos cuales son los obligatorio
3. Colocar los controles para hacer el formulario label, textbox
IdUsuario (label) no se modifica porque es autonumerico (Textbox) su propiedad
readonly: true
IdTipoDocumento(label) combobox (tipo de documento)
4. Lo que se hace en el combobox para que salga la lista de tipo de documento
a. Ir al ds y arrastrar la tabla tipodocumento
b. El ds de aplicacin comercial se tiene que crear al otro proyecto para hacer las consultas
en proyecto aplicacin comercial agregar nuevo elemento llamamos
dsAplicacionComercial arrastrar todas las tablas (utiliza para llenar gridview, combos)
c. En el control tipo de documento usar elementos enlazados a datos otros orgenes de
datos DSAplicacionComercial llenar origen de datos: tipodedocumento, mostrar
miembro: Descripcin (Valor que se va a mostrar) miembro de valor: IdtipoDocumento,
valor seleccionado: ninguno.
d. Probar y colocar la propiedad enabled del combobox en false
e. Documento (textbox y readonly true)
f. Nombre comercial (aplica para las empresas) en personas naturales nombre de contacto
puede ser la misma empresa se hara lo mismo con todos los dems campos todos con
label y textbox
Video 2.3 CRUD, clientes cargar datos en grid
1. Seguir haciendo formulario clientes desde correo el campo aniversario se hace con
control datetimepicker colocarle enable en false y notas al textbox se le coloca la
propiedad multiline en true y Scrolbals: vertical
2. Colocar abajo un datagridview con nombre dgvDatos y definimos las siguientes
propiedades anchor: seleccionar todas queden negrilla.
3. Vamos a crear una clase CAD que devuelva todos los clientes para llenarlos en la
cuadricula
4. Vamos al ds del CAD y arrastramos la tabla cliente ya se tiene una consulta getdata que
devuelve todos los clientes pero no se puede usar si no se tiene clase para acceder a esa
consulta
5. Crear clase que permita manipular clientes
6. Para manipular los datos necesitamos un objeto que es un adaptador de la clase cliente
que se crea con el siguiente cdigo en CADCliente
private static ClienteTableAdapter adaptador = new ClienteTableAdapter();
public static dsAplicacionComercial.ClienteDataTable GetData()
{
return adaptador.GetData();
}

Se hizo un mtodo llamado getdata que trae los datos del adaptador cliente y los devuelve
en un objeto que va ser un clientedatatable y lo que se debe hacer es que ese objeto nos
sirve para cargar los clientes al gridview al proyecto de arriba.
7. Compilemos solucin
8. Colocar publica la clase cliente
9. Activamos evento load dando doble clic en cualquier parte del formulario cliente y colocar
el siguiente cdigo
dgvDatos.DataSource = CADCliente.GetData();
10. Probar que salgan todos los clientes
11. Para que nos muestre el 1er registro
12. Declarar al formulario de clientes un atributo privado al inicio del formulario despus de
public partial class frmClientes : Form
{ // ya seta
private int i = 0;
//i es un subndice porque los registros se comportan como un vector
13. La grid view solo dejarle chulito habilitar reordenacin de columnas
14. Vamos a crear un mtodo llamado mostrarregistros
MostrarRegistros(); ctl + .
}
private void MostrarRegistros()
{
txtIDCliente.Text = dgvDatos.Rows[i].Cells["IdCliente"].Value.ToString();
txtDocumento.Text = dgvDatos.Rows[i].Cells["Documento"].Value.ToString();
txtNombresContacto.Text = dgvDatos.Rows[i].Cells["NombresContacto"].Value.ToString();
txtApellidosContacto.Text = dgvDatos.Rows[i].Cells["ApellidosContacto"].Value.ToString();
txtNombreComercial.Text = dgvDatos.Rows[i].Cells["NombreComercial"].Value.ToString();
txtDireccion.Text = dgvDatos.Rows[i].Cells["Direccion"].Value.ToString();
txtTelefono1.Text = dgvDatos.Rows[i].Cells["Telefono1"].Value.ToString();
}
Video 2.4 crud clientes botones de navegacin
1. Seguir con lo anterior los cuadros de texto
txtTelefono1.Text = dgvDatos.Rows[i].Cells["Telefono1"].Value.ToString();
txtTelefono2.Text = dgvDatos.Rows[i].Cells["Telefono2"].Value.ToString();
txtCorreo.Text = dgvDatos.Rows[i].Cells["Correo"].Value.ToString();
txtNotas.Text = dgvDatos.Rows[i].Cells["Notas"].Value.ToString();
2. El combobox y datepicker
cmbTipoDocumento.SelectedValue = dgvDatos.Rows[i].Cells["IdTipoDocumento"].Value;
dtpAniversario.Value = Convert.ToDateTime(dgvDatos.Rows[i].Cells["Aniversario"].Value);
3. En caso de que no haya registros para que no saque error se hace una validacin debajo
de

private void MostrarRegistros()


{ // Ya est antes de lo ingresado anteriormente
if (dgvDatos.Rows.Count == 0) return;
4. Probar
5. Cdigo para botn siguiente
private void tsbSiguiente_Click(object sender, EventArgs e)
{
if (i >= dgvDatos.Rows.Count - 1) return;
i++;
MostrarRegistros();
}
6. Codigo botn anterior
private void tsbAnterior_Click(object sender, EventArgs e)
{
if (i == 0) return;
i--;
MostrarRegistros();
}
7. Cdigo para mostrar el primero
private void tsbPrmero_Click(object sender, EventArgs e)
{
i = 0;
MostrarRegistros();
}
8. Cdigo para ir al ltimo registro
private void tsbUltimo_Click(object sender, EventArgs e)
{
i = dgvDatos.Rows.Count - 1;
MostrarRegistros();
}
9. Como por fechas puede molestar si esta es nula hacemos lo siguiente con el
dtpaniversario en load frmClientes lo colocamos en un try
try
{
dtpAniversario.Value = Convert.ToDateTime(dgvDatos.Rows[i].Cells["Aniversario"].Value);
}
catch (Exception)
{
dtpAniversario.Value = DateTime.Now;
}
10. Probar
Video 3 crud clientes botones editar y nuevo
1. Botn guardar y cancelar colocar enable: false

2. Para botn editar los botones de la barra de herramientas habilitados se deshabilitan y


viceversa y lo mismo con los controles del formulario a excepcin del IDCliente
3. Clic en lpiz(editar) se hace este codigo se crea procedimiento habilitarCampos()
private void tsbModificar_Click(object sender, EventArgs e)
{
HabilitarCampos(); ctl + .
}
Private void HabilitarCampos ()
{
tsbPrmero.Enabled = false;
tsbUltimo.Enabled = false;
tsbAnterior.Enabled = false;
tsbSiguiente.Enabled = false;
tsbModificar.Enabled = false;
tsbNuevo.Enabled = false;
tsbBorrar.Enabled = false;
tsbBuscar.Enabled = false;
tsbGuardar.Enabled = true;
tsbCancelar.Enabled = true;
txtDocumento.ReadOnly = false;
txtNombresContacto.ReadOnly = false;
txtApellidosContacto.ReadOnly = false;
txtNombreComercial.ReadOnly = false;
txtDireccion.ReadOnly = false;
txtTelefono1.ReadOnly = false;
txtTelefono2.ReadOnly = false;
txtCorreo.ReadOnly = false;
txtNotas.ReadOnly = false;
cmbTipoDocumento.Enabled = true;
dtpAniversario.Enabled = true;
cmbTipoDocumento.Focus();
4. El botn cancelar se hace lo siguiente
Private void tsbCancelar_Click(object sender, EventArgs e)
{
DeshabilitarCampos(); ctl + .
MostrarRegistros();
}
Private void DeshabilitarCampos()
{
tsbPrmero.Enabled = true;
tsbUltimo.Enabled = true;
tsbAnterior.Enabled = true;
tsbSiguiente.Enabled = true;
tsbModificar.Enabled = true;
tsbNuevo.Enabled = true;
tsbBorrar.Enabled = true;

tsbBuscar.Enabled = true;
tsbGuardar.Enabled = false;
tsbCancelar.Enabled = false;
txtDocumento.ReadOnly = true;
txtNombresContacto.ReadOnly = true;
txtApellidosContacto.ReadOnly = true;
txtNombreComercial.ReadOnly = true;
txtDireccion.ReadOnly = true;
txtTelefono1.ReadOnly = true;
txtTelefono2.ReadOnly = true;
txtCorreo.ReadOnly = true;
txtNotas.ReadOnly = true;
cmbTipoDocumento.Enabled = false;
dtpAniversario.Enabled = false;
}
5. PROBAR
6. Para botn nuevo
private void tsbNuevo_Click(object sender, EventArgs e)
{
HabilitarCampos();
LimpiarCampos(); ctl +.
}
private void LimpiarCampos()
{
txtIDCliente.Text = "";
txtDocumento.Text = "";
txtNombresContacto.Text = "";
txtApellidosContacto.Text = "";
txtNombreComercial.Text = "";
txtDireccion.Text = "";
txtTelefono1.Text = "";
txtTelefono2.Text = "";
txtCorreo.Text = "";
txtNotas.Text = "";
cmbTipoDocumento.SelectedIndex = -1;
dtpAniversario.Value = DateTime.Now;
}
7. Para saber si se digito o no un registro nuevo (si no es nuevo era registro editado)
8. En botn editar
nuevo = false;
9. En el botn nuevo
nuevo = true;
//para saber si al presionar guardar se le dio esta opcin por ser registro nuevo o
modificado
Video 3.1 crud clientes botn guardar
1. Para hacer el botn guardar primero hay que validar se debe utilizar un errorprovider
arrastra a cualquier parte del formulario

Se valida que los campos obligatorios no estn vacos


Que no digiten dos usuarios con el mismo nmero y tipo de documento (para esto es
necesario ir a la bd)
Validar que el correo sea valido
2. Por ahora solo validacin de vacos
private void tsbGuardar_Click(object sender, EventArgs e)
{
if (!ValidarCampos()) return;
}
private bool ValidarCampos()
{
if (cmbTipoDocumento.SelectedIndex == -1)
{
errorProvider1.SetError(cmbTipoDocumento, "Debe seleccionar un tipo de documento");
cmbTipoDocumento.Focus();
return false;
}
errorProvider1.SetError(cmbTipoDocumento, "");
if (txtDocumento.Text == "")
{
errorProvider1.SetError(txtDocumento, "Debe ingresar un documento");
txtDocumento.Focus();
return false;
}
errorProvider1.SetError(txtDocumento, "");
if (txtNombresContacto.Text == "")
{
errorProvider1.SetError(txtNombresContacto, "Debe ingresar un nombre(s) de contacto");
txtNombresContacto.Focus();
return false;
}
errorProvider1.SetError(txtNombresContacto, "");
if (txtApellidosContacto.Text == "")
{
errorProvider1.SetError(txtApellidosContacto, "Debe ingresar apellido(s) de contacto");
txtApellidosContacto.Focus();
return false;
}
errorProvider1.SetError(txtApellidosContacto, "");
if (txtNombreComercial.Text == "")
{
errorProvider1.SetError(txtNombreComercial, "Debe ingresar nombre comercial");
txtNombreComercial.Focus();
return false;
}
errorProvider1.SetError(txtNombreComercial, "");
return true;
}

3.
4.
5.
6.

Toca saber si lo que se hace es un insert o un update


Toca manipular datos
Ir al proyecto de datos y crear dos metodoss (insert, update)
El adaptador tiene insrt, update y delete pero es mejor construir unas nuevas para asi
tener control
7. Crear procedimiento de insertar agregar consulta nuevo proc alm insert
INSERT INTO [dbo].[Cliente] ([IdTipoDocumento], [Documento], [NombreComercial],
[NombresContacto], [ApellidosContacto], [Direccion], [Telefono1], [Telefono2], [Correo],
[Notas], [Aniversario]) VALUES (@IdTipoDocumento, @Documento, @NombreComercial,
@NombresContacto, @ApellidosContacto, @Direccion, @Telefono1, @Telefono2,
@Correo, @Notas, @Aniversario);
Llamado InsertCliente
8. En la clase CADCliente creamos el mtodo
public static void InsertCliente(int IdTipoDocumento, string Documento,
string NombreComercial, string NombresContacto,
string ApellidosContacto, string Direccion, string Telefono1,
string Telefono2, string Correo, string Notas, DateTime Aniversario)
{
adaptador.InsertCliente(IdTipoDocumento, Documento, NombreComercial,
NombresContacto,
ApellidosContacto, Direccion, Telefono1, Telefono2, Correo, Notas, Aniversario);
}
9. Crear proc almacenado para actualizar cliente
UPDATE [dbo].[Cliente] SET
[IdTipoDocumento] = @IdTipoDocumento,
[Documento] = @Documento,
[NombreComercial] = @NombreComercial,
[NombresContacto] = @NombresContacto,
[ApellidosContacto] = @ApellidosContacto,
[Direccion] = @Direccion,
[Telefono1] = @Telefono1,
[Telefono2] = @Telefono2,
[Correo] = @Correo,
[Notas] = @Notas,
[Aniversario] = @Aniversario
WHERE [IdCliente] = @IdCliente
Lo llamamos UpdateCliente
10. Agregamos consulta de delete
DELETE FROM [dbo].[Cliente] WHERE [IdCliente] = @IdCliente
Llamamos deleteCliente
Video 3.2.CRUD Clientes y botn borrar
1. En el CADCliente creamos los mtodos de update y delete
Update
public static void UpdateCliente(int IdTipoDocumento, string Documento,
string NombreComercial, string NombresContacto,
string ApellidosContacto, string Direccion, string Telefono1,

string Telefono2, string Correo, string Notas, DateTime Aniversario, int IdCliente)
{
adaptador.UpdateCliente(IdTipoDocumento, Documento, NombreComercial,
NombresContacto,
ApellidosContacto, Direccion, Telefono1, Telefono2, Correo, Notas, Aniversario, IdCliente);
}
Delete
public static void DeleteCliente(int IdCliente)
{
adaptador.DeleteCliente(IdCliente);
}
2. Cuando se diga guardar ahora si se llena
if (!ValidarCampos()) return;
if (nuevo)
{
CADCliente.InsertCliente((int)cmbTipoDocumento.SelectedValue, txtDocumento.Text,
txtNombreComercial.Text, txtNombresContacto.Text, txtApellidosContacto.Text,
txtDireccion.Text, txtTelefono1.Text, txtTelefono2.Text, txtCorreo.Text,
txtNotas.Text, dtpAniversario.Value);
}
else
{
CADCliente.UpdateCliente((int)cmbTipoDocumento.SelectedValue, txtDocumento.Text,
txtNombreComercial.Text, txtNombresContacto.Text, txtApellidosContacto.Text,
txtDireccion.Text, txtTelefono1.Text, txtTelefono2.Text, txtCorreo.Text, txtNotas.Text,
dtpAniversario.Value, Convert.ToInt32(txtIDCliente.Text));
}
DeshabilitarCampos();
dgvDatos.DataSource = null;
dgvDatos.DataSource = CADCliente.GetData();
if (nuevo) tsbUltimo_Click(sender, e);
MostrarRegistros();
3. Probar
4. Hacer botn eliminar
private void tsbBorrar_Click(object sender, EventArgs e)
{
DialogResult rta = MessageBox.Show("Esta seguro que desea borrar el registro actual",
"Confirmacion", MessageBoxButtons.YesNo, MessageBoxIcon.Question,
MessageBoxDefaultButton.Button2);
if (rta == DialogResult.No) return;
CADCliente.DeleteCliente(Convert.ToInt32(txtIDCliente.Text));
dgvDatos.DataSource = null;
dgvDatos.DataSource = CADCliente.GetData();
if (i != 0) i--;
MostrarRegistros();
}

Video 4 CRUD Proveedores parte 1


1. Agregamos formulario para hacer proveedores
2. Vamos a la barra de herramientas que se llama orgenes de datos la sacamos de ver
otras ventanas orgenes de datos
3. Cojo la tabla proveedores y se arrastra al formulario
4. Colocarle propiedad anchor: todos grises
5. Vamos al formulario principal y darle clic en proveedores y escribir
private void proveedoresToolStripMenuItem_Click(object sender, EventArgs e)
{
frmProveedores miform = new frmProveedores();
miform.MdiParent = this;
miform.Show();
}
6. Probar

En caso de que no haya registros para que no saque error se hace una validacin debajo
de
private void MostrarRegistros()
{ // Ya est antes de lo ingresado anteriormente
if (dgvDatos.Rows.Count == 0) return; //solo para tener en cuenta an no se ha
hecho
7. Organizar formulario y colocarle nombres y orden de tabulacin
Video 4.1 CRUD Proveedores parte 2
1. Arreglarle a la cuadricula para colocarle las tilde con editar columnas en la propiedad
header text y ponerle chulito solo en habilitar reordenacin.

2. Hacer funcionar el combo box


Usar elementos enlazados a datos
Orgenes de datos: tipodocumento
Mostrar miembro: descripcin
Miembro de valor: id tipodoc
Valor seleccionado: ninguno
3. Activarle al combobox la propiedad buscada por categora databinding la opcin
selectedvalue proveedorBindingSource IdTipoDocumento y la opcin text: ninguno
4. Para que en la cuadricula no salga el codigo del tipo de documento si no que salga la
descripcin le damos en la flechita de la cuadricula editar columnas tipo Documento
en la opcin column type lo cambio por comboBoxColumn y arriba sale la pestaa datos
donde solicita el datasource: TipoDocumentoBindingSource DisplayMember:
Descripcin
5. Seleccionar todos los textbox y colocarle la propiedad readonly: true y el combobox y
botn guardar se le coloca la propiedad enabled: false
Video 4.2. CRUD Proveedores parte 3
1. Cambiarle los nombres a la barra de herramientas y agregar botn de editar y los otros
botones y colocarle codigo de editar
private void bnModificar_Click(object sender, EventArgs e)
{
HabilitarCampos(); ctl + .
}
private void HabilitarCampos()
{
bnPrimero.Enabled = false;
bnAnterior.Enabled = false;
bnActual.Enabled = false;
bnCantidadRegistros.Enabled = false;
bnSiguiente.Enabled = false;
bnUltimo.Enabled = false;
bnModificar.Enabled = false;
bnNuevo.Enabled = false;
bnBorrar.Enabled = false;
bnCancelar.Enabled = true;
bnBuscar.Enabled = false;
bnGuardar.Enabled = true;
cmbTipoDocumento.Enabled = true;
txtDocumento.ReadOnly = false;
txtNombresContacto.ReadOnly = false;
txtApellidosContacto.ReadOnly = false;
txtNombre.ReadOnly = false;
txtDireccion.ReadOnly = false;
txtTelefono1.ReadOnly = false;
txtTelefono2.ReadOnly = false;
txtCorreo.ReadOnly = false;
txtNotas.ReadOnly = false;

}
2. probar
3. En el botn guardar colocar el siguiente codigo debajo del que ya se coloc
automticamente
private void bnGuardar_Click(object sender, EventArgs e)
{
this.Validate();
this.proveedorBindingSource.EndEdit();
this.tableAdapterManager.UpdateAll(this.dSAplicacionComercial);
DeshabilitarCampos(); ctl + .
}
private void DeshabilitarCampos()
{
bnPrimero.Enabled = true;
bnAnterior.Enabled = true;
bnActual.Enabled = true;
bnCantidadRegistros.Enabled = true;
bnSiguiente.Enabled = true;
bnUltimo.Enabled = true;
bnModificar.Enabled = true;
bnNuevo.Enabled = true;
bnBorrar.Enabled = true;
bnCancelar.Enabled = false;
bnBuscar.Enabled = true;
bnGuardar.Enabled = false;
cmbTipoDocumento.Enabled = false;
txtDocumento.ReadOnly = true;
txtNombresContacto.ReadOnly = true;
txtApellidosContacto.ReadOnly = true;
txtNombre.ReadOnly = true;
txtDireccion.ReadOnly = true;
txtTelefono1.ReadOnly = true;
txtTelefono2.ReadOnly = true;
txtCorreo.ReadOnly = true;
txtNotas.ReadOnly = true;
}
4. Probar
5. Hacer botn de cancelar el cdigo es
private void bnCancelar_Click(object sender, EventArgs e)
{
this.proveedorBindingSource.CancelEdit();
DeshabilitarCampos();
}
6. Probar

Video 5 CRUD Proveedores parte 4


1. Cogemos el objeto llamado proveedorBindingNavigator de la parte de abajo del formulario
y cambiamos dos propiedades para asi dejar esos botones sin opcin y podemos
nosotros tomar control de esos botones las propiedad AddNewItem: ninguno y
DeleteItem: ninguno.
2. Revisar en la base de datos en la tabla proveedor cuales datos son obligatorios para
hacerle las respectivas validaciones.
3. Aadir un errorprovider
4. En doble clic guardar y seguir con el codigo
private void bnGuardar_Click(object sender, EventArgs e)
{
if (!ValidarCampos()) return;
this.Validate();
this.proveedorBindingSource.EndEdit(); //finaliza edicin y graba los cambios
this.tableAdapterManager.UpdateAll(this.dSAplicacionComercial); //actualiza la cuadricula
de abajo
DeshabilitarCampos();
}
private bool ValidarCampos()
{
if (cmbTipoDocumento.SelectedIndex == -1)
{
errorProvider1.SetError(cmbTipoDocumento, "Debe seleccionar un tipo de documento");
cmbTipoDocumento.Focus();
return false;
}
errorProvider1.SetError(cmbTipoDocumento, "");
if (txtDocumento.Text == "")
{
errorProvider1.SetError(txtDocumento, "Debe ingresar un nmero de documento");
txtDocumento.Focus();
return false;
}
errorProvider1.SetError(txtDocumento, "");
if (txtNombresContacto.Text == "")
{
errorProvider1.SetError(txtNombresContacto, "Debe ingresar al menos un nombre de
contacto");
txtNombresContacto.Focus();
return false;
}
errorProvider1.SetError(txtNombresContacto, "");
if (txtApellidosContacto.Text == "")
{
errorProvider1.SetError(txtApellidosContacto, "Debe ingresar al menos un apellido de
contacto");
txtApellidosContacto.Focus();
return false;
}

errorProvider1.SetError(txtApellidosContacto, "");
}
if (txtNombre.Text == "")
{
errorProvider1.SetError(txtNombre, "Debe ingresar un nombre de proveedor");
txtNombre.Focus();
return false;
}
errorProvider1.SetError(txtNombre, "");
return true;
Video 5.1 CRUD Proveedores parte 5
1. Validamos que el correo sea vlido para eso toca agregar una clase llamada
RegexUtilities en aplicacin comercial agregar elemento existente y buscar la clase
regexUtilities esta clase tiene un mtodo llamado IsValidEmail que devuelve verdadero si
el correo es valido
errorProvider1.SetError(txtNombre, "");
if (txtCorreo.Text != "")
{
RegexUtilities regexUtilities = new RegexUtilities();
if (!regexUtilities.IsValidEmail(txtCorreo.Text))
{
errorProvider1.SetError(txtCorreo, "Si ingresa un correo, este debe ser valido");
txtCorreo.Focus();
return false;
}
errorProvider1.SetError(txtCorreo, "");
}
return true;
2. Probar
3. Para botn nuevo
private void bnNuevo_Click(object sender, EventArgs e)
{
HabilitarCampos();
proveedorBindingSource.AddNew();
cmbTipoDocumento.Focus();
}
4. Probar
Video 5.2 CRUD Proveedores parte 6
1. Cuando el tipo de documento es para persona natural una cedula los nombres de
contacto y comercial son los mismos para no escribirlo dos veces se hace lo siguiente
para eso le damos doble clic al cuadro de texto NombresContacto activa evento de
textChanged que significa que cuando cambie el texto vamos a llamar un procedimiento
que se llama arma nombre ponemos el siguiente cdigo.
private void txtNombresContacto_TextChanged(object sender, EventArgs e)

{
ArmaNombre(); ctl + .
}
private void ArmaNombre()
{
if (cmbTipoDocumento.SelectedIndex == 1)
{
txtNombre.Text = txtNombresContacto.Text + " " + txtApellidosContacto.Text;
}
}
private void txtApellidosContacto_TextChanged(object sender, EventArgs e)
{
ArmaNombre();
}
2. Intervenir el botn eliminar
private void bnBorrar_Click(object sender, EventArgs e)
{
DialogResult rta = MessageBox.Show("Est seguro que desea borrar el registro actual",
"Confirmacin", MessageBoxButtons.YesNo, MessageBoxIcon.Question,
MessageBoxDefaultButton.Button2);
if (rta == DialogResult.No) return;
proveedorBindingSource.RemoveAt(proveedorBindingSource.Position);
this.tableAdapterManager.UpdateAll(this.dSAplicacionComercial);

//falta validar que cuando un proveedor ya se le ha hecho una compra no se pueda borrar
}
INSERT INTO [dbo].[Proveedor] ([IdTipoDocumento], [Documento], [NombresContacto],
[ApellidosContacto], [Nombre], [Direccion], [Telefono1], [Telefono2], [Correo], [Notas])
VALUES (@Nombre, @IdTipoDocumento, @Documento, @NombresContacto,
@ApellidosContacto, @Direccion, @Telefono1, @Telefono2, @Correo, @Notas);
UPDATE [dbo].[Proveedor] SET [IdTipoDocumento] = @IdTipoDocumento, [Documento] =
@Documento, [NombresContacto] = @NombresContacto, [ApellidosContacto] =
@ApellidosContacto, [Nombre] = @Nombre, [Direccion] = @Direccion, [Telefono1] =
@Telefono1, [Telefono2] = @Telefono2, [Correo] = @Correo, [Notas] = @Notas WHERE
[IdProveedor] = @IdProveedor
DELETE FROM [dbo].[Proveedor] WHERE [IdProveedor] = @IdProveedor
public class CADProveedor
{
private static ProveedorTableAdapter adaptador = new ProveedorTableAdapter();
public static dsAplicacionComercial.ProveedorDataTable GetData()
{
return adaptador.GetData();
}
public static void UpdateProveedor( int IdTipoDocumento, string Documento,

string NombresContacto, string ApellidosContacto, string Nombre, string Direccion,


string Telefono1,
string Telefono2, string Correo, string Notas, DateTime Aniversario, int IdProveedor)
{
adaptador.UpdateProveedor(IdTipoDocumento, Documento, NombresContacto,
ApellidosContacto, Nombre, Direccion,
Telefono1, Telefono2, Correo, Notas, IdProveedor);
}

public static void DeleteProveedor(int IdProveedor)


{
adaptador.DeleteProveedor(IdProveedor);
}

Video 6 Bsqueda de proveedores parte 1

1. Crear un nuevo formulario para la bsqueda de proveedores llamado


frmBusquedaProveedor

2. Colocar una cuadricola donde se muestran todos los proveedores para eso arrastrar
control dataGridView llamarlo dgvBusqueda y en el triangulito en elegir orgenes de datos
escogemos la tabla proveedor
3. Personalizamos cuadricula los nombres de los campos y solo dejar habilitado opcin de
reordenacin.
4. Ir al formulario de proveedores y clic en icono de buscar y colocar el siguiente codigo
private void bnBuscar_Click(object sender, EventArgs e)
{
frmBusquedaProveedor miBusqueda = new frmBusquedaProveedor();
miBusqueda.ShowDialog(); //abrir formulario como modal y es de dialogo por lo que no se
puede hacer clic en otro lado
}
5. Cambiar los cdigos de los tipos de documentos por la descripcin desde la <gridview en
el triangulo colocar el columntype: combobox en datos la opcin datasource: tabla tipo
de documento displaymenber: descripcin valuemember: idtipodoc y la propiedad
anchor: 4 esquinas.
6. Otra vez en el triangulito agregar consulta copiar lo siguiente
SELECT IdProveedor, Nombre, IdTipoDocumento, Documento, NombresContacto,
ApellidosContacto, Direccion, Telefono1, Telefono2, Correo, Notas
FROM dbo.Proveedor WHERE Documento LIKE @Documento
AND Nombre LIKE @Nombre AND NombresContacto LIKE @NombresContacto
AND ApellidosContacto LIKE @ApellidosContacto aceptar
7. Cambiar el fiiby1 la propiedad displayStyle: Image y colocarle una imagen y el
tooltipText: Aplica los criterios de bsqueda seleccionados y cambiarle nombres a los
textbox que se crearon
8. Intervenir ese botn de bsqueda
1.
2.
3.
4.
5.

Video 6.1 Bsqueda proveedores parte 2


Colocar un groupbox llamarlo tipo criterio
Colocar radiobutton para los criterios de bsqueda contenga, empiece por, termine
en, igual a y seleccionamos contenga y colocamos propiedad checked: true
Botones de aceptar y cancelar del formulario login y la propiedad anchor: bottom, right y
no olvidar colocarle nombres a los radiobutton
Probar
Completar el botn
private void fillByToolStripButton_Click(object sender, EventArgs e)
{
string Documento, Nombre, NombreContacto, ApellidoContacto;
if (rbtContenga.Checked == true)
{
Documento = "%" + tstxtDocumento.Text + "%";
Nombre = "%" + tstxtNombre.Text + "%";
NombreContacto = "%" + tstxtNombresContacto.Text + "%";
ApellidoContacto = "%" + tstxtApellidosContacto.Text + "%";

}
else if (rbtEmpiece.Checked == true)
{
Documento = tstxtDocumento.Text + "%";
Nombre = tstxtNombre.Text + "%";
NombreContacto = tstxtNombresContacto.Text + "%";
ApellidoContacto = tstxtApellidosContacto.Text + "%";
}
else if (rbtTermine.Checked == true)
{
Documento = "%" + tstxtDocumento.Text;
Nombre = "%" + tstxtNombre.Text;
NombreContacto = "%" + tstxtNombresContacto.Text;
ApellidoContacto = "%" + tstxtApellidosContacto.Text;
}
else
{
Documento = tstxtDocumento.Text;
Nombre = tstxtNombre.Text;
NombreContacto = tstxtNombresContacto.Text;
ApellidoContacto = tstxtApellidosContacto.Text;
}
try
{
this.proveedorTableAdapter.FillBy(this.dSAplicacionComercial.Proveedor,
Documento, Nombre, NombreContacto, ApellidoContacto);
}
catch (System.Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
}
6. Probar
7. Colocar botn para que quite los filtros con el siguiente cdigo
private void btnQuitarFiltros_Click(object sender, EventArgs e)
{
tstxtDocumento.Text = "";
tstxtNombre.Text = "";
tstxtNombresContacto.Text = "";
tstxtApellidosContacto.Text = "";
fillByToolStripButton_Click(sender, e);
}
Video 6.2 Bsqueda proveedores parte 3
1. En el formulario de bsqueda de proveedores crear un atributo privado y con esto
comunicar el idcliente entre los dos formularios el de proveedor y el de bsqueda
public partial class frmBusquedaProveedor : Form
{

private int idProveedor; CTL R + E


public int IDProveedor
{
get { return idProveedor; }
}
2. Bsqueda de proveedor al presionar cancelar
private void btnCancelar_Click(object sender, EventArgs e)
{
idProveedor = 0;
this.Close();
}
3. Si se presiona el botn aceptar se debe validar
Pueden pasar 3 cosas cuando se hace bsqueda
Que este vaco
Que no se haya seleccionado ninguno y se asume que es el 1ro
De los registros buscados se haya seleccionado alguno de la gridview
Con este codigo en botn aceptar para que devuelva registro seleccionado o buscado al
otro formulario
private void btnAceptar_Click(object sender, EventArgs e)
{
if (dgvBusqueda.RowCount == 0)
{
idProveedor= 0;
}
else if (dgvBusqueda.SelectedRows.Count != 0)
{
idCProveedor = (int)dgvBusqueda.SelectedRows[0].Cells[0].Value;
}
Else
{
idProveedor= (int)dgvBusqueda.Rows[0].Cells[0].Value;
}
this.Close();
}
4. Clic buscar de proveedor y adicionar
miBusqueda.ShowDialog();
if (miBusqueda.IDProveedor == 0) return;
int position = proveedorBindingSource.Find("IDProveedor", miBusqueda.IDProveedor);
proveedorBindingSource.Position = position;
5. Probar
Video 7 Validacin de documento nico y CRUD Productos parte 1
1. Para que no se reviente la aplicacin cuando se meten dos registros con el
mismo tipo de documento y el mismo documento hacemos lo siguiente en botn guardar

if (!ValidarCampos()) return;
this.Validate();
this.proveedorBindingSource.EndEdit();
try
{
this.tableAdapterManager.UpdateAll(this.dSAplicacionComercial);
}
catch (Exception)
{
errorProvider1.SetError(txtDocumento, "Ese nmero de documento ya esta asgnado");
txtDocumento.Focus();
return;
}
errorProvider1.Clear();
DeshabilitarCampos();
2. Hacer crud clientes, bodegas, conceptos, departamento, unidades de medida, tipo doc
falta validacin de que no se repita una bodega, departamento, unidad de medida, tipo
doc
3. Al hacer el crud de productos en ese mismo crud se podr agregar los cdigos de barras
asociados a ese producto y parmetros de bodega
4. Agregar formulario frmProductos
5. Orgenes de datos - tabla productos definirle propiedad anchor
Video 7.1 CRUD Productos parte 2
1. En el formulario principal en la opcin productos colocar
frmProductos miform = new frmProductos();
miform.MdiParent = this;
miform.Show();

2. Cambiarle nombre a la barra de herramientos, los botones, personalizar gridview


departamento
ponerle combobox y definirle propiedades valor seleccionado
(productoBindingSource idDepartamento) y en las propiedades no olvidar en la
propiedad text colocar ninguno y hacer lo mismo con IVA
3. Probar
4. Personalizar todo eso en la gridview tambin
5. Descripcin en gridview 300 de tamao
6. Precio formato C2 y aliniacion middlerigh esta en la opcin defaultceelstyle
1.
2.
3.
4.
5.
6.

Video 7.2 CRUD Productos parte 3


Cuadricula para agregar y elimiar cdigos de barras y bodegas
Agregamos un groupbox que llamaremos codigo de barras
Dentro de ese arrastramos undatagrid lo renombramos
Agregamos dos botones para agregar y eliminar
Agregamos otro groupbox para parmetros de bodega
Personalizamos las cuadriculas para personalizalizarlas la de barras en
orgenes de datos utiliza orgenes de datos enlazados otros orgenes de datos
orgenes de datos del proyecto elegir la tabla barra

7. Lo mismo con parmetros de bodega con la tabla bodegaProducto


8. Agreguemos en sql registros en la tabla barras y bodegaproductos
9. Agregamos anchor de parmetros bodegas todos menos abajo y del gridview
interno todos menos abajo y del botn agregar que se mueva a la derecha
10.Vamos hacer que los registros se muestren en su respectivo producto
Video 7.3 CRUD Productos parte 4
1. El gv de codigo de barras est ligado a un bindingsource que se llama
barraBindngSource y la cuadricula tiene una propiedad que se llama
DataSource entonces a barraBindingSource le decimos agregar consulta
SELECT IdProducto, Barra FROM dbo.Barra WHERE IdProducto = @ IdProducto
2. Crear una barra de herramientas de la cual solo necesitamos el codigo del
fillby cogemos codigo dentro de try y lo copiamos arriba en el load debajo de
this.barraTableAdapter.Fill(this.dSAplicacionComercial.Barra); // DE 2DO
this.barraTableAdapter.FillBy(this.dSAplicacionComercial.Barra, ((int)
(System.Convert.ChangeType(idProductoToolStripTextBox.Text, typeof(int))))); // ESTE SE
MODIFICA se coloca abajo CAMBIO ESTE POR
this.barraTableAdapter.FillBy(this.dSAplicacionComercial.Barra,
Convert.ToInt32(txtIdProducto.Text)); // QDA EN LA PARTE DE ABAJO

3. Borrar la barra herramientas que se creo ya q esa solo se necesitaba codigo y borrar
tambin el codigo q se creo con la barra de herramientas
4. Probar
5. Crear evento llenarGrillas(); antes de cerrar corchete
6. Con esre codigo de arriba pasarlo abajo
private void LlenarGrillas()
{
// TODO: esta lnea de cdigo carga datos en la tabla 'dSAplicacionComercial.Barra' Puede
moverla o quitarla segn sea necesario.
this.barraTableAdapter.FillBy1(this.dSAplicacionComercial.Barra,
Convert.ToInt32(txtIdProducto.Text));
}
7. Clic en estos botones llaar evento
private void bnSiguiente_Click(object sender, EventArgs e)
{
LlenarGrillas();
}
private void bnAnterior_Click(object sender, EventArgs e)
{
LlenarGrillas();
}
private void bnPrimero_Click(object sender, EventArgs e)
{
LlenarGrillas();
}
private void bnUltimo_Click(object sender, EventArgs e)
{
LlenarGrillas();
}

8. Para bodega lo mismo


9. clic a bodegaproductobindingsource de los aparecen abajo
10. agregar consulta
SELECT IdBodega, IdProducto, Stock, Minimo, Maximo, DiasReposicion, CantidadMinima
FROM dbo.BodegaProducto
WHERE IdProducto = @IdProducto
11. crea el fillby nos sirve codigo de guis clc ah cambiarlo por el de arriba de bodega producto
y moverlo al evento llenargrillas quedando asi
private void LlenarGrillas()
{
// TODO: esta lnea de cdigo carga datos en la tabla 'dSAplicacionComercial.Barra' Puede
moverla o quitarla segn sea necesario.
this.barraTableAdapter.FillBy1(this.dSAplicacionComercial.Barra,
Convert.ToInt32(txtIdProducto.Text));
// TODO: esta lnea de cdigo carga datos en la tabla
'dSAplicacionComercial.BodegaProducto' Puede moverla o quitarla segn sea necesario.
this.bodegaProductoTableAdapter.FillBy(this.dSAplicacionComercial.BodegaProducto,
Convert.ToInt32(txtIdProducto.Text));
}
12. borrar barra y codigo try del fillby
13. probar
14. personalizar cuadricula de barras idpto propiedad visible: false y barra alinearla
middleright y barra colocarla mas grande de 150px
15. personalizar cuadricula parmetros bodega idbodega que muestre nombre de bodega, el
idproducto visible: false y las otras N0 PARA DIAS REPOSICION Y EL RESTO N2 Y
MIDDLERIGHT

Video 8 CRUD Productos parte 5


1.
2.
3.
4.
5.

personalizar barra de herramientas


botones enabled en false
arreglar orden de tabulacin
el picturebox la propiedad borderstyle en 3d
crear barra de herramientas al men principal con las opciones mas importantes agregar
toolstrip con 3 botones ( clientes, ptos y prov)
6. personalizar nombres e imgenes
7. personalizar los botones de la barra de herramientas con el siguiente codigo
private void tsbClientes_Click(object sender, EventArgs e)
{
clientesToolStripMenuItem_Click(sender, e);
}
private void tsbProveedor_Click(object sender, EventArgs e)
{
proveedoresToolStripMenuItem_Click(sender, e);
}
private void tsbProductos_Click(object sender, EventArgs e)
{
productosToolStripMenuItem1_Click(sender, e);
}
8. probar

Video 8.1 CRUD Productos parte 6


1. Productobindingnavigator colocarle propiedades AddNewItem y DeleteItem
en ninguno (por si no se ha hecho)

2. Intervenir el botn modificar con el codigo que se tiene en proveedores y


modificarlo adems de agregarle la habilitacin de los botones agregar barra y
bodega, eliminar barra, modificar barra y buscar imagen
3. Darle focus al botn descripcin
4. Probar
5. Intervenir botn nuevo
private void bnNuevo_Click(object sender, EventArgs e)
{
HabilitarCampos();
productosBindingSource.AddNew();
}
6. Intervenir botn borrar con codigo de proveedor guiarse

Video 8.2 CRUD Productos parte 7


1. Intervenir botn guardar
2. Crear procedimiento ValidarCampos y DeshabilitarCampos()
3. Para la validacin de precio a parte de validacin de vacio se valida que sea
numero y que no sea negativo de lasiguiente forma
decimal precio;
if (!decimal.TryParse(txtPrecio.Text, out precio))
{
errorProvider1.SetError(txtPrecio, "Debe ingresar un valor numrico en el precio del
producto");
txtPrecio.Focus();
return false;
}
errorProvider1.Clear();
if (precio <= 0)
{
errorProvider1.SetError(txtPrecio, "Debe ingresar un valor nmayor a cero(0) en el precio del
producto");
txtPrecio.Focus();
return false;
}
errorProvider1.Clear();

4. Intervenir botn cancelar igual que el de proveedores


Video 8.3 CRUD Productos parte 8
1. Vamos hacer la de la imagen el botn de le colocamos el siguiente codigo
2. Llamamos un openFileDialog que agregamos al formulario ese botn y para que aparezca la
ruta de la imagen i la imagen colocamos lo siguiente
private void btnBuscarImagen_Click(object sender, EventArgs e)
{
openFileDialog1.ShowDialog();
txtImagen.Text = openFileDialog1.FileName;
pbxImagen.Load(txtImagen.Text); //lo quitamos de aca para colocarlo abajo
}

3. Darle la propiedad sizemode strech


4. Validat que solo se vea en ul registro correcto subprograma cargarimagen()

private void CargarImagen()


{
if (txtImagen.Text == string.Empty)
{
pbxImagen.Image = null;
}
else
{
if (File.Exists(txtImagen.Text))
{
pbxImagen.Load(txtImagen.Text);
}
}

5. En los botones de primero ultimo, etc despus del mtodo colocar esto y tambin cuando el
formulario haga load
private void bnSiguiente_Click(object sender, EventArgs e)
{
LlenarGrillas();
CargarImagen();
}

6. Probar

Video 9 CRUD Productos parte 8


1. Para la parte de codigo de barra al decirle agregar aparezca una ventana
modal para adicionar cdigos de barras y lo mismo en eliminar
2. Agregar formulario llamado frmBarras colocarle un label llamado barra y el
textbox que permita adicionar la barra y botones de aceptar y cancelar
3. Para parmetros de bodega sera lo mismo permita agregar y modificar pero el
stock no se puede cambiar hasta empezar hacer movimiento
4. Formulario no se le pueda cambiar el tamao propiedad forborderStyle:
FixedDialog y maximeBox: false y minimeBox: false aceptbutton:
btnAceptar y cancelbutton: cancel, startposition: ceterparaent y revisar
orden de tabulacin
5. En el formulario de productos en el agregar de barras colocamos esto

6.
7.
8.

9.

private void btnAgregarBarra_Click(object sender, EventArgs e)


{
frmBarras miform = new frmBarras();
miform.ShowDialog();
}
Probar
Al formulario de barras de ptos agregarle un error provider
En evento load al inicio crear atributo privado
public partial class frmBarras : Form
{
private long barra = 0; ctr + R + E (haciendolo = 0 significa que se le dio a la x para
cerrarlo)
public long Barra
{
get { return barra; } // set se borra
}
Hacer clic en boton cancelar del formulario modal barra de ptos colocar lo siguiente
private void btnCancelar_Click(object sender, EventArgs e)

{
barra = 0;
this.Close();
}

10. Para el botn aceptar el siguiente codigo de validaciones vacio, numrica, que no haya otra barra
igual, que no haya un codigo de producto igual al de una barra
private void btnAceptar_Click(object sender, EventArgs e)
{
if (txtBarra.Text == string.Empty)
{
errorProvider1.SetError(txtBarra, "Debe ingresar un nmero de cdigo barras");
txtBarra.Focus();
return;
}
errorProvider1.Clear();
if(!long.TryParse(txtBarra.Text, out barra))
{
errorProvider1.SetError(txtBarra, "Debe ingresar un nmero entero en el cdigo barras");
txtBarra.Focus();
return;
}
errorProvider1.Clear();
if (barra < 10000000)
{
errorProvider1.SetError(txtBarra, "El nmero no corresponde a un cdigo de barras");
txtBarra.Focus();
return;
}
errorProvider1.Clear();
this.Close();
}
}

Video 9.1 CRUD Productos parte 10


1. Para la validacin de si la barra existe o no toca ir a la base de datos toca ir al dataset y adicionar
la tabla barras y hacer una consulta que valide si ya hay o no barras agregar consulta select que
devuelve un solo valor
SELECT 1 FROM Barra WHERE Barra = @Barra

2. Para poder accede a esta consulta se necesita una clase que pueda usar esa consulta en el
proyecto CAD agregamos la clase CADBarra a la clase que se crea toca colocarla publica y un
mtodo que utilice la consulta de ese table adapter llamado existe barra

private static BarraTableAdapter adapter = new BarraTableAdapter();


public static bool ExisteBarra(long Barra)
{
if (adapter.ExisteBarra(Barra) == null)
{
return false;
}
else
{
return true;
}
}

3. Ahora si realizer la otra validacion debajo de las demas validaciones


errorProvider1.SetError(txtBarra, "El nmero no corresponde a un cdigo de barras");
txtBarra.Focus();
return;
}
errorProvider1.Clear();
if (CADBarra.ExisteBarra(barra))
{
errorProvider1.SetError(txtBarra, "El nmero de barra ya est asignado a otro producto");
txtBarra.Focus();
return;
}
errorProvider1.Clear();
this.Close();
}
}

4. Se debe agregar una consulta en la tabla barra para agregar registros que se llamara insertBarra y
queda de la siguiente manera
INSERT INTO [dbo].[Barra] ([IdProducto], [Barra]) VALUES (@IdProducto, @Barra)
5. Creamos en el mtodo CADBarra que llame ese insert barra de la siguiente forma
if (adapter.ExisteBarra(Barra) == null)
{
return false;
}
else
{
return true;
}
}
public static void InsertBarra(int IdProducto, long Barra)
{
adapter.InsertBarra(IdProducto, Barra);
}

6. En el botn agregar barra que esta en formulario ptos despues de mostrar el formulario barra
miform.ShowDialog();
if (miform.Barra == 0) return;
CADBarra.InsertBarra(Convert.ToInt32(txtIdProducto.Text), miform.Barra);
this.barraTableAdapter.FillBy1(this.dSAplicacionComercial.Barra,
Convert.ToInt32(txtIdProducto.Text)); //este ultimo se coje de el mtodo llenargirllas() la
parte de barra ya que no se invoca como tal xq el tambin llena la tabla bodegaProducto

7. Probar
8. Hacer botn eliminar
private void btnEliminarBarra_Click(object sender, EventArgs e)
{
DialogResult rta = MessageBox.Show("Est seguro que desea borrar la barra",
"Confirmacin", MessageBoxButtons.YesNo, MessageBoxIcon.Question,
MessageBoxDefaultButton.Button2);
if (rta == DialogResult.No) return;
}
9. Toca ir al dataset para hacer la consulta de eliminar barra llama deleteBarra
C
10. En el CADBarra despues del insertBarra colocamos
public static void DeleteBarra(long Barra)
{
adapter.DeleteBarra(Barra);
}

Video 9.1 CRUD Productos parte 11


1. En ptos en boton eliminar de la barra colocamos adicionamos lo siguiente
if (rta == DialogResult.No) return;
long barra = (long) dgvBarras.Rows[barraBindingSource.Position].Cells[1].Value; // da el
indice
CADBarra.DeleteBarra(barra);
this.barraTableAdapter.FillBy1(this.dSAplicacionComercial.Barra,
Convert.ToInt32(txtIdProducto.Text));
}

2. Probar
3. HAGAMOS CRUD DE EXISTECONCEPTOS EXISTEBODEGAS, EXISTE DEPARTAMENTO,
existeunidadMedida, existeBodega (pendiente existecorreo)
4. Vamos modificar parmetros bodega
5. Agregamos formulario llamado frmParamentrosBodegas propiedad formBorderStyle: fixeddialog:
maximixebox y minimixebox en false y startposition: centerparent
6. Agregar label llamado bodega con su respectivo combobox y editar las propiedades especiales y la
ultima se deja en ninguno por no estar ligado al formulario
7. En formulario de ptos en el agregar de parametrosbodegas se coloca
private void btnAgregarBodegas_Click(object sender, EventArgs e)
{
frmParametrosBodega miForm = new frmParametrosBodega();
miForm.ShowDialog();
}

8. Cuando se carga formulario aadimos este codigo para que no seleccione la primera opcion por
defecto
private void frmParametrosBodega_Load(object sender, EventArgs e)
{
// TODO: esta lnea de cdigo carga datos en la tabla 'dSAplicacionComercial.Bodega' Puede
moverla o quitarla segn sea necesario.
this.bodegaTableAdapter.Fill(this.dSAplicacionComercial.Bodega);
cmbBodegas.SelectedIndex = -1;
}

9. Aadimos los controles segn campos de la tabla BodegaProducto con textbox del stock con
readonly y para los que son nmeros un control llamado numericupdown
10. Demos doble clic en combobox de bodega
11. Vamos al ds y agregamos tabla bodegaProducto
12. Hagamos un mtodos que devuelva todos los datos agregar consulta para mostrarlo en el
formulario pero como son varios campos se empaqueta en una clase se agrega consulta que
devuelva filas que queda asi
SELECT IdBodega, IdProducto, Stock, Minimo, Maximo, DiasReposicion, CantidadMinima
FROM dbo.BodegaProducto
WHERE IdBodega =@IdBodega AND IdProducto = @IdProducto
Llamara GetBodegaProductoByIdBodegaAndIdProducto
Quitamos chulito de rellenar datatable y le ponemos mismo nombre mtodo

Video 9.2 CRUD Productos parte 12


1. Agregar clase cadbodegapto y ponerla public
2. Crear el mtodo privado y quiero crear un empaquetado de los atributos de la tabla
public class CADBodegaProducto
{
//empaquetan campos
public int IdBodega { get; set; }
public int IdProducto { get; set; }
public float Stock { get; set; }
public float Minimo { get; set; }
public float Maximo { get; set; }
public int DiasReposicion { get; set; }
public float CantidadMinima { get; set; }
private static BodegaProductoTableAdapter adapter = new BodegaProductoTableAdapter();
//crear metodo que devuelva objeto clase bodegaproducto
public static CADBodegaProducto GetBodegaProductoByIdBodegaAndIdProducto(int
IdBodega, int IdProducto)

{
CADBodegaProducto miBodegaProducto = null;
dsAplicacionComercial.BodegaProductoDataTable miTabla =
adapter.GetBodegaProductoByIdBodegaAndIdProducto(IdBodega, IdProducto);
if (miTabla.Rows.Count == 0) return miBodegaProducto;
dsAplicacionComercial.BodegaProductoRow miRegistro =
(dsAplicacionComercial.BodegaProductoRow)miTabla.Rows[0]; //miregistro tiene la
informacion de ese registro como tal
//miregistro se convierte al objeto asi
miBodegaProducto = new CADBodegaProducto();
//CTIVAR PROPIEDADES
miBodegaProducto.CantidadMinima = (float)miRegistro.CantidadMinima;
miBodegaProducto.DiasReposicion = miRegistro.DiasReposicion;
miBodegaProducto.IdBodega = miRegistro.IdBodega;
miBodegaProducto.IdProducto = miRegistro.IdProducto;
miBodegaProducto.Maximo = (float)miRegistro.Maximo;
miBodegaProducto.Minimo = (float)miRegistro.Minimo;
miBodegaProducto.Stock = (float)miRegistro.Stock;
return miBodegaProducto;
}
}
3.

En el combobox parametrosBodega doble clic para activar ste evento


private void BodegaComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
CADBodegaProducto miBodegaProducto =
CADBodegaProducto.GetBodegaProductoByIdBodegaAndIdProducto
}

Comunicar formularios en parmetros bodega producto crear la propiedad


public partial class frmParametrosBodega : Form
{
private int idProducto;
public int IDProducto
{
set { idProducto = value; }
}

4. En boton agregar bodega de formulario product agregamos esta linea de codigo


private void btnAgregarBodegas_Click(object sender, EventArgs e)
{
frmParametrosBodega miForm = new frmParametrosBodega();
miForm.IDProducto = Convert.ToInt32(txtIdProducto.Text))
miForm.ShowDialog();
}

5. Al darle clic en el combobox se coloca


private void cmbBodegas_SelectedIndexChanged(object sender, EventArgs e)
{
if (cmbBodegas.SelectedIndex == -1) return;
CADBodegaProducto miBodegaProducto =
CADBodegaProducto.GetBodegaProductoByIdBodegaAndIdProducto( (int)cmbBodegas.Selec
tedValue, idProducto);

if (miBodegaProducto == null)
{
txtStock.Text = string.Empty;
nudCantidadMinimaOrdenar.Value = 1;
nudMaximo.Value = 1;
nudMinimo.Value = 1;
nudDias.Value = 1;
}
}

Video 9.3 CRUD Productos parte 13

1. Continuacin del if anterior


else
{
txtStock.Text = miBodegaProducto.Stock.ToString();
nudMinimo.Value =(decimal) miBodegaProducto.Minimo;
nudMaximo.Value = (decimal)miBodegaProducto.Maximo;
nudDias.Value = (decimal)miBodegaProducto.DiasReposicion;
nudCantidadMinimaOrdenar.Value = (decimal)miBodegaProducto.CantidadMinima;
}

2. Probar
3. Para el botn aceptar si el prametro de bodega existe se actualiza y si no existe se inserta
por lo que toca agregar dos mtodos el de insertar y el de actualizar
INSERT INTO [dbo].[BodegaProducto] ([IdBodega], [IdProducto], [Stock], [Minimo],
[Maximo], [DiasReposicion], [CantidadMinima]) VALUES (@IdBodega, @IdProducto, 0,
@Minimo, @Maximo, @DiasReposicion, @CantidadMinima) llamado
insertBodegaProducto
UPDATE [dbo].[BodegaProducto] SET [Minimo] = @Minimo, [Maximo] = @Maximo,
[DiasReposicion] = @DiasReposicion, [CantidadMinima] = @CantidadMinima WHERE
[IdBodega] = @IdBodega) AND [IdProducto] = @IdProducto llamado
updateBodegaProducto
4. Vamos hacer mtodo que haga insert o update segn lo que se necesite en
CADBodegaProducto
public static void UpdateBodegaProducto(int IdBodega, int IdProducto, double Minimo,
double Maximo, int DiasReposicion, double CantidadMinima)
{
try
{
adapter.InsertBodegaProducto(IdBodega, IdProducto, Minimo, Maximo, DiasReposicion,
CantidadMinima);
}
catch (Exception)
{
adapter.UpdateBodegaProducto(Minimo, Maximo, DiasReposicion, CantidadMinima,
IdBodega, IdProducto);
}
}

5. Botn aceptar del formulario modal


private void btnAceptar_Click(object sender, EventArgs e)

{
CADBodegaProducto.UpdateBodegaProducto((int)cmbBodegas.SelectedValue, idProducto,
(double) nudMinimo.Value, (double)nudMaximo.Value, (int)nudDias.Value,
(double)nudCantidadMinimaOrdenar.Value);
this.Close();
}

6. En el formulario productos actualizar grilla cogemos codigo llenargrilla de bodegas y se


coloca en el botn de agregarbodega del formulario producto
private void btnAgregarBodegas_Click(object sender, EventArgs e)
{
frmParametrosBodega miForm = new frmParametrosBodega();
miForm.IDProducto = Convert.ToInt32(txtIdProducto.Text);
miForm.ShowDialog();
// TODO: esta lnea de cdigo carga datos en la tabla
'dSAplicacionComercial.BodegaProducto' Puede moverla o quitarla segn sea necesario.
this.bodegaProductoTableAdapter.FillBy(this.dSAplicacionComercial.BodegaProducto,
Convert.ToInt32(txtIdProducto.Text));
}

7. Adicionar errorprovider en formulario parmetro bodega en el botn aceptar


if (cmbBodegas.SelectedIndex == -1)
{
errorProvider1.SetError(cmbBodegas, "Debe seleccionar una bodega");
cmbBodegas.Focus();
return;
}
errorProvider1.Clear();
CADBodegaProducto.UpdateBodegaProducto(

8. Como ya hay varios procedimientos almacenados vamos a hacer el Bck up de la base de


datos
9. En sql aplicacionComercialDiana clic derecho tareas copias de seguridad y
despus simplemente se restura

Video 10 CRUD Usuarios parte 1


1. Agregarmos gv, campos, modifcamos nombres, en la opcin de clave al

textbox se le coloca propiedad passwordchar:* y adicionar un label y textbox


llamado confirmacion alcual tambin se le coloca la propiedad passwordchar, al
campo fecha en propiedad format: short
2. El combobox de idrol en valorseleccionado colocamos usuario binding rol idrol
y tambin establecemos otro propiedad en los databinding en la propiedad
text: ninguno
3. En el formulario principal llamarlo
4. Este codigo evento load y cada vez que el usuario se mueva primero ultimo, y
en el actual pero cambiando el evento en las propiedades por el llamado
textChanged etc
private void frmUsuarios_Load(object sender, EventArgs e)
{
// TODO: esta lnea de cdigo carga datos en la tabla 'dSAplicacionComercial.Rol' Puede
moverla o quitarla segn sea necesario.
this.rolTableAdapter.Fill(this.dSAplicacionComercial.Rol);
// TODO: esta lnea de cdigo carga datos en la tabla 'dSAplicacionComercial.Usuario'
Puede moverla o quitarla segn sea necesario.
this.usuarioTableAdapter.Fill(this.dSAplicacionComercial.Usuario);
txtConfirmacion.Text = txtClave.Text;
}
Ese codigo escrito anteriormente se coloca tambin en clic de cada uno de los botones de
primero, anterior, siguiente y ultimo de la barra de herramientas y en registro actual pero
vamos a propiedades y cambiamos el evento que aparece por defecto por uno llamado
textChanged

Video 10.1 CRUD Usuarios parte 2

1. No olvidar desactivar en el usuariobindingnavigator: ninguno cuando se haga el


delete y la operacin de addnewitem
2. Revizar orden de tablulacion

3. Cargar errorprovider
4. Intervenir botn editar (fecha de modificacin no se manipula nuca siempre
estar desabilitada solo se deja a manera de consulta
5. Probar
6. Intervenir botn cancelar con ayuda de otro codigo de otro formulario
quedando asi
private void bnCancelar_Click(object sender, EventArgs e)
{
DeshabilitarCampos();
this.usuarioBindingSource.CancelEdit();
txtConfirmacion.Text = txtClave.Text;
errorProvider1.Clear();
private void DeshabilitarCampos() //solo habilitar campos es que se da focus
{
bnPrimero.Enabled = true;
bnAnterior.Enabled = true;
bnActual.Enabled = true;
bnCantidadRegistros.Enabled = true;
bnSiguiente.Enabled = true;
bnUltimo.Enabled = true;
bnModificar.Enabled = true;
bnBorrar.Enabled = true;
bnCancelar.Enabled = false;
bnBuscar.Enabled = true;
bnGuardar.Enabled = false;
txtIdUsuario.ReadOnly = true;
cmbIdRol.Enabled = false;
txtNombres.ReadOnly = true;
txtClave.ReadOnly = true;
txtConfirmacion.ReadOnly = true;
txtCorreo.ReadOnly = true;
}

7. Para boton nuevo


private void bnNuevo_Click(object sender, EventArgs e)
{
usuarioBindingSource.AddNew();
HabilitarCampos();
txtIdUsuario.ReadOnly = false;
cmbIdRol.Focus();
iftxtConfirmacion.Clear();
dtpfechaModificaionClave.Value = DateTime.Now;
}

8. Logica del guarder


private void usuarioBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
if (!ValidarCampos()) return;
this.Validate();
this.usuarioBindingSource.EndEdit();
this.tableAdapterManager.UpdateAll(this.dSAplicacionComercial);
DeshabilitarCampos();

private bool ValidarCampos()


{
if (nuevo)
{
if (txtIdUsuario.Text == string.Empty)
{
errorProvider1.SetError(txtIdUsuario, "Debe ingresar un Id de usuario");
txtIdUsuario.Focus();
return false;
}
errorProvider1.Clear();
}
return true;
}

9. Como se debe saber cuando se presiona nuevo al inicio del formulario de


usuarios hacemos lo siguiente
public partial class frmUsuarios : Form
{
private bool nuevo = false; //sirve para cuando se le diga editar sabe que no es nuevo
public frmUsuarios()

10.En editar adicionamos esto


HabilitarCampos();

Nuevo = false

11.y en nuevo seria


txtConfirmacion.Clear();

nuevo = true;
Esto sirve para cuando se guarde se pueda validar si el usuario existe o no
existe por lo que el codigo de guardar queda asi
12.Crear mtodo validar usuario select que devuele solo valor llamado
existeUsuario
SELECT 1 FROM Usuario WHERE IdUsuario = @IdUsuario
13.Modicamos clase cadUsuario
public static bool ExisteUsuario(string IdUsuario)
{
if (adaptador.ExisteUsuario(IdUsuario) == null)
{
return false;

}
else
{
return true;
}
}

Video 10.2 CRUD Usuarios parte 3 y seguridad de la aplicacin parte 1

1. Llamamos mtodo creado en botn guardar y seguimos validando


errorProvider1.Clear();
if (CADUsuario.ExisteUsuario(txtIdUsuario.Text))
{
errorProvider1.SetError(txtIdUsuario, "Id de usuario ya est siendo utilizado por otro
usuario");
txtIdUsuario.Focus();
return false;
}
errorProvider1.Clear();
}
return true;
}

2. Siendo o no nuevo se valida lo siguiente


if (CADUsuario.ExisteUsuario(txtIdUsuario.Text))
{
errorProvider1.SetError(txtIdUsuario, "Id de usuario ya est siendo utilizado por otro
usuario");
txtIdUsuario.Focus();
return false;
}
errorProvider1.Clear();
}
if (cmbIdRol.SelectedIndex == -1)
{
errorProvider1.SetError(cmbIdRol, "Debe seleccionar un rol para el usuario");
cmbIdRol.Focus();
return false;
}
errorProvider1.Clear();
if (txtNombres.Text == string.Empty)
{
errorProvider1.SetError(txtNombres, "Debe ingresar al menos un npmbre de usuario");
txtNombres.Focus();
return false;
}
errorProvider1.Clear();
if (txtApellido.Text == string.Empty)
{
errorProvider1.SetError(txtApellido, "Debe ingresar al menos un apellido de usuario");
txtApellido.Focus();
return false;
}
errorProvider1.Clear();
if (txtApellido.Text == string.Empty)

{
errorProvider1.SetError(txtApellido, "Debe ingresar al menos un apellido de usuario");
txtApellido.Focus();
return false;
}
errorProvider1.Clear();
if (txtClave.Text == string.Empty)
{
errorProvider1.SetError(txtClave, "Debe ingresar una clave para el usuario");
txtClave.Focus();
return false;
}
errorProvider1.Clear();
if (txtConfirmacion.Text == string.Empty)
{
errorProvider1.SetError(txtConfirmacion, "Debe ingresar una confirmacin para la clave de
usuario");
txtConfirmacion.Focus();
return false;
}
errorProvider1.Clear();
if (txtClave.Text != txtConfirmacion.Text)
{
errorProvider1.SetError(txtClave, "La clave y la confirmacin no coinciden");
errorProvider1.SetError(txtConfirmacion, "La clave y la confirmacin no coinciden");
txtClave.Focus();
return false;
}
errorProvider1.Clear();
if (txtCorreo.Text != txtCorreo.Text)
{
errorProvider1.SetError(txtCorreo, "Debe ingresar una direccin de correo");
txtCorreo.Focus();
return false;
}
errorProvider1.Clear();
RegexUtilities miValidador = new RegexUtilities();
if (!miValidador.IsValidEmail(txtCorreo.Text))
{
errorProvider1.SetError(txtCorreo, "Debe ingresar una direccin de correo valida");
txtCorreo.Focus();
return false;
}
errorProvider1.Clear();
return true;

3. Probar
4. Hacer borrar
private void bnBorrar_Click(object sender, EventArgs e)
{
DialogResult rta = MessageBox.Show("Est seguro que desea borrar el registro actual",
"Confirmacin", MessageBoxButtons.YesNo, MessageBoxIcon.Question,
MessageBoxDefaultButton.Button2);
if (rta == DialogResult.No) return;
usuarioBindingSource.RemoveAt(usuarioBindingSource.Position);
this.tableAdapterManager.UpdateAll(this.dSAplicacionComercial);

5. Valida permisos segn rol necesario saber con que usuario se entro
6. Creamos un empaquetado con todo atributos de la clase usuario para crear
objetos de la clase usuario eso se hace en el CADUsuarios
public class CADUsuario
{
public string IdUsuario { get; set; }
public string Nombres { get; set; }
public string Apellidos { get; set; }
public string Clave { get; set; }
public DateTime FechaModificaionClave { get; set; }
public int IdRol { get; set; }
public string Correo { get; set; }
private static UsuarioTableAdapter adaptador = new UsuarioTableAdapter();
//continua siguiente video //pendiente hacer consulta y mtodo para ExisteCorreo

Video 10.3 seguridad de la aplicacin parte 2 (video 37)


1. Haremos un mtodo que devuelva un usuario con los datos de la bd
2. Crear consulta en el DS seria un select que devuelve filas
SELECT IdUsuario, Nombres, Apellidos, Clave, FechaModificaionClave, IdRol, Correo FROM
dbo.Usuario WHERE IdUsuario = @IdUsuario mtodo se llama GetUsuario que no rellene
datatable si no que solo devuelve y el mtodo se llamara igua
3. En clase usuario se hace un mtodo q devuelva un objeto de la clase CADUsuario y ese
mtodo se usa en el formulario login para pasarlo al ppal para q este sepa quies es el q esta
logueado
public static CADUsuario GetUsuario(string IdUsuario) //devuelve objeto clase CADUsuario
{
CADUsuario miUsuario = null; // creamos objeto vacio
//vamos a utilizar la consulta que devuelve tabla del usuario
dsAplicacionComercial.UsuarioDataTable miTabla = adaptador.GetUsuario(IdUsuario);
//validar que devolvio regisstros
if (miTabla.Rows.Count == 0) return miUsuario;
dsAplicacionComercial.UsuarioRow miRegistro =
(dsAplicacionComercial.UsuarioRow)miTabla.Rows[0];//obtener fila
miUsuario = new CADUsuario();
miUsuario.Apellidos = miRegistro.Apellidos;
miUsuario.Clave = miRegistro.Clave;
miUsuario.Correo = miRegistro.Correo;
miUsuario.FechaModificaionClave = miRegistro.FechaModificaionClave;
miUsuario.IdRol = miRegistro.IdRol;
miUsuario.IdUsuario = miRegistro.IdUsuario;
miUsuario.Nombres = miRegistro.Nombres;
return miUsuario;
}
4. Vamos al formulario principal creamos atributo privado de la clase CADUsuario y lo
convertimos en propiedad publica en esto se hace para que cuando nos logueamos para
antes de abrir el formulario ya saber quien es la persona que se loguea entonces se hace lo
siguiente
public partial class frmPrincipal : Form

{
private CADUsuario usuarioLogueado;
public CADUsuario UsuarioLogueado
{
get { return usuarioLogueado; }
set { usuarioLogueado = value; }
}
Y en el login colocamos esto
frmPrincipal miForm = new frmPrincipal();
miForm.UsuarioLogueado = CADUsuario.GetUsuario(txtUsuario.Text);
miForm.Show();
this.Hide();

5. Creamos barra de estado en el formulario principal para saber quien es elq esta logueado
6. En barra de hmientas cogemos un statusstip y agregamos statusLabel se cambia nombre y
en el text no ponemos nada la idea es que cuando el formulario cargue en esa barra diga el
nombre de usuario
7. En el load del formulario principal
private void frmPrincipal_Load(object sender, EventArgs e)
{
tstNombresUsuarios.Text = "Usuario: " + usuarioLogueado.Nombres
+ " " + usuarioLogueado.Apellidos;
}
8. Probar

Video 11 seguridad de la aplicacin parte 3


1. Para cambio de clave creamos nuevo formulario llamado cambio clave con 3
textbox que se les coloca la propiedad passwordchar: * que no cambie de
tamao formBorderstile: FixedDialog minimeBox: false maximeBox: false
acceptbutton: btnAcetar y cancelbutton: btnCancelar y
startposition:CenterScrem
2. En el formulario principal llamarlo de forma modal
private void cambioDeClaveToolStripMenuItem_Click(object sender, EventArgs e)

{
frmCambioClave miform = new frmCambioClave();
miform.Show();
}
3. Copiar atributo y propiedad CADUsuario del formulario principal al cambio clave(se tiene
que hacer en casi todos los formularios)
public partial class frmCambioClave : Form
{
private CADUsuario usuarioLogueado;
public CADUsuario UsuarioLogueado
{
get { return usuarioLogueado; }
set { usuarioLogueado = value; }
}
4. Y en formulario cambio clave aadimos esta lnea
frmCambioClave miform = new frmCambioClave();
miform.UsuarioLogueado = this.usuarioLogueado;
5. En el boton aceptar
private void btnAceptar_Click(object sender, EventArgs e)
{
if(txtClaveAnterior.Text == string.Empty)
{
errorProvider1.SetError(txtClaveAnterior, "Debe ingresar la clave anterior");
txtClaveAnterior.Focus();
return;
}
errorProvider1.Clear();
if (usuarioLogueado.Clave != usuarioLogueado.Clave)
{
errorProvider1.SetError(txtClaveAnterior, "Clave incorrecta");
txtClaveAnterior.Focus();
return;
}
errorProvider1.Clear();
if (txtConfirmacionClave.Text == string.Empty)
{
errorProvider1.SetError(txtConfirmacionClave, "Debe ingresar una confirmacin para
clave");
txtConfirmacionClave.Focus();
return;
}
errorProvider1.Clear();
if(txtNuevaClave.Text == string.Empty)
{
errorProvider1.SetError(txtNuevaClave, "Debe ingresar una nueva clave");
txtNuevaClave.Focus();
return;
}
errorProvider1.Clear();
if (txtNuevaClave.Text != txtConfirmacionClave.Text)
{
errorProvider1.SetError(txtNuevaClave, "La clave y la confirmacin no son iguales");
errorProvider1.SetError(txtConfirmacionClave, "La clave y la confirmacin no son iguales");
txtNuevaClave.Focus();
return;
}
errorProvider1.Clear();

6. CREAR PROCEDIMIENTO ALMACENADO PARA ACTUALIZACION DE CLAVE


UPDATE [dbo].[Usuario] SET
[Clave] = @Clave,
[FechaModificaionClave] = @FechaModificaionClave
WHERE [IdUsuario] = @IdUsuario
llamamara cambio clave
Video 11.1 seguridad de la aplicacin parte 4

1. Vamos a la claseCADUsuario para poder utilizar la consulta


2. Creamos un nuevo mtodo para ejecutar la consulta
public static void CambioClave(string Clave, string IdUsuario)
{
adaptador.CambioClave(Clave, DateTime.Now, IdUsuario);
}

3. En el formulario de cambio clave


errorProvider1.SetError(txtConfirmacionClave, "La clave y la confirmacin no son iguales");
txtNuevaClave.Focus();
return;
}
errorProvider1.Clear();
CADUsuario.CambioClave(txtNuevaClave.Text, usuarioLogueado.IdUsuario);
MessageBox.Show("Cambio de clave realizado con xito", "Confirmacin",
MessageBoxButtons.OK, MessageBoxIcon.Information);
This.Close();

4. Probar
5. Para obligar a cambiar clave en el load del formulario principal hacemos el ste
mtodo
tslNombresUsuarios.Text = "Usuario: " + usuarioLogueado.Nombres + " " +
usuarioLogueado.Apellidos;
VerificaCambioClave(sender,e);
}
private void VerificaCambioClave(object sender, EventArgs e)
{
if (usuarioLogueado.FechaModificaionClave.AddMonths(1) < DateTime.Now)
{
cambioDeClaveToolStripMenuItem_Click(sender, e);
}
}

6. Para obligarlo a cambiarla que no sirva darle en cancelar colocar el codigo


anterior en el formulario cambio clave
Video 11.2 seguridad de la aplicacin parte 5

En el formulario cambioclave activar evento formclosin y hay colocar codigo

private void frmCambioClave_FormClosing(object sender, FormClosingEventArgs e)


{
if (usuarioLogueado.FechaModificaionClave.AddMonths(1) < DateTime.Now)
{
errorProvider1.SetError(txtNuevaClave, "Debe cambiar la clave");
txtNuevaClave.Focus();
e.Cancel = true;
return;
errorProvider1.Clear();
}
}
1. Colocar esto
MessageBox.Show("Cambio de clave realizado con xito", "Confirmacin",
MessageBoxButtons.OK, MessageBoxIcon.Information);
usuarioLogueado.Clave = txtNuevaClave.Text;
usuarioLogueado.FechaModificaionClave = DateTime.Now;
this.Close();

2. Para la opcin cambio usuario creamos otro formulario copiamos los botones del de login
definimos prop de maximeBox, minimeBox, formborderstile, acceptbutton y cancelbutton
3. Intervenir botn aceptar le colocamos la propiedad de cambio de usuario y lo del botn
aceptar del login todo prcticamente igual pero quitamos la lnea de cargar formulario ppal
public partial class frmCambioUsuario : Form
{
private CADUsuario usuarioLogueado;
public CADUsuario UsuarioLogueado
{
get { return usuarioLogueado; }
set { usuarioLogueado = value; }
}
public frmCambioUsuario()
{
InitializeComponent();
}
private void btnAceptar_Click(object sender, EventArgs e)
{
if (txtClave.Text == string.Empty)
{
errorProvider1.SetError(txtClave, "Debe ingresar una clave");
txtClave.Focus();

return;
}
errorProvider1.Clear();
if (!CADUsuario.ValidaUsuario(txtUsuario.Text, txtClave.Text))
{
MessageBox.Show("Usuario o clave no valido", "Error", MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
txtUsuario.Text = "";
txtClave.Text = "";
txtUsuario.Focus();
return;
}
usuarioLogueado = CADUsuario.GetUsuario(txtUsuario.Text);
this.Close();
}
private void btnCancelar_Click(object sender, EventArgs e)
{
usuarioLogueado = null;
this.Close();
}
4. En el formulario principal en evento de cambioUsuario colocamos lo siguiente
private void cambioDeUsuarioToolStripMenuItem_Click(object sender, EventArgs e)
{
frmCambioUsuario miForm = new frmCambioUsuario();
miForm.ShowDialog();
if (miForm.UsuarioLogueado != null)
{
this.usuarioLogueado = miForm.UsuarioLogueado;
tslNombresUsuarios.Text = "Usuario: " +
usuarioLogueado.Nombres + " " + usuarioLogueado.Apellidos;
}
}
5. Probar

Video 11.3 seguridad de la aplicacin parte 6

1.
2.
-

Para el manejo de la seguridad de la aplicacion hay dos tablas usuario y rol


En la base de datos crear una nueva table con los stes campos
IdPermiso int (autonumerico) y clave primaria
IdRol int no permite nulos

Formulario nvarchar(MAX) no permite nulos (contiene el nombre de los formularios)


PuedeVer boleano que en la base de datos se llama bit (no permite nnulos)
PuedeModificar bit
PuedeBorrar bit
Esta table toca mantenerla actualizando la llamamos PermisoRol

3. En el diagrama de base de datos en caso de que no tenga permisos para ingresar se


hace la siguiente consulta
Alter authorization on database: : nombreBaseDatos to sa (NombreUsuario)
4.
5.
6.
-

Creamos un diagrama con las tablas rol, usuario y permiso rol


Definemos la relacion de que un rol puede tener muchos permisos y lo llamamos DER
La tabla permisoRol editar las primeras 200 filas
Dar permiso a gerente que pueda hacer de todo ejemplo con frmProveedores
idRol 1 (gerente)
formulario: frmProveedores
PuedeVer: True
PuedeMpdofocar: True
PuedeBorrar: True
idRol 2 (administrador de inventario)
formulario: frmProveedores
PuedeVer: True
PuedeMpdofocar: True
PuedeBorrar: false
idRol 3 (cajero)
formulario: frmProveedores
PuedeVer: false
PuedeMpdofocar: false
PuedeBorrar: false
Hacerlo con todos los formularios

7. Vamos a la aplicacin para establecer los permisos


8. Vamos al formulario principal en la opcin proveedores propiedades visible: false
9. En load del principal crear un evento se hace como ejemplo para proveedores pero se
tiene que hacer con todos los formularios
VerificarPermisos(); ctl.
public static bool PuedeModificar(int IdRol, string Formulario)
{
if (adaptador.PuedeModificar(IdRol, Formulario) == null) return false;
return true;
}
public static bool PuedeBorrar(int IdRol, string Formulario)
{
if (adaptador.PuedeBorrar(IdRol, Formulario) == null) return false;
return true;
}

Video 11.4 seguridad de la aplicacin parte 7

1. Vamos al formulario principal al mtodo verificarPermisos(); hacer esto con


todos los formularios excepto cambioUsuario y CambioClave
private void VerificarPermisos()
{
if(CADPermisoRol.PuedeVer(usuarioLogueado.IdRol, "frmProveedores"))
proveedoresToolStripMenuItem.Visible = true;
else
proveedoresToolStripMenuItem.Visible = false;
}

2. En la opcin cambioUsuario actualizar permisos


usuarioLogueado.Nombres + " " + usuarioLogueado.Apellidos;
VerificarPermisos();

3. probar
4. Ahora se mira si el usuario puede modificar y puede borrar ejemplo con
proveedores
5. Entramos al formulario de proveedores y se le vca a cargar el usuario logueado
public partial class frmProveedores : Form
{
private CADUsuario usuarioLogueado;
public CADUsuario UsuarioLogueado
{
get { return usuarioLogueado; }
set { usuarioLogueado = value; }
}

6. Cuando se llame proveedores desde el principal agregar


miform.MdiParent = this;
miform.UsuarioLogueado = usuarioLogueado;
miform.Show();

7. En load de proveedores colocar evento verificarpermisos()


this.proveedorTableAdapter.Fill(this.dSAplicacionComercialDiana.Proveedor);
VerificaPermisos();
private void VerificarPermisos()
{
if (CADPermisoRol.PuedeModificar(usuarioLogueado.IdRol, this.Name))
{
bindingNavigatorAddNewItem.Enabled = true;
BindingNavigatorEditItem.Enabled = true;
}
else
{
bindingNavigatorAddNewItem.Enabled = false;
BindingNavigatorEditItem.Enabled = false;
}
if (CADPermisoRol.PuedeBorrar(usuarioLogueado.IdRol, this.Name))
{
bindingNavigatorDeleteItem.Enabled = true;
}

else
{
bindingNavigatorDeleteItem.Enabled = false;
}
}
8. En guardar y cancelar adicionar despus de deshabilitar
DeshabilitarCampos();
VerificarPermisos();

Video 12 seguridad de la aplicacin parte 8


1. Llenar tabla permiso rol segn los permisos tabla de Excel
2. Al formulario proveedores se lwe cargo propiedad de usuario logueado se le
debe de cargar a todos los formularios
private CADUsuario usuarioLogueado;
public CADUsuario UsuarioLogueado
{
get { return usuarioLogueado; }
set { usuarioLogueado = value; }
}

3. En el formulario principal al llamar bodegas y a todos los formularios colocar el


siguiente codigo
frmBodegas miform = new frmBodegas();
miform.MdiParent = this;
miform.UsuarioLogueado = usuarioLogueado;
miform.Show();

4. Lo que se implement para proveedores en el metodo verificarPermisos del formulario


principal se hace con todos los formularios
if (CADPermisoRol.PuedeVer(usuarioLogueado.IdRol, "frmProveedores"))
{
proveedoresToolStripMenuItem.Visible = true;
}
else
{
proveedoresToolStripMenuItem.Visible = false;
}

5. El metodo verifica permisos de proveedores se coge codigo y se copia el llamado y el


desarrollo del metodo y se le copia en el load de cada formulario (por ahora hecho para
los formularios ya diseados)
VerificarPermisos();
}
private void VerificarPermisos()
{
if (CADPermisoRol.PuedeModificar(usuarioLogueado.IdRol, this.Name))
{
bindingNavigatorAddNewItem.Enabled = true;
BindingNavigatorEditItem.Enabled = true;

}
else
{
bindingNavigatorAddNewItem.Enabled = false;
BindingNavigatorEditItem.Enabled = false;
}
if (CADPermisoRol.PuedeBorrar(usuarioLogueado.IdRol, this.Name))
{
bindingNavigatorDeleteItem.Enabled = true;
}
else
{
bindingNavigatorDeleteItem.Enabled = false;
}
}

Se borro en clients
6. Las opciones q estan en la barra de hmientas se valida tambien permisos en formulario
principal en verificar permisos aadir lo ste en ptos, clients y proveedores
if (CADPermisoRol.PuedeVer(usuarioLogueado.IdRol, "frmProductos"))
{
productosToolStripMenuItem1.Visible = true;
ProductostoolStripButton.Visible = true;
}
else
{
productosToolStripMenuItem1.Visible = false;
ProductostoolStripButton.Visible = false;
}

Video 12.1 Compras parte 1


1. Coloquemole iconos a las opciones de la barra de herramientas con la
propiedad image formato .PNG de 32 x 32
2. Colocarle iconos a los formularios los cuales deben estar en formato .ICO 32 x
32
3. Hacer los movimientos con compras ya no se hace crud se mira tabla compras
y detalleCompras y modificacin de bodegaPto y la tabla Kardex cada q se
haga mov de compra se hacen cambios en esas cuatro tablas no solo en un
registro si no en varios registros
4. Vamos hacer el layout de lo que quiero que sea mi compra empezamos con la
tabla compra que es el encabezado
5. Cogemos un label llamamos fecha y un datetimepicker otro label para
proveedor con su combo box y un botn para buscar proveedores (utilizar
formulario busquedaProveedor) y lo mismo otro label para bodega a la cual se
hace la compra con su combobox y los combobox enlazarlos con las tablas la
ultima opcin queda en ninguno
6. Organizar orden en los combobox en el el triangulo de proveedor y bodega
agregar consulta

SELECT IdProveedor, Nombre, IdTipoDocumento, Documento,


NombresContacto,
ApellidosContacto, Direccion, Telefono1, Telefono2, Correo, Notas
FROM dbo.Proveedor
ORDER BY Nombre
7. El crea la barra de hmientas se coge el codigo del botn fillby cogemos este
codigo que se genera
this.proveedorTableAdapter.FillBy2(this.dSAplicacionComercial.Proveedor); y se copia y se
cambia por este otro
this.proveedorTableAdapter.Fill(this.dSAplicacionComercial.Proveedor);
y borro la barra de herramientas con el codigo que me creo

8. Para bodegas
SELECT IdBodega, Descripcion FROM dbo.Bodega
ORDER BY Descripcion

Colocar este codigo this.bodegaTableAdapter.FillBy(this.dSAplicacionComercial.Bodega);


Reemplazarlo por este
this.bodegaTableAdapter.Fill(this.dSAplicacionComercial.Bodega);

borrar brra de herramientas y codigo que sobro

9. Probar
10.Cuando se empiece una compra nueva adicionar el ste codigo para que no este
por defecto el primer proveedor y bodeha en el load del formulario y que tenga
por defecto cla fecha del sistema
this.proveedorTableAdapter.FillBy2(this.dSAplicacionComercial.Proveedor);
FechaDateTimePicker.Value = DateTime.Now;
ProveedorComboBox.SelectedIndex = -1;
BodegsComboBox.SelectedIndex = -1;
}

Video 12.2 Compras parte 2


1. Codigo del botn de buscar le damos doble clic y colocamos lo ste
private void BuscarProveedorButton_Click(object sender, EventArgs e)
{
frmBusquedaProveedor miBusqueda = new frmBusquedaProveedor();
miBusqueda.ShowDialog();
if (miBusqueda.IDProveedor == 0) return;
ProveedorComboBox.SelectedValue = miBusqueda.IDProveedor;
}

2. Probar
3. Comenzamos con la opcin de agregar productos a la compra (min 4:34)
agregamos otro label llamado pto y cuadro textbox para el pto que se puede
encontrar x codigo de barras, cod de pto o descrpcion y un botn para buscarlo
y un label que le ponemos Descripcion Producto lo ponemos yn azul y negrita
que se llama ProductoLabel. El textbox y le colocamos nombre altextbox y al
boton
4. Cargar errorprovider
5. Se necesita un evento que cuando salga de ah dispare el evento algo las
propiedades del textbox escoger entre los eventos el llamado validating
6. Toca validar si lo ingresado existe como pto o como barras
7. Hacer validaciones locales en el evento activado

private void ProductoTextBox_Validating(object sender, CancelEventArgs e)


{
if (ProductoTextBox.Text == string.Empty)
{
errorProvider1.SetError(ProductoTextBox, "Debe ingresar un Id de producto o un
cdigo de barras");
return;
}
errorProvider1.Clear();
long producto;
if (!long.TryParse(ProductoTextBox.Text, out producto))
{
errorProvider1.SetError(ProductoTextBox, "Debe ingresar un valor numrico
entero");
return;
}
errorProvider1.Clear();

if (producto <= 0)
{
errorProvider1.SetError(ProductoTextBox, "Debe ingresar un valor mayor a 0");
return;
}
errorProvider1.Clear();

8. Probar
9. Cuando el formulario haga load tambin debe blanquear el label
BodegaComboBox.SelectedIndex = -1;
ProductoLabel.Text = string.Empty;

10. Otras validaciones de si existe o no existe. SsE Necesita ir a la base de datos para en caso
de que exista lo digitado corresponde a un codigo de barras o a un Id de producto para eso
se necesita hacer un metodo

Video 12.3 Compras parte 3


1. Se debe buscar en pto y si no se encuentra buscar en la tabla barra
2. Vamos a la aplicacin comercial y agregamos la tabla producto para hacer un
mtodo que devuelva la descripcin si el pto existe como pto
Agregar consulta sselect que devulve filas y lo mismo en barra
3. Agregamos el CADProductos colocarla publica y definirle adaptador y una
consulta que devuelva todos los datos del pto
4. Este es la consuilta del proc almacenado
SELECT IdProducto, Descripcion, IdDepartamento, IdIVA, Precio, Notas, Imagen,
IdMedida, Medida FROM dbo.Productos
WHERE IdProducto = @IdProducto llamamos GetProductoByIdProducto no
rellena un datatable si no que devuelve un datatable
5. Vamos a utilizar la consulta en la clase pto vamos a empaquetar todos los
atributos de la tabla pto los colocamos como propiedades en la clase
Prop (tab tab)
SELECT IdProducto, Descripcion, IdDepartamento, IdIVA, Precio, Notas, Imagen,
IdMedida, Medida
FROM Barra INNER JOIN Producto ON Barra.IdProducto = Producto.IdProducto
WHERE Barra = @Barra

public int IdProducto { get; set; }


public string Descripcion { get; set; }
public int IdDepartamento { get; set; }
public int IdIVA { get; set; }
public decimal Precio { get; set; }
public string Notas { get; set; }
public string Imagen { get; set; }
public int IdMedida { get; set; }
public float Medida { get; set; }
private static ProductosTableAdapter adaptador = new ProductosTableAdapter();

6. Creamos mtodo publico que devuelve objeto de la clase producto

private static ProductosTableAdapter adaptador = new ProductosTableAdapter();


public static CADProducto GetProductoByIdProducto(int IdProducto)
{
CADProducto miProducto = null;
//hacemos consulta para que devuelva datatable
dsAplicacionComercial.ProductosDataTable miTabla =
adaptador.GetProductoByIdProducto(IdProducto);
//preguntar si devuelve filas o no
if (miTabla.Rows.Count == 0) return miProducto;
dsAplicacionComercial.ProductosRow miRegistro =
(dsAplicacionComercial.ProductosRow)miTabla.Rows[0];
//registro convertirlo en un objeto producto
miProducto = new CADProducto();
miProducto.Descripcion = miRegistro.Descripcion;
miProducto.IdDepartamento = miRegistro.IdDepartamento;
miProducto.IdIVA = miRegistro.IdIVA;
miProducto.IdMedida = miRegistro.IdMedida;
miProducto.IdProducto = miRegistro.IdProducto;
miProducto.Imagen = miRegistro.Imagen;
miProducto.Medida = (float) miRegistro.Medida;
miProducto.Notas = miRegistro.Notas;
miProducto.Precio = miRegistro.Precio;
return miProducto;
}

7. Como no se sabe si se digito un codigo de barras o un id de pto se hace algo similar en


barras en pto vamos a crear otra consulta agregar consultan- select que devuelve filas
SELECT Productos.IdProducto, Descripcion, IdDepartamento, IdIVA, Precio, Notas,
Imagen, IdMedida, Medida
FROM Barra INNER JOIN Productos ON Barra.IdProducto = Productos.IdProducto
WHERE Barra = @Barra

Video 12.4 Compras parte 4


1. Vamos al mtodo copiamos el codigo anterior y solo cambia nombre mtodo la
consulta
public static CADProducto GetProductoByBarra(long Barra)
{
CADProducto miProducto = null;

dsAplicacionComercial.ProductosDataTable miTabla =
adaptador.GetProductoByBarra(Barra);
if (miTabla.Rows.Count == 0) return miProducto;
dsAplicacionComercial.ProductosRow miRegistro =
(dsAplicacionComercial.ProductosRow)miTabla.Rows[0];
miProducto = new CADProducto();
miProducto.Descripcion = miRegistro.Descripcion;
miProducto.IdDepartamento = miRegistro.IdDepartamento;
miProducto.IdIVA = miRegistro.IdIVA;
miProducto.IdMedida = miRegistro.IdMedida;
miProducto.IdProducto = miRegistro.IdProducto;
miProducto.Imagen = miRegistro.Imagen;
miProducto.Medida = (float)miRegistro.Medida;
miProducto.Notas = miRegistro.Notas;
miProducto.Precio = miRegistro.Precio;
return miProducto;
}
2. En la clase del formulario compras se valida si existe o no
3. Crear un objeto de la clase CADProducto asi
errorProvider1.Clear();
CADProducto miProducto = CADProducto.GetProductoByIdProducto((int)producto);
if (miProducto == null) // no lo encontro como codigo de pto
{
miProducto = CADProducto.GetProductoByBarra(producto);
}
if (miProducto == null) // no esta en bd
{
errorProvider1.SetError(ProductoTextBox, "Producto no existe");
ProductoLabel.Text = string.Empty;
}
else
{
ProductoLabel.Text = miProducto.Descripcion;
}
}

4. Como saca error cuando no hay imagen y cuando no hay nada en el campo
notas en cambiar este codigo del dsaplicacioncomercial.designer
public string Imagen {
get {
try {
return ((string)(this[this.tableProductos.ImagenColumn]));
}
catch (global::System.InvalidCastException e) {
throw new global::System.Data.StrongTypingException("El valor de la
columna \'Imagen\' de la tabla \'Productos\' es DBNull.", e); borrar eso y colocar
return ;
}
}
set {
this[this.tableProductos.ImagenColumn] = value;
}
}
5. Probar
6. Codigo botn de bsqueda de pto y disparar evento validating
private void BuscarProductoButton_Click(object sender, EventArgs e)

frmBusquedaProductos miBusqueda = new frmBusquedaProductos();


miBusqueda.ShowDialog();
if (miBusqueda.IDProducto == 0) return;
ProductoTextBox.Text = miBusqueda.IDProducto.ToString();
ProductoTextBox_Validating(sender, new CancelEventArgs());

7. Probar
8. Colocar que salga imagen para los ptos que tienen imagen el picture box de ptos pegarlo
en formulario de compras
CADProducto miProducto = CADProducto.GetProductoByIdProducto((int)producto);
if (miProducto == null) // no lo encontro como codigo de pto
{
miProducto = CADProducto.GetProductoByBarra(producto);
}
if (miProducto == null) // no esta en bd
{
errorProvider1.SetError(ProductoTextBox, "Producto no existe");
ProductoLabel.Text = string.Empty;
pbxImagen.Image = null;
}
else
{
ProductoLabel.Text = miProducto.Descripcion;
if (miProducto.Imagen != string.Empty)
{
if (File.Exists("Images\\" + miProducto.Imagen))
{
pbxImagen.Load("Images\\" + miProducto.Imagen);
}
else
{
pbxImagen.Image = null;
}
}
else
{
pbxImagen.Image = null;
}
}
}

9. Probar
10. Se necesita saber la cantidad de ptos a comprar
11. Hacemos label y textbox para la cantidad y un boton para agregar le colocamos imagen y
nombre
12. Adicionar un dataGrid en donde se coloca los datos de lo que el usuario esta comprando
Video 12.5 Compras parte 5
1. La cuadricola tiene una temporal de los ptos q se van comprando y para eso se debe
crear una lista para almacenar ptos temporales que vamos comprando
2. Para crear una lista se crea una clase llamada DetalleCompra y se agrega en aplicacin
comercial no en el CAD que tendr los atributos que se quiere que vayan temporales en la
compra

class DetalleCompra
{
public int IdProducto { get; set; }
public string Descripcion { get; set; }
public decimal Costo { get; set; }
public float Cantidad { get; set; }
public float PorcentajeIVA { get; set; }
public float PorcentajeDescuento { get; set; }
}

i. Cuando hace load en el


formulario compras
creamos un atributo
generic que se llama
misDetalles
public partial class frmCompras : Form
{
List<DetalleCompra> misDetalles = new List<DetalleCompra>();

3. El list tambin puede ser el origen de datos de la gv de compras le cambiamos el nombre a

4.
5.
6.

7.

esa gv por DetallaDataGridView y cuando se entre al formulario y cuando haga load se


copia lo ste
ProductoLabel.Text = string.Empty;
DetalleDataGridView.DataSource = misDetalles;
Probar
Agregamos label y textbox para costo
Crear un atributo al principio del formulario compras de la clase prosucto llamado
ultimoProducto
List<DetalleCompra> misDetalles = new List<DetalleCompra>();
CADProducto ultimoProducto = null;
Y debajo de (esto se hace para cuando se haga agregar se valide que si se haya digitado un
ultimo pto
CADProducto miProducto = CADProducto.GetProductoByIdProducto((int)producto);
if (miProducto == null) // no lo encontro como codigo de pto
{
miProducto = CADProducto.GetProductoByBarra(producto);
}
if (miProducto == null) // no esta en bd
{
errorProvider1.SetError(ProductoTextBox, "Producto no existe");
ProductoLabel.Text = string.Empty;
pbxImagen.Image = null;
ultimoProducto = null;
}
else

{
ProductoLabel.Text = miProducto.Descripcion;
ultimoProducto = miProducto;

8. El codigo del botn agregar


private void AgregarButton_Click(object sender, EventArgs e)
{
if (ultimoProducto == null) //significa que el ultimo pto no existia o no han buscado
nimgun pto
{
errorProvider1.SetError(ProductoTextBox, "Debe ingresar un producto");

ProductoTextBox.Focus();
return;
}
errorProvider1.Clear();
}

9. Probar
10. Vamos a validar cantidad, costo, %Descuento valido en agregar pto colocar ste codigo
if (CantidadTextBox.Text == string.Empty)
{
errorProvider1.SetError(CantidadTextBox, "Debe ingresar una cantidad");
return;
}
errorProvider1.Clear();
float cantidad;
if (!float.TryParse(CantidadTextBox.Text, out cantidad))
{
errorProvider1.SetError(CantidadTextBox, "Debe ingresar un valor numrico");
return;
}
errorProvider1.Clear();
if (cantidad <= 0)
{
errorProvider1.SetError(CantidadTextBox, "Debe ingresar un valor mayor a 0");
return;
}
errorProvider1.Clear();

if (CostoTextBox.Text == string.Empty)
{
errorProvider1.SetError(CostoTextBox, "Debe ingresar un costo del producto");
return;
}
errorProvider1.Clear();
decimal costo;
if (!decimal.TryParse(CostoTextBox.Text, out costo))
{
errorProvider1.SetError(CostoTextBox, "Debe ingresar un valor numrico");
return;
}
errorProvider1.Clear();
if (costo <= 0)
{
errorProvider1.SetError(CostoTextBox, "Debe ingresar un valor mayor a 0");
return;
}
errorProvider1.Clear();

float porcentajeDescuento = 0;
if (PorcentajeDescuentoTextBox.Text != string.Empty)
{
if (!float.TryParse(PorcentajeDescuentoTextBox.Text, out porcentajeDescuento))

errorProvider1.SetError(PorcentajeDescuentoTextBox, "Debe ingresar un valor

numrico");

return;
}
errorProvider1.Clear();

if (porcentajeDescuento < 0 && porcentajeDescuento>100) )


{
errorProvider1.SetError(PorcentajeDescuentoTextBox, "Debe ingresar un valor
mayor o igual a 0" y mennor o igual a 100);
return;
}
}

11. Probar
12. Lo agregado aparezca en la gridview
if (porcentajeDescuento < 0 && porcentajeDescuento>100)
{
errorProvider1.SetError(PorcentajeDescuentoTextBox, "Debe ingresar un valor
mayor o igual a 0" y mennor o igual a 100);
return;
}
errorProvider1.Clear();
}
DetalleCompra miDetalle = new DetalleCompra();
miDetalle.Cantidad = cantidad;
miDetalle.Costo = costo;
miDetalle.Descripcion = ultimoProducto.Descripcion;
miDetalle.IdProducto = ultimoProducto.IdProducto;
miDetalle.PorcentajeDescuento = porcentajeDescuento;
miDetalle.PorcentajeIVA = 0; //OJO PENDIENTE
misDetalles.Add(miDetalle);
DetalleDataGridView.DataSource = null;
DetalleDataGridView.DataSource = misDetalles;
//codigo adicional agregado por mi no en videop pero si aparece desues
ultimoProducto = null;
CantidadTextBox.Text = string.Empty;
CostoTextBox.Text = string.Empty;
PorcentajeDescuentoTextBox.Text = string.Empty;

13. Probar que lo pase abajo


Video 13 Compras parte 6

1. Crear opcion de compras para acceso rapido


2. Solucionar lo del IVA, en la clase CAD se crea un metodo que se le pase el codigo
del IVA y que devuelva un objeto que tenga empaquetados todos los campos de la
table IVA
3. Vamos al dataset y se arrastra table de IVA

4. Hacer un metodo que devuelva una tarifa de IVA, hay un metodo getData ya pero
ese nos devuelve toda la table de IVA agregar consula .- nuevo proc almac
select que devuelve filas
SELECT IdIVA, Descripcion, Tarifa FROM dbo.IVA WHERE IdIVA = @IdIVA el
nombre del metodo sera GetIVA
5. Para poder accede a la clase se necesita consulta vamos
6. agregar una nueva clase CADIVA colocarla publica
public class CADIVA
{
public int IdIVA { get; set; }
public string Descripcion { get; set; }
public float Tarifa { get; set; }
private static IVATableAdapter adaptador = new IVATableAdapter();
public static CADIVA GetIva(int IdIVA)
{
CADIVA miIVA = null;
dsAplicacionComercial.IVADataTable miTabla = adaptador.GetIVA(IdIVA);
if (miTabla.Rows.Count == 0) return miIVA;
dsAplicacionComercial.IVARow miRegistro = (dsAplicacionComercial.IVARow)
miTabla.Rows[0];
miIVA = new CADIVA();
miIVA.Descripcion = miRegistro.Descripcion;
miIVA.IdIVA = miRegistro.IdIVA;
miIVA.Tarifa = (float)miRegistro.Tarifa;
return miIVA;
}
}

7.
errorProvider1.Clear();
}
CADIVA miIVA = CADIVA.GetIva(ultimoProducto.IdIVA);
DetalleCompra miDetalle = new DetalleCompra();
miDetalle.Cantidad = cantidad;
miDetalle.Costo = costo;
miDetalle.Descripcion = ultimoProducto.Descripcion;
miDetalle.IdProducto = ultimoProducto.IdProducto;
miDetalle.PorcentajeDescuento = porcentajeDescuento;
miDetalle.PorcentajeIVA = miIVA.Tarifa; PARA QUE TOME TARIFA EN DECIMAL

8. Como el % se maneja como decimal se hace lo ste


errorProvider1.Clear();
porcentajeDescuento /=100;
}
CADIVA miIVA = CADIVA.GetIva(ultimoProducto.IdIVA);
DetalleCompra miDetalle = new DetalleCompra();

9. Lo que se areglo anteriormete con respect al campo notas e imagen que se coloca
return en vez del codigo largo se daa cada vez que se agrega un metodo por lo
tanto es necesario hacer lo siguiente vamos al dataset del CAD seleccionamos

campo notas e imagen en sus propiedades canbiar la opcion de nullvalue que es


(Throw exception) por la opcion (empty)
10. probar
Video 13.1 Compras parte 7

1. lo pintado en la cuadricula se tiene en una clase llamada detalleCompra


2. no todos los atributos de la clase deben ser genericos se pueden crear atributos
que se calculen en relacion a otros preexistentes se crea otras property en la clase
public float PorcentajeDescuento { get; set; }
public decimal ValorBruto { get {return Costo*(decimal)Cantidad;} } //valor a pagar sin IVA
y sin descuento el cual no tiene set
public decimal ValorIVA { get { return ValorBruto*(decimal) PorcentajeIVA; } } //como uno
es decimal y el otro es float se debe castear
public decimal ValorDescuento { get { return ValorBruto * (decimal) PorcentajeDescuento; }
}
public decimal ValorNeto { get { return ValorBruto + ValorIVA - ValorDescuento;} }
3.

hacer mtodo refrecarGrid()


misDetalles.Add(miDetalle);
RefrescaGrid();
private void RefrescaGrid()
{
DetalleDataGridView.DataSource = null;
DetalleDataGridView.DataSource = misDetalles;
PersonalizaGrid(); // adicionarlo despus de crear mtodo personalizaGrid
}

4. personalizar cuadricula por codigo


misDetalles.Add(miDetalle);
RefrescaGrid();
PersonalizaGrid();
private void PersonalizaGrid()
{
DetalleDataGridView.Columns["IdProducto"].HeaderText = "Id Producto";
DetalleDataGridView.Columns["IdProducto"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DetalleDataGridView.Columns["IdProducto"].Width = 80;
DetalleDataGridView.Columns["Descripcion"].HeaderText = "Descripcin";
DetalleDataGridView.Columns["Descripcion"].Width = 200;
DetalleDataGridView.Columns["Costo"].HeaderText = "Costo";
DetalleDataGridView.Columns["Costo"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DetalleDataGridView.Columns["Costo"].DefaultCellStyle.Format = "C2";
DetalleDataGridView.Columns["Costo"].Width = 80;
DetalleDataGridView.Columns["Cantidad"].HeaderText = "Cantidad";
DetalleDataGridView.Columns["Cantidad"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DetalleDataGridView.Columns["Cantidad"].DefaultCellStyle.Format = "N2";
DetalleDataGridView.Columns["Cantidad"].Width = 80;
DetalleDataGridView.Columns["PorcentajeIVA"].HeaderText = "Porcentaje IVA";
DetalleDataGridView.Columns["PorcentajeIVA"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DetalleDataGridView.Columns["PorcentajeIVA"].DefaultCellStyle.Format = "P2";

DetalleDataGridView.Columns["PorcentajeIVA"].Width = 80;
DetalleDataGridView.Columns["PorcentajeDescuento"].HeaderText = "Porcentaje
Descuento";
DetalleDataGridView.Columns["PorcentajeDescuento"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DetalleDataGridView.Columns["PorcentajeDescuento"].DefaultCellStyle.Format =
"P2";
DetalleDataGridView.Columns["PorcentajeDescuento"].Width = 80;
DetalleDataGridView.Columns["ValorBruto"].HeaderText = "Valor Bruto";
DetalleDataGridView.Columns["ValorBruto"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DetalleDataGridView.Columns["ValorBruto"].DefaultCellStyle.Format = "C2";
DetalleDataGridView.Columns["ValorBruto"].Width = 80;
DetalleDataGridView.Columns["ValorIVA"].HeaderText = "Valor IVA";
DetalleDataGridView.Columns["ValorIVA"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DetalleDataGridView.Columns["ValorIVA"].DefaultCellStyle.Format = "C2";
DetalleDataGridView.Columns["ValorIVA"].Width = 80;
DetalleDataGridView.Columns["ValorDescuento"].HeaderText = "Valor Descuento";
DetalleDataGridView.Columns["ValorDescuento"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DetalleDataGridView.Columns["ValorDescuento"].DefaultCellStyle.Format = "C2";
DetalleDataGridView.Columns["ValorDescuento"].Width = 80;
DetalleDataGridView.Columns["ValorNeto"].HeaderText = "Valor Neto";
DetalleDataGridView.Columns["ValorNeto"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DetalleDataGridView.Columns["ValorNeto"].DefaultCellStyle.Format = "C2";
DetalleDataGridView.Columns["ValorNeto"].Width = 80;
}
5. QUITAR /100 DE %IVA

Video 13.2 Compras parte 8

1. Anchor de botnes buscar bodega y proveedor y la imagen Top, Right


2. Anchor de combobox Top, Right, left
3. Hacer opcin totalizar debajo de la gv colocamos un label llamar totales
(valor bruto, iva, descuento y neto
4. Definirle al formulario compras 4 propiedades que sern esos totales
List<DetalleCompra> misDetalles = new List<DetalleCompra>();
CADProducto ultimoProducto = null;
private CADUsuario usuarioLogueado;
private decimal totalBruto = 0;
private decimal totalDescuento = 0;
private decimal totalIVA = 0;
private decimal totalNeto = 0

5. Cuando el usuario adicione un pto aparte de que ingrese a la cuadricula se


refrescan totales
miDetalle.PorcentajeIVA = miIVA.Tarifa;
totalBruto += miDetalle.ValorBruto;
totalIVA += miDetalle.ValorIVA;
totalDescuento += miDetalle.ValorDescuento;
totalNeto += miDetalle.ValorNeto; quitarlo de aqu
misDetalles.Add(miDetalle);

6.

Crear en el formulario 4 textbox para mostrar totales con readonly en true y anchor
Bottom, Right y colocarle nombres a los textbox
private void RefrescaGrid()

{
totalBruto = 0;
totalDescuento = 0;
totalIVA = 0;
totalNeto = 0;
DetalleDataGridView.DataSource = null;
DetalleDataGridView.DataSource = misDetalles;
foreach (DetalleCompra miDetalle in misDetalles)
{
totalBruto += miDetalle.ValorBruto;
totalIVA += miDetalle.ValorIVA;
totalDescuento += miDetalle.ValorDescuento;
totalNeto += miDetalle.ValorNeto;
}

TotalBrutoTextBox.Text = string.Format("{0:C2}", totalBruto);


TotalIVATextBox.Text = string.Format("{0:C2}", totalIVA);
TotalDescuentoTextBox.Text = string.Format("{0:C2}", totalDescuento);
TotalNetoTextBox.Text = string.Format("{0:C2}", totalNeto);
PersonalizaGrid();

7. Definir propiedad textAlig de los textbox en right


8. Probar
9. Crear botn para grabar compra eso afecta 4 tablas compra, detallecompra,
bodegapto, Kardex
10. Crear dos botones

Video 13.3 Compras parte 9


1. Agregar botones de grabar y cancelar
2. Hacer codigo de guardar se valida que este un proveedor y bodega,
minimo haya un pto
3. Codigo para cancelar
private void CancelarButton_Click(object sender, EventArgs e)
{
this.Close();
}
4. Codigo para guardar
private void GrabarButton_Click(object sender, EventArgs e)
{
if (ProveedorComboBox.SelectedIndex == -1)
{
errorProvider1.SetError(ProveedorComboBox, "Debe seleccionar un
proveedor");
ProveedorComboBox.Focus();
return;
}
errorProvider1.Clear();

if (BodegaComboBox.SelectedIndex == -1)
{
errorProvider1.SetError(BodegaComboBox, "Debe seleccionar una
bodega");
BodegaComboBox.Focus();
return;
}
errorProvider1.Clear();
if (misDetalles.Count==0)
{
errorProvider1.SetError (ProductoTextBox, "Debe ingresar productos en la
compra");
ProductoTextBox.Focus();
return;
}
errorProvider1.Clear();
}

5. PREGUNTAR SI SE ESTA SEGURO DE GUARDAR


errorProvider1.Clear();
DialogResult rta = MessageBox.Show("Es seguro que querer grabar la
compra?",
"Confirmacin", MessageBoxButtons.YesNo, MessageBoxIcon.Question,
MessageBoxDefaultButton.Button2);
if (rta == DialogResult.No) return;
6. Probar

7. Vamos al ds y arrastramos tabla compra xompradetalle y Kardex


8. Agregar un registro a la tabla compra con la fecha de la compra y con el
proveedor y bodega seleccionada, el da un num de compra que toca
guardarlo ya que se liga a compraDetalle agregar consulta insert
Video 13.4 Compras parte 10
1. INSERT INTO [dbo].[Compra] ([Fecha], [IdProveedor], [IdBodega]) VALUES
(@Fecha, @IdProveedor, @IdBodega);
SELECT IdCompra, Fecha, IdProveedor, IdBodega FROM Compra WHERE
(IdCompra = SCOPE_IDENTITY()) ese scope significa que devuelve el
ultimo registro insertado
2. Creamos el CADCompra que la colocamos public
public class CADCompra
{
private static CompraTableAdapter adaptador = new CompraTableAdapter();
public static int InsertCompra(DateTime Fecha, int IdProveedor, int IdBodega)
{
return (int) adaptador.InsertCompra(Fecha, IdProveedor, IdBodega);
}
}
3. Vamos a opcin grabar
int IDBodega = (int)BodegaComboBox.SelectedValue;
int IDProveedor = (int) ProveedorComboBox.SelectedValue; // se hace para no estarlo
casteando a cada rato

//grabamos cencabezado de la compra


int IDCompra = CADCompra.InsertCompra(FechaDateTimePicker.Value,
IDProveedor, IDBodega);
//grabamos detalle de la compra recorrer la lista
foreach (DetalleCompra miDetalle in misDetalles)
{
//consultar saldo de pto en una bodega hacer un metodo que nos devuelva detalle
de un pto en una bodega con el metodo getbodegaProductoBIdpto que nos devuelva
el dellae en esa bodega de un pto
CADBodegaProducto miBodegaProducto =
CADBodegaProducto.GetBodegaProductoByIdBodegaAndIdProducto(IDBodega,
miDetalle.IdProducto);

if(miBodegaProducto != null) //actualizamos bodegaPto


{
stock = miBodegaProducto.Stock;
} // CAMBIA MAS ABAJO

Video 13.5 Compras parte 11


1. En la tabla bodegapto hay un mtodo update que actualiza todos los
campos pero yo no quiero que me actualice todos si no solo el stock
entonces creamos un nuevo mtodo tambin de update que actualice el
stock con lo que tenga en el momento mas el nuevo stock
UPDATE [dbo].[BodegaProducto] SET
[Stock] = [Stock] + @Cantidad
WHERE [IdBodega] = @IdBodega AND [IdProducto] = @IdProducto
llamado aumentarStock
2. En el CADBodegaProducto colocamos
public static void AumentarStock(double Cantidad,int IdBodega, int IdProducto)
{
adapter.AumentarStock(Cantidad,IdBodega,IdProducto);
}
3. En la tabla compras en grabar
if (miBodegaProducto == null) //actualizamos bodegaPto
{
CADBodegaProducto.UpdateBodegaProducto(IDBodega, miDetalle.IdProducto, 1, 1,
1, 1);
}
CADBodegaProducto.AumentarStock(miDetalle.Cantidad, IDBodega,
miDetalle.IdProducto); //HUBO CAMBIOS CON RESPECTO A ESTE CODIGO
4. PROBAR MIRAR TABLA DE PTO LOS PARAMETROS BODEGA Y LUEGO HACER COMPRA
GRABARLA Y VOLVER A MIRAR LOS NUEVOS PARAMETROS BODEGA

Video 14 Compras parte 12


1. Tabla Excel explicar costo prom
Fecha

Producto

entrada

Salida

Saldo

Ultimo
costo

Costo
promedio

13 sept
14 sept
15 sept

Mango
Mango
Mango

10
10
20
37

10
20
40
77

1000
1000
2000
1345.78

1000
1000
1500
1425.89

Ejemplo hasta 14 sep


Saldo ant* cosro prom
Ultima entrada* ultimo
costo
suma de totales
Costo prom

20*1000 = 20000
20*2000 = 40000
20000 + 40000 =
60000 y 20+20= 40
60000/40= 1500

Ejemplo hasta 15 sept


Saldo ant* cosro prom
Ultima entrada* ultimo
costo
suma de totales

Costo prom

40* 1500 = 60000


37* 1345.78 =
49793.86
60000 + 49,793.86 =
109,793.86
40+37=77
109,793.86/77 =
1425.89

2. Registrar a mano registros ejemplo en Kardex en sql


3. Mtodo que devuelva ultimo valor del Kardex
4. En ds aplicacin CAD en tabla Kardex y hacer consuta que de ultimo
registro de cada Kardex
Video 14.1 Compras parte 13
1. Consulta con subconsulta sql
SELECT * FROM Kardex
WHERE IdBodega = 1 AND IdProducto = 99 AND IdKardex = (SELECT
MAX(IdKardex) FROM Kardex WHERE IdBodega = 1 AND IdProducto = 99
AND IdProducto = 99)
2. Crear en la tabla Kardex consulta llamada ultimoKardex select que
devuelve filas
SELECT IdKardex, IdBodega, IdProducto, Fecha, Documento, Entrada,
Salida, Saldo, UltimoCosto, CostoPromedio FROM dbo.Kardex
WHERE IdBodega = @IdBodega AND IdProducto = @IdProducto AND
IdKardex = (SELECT MAX(IdKardex) FROM Kardex WHERE IdBodega =
@IdBodega AND IdProducto = @IdProducto)
3. Crear CADKardex colocarla publica y hacer mtodo que devulva todos
los campos de la tabla Kardex empaquetados
public class CADKardex
{
public int IdKardex { get; set; }
public int IdBodega { get; set; }

public
public
public
public
public
public
public
public

int IdProducto { get; set; }


DateTime Fecha { get; set; }
string Documento { get; set; }
float Entrada { get; set; }
float Salida { get; set; }
float Saldo { get; set; }
decimal UltimoCosto { get; set; }
decimal CostoPromedio { get; set; }

private static KardexTableAdapter adaptador = new KardexTableAdapter();


public static CADKardex UltimoKardex(int IdBodega, int IdProducto)
{
CADKardex miKardex = null;
dsAplicacionComercial.KardexDataTable miTabla =
adaptador.UltimoKardex(IdBodega, IdProducto);
if (miTabla.Rows.Count == 0) return miKardex;
dsAplicacionComercial.KardexRow miRegistro =
(dsAplicacionComercial.KardexRow)miTabla.Rows[0];
miKardex = new CADKardex();
miKardex.CostoPromedio = miRegistro.CostoPromedio;
miKardex.Documento = miRegistro.Documento;
miKardex.Entrada = (float)miRegistro.Entrada;
miKardex.Fecha = miRegistro.Fecha;
miKardex.IdBodega = miRegistro.IdBodega;
miKardex.IdKardex = miRegistro.IdKardex;
miKardex.IdProducto = miRegistro.IdProducto;
miKardex.Saldo = (float)miRegistro.Saldo;
miKardex.Salida =(float) miRegistro.Salida;
miKardex.UltimoCosto = miRegistro.UltimoCosto;
return miKardex;
}

4. En la opcin grabar del formulario compras

CADBodegaProducto.AumentarStock(miDetalle.Cantidad, IDBodega,
miDetalle.IdProducto);
// actualizamos el kardex
CADKardex miKardex = CADKardex.UltimoKardex(IDBodega,
miDetalle.IdProducto);
if (miKardex == null)
{
}

Video 14.2 Compras parte 14


1. Continuando con lo anterior agregando mtodo de insert en Kardex
agregar consulta insert llamamos InsertKardex esta consulta inserta el
registro y luego devuelve codigo de Kardex
INSERT INTO [dbo].[Kardex] ([IdBodega], [IdProducto], [Fecha],
[Documento], [Entrada], [Salida], [Saldo], [UltimoCosto],
[CostoPromedio]) VALUES (@IdBodega, @IdProducto, @Fecha,
@Documento, @Entrada, @Salida, @Saldo, @UltimoCosto,
@CostoPromedio);
SELECT IdKardex FROM Kardex WHERE (IdKardex = SCOPE_IDENTITY())

2. Para usarlo en el cadKardex colocamos lo ste


public static int InsertKardex(int IdBodega, int IdProducto, DateTime Fecha, string
Documento,
float Entrada, float Salida, float Saldo, decimal UltimoCosto, decimal
CostoPromedio)
{
return (int) adaptador.InsertKardex(IdBodega, IdProducto, Fecha, Documento,
Entrada, Salida,
Saldo, UltimoCosto, CostoPromedio);
}

3. En compras usamos el mtodo InsertKardex


int IdKardex;
float nuevoSaldo;
decimal nuevoCostoPromedio;
decimal nuevoUltimoCosto; //adiciona despues
if (miKardex == null)
{
nuevoSaldo = miDetalle.Cantidad;
nuevoCostoPromedio = miDetalle.Costo;
nuevoUltimoCosto = nuevoCostoPromedio;
}
else
{
nuevoSaldo = miKardex.Saldo + miDetalle.Cantidad;
nuevoCostoPromedio = (miKardex.CostoPromedio * (decimal) miKardex.Saldo +
miDetalle.ValorNeto)/(decimal)nuevoSaldo;
nuevoUltimoCosto = miDetalle.ValorNeto / (decimal) miDetalle.Cantidad;
}

IdKardex = CADKardex.InsertKardex(IDBodega, miDetalle.IdProducto,


Fecha, string.Format("CO-{0}", IDCompra), miDetalle.Cantidad, 0,
nuevoSaldo, nuevoUltimoCosto, nuevoCostoPromedio);

4. Para la fecha no estarla calculando creamos la ste variable

//grabamos cencabezado de la compra


int IDCompra = CADCompra.InsertCompra(FechaDateTimePicker.Value,
IDProveedor, IDBodega);
DateTime Fecha = FechaDateTimePicker.Value;

5. AHORA CODIGO DE COMPRADETALLE vamos al ds para crear mtodo y


arrastramos tabla compraDDetalle
INSERT INTO [dbo].[CompraDetalle] ([IdCompra], [IdProducto],
[Descripcion], [Costo], [Cantidad], [IdKardex], [PorcentajeIVA],
[PorcentajeDescuento]) VALUES (@IdCompra, @IdProducto,
@Descripcion, @Costo, @Cantidad, @IdKardex, @PorcentajeIVA,
@PorcentajeDescuento)
6. // actualizamos compra detalleAgregar la clase CADCompraDetalle
private static CompraDetalleTableAdapter adaptador = new
CompraDetalleTableAdapter();

public static void InsertCompraDetalle(int IdCompra, int IdProducto,string


Descripcion,

decimal Costo,float Cantidad, int IdKardex, float PorcentajeIVA, float


PorcentajeDescuento)
{
adaptador.InsertCompraDetalle(IdCompra, IdProducto, Descripcion,
Costo, Cantidad, IdKardex, PorcentajeIVA, PorcentajeDescuento);
}

Video 14.3 Compras parte 15


1. En el formulario de compras

// actualizamos compra detalle


CADCompraDetalle.InsertCompraDetalle(IDCompra,
miDetalle.IdProducto, miDetalle.Descripcion,
miDetalle.Costo, miDetalle.Cantidad,
IdKardex, miDetalle.PorcentajeIVA, miDetalle.PorcentajeDescuento);

2. Inicializamos el formulario para que quede listo para la ste compra

miDetalle.Costo, miDetalle.Cantidad,
IdKardex, miDetalle.PorcentajeIVA, miDetalle.PorcentajeDescuento);
}

totalBruto = 0;
totalDescuento = 0;
totalIVA = 0;
totalNeto = 0;

MessageBox.Show(string.Format("La compra: {0}, fue grabada de forma exitosa",


IDCompra), "Confirmacin", MessageBoxButtons.OK, MessageBoxIcon.Information);
ProveedorComboBox.SelectedIndex = -1;
BodegaComboBox.SelectedIndex = -1;
misDetalles.Clear();
RefrescaGrid();
ProveedorComboBox.Focus();

3. Limpiar registros basura si la bd los tiene en lo que tiene que ver con inventario
hacer consulta en sql con este codigo

delete from CompraDetalle;


DELETE From Compra;
DELETE FROM Kardex;
UPDATE BodegaProducto SET Stock = 0
DBCC CHECKIDENT (CompraDetalle, RESEED, 0)
DBCC CHECKIDENT (Compra, RESEED, 0)
DBCC CHECKIDENT (Kardex, RESEED, 0)

4. Probar
Video 15 Compras parte 16
1. Cosas para corregir
- Botn de eliminar uno o todas las compras
- Corregir lo del cambio de posicin
- Imgenes

- Validacin de borrado con movimiento


2. Adicionamos botones al formulario compras de borrar lnea y borrar todo
3. Codigo de botn borrarTodo

private void BorrarTodoButton_Click(object sender, EventArgs e)


{
errorProvider1.Clear();
if(misDetalles.Count ==0) return;
DialogResult rta = MessageBox.Show("Est seguro de borrar todas las lneas de la
compra?",
"Confirmacin", MessageBoxButtons.YesNo, MessageBoxIcon.Question,
MessageBoxDefaultButton.Button2);
if (rta == DialogResult.No) return;
misDetalles.Clear();
RefrescaGrid();
}

4. Probar
5. BORRAR LINEA CODDIGO
SI HAY UNA LINEA SELECCIONADA ESA SE BORRA Y SI NO SE BORRA EN
ORDEN

private void BorrarLineaButton_Click(object sender, EventArgs e)


{
errorProvider1.Clear();
if (misDetalles.Count == 0) return;
if (DetalleDataGridView.SelectedRows.Count == 0)
{
misDetalles.RemoveAt(misDetalles.Count - 1);
RefrescaGrid();
pbxImagen.Image = null;
}
}

6. Cargar evento al formulario formclosing


private void frmCompras_FormClosing(object sender, FormClosingEventArgs e)
{
if (misDetalles.Count != 0)
{
DialogResult rta = MessageBox.Show("Est seguro de cerrar el formulario y
perder los registros ingresados?",
"Confirmacin", MessageBoxButtons.YesNo, MessageBoxIcon.Question,
MessageBoxDefaultButton.Button2);
}
}

Video 15.1 Correcciones varias parte 1


1. Terminamos 1er areglo
DialogResult rta = MessageBox.Show("Est seguro de cerrar el formulario de compra y
perder los registros ingresados?",
"Confirmacin", MessageBoxButtons.YesNo, MessageBoxIcon.Question,
MessageBoxDefaultButton.Button2);

if (rta == DialogResult.No) ;
{
e.Cancel = true;

2. El otro areglo es lo de corregir cambio posicin en form pto llega un momento que
no actualiza parmetros de bodega se activa evento alboton ptobindingsource
positionchanged y colocamos ste

private void productosBindingSource_PositionChanged(object sender, EventArgs e)


{
LlenarGrillas();
CargarImagen();
}
Y se puede quitar esos dos eventos de los botones de movimiento arriba y el evento
llenargillas hacerle este areglo
private void LlenarGrillas()
{
if (idProductoTextBox.Text == string.Empty) return;
// TODO: esta lnea de cdigo carga datos en la tabla 'dSAplicacionComercial.Barra'
Puede moverla o quitarla segn sea necesario.
this.barraTableAdapter.FillBy1(this.dSAplicacionComercial.Barra,
Convert.ToInt32(idProductoTextBox.Text));
// TODO: esta lnea de cdigo carga datos en la tabla
'dSAplicacionComercial.BodegaProducto' Puede moverla o quitarla segn sea necesario.
this.bodegaProductoTableAdapter.FillBy(this.dSAplicacionComercial.BodegaProducto,
Convert.ToInt32(idProductoTextBox.Text));

3. Aregla ruta imgenes que no salga toda


private void btnBuscarImagen_Click(object sender, EventArgs e)
{
openFileDialog1.ShowDialog();
imagenTextBox.Text = openFileDialog1.SafeFileName; //agregar esa palabra
pbxImagen.Load(imagenTextBox.Text); ELIMINA
CargarImagen();
}

4. Mtodo cargar imagen hacerle cambio


private void CargarImagen()
{
if (imagenTextBox.Text == string.Empty)
{
pbxImagen.Image = null;
}
else
{
if (File.Exists("Images\\" +imagenTextBox.Text))
{
pbxImagen.Load("Images\\" +imagenTextBox.Text);
}

5. Cambiar ruta donde estn guardadas imgenes de los productos a


apcom/apcome/bin/debug/images
Video 15.2 Correcciones varias parte 2
1. Para q no se reviente la aplicacin uando se borra pto o prov con
compras vamos al ds para crear dos consultas que devuelve un solo
valor
SELECT TOP 1 1 FROM Compra WHERE IdProveedor = @IdProveedor llamada
ProveedorTieneCompras
2. Para Kardex
SELECT TOP 1 1 FROM Kardex WHERE IdProducto = @IdProducto llama
KardexTieneMovimientoPorIdProducto y validar bodegas dentro de Kardex
SELECT TOP 1 1 FROM Kardex WHERE IdBodega = @IdBodega llamada
KardexTieneMovimientoPorIdBodega
3. Utilizar consultas vamos all CADCompra crea un mtodo
public static bool ProveedorTieneCompras(int IdProveedor)

if (adaptador.ProveedorTieneCompras(IdProveedor) == null)
{
return false;
}
return true;

4. Cadkardex

ublic static bool KardexTieneMovimientoPorIdProducto(int IdProducto)


{
if (adaptador.KardexTieneMovimientoPorIdProducto(IdProducto) == null)
{
return false;
}
return true;
}

public static bool KardexTieneMovimientoPorIdBodega(int IdBodega)


{
if (adaptador.KardexTieneMovimientoPorIdBodega(IdBodega) == null)
{
return false;
}
return true;
}

5. En proveedores antes de borrar


if (rta == DialogResult.No) return;
if (CADCompra.ProveedorTieneCompras(Convert.ToInt32(iDProveedorTextBox.Text)))
{
MessageBox.Show("No se puede borrar proveedor porque ya tiene movimientos",
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}

6. Lo mismo bodegas antes confirmar borrar


if (rta == DialogResult.No) return;
if
(CADKardex.KardexTieneMovimientoPorIdBodega(Convert.ToInt32(idBodegaTextBox.Text)))
{
MessageBox.Show("No se puede borrar bodega porque ya tiene movimientos",
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}

Video 15.3 Correcciones varias parte 3


1. Y en pto lo mismo
if (rta == DialogResult.No) return;

if (CADKardex.KardexTieneMovimientoPorIdProducto
(Convert.ToInt32(idProductoTextBox.Text)))
{
MessageBox.Show("No se puede borrar producto porque ya tiene movimientos",
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
productosBindingSource.RemoveAt(productosBindingSource.Position);
this.tableAdapterManager.UpdateAll(this.dSAplicacionComercial);

2. Cuando un pto tiene cod de barras y parmetros de bodega pero no


tiene movimientos (compras) y no se reviente la aplicacin al intentar
borrarlo se hace lo ste ir al ds y agregar un nuevo proc almacenado en la
tabla barras para borrar
DELETE FROM [dbo].[Barra] WHERE [IdProducto] = @IdProducto llamado
DeleteBarraByIdProducto
3. En la tabla bodegaProducto tambin creamos un nuevo delete
DELETE FROM [dbo].[BodegaProducto] WHERE [IdProducto] = @IdProducto
llamado DeleteBodegaProductoByIdProducto
4. Implementar las consultas en el CADBarra

public static void DeleteBarraByIdProducto(int IdProducto)


{
adapter.DeleteBarraByIdProducto(IdProducto);
}
5. Y lo mismo en el cadBodegaPto

public static void DeleteBodegaProductoByIdProducto(int IdProducto)


{
adapter.DeleteBodegaProductoByIdProducto(IdProducto);
}

6. En el formulario pto en el botn borrar usamos los mtodos creados

CADBarra.DeleteBarraByIdProducto(Convert.ToInt32(idProductoTextBox.Text));
CADBodegaProducto.DeleteBodegaProductoByIdProducto(Convert.ToInt32(idProductoTextBo
x.Text));
productosBindingSource.RemoveAt(productosBindingSource.Position);
this.tableAdapterManager.UpdateAll(this.dSAplicacionComercial);
CargarImagen();

Video 15.4 Ventas parte 2


1. Se quiere que el pto salga ya con IVA incluido entonces en
CADDetalleCompra se hacen cambios a las formulas

public decimal ValorBruto { get {return Costo*(decimal)Cantidad/(1 + (decimal)


PorcentajeIVA);} } //valor a pagar con IVA y sin descuento el cual no tiene set
public decimal ValorIVA { get { return Costo * (decimal)Cantidad - ValorBruto; } }
//como uno es decimal y el otro es float se debe castear

public decimal ValorDescuento { get { return (ValorBruto + ValorIVA) * (decimal)


PorcentajeDescuento; } }
public decimal ValorNeto { get { return Costo * (decimal)Cantidad ValorDescuento; } }

2. Con respecto Kardex un areglo

nuevoSaldo = miDetalle.Cantidad;
nuevoCostoPromedio = miDetalle.ValorNeto / (decimal)miDetalle.Cantidad;

nuevoSaldo = miKardex.Saldo + miDetalle.Cantidad;


nuevoCostoPromedio = (miKardex.CostoPromedio * (decimal) miKardex.Saldo +
miDetalle.ValorNeto) /(decimal)nuevoSaldo;

3. Limpiar INVENTARIO CON UN PROC

CREATE PROCEDURE InicializarInventario AS


DELETE FROM CompraDetalle;
DELETE FROM Compra;
DELETE FROM Kardex;
UPDATE BodegaProducto SET Stock = 0
DBCC CHECKIDENT (CompraDetalle, RESEED, 0)
DBCC CHECKIDENT (Compra, RESEED, 0)
DBCC CHECKIDENT (Kardex, RESEED, 0)
4. EXEC InicializarInventario

5. Empezar con ventas


6. Para hacer barra de hmientas de acceso rpido ,mas grande coger cada
icono y en la propiedad ImageScaling ponerla en none pero para
esoasegurar bajar todos los iconos del mismo tamao
Video 15.5 Ventas parte 3
1. Copiamos todo el formulario de compras le cambiamos nombres en vez
de proveedor seria cliente en vez de costo precio que se coloca readonly:
true
2. Configuramos combobox de cliente y bodega
3. Cuando se hace load alformulario
this.clienteTableAdapter.Fill(this.dSAplicacionComercial.Cliente);
ClienteComboBox.SelectedIndex = -1;
BodegaComboBox.SelectedIndex = -1;
ProductoLabel.Text = string.Empty;

4. En el botn de buscar cliente y buscar bodega y buscar pto


private void BuscarClienteButton_Click(object sender, EventArgs e)
{
frmBusquedaClientes miBusqueda = new frmBusquedaClientes();
miBusqueda.ShowDialog();
if (miBusqueda.IDCliente == 0) return;
ClienteComboBox.SelectedValue = miBusqueda.IDCliente;
}

5. En ventas activar cevento validating al textbox ptos y copiar lo mismo de compras


private void ProductoTextBox_Validating(object sender, CancelEventArgs e)
{
if (ProductoTextBox.Text == string.Empty)
{
errorProvider1.SetError(ProductoTextBox, "Debe ingresar un Id de producto o un
cdigo de barras");
return;
}
errorProvider1.Clear();
long producto;
if (!long.TryParse(ProductoTextBox.Text, out producto))
{
errorProvider1.SetError(ProductoTextBox, "Debe ingresar un valor numrico
entero");
return;
}
errorProvider1.Clear();
if (producto <= 0)
{
errorProvider1.SetError(ProductoTextBox, "Debe ingresar un valor mayor a 0");
return;
}
errorProvider1.Clear();
CADProducto miProducto = CADProducto.GetProductoByIdProducto((int)producto);
if (miProducto == null) // no lo encontro como codigo de pto
{
miProducto = CADProducto.GetProductoByBarra(producto);
}
if (miProducto == null) // no esta en bd
{
errorProvider1.SetError(ProductoTextBox, "Producto no existe");
ProductoLabel.Text = string.Empty;
pbxImagen.Image = null;
ultimoProducto = null;
}
else
{
ProductoLabel.Text = miProducto.Descripcion;
ultimoProducto = miProducto;
if (miProducto.Imagen != string.Empty)

if (File.Exists("Images\\" + miProducto.Imagen))
{
pbxImagen.Load("Images\\" + miProducto.Imagen);
}
else
{
pbxImagen.Image = null;
}

}
else
{
pbxImagen.Image = null;
}
}

6. Saca error por errorProveder que se aade al form ventas y por la variable ultimoPto
que toca definirla al inicio del formulario comose hizo en compras en el load de vtas

private CADUsuario usuarioLogueado;


public CADUsuario UsuarioLogueado
{
get { return usuarioLogueado; }
set { usuarioLogueado = value; }
}
CADProducto ultimoProducto = null;

7. probar
8. adicionar para que salga precio
else
{

pbxImagen.Image = null;

}
}
PrecioTextBox.Text = string.Format("{0:C2}", ultimoProducto.Precio);

9. creamos nueva clase en el proy apcom llamada DetalleVta


class DetalleVenta
{
public int IdProducto { get; set; }
public string Descripcion { get; set; }
public decimal Precio { get; set; }
public float Cantidad { get; set; }
public float PorcentajeIVA { get; set; }
public float PorcentajeDescuento { get; set; }
public decimal ValorBruto { get { return Precio * (decimal)Cantidad / (1 +
(decimal)PorcentajeIVA); } } //valor a pagar con IVA y sin descuento el cual no tiene set

public decimal ValorIVA { get { return Precio * (decimal)Cantidad - ValorBruto; } }


//como uno es decimal y el otro es float se debe castear
public decimal ValorDescuento { get { return (ValorBruto + ValorIVA) *
(decimal)PorcentajeDescuento; } }
public decimal ValorNeto { get { return Precio * (decimal)Cantidad ValorDescuento; } }
}

10.crear la lista detalleVenta


private CADUsuario usuarioLogueado;
CADProducto ultimoProducto = null;
List<DetalleVenta> misDetalles = new List<DetalleVenta>();
class DetalleVenta
{
public int IdProducto { get; set; }
public string Descripcion { get; set; }
public decimal Precio { get; set; }
public float Cantidad { get; set; }
public float PorcentajeIVA { get; set; }
public float PorcentajeDescuento { get; set; }
public decimal ValorBruto { get { return Precio * (decimal)Cantidad / (1 +
(decimal)PorcentajeIVA); } } //valor a pagar con IVA y sin descuento el cual no tiene set
public decimal ValorIVA { get { return Precio * (decimal)Cantidad - ValorBruto; } }
//como uno es decimal y el otro es float se debe castear
public decimal ValorDescuento { get { return (ValorBruto + ValorIVA) *
(decimal)PorcentajeDescuento; } }
public decimal ValorNeto { get { return Precio * (decimal)Cantidad ValorDescuento; } }
}

11.todo el codigo de ventas


private CADUsuario usuarioLogueado;
public CADUsuario UsuarioLogueado
{
get { return usuarioLogueado; }
set { usuarioLogueado = value; }
}
List<DetalleVenta> misDetalles = new List<DetalleVenta>();
CADProducto ultimoProducto = null;
private decimal totalBruto = 0;
private decimal totalDescuento = 0;
private decimal totalIVA = 0;
private decimal totalNeto = 0;
public frmVentas()
{
InitializeComponent();
}
private void frmVentas_Load(object sender, EventArgs e)
{
// TODO: esta lnea de cdigo carga datos en la tabla
'dSAplicacionComercial.Bodega' Puede moverla o quitarla segn sea necesario.

this.bodegaTableAdapter.Fill(this.dSAplicacionComercial.Bodega);
// TODO: esta lnea de cdigo carga datos en la tabla 'dSAplicacionComercial.Cliente'
Puede moverla o quitarla segn sea necesario.
this.clienteTableAdapter.Fill(this.dSAplicacionComercial.Cliente);
ClienteComboBox.SelectedIndex = -1;
BodegaComboBox.SelectedIndex = -1;
ProductoLabel.Text = string.Empty;
}
private void BuscarClienteButton_Click(object sender, EventArgs e)
{
frmBusquedaClientes miBusqueda = new frmBusquedaClientes();
miBusqueda.ShowDialog();
if (miBusqueda.IDCliente == 0) return;
ClienteComboBox.SelectedValue = miBusqueda.IDCliente;
}
private void BuscarBodegaButton_Click(object sender, EventArgs e)
{
frmBusquedaBodegas miBusqueda = new frmBusquedaBodegas();
miBusqueda.ShowDialog();
if (miBusqueda.IDBodega == 0) return;
BodegaComboBox.SelectedValue = miBusqueda.IDBodega;
}
private void BuscarProductoButton_Click(object sender, EventArgs e)
{
frmBusquedaProductos miBusqueda = new frmBusquedaProductos();
miBusqueda.ShowDialog();
if (miBusqueda.IDProducto == 0) return;
ProductoTextBox.Text = miBusqueda.IDProducto.ToString();
ProductoTextBox_Validating(sender, new CancelEventArgs());
}
private void ProductoTextBox_Validating(object sender, CancelEventArgs e)
{
if (ProductoTextBox.Text == string.Empty)
{
errorProvider1.SetError(ProductoTextBox, "Debe ingresar un Id de producto o un
cdigo de barras");
return;
}
errorProvider1.Clear();
long producto;
if (!long.TryParse(ProductoTextBox.Text, out producto))
{
errorProvider1.SetError(ProductoTextBox, "Debe ingresar un valor numrico
entero");
return;
}
errorProvider1.Clear();
if (producto <= 0)

errorProvider1.SetError(ProductoTextBox, "Debe ingresar un valor mayor a 0");


return;

}
errorProvider1.Clear();

CADProducto miProducto = CADProducto.GetProductoByIdProducto((int)producto);


if (miProducto == null) // no lo encontro como codigo de pto
{
miProducto = CADProducto.GetProductoByBarra(producto);
}
if (miProducto == null) // no esta en bd
{
errorProvider1.SetError(ProductoTextBox, "Producto no existe");
ProductoLabel.Text = string.Empty;
pbxImagen.Image = null;
ultimoProducto = null;
}
else
{
ProductoLabel.Text = miProducto.Descripcion;
ultimoProducto = miProducto;
if (miProducto.Imagen != string.Empty)
{
if (File.Exists("Images\\" + miProducto.Imagen))
{
pbxImagen.Load("Images\\" + miProducto.Imagen);
}
else
{
pbxImagen.Image = null;
}
}
else
{
pbxImagen.Image = null;
}
}
PrecioTextBox.Text = string.Format("{0:C2}", ultimoProducto.Precio);
}
private void AgregarButton_Click(object sender, EventArgs e)
{
if (ultimoProducto == null) //significa que el ultimo pto no existia o no han buscado
nimgun pto
{
errorProvider1.SetError(ProductoTextBox, "Debe ingresar un producto");
ProductoTextBox.Focus();
return;
}
errorProvider1.Clear();
if (CantidadTextBox.Text == string.Empty)
{
errorProvider1.SetError(CantidadTextBox, "Debe ingresar una cantidad");
return;

}
errorProvider1.Clear();
float cantidad;
if (!float.TryParse(CantidadTextBox.Text, out cantidad))
{
errorProvider1.SetError(CantidadTextBox, "Debe ingresar un valor numrico");
return;
}
errorProvider1.Clear();
if (cantidad <= 0)
{
errorProvider1.SetError(CantidadTextBox, "Debe ingresar un valor mayor a 0");
return;
}
errorProvider1.Clear();
float porcentajeDescuento = 0;
if (PorcentajeDescuentoTextBox.Text != string.Empty)
{
if (!float.TryParse(PorcentajeDescuentoTextBox.Text, out porcentajeDescuento))
{
errorProvider1.SetError(PorcentajeDescuentoTextBox, "Debe ingresar un valor
numrico");
}
errorProvider1.Clear();
if (porcentajeDescuento < 0 && porcentajeDescuento > 100)
{
errorProvider1.SetError(PorcentajeDescuentoTextBox, "Debe ingresar un valor
mayor o igual a 0 y mennor o igual a 100");
return;
}
errorProvider1.Clear();
porcentajeDescuento /= 100;
}
CADIVA miIVA = CADIVA.GetIva(ultimoProducto.IdIVA);
DetalleVenta miDetalle = new DetalleVenta();
miDetalle.Cantidad = cantidad;
miDetalle.Descripcion = ultimoProducto.Descripcion;
miDetalle.IdProducto = ultimoProducto.IdProducto;
miDetalle.PorcentajeDescuento = porcentajeDescuento;
miDetalle.PorcentajeIVA = miIVA.Tarifa / 100;
misDetalles.Add(miDetalle);
RefrescaGrid();
//DetalleDataGridView.DataSource = null; //no esta
//DetalleDataGridView.DataSource = miDetalle; //no esta
//PersonalizaGrid(); //no esta
ultimoProducto = null;
ProductoTextBox.Text = string.Empty;
ProductoLabel.Text = string.Empty;

CantidadTextBox.Text = string.Empty;
PrecioTextBox.Text = string.Empty;
PorcentajeDescuentoTextBox.Text = string.Empty;
ProductoTextBox.Focus();
}

//pbxImagen.Image = null;

private void RefrescaGrid()


{
DetalleDataGridView.DataSource = null;
DetalleDataGridView.DataSource = misDetalles;
totalBruto = 0;
totalDescuento = 0;
totalIVA = 0;
totalNeto = 0;
foreach (DetalleVenta miDetalle in misDetalles)
{
totalBruto += miDetalle.ValorBruto;
totalIVA += miDetalle.ValorIVA;
totalDescuento += miDetalle.ValorDescuento;
totalNeto += miDetalle.ValorNeto;
}
TotalBrutoTextBox.Text = string.Format("{0:C2}", totalBruto);
TotalIVATextBox.Text = string.Format("{0:C2}", totalIVA);
TotalDescuentoTextBox.Text = string.Format("{0:C2}", totalDescuento);
TotalNetoTextBox.Text = string.Format("{0:C2}", totalNeto);
PersonalizaGrid();
}
private void PersonalizaGrid()
{
DetalleDataGridView.Columns["IdProducto"].HeaderText = "Id Producto";
DetalleDataGridView.Columns["IdProducto"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DetalleDataGridView.Columns["IdProducto"].Width = 80;
DetalleDataGridView.Columns["Descripcion"].HeaderText = "Descripcin";
DetalleDataGridView.Columns["Descripcion"].Width = 200;
DetalleDataGridView.Columns["Precio"].HeaderText = "Precio";
DetalleDataGridView.Columns["Precio"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DetalleDataGridView.Columns["Precio"].DefaultCellStyle.Format = "C2";
DetalleDataGridView.Columns["Precio"].Width = 80;
DetalleDataGridView.Columns["Cantidad"].HeaderText = "Cantidad";
DetalleDataGridView.Columns["Cantidad"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DetalleDataGridView.Columns["Cantidad"].DefaultCellStyle.Format = "N2";
DetalleDataGridView.Columns["Cantidad"].Width = 80;
DetalleDataGridView.Columns["PorcentajeIVA"].HeaderText = "Porcentaje IVA";
DetalleDataGridView.Columns["PorcentajeIVA"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DetalleDataGridView.Columns["PorcentajeIVA"].DefaultCellStyle.Format = "P2";
DetalleDataGridView.Columns["PorcentajeIVA"].Width = 80;

DetalleDataGridView.Columns["PorcentajeDescuento"].HeaderText = "Porcentaje
Descuento";
DetalleDataGridView.Columns["PorcentajeDescuento"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DetalleDataGridView.Columns["PorcentajeDescuento"].DefaultCellStyle.Format =
"P2";
DetalleDataGridView.Columns["PorcentajeDescuento"].Width = 80;
DetalleDataGridView.Columns["ValorBruto"].HeaderText = "Valor Bruto";
DetalleDataGridView.Columns["ValorBruto"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DetalleDataGridView.Columns["ValorBruto"].DefaultCellStyle.Format = "C2";
DetalleDataGridView.Columns["ValorBruto"].Width = 80;
DetalleDataGridView.Columns["ValorIVA"].HeaderText = "Valor IVA";
DetalleDataGridView.Columns["ValorIVA"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DetalleDataGridView.Columns["ValorIVA"].DefaultCellStyle.Format = "C2";
DetalleDataGridView.Columns["ValorIVA"].Width = 80;
DetalleDataGridView.Columns["ValorDescuento"].HeaderText = "Valor Descuento";
DetalleDataGridView.Columns["ValorDescuento"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DetalleDataGridView.Columns["ValorDescuento"].DefaultCellStyle.Format = "C2";
DetalleDataGridView.Columns["ValorDescuento"].Width = 80;
DetalleDataGridView.Columns["ValorNeto"].HeaderText = "Valor Neto";
DetalleDataGridView.Columns["ValorNeto"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DetalleDataGridView.Columns["ValorNeto"].DefaultCellStyle.Format = "C2";
DetalleDataGridView.Columns["ValorNeto"].Width = 80;
1.
}probar

INSERT INTO [dbo].[Venta] ([Fecha], [IdCliente], [IdBodega]) VALUES (@Fecha,


@IdCliente, @IdBodega);
SELECT IdVenta FROM Venta WHERE (IdVenta = SCOPE_IDENTITY())
INSERT INTO [dbo].[VentaDetalle] ([IdVenta], [IdProducto], [Descripcion],
[Precio], [Cantidad], [IdKardex], [PorcentajeIVA], [PorcentajeDescuento])
VALUES (@IdVenta, @IdProducto, @Descripcion, @Precio, @Cantidad,
@IdKardex, @PorcentajeIVA, @PorcentajeDescuento) llamado InsertVtaDetalle

Video 1 Re-kardex parte 1


1. Para que el Kardex sea consistente cuando se ingreses movimientos de
fechas anteriores vamos al CADKardex y creamos un nuevo mtodo se
recalcula el Kardex
2. Obtener registros de la tabla BodegaPto
3. Vamos a usar el getdato de bodegaPto en el CADBodegaPto colocamos
lo ste
public static dsAplicacionComercial.BodegaProductoDataTable GetData()
{
return adapter.GetData();
}

4. Hacemos el ste mtodo en Kardex

public static void Rekardex()


{
dsAplicacionComercial.BodegaProductoDataTable misBodegaProducto =
CADBodegaProducto.GetData();
foreach ( dsAplicacionComercial.BodegaProductoRow miBodegaProducto in
misBodegaProducto.Rows)
{

}
}
5. Creamos una consulta en el ds de Kardex un select que devuelve filas

SELECT IdKardex, IdBodega, IdProducto, Fecha, Documento, Entrada, Salida,


Saldo, UltimoCosto, CostoPromedio FROM dbo.Kardex
WHERE IdBodega = @IdBodega AND IdProducto = @IdProducto ORDER BY
Fecha que se llamara GetKardexByIdBodegaAndIdProducto
6.

Dentro del forech va lo ste

foreach ( dsAplicacionComercial.BodegaProductoRow miBodegaProducto in


misBodegaProducto.Rows)
{
dsAplicacionComercial.KardexDataTable misKardex =
adaptador.GetKardexByIdBodegaAndIdProducto(miBodegaProducto.IdBodega,
miBodegaProducto.IdProducto);
if (misKardex.Rows.Count == 0)
{
float saldo = 0;
decimal costoPromedio = 0;
decimal ultimoCosto = 0; // adicionarlo despus de actualizar mtodo updateKardex por sql
if (misKardex[0].Entrada > 0)
{
saldo = (float)misKardex[0].Entrada;
costoPromedio = misKardex[0].UltimoCosto;
ultimoCosto = misKardex[0].UltimoCosto; // se adiciono despues
}
else
{

saldo = -(float)misKardex[0].Salida;
}
adaptador.UpdateKardex(saldo, costoPromedio, ultimoCosto, misKardex[0].IdKardex);
//adicionar despus de crear mtodo updateKardex en el prximo video //se adiciona lo no
coloreado
for (int i = 1; i < misKardex.Rows.Count; i++)
{
if (misKardex[i].Entrada > 0)
{
costoPromedio = ((decimal)saldo * costoPromedio +
(decimal)misKardex[i].Entrada*misKardex[i].UltimoCosto)/
(decimal)(saldo + misKardex[i].Entrada);
saldo+=
}
}

Video 2 Re-kardex parte 2


1. Continuacin codigo anterior
if (misKardex[i].Entrada > 0)
{
costoPromedio = ((decimal)saldo * costoPromedio +
(decimal)misKardex[i].Entrada*misKardex[i].UltimoCosto)/
(decimal)(saldo + misKardex[i].Entrada);
ultimoCosto = misKardex[0].UltimoCosto; // se adiciona despus cuando actualice proc
update Kardex por sql
saldo+= += (float)misKardex[i].Entrada
}
else
{
saldo -= (float)misKardex[i].Salida;
}
adaptador.UpdateKardex(saldo, costoPromedio, ultimoCosto, misKardex[i].IdKardex);
//adicionar despus de crear mtodo updateKardex en este video //lo no coloreado se
adiciona despus del paso 2

}
2. En ds Kardex creamos mtodo para actualizar Kardex
UPDATE [dbo].[Kardex] SET
[Saldo] = @Saldo,
[CostoPromedio] = @CostoPromedio,
[UltimoCosto] = @UltimoCosto // se actualizo y se coloco esto que faltaba
WHERE [IdKardex] = @IdKardex
Llamado UpdateKardex

3. Ese mtodo solo se llama cuando ingreso de facturas no se ingresen en


orden en el men principal para llamar Kardex se crea en movimiento la

nueva opcin que se llame Verificar consistencia de Kardex y al darle clic


copiar lo ste
private void verificarConsistenciaDeKardexToolStripMenuItem1_Click(object sender,
EventArgs e)
{
DialogResult rta = MessageBox.Show("Est seguro de querer verificar la
consistencia del kardex?",
"Confirmacin", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

if(rta == DialogResult.No) return;


CADKardex.Rekardex();
MessageBox.Show("Verificacin de kardex finalizada", "Mensaje",
MessageBoxButtons.OK, MessageBoxIcon.Information);

4. Como se actualizo el updatekardex se borra del ds y se vuelve a agregar


como proc ya existente no devuelve valores
5. Cuando se haga actualizacin tambin se hace en la clase cadKardex se
adiciona lo escrito y especificado arriba relacionado con variable
ultimoCosto
6. Probar
Video 4 correccion a ultimo Kardex & consulta Kardex parte 2
1. Enlazar el combobox de bodegas
2. En el texbox de ptos activar evento validated cuando ya se valido y le
colocamos el mtodo ActualizarDatos igual que en el evento que se
activa al dar doble clic al combobox de bodegas que se el
selectedIndexChanged
3. Cuando el formulario haga load ponemos lo ste

private void frmConsultaKardex_Load(object sender, EventArgs e)


{
this.bodegaTableAdapter.Fill(this.dSAplicacionComercial.Bodega);
this.kardexTableAdapter.Fill(this.dSAplicacionComercial.Kardex); // se borra
BodegaComboBox.SelectedIndex = -1; se adiciona
ProductoLabel.Text = string.Empty;
}

4. Creamos mtodo ActualizarDatos


private void ActualizarDatos()
{
if (BodegaComboBox.SelectedIndex == -1 || ProductoTextBox.Text ==
string.Empty) return;
{
int IDBodega = (int)BodegaComboBox.SelectedValue;
int IDProducto = Convert.ToInt32(ProductoTextBox.Text);
this.kardexTableAdapter.FillBy(this.dSAplicacionComercial.Kardex,
IDBodega, IDProducto); //este codigo sacado del fillby que se creo con la consulta la
cual ya se puede borrar xq solo se necesitaba el codigo dentro del try que se le
cambio la ultima parte por solo el nombre de las variables idbodega y udpto
}

5. Vamos al form principal cuando se haga click en Kardex de consulta


colocar lo siguiente
private void kardexToolStripMenuItem_Click(object sender, EventArgs e)
{
frmConsultaKardex miform = new frmConsultaKardex();
miform.MdiParent = this;
// miform.UsuarioLogueado = usuarioLogueado;
miform.Show();
}

6. Personalizar la cuadricula
Idkarx, idpto y IdBodega visible: false
Fecha ancho colocarlo 150
Docum: 80 ancho
Entrada, Salida y saldo formato alineacin derecha N2
Ultimocosto y costoprom alineacin derecha C2

9. PARA QUE MUESTRE UNA CELDA DE UN COLOR Y LA OTRA DE OTRO


VAMOS A UNA PROPIEDAD ALTERNATINROWS Y EN LA OPCION
BACKCOLOR COGEMOS COLOR
10.PROBAR
11.Codigo botn buscar
private void BuscarProductoButton_Click(object sender, EventArgs e)
{
frmBusquedaProductos miBusqueda = new frmBusquedaProductos();
miBusqueda.ShowDialog();
if (miBusqueda.IDProducto == 0) return;
ProductoTextBox.Text = miBusqueda.IDProducto.ToString();
ProductoTextBox_Validated(sender, e);
}
12 en evento validated codigo completo
private void ProductoTextBox_Validated(object sender, EventArgs e)
{
if (ProductoTextBox.Text == string.Empty)
{
errorProvider1.SetError(ProductoTextBox, "Debe ingresar un Id de producto o un
cdigo de barras");
return;
}
errorProvider1.Clear();
long producto;
if (!long.TryParse(ProductoTextBox.Text, out producto))
{
errorProvider1.SetError(ProductoTextBox, "Debe ingresar un valor numrico
entero");
return;
}
errorProvider1.Clear();
if (producto <= 0)

errorProvider1.SetError(ProductoTextBox, "Debe ingresar un valor mayor a 0");


return;

}
errorProvider1.Clear();

CADProducto miProducto = CADProducto.GetProductoByIdProducto((int)producto);


if (miProducto == null) // no lo encontro como codigo de pto
{
miProducto = CADProducto.GetProductoByBarra(producto);
}
if (miProducto == null) // no esta en bd
{
errorProvider1.SetError(ProductoTextBox, "Producto no existe");
productoLabel.Text = string.Empty;
}
else
{
productoLabel.Text = miProducto.Descripcion;
}

ProductoTextBox.Text = miProducto.IdProducto.ToString();
ActualizarDatos();

Video 3 correccion a ultimo Kardex & consulta Kardex parte 1


1. Se hace cambio en sql del procedimiento almacenado ultimoKardex

SELECT IdKardex, IdBodega, IdProducto, Fecha, Documento, Entrada, Salida, Saldo,


UltimoCosto, CostoPromedio FROM dbo.Kardex
WHERE IdBodega = @IdBodega AND IdProducto = @IdProducto AND Fecha = (SELECT
MAX(Fecha) FROM Kardex WHERE IdBodega = @IdBodega AND IdProducto = @IdProducto)

2. REALIZAMOS FORMULARIO PARA CONSULTA KARDEX


3. Agregamos un gv que devulelva esa consulta lo ligo con la tabla Kardex
y le desactivo las 4 opciones hasta la de reordenacin ya que este es
importante verlo en orden cronolgico
4. Agrego consulta que queda asi
SELECT IdKardex, IdBodega, IdProducto, Fecha, Documento, Entrada,
Salida,
Saldo, UltimoCosto, CostoPromedio
FROM dbo.Kardex
WHERE IdBodega = @IdBodega AND IdProducto = @IdProducto
ORDER BY Fecha
5. Crea una barra de herramientas
6. Agregamos un label para bodega con su combobox
7. Y para ptos copiamos la parte de ptos del form compras

Video 5 devolucion clientes parte 1


1. Una devolucin de cliente esta basada en vta
2. Colocar label llamado vta y un combo box
3. Consulta en sql
SELECT Venta.IdVenta, CONVERT(nvarchar, Venta.Fecha) + '. Cliente:' +
CONVERT(nvarchar, Venta.IdCliente) + ' ' + Cliente.NombreComercial AS Venta
FROM Venta INNER JOIN Cliente ON Venta.IdCliente = Cliente.IdCliente

4. Para que el combo box tenga la rta de la consulta vamos al ds de


Windows creo un tableAdapter pregunta conexin utilizamo la que se
esta utilizando ste usar instruccin sql ste
SELECT Venta.IdVenta, CONVERT(nvarchar, Venta.Fecha) + '. Cliente:' +
CONVERT(nvarchar, Venta.IdCliente) + ' ' + Cliente.NombreComercial AS Venta
FROM Venta INNER JOIN Cliente ON Venta.IdCliente = Cliente.IdCliente y ste si
rellena datatable se deja con lod dos chulitos y se llama GetData finalizar queda
tabla venta1 que ser el origen de datos del combobox lo enlazamos en el miembro
es vta y en wl valor IdVenta

5. HACER LO MISMO CON DEVOLUCIONES A PROVEDORES ESTA SERIA LA


CONSULTA
SELECT Compra.IdCompra, CONVERT(nvarchar, Compra.Fecha) + '. Proveedor:' +
CONVERT(nvarchar, Compra.IdProveedor) + ' ' + Proveedor.Nombre AS Compra
FROM Compra INNER JOIN Proveedor ON Compra.IdProveedor =
Compra.IdProveedor
6. PROBAR
7. VAMOS AL PPAL PARA COLOCAR LOS ICONOS EN LA BARRA DE ACCESO RAPIDO NO
OLVIDAR COLOCAR LA PROPIEDAD IMAGESCALING EN NONE PARA QUE SALGAN
TODOS DEL MISMO TAMAO y cambiamos el nombre de los botones y le ponemos el
codigo respectivo

8. En el load de ambos formularios segn correponda colocar esto

CompraComboBox.SelectedIndex = -1;
VentaComboBox.SelectedIndex = -1;
Para que cuando inicie no este seleccionado ninguna venta o compra por defecto

Video 6 devolucion clientes parte 2


1. Quiero que me muestre los datos de la venta y la compra
2. Label: fecha y textbox de solo lectura la fecha en la que se hizo venta o
compra
3. Quiero que me muestre quien es el cliente o proveedor segn caso
creamos otro label llamado cliente o proveedor para que aparezca a que
cliente se le hizo la venta o a que proveedor se le hizo la compra estos
van con su combobox los cuales enlazamos y enable en false de
combobox y para ambos formularios agregamos un label de bodega con
un combobox que tambin se deshabilita.
4. En el load tambin colocar los combobox de cada forma vacios al iniciar
quedando para devoluciones de clientes asi
VentaComboBox.SelectedIndex = -1;
ClienteComboBox.SelectedIndex = -1;
BodegaComboBox.SelectedIndex = -1;

Y para devoliciones a proveedores asi


CompraComboBox.SelectedIndex = -1;
ProveedorComboBox.SelectedIndex = -1;
BodegaComboBox.SelectedIndex = -1;

5. Si se desea se eliminan los comentarios que se originan en los load


6. Para lo que en el combobox de compra o venta aparezca mas detallado abajo se
debe obtener la compra o la venta segn sea el caso y para eso se deben
empaquetar
7. En el cad en la tabla venta y compra creamos un mtodo que devuelva la venta y
compra respectivamente es un proc almacenado de select que devuelve filas

SELECT IdVenta, Fecha, IdCliente, IdBodega FROM dbo.Venta WHERE IdVenta =


@IdVenta llamara GetVentaByIdVenta no rellena datatable
SELECT IdCompra, Fecha, IdProveedor, IdBodega FROM dbo.Compra WHERE
IdCompra = @IdCompra llamara GetCompraByIdCompra no rellena datatable
8. Para poderlos utilizar los aadimos en la clase CADVenta y CADCompra
respectivamente al inicio despus de que habr corchetes la clase
public
public
public
public

int IdVenta { get; set; }


DateTime Fecha { get; set; }
int IdCliente { get; set; }
int IdBodega { get; set; }

public int IdCompra { get; set; }


public DateTime Fecha { get; set; }
public int IdProveedor { get; set; }
public int IdBodega { get; set; }

9. Ah mismo apenas termine el mtodo de insert colocamos lo ste en cada


CAD
public static CADVenta GetVentaByIdVenta(int IdVenta)
{
dsAplicacionComercial.VentaDataTable miTabla = adaptador.GetVentaByIdVenta(IdVenta);
if (miTabla.Rows.Count == 0) return null;
dsAplicacionComercial.VentaRow miRegistro = (dsAplicacionComercial.VentaRow)
miTabla.Rows[0];
CADVenta miVenta = new CADVenta();
miVenta.Fecha = miRegistro.Fecha;
miVenta.IdBodega = miRegistro.IdBodega;
miVenta.IdCliente = miRegistro.IdCliente;
miVenta.IdVenta = miRegistro.IdVenta;
return miVenta;
}

public static CADCompra GetCompraByIdCompra(int IdCompra)


{
dsAplicacionComercial.CompraDataTable miTabla =
adaptador.GetCompraByIdCompra(IdCompra);
if (miTabla.Rows.Count == 0) return null;
dsAplicacionComercial.CompraRow miRegistro =
(dsAplicacionComercial.CompraRow)miTabla.Rows[0];

CADCompra miCompra = new CADCompra();


miCompra.Fecha = miRegistro.Fecha;
miCompra.IdBodega = miRegistro.IdBodega;
miCompra.IdProveedor = miRegistro.IdProveedor;
miCompra.IdCompra = miRegistro.IdCompra;
return miCompra;
}

10.En los fotmularios de devoluciones activamos evento que viene en los


combobox de compra y venta y colocamos los cdigos stes
private void VentaComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (VentaComboBox.SelectedValue == null) return;
CADVenta miVenta = CADVenta.GetVentaByIdVenta((int)
VentaComboBox.SelectedValue);
FechaVentaTextBox.Text = miVenta.Fecha.ToString();
ClienteComboBox.SelectedValue = miVenta.IdCliente;
BodegaComboBox.SelectedValue = miVenta.IdBodega;
misDisponibles.Clear();
misDevueltos.Clear();
ProductoComboBox.SelectedIndex = -1;
}
private void CompraComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (CompraComboBox.SelectedValue == null) return;
CADCompra miCompra =
CADCompra.GetCompraByIdCompra((int)CompraComboBox.SelectedValue);
FechaCompraTextBox.Text = miCompra.Fecha.ToString();
ProveedorComboBox.SelectedValue = miCompra.IdProveedor;
BodegaComboBox.SelectedValue = miCompra.IdBodega;
misDisponibles.Clear();
misDevueltos.Clear();
ProductoComboBox.SelectedIndex = -1;
}

11.Hacemos cuadricula con el deltalle de la vta y compra


12.Vamos al ds del CAD en donde creamos un mtodo que devuelva todas
las ventas segn codigo de vta lo creamos en la tabla vtaDetalle y lo
mismo hacemos en compraDetalle un mtodo que devuelva las compras
segn idCompra
13.Creamos consulta select que devuelve filas
SELECT IdLinea, IdVenta, IdProducto, Descripcion, Precio, Cantidad, IdKardex,
PorcentajeIVA, PorcentajeDescuento FROM dbo.VentaDetalle
WHERE IdVenta = @IdVenta llamado GetVentaDetalleByIdVenta
SELECT IdLinea, IdCompra, IdProducto, Descripcion, Costo, Cantidad, IdKardex,
PorcentajeIVA, PorcentajeDescuento FROM dbo.CompraDetalle

WHERE IdCompra = @IdCompra llamado GetCompraDetalleByIdCompra


14.Para poder utilizar los mtodos creados vamos a los CAD de detalleVenta
y detalleCompra
public static dsAplicacionComercial.VentaDetalleDataTable GetVentaDetalleByIdVenta(int
IdVenta)
{
return adaptador.GetVentaDetalleByIdVenta(IdVenta);
}
Para compra
public static dsAplicacionComercial.CompraDetalleDataTable
GetVentaDetalleByIdCompra(int IdCompra)
{
return adaptador.GetCompraDetalleByIdCompra(IdCompra);
}

15.Para pintar los datos en devCLiente y DevProv es mas fcil para poder
hacer clculos en una lista por lo que tiene dos listas
- disponibles a devolver (cant disp. A devolver)
- Los que se han devuelto (cantidad devuelta)
Se necesitan dos clases por lo que en el proyecto Windows se crean dos
clases para DevCliente y dos Clases para devCompra
Video 7 devolucion clientes parte 3
1. La 1ra clase creada en el proyecto Windows la llamamos
DevolucionClienteDisponible que dice cuales son los disponibles para
devolver y creamos otra clase llama DevolucionClienteDevuleto que es
lo que ya se ha devuelto en esa devolucin
2. Lo mismo hacemos en compra DevolucionProveedorDisponible y
DevolucionProveedorDevuelto

class DevolucionClienteDisponible
{
public int IdProducto { get; set; }
public string Descripcion { get; set; }
public decimal Precio { get; set; }
public float CantidadOriginal { get; set; }
public float PorcentajeIVA { get; set; }
public float PorcentajeDescuento { get; set; }
public float CantidadDevuelta { get; set; }
public float CantidadDisponible { get { return CantidadOriginal - CantidadDevuelta;} }
}

class DevolucionClienteDevuelto
{
public int IdProducto { get; set; }
public string Descripcion { get; set; }

public
public
public
public

decimal Precio { get; set; }


float CantidadAdevolver { get; set; }
float PorcentajeIVA { get; set; }
float PorcentajeDescuento { get; set; }

class DevolucionProveedorDisponible
{
public int IdProducto { get; set; }
public string Descripcion { get; set; }
public decimal Costo { get; set; }
public float CantidadOriginal { get; set; }
public float PorcentajeIVA { get; set; }
public float PorcentajeDescuento { get; set; }
public float CantidadDevuelta { get; set; }
public float CantidadDisponibleDevolver { get { return CantidadOriginal CantidadDevuelta; } }
}
lass DevolucionProveedorDevuelto
{
public int IdProducto { get; set; }
public string Descripcion { get; set; }
public decimal Costo { get; set; }
public float CantidadADevolver { get; set; }
public float PorcentajeIVA { get; set; }
public float PorcentajeDescuento { get; set; }
}

3. Agregamos 2 dgv a los formularios de devprov y DevClientes que en


ambos se llaman disponibledgv y devueltodgv
4. Como los dgv se llenan por codigo entonces cuando el formulari al inicio
del formulario colocar esto
private List<DevolucionClienteDisponible> misDisponibles = new
List<DevolucionClienteDisponible>();
private List<DevolucionClienteDevuelto> misDevueltos = new
List<DevolucionClienteDevuelto>();
private List<DevolucionProveedorDisponible> misDisponibles = new
List<DevolucionProveedorDisponible>();
private List<DevolucionProveedorDevuelto> misDevueltos = new
List<DevolucionProveedorDevuelto>();

5. Y adicionar tambin este codigo en load de ambos formularios despus


de dejar en blanco los combobox
DisponibleDataGridView.DataSource = misDisponibles;
DevueltoDataGridView.DataSource = misDevueltos;

6. Probar

7. VAMOS A USAR EL METODO QUE DEVUELVE LOS DETALLES DE LAS


VENTAS Y DE LAS COMPRAS
8. Cuando el combobox de venta y compra cambien colocamos lo siguiente
en el selectedIndex
CADAplicacionComercial.dsAplicacionComercial.CompraDetalleDataTable miTabla
= CADCompraDetalle.GetCompraDetalleByIdCompra(miCompra.IdCompra);
foreach (CADAplicacionComercial.dsAplicacionComercial.CompraDetalleRow
miRegistro in miTabla.Rows)
{
DevolucionProveedorDisponible miDisponible = new DevolucionProveedorDisponible();
miDisponible.CantidadDevuelta = 0;//ojo falta llenar dev previas
miDisponible.CantidadOriginal = (float)miRegistro.Cantidad;
miDisponible.Descripcion = miRegistro.Descripcion;
miDisponible.IdProducto = miRegistro.IdProducto;
miDisponible.PorcentajeDescuento = (float)miRegistro.PorcentajeDescuento;
miDisponible.PorcentajeIVA = (float)miRegistro.PorcentajeIVA;
miDisponible.Costo = miRegistro.Costo;
misDisponibles.Add(miDisponible);

}
DisponibleDataGridView.DataSource = null;
DisponibleDataGridView.DataSource = misDisponibles;
PersonalizarDisponibles();
PersonalizarDevueltos();
CADAplicacionComercial.dsAplicacionComercial.VentaDetalleDataTable miTabla
= CADVentaDetalle.GetVentaDetalleByIdVenta(miVenta.IdVenta);
foreach ( CADAplicacionComercial.dsAplicacionComercial.VentaDetalleRow
miRegistro in miTabla.Rows)
{
DevolucionClienteDisponible miDisponible = new DevolucionClienteDisponible();
miDisponible.CantidadDevuelta = 0;//ojo falta llenar dev previas
miDisponible.CantidadOriginal = (float)miRegistro.Cantidad;
miDisponible.Descripcion = miRegistro.Descripcion;
miDisponible.IdProducto = miRegistro.IdProducto;
miDisponible.PorcentajeDescuento = (float)miRegistro.PorcentajeDescuento;
miDisponible.PorcentajeIVA = (float)miRegistro.PorcentajeIVA;
miDisponible.Precio = miRegistro.Precio;
misDisponibles.Add(miDisponible);

}
DisponibleDataGridView.DataSource = null;
DisponibleDataGridView.DataSource = misDisponibles;
PersonalizarDisponibles();
PersonalizarDevueltos();

9. Probar
10.Personalizar gv

private void PersonalizarDisponibles()


{
DisponibleDataGridView.Columns["IdProducto"].HeaderText = "Id Producto";
DisponibleDataGridView.Columns["IdProducto"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DisponibleDataGridView.Columns["IdProducto"].Width = 80;
DisponibleDataGridView.Columns["Descripcion"].HeaderText = "Descripcin";
DisponibleDataGridView.Columns["Descripcion"].Width = 200;
DisponibleDataGridView.Columns["Precio"].HeaderText = "Precio";
DisponibleDataGridView.Columns["Precio"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DisponibleDataGridView.Columns["Precio"].DefaultCellStyle.Format = "C2";
DisponibleDataGridView.Columns["Precio"].Width = 80;
DisponibleDataGridView.Columns["CantidadOriginal"].HeaderText = "Cantidad Original";
DisponibleDataGridView.Columns["CantidadOriginal"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DisponibleDataGridView.Columns["CantidadOriginal"].DefaultCellStyle.Format =
"N2";
DisponibleDataGridView.Columns["CantidadOriginal"].Width = 80;
DisponibleDataGridView.Columns["PorcentajeIVA"].HeaderText = "Porcentaje IVA";
DisponibleDataGridView.Columns["PorcentajeIVA"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DisponibleDataGridView.Columns["PorcentajeIVA"].DefaultCellStyle.Format = "P2";
DisponibleDataGridView.Columns["PorcentajeIVA"].Width = 80;
DisponibleDataGridView.Columns["PorcentajeDescuento"].HeaderText = "Porcentaje
Descuento";
DisponibleDataGridView.Columns["PorcentajeDescuento"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DisponibleDataGridView.Columns["PorcentajeDescuento"].DefaultCellStyle.Format =
"P2";
DisponibleDataGridView.Columns["PorcentajeDescuento"].Width = 80;
DisponibleDataGridView.Columns["CantidadDevuelta"].HeaderText = "Cantidad Devuelta";
DisponibleDataGridView.Columns["CantidadDevuelta"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DisponibleDataGridView.Columns["CantidadDevuelta"].DefaultCellStyle.Format =
"N2";
DisponibleDataGridView.Columns["CantidadDevuelta"].Width = 80;
DisponibleDataGridView.Columns["CantidadDisponible"].HeaderText = "Cantidad Disponible
Devolver";
DisponibleDataGridView.Columns["CantidadDisponible"].DefaultCellStyle.Alignment
= DataGridViewContentAlignment.MiddleRight;
DisponibleDataGridView.Columns["CantidadDisponible"].DefaultCellStyle.Format =
"N2";
DisponibleDataGridView.Columns["CantidadDisponible"].Width = 80;
}
La de devAProv es igual solo cambia la variable precio por costo

Video 8 devolucion clientes parte 4


1. En el load de ambos form colocar personalizar grid()
2. Personalicemos la grid de devueltos
3. Crear combobox que diga el pto a devolver y la cantidad

private void PersonalizarDevueltos()


{
DevueltoDataGridView.Columns["IdProducto"].HeaderText = "Id Producto";
DevueltoDataGridView.Columns["IdProducto"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DevueltoDataGridView.Columns["IdProducto"].Width = 80;
DevueltoDataGridView.Columns["Descripcion"].HeaderText = "Descripcin";
DevueltoDataGridView.Columns["Descripcion"].Width = 200;
DevueltoDataGridView.Columns["Precio"].HeaderText = "Precio";
DevueltoDataGridView.Columns["Precio"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DevueltoDataGridView.Columns["Precio"].DefaultCellStyle.Format = "C2";
DevueltoDataGridView.Columns["Precio"].Width = 80;
DevueltoDataGridView.Columns["CantidadADevolver"].HeaderText = "Cantidad
disponible a devolver";
DevueltoDataGridView.Columns["CantidadADevolver"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DevueltoDataGridView.Columns["CantidadADevolver"].DefaultCellStyle.Format =
"N2";
DevueltoDataGridView.Columns["CantidadADevolver"].Width = 80;
DevueltoDataGridView.Columns["PorcentajeIVA"].HeaderText = "Porcentaje IVA";
DevueltoDataGridView.Columns["PorcentajeIVA"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DevueltoDataGridView.Columns["PorcentajeIVA"].DefaultCellStyle.Format = "P2";
DevueltoDataGridView.Columns["PorcentajeIVA"].Width = 80;
DevueltoDataGridView.Columns["PorcentajeDescuento"].HeaderText = "Porcentaje
Descuento";
DevueltoDataGridView.Columns["PorcentajeDescuento"].DefaultCellStyle.Alignment
= DataGridViewContentAlignment.MiddleRight;
DevueltoDataGridView.Columns["PorcentajeDescuento"].DefaultCellStyle.Format =
"P2";
DevueltoDataGridView.Columns["PorcentajeDescuento"].Width = 80;
}

private void PersonalizarDevueltos()


{
DevueltoDataGridView.Columns["IdProducto"].HeaderText = "Id Producto";
DevueltoDataGridView.Columns["IdProducto"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DevueltoDataGridView.Columns["IdProducto"].Width = 80;
DevueltoDataGridView.Columns["Descripcion"].HeaderText = "Descripcin";
DevueltoDataGridView.Columns["Descripcion"].Width = 200;
DevueltoDataGridView.Columns["Costo"].HeaderText = "Costo";
DevueltoDataGridView.Columns["Costo"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DevueltoDataGridView.Columns["Costo"].DefaultCellStyle.Format = "C2";
DevueltoDataGridView.Columns["Costo"].Width = 80;

DevueltoDataGridView.Columns["CantidadADevolver"].HeaderText = "Cantidad
disponible a devolver";
DevueltoDataGridView.Columns["CantidadADevolver"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DevueltoDataGridView.Columns["CantidadADevolver"].DefaultCellStyle.Format =
"N2";
DevueltoDataGridView.Columns["CantidadADevolver"].Width = 80;
DevueltoDataGridView.Columns["PorcentajeIVA"].HeaderText = "Porcentaje IVA";
DevueltoDataGridView.Columns["PorcentajeIVA"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;
DevueltoDataGridView.Columns["PorcentajeIVA"].DefaultCellStyle.Format = "P2";
DevueltoDataGridView.Columns["PorcentajeIVA"].Width = 80;
DevueltoDataGridView.Columns["PorcentajeDescuento"].HeaderText = "Porcentaje
Descuento";
DevueltoDataGridView.Columns["PorcentajeDescuento"].DefaultCellStyle.Alignment
= DataGridViewContentAlignment.MiddleRight;
DevueltoDataGridView.Columns["PorcentajeDescuento"].DefaultCellStyle.Format =
"P2";
DevueltoDataGridView.Columns["PorcentajeDescuento"].Width = 80;
}

4. Colocar combobox para pto ese si va habilitado le quitamos la opcin de


eelementos enlazados por que se llena con codigo por lo que en la
propiedad valuemember es IdProducto y displayMembers: Descripciom
en ambos formularios
5. En el selectedChanged que es el evento que se activa dando clic al
textbox de vtas o compras escribir lo siguiente
ProductoComboBox.DataSource = misDisponibles;

6. Probar
7. Copiar los botones y el de cantidad de vta y compra
8. Codigo para botn agregar de ambos formularios
if (ProductoComboBox.SelectedIndex == -1)
{
errorProvider1.SetError(ProductoComboBox, "Debe seleccionar un producto");
ProductoComboBox.Focus();
return;
}
errorProvider1.Clear();
if (CantidadTextBox.Text == string.Empty)
{
errorProvider1.SetError(CantidadTextBox, "Debe ingresar una cantidad");
return;
}
errorProvider1.Clear();
float cantidad;
if (!float.TryParse(CantidadTextBox.Text, out cantidad))
{
errorProvider1.SetError(CantidadTextBox, "Debe ingresar un valor numrico");
return;

}
errorProvider1.Clear();
if (cantidad <= 0)
{
errorProvider1.SetError(CantidadTextBox, "Debe ingresar un valor mayor a 0");
return;
}
errorProvider1.Clear();
if (cantidad > misDisponibles[ProductoComboBox.SelectedIndex].CantidadDisponible)
{
errorProvider1.SetError(CantidadTextBox, "La cantidad a devolver no puede ser
mayor a la disponible");
return;
}
errorProvider1.Clear();

9. Al final del botn agregar para que lo de arriba aparezca abajo


DevolucionProveedorDevuelto miDevuelto = new DevolucionProveedorDevuelto();
miDevuelto.CantidadADevolver = cantidad;
miDevuelto.Costo = misDisponibles[ProductoComboBox.SelectedIndex].Costo;
miDevuelto.Descripcion =
misDisponibles[ProductoComboBox.SelectedIndex].Descripcion;
miDevuelto.IdProducto =
misDisponibles[ProductoComboBox.SelectedIndex].IdProducto;
miDevuelto.PorcentajeDescuento =
misDisponibles[ProductoComboBox.SelectedIndex].PorcentajeDescuento;
miDevuelto.PorcentajeIVA =
misDisponibles[ProductoComboBox.SelectedIndex].PorcentajeIVA;
misDevueltos.Add(miDevuelto);
ProductoComboBox.SelectedIndex = -1;
CantidadTextBox.Text = string.Empty;

DevolucionClienteDevuelto miDevuelto = new DevolucionClienteDevuelto();


miDevuelto.CantidadADevolver = cantidad;
miDevuelto.Descripcion =
misDisponibles[ProductoComboBox.SelectedIndex].Descripcion;
miDevuelto.IdProducto =
misDisponibles[ProductoComboBox.SelectedIndex].IdProducto;
miDevuelto.PorcentajeDescuento =
misDisponibles[ProductoComboBox.SelectedIndex].PorcentajeDescuento;
miDevuelto.PorcentajeIVA =
misDisponibles[ProductoComboBox.SelectedIndex].PorcentajeIVA;
miDevuelto.Precio = misDisponibles[ProductoComboBox.SelectedIndex].Precio;
misDevueltos.Add(miDevuelto);
ProductoComboBox.SelectedIndex = -1;
CantidadTextBox.Text = string.Empty;

Video 9 devolucion clientes parte 5


1. Probar

2. Despus de cantidad = string.empty colocar esto


DevueltoDataGridView.DataSource = null;
ProductoComboBox.Focus();
DevueltoDataGridView.DataSource = misDevueltos;
PersonalizarDevueltos();

3. Cuando se diga grabar afecta dev cliente o prov devdetalle, Kardex y


bodegapto
4. Si se hace devcliente la mercanca entra (similar a compra) inventario y
dev a prov sale del inv (similar a vta)
// pendiente en agregar q no deje eter 2 veces mismo pto
5. Hacer botn grabar pero en el CAD agregar devolucionCliente y
devprov
6. Terminar de areglar cdigos que salen cuando se copio codigo de
compras a devClientes y se quedo donde se iba agregar consulta a la
tabla devcliente agregada en el cad tambin se agrego devprov para
hacer mismo codigo al mismo tiempo
7. Crear consulta de insert
INSERT INTO [dbo].[DevolucionCliente] ([Fecha], [IDVenta]) VALUES (@Fecha,
@IDVenta);
SELECT IdDevolucionCliente
FROM DevolucionCliente
WHERE (IdDevolucionCliente = SCOPE_IDENTITY()) llamado
InsertDevolucionCliente
INSERT INTO [dbo].[DevolucionProveedor] ([Fecha], [IdCompra]) VALUES
(@Fecha, @IdCompra);
SELECT IdDevolucionProveedor
FROM DevolucionProveedor
WHERE (IdDevolucionProveedor =
SCOPE_IDENTITY())InsertDevolucionProveedor
8. Despus de agregarlas las eliminamos
9. Se vuelven a agrgar como usar proc almacenado existente y con la
opcin de un solo valor
10.
Para poder usarla creamos en el cad la clase de devCliente y
devProveedor las ponemos public y colocamos el siguiente codigo
private static DevolucionClienteTableAdapter adaptador = new
DevolucionClienteTableAdapter();
public static int InsertDevolucionCliente(DateTime Fecha, int IDVenta)
{
return (int)adaptador.InsertDevolucionCliente(Fecha, IDVenta);
}
private static DevolucionProveedorTableAdapter adaptador = new
DevolucionProveedorTableAdapter();
public static int InsertDevolucionProveedor(DateTime Fecha, int IDCompra)

return (int)adaptador.InsertDevolucionProveedor(Fecha, IDCompra);

11.
Agregamos en el formulario otro campo para fechaDevolucion con
un dateTimePicker y cambiamos el que se llama fecha por FechaVenta
12.
Organizar orden de tabulacin
13.
Cuando formulario haga load aadir
FechaDevolucionDateTimePicker1.Value = DateTime.Now;

Video 10 devolucion clientes parte 6


1. Agregamos tabla de devClienteDetalle y devProveedorDetalle

INSERT INTO [dbo].[DevolucionClienteDetalle] ([IdDevolucionCliente],


[IdProducto], [Descripcion], [Precio], [Cantidad], [IdKardex], [PorcentajeIVA],
[PorcentajeDescuento]) VALUES (@IdDevolucionCliente, @IdProducto,
@Descripcion, @Precio, @Cantidad, @IdKardex, @PorcentajeIVA,
@PorcentajeDescuento)
INSERT INTO [dbo].[DevolucionProveedorDetalle] ([IdDevolucionProveedor],
[IdProducto], [Descripcion], [Precio], [Cantidad], [IdKardex], [PorcentajeIVA],
[PorcentajeDescuento]) VALUES (@IdDevolucionProveedor, @IdProducto,
@Descripcion, @Precio, @Cantidad, @IdKardex, @PorcentajeIVA,
@PorcentajeDescuento)
2. Agregamos los cad correspondientes

private static DevolucionClienteDetalleTableAdapter adaptador = new


DevolucionClienteDetalleTableAdapter();
public static void InsertDevolucionClienteDetalle(int IdDevolucionCliente, int
IdProducto, string Descripcion,
decimal Precio,float Cantidad,int IdKardex,float PorcentajeIVA,float
PorcentajeDescuento)
{
adaptador.InsertDevolucionClienteDetalle(IdDevolucionCliente, IdProducto,
Descripcion, Precio, Cantidad,
IdKardex, PorcentajeIVA, PorcentajeDescuento);
}

3. Los cdigos de los botones grabar de los formularios son los siguientes
private void GrabarButton_Click(object sender, EventArgs e)
{
if (CompraComboBox.SelectedIndex == -1)
{
errorProvider1.SetError(CompraComboBox, "Debe seleccionar una compra");
CompraComboBox.Focus();
return;
}

errorProvider1.Clear();
if (misDevueltos.Count == 0)
{
errorProvider1.SetError(ProductoComboBox, "Debe ingresar productos en la
devolucin");
ProductoComboBox.Focus();
return;
}
errorProvider1.Clear();
DialogResult rta = MessageBox.Show("Es seguro que querer grabar la
devolucin?",
"Confirmacin", MessageBoxButtons.YesNo, MessageBoxIcon.Question,
MessageBoxDefaultButton.Button2);
if (rta == DialogResult.No) return;
int IDBodega = (int)BodegaComboBox.SelectedValue;
int IDCompra = (int)CompraComboBox.SelectedValue; // se hace para no estarlo
casteando a cada rato
DateTime Fecha = FechaDevolucionDateTimePicker1.Value; //cambiamos de posicion
de antes a despues de comentario
//grabamos cencabezado de la devolucin
int IDDevolucion = CADDevolucionProveedor.InsertDevolucionProveedor(Fecha,
IDCompra);
//grabamos detalle de la devolucion cliente
foreach (DevolucionProveedorDevuelto miDetalle in misDevueltos)
{
//consultar saldo de pto en una bodega hacer un metodo que nos devuelva
detalle de un pto en una bodega con el metodo getbodegaProductoBIdpto que nos devuelva
el dellae en esa bodega de un pto
CADBodegaProducto miBodegaProducto =
CADBodegaProducto.GetBodegaProductoByIdBodegaAndIdProducto(
IDBodega, miDetalle.IdProducto);
if (miBodegaProducto == null) //actualizamos bodegaPto
{
CADBodegaProducto.UpdateBodegaProducto(IDBodega, miDetalle.IdProducto,
1, 1, 1, 1);
}
CADBodegaProducto.AumentarStock(miDetalle.CantidadADevolver, IDBodega,
miDetalle.IdProducto); //HUBO CAMBIOS CON RESPECTO A ESTE CODIGO
CADKardex miKardex = CADKardex.UltimoKardex(IDBodega,
miDetalle.IdProducto);
int IdKardex;
float nuevoSaldo;
decimal nuevoCostoPromedio;
decimal nuevoUltimoCosto; //adiciona despues
if (miKardex == null)
{
nuevoSaldo = miDetalle.CantidadADevolver;

nuevoCostoPromedio = miDetalle.Costo;
nuevoUltimoCosto = nuevoCostoPromedio;
}
else
{
nuevoSaldo = miKardex.Saldo + miDetalle.CantidadADevolver;
nuevoCostoPromedio =
(miKardex.CostoPromedio * (decimal)miKardex.Saldo +
miDetalle.Costo * (decimal)miDetalle.CantidadADevolver) /
(decimal)nuevoSaldo;
nuevoUltimoCosto = miDetalle.Costo;
}
IdKardex = CADKardex.InsertKardex(IDBodega, miDetalle.IdProducto,
Fecha, string.Format("DV-{0}", IDDevolucion), miDetalle.CantidadADevolver, 0,
nuevoSaldo, nuevoUltimoCosto, nuevoCostoPromedio);
// actualizamos devolucion PROVEEDOR detalle
CADDevolucionProveedorDetalle.InsertDevolucionProveedorDetalle(IDDevolucion,
miDetalle.IdProducto, miDetalle.Descripcion,
miDetalle.Costo, miDetalle.CantidadADevolver, IdKardex,
miDetalle.PorcentajeIVA, miDetalle.PorcentajeDescuento);
}
MessageBox.Show(string.Format("La devolucin al proveedor: {0}, fue grabada de
forma exitosa", IDDevolucion),
"Confirmacin", MessageBoxButtons.OK, MessageBoxIcon.Information);

CompraComboBox.SelectedIndex = -1;
ProveedorComboBox.SelectedIndex = -1;
BodegaComboBox.SelectedIndex = -1;
misDisponibles.Clear();
misDevueltos.Clear();
DisponibleDataGridView.DataSource = null;
DevueltoDataGridView.DataSource = null;
DisponibleDataGridView.DataSource = misDisponibles;
DevueltoDataGridView.DataSource = misDevueltos;
PersonalizarDisponibles();
PersonalizarDevueltos();
FechaDevolucionDateTimePicker1.Value = DateTime.Now;
}

CompraComboBox.Focus();

Grabar devclientes
private void GrabarButton_Click(object sender, EventArgs e)
{

if (VentaComboBox.SelectedIndex == -1)
{
errorProvider1.SetError(VentaComboBox, "Debe seleccionar una venta");
VentaComboBox.Focus();
return;
}
errorProvider1.Clear();

if (misDevueltos.Count == 0)
{
errorProvider1.SetError(ProductoComboBox, "Debe ingresar productos en la
devolucin");
ProductoComboBox.Focus();
return;
}
errorProvider1.Clear();
DialogResult rta = MessageBox.Show("Es seguro que querer grabar la
devolucin?",
"Confirmacin", MessageBoxButtons.YesNo, MessageBoxIcon.Question,
MessageBoxDefaultButton.Button2);
if (rta == DialogResult.No) return;
int IDBodega = (int)BodegaComboBox.SelectedValue;
int IDVenta = (int)VentaComboBox.SelectedValue; // se hace para no estarlo
casteando a cada rato
DateTime Fecha = FechaDevolucionDateTimePicker1.Value; //cambiamos de posicion
de antes a despues de comentario
//grabamos cencabezado de la devolucin
int IDDevolucion = CADDevolucionCliente.InsertDevolucionCliente(Fecha,
IDVenta);
//grabamos detalle de la devolucion cliente
foreach (DevolucionClienteDevuelto miDetalle in misDevueltos)
{
//consultar saldo de pto en una bodega hacer un metodo que nos devuelva
detalle de un pto en una bodega con el metodo getbodegaProductoBIdpto que nos devuelva
el dellae en esa bodega de un pto
CADBodegaProducto miBodegaProducto =
CADBodegaProducto.GetBodegaProductoByIdBodegaAndIdProducto(
IDBodega, miDetalle.IdProducto);
if (miBodegaProducto == null) //actualizamos bodegaPto
{
CADBodegaProducto.UpdateBodegaProducto(IDBodega, miDetalle.IdProducto,
1, 1, 1, 1);
}
CADBodegaProducto.AumentarStock(miDetalle.CantidadADevolver, IDBodega,
miDetalle.IdProducto); //HUBO CAMBIOS CON RESPECTO A ESTE CODIGO
CADKardex miKardex = CADKardex.UltimoKardex(IDBodega,
miDetalle.IdProducto);
int IdKardex;
float nuevoSaldo;

decimal nuevoCostoPromedio;
decimal nuevoUltimoCosto; //adiciona despues
if (miKardex == null)
{
nuevoSaldo = miDetalle.CantidadADevolver;
nuevoCostoPromedio = miDetalle.Precio;
nuevoUltimoCosto = nuevoCostoPromedio;
}
else
{
nuevoSaldo = miKardex.Saldo + miDetalle.CantidadADevolver;
nuevoCostoPromedio =
(miKardex.CostoPromedio * (decimal)miKardex.Saldo +
miDetalle.Precio * (decimal)miDetalle.CantidadADevolver) /
(decimal)nuevoSaldo;
nuevoUltimoCosto = miDetalle.Precio;
}
IdKardex = CADKardex.InsertKardex(IDBodega, miDetalle.IdProducto,
Fecha, string.Format("DC-{0}", IDDevolucion), miDetalle.CantidadADevolver, 0,
nuevoSaldo, nuevoUltimoCosto, nuevoCostoPromedio);
// actualizamos devolucion cliente detalle
CADDevolucionClienteDetalle.InsertDevolucionClienteDetalle(IDDevolucion,
miDetalle.IdProducto, miDetalle.Descripcion,
miDetalle.Precio, miDetalle.CantidadADevolver, IdKardex,
miDetalle.PorcentajeIVA, miDetalle.PorcentajeDescuento);
}
MessageBox.Show(string.Format("La devolucin de cliente: {0}, fue grabada de
forma exitosa", IDDevolucion),
"Confirmacin", MessageBoxButtons.OK, MessageBoxIcon.Information);

VentaComboBox.SelectedIndex = -1;
ClienteComboBox.SelectedIndex = -1;
BodegaComboBox.SelectedIndex = -1;
misDisponibles.Clear();
misDevueltos.Clear();
DisponibleDataGridView.DataSource = null;
DevueltoDataGridView.DataSource = null;
DisponibleDataGridView.DataSource = misDisponibles;
DevueltoDataGridView.DataSource = misDevueltos;
PersonalizarDisponibles();
PersonalizarDevueltos();
FechaDevolucionDateTimePicker1.Value = DateTime.Now;
}

VentaComboBox.Focus();

4. SE VA ARREGLAR LA PARTE DONDE SI SE DEVUELVE UNA VTA O COMPRA


LA CANTIDAD DEVUELTA DEBE DAR LA SUMA DE TODAS LAS DEV
PREVIAS
SE HACE ESTE QUERY EN SQL
SELECT
SUM(dbo.DevolucionClienteDetalle.Cantidad) AS Expr1
FROM
dbo.DevolucionCliente INNER JOIN
dbo.DevolucionClienteDetalle ON
dbo.DevolucionCliente.IdDevolucionCliente =
dbo.DevolucionClienteDetalle.IdDevolucionCliente
WHERE
(dbo.DevolucionCliente.IDVenta = 1) AND
(dbo.DevolucionClienteDetalle.IdProducto = 1) igual con proveedor

Video 11 devolucion clientes parte 7


MIN 4:44
1. Consulta de un select que devuelva un solo valor en
devolucionClienteDetalle y devolucionProveedorDetalle

SELECT SUM(DevolucionClienteDetalle.Cantidad)
FROM DevolucionCliente
INNER JOIN DevolucionClienteDetalle ON
DevolucionCliente.IdDevolucionCliente =
DevolucionClienteDetalle.IdDevolucionCliente
WHERE (DevolucionCliente.IDVenta = @IdVenta) AND
(DevolucionClienteDetalle.IdProducto = @IdProducto) llamado
GetHistoriaDevolucionCliente

SELECT SUM(DevolucionProveedorDetalle.Cantidad)
FROM DevolucionProveedor
INNER JOIN DevolucionProveedorDetalle ON
DevolucionProveedor.IdDevolucionProveedor =
DevolucionProveedorDetalle.IdDevolucionProveedor
WHERE (DevolucionProveedor.IDCompra = @IdCompra) AND
(DevolucionProveedorDetalle.IdProducto = @IdProducto) llamado
GetHistoriaDevolucionProveedor
2. Vamos al cadDevClienteDet y DevProvDet para poder usar mtodos
acabados de crear

public static double GetHistoriaDevolucionProveedor(int IdCompra, int IdProducto)


{

try
{
return (double)adaptador.GetHistoriaDevolucionProveedor(IdCompra, IdProducto);
}
catch (Exception)
{
return 0;
}
}

public static double GetHistoriaDevolucionCliente(int IdVenta, int IdProducto)


{
try
{
return (double)adaptador.GetHistoriaDevolucionCliente(IdVenta, IdProducto);
}
catch (Exception)
{
}

return 0;

3. Vamos a devCliente y DevProv para colcoar lo ste segn sea el caso


PARA DEVOLUCIONES PREVIAS

DevolucionClienteDisponible miDisponible = new DevolucionClienteDisponible();


miDisponible.CantidadDevuelta = (float)
CADDevolucionClienteDetalle.GetHistoriaDevolucionCliente(miRegistro.IdVenta,
miRegistro.IdProducto);
miDisponible.CantidadOriginal = (float)miRegistro.Cantidad;
DevolucionClienteDisponible miDisponible = new DevolucionClienteDisponible();
miDisponible.CantidadDevuelta = (float)
CADDevolucionProveedorDetalle.GetHistoriaDevolucionProveedor(miRegistro.IdCompra,
miRegistro.IdProducto);
miDisponible.CantidadOriginal = (float)miRegistro.Cantidad;

4. Probar
5. Otra validacin

Video 12 devolucion clientes parte 8


1. Validacin si el pto esta agregado en la lista de devueltos en el codigo
del botn agregar despus de a validacin de cantidad

foreach (DevolucionClienteDevuelto midevuelto in misDevueltos)


{
if ((int)ProductoComboBox.SelectedValue == midevuelto.IdProducto)
{

errorProvider1.SetError(ProductoComboBox, "El producto ya fue agregado a la


devolucin");
ProductoComboBox.Focus();
return;
}
}
errorProvider1.Clear();

foreach (DevolucionProveedorDevuelto midevuelto in misDevueltos)


{
if ((int)ProductoComboBox.SelectedValue == midevuelto.IdProducto)
{
errorProvider1.SetError(ProductoComboBox, "El producto ya fue agregado a la
devolucin");
ProductoComboBox.Focus();
return;
}
}
errorProvider1.Clear();

2. Botn cancelar colocar


private void CancelarButton_Click(object sender, EventArgs e)
{
this.Close();
}

3. Botn borrar todo

private void BorrarTodoButton_Click(object sender, EventArgs e)


{
errorProvider1.Clear();
if (misDevueltos.Count == 0) return;
DialogResult rta = MessageBox.Show("Est seguro de borrar todas las lneas de la
devolucin?",
"Confirmacin", MessageBoxButtons.YesNo, MessageBoxIcon.Question,
MessageBoxDefaultButton.Button2);
if (rta == DialogResult.No) return;
misDevueltos.Clear();
RefrescarDevueltos()
}

4. Botn borrar lnea

private void BorrarLineaButton_Click(object sender, EventArgs e)


{
errorProvider1.Clear();
if (misDevueltos.Count == 0) return;
if (DevueltoDataGridView.SelectedRows.Count == 0)
{
misDevueltos.RemoveAt(misDevueltos.Count - 1);
RefrescarDevueltos()
}

else
{
int IDProducto = (int)DevueltoDataGridView.SelectedRows[0].Cells[0].Value;
for (int i = 0; i < misDevueltos.Count; i++)
{
if (misDevueltos[i].IdProducto == IDProducto)
{
misDevueltos.RemoveAt(i);
break;
}
}
}
RefrescarDevueltos()
}

10.Si se quiere se crea el mtodo refrescarDevueltos


private void RefrescarDevueltos()
{
DevueltoDataGridView.DataSource = null;
DevueltoDataGridView.DataSource = misDevueltos;
PersonalizarDevueltos();
}

11.Agregar botn anular todo

private void AnularTodoButton_Click(object sender, EventArgs e)


{
DialogResult rta = MessageBox.Show
("Est seguro de querer agregar todos los productos de la compra oroginal a la
devolucin?",
"Confirmacin", MessageBoxButtons.YesNo, MessageBoxIcon.Question,
MessageBoxDefaultButton.Button2);
if (rta == DialogResult.No) return;
misDevueltos.Clear();
foreach (DevolucionProveedorDisponible miDisponible in misDisponibles)
{
if (miDisponible.CantidadDisponible > 0)
{
DevolucionProveedorDevuelto miDevuelto = new
DevolucionProveedorDevuelto();
miDevuelto.CantidadADevolver = miDisponible.CantidadDisponible;
miDevuelto.Descripcion = miDisponible.Descripcion;
miDevuelto.IdProducto = miDisponible.IdProducto;
miDevuelto.PorcentajeDescuento = miDisponible.PorcentajeDescuento;
miDevuelto.PorcentajeIVA = miDisponible.PorcentajeIVA;
miDevuelto.Costo = miDisponible.Costo;
misDevueltos.Add(miDevuelto);

}
}
RefrescarDevueltos();

private void AnularTodoButton_Click(object sender, EventArgs e)

{
DialogResult rta = MessageBox.Show
("Est seguro de querer agregar todos los productos de la venta oroginal a la
devolucin?",
"Confirmacin", MessageBoxButtons.YesNo, MessageBoxIcon.Question,
MessageBoxDefaultButton.Button2);
if (rta == DialogResult.No) return;
misDevueltos.Clear();
foreach (DevolucionClienteDisponible miDisponible in misDisponibles)
{
if (miDisponible.CantidadDisponible > 0)
{
DevolucionClienteDevuelto miDevuelto = new DevolucionClienteDevuelto();
miDevuelto.CantidadADevolver = miDisponible.CantidadDisponible;
miDevuelto.Descripcion = miDisponible.Descripcion;
miDevuelto.IdProducto = miDisponible.IdProducto;
miDevuelto.PorcentajeDescuento = miDisponible.PorcentajeDescuento;
miDevuelto.PorcentajeIVA = miDisponible.PorcentajeIVA;
miDevuelto.Precio = miDisponible.Precio;
misDevueltos.Add(miDevuelto);

}
}
RefrescarDevueltos();

12 una adicion para que no se reviente x divisin por 0 en devClientes


if (miKardex == null)
{
nuevoSaldo = miDetalle.CantidadADevolver;
nuevoCostoPromedio = miDetalle.Precio;
nuevoUltimoCosto = nuevoCostoPromedio;
}
else
{
nuevoSaldo = miKardex.Saldo + miDetalle.CantidadADevolver;
if (nuevoSaldo != 0)
{
nuevoCostoPromedio =
(miKardex.CostoPromedio * (decimal)miKardex.Saldo +
miDetalle.Precio * (decimal)miDetalle.CantidadADevolver) /
(decimal)nuevoSaldo;
}
else
{
nuevoCostoPromedio = 0;
}
nuevoUltimoCosto = miDetalle.Precio;

Video 13 explicacion resto movimientos


1. Hacer mov salidas
2. Hacer mov traslados

3. Agrego una opcin de inventario fsico a la barra de mov con las stes
opciones
- Paso 1: Programar inventario
- Paso 2: Ingresar primer conteo
- Paso 3: Ingresar segundo conteo
- Paso 4 Ingresar conteo final y hacer ajustes
- Cancelar inventarios no terminados
4. Actualizar inventario inicializarInventario

ALTER PROCEDURE [dbo].[InicializarInventario] AS


DELETE FROM DevolucionClienteDetalle
DELETE FROM DevolucionCliente
DELETE FROM DevolucionProveedorDetalle
DELETE FROM DevolucionProveedor
DELETE FROM CompraDetalle
DELETE FROM Compra
DELETE FROM InventarioDetalle
DELETE FROM Inventario
DELETE FROM SalidaDetalle1
DELETE FROM Salida
DELETE FROM TrasladoDetalle
DELETE FROM Traslado
DELETE FROM Salida
DELETE FROM VentaDetalle;
DELETE FROM Venta;
DELETE FROM Kardex;
UPDATE BodegaProducto SET Stock = 0
DBCC
DBCC
DBCC
DBCC
DBCC
DBCC
DBCC
DBCC
DBCC
DBCC
DBCC
DBCC
DBCC
DBCC
DBCC

CHECKIDENT
CHECKIDENT
CHECKIDENT
CHECKIDENT
CHECKIDENT
CHECKIDENT
CHECKIDENT
CHECKIDENT
CHECKIDENT
CHECKIDENT
CHECKIDENT
CHECKIDENT
CHECKIDENT
CHECKIDENT
CHECKIDENT

(DevolucionClienteDetalle, RESEED, 0)
(DevolucionCliente, RESEED, 0)
(DevolucionProveedorDetalle, RESEED, 0)
(DevolucionProveedor, RESEED, 0)
(InventarioDetalle, RESEED, 0)
(Inventario, RESEED, 0)
(SalidaDetalle1, RESEED, 0)
(Salida, RESEED, 0)
(TrasladoDetalle, RESEED, 0)
(Traslado, RESEED, 0)
(VentaDetalle, RESEED, 0)
(Venta, RESEED, 0)
(CompraDetalle, RESEED, 0)
(Compra, RESEED, 0)
(Kardex, RESEED, 0)

5. Realicemos una compra


6. En salida mercanca y traslados el dgv tiene idpto, descripcin, cantidad
Y CONSULTA KARDEX(FECHA DOC, ENTRADA, SALIDA, SALDO,
ULTMICOSTO, COSTOPROM

1. Hacer en el proyecto Windows la clase detalleSalida

public int IdProducto { get; set; }


public string Descripcion { get; set; }
public float Cantidad { get; set; }

2. Agregar al cad salida y salidaDetalle


class DetalleSalida
{
public int IdProducto { get; set; }
public string Descripcion { get; set; }
public float Cantidad { get; set; }
}
3. Agregar List<DetalleSalida> misSalidas = new
List<DetalleSalida>();
4. El list tambin puede ser el origen de datos de la gv de
compras le cambiamos el nombre a esa gv por
DetalleSalidaDataGridView y cuando se entre al formulario y
cuando haga load se copia lo ste
ProductoLabel.Text = string.Empty;
DetalleSalidaDataGridView.DataSource = misSalidas;
ConceptoComboBox.SelectedIndex = -1;
BodegaComboBox.SelectedIndex = -1;

INSERT INTO [dbo].[Salida] ([Fecha], [IdConcepto],


[IdBodega]) VALUES (@Fecha, @IdConcepto,
@IdBodega);
SELECT IdSalida, Fecha, IdConcepto, IdBodega FROM
Salida WHERE (IdSalida = SCOPE_IDENTITY())
SELECT IdLinea, IdSalida, IdProducto, Descripcion,
Cantidad, IdKardex
FROM dbo.SalidaDetalle1
WHERE IdSalida = @IdSalida

Video 14 Listados y reportes parte 1


1. Los reportes permiten mostrar informacin que se pueden consultar por
pantalla y exportarla a Excel , pdf o imprimirla
2. Agregar nuevo elementos reporting cristal reports
3. Esa opcin no esta normalmente en el visual toca instalarlo
4. Se agrupa todo por carpetas
5. Realizamos listados los cuales yienen dos objetos el cristal repor que es el
reporte y un formulario que permita visualizar reporte en pantalla antes de
imprimirlo
6. Agregamos en la opcin reporting cristal report llama cryListadosProductos
aceptar
Datos del proyecto ado net dataset aplcome pto ste agregar
todo menos notas e imagen no elegir nada para agrupar ste sin filtros
ste borde rojo azul ste
7. Para verlo anecesita agregar form frmListadoProductos

8. Del cuadro de hmientas agregamos un panel que ocupe casi todo el form y
luego un crystalReportViewer Y UN BOTON EN LA PARTE DE ARRIBA
9. EN EL PPAL UN AGREGAMOS AL MEMU REPORTES LA OPCION LISTADOS

Video 14 Listados y reportes parte 2


cryListadosProductos miReporte = new cryListadosProductos(); //creamos objeto reporte
DSAplicacionComercial miDS = new DSAplicacionComercial();//creamos onjeto ds
ProductosTableAdapter miAdaptador = new ProductosTableAdapter();//ceo adaptado
miAdaptador.Fill(miDS.Productos); //Llenar ds con adaptador
miReporte.SetDataSource(miDS); //Decirle al reporte que use los datos
crystalReportViewer1.ReportSource = miReporte;
10. Cambiar instruccin en el app.config colocar esto
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>

11.Probar que esas instrucciones es lo que permite ver el reporte


12.Min 11:21 mejorara reporte
13.Borra ese ejemplo de reporte para mejorarlo y creamos una consulta
SELECT
Departamento.Descripcion AS Departamento, Productos.IdProducto,
Productos.Descripcion, IVA.Descripcion AS IVA, Productos.Precio, Productos.IdMedida,
Productos.Medida
FROM
Departamento INNER JOIN
Productos ON Departamento.IdDepartamento = Productos.IdDepartamento
INNER JOIN
IVA ON Productos.IdIVA = IVA.IdIVA
14. Como tiene campos creados se debe crear un adaptador
15. En el ds de la aplicacin win creamos un nuevo table adapter con uso de instrucciones
sql donde copiamps la consulta abterior se deja con las 2 opciones seleccionadas y
finalizar le colocamos nombre de listadoProductos

Video 15 Listados y reportes parte 3


1. Agregagamos de nuevo el reporte
2. Cogemos la tabla creado que lo agrupe por dep que no tatalice que no haya filtro opcin
borde rojo azul y finalizar
3. Cambiamos el codigo del botn ver reporte por este
private void VerReporteButton_Click(object sender, EventArgs e)
{
cryListadosProductos miReporte = new cryListadosProductos();
DSAplicacionComercial miDS = new DSAplicacionComercial();
ListadoProductosTableAdapter miAdaptador = new ListadoProductosTableAdapter();
miAdaptador.Fill(miDS.ListadoProductos);
miReporte.SetDataSource(miDS);
crystalReportViewer1.ReportSource = miReporte;
}
4. Para hacer filtrod
5. Agregamos checkbox que lo ponemoscon prop checked en true y lo llamamos todos

6. Agregamos label llama departamento y un combobox lo enlazamos


7. Se aregla orden de tabulacin
8. En el ds de listadopto agregamos el ste filtro
SELECT Departamento.Descripcion AS Departamento, Productos.IdProducto,
Productos.Descripcion, IVA.Descripcion AS IVA, Productos.Precio, Productos.IdMedida,
Productos.Medida
FROM Departamento
INNER JOIN Productos ON Departamento.IdDepartamento = Productos.IdDepartamento
INNER JOIN IVA ON Productos.IdIVA = IVA.IdIVA
WHERE Producto.IdDepartamento = @IdDepartamento como consulta una instruccin sql
SELECT Departamento.Descripcion AS Departamento, Productos.IdProducto,
Productos.Descripcion, IVA.Descripcion
AS IVA, Productos.Precio, Medida.Descripcion AS [Unidad de medida], Productos.Medida
FROM Departamento
INNER JOIN Productos ON Departamento.IdDepartamento = Productos.IdDepartamento
INNER JOIN IVA ON Productos.IdIVA = IVA.IdIVA
INNER JOIN Medida ON Productos.IdMedida = Medida.IdMedida
WHERE Productos.IdDepartamento = @IdDepartamento
9. Em e cpdogp agregar lo ste
ListadoProductosTableAdapter miAdaptador = new ListadoProductosTableAdapter();
if (TodoscheckBox.Checked)
{
miAdaptador.Fill(miDS.ListadoProductos); //se metio en el if
}
else
{
miAdaptador.FillBy(miDS.ListadoProductos,
(int)DepartamentoComboBox.SelectedValue);
}
miReporte.SetDataSource(miDS); //
crystalReportViewer1.ReportSource = miReporte;
10. Probar
11.

Video 16 Listados y reportes parte 4


1. En el formulario ptos en la barra de hmientas crear un nuevo botn para
listado

private void PrintToolStripButton_Click(object sender, EventArgs e)


{
frmListadoProductos miForm = new frmListadoProductos();
miForm.Show();
}

2. Hacer un reporte de vtas hacemos una consulta

SELECT Venta.Fecha, Venta.IdCliente, Cliente.NombreComercial, Venta.IdBodega,


Bodega.Descripcion AS DescripcionBodega, Venta.IdVenta, VentaDetalle.IdProducto,
VentaDetalle.Descripcion AS DescripcionProducto, VentaDetalle.Precio,
VentaDetalle.Cantidad, VentaDetalle.PorcentajeIVA, VentaDetalle.PorcentajeDescuento,
(VentaDetalle.Precio * VentaDetalle.Cantidad) AS ValorBruto,
(VentaDetalle.Precio * VentaDetalle.Cantidad)/ (1 + VentaDetalle.PorcentajeIVA) AS
ValorBase,
(VentaDetalle.Precio * VentaDetalle.Cantidad) - ((VentaDetalle.Precio *
VentaDetalle.Cantidad)/ (1 + VentaDetalle.PorcentajeIVA)) AS ValorIVA,
(((VentaDetalle.Precio * VentaDetalle.Cantidad) / (1 + VentaDetalle.PorcentajeIVA) +
(VentaDetalle.Precio * VentaDetalle.Cantidad) - ((VentaDetalle.Precio *
VentaDetalle.Cantidad)/ (1 + VentaDetalle.PorcentajeIVA))) *
VentaDetalle.PorcentajeDescuento) AS ValorDescuento,
VentaDetalle.Precio * VentaDetalle.Cantidad - (((VentaDetalle.Precio *
VentaDetalle.Cantidad) / (1 + VentaDetalle.PorcentajeIVA) +
(VentaDetalle.Precio * VentaDetalle.Cantidad) - ((VentaDetalle.Precio *
VentaDetalle.Cantidad)/ (1 + VentaDetalle.PorcentajeIVA))) *
VentaDetalle.PorcentajeDescuento)
AS ValorAPagar
FROM Venta INNER JOIN
VentaDetalle ON Venta.IdVenta = VentaDetalle.IdVenta INNER JOIN
Cliente ON Venta.IdCliente = Cliente.IdCliente INNER JOIN
Bodega ON Venta.IdBodega = Bodega.IdBodega
Select * from VentaDetalle

Video 17 Listados y reportes parte 5


1. Hacer un nuevo dataAdapter en el ds Windows para colocar consulta en
un nuevo dataadapter que llamamos ReporteVentas
2. Vamos hacer el cristalReport que utilice este tableAdapter
3. Cpja el tableAdapter creado todos los campos agrupe por fecha y
cliente y vta
4. Sume cantidad y los dif valores en cada nivel
5. Grupo a ordenar Ninguno
6. Sin grafico
7. Filtros no se escoge ninguno mejor hacerlos por codigo
8. Seccin 1 encabezado de informe colocarle titulo en el cuadro de
hmientas escoger objeto de texto y colocarle titulo reporte de ventas 14
y negrita
9. groupHeaderSection1 borrar cuadro que aparece ah y en los otros
encabezados tambien
10.pasar cuadro de fecha de seccin 2 a headerseccion1 y el cuadro de
fecha de seccion3 a headerSeccion1
11.sigue todo lo q tiene que ver con el cliente el IdCLiente pasarlo de la
seccin 2 a header seccion2 y el idcliente de detalles pasarlo a
headerSeccion2
12.el idventa seccin 2 pasarlo a headerSeccion 3 y el idventa de detalle a
headerseccion3
13.NombreComercial de seccion2 pasarlo a headerseccion2 y
nombrecomercial de detalle a headerseccion2

14.Descrpcionbodega de seccin 3 a headerseccion2


15.Los encabexados de la seccion2 desde descrpcion pasarlos a header
seccion3

Video 18 Listados y reportes parte 6


1. Agregar un formulario colocarle frmReporteVentas
2. Agregar del cuadro de hmientas un panel con anchor todas las esquinas
que ocupe cas toda la pantalla
3. Dentro del panel colocamos el cristaReportViewer
4. Agregar botn ver reporte con el ste codigo

private void VerReporteButton_Click(object sender, EventArgs e)


{
cryReporteVentas miReporte = new cryReporteVentas();
DSAplicacionComercial miDS = new DSAplicacionComercial();
ReporteVentasTableAdapter miAdaptador = new ReporteVentasTableAdapter();
miAdaptador.Fill(miDS.ReporteVentas);
miReporte.SetDataSource(miDS);
crystalReportViewer1.ReportSource = miReporte;
}

5. En el ppal llamarlo

private void ventasToolStripMenuItem1_Click(object sender, EventArgs e)


{

frmReporteVentas miform = new frmReporteVentas();


miform.MdiParent = this;
//miform.UsuarioLogueado = usuarioLogueado;
miform.Show();

6. Probar
7. Como sale error en el ds no solo dejar de clave 1ria el idventa si no que
adicionarle fevha
8. Vamos hacer filtros en el ds en reporteVentas agregamos nueva consulta
usar instrucciones sql select que devuelve filas

Video 19 Listados y reportes parte 7


1. Adicionar al codigo que sale por defecto WHERE Venta.IdCliente =
@IdCliente para adicionar el filtro por IdCliente y agregar otra consulta
agregarle esto WHERE Venta.IdVenta = @IdVenta
2. Usar las consultas creadas
3. Colocar en el formulario de reporteVentas un groupbox con tres
radioboton que son sin filtro por cliente y por venta y sin filtro la prop
checked en true
4. Adicionar un combox y ligarlo a cliente Y UN NUMERICUPDOWN para vta
y ponerles prop visible false

5. Crear mtodo actualizaFiltro(); y llamarlo en los tres radiobutton

private void ActualizaFiltro()


{
if (SinFiltroRadioButton.Checked)
{
ClienteComboBox.Visible = false;
VentaNumericUpDown.Visible = false;
}
else if (PorClienteRadioButton.Checked)
{
ClienteComboBox.Visible = true;
VentaNumericUpDown.Visible = false;
}
else
{
ClienteComboBox.Visible = false;
VentaNumericUpDown.Visible = true;
}
}

6. El botn de verreporte queda asi

private void VerReporteButton_Click(object sender, EventArgs e)


{
cryReporteVentas miReporte = new cryReporteVentas();
DSAplicacionComercial miDS = new DSAplicacionComercial();
ReporteVentasTableAdapter adaptador = new ReporteVentasTableAdapter();
if (SinFiltroRadioButton.Checked)
{
adaptador.Fill(miDS.ReporteVentas);
}
else if (PorClienteRadioButton.Checked)
{
adaptador.FillByIdCliente(miDS.ReporteVentas,
(int)ClienteComboBox.SelectedValue);
}
else
{
adaptador.FillByIdVenta(miDS.ReporteVentas, (int)VentaNumericUpDown.Value);
}
miReporte.SetDataSource(miDS);
crystalReportViewer1.ReportSource = miReporte;
}

7. Poner esto al principio del formulario

public partial class frmReporteVentas : Form


{
private int idVenta;

public int IDVenta


{
}

get { return idVenta; }


set { idVenta = value; }

8. En el load colocar lo ste

private void frmReporteVentas_Load(object sender, EventArgs e)


{
// TODO: esta lnea de cdigo carga datos en la tabla 'dSAplicacionComercial.Cliente'
Puede moverla o quitarla segn sea necesario.
this.clienteTableAdapter.Fill(this.dSAplicacionComercial.Cliente);
if (idVenta != 0)
{
cryReporteVentas miReporte = new cryReporteVentas();
DSAplicacionComercial miDS = new DSAplicacionComercial();
ReporteVentasTableAdapter adaptador = new ReporteVentasTableAdapter();
adaptador.FillByIdVenta(miDS.ReporteVentas, idVenta);
miReporte.SetDataSource(miDS);
crystalReportViewer1.ReportSource = miReporte;
}
}

9. En el formulario de ventas cuando se haga una venta quiero que me


muestre el reporte por lo que en ese formulario de venta agrego lo ste
debajo del codigo del botn grabar despus del mensaje y antes de las
variables de total

MessageBox.Show(string.Format("La venta: {0}, fue grabada de forma exitosa", IDVenta),


"Confirmacin", MessageBoxButtons.OK, MessageBoxIcon.Information);
frmReporteVentas miReporte = new frmReporteVentas();
miReporte.IDVenta = IDVenta;
miReporte.Show();
totalBruto = 0;
totalDescuento = 0;
totalIVA = 0;
totalNeto = 0;
pbxImagen.Image = null;
10. Probar que cuando se realice una venta salga el reporte

Video 20 Listados y reportes parte 8


Se esta construyendo un SI
-

Se hizo modulo de seguridad sencillo


CRUD

Sistema que permite hacer compras, vtas, traslados, dev, salidas,


inventarios fsicos una serie de operaciones

Para que sea SI debe responder preguntas los datos volverlos informacin
Con el reporte de ventas se reponde pregunta de
- cuanto he vendido?
- Cuanto vale mi inventario?
- Cual fue mi utilidad?
- Cuales ptos me generan perdidas?
- Cuales ptos tienen inventario negativo?
- Cuanto me han valido las salidas de mercanca?
- Cuanto me valio el ajuste de inventario?
- Cuales artculos tienen mayor rotacin?
- Cuales deberan ser mis precios para obtener la utilidad deseada?
1. Se empieza creando una consulta en una vista en sql para saber cuanto
vale mi inventario hacemos una vista que diga de todos los artculos cual
es el ultimo costo, costo promedio y saldo de los artculos escojemos la
tabla kartex
2. Quiero consulta que muestre todos los datos del Kardex

SELECT
FROM

TOP (100) PERCENT IdBodega, IdProducto, MAX(Fecha) AS Fecha


dbo.Kardex

GROUP BY IdBodega, IdProducto llamomos ultimoKardex1


3. Otra vista con la tabla Kardex y la vidta creada

SELECT
dbo.Kardex.IdBodega, dbo.Bodega.Descripcion AS Bodega,
dbo.Kardex.IdProducto, dbo.Productos.Descripcion AS Producto,
dbo.Kardex.Saldo, dbo.Kardex.UltimoCosto, dbo.Kardex.CostoPromedio
FROM

dbo.Kardex INNER JOIN

dbo.UltimoKardex1 ON dbo.Kardex.IdBodega =
dbo.UltimoKardex1.IdBodega AND dbo.Kardex.IdProducto =
dbo.UltimoKardex1.IdProducto AND dbo.Kardex.Fecha =
dbo.UltimoKardex1.Fecha INNER JOIN
dbo.Bodega ON dbo.Kardex.IdBodega = dbo.Bodega.IdBodega
INNER JOIN
dbo.Productos ON dbo.Kardex.IdProducto =
dbo.Productos.IdProducto

4. Con eso se tiene el inventario valorizado a ultimo costo se puede saber


cuanto vale inventario multiplicando saldo * ultimoCosto y si se
multiplica el saldo por costo promedio da el inventario valorizado a costo
prom

Video 21 Listados y reportes parte 9


1. Haremos inventario a costo promedio
2. Esa vista colocarla en consulta ctl + h reemplazar dbo. Por espacio vacio
y reemplazar doble espaciop por espacio queda asi como se valoriza
costo prome se elimina ultimo costo y se adiciona la mult del saldo por el
costo prom crando nueva columna llamada valor inventario

Para costo promedio


SELECT Kardex.IdBodega, Bodega.Descripcion AS Bodega, Departamento.IdDepartamento,
Departamento.Descripcion AS Departamento,
Kardex.IdProducto, Productos.Descripcion AS Producto,
Kardex.Saldo, Kardex.CostoPromedio AS Costo, Kardex.Saldo* Kardex.CostoPromedio AS
ValorInventario
FROM Kardex INNER JOIN
UltimoKardex1 ON Kardex.IdBodega = UltimoKardex1.IdBodega AND Kardex.IdProducto =
UltimoKardex1.IdProducto AND Kardex.Fecha = UltimoKardex1.Fecha INNER JOIN
Bodega ON Kardex.IdBodega = Bodega.IdBodega INNER JOIN
Productos ON Kardex.IdProducto = Productos.IdProducto INNER JOIN
Departamento ON Productos.IdDepartamento = Departamento.IdDepartamento
Para ultimo costo
SELECT Kardex.IdBodega, Bodega.Descripcion AS Bodega, Departamento.IdDepartamento,
Departamento.Descripcion AS Departamento,
Kardex.IdProducto, Productos.Descripcion AS Producto,
Kardex.Saldo, Kardex.UltimoCosto AS Costo, Kardex.Saldo* Kardex.UltimoCosto AS
ValorInventario
FROM Kardex INNER JOIN
UltimoKardex1 ON Kardex.IdBodega = UltimoKardex1.IdBodega AND Kardex.IdProducto =
UltimoKardex1.IdProducto AND Kardex.Fecha = UltimoKardex1.Fecha INNER JOIN
Bodega ON Kardex.IdBodega = Bodega.IdBodega INNER JOIN
Productos ON Kardex.IdProducto = Productos.IdProducto INNER JOIN
Departamento ON Productos.IdDepartamento = Departamento.IdDepartamento

3. Como valorizamos inventario a costo


4. Ya esta lista la consulta
5. Vamos al ds de Windows agregamos un tableAdapter Creamos ds que
sirva para filtrar ese query y que lo llamamos
ReporteValorInventarioCostoPromedio al data set cuando termine de
crearlo es cambiarle nombre y hacemos lo mismo para la consulta de
ultimo costo que solo tendra un cambio con respecto a ese campo
6. Creamos el reporte llamamos cryReporteValorInventario que utilice la
tabla de reporteCostoProm ste todos los campos totalicepor codigo
de bodega dentro de bodega por codigo de departamentp que sume
saldo y valor inventario no agrupr sin graficos sin filtros tojoazul finalizar

Video 22 Listados y reportes parte 10


1. Colocarle titulo al reporte Valor de inventario en la seccion1:
encabezado del informe
2. Borrar lo que esta en encabezado de grupo 1 y 2
3. De detalles pasar codigo y nombre de bodega a encabezado de
grupo 1
4. De detalles pasar codigo y descripcin de departamento a
encabezado de grupo 2
5. Seccion2 borrar bodega y departamento los cuadritos
6. Cuadrar el resto de los cuadros en la seccin 3 detalles
7. Borrar del pie de gurpo 2 y 3 el cuadro nombre
8. Crear el formulario
9. Agregar panel y el cristalReportViewer y el botn de ver
reporte

private void VerReporteButton_Click(object sender, EventArgs e)


{
cryReporteValorInventario miReporte = new cryReporteValorInventario();
DSAplicacionComercial miDS = new DSAplicacionComercial();
ReporteValorInventarioCostoPromedioTableAdapter adaptador = new
ReporteValorInventarioCostoPromedioTableAdapter();
adaptador.Fill(miDS.ReporteValorInventarioCostoPromedio);
miReporte.SetDataSource(miDS);
crystalReportViewer1.ReportSource = miReporte;
}

10.Colocar groupbox llamado valorizacin y dos radiobutton para


costoprom y ultimocosto
11.El ver reporte queda de la ste forma

private void VerReporteButton_Click(object sender, EventArgs e)


{
cryReporteValorInventario miReporte = new cryReporteValorInventario();
DSAplicacionComercial miDS = new DSAplicacionComercial();
if (CostoPromedioRadioButton.Checked)
{
ReporteValorInventarioCostoPromedioTableAdapter adaptador = new
ReporteValorInventarioCostoPromedioTableAdapter();
adaptador.Fill(miDS.ReporteValorInventarioCostoPromedio);
}
else
{
ReporteValorInventarioUltimoCostoTableAdapter adaptador = new
ReporteValorInventarioUltimoCostoTableAdapter();
adaptador.Fill(miDS.ReporteValorInventarioUltimoCosto);
}
miReporte.SetDataSource(miDS);
crystalReportViewer1.ReportSource = miReporte;

Video 23 Listados y reportes parte 11


1.

hacer todo de nuevo pero con ultimo costo

private void VerReporteButton_Click(object sender, EventArgs e)


{
if (CostoPromedioRadioButton.Checked)
{
cryValorInventarioCostoPromedio miReporte = new
cryValorInventarioCostoPromedio();
DSAplicacionComercial miDS = new DSAplicacionComercial();
ReporteValorInventarioCostoPromedioTableAdapter adaptador = new
ReporteValorInventarioCostoPromedioTableAdapter();
adaptador.Fill(miDS.ReporteValorInventarioCostoPromedio);
miReporte.SetDataSource(miDS);
crystalReportViewer1.ReportSource = miReporte;
}
else
{
cryValorInventarioUltimoCosto miReporte = new cryValorInventarioUltimoCosto();
DSAplicacionComercial miDS = new DSAplicacionComercial();
ReporteValorInventarioUltimoCostoTableAdapter adaptador = new
ReporteValorInventarioUltimoCostoTableAdapter();
adaptador.Fill(miDS.ReporteValorInventarioUltimoCosto);
miReporte.SetDataSource(miDS);
crystalReportViewer1.ReportSource = miReporte;

}
}
2. Hacemos filtros
3. Creamos otro group box llamado bodegas donde aadimos un checkbox con prop
checked en true y que llamamos todas y un combobox al lado con enable en false y
lo enlazamos con bodegas
4. Al hacer clic en el checkbox copiamos lo ste

private void TodasLasBodegasCheckBox_CheckedChanged(object sender, EventArgs e)


{
if (TodasLasBodegasCheckBox.Checked)
{
BodegasComboBox.Enabled = false;
}
else
{

BodegasComboBox.Enabled = true;

Video 24 Listados y reportes parte 12


1. Hacer otro groupbox de saldos con 3 radiobutton de todos, positivos y
negativos
2. Vamos al ds del proyecto win en reportecostoprom agregamos consulta
con instruccin sql
Para inventarioCostoPromedio
SELECT Kardex.IdBodega, Bodega.Descripcion AS Bodega,
Productos.IdDepartamento,
Departamento.Descripcion AS Departamento, Kardex.IdProducto,
Productos.Descripcion AS Producto,
Kardex.Saldo, Kardex.CostoPromedio AS Costo, Kardex.Saldo*
Kardex.CostoPromedio AS ValorInventario
FROM Kardex INNER JOIN
UltimoKardex1 ON Kardex.IdBodega = UltimoKardex1.IdBodega AND
Kardex.IdProducto = UltimoKardex1.IdProducto AND
Kardex.Fecha = UltimoKardex1.Fecha INNER JOIN
Bodega ON Kardex.IdBodega = Bodega.IdBodega INNER JOIN
Productos ON Kardex.IdProducto = Productos.IdProducto INNER JOIN
Departamento ON Productos.IdDepartamento = Departamento.IdDepartamento
WHERE Kardex.IdBodega = @IdBodega
Llamado fiibyIdBodega y GetDataIdBodega

Para saldos positivos


SELECT Kardex.IdBodega, Bodega.Descripcion AS Bodega,
Productos.IdDepartamento,
Departamento.Descripcion AS Departamento, Kardex.IdProducto,
Productos.Descripcion AS Producto,
Kardex.Saldo, Kardex.CostoPromedio AS Costo, Kardex.Saldo*
Kardex.CostoPromedio AS ValorInventario
FROM Kardex INNER JOIN

UltimoKardex1 ON Kardex.IdBodega = UltimoKardex1.IdBodega AND


Kardex.IdProducto = UltimoKardex1.IdProducto AND
Kardex.Fecha = UltimoKardex1.Fecha INNER JOIN
Bodega ON Kardex.IdBodega = Bodega.IdBodega INNER JOIN
Productos ON Kardex.IdProducto = Productos.IdProducto INNER JOIN
Departamento ON Productos.IdDepartamento = Departamento.IdDepartamento
WHERE Kardex.Saldo >= 0 y para saldos negativos seria WHERE Kardex.Saldo
< 0 el resto queda igual fiibyPositivos

Se pueden hacer por bodega y saldo cambiaria el where


WHERE Kardex.IdBodega = @IdBodega AND Kardex.Saldo >=0
WHERE Kardex.IdBodega = @IdBodega AND Kardex.Saldo <0 llamados
IdBodegaAndNegativos
3. Vamos al formulario de inventario y aadimos el siguiente codigo

if (CostoPromedioRadioButton.Checked)
{
cryValorInventarioCostoPromedio miReporte = new
cryValorInventarioCostoPromedio();
DSAplicacionComercial miDS = new DSAplicacionComercial();
ReporteValorInventarioCostoPromedioTableAdapter adaptador = new
ReporteValorInventarioCostoPromedioTableAdapter();
if (TodasLasBodegasCheckBox.Checked && TodosRadioButton.Checked)
{
adaptador.Fill(miDS.ReporteValorInventarioCostoPromedio);
}
else if (TodasLasBodegasCheckBox.Checked && PositivosRadioButton.Checked)
{
adaptador.FillByPositivos(miDS.ReporteValorInventarioCostoPromedio);
}
else if (TodasLasBodegasCheckBox.Checked && NegativosRadioButton.Checked)
{
adaptador.FillByNegativos(miDS.ReporteValorInventarioCostoPromedio);
}
else if (!TodasLasBodegasCheckBox.Checked && TodosRadioButton.Checked)
{
adaptador.FillByIdBodega(miDS.ReporteValorInventarioCostoPromedio,
(int)BodegasComboBox.SelectedValue);
}
else if (!TodasLasBodegasCheckBox.Checked && PositivosRadioButton.Checked)
{

adaptador.FillByIdBodegaAndPositivos(miDS.ReporteValorInventarioCostoPromedio,
(int)BodegasComboBox.SelectedValue);
}
else
{
adaptador.FillByIdBodegaAndNegativos(miDS.ReporteValorInventarioCostoPromedio,
(int)BodegasComboBox.SelectedValue);
}
miReporte.SetDataSource(miDS);
crystalReportViewer1.ReportSource = miReporte;
}
Hacer para ultimo costo las mismas consultas y el codigo anterior sirve tambin

Video 25 Listados y reportes parte 13


1. Hacer reporte para saber utilidad
2. Realizar consulta con vista en sql para ultimoCosto y costoProm que solo
cambiaria esa columna

SELECT Venta.Fecha, Venta.IdBodega, Bodega.Descripcion AS Bodega,


VentaDetalle.IdProducto, VentaDetalle.Descripcion AS Producto, VentaDetalle.Cantidad,
Kardex.CostoPromedio AS Costo, VentaDetalle.Precio, VentaDetalle.Cantidad *
VentaDetalle.Precio - VentaDetalle.Cantidad * Kardex.CostoPromedio AS Utilidad
FROM Venta INNER JOIN
VentaDetalle ON Venta.IdVenta = VentaDetalle.IdVenta INNER JOIN
Bodega ON Venta.IdBodega = Bodega.IdBodega INNER JOIN
Kardex ON VentaDetalle.IdKardex = Kardex.IdKardex

3. Vamos al ds para agregar eltable adapter con la consulta realizada que


lo llamaremos utilidadUltimoCosto y utilidadACostopromedio
4. Crear el cristal para utlidad a costo prom y a ultimo costo reporte
estndar utilizando el ds correspondiente de utilidad mostrar todos
los campos agrupe por fecha. Idbodega, idpto totalizar solo cantidad
y utilidad ninguno sin grfico sinfiltros borde rojo azul
5. Organizarlos
6. Agregarles ttulos
7. Quitar los encabezados de grupo 1,2,3
8. Fecha de detalle pasarle a encabezado de grupo 1
9. Bodega y nombre de bodega pasarlo de detalle a encabezado de grupo2
10.Producto y el nombre pasarlo de detalle a encabezado de grupo3
11.Eliminar ttulos de la seccin 2 desde fecha hasta pto

Video 26 Listados y reportes parte 14


1. Colocar del mismo tamao las columnas de cantidad y alinearlas, lo
mismo con costo, precio

2. Crear el formulario para ver el reporte de utilidad este se parece mucho


al de inventario por lo que le ponemos mismo tamao
3. En ver reporte colocar

cryReporteUtilidadCostoPromedio miReporte = new cryReporteUtilidadCostoPromedio();


DSAplicacionComercial miDS = new DSAplicacionComercial();
ReporteUtilidadCostoPromedioTableAdapter miAdaptador = new
ReporteUtilidadCostoPromedioTableAdapter();
miAdaptador.Fill(miDS.ReporteUtilidadCostoPromedio);
miReporte.SetDataSource(miDS);
crystalReportViewer1.ReportSource = miReporte;
cryReporteUtilidadUltimoCosto miReporte = new cryReporteUtilidadUltimoCosto();
DSAplicacionComercial miDS = new DSAplicacionComercial();
ReporteUtilidadUltimoCostoTableAdapter miAdaptador = new
ReporteUtilidadUltimoCostoTableAdapter();
miAdaptador.Fill(miDS.ReporteUtilidadUltimoCosto);
miReporte.SetDataSource(miDS);
crystalReportViewer1.ReportSource = miReporte;
4, en men ppal colocar

private void UtilidadToolStripMenuItem4_Click(object sender, EventArgs e)


{
frmReporteUtilidad miform = new frmReporteUtilidad();
miform.MdiParent = this;
//miform.UsuarioLogueado = usuarioLogueado;
miform.Show();
}

4. Hacer los filtros el de valorizacin a costoPromedio y a ultimoCosto, por


fecha con un checkbox de todos y un datetimepicker y el de costos
todos, cero, positivo
5. Como la fecha da con minutos y segundos toca botar esa parte o si no
no deja hacer el filtro hacer consulta que convierta la fecha y la deje sin
horas, min y segundos

SELECT Venta.Fecha, Venta.IdBodega, Bodega.Descripcion AS Bodega,


VentaDetalle.IdProducto, VentaDetalle.Descripcion AS Producto, VentaDetalle.Cantidad,
Kardex.UltimoCosto AS Costo,
VentaDetalle.Precio, VentaDetalle.Cantidad * VentaDetalle.Precio - VentaDetalle.Cantidad *
Kardex.UltimoCosto AS Utilidad
FROM Venta INNER JOIN
VentaDetalle ON Venta.IdVenta = VentaDetalle.IdVenta INNER JOIN
Bodega ON Venta.IdBodega = Bodega.IdBodega INNER JOIN
Kardex ON VentaDetalle.IdKardex = Kardex.IdKardex
WHERE CONVERT(DATE, Venta.Fecha) = @Fecha
6. Hacer filtro de costos

Video 27 Creacion capa BL parte 1


1. Se crea un capa de lgica del negocio es una capa adicional intermedia
se relaciona con el proyecto CAD , con el proyecto Windows por lo que
quedara como primera capa la capa de datos, la 2da la de BL y la 3ra la
capa de presentacin de usuario
2. La aplicacin web aparte de que se conecta con el CAD se conecta con
la capa de lgica del negocio
3. En BL se guarda lgica brava del proyecto (grabar compra, vta,
traslados), que a su vez es lgica que se conecta mucho con el CAD
4. Si se hace de esta manera el grabar compra por ejemplo para la
aplicacin web no va a tocar copiar y pegar todo el codigo y modificarlo
simplemente se hacen validaciones en la aplicacin web porque son
diferentes a las hechas en la aplicacin Windows
5. El web service se concta con el CAD y con la aplicacin WEB
6. La aplicacin mvil necesita el web service
7. Copiar pantallazo
8. En grabar de compra adicionar lo ste

int IDBodega = (int)BodegaComboBox.SelectedValue;


int IDProveedor = (int)ProveedorComboBox.SelectedValue; // se hace para no estarlo
casteando a cada rato
DateTime Fecha = FechaDateTimePicker.Value;

//grabamos cencabezado de la compra


int IDCompra = CADCompra.InsertCompra(Fecha,
IDProveedor, IDBodega);

9. Crear un mtodo independiente de grabar compra

DateTime Fecha = FechaDateTimePicker.Value;


int IDCompra = GrabarCompra(IDBodega, IDProveedor, Fecha, misDetalles);
//grabamos cencabezado de la compra
int IDCompra = CADCompra.InsertCompra(Fecha,
IDProveedor, IDBodega);

10.Dentro del mtodo creado copiamos todo lo de grabar compra desde


encabezado compra hasta antes del messagebox

private int GrabarCompra(int IDBodega, int IDProveedor, DateTime Fecha,


List<DetalleCompra> misDetalles)
{
//grabamos encabezado de la compra

int IDCompra = CADCompra.InsertCompra(Fecha,


IDProveedor, IDBodega);
//grabamos detalle de la compra recorrer la lista
foreach (DetalleCompra miDetalle in misDetalles)
{
//consultar saldo de pto en una bodega hacer un metodo que nos devuelva
detalle de un pto en una bodega con el metodo getbodegaProductoBIdpto que nos devuelva
el dellae en esa bodega de un pto
CADBodegaProducto miBodegaProducto =
CADBodegaProducto.GetBodegaProductoByIdBodegaAndIdProducto(
IDBodega, miDetalle.IdProducto);
if (miBodegaProducto == null) //actualizamos bodegaPto
{
CADBodegaProducto.UpdateBodegaProducto(IDBodega, miDetalle.IdProducto,
1, 1, 1, 1);
}
CADBodegaProducto.AumentarStock(miDetalle.Cantidad, IDBodega,
miDetalle.IdProducto); //HUBO CAMBIOS CON RESPECTO A ESTE CODIGO
// actualizamos el kardex
CADKardex miKardex = CADKardex.UltimoKardex(IDBodega,
miDetalle.IdProducto);
int IdKardex;
float nuevoSaldo;
decimal nuevoCostoPromedio;
decimal nuevoUltimoCosto; //adiciona despues
if (miKardex == null)
{
nuevoSaldo = miDetalle.Cantidad;
nuevoCostoPromedio = miDetalle.ValorNeto / (decimal)miDetalle.Cantidad;
nuevoUltimoCosto = nuevoCostoPromedio;
}
else
{

nuevoSaldo = miKardex.Saldo + miDetalle.Cantidad;


nuevoCostoPromedio = (miKardex.CostoPromedio * (decimal)miKardex.Saldo +
miDetalle.ValorNeto) / (decimal)nuevoSaldo;
nuevoUltimoCosto = miDetalle.ValorNeto / (decimal)miDetalle.Cantidad;

IdKardex = CADKardex.InsertKardex(IDBodega, miDetalle.IdProducto,


Fecha, string.Format("CO-{0}", IDCompra), miDetalle.Cantidad, 0,
nuevoSaldo, nuevoUltimoCosto, nuevoCostoPromedio);
// actualizamos compra detalle
CADCompraDetalle.InsertCompraDetalle(IDCompra, miDetalle.IdProducto,
miDetalle.Descripcion,
miDetalle.Costo, miDetalle.Cantidad,
IdKardex, miDetalle.PorcentajeIVA, miDetalle.PorcentajeDescuento);

}
return IDCompra;
}

11.El mtodo grabarCompra ests en el proyecto Windows y lo quiero sacar


de ah que haga parte de otra capa para que sea utilizable
12.Tenemos la solucin aplicacin comercial que en este momento tiene dos
proyectos
- La biblioteca de clases (CAD)
- Proyecto WIN que es la aplicacin de Windows form
13.Agregamos un nuevo proyecto que es una biblioteca de clases que es la
que contiene la lgica del negocio llamado BL

Video 28 Creacion capa BL parte 2


1. Todas las clases del proyecto win llevarlas al proyecto BL
2. Coger el nameespace de class1 y borrar esa clase y cambirselo a las
clases que acabe de copiar y colocarlas todas publicas
3. Agregar referencia en BL para que sea referido al proyecto CAD en
references de BL agregar referecias chulito a CAD
4. EN EL REFERENCES DEL PROYECTO WIND AGREGAR REFERECIAS Y
ELEGIR EL BL
5. En los formularios toca hacer using BL
6. Agregar nueva clase en BL llamada movimientos cogemos el mtodo
grabarCompra lo copiamos en esa nueva clase colocarlo static y piblic
7. El formulario esta lnea cambiarla y dejarla asi
int IDCompra = Operaciones.GrabarCompra(IDBodega, IDProveedor, Fecha, misDetalles);

8. La clase operaciones queda asi

public class Operaciones


{
public static int GrabarCompra(int IDBodega, int IDProveedor, DateTime Fecha,
List<DetalleCompra> misDetalles)
{
//grabamos encabezado de la compra
int IDCompra = CADCompra.InsertCompra(Fecha,
IDProveedor, IDBodega);
//grabamos detalle de la compra recorrer la lista
foreach (DetalleCompra miDetalle in misDetalles)
{
//consultar saldo de pto en una bodega hacer un metodo que nos devuelva
detalle de un pto en una bodega con el metodo getbodegaProductoBIdpto que nos devuelva
el dellae en esa bodega de un pto
CADBodegaProducto miBodegaProducto =
CADBodegaProducto.GetBodegaProductoByIdBodegaAndIdProducto(
IDBodega, miDetalle.IdProducto);

if (miBodegaProducto == null) //actualizamos bodegaPto


{
CADBodegaProducto.UpdateBodegaProducto(IDBodega, miDetalle.IdProducto,
1, 1, 1, 1);
}
CADBodegaProducto.AumentarStock(miDetalle.Cantidad, IDBodega,
miDetalle.IdProducto); //HUBO CAMBIOS CON RESPECTO A ESTE CODIGO
// actualizamos el kardex
CADKardex miKardex = CADKardex.UltimoKardex(IDBodega,
miDetalle.IdProducto);
int IdKardex;
float nuevoSaldo;
decimal nuevoCostoPromedio;
decimal nuevoUltimoCosto; //adiciona despues
if (miKardex == null)
{
nuevoSaldo = miDetalle.Cantidad;
nuevoCostoPromedio = miDetalle.ValorNeto / (decimal)miDetalle.Cantidad;
nuevoUltimoCosto = nuevoCostoPromedio;
}
else
{
nuevoSaldo = miKardex.Saldo + miDetalle.Cantidad;
nuevoCostoPromedio = (miKardex.CostoPromedio * (decimal)miKardex.Saldo +
miDetalle.ValorNeto) / (decimal)nuevoSaldo;
nuevoUltimoCosto = miDetalle.ValorNeto / (decimal)miDetalle.Cantidad;
}
IdKardex = CADKardex.InsertKardex(IDBodega, miDetalle.IdProducto,
Fecha, string.Format("CO-{0}", IDCompra), miDetalle.Cantidad, 0,
nuevoSaldo, nuevoUltimoCosto, nuevoCostoPromedio);
// actualizamos compra detalle
CADCompraDetalle.InsertCompraDetalle(IDCompra, miDetalle.IdProducto,
miDetalle.Descripcion,
miDetalle.Costo, miDetalle.Cantidad,
IdKardex, miDetalle.PorcentajeIVA, miDetalle.PorcentajeDescuento);

}
return IDCompra;

9. Hacerle el cambio al resto de mtodos y copiarlos tambin ah

Video 29 Instalador windows parte 1


1. Hay un app.config por cada capa en este caso 3 y es necesario que solo
alla uno por toda la aplicacin
2. El proyecto CAD tiene un app.config que almacena la conexin de la
base de datos no se puede dejar que el CAD genere string de coneccion
porque cuando se genere el ejecutable el proyecto CAD se genera como
un dll que no tiene archivo de configuracin y si no se hace el cambio el
string de conexin queda quemado
3. Se necesita hacer un instalador y x eso en ese app.config esta en
formato xml(la 1ra lnea) para cuando se instale tambin se le instale la
base de datos al cliente y puede que el servidor del cliente se llame
diferente
4. El proyecto win tiene otro app.config
5. Se pueden hacer dos cosas coger el pedazo de codigo del app.config del
CAD

<add
name="CADAplicacionComercial.Properties.Settings.AplicacionComercialDianaConnectionSt
ring"
connectionString="Data Source=DIANA-PC\SQLEXPRESS;Initial
Catalog=AplicacionComercialDiana;Integrated Security=True"
providerName="System.Data.SqlClient" />

6. COPIAR ESTE CODIGO EN EL APP.CONFIG DE WINDOWS Y


COMENTAREAR ese codigo EN EL APP.COMFIG DEL CAD el app.config de
win queda con el ste codigo aadido

<connectionStrings>
<add
name="AplicacionComercial.Properties.Settings.AplicacionComercialDianaConnectionString"
connectionString="Data Source=DIANA-PC\SQLEXPRESS;Initial
Catalog=AplicacionComercialDiana;Integrated Security=True"
providerName="System.Data.SqlClient" />
<add
name="CADAplicacionComercial.Properties.Settings.AplicacionComercialDianaConnectionSt
ring"
connectionString="Data Source=DIANA-PC\SQLEXPRESS;Initial
Catalog=AplicacionComercialDiana;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>

7. LOS APP.CONFIG No es que se carguen por poryecto sino que el proyecto


ppal (en negrita el cual es el proyecto de inicio) cuando ese proyecto
carga todos los app.config como se comentario el del CAD es como si no
existiera
8. Probar

9. Esos dos string de conexin que quedaron en el win son prcticamente


iguales solo cambia el nombre inicial
10.EL string de conexin en verde lo comentaramos
11.En propiedades del proyecto Windows en la pestaa aplicacion
Nombre del ensamblado: AplicacionComercial
Espacio de nombre predeterminado: AplicacionComercial
Framework: 4.5
Tipo de resultado: ap para Windows
Icono: se puede escoger cualquiera
EN CONFIGURACION ESTA EL STRING DE CONEXIONM
12.Para hacer el ejecutable hacemos un instalador la cual seria otra capa
agregamos nuevo proyecto otros tipos de proyecto instalacin e
implementacin deben salir dos opciones (installShield limited edition
Project y Habilitar pero normalmente solo sale una debe agregar la otra
se llama setupwin
13.La versin de la la aplicacin se maneja asi 1.00.0000 si el cambio el
relativamente importante se le cambia el ultimo digito, si no es tan
importante se le cambia los de 00 y si es muy importante el 1er
nuumero

Video 30 Instalador windows parte 2


-

Seguir los pasos del asistente de proyectos en aplication Information


esta la versin el nombre de la compaa
En instalation requerimientos para que win se va a generar para
todos los win y sin frameworks
Aplication files donde crear el sw cambiar nombre a
aplicacionComercial y le damos en add Project outputs y cojemos
proyecto que tiene la salida que en este caso es el proyecto win y
marcamos resultado principal y ok
En las propiedades del proyecto Windows cambiar el icono para que
no saque error cuando compile el ejecutable creado
Todas las preguntas las dejamos con yes
Tenemos al final que elegir el ejecutable antes de generarlo
SetupWin toca volverlo a construir cuando este todo completo

Video 31 Instalador web empezando y primer CRUD


1. La clase de administracin de usuarios ya no se hara con usuarios y
perfiles si no con unas clases que tiene .net que sellaman la sistema web
security (revizar desarrollo de software parte 14 seguridad web con
sistema security
2. Agregar nuevo proyecto web aplicacin asp.net web form WEB
3. Establecer como proyecto de inicio el proy WEB
4. usuarios para que toda la aplicacin quede vlidando con las tablas del
membership incluso la parte Windows
5. El proyrcto web tiene una carpeta de properties que define propiedades
de la aplicacin
6. En references tiene muchas referencias

7. En la carpeta account estn las pantallas que nos permiten hacer login,
cambio de contrasea, pagina registro
8. En app_data define archivos de configuracin
9. Dntro de content hay un archivo que es el css es el archivo que maneja
estilo de la aplicacin
10.Dentro de themes encontramos estilos de j query
11.Esta carpeta images
12.En scripts hay script de jquery
13.Crea pagina about acerca de y la pagina de contacto
14.Tiene la pagina importante que es el site master que es el encabezado
que tienen todas las paginas
15.Y el web config es donde se guarda la configuracin
16.Vamos a cambiar la bd que trae por defecto ya que si yo quiero coger mi
aplicacin y montarla en servidor web el no es capaz de hacer eso
17.De nuestra bd no usaremos ni la tabla usuario ni rol
18.Pegamos con el memberchip la aplicacin web valida usuarios con
memberships y la aplicacin Windows con la tabla usuarios
19.Vamos a crear web service que valide los usuarios para que toda la
aplicacin valide con membership
20.Creamos un web service y hacemos que la aplicacin Windows consuma
ese web service que es el q da los mtodos de si el usuario es valido o
no y a que roles pertenecen
21.Crear tablas del membersghip vamos a la capeta c Windows
Microsoft.net framework64 v4030319 asp.net_regsql.exe ste ste
nombre servidor: DIANA-PC\SQLEXPRESS base de datos:
AplicacionComercialDiana

Video adicional de web Security


1.crear una aplicacin web con framework 3.5 llamada DemoSeguridad
<div>
<h1>Ingreso al sistema</h1>
</div>

3. Proyecto configuracin de asp.net seguridad puede sacar un error xq


esta intentando crear bd local la intenta crear como bd sql express 2005
4. Vamos al sql crear bd si es necesario
5. Crear tablas del membersghip vamos a la capeta c Windows
Microsoft.net framework64 v4030319 asp.net_regsql.exe ste ste
nombre servidor: DIANA-PC\SQLEXPRESS base de datos:
AplicacionComercialDiana
6. Al proyecto se le debe decir que se conecte a la bs ver explorador de
servidores nueva conexin sql server nombre bd aceptar en
propiedades me muestra cadena de conexin
7. En web.config en conection string donde estn todas las conexiones a
las bd lo debemos poner asi
8. <connectionStrin> aqu se pueden tener una conwxion a varias bd
<remove name= LocalSqlServer/>

<add name=LocalSqlServer //se hace por seguridad quitarlo para que


quite cualquier rastro de conexin vieja//
conectionStrings=aqu se coloca la cadena de conexin que esta en
prop de explorador de servidores
providerName = System.Data.SqlClient/>
</connectionStrings>
9. Proyecto asp.net seguridad sel tipo autentificacin si se le dice
desde internet es decirle que yo quiero que se tenga manejo de usuarios
que ellos se pueden autoregistrar se escoge esa opcin
10.Podemos crear usuario por la opcin que da asp.net el correo electrnico
colocarlo valido
11.Debajo de ingreso al sistema utilizamos botn loginView es un objeto
que tiene dos estado el cual nos muetra unas paginas cuando el usuario
esta logueado y otras cuando no
12.Dentro del loginview definimos dos etiquetas un anonymustemplate es
cuando el usuario no esta logueado y la otra etiqueta es un
loggedInTempalte
13.Si el usuario no esta logueado mostramos ventana de usuario y pass se
arrastra un login
14.Si el usuario esta logueado mostrar un prrafo Bienvenido Nombre del
usuario(se hace con control logginName todo esto se hace dentro un
prrafo
15.Saltamos de lnea con br> y colocamos un logedStatus dice si el usuario
esta logueado parece la opcin de cerrar sesin
16.Se debe dejar en vista de annimos que seria la que inicia
17.Crear opcin para que usuarios puedan autoregistrarse agregamos un
formularioWindowsWebForm llamamos Registrar Usuario entre el div
colocamos una etiqueta de registro de usuario
18.Utilizamos control createUserWizard
19.De donde se llama en la pagina default en propiedades en la propiedad
createUserText le colocamos Registrarse Como nuevo usuario y la
propiedad crateUserUrl marcamos la otra pagina que adicionamos
20.Si yo quiero q despus de haber creado el usuario lo mande a la pagina
ppal en la otra vista del control creareUserWizar le damos doble clic a
botn continuar ah colocar response.redirecr(Pagina aa la cual quiere
uno devolver.aspx) en este caso seria la default y lo vuelvo a cambiar a
la vista de registrarse
21.Toca definir pagina de inicio por defecto clic derecho a la pag de default
y estab como pag ppal
22.Vamos a crear una opcin nueva para gestionar usuarios
23.Crear roles por la configuracin del asp.net la cual se hace por carpetas
segn la carpeta y el rol se sabe cual puede entrar creamos carpeta
llamada zonaAdministracion ah dentro se crea la opcin de admos de
usuarios agregando un nuevo form que se llama GestionUsuarios le
colocamos el titulo de Gestion de Usuarios se separa en una carpeta
para poderle dar permiso

24.En el default cuando el usuario este logueado colocamos link para ir a


esa pagina con un control de linkbutton que en el titulo se coloca
gestin de usuarios se le define la propiedad en vista del modo diseo
seleccionamos el linkbutton y la propiedad postBackUrl y escoger la pag
que creamos que esta dentro de la carpeta
25.Colocamos un br entre los dos lneas de codigo para que no quede
pegado (no olvidar colocar en vista por defecto)
26.Organizar permisos por carpetas
27.Vamos a la conf del asp.net crear o administrar funciones creamos las
funciones adminsitrador y empleado y en usuario uno pued escoger a
que usuario tienen permiso
28.Tambin es necesario crear unas reglas de acceso por defecto aparece
que todos esta pemitido
29.Elegimos la carpeta creamos la regla usuarios con permiso le
permitimos y creamos otra que a todos los usuarios se le niega eso se
lee de arriba para abajo
30.Vamos a adicionar que si yo no tengo permisos para entrar a x pagina no
pueda ver la opcin
31.En la vista diseo el cuadro de loginview en la vista de logedintemplade
el botn de gestin de usuario le colocamos propiedad visible: false
32.En la pagina default en el evento load validamos cuando el formulario
cargue verificamos perfil de usuario hay una clase que se llama las
clases del membership le decimos lo ste
La clase roles no la reconoce por lo que importamos una librera le
ponemos usung system.web.security
If(roles.isUserRole(Administrador))
{
LinkButton link =(LinkButton) LoginView1.FindControl(LinkButton1);
}
Link.visible = true;
33.Arrastramos una gv a la pag de gestin de usuario se le coloca cuando la
pag haga load muestre en el gv todos los usuarios
34.Establecemos propiedad de datasource del dgv
gvUsuarios.datasource = membership.getallUsers();
gvUsuarios.databind();

Video 32 Instalador web empezando y primer CRUD


1. Sigue el asistente la idea es crear las tablas de seguridad a la
aplicacin comercial
2. En la aplicacin comercial cambia la cadena de conexin
cambbiamos este

<connectionStrings>
<add name="DefaultConnection" providerName="System.Data.SqlClient"
connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-WEB20151103104610;Integrated Security=SSPI;AttachDBFilename=|
DataDirectory|\aspnet-WEB-20151103104610.mdf" />
</connectionStrings>

Por este
<connectionStrings>
<add name="DefaultConnection"
connectionString="Data Source=DIANA-PC\SQLEXPRESS;Initial
Catalog=AplicacionComercialDiana;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
<connectionStrings>
<add name="DefaultConnection" providerName="System.Data.SqlClient"
connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-WEB20151103184853;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetWEB-20151103184853.mdf" />
<add name="DefaultConnection" connectionString="Data
Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\aspnet-WEB20151103184853.mdf;Initial Catalog=aspnet-WEB-20151103184853;Integrated
Security=True;User Instance=True" providerName="System.Data.SqlClient" />
</connectionStrings>

3. Probamos y creamos un usuario


4. <connectionStrings>
5.
<add name="DefaultConnection" providerName="System.Data.SqlClient"
connectionString="Data Source=(LocalDb)\v11.0;
6.
Initial Catalog=aspnet-WEB-20151103184853;Integrated
Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-WEB20151103184853.mdf" />
7.
8.
</connectionStrings>
9. <!--

Вам также может понравиться