Utilizamos cookies propias y de terceros. [Más información sobre las cookies].
Política de cookies
Proyecto AjpdSoft

· Inicio
· Buscar
· Contactar
· Cookies
· Descargas
· Foros
· Historia
· Nosotros
· Temas
· Top 10
· Trucos
· Tutoriales
· Wiki

Programación: Cómo programar control de stock (existencias) de artículos paso a paso
Delphi


Este artículo explica cómo realizar un programa en Delphi (extensible para cualquier lenguaje de programación) que gestione y calcule eficientemente el control de stock (control de existencias de artículos en almacén). Os explicaremos paso a paso los campos necesarios en la tabla de artículos, facturas a clientes y facturas de proveedores. También os explacamos en qué eventos de los formularios/ventanas de Delphi será preciso colocar el código fuente necesario para llevar esta gestión.



Cómo programar control de stock (existencias en almacén) de artículos paso a paso

Cómo programar control de stock (existencias en almacén) de artículos paso a paso

Este artículo explica cómo realizar un programa en Delphi (extensible para cualquier lenguaje de programación) que gestione y calcule eficientemente el control de stock (control de existencias de artículos en almacén). Os explicaremos paso a paso los campos necesarios en la tabla de artículos, facturas a clientes yfacturas de proveedores. También os explacamos en qué eventos de los formularios/ventanas de Delphi será preciso colocar el código fuente necesario para llevar esta gestión.

El control de existencias en almacén se hace imprescindible en organizaciones/empresas de compra/venta de artículos (para controlar los artículos disponibles en almacén), de montaje de maquinaria (para controlar la disponibilidad de las piezas necesarias para el montaje), agrícolas (para controlar la disponibilidad de los productos fitosanitarios en almacén), informáticas (para controlar la disponibilidad del material para montaje y venta de equipos). En definitiva se hace necesario para cualquier empresa que realice compras de material/artículos/productos y quiera saber en todo momento de cuantos elementos dispone.

En este manual mencionaremos siempre "almacén" como el sitio físico donde se alojen los productos/material/artículos, no tiene por qué ser un almacén como tal, puede ser cualquier tipo de ubicación, incluso puede que no sea física.

En primer lugar crearemos las tablas de la base de datos necesarias para esta gestión, por supuesto este artículo es un ejemplo simple, se puede complicar todo lo que se quiera.

La primera tabla y la más importante es la de artículos, os mostramos el script sql para MySQL necesario para crear esta tabla (en negrita destacamos los campos para el stock):

CREATE TABLE articulo (
codigo int(10) unsigned NOT NULL auto_increment,
fecha datetime,
codigoproveedor int(10) unsigned,
nombre varchar(150),
preciocompra float,
precioventa float,
stock float,
stockminimo float,
avisostockminimo char(1),

observacion varchar(255),
codigomarca int(10) unsigned,
codigofamilia int(10) unsigned,
codigomodelo int(10) unsigned,
codigobarras varchar(30),
caracteristicas text,
porcentajebeneficio float,
porcentajeiva float,
porcentajedto float,
PRIMARY KEY (codigo)
);

Otra de las tablas será la que almacene las facturas de proveedores (los que nos sirven el material), estará formada a su vez por dos tablas enlazadas por la clave foránea, por un lado la tabla de factura propiamente dicha, con la siguiente estructura:

CREATE TABLE facturaproveedor (
codigo int(10) unsigned NOT NULL auto_increment,
numero varchar(10),
importetotal float,
baseimponible float,
porcentajeiva float,
importeiva float,
porcentajedescuento float,
importedescuento float,
codigoproveedor int(10) unsigned NOT NULL,
fecha datetime,
cobrado char(1),
observacion varchar(255),
importepagado float,
PRIMARY KEY (codigo)
);

y por otro lado la tabla detalle, donde se guardarán las líneas de la factura (en negrita indicamos el campo que afectará a la gestión del stock):

CREATE TABLE facturaproveedordetalle (
codigo int(10) unsigned NOT NULL auto_increment,
codigofactura int(10) unsigned,
codigoarticulo int(10) unsigned,
concepto varchar(150),
cantidad float,
importe float,
precio float,
porcentajedto float,
PRIMARY KEY (codigo)
);

Al igual que las facturas de los proveedores, también guardaremos, necesariamente, las facturas de los clientes. Así podremos controlar las dos formas de entrada (proveedores) y salida (clientes) de stock. La estructura de la tabla de facturas de clientes sería:

CREATE TABLE facturacliente (
codigo int(10) unsigned NOT NULL auto_increment,
numero varchar(15),
importetotal float,
baseimponible float,
porcentajeiva float,
importeiva float,
porcentajedescuento float,
importedescuento float,
codigocliente int(10) unsigned NOT NULL,
fecha datetime,
cobrado char(1),
observacion varchar(255),
importecobrado float,
contabiliza char(1),
imprimida char(1),
enviada char(1),
fechaenvio datetime,
piefactura text,
PRIMARY KEY (codigo)
);

la tabla donde se guardarán las líneas de las facturas de los clientes será:

CREATE TABLE facturadetalle (
codigo int(10) unsigned NOT NULL auto_increment,
codigofactura int(10) unsigned,
codigoarticulo int(10) unsigned,
concepto varchar(150),
cantidad float,
importe float,
precio float,
porcentajedto float,
PRIMARY KEY (codigo)
);

Por supuesto, las tablas anteriores y su estructura es un ejemplo sencillo, se puede enfocar como se desee, dependiendo de las características de la organización que vaya a utilizar la aplicación.

Una vez creadas las tablas, desde Delphi o cualquier otro lenguaje de programación, tendremos en cuenta las siguientes acciones:

* En el formulario de alta de artículo, una ventana como esta:

colocaremos los dos campos, el primero para saber y poder modificar (aunque se puede impedir la modificación manual) el stock actual del artículo, el segundo para indicar cual es el stock mínimo a partir del cual se avisará al usuario. En principio.

* En el formulario de alta de línea de factura de proveedor (entrada de stock), una ventana como esta:

colocaremos el campo "cantidad" necesario para el control de stock, opcionalmente podremos colocar una etiqueta informativa con el stock actual de artículo, para mostrarlo, en el evento "onExit" del código de artículo o al seleccionar el artículo con el botón de selección o mediante el lector de códigos de barras, añadiremos el siguiente código fuente:

  md.TC2.Close;
  md.TC2.SQL.Clear;
  md.TC2.SQL.Add('Select a.stock');
  md.TC2.SQL.Add ('from articulo');
  md.TC2.SQL.Add ('where a.codigo = :pCodigo');
  md.TC2.ParamByName('pCodigo').Value := codigo;
  md.TC2.Open;
  if md.TC2.RecordCount > 0 then
    lstock.Caption := md.tc2.fieldbyname('stock').AsString;
  else
    lstock.Caption := '';

si se trata de una modificación de un artículo existente, deberemos guardar en una variable global la cantidad actual (antes de que el usuario la modifique) del artículo actual. Para ello declararemos esta variable en esta ventana:

 private
    { Private declarations }
    codigoArticuloAnterior : integer;
    cantidadActual : Double;
  public
    { Public declarations }
  end;

y en el evento "show" ó "create" del formulario añadiremos el siguiente código:

  if tag = 2 then //Modificar
  begin
    BSeleccionarProducto.Enabled := true;
    md.tFacturaDetalleProveedor.edit;
    txtCodigoArticulo.SetFocus;
    caption := 'Modificación de ' + ventana + '...';
    obtenerDatosArticulo(md.tFacturaDetalleProveedorcodigoarticulo.Value, 
''); cantidadActual := md.tFacturaDetalleProveedorcantidad.AsFloat; end;

y, por supuesto, en el evento "onClick" del botón "Aceptar", colocaremos las siguientes líneas de código:

  try
    md.tFacturaDetalleProveedor.Post; //validar
    actualizarStock (true, md.tFacturaDetalleProveedorcantidad.AsFloat - 
cantidadActual,
md.tFacturaDetalleProveedorcodigoarticulo.AsInteger);
except txtCodigoArticulo.setfocus; raise; end; close;

el código del procedimiento "actualizarStock" será el siguiente:

procedure actualizarStock (entrada : boolean; 
cantidad : double; codigo : Integer); begin with md.tcStock do begin close; SQL.Clear; SQL.Add('UPDATE articulo); if entrada then SQL.Add('SET stock = stock + :pCantidad') else SQL.Add('SET stock = stock - :pCantidad'); SQL.Add('WHERE Codigo = :pCodigo'); ParamByName('pCantidad').DataType := ftFloat; ParamByName('pCantidad').Value := cantidad; ParamByName('pCodigo').DataType := ftInteger; ParamByName('pCodigo').Value := codigo; execsql; close; end; end;

en el caso de que sea una inserción de una nueva línea de factura de proveedor, no será necesario guardar la cantidad anterior pues no existe, con lo cual la variable global "cantidadActual" se inicializará a cero. El resto de procedimientos será el mismo que para la modificación.

* En el formulario de alta de línea de factura de cliente (salida de stock), una ventana como esta:

se tratará de forma similiar a las líneas de facturas de proveedores, con la única salvedad del procedimiento "onClick" del botón "Aceptar" que será el siguiente:

  try
    md.tFacturaDetalle.Post; //validar
    actualizarStock (false, md.tFacturaDetallecantidad.AsFloat -
        cantidadActual, md.tFacturaDetallecodigoarticulo.AsInteger);
  except
    txtCodigoArticulo.setfocus;
    raise;
  end;
  close;

Si queremos avisar al usuario en el caso en que el stock actual del artículo sea inferior al stock mínimo, en el evento "onClick" del botón "Aceptar" podremos colocar el siguiente código, después de validar la línea:

  md.TC2.Close;
  md.TC2.SQL.Clear;
  md.TC2.SQL.Add('Select a.stock, a.stockminimo');
  md.TC2.SQL.Add ('from articulo');
  md.TC2.SQL.Add ('where a.codigo= :pCodigo');
  md.TC2.ParamByName('pCodigo').Value := codigo;
  md.TC2.Open;
  if md.TC2.RecordCount > 0 then
    if md.TC2.FieldByName('stock').AsFloat < 
md.TC2.FieldByName('stockminimo').AsFloat then showmessage ('Atención: el stock del artículo es inferior a ' + md.TC2.fieldbyname ('stockminimo').AsString;

Otro evento que debemos tener en cuenta es la posibilidad de que el usuario elimine una línea de la factura de proveedor o de la factura de cliente o incluso una factura de cliente o proveedor completa. En estos casos se debe restablecer el stock de los artículos que se eliminarán, en cuyo caso colocaremos el siguiente código, en el evento "eliminarFacturaCliente":

  md.tc2.Close;
  md.tc2.sql.clear;
  md.tc2.SQL.add('SELECT cantidad, codigoarticulo');
md.tc2.SQL.add('FROM facturadetalle');
md.tc2.SQL.add('WHERE CodigoFactura = :pCodigo'); md.tc2.ParamByName('pCodigo').DataType := ftString; md.tc2.ParamByName('pCodigo').AsInteger := codigoFacturaEliminar; md.tc2.open; while not md.tc2.Eof do begin codigoMaterial := md.tc2.fieldbyname ('codigoarticulo').AsInteger; cantidad := md.tc2.fieldbyname ('cantidad').AsFloat; actualizarStock (true, cantidad, codigoMaterial); md.tc2.Next; end; try md.tc2.Close; md.tc2.sql.clear; md.tc2.SQL.add('DELETE FROM FacturaDetalle'); md.tc2.SQL.add('WHERE CodigoFactura = :pCodigo'); md.tc2.ParamByName('pCodigo').DataType := ftString; md.tc2.ParamByName('pCodigo').AsInteger := codigoFacturaEliminar; md.tc2.ExecSQL; ttabla.Delete; except raise; end;
 
para "eliminarFacturaProveedor" haremos lo mismo cambiando "True" por "False" en el procedimiento "actualizarStock", obviamente cambiaremos también los nombres de los campos y tablas.
 

Por último, deberemos controlar el evento "Eliminar línea factura", que se producirá cuando un usuario decida eliminar sólo una línea de la factura, en cuyo caso colocaremos el siguiente código (para restablecer el stock):

  if messagedlg ('¿Está seguro que desea eliminar el concepto [' + 
nombre + '] de la ' + ventana + '?', mtconfirmation, [mbyes, mbno], 0) = mryes then begin codigoMaterial := md.tFacturaDetallecodigoarticulo.AsInteger; cantidad := md.tFacturaDetallecantidad.AsFloat; actualizarStock (true, cantidad, codigoMaterial); try md.tFacturaDetalle.delete; except raise; end; end;
 

Nota: Revisado por AjpdSoft el 21-01-2007.
Anuncios


Enviado el Domingo, 07 enero a las 10:51:16 por ajpdsoft
Visita nuestro nuevo sitio web con programas y contenidos actualizados: Proyecto A