This repository has been archived on 2024-11-29. You can view files and clone it, but cannot push or open issues or pull requests.
Tecsitel_FactuGES/Almacenes/MovimientoAlmacenes.pas
2007-06-21 15:47:20 +00:00

1827 lines
61 KiB
ObjectPascal

{
===============================================================================
Copyright (©) 2001. Rodax Software.
===============================================================================
Los contenidos de este fichero son propiedad de Rodax Software titular del
copyright. Este fichero sólo podrá ser copiado, distribuido y utilizado,
en su totalidad o en parte, con el permiso escrito de Rodax Software, o de
acuerdo con los términos y condiciones establecidas en el acuerdo/contrato
bajo el que se suministra.
-----------------------------------------------------------------------------
Web: www.rodax-software.com
===============================================================================
Fecha primera versión: 01-10-2001
Versión actual: 1.1.2
Fecha versión actual: 04-10-2004
===============================================================================
Modificaciones:
Fecha Comentarios
---------------------------------------------------------------------------
06-10-2001 Eliminados algunos SetFocus porque hay veces que la ventana
todavía está oculta.
09-10-2001 Cambiar mensaje NoExisteArticulo. Cambiar el BuscarPedido
con el fin de que si no hay código almacén en el pedido
se cargue la direccion y persona de contacto que tenga.
RellenarLineasDetalle el orden debe ser descending para luego
ir introduciendo en la lista y que el orden no sea inverso al
introducido en el pedido.
12-10-2001 No permitir que al recibir un pedido se introduzcan cantidades
mayores de las pedidas, y no queden registrados los movimientos
de 0 unidades
21-10-2001 Comprobar en la transaccion de la operacion de recibir pedido
y devolver pedido que éste no ha sido recibido ya por otro
usuario.
21-10-2001 Se ha añadido la fecha de recepción del pedido.
03-11-2001 Modificación de la politica de realizar entradas y salidas.
27-11-2001 En realizar Entrada y Salida se comprueba si el pedido no ha
sido ya recibido o devuelto en el momento en el que se
realiza la operacion. Esto se consigue mejorando las
sentencias SQL de DevolverPedido. Y los titulos de las
etiquetas dependiendo de las entidades.
08-01-2002 Falla 'RealizarEntrada'.
02-03-2002 En el contenido se pueden añadir muchos materiales a la vez.
16-03-2002 Al eliminar un concepto o todos los conceptos de la lista
detalle que consulte confirmación, recordar el último codigo
de articulo seleccionado para la siguiente selección en
la lista detalle estos cambios se ha producido en los
procedimientos bEliminar, bEliminarTodo, VerModal.
04-04-2002 La tabla de memoria se genera dinamicamente mediante una
tabla virtual en el función 'copiarTablaVirtual',
el metodo 'BorrarLineasDetalle' desaparece del frame y
solo es de esta unidad, literales se convierten en
constantes y limpieza de comentarios.
07-04-2002 Se ha adaptado a una unica transacción.
09-05-2002 Cambio de grid en lugar de utilizar UltimDBGrid, utilizaremos
dxDBGrid.
20-08-2002 P237. Revisar los botones de 'Eliminar' y 'Eliminar todo'
para que al pulsar 'Esc' cancele la operación y no la
ejecute como ahora.
06-03-2004 Se ha eliminado el tratamiento de perfiles de usuario.
09-04-2004 P272. Adaptación a multiempresa.
04-10-2004 Cambio CambiarEntidad para que soporte otro color.
===============================================================================
}
unit MovimientoAlmacenes;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Grids, DBGrids, RdxBotones, StdCtrls, IB,
RdxMemo, RdxCampos, ExtCtrls, Tipos, IBCustomDataSet,
RdxComboBox, Db, DBTables, RXDBCtrl, RdxTitulos, RdxPaneles, IBSQL,
RdxBarras, DBCtrls, RxMemDS, RdxCheckBox, StrFunc, RdxFrameMovimientos,
Mensajes, dxCntner, dxTL, dxDBCtrl, dxDBGrid, dxDBTLCL, dxEditor,
dxExEdtr, dxEdLib, dxDBELib, cxControls, cxContainer, cxEdit, cxTextEdit,
cxMaskEdit, cxDropDownEdit, cxCalendar, cxButtonEdit, cxDBEdit;
type
TfrMovimientoAlmacenes = class(TRdxFrameMovimientos)
pnlDatos: TRdxScrollPanel;
pnlArticulos: TRdxPanel;
cMateriales: TRdxCabecera;
dsTablaDetalle: TDataSource;
dsTablaPedidos: TDataSource;
pnlGridArticulos: TPanel;
pnlBarraGrid: TRdxPanel;
bAnadir: TRdxBoton;
bEliminar: TRdxBoton;
bElminarTodo: TRdxBoton;
pnlPedido: TRdxPanel;
cPedido: TRdxCabecera;
eCodigoPedido: TLabel;
eNombreProv: TLabel;
eCIFNIFProv: TLabel;
eNombreAlmacen: TLabel;
eCodigoAlmacen: TLabel;
eCalle: TLabel;
ePersona: TLabel;
pnlAlmacenes: TRdxPanel;
cAlmacenes: TRdxCabecera;
eAlmacenOrigen: TLabel;
eAlmacenDestino: TLabel;
pnlAlmacen: TRdxPanel;
cAlmacen: TRdxCabecera;
eAlmacen: TLabel;
pnlDetalle: TRdxPanel;
cDetalle: TRdxCabecera;
eTipoOperacion: TLabel;
eTipoMovimiento: TLabel;
eCodCliente: TLabel;
eNombreCliente: TLabel;
eCausa: TLabel;
eCIFNIF: TLabel;
cbAsociar: TRdxCheckBox;
NombreAlmacen: TRdxEdit;
Calle: TRdxEdit;
TipoOperacion: TRdxEdit;
TipoMovimiento: TRdxEdit;
cbxAlmacen: TRdxComboBox;
Causa: TRdxMemo;
NifCifCliente: TRdxEdit;
NombreCliente: TRdxEdit;
brDoble: TRdxBarraInferior;
bAceptar: TRdxBoton;
bCancelar: TRdxBoton;
Titulo: TRdxPanelTituloOperacion;
NifCifProveedor: TRdxDBEdit;
NombreProveedor: TRdxDBEdit;
cbxOrigen: TRdxComboBox;
cbxDestino: TRdxComboBox;
gridDetalles: TdxDBGrid;
FechaRecepcion: TcxDateEdit;
CodPedido: TcxDBButtonEdit;
CodigoAlmacen: TcxButtonEdit;
CodCliente: TcxButtonEdit;
procedure bAceptarClick(Sender: TObject);
procedure bCancelarClick(Sender: TObject);
procedure bAnadirClick(Sender: TObject);
procedure bEliminarClick(Sender: TObject);
procedure bElminarTodoClick(Sender: TObject);
procedure cbxAlmacenEntradaChange(Sender: TObject);
procedure cbxAlmacenSalidaChange(Sender: TObject);
procedure cbxAlmacenOrigenChange(Sender: TObject);
procedure cbxAlmacenDestinoChange(Sender: TObject);
procedure cbAsociarClick(Sender: TObject);
procedure GridBotonClick(Sender: TObject);
procedure CodigoArticuloDetalleSetText(Sender: TField; const Text: String);
procedure CantidadDetalleSetText(Sender: TField; const Text: String);
procedure StocksDetalleSetText(Sender: TField; const Text: String);
procedure gridDetallesExit(Sender: TObject);
procedure CodPedidoPropertiesButtonClick(Sender: TObject;
AButtonIndex: Integer);
procedure CodigoAlmacenPropertiesButtonClick(Sender: TObject;
AButtonIndex: Integer);
procedure CodigoAlmacenPropertiesValidate(Sender: TObject;
var DisplayValue: Variant; var ErrorText: TCaption;
var Error: Boolean);
procedure CodClientePropertiesButtonClick(Sender: TObject;
AButtonIndex: Integer);
procedure CodClientePropertiesValidate(Sender: TObject;
var DisplayValue: Variant; var ErrorText: TCaption;
var Error: Boolean);
private
FCodigoAlmacen : Variant;
procedure ActivarCamposDetalle;
procedure DesactivarCamposDetalle;
procedure ActivarCampoCodigo;
procedure DesactivarCampoCodigo;
procedure RecalcularExistencias;
function RealizarEntrada: Boolean;
function RealizarSalida: Boolean;
function EjecutarEntrada: Boolean;
function EjecutarSalida: Boolean;
function EjecutarTraslado: Boolean;
protected
procedure ActivarModoTraslado; override;
procedure ActivarModoEntrada; override;
procedure ActivarModoEntradaPedido; override;
procedure ActivarModoSalida; override;
procedure ActivarModoSalidaDevolucion; override;
procedure VerModal; override;
procedure SetCodigoArticulo (Value : Variant); override;
procedure FreeContenido; override;
procedure BuscarAlmacenOrigen; override;
procedure BuscarAlmacenDestino; override;
procedure BuscarPedido; override;
procedure BuscarCliente; override;
procedure BorrarLineasDetalle;
function ComprobarDatos : Boolean;
procedure RellenarLineasDetalle;
procedure CambiarModo(ModoAnterior, Modo : TRdxModo); override;
function CambiarEntidad (EntidadAnterior, Entidad : TRdxEntidad): Boolean; override;
procedure AfterRefreshPedidos(DataSet: TDataSet);
public
constructor Create (AOwner : TComponent); override;
destructor Destroy; override;
published
property TablaPedidos;
property TablaDetalleMem;
property CodigoAlmacenOrigen;
property CodigoAlmacenDestino;
property CodigoArticulo;
property CodigoPedido;
property CodigoCliente;
end;
var
frMovimientoAlmacenes: TfrMovimientoAlmacenes;
implementation
{$R *.DFM}
uses
BaseDatos, Articulos, ArticulosAlmacen, TablaMovimientos, DateFunc,
RdxFrameArticulosAlmacen, TablaArticulos, RdxFrameArticulos, NumFunc,
TablaPedidosProveedor, RdxFramePedidosProveedor, PedidosProveedores,
TablaAlmacenes, TablaClientes, RdxFrameAlmacenes, Almacenes,
clientes, RdxFrameClientes, TablaArticulosAlmacen, Excepciones,
IBErrorCodes, Configuracion, RdxEmpresaActiva, Literales;
constructor TfrMovimientoAlmacenes.Create(AOwner : TComponent);
var
TablaDetalle : TIBDataSet;
begin
inherited Create(AOwner);
ConfigurarFrame(Self, Self.Entidad);
BaseDatos := dmBaseDatos.BD;
Transaccion := dmBaseDatos.Transaccion;
TablaDetalle := TIBDataSet.Create(Self);
TablaDetalleMem := TRxMemoryData.Create(Self);
//Tabla Pedidos valida solo para los modos EntradaPedido y SalidaDevolucion
TablaPedidos := TIBDataSet.Create(Self);
dsTablaDetalle.DataSet := TablaDetalleMem;
dsTablaPedidos.DataSet := TablaPedidos;
with TablaDetalle do
begin
Database := BaseDatos;
Transaction := Transaccion;
SelectSQL.Assign(dmTablaMovimientos.sqlConsultarDetalles);
RefreshSQL.Assign(dmTablaMovimientos.sqlConsultarDetalles);
end;
with TablaPedidos do
begin
DataBase := BaseDatos;
Transaction := Transaccion;
SelectSQL.Assign(dmTablaMovimientos.sqlConsultarPedido);
RefreshSQL.Assign(dmTablaMovimientos.sqlConsultarPedido);
end;
try
TablaDetalleMem.CopyStructure(TablaDetalle);
TablaDetalleMem.FieldByName('CODIGOPEDIDO').Required := False;
TablaDetalleMem.FieldByName('NUMCONCEPTO').Required := False;
TablaDetalleMem.FieldByName('CODIGOARTICULO').OnSetText := CodigoArticuloDetalleSetText;
except
on E : EIBError do
TratarExcepcion(E);
on E : Exception do
TratarExcepcion(E);
end;
dmTablaMovimientos.InicializarGridDetalles(gridDetalles);
(gridDetalles.ColumnByFieldName('CODIGOARTICULO') as TdxDBTreeListButtonColumn).OnEditButtonClick := GridBotonClick;
FechaRecepcion.Date := Date;
end;
destructor TfrMovimientoAlmacenes.Destroy;
begin
TablaDetalleMem.Close;
TablaPedidos.Close;
TablaPedidos.UnPrepare;
TablaPedidos.Free;
inherited;
end;
procedure TfrMovimientoAlmacenes.VerModal;
begin
if (ContenidoModal is TRdxFrameArticulosAlmacen) then
begin
(ContenidoModal as TRdxFrameArticulosAlmacen).CodigoAlmacen := CodigoAlmacenOrigen;
(ContenidoModal as TRdxFrameArticulosAlmacen).CodigoArticulo := CodigoArticulo;
//Aunque desactive Almacen no se asegura que pueda darse un cambio de almacen
(ContenidoModal as TfrArticulosAlmacen).cbxAlmacen.Enabled := False;
(ContenidoModal as TfrArticulosAlmacen).bFinalizar.Visible := False;
end;
inherited VerModal;
end;
procedure TfrMovimientoAlmacenes.ActivarModoTraslado;
begin
TablaDetalleMem.FieldByName('CANTIDAD').OnSetText := CantidadDetalleSetText;
pnlDetalle.Visible := False;
pnlArticulos.Visible := False;
pnlPedido.Visible := False;
pnlAlmacen.Visible := False;
pnlAlmacenes.Visible := False;
TipoOperacion.Text := etiMovEntradaSalida;
TipoMovimiento.Text := etiMovTraslado;
pnlAlmacenes.Visible := True;
pnlArticulos.Visible := True;
pnlDetalle.Visible := True;
CodCliente.Properties.ReadOnly := True;
CodCliente.Properties.OnValidate := CodClientePropertiesValidate;
cbAsociar.Checked := False;
Causa.Clear;
Causa.Lines.Add(etiMovEntSalTraslado);
pnlBarraGrid.Visible := True;
DesactivarCamposDetalle;
ActivarCampoCodigo;
Visible := True;
end;
procedure TfrMovimientoAlmacenes.ActivarModoEntrada;
begin
TablaDetalleMem.FieldByName('CANTIDAD').OnSetText := CantidadDetalleSetText;
TablaDetalleMem.FieldByName('STOCKMIN').OnSetText := StocksDetalleSetText;
TablaDetalleMem.FieldByName('STOCKMAX').OnSetText := StocksDetalleSetText;
cbxAlmacen.OnChange:= cbxAlmacenEntradaChange;
pnlDetalle.Visible := False;
pnlArticulos.Visible := False;
pnlPedido.Visible := False;
pnlAlmacen.Visible := False;
pnlAlmacenes.Visible := False;
TipoOperacion.Text := etiMovEntrada;
TipoMovimiento.Text := etiMovRegularizacion;
pnlAlmacen.Visible := True;
pnlArticulos.Visible := True;
pnlDetalle.Visible := True;
CodCliente.Properties.ReadOnly := True;
CodCliente.Properties.OnValidate := CodClientePropertiesValidate;
cbAsociar.Checked := False;
Causa.Clear;
Causa.Lines.Add(etiMovEntRegularizacion);
pnlBarraGrid.Visible := True;
DesactivarCamposDetalle;
ActivarCampoCodigo;
Visible := True;
end;
procedure TfrMovimientoAlmacenes.ActivarModoEntradaPedido;
begin
TablaDetalleMem.FieldByName('CANTIDAD').OnSetText := CantidadDetalleSetText;
TablaPedidos.AfterOpen := AfterRefreshPedidos;
pnlDetalle.Visible := False;
pnlArticulos.Visible := False;
pnlPedido.Visible := False;
pnlAlmacen.Visible := False;
pnlAlmacenes.Visible := False;
eCodigoAlmacen.Caption := etiMovCodigoAlmObrDestino;
eNombreAlmacen.Caption := etiMovNombreAlmObrDestino;
TipoOperacion.Text := etiMovEntrada;
TipoMovimiento.Text := etiMovPedido;
pnlPedido.Visible := True;
pnlArticulos.Visible := True;
pnlDetalle.Visible := True;
CodCliente.Properties.ReadOnly := True;
CodCliente.Properties.OnValidate := CodClientePropertiesValidate;
cbAsociar.Checked := False;
Causa.Clear;
pnlBarraGrid.Visible := False;
DesactivarCamposDetalle;
DesActivarCampoCodigo;
Visible := True;
end;
procedure TfrMovimientoAlmacenes.ActivarModoSalida;
begin
TablaDetalleMem.FieldByName('CANTIDAD').OnSetText := CantidadDetalleSetText;
cbxAlmacen.OnChange:= cbxAlmacenSalidaChange;
pnlDetalle.Visible := False;
pnlArticulos.Visible := False;
pnlPedido.Visible := False;
pnlAlmacen.Visible := False;
pnlAlmacenes.Visible := False;
TipoOperacion.Text := etiMovSalida;
TipoMovimiento.Text := etiMovRegularizacion;
pnlAlmacen.Visible := True;
pnlArticulos.Visible := True;
pnlDetalle.Visible := True;
CodCliente.Properties.ReadOnly := True;
CodCliente.Properties.OnValidate := CodClientePropertiesValidate;
cbAsociar.Checked := False;
Causa.Clear;
Causa.Lines.Add(etiMovSalidaRegularizacion);
pnlBarraGrid.Visible := True;
DesactivarCamposDetalle;
ActivarCampoCodigo;
Visible := True;
end;
procedure TfrMovimientoAlmacenes.ActivarModoSalidaDevolucion;
begin
TablaPedidos.AfterOpen := AfterRefreshPedidos;
TablaDetalleMem.FieldByName('CANTIDAD').OnSetText := CantidadDetalleSetText;
pnlDetalle.Visible := False;
pnlArticulos.Visible := False;
pnlPedido.Visible := False;
pnlAlmacen.Visible := False;
pnlAlmacenes.Visible := False;
eCodigoAlmacen.Caption := etiMovCodigoAlmObrOrigen;
eNombreAlmacen.Caption := etiMovNombreAlmObrOrigen;
TipoOperacion.Text := etiMovSalida;
TipoMovimiento.Text := etiMovDevolucion;
pnlPedido.Visible := True;
pnlArticulos.Visible := True;
pnlDetalle.Visible := True;
CodCliente.Properties.ReadOnly := True;
CodCliente.Properties.OnValidate := CodClientePropertiesValidate;
cbAsociar.Checked := False;
Causa.Clear;
pnlBarraGrid.Visible := False;
DesactivarCamposDetalle;
DesactivarCampoCodigo;
Visible := True;
end;
procedure TfrMovimientoAlmacenes.bAnadirClick(Sender: TObject);
begin
try
TablaDetalleMem.Append;
gridDetalles.SetFocus;
except
on E : EIBError do
TratarExcepcion(E);
on E : Exception do
TratarExcepcion(E);
end;
end;
procedure TfrMovimientoAlmacenes.bEliminarClick(Sender: TObject);
begin
if (VerMensajePregunta(msgDeseaBorrar) <> IDYES) then
Exit;
try
if TablaDetalleMem.RecordCount <> 0 then
TablaDetalleMem.Delete
else
{ Hacemos un cancel de la tabla por si el registro actual estuviera
recien creado }
TablaDetalleMem.Cancel;
if TablaDetalleMem.RecordCount = 0 then
DesactivarCamposDetalle;
except
on E : EIBError do
TratarExcepcion(E);
on E : Exception do
TratarExcepcion(E);
end;
end;
procedure TfrMovimientoAlmacenes.bElminarTodoClick(Sender: TObject);
begin
if (VerMensajePregunta(msgDeseaBorrarTodo) <> IDYES) then
Exit;
BorrarLineasDetalle;
end;
procedure TfrMovimientoAlmacenes.SetCodigoArticulo(Value: Variant);
var
DatosArticulo : TDatosArticulo;
begin
inherited;
if VarIsNull(Value) then
Exit;
DatosArticulo := TDatosArticulo.Create;
if Modo in [Traslado, Salida, SalidaDevolucion] then
begin
if not EsCadenaVacia(CodigoAlmacenOrigen) then
DatosArticulo.CodigoAlmacen := CodigoAlmacenOrigen;
end
else
begin
if not EsCadenaVacia(CodigoAlmacenDestino) then
DatosArticulo.CodigoAlmacen := CodigoAlmacenDestino;
end;
try
DatosArticulo.Codigo := CodigoArticulo;
dmTablaArticulos.darDatosArticulo(DatosArticulo);
dmTablaArticulosAlmacen.DarDatosArticuloAlmacen(EmpresaActiva.Codigo, DatosArticulo);
with TablaDetalleMem do
begin
FieldByName('CODIGOARTICULO').AsString := DatosArticulo.Codigo;
FieldByName('FAMILIA').AsString := DatosArticulo.Familia;
FieldByName('DESCRIPCION').AsString := DatosArticulo.Descripcion;
FieldByName('UNIDADESMEDIDA').AsString := DatosArticulo.Unidadesmedida;
FieldByName('EXISTENCIAS').AsString := DatosArticulo.Existencias;
FieldByName('CANTIDAD').AsString := '0';
FieldByName('STOCKMIN').AsString := DatosArticulo.StockMin;
FieldByName('STOCKMAX').AsString := DatosArticulo.StockMax;
FieldByName('PRECIO').AsString := DatosArticulo.PrecioRecepcion;
FieldByName('PRECIORECEPCION').AsString := DatosArticulo.PrecioRecepcion;
FieldByName('FECHARECEPCION').AsString := DatosArticulo.FechaRecepcion;
end;
finally
DatosArticulo.Free;
ActivarCamposDetalle;
end;
end;
procedure TfrMovimientoAlmacenes.FreeContenido;
var
Contador : integer;
ListaCodigos : TStringList;
begin
if (ContenidoModal is TRdxFramePedidosProveedor) then
CodigoPedido := (ContenidoModal as TRdxFramePedidosProveedor).CodigoPedido;
if (ContenidoModal is TRdxFrameArticulosAlmacen) then
begin
if CodigoAlmacenOrigen = (ContenidoModal as TRdxFrameArticulosAlmacen).CodigoAlmacen then
begin
ListaCodigos := (ContenidoModal as TRdxFrameArticulosAlmacen).ListaArticulos;
for Contador := 0 to ListaCodigos.Count - 1 do
begin
CodigoArticulo := ListaCodigos.Strings[Contador];
bAnadirClick(Self);
end;
TablaDetalleMem.Cancel;
end
else
VerMensaje(msgMovArtAlmIncorrecto);
end;
if (ContenidoModal is TRdxFrameArticulos) then
begin
ListaCodigos := (ContenidoModal as TRdxFrameArticulos).ListaArticulos;
for Contador := 0 to ListaCodigos.Count - 1 do
begin
CodigoArticulo := ListaCodigos.Strings[Contador];
bAnadirClick(Self);
end;
TablaDetalleMem.Cancel;
end;
if (ContenidoModal is TRdxFrameAlmacenes) then
begin
Case Modo of
EntradaPedido : CodigoAlmacenDestino := (ContenidoModal as TRdxFrameAlmacenes).CodigoAlmacen;
SalidaDevolucion : CodigoAlmacenOrigen := (ContenidoModal as TRdxFrameAlmacenes).CodigoAlmacen;
end;
end;
if (ContenidoModal is TRdxFrameClientes) then
CodigoCliente := (ContenidoModal as TRdxFrameClientes).CodigoCliente;
inherited FreeContenido;
end;
procedure TfrMovimientoAlmacenes.BorrarLineasDetalle;
begin
try
TablaDetalleMem.DisableControls;
TablaDetalleMem.Close;
TablaDetalleMem.Open;
TablaDetalleMem.EnableControls;
DesactivarCamposDetalle;
except
on E : EIBError do
TratarExcepcion(E);
on E : Exception do
TratarExcepcion(E);
end;
end;
procedure TfrMovimientoAlmacenes.BuscarAlmacenOrigen;
var
Datos : TDatosAlmacen;
Existe : Boolean;
begin
//Por seguridad, nunca se llamará a buscar almacen origen en una entrada
if Modo in [Entrada, EntradaPedido] then
Exit;
Datos := TDatosAlmacen.Create;
Datos.CodigoEmpresa := EmpresaActiva.Codigo;
Datos.Codigo := CodigoAlmacenOrigen;
Existe := dmTablaAlmacenes.darDatosAlmacen(Datos);
CodigoCliente := Datos.CodigoCliente;
Case Modo of
Salida: cbxAlmacen.ItemIndex := cbxAlmacen.Items.IndexOf(FListaCodigosAlmacen.Values[CodigoAlmacenOrigen]);
Traslado: cbxOrigen.ItemIndex := cbxOrigen.Items.IndexOf(FListaCodigosAlmacen.Values[CodigoAlmacenOrigen]);
SalidaDevolucion : begin
CodigoAlmacen.Text := CodigoAlmacenOrigen;
NombreAlmacen.Text := Datos.Nombre;
Calle.Text := Datos.Calle;
if (length(CodigoAlmacenOrigen) <> 0) and (not Existe) then begin
VerMensajeFmt(msgAlmCodAlmNoExiste, [CodigoAlmacenOrigen]);
CodigoAlmacen.SetFocus;
end;
end;
end;
recalcularExistencias;
Datos.free;
end;
procedure TfrMovimientoAlmacenes.BuscarAlmacenDestino;
var
Datos : TDatosAlmacen;
Existe : Boolean;
begin
//Por seguridad, nunca se llamará a buscar almacen destino en una salida
if Modo in [Salida, SalidaDevolucion] then
Exit;
Datos := TDatosAlmacen.Create;
Datos.CodigoEmpresa := EmpresaActiva.Codigo;
Datos.Codigo := CodigoAlmacenDestino;
Existe := dmTablaAlmacenes.darDatosAlmacen(Datos);
CodigoCliente := Datos.CodigoCliente;
case Modo of
Entrada: cbxAlmacen.ItemIndex := cbxAlmacen.Items.IndexOf(FListaCodigosAlmacen.Values[CodigoAlmacenDestino]);
Traslado: cbxDestino.ItemIndex := cbxDestino.Items.IndexOf(FListaCodigosAlmacen.Values[CodigoAlmacenDestino]);
EntradaPedido : begin
CodigoAlmacen.Text := CodigoAlmacenDestino;
NombreAlmacen.Text := Datos.Nombre;
Calle.Text := Datos.Calle;
if (length(CodigoAlmacenDestino) <> 0) and (not Existe) then
begin
VerMensajeFmt(msgAlmCodAlmNoExiste, [CodigoAlmacenDestino]);
Exit
end;
end;
end;
RecalcularExistencias;
Datos.free;
end;
procedure TfrMovimientoAlmacenes.BuscarPedido;
var
Datos : TDatosPedidoProveedor;
begin
if VarIsNull(CodigoPedido) then
Exit;
try
with TablaPedidos do
begin
Close;
Params.ByName('CODIGO').AsString := CodigoPedido;
Params.ByName('CODIGOEMPRESA').AsInteger := EmpresaActiva.Codigo;
Prepare;
Open;
case Modo of
EntradaPedido : Causa.Lines.Add(etiMovEntradaPedido + CodigoPedido);
SalidaDevolucion : Causa.Lines.Add(etiMovSalidaDevolucion + CodigoPedido);
end
end;
except
on E : EIBError do
TratarExcepcion(E);
on E : Exception do
TratarExcepcion(E);
end;
Datos := TDatosPedidoProveedor.Create;
Datos.Codigo := CodigoPedido;
Datos.CodigoEmpresa := EmpresaActiva.Codigo;
// Aunque siempre va a existir por si concurrentemente de muy mala suerte alguien borra el pedido
if not dmTablaPedidosProveedor.darDatosPedido(Datos) then
begin
VerMensajeFmt(msgMovNoExistePedido,[CodigoPedido]);
CodigoAlmacen.SetFocus
end
else
begin
BorrarLineasDetalle;
RellenarLineasDetalle;
end;
if EsCadenaVacia(Datos.CodigoAlmacen) then
begin
NombreAlmacen.Text := Datos.NombreAlmacen;
Calle.Text := Datos.CalleAlmacen;
exit;
end;
Case Modo of
EntradaPedido : CodigoAlmacenDestino := Datos.CodigoAlmacen;
SalidaDevolucion : CodigoAlmacenOrigen := Datos.CodigoAlmacen;
end;
Datos.free;
end;
procedure TfrMovimientoAlmacenes.BuscarCliente;
var
Datos : TDatosCliente;
Existe : Boolean;
begin
if (Length(Trim(CodigoCliente)) = 0) then
begin
CodCliente.Text := '';
NifCifCliente.Text := '';
NombreCliente.Text := '';
cbAsociar.Checked := False;
CodCliente.Properties.Buttons[0].Visible := False;
CodCliente.Properties.ReadOnly := True;
CodCliente.Properties.OnValidate := nil;
Exit;
end;
CodCliente.Text := CodigoCliente;
Datos := TDatosCliente.Create;
Datos.Codigo := CodigoCliente;
Existe := dmTablaClientes.darDatosCliente(Datos);
NifCifCliente.Text := Datos.Nifcif;
NombreCliente.Text := Datos.Nombre;
Datos.Free;
if not Existe then
begin
VerMensajeFmt(msgMovNoExistePedido,[CodigoCliente]);
CodCliente.SetFocus
end
else
begin
cbAsociar.Checked := True;
CodCliente.Properties.Buttons[0].Visible := True;
CodCliente.Properties.ReadOnly := False;
CodCliente.Properties.OnValidate := CodClientePropertiesValidate;
end;
end;
procedure TfrMovimientoAlmacenes.cbxAlmacenOrigenChange(Sender: TObject);
begin
CodigoAlmacenOrigen := FListaAlmacenesCodigo.Values[cbxOrigen.Text];
end;
procedure TfrMovimientoAlmacenes.cbxAlmacenDestinoChange(Sender: TObject);
begin
CodigoAlmacenDestino := FListaAlmacenesCodigo.Values[cbxDestino.Text];
end;
procedure TfrMovimientoAlmacenes.cbxAlmacenEntradaChange(Sender: TObject);
begin
CodigoAlmacenDestino := FListaAlmacenesCodigo.Values[cbxAlmacen.Text];
end;
procedure TfrMovimientoAlmacenes.cbxAlmacenSalidaChange(Sender: TObject);
begin
CodigoAlmacenOrigen := FListaAlmacenesCodigo.Values[cbxAlmacen.Text];
end;
procedure TfrMovimientoAlmacenes.cbAsociarClick(Sender: TObject);
begin
if cbAsociar.Checked = True then
begin
CodigoCliente := NULL;
CodCliente.Clear;
NifCifCliente.Clear;
NombreCliente.Clear;
CodCliente.Properties.Buttons[0].Visible := False;
CodCliente.Properties.ReadOnly := True;
CodCliente.Properties.OnValidate := nil;
end
else begin
CodCliente.Properties.Buttons[0].Visible := True;
CodCliente.Properties.ReadOnly := False;
CodCliente.Properties.OnValidate := CodClientePropertiesValidate;
end
end;
function TfrMovimientoAlmacenes.EjecutarTraslado: Boolean;
var
DatosArticulo : TDatosArticulo;
DatosMovimiento : TDatosMovimiento;
Cantidad : String;
begin
Result := False;
if Transaccion = NIL then
exit;
try
TablaDetalleMem.DisableControls;
if not RealizarSalida then
begin
Rollback;
TablaDetalleMem.EnableControls;
Exit
end;
if not RealizarEntrada then
begin
Rollback;
TablaDetalleMem.EnableControls;
Exit
end;
Commit;
BorrarLineasDetalle;
Result := True;
except
on E : EIBError do
begin
case E.IBErrorCode of
isc_lock_conflict : begin
Rollback;
VerMensaje(msgAlmBloqueado);
end
else begin
Rollback;
TratarExcepcion(E);
end;
end;
end;
on E : Exception do begin
Rollback;
TratarExcepcion(E);
end;
end;
TablaDetalleMem.EnableControls;
end;
function TfrMovimientoAlmacenes.RealizarEntrada: Boolean;
{Se utiliza una misma transaccion para todas las operaciones, se comprueba si
el almacén destino sigue existiendo (por si en el periodo de introduccion de
los articulos otro usuario a eliminado el almacen y todos sus articulos), para
cada articulo comprobamos si existe articulos por si al igual que en el caso
anterior ha sido dado de baja en cuyo caso se avisara al usuario y se saltará
el movimiento de ese artículo, en el caso que la cantidad del articulo a insertar
sea 0 se insertará con dicha cantidad}
var
CodigoPedido : String;
FechaRecep : String;
DatosArticulo : TDatosArticuloAlmacen;
DatosDetallePedidoProveedor : TDatosDetallePedidoProveedor;
begin
Result := False;
CodigoPedido := CodPedido.Text;
FechaRecep := FechaRecepcion.Text;
try
DatosDetallePedidoProveedor := TDatosDetallePedidoProveedor.Create;
DatosDetallePedidoProveedor.CodigoPedido := CodigoPedido;
DatosDetallePedidoProveedor.CodigoEmpresa := EmpresaActiva.Codigo;
DatosArticulo := TDatosArticuloAlmacen.Create;
//Datos generales del movimiento de cada artículo
DatosArticulo.TipoOperacion := etiMovEntrada;
DatosArticulo.TipoMovimiento := TipoMovimiento.Text;
//Para saber de donde se han recibido los artículos en un entrada por traslado
if Modo = Traslado then
DatosArticulo.Causa := etiMovIniTrasladoEnt + CodigoAlmacenOrigen
+ etiMovMedTraslado + FListaCodigosAlmacen.Values[CodigoAlmacenOrigen]
+ etiMovFinTraslado
else
DatosArticulo.Causa := Causa.Lines.Text;
DatosArticulo.CodigoAlmacen := CodigoAlmacenDestino;
DatosArticulo.NombreCliente := NombreCliente.Text;
if Modo = EntradaPedido then
if not dmTablaPedidosProveedor.BloquearPedido(EmpresaActiva.Codigo, CodigoPedido, FechaRecep) then
begin
VerMensajeFmt(msgMovPedidoRecibido,[CodigoPedido]);
exit;
end;
// Para cada articulo
TablaDetalleMem.First;
while not TablaDetalleMem.Eof do
begin
{En el caso de entrada de pedido se tiene que recalcular las unidades
pendientes de recibir de cada uno de los articulos del pedido}
if Modo = EntradaPedido then
begin
DatosDetallePedidoProveedor.CodigoEmpresa := EmpresaActiva.Codigo;
DatosDetallePedidoProveedor.CodigoArticulo := TablaDetalleMem.FieldByName('CODIGOARTICULO').AsString;;
DatosDetallePedidoProveedor.NumConcepto := TablaDetalleMem.FieldByName('NUMCONCEPTO').AsInteger;
DatosDetallePedidoProveedor.Cantidad := TablaDetalleMem.FieldByName('CANTIDAD').AsString;
dmTablaPedidosProveedor.ModificarUnidadesPendientesArticulo(DatosDetallePedidoProveedor);
end;
DatosArticulo.Codigo := TablaDetalleMem.FieldByName('CODIGOARTICULO').AsString;
//Solo modifico existencias de articulos existentes en l aplicación
if not esCadenaVacia (DatosArticulo.Codigo) then begin
//Aprovecho el campo existencias de la estructura de datos de articulo
//para darle en el la cantidad
DatosArticulo.Existencias := TablaDetalleMem.FieldByName('CANTIDAD').AsString;
DatosArticulo.StockMin := TablaDetalleMem.FieldByName('STOCKMIN').AsString;
DatosArticulo.StockMax := TablaDetalleMem.FieldByName('STOCKMAX').AsString;
//Comprobamos el precio del articulo si existe en almacén para asignarle el
//nuevo precio o mantener el que tiene
if (TablaDetalleMem.FieldByName('FECHARECEPCION').AsDateTime < StrToDate(FechaRecep)) then
begin
DatosArticulo.PrecioRecepcion := TablaDetalleMem.FieldByName('PRECIO').AsString;
DatosArticulo.FechaRecepcion := FechaRecep
end
else
begin
DatosArticulo.PrecioRecepcion := TablaDetalleMem.FieldByName('PRECIORECEPCION').AsString;
DatosArticulo.FechaRecepcion := TablaDetalleMem.FieldByName('FECHARECEPCION').AsString;
end;
dmTablaArticulosAlmacen.ModificarExistenciasEntrada(EmpresaActiva.Codigo, DatosArticulo);
end;
TablaDetalleMem.Next;
end;
//Cambiamos de situacion el pedido si ya no hay unidades pendientes de recibir
if Modo = EntradaPedido then
begin
if dmTablaPedidosProveedor.darUnidadesPendientes(EmpresaActiva.Codigo, CodigoPedido) = '0' then
dmTablaPedidosProveedor.RecibirTotalmentePedido(EmpresaActiva.Codigo, CodigoPedido, FechaRecep)
else
dmTablaPedidosProveedor.RecibirParcialmentePedido(EmpresaActiva.Codigo, CodigoPedido, FechaRecep);
end;
Result := True;
finally
DatosArticulo.free;
DatosDetallePedidoProveedor.free;
end;
end;
function TfrMovimientoAlmacenes.RealizarSalida: Boolean;
var
CodigoPedido : String;
FechaDevolucion : String;
DatosArticulo : TDatosArticuloAlmacen;
DatosDetallePedidoProveedor : TDatosDetallePedidoProveedor;
begin
Result := False;
//No es necesaria la fecha de devolución pero por si en un futuro la piden
FechaDevolucion := FormatDateTime('dd/mm/yyyy', Now);
CodigoPedido := CodPedido.Text;
try
DatosDetallePedidoProveedor := TDatosDetallePedidoProveedor.Create;
DatosDetallePedidoProveedor.CodigoPedido := CodigoPedido;
DatosDetallePedidoProveedor.CodigoEmpresa := EmpresaActiva.Codigo;
DatosArticulo := TDatosArticuloAlmacen.Create;
//Datos generales del movimiento de cada artículo
DatosArticulo.TipoOperacion := etiMovSalida;
DatosArticulo.TipoMovimiento := TipoMovimiento.Text;
//Para saber de donde se han ido los artículo en un salida por traslado
if Modo = Traslado then
DatosArticulo.Causa := etiMovIniTrasladoSal + CodigoAlmacenDestino
+ etiMovMedTraslado + FListaCodigosAlmacen.Values[CodigoAlmacenDestino]
+ etiMovFinTraslado
else
DatosArticulo.Causa := Causa.Lines.Text;
DatosArticulo.CodigoAlmacen := CodigoAlmacenOrigen;
DatosArticulo.NombreCliente := NombreCliente.Text;
if Modo = SalidaDevolucion then
if not dmTablaPedidosProveedor.BloquearPedido(EmpresaActiva.Codigo, CodigoPedido, FechaDevolucion) then
begin
VerMensajeFmt(msgMovPedidoDevuelto,[CodigoPedido]);
exit;
end;
// Para cada articulo
TablaDetalleMem.First;
while not TablaDetalleMem.Eof do
begin
DatosArticulo.Codigo := TablaDetalleMem.FieldByName('CODIGOARTICULO').AsString;
//Solo modifico existencias de articulos existentes en la aplicación
if length(DatosArticulo.Codigo) <> 0 then begin
//Aprovecho el campo existencias de la estructura de datos de articulo
//para darle en el la cantidad
DatosArticulo.Existencias := TablaDetalleMem.FieldByName('CANTIDAD').AsString;
DatosArticulo.StockMin := TablaDetalleMem.FieldByName('STOCKMIN').AsString;
DatosArticulo.StockMax := TablaDetalleMem.FieldByName('STOCKMAX').AsString;
dmTablaArticulosAlmacen.ModificarExistenciasSalida(EmpresaActiva.Codigo, DatosArticulo);
end;
TablaDetalleMem.Next;
end;
if Modo = SalidaDevolucion then
dmTablaPedidosProveedor.DevolverPedido(EmpresaActiva.Codigo, CodigoPedido, FechaDevolucion);
Result:= True;
except
on E : Exception do begin
raise;
end;
end;
DatosArticulo.free;
DatosDetallePedidoProveedor.free;
end;
procedure TfrMovimientoAlmacenes.bAceptarClick(Sender: TObject);
begin
if not ComprobarDatos then
Exit;
Case Modo of
Entrada,
EntradaPedido : if not EjecutarEntrada then Exit;
Salida,
SalidaDevolucion : if not EjecutarSalida then Exit;
Traslado : if not EjecutarTraslado then Exit;
end;
CloseFrame;
end;
procedure TfrMovimientoAlmacenes.bCancelarClick(Sender: TObject);
begin
inherited;
CloseFrame;
end;
procedure TfrMovimientoAlmacenes.RellenarLineasDetalle;
var
oSQL : TIBSQL;
DatosArticulo : TDatosArticulo;
begin
oSQL := TIBSQL.Create(Self);
with oSQL do
begin
Database := dmBaseDatos.BD;
Transaction := Transaccion;
SQL.Add('select CODIGOALMACEN, CODIGOPEDIDO, CODIGOARTICULO, NUMCONCEPTO, DESCRIPCION, ');
SQL.Add('CANTIDAD, PENDIENTES, PRECIO ');
SQL.Add('from PEDIDOSPROVEEDOR PED, DETALLESPEDIDOSPROVEEDOR DEP');
SQL.Add('where (PED.CODIGOEMPRESA = DEP.CODIGOEMPRESA)');
SQL.Add('and (CODIGO = CODIGOPEDIDO)');
SQL.Add('and (CODIGOPEDIDO = :CODIGOPEDIDO) and ');
SQL.Add('(PED.CODIGOEMPRESA = :CODIGOEMPRESA) ');
SQL.Add('order by NUMCONCEPTO descending');
end;
try
with oSQL do
begin
ParamByName('CODIGOEMPRESA').AsInteger := EmpresaActiva.Codigo;
ParamByName('CODIGOPEDIDO').AsString := CodigoPedido;
Prepare;
ExecQuery;
// Relleno la estructura de datos con el almacén sobre el que se va a
// realizar el movimiento
DatosArticulo := TDatosArticulo.Create;
//Por defecto se carga el almacen que tenga seleccionado el pedido
DatosArticulo.CodigoAlmacen := FieldByName('CODIGOALMACEN').AsString;
Case Modo of
EntradaPedido : if not VarIsNull(CodigoAlmacenDestino) then
DatosArticulo.CodigoAlmacen := CodigoAlmacenDestino;
SalidaDevolucion: if not VarIsNull(CodigoAlmacenOrigen) then
DatosArticulo.CodigoAlmacen := CodigoAlmacenOrigen;
end;
TablaDetalleMem.DisableControls;
while not EOF do
begin
DatosArticulo.Codigo := FieldByName('CODIGOARTICULO').AsString;
// Recupera los datos del articulo, si no existe le asigna la
// descripcion de ese artículo en el pedido
if not dmTablaArticulos.darDatosArticulo(DatosArticulo) then
DatosArticulo.Descripcion := FieldByName('Descripcion').AsString;
dmTablaArticulosAlmacen.darDatosArticuloAlmacen(EmpresaActiva.Codigo, DatosArticulo);
TablaDetalleMem.Insert;
TablaDetalleMem.FieldByName('CODIGOPEDIDO').AsString := FieldByName('CODIGOPEDIDO').AsString;
TablaDetalleMem.FieldByName('CODIGOARTICULO').AsString := DatosArticulo.Codigo;
TablaDetalleMem.FieldByName('NUMCONCEPTO').AsInteger := FieldByName('NUMCONCEPTO').AsInteger;
TablaDetalleMem.FieldByName('FAMILIA').AsString := DatosArticulo.Familia;
TablaDetalleMem.FieldByName('DESCRIPCION').AsString := DatosArticulo.Descripcion;
TablaDetalleMem.FieldByName('UNIDADESMEDIDA').AsString := DatosArticulo.Unidadesmedida;
TablaDetalleMem.FieldByName('EXISTENCIAS').AsString := DatosArticulo.Existencias;
TablaDetalleMem.FieldByName('STOCKMIN').AsString := DatosArticulo.StockMin;
TablaDetalleMem.FieldByName('STOCKMAX').AsString := DatosArticulo.StockMax;
TablaDetalleMem.FieldByName('PRECIO').AsString := FieldByName('PRECIO').AsString;
TablaDetalleMem.FieldByName('PRECIORECEPCION').AsString := DatosArticulo.PrecioRecepcion;
TablaDetalleMem.FieldByName('FECHARECEPCION').AsString := DatosArticulo.FechaRecepcion;
Case Modo of
EntradaPedido : begin
TablaDetalleMem.FieldByName('CANTIDAD').AsFloat := FieldByName('PENDIENTES').AsFloat;
TablaDetalleMem.FieldByName('PENDIENTES').AsFloat := FieldByName('PENDIENTES').AsFloat;
end;
SalidaDevolucion: begin
TablaDetalleMem.FieldByName('CANTIDAD').AsFloat := FieldByName('CANTIDAD').AsFloat;
TablaDetalleMem.FieldByName('PENDIENTES').AsFloat := FieldByName('CANTIDAD').AsFloat;
end;
end;
TablaDetalleMem.Post;
Next;
end;
TablaDetalleMem.EnableControls;
if (Modo <> SalidaDevolucion) AND (TablaDetalleMem.RecordCount > 0) then
ActivarCamposDetalle;
end;
except
on E : EIBError do
TratarExcepcion(E);
on E : Exception do
TratarExcepcion(E);
end;
oSQL.Close;
oSQL.Free;
end;
procedure TfrMovimientoAlmacenes.CambiarModo(ModoAnterior, Modo: TRdxModo);
var
i : Integer;
begin
BorrarLineasDetalle;
Case Entidad of
entArticulosAlmacen : dmTablaAlmacenes.darAlmacenes(EmpresaActiva.Codigo, FListaAlmacenesCodigo,FListaCodigosAlmacen);
entArticulosAlmacenFisico : dmTablaAlmacenes.darAlmacenesFisicos(EmpresaActiva.Codigo, FListaAlmacenesCodigo,FListaCodigosAlmacen);
entArticulosAlmacenObra : dmTablaAlmacenes.darAlmacenesObras(EmpresaActiva.Codigo, FListaAlmacenesCodigo,FListaCodigosAlmacen);
end;
Case Modo of
Entrada,
Salida : begin
cbxAlmacen.Items.Clear;
for i:=0 to FListaAlmacenesCodigo.Count-1 do
cbxAlmacen.Items.Add(FListaAlmacenesCodigo.Names[i]);
cbxAlmacen.ItemIndex := 0;
if Modo = Entrada
then CodigoAlmacenDestino := FListaAlmacenesCodigo.Values[cbxAlmacen.Text]
else CodigoAlmacenOrigen := FListaAlmacenesCodigo.Values[cbxAlmacen.Text]
end;
Traslado : begin
//En el almacén origen se estableceran los fisicos o de obras dependiendo de la entidad en la que estemos
cbxOrigen.Items.Clear;
cbxDestino.Items.Clear;
for i:=0 to FListaAlmacenesCodigo.Count-1 do
cbxOrigen.Items.Add(FListaAlmacenesCodigo.Names[i]);
//En el almacén destino se establecen todos los almacenes
dmTablaAlmacenes.darAlmacenes(EmpresaActiva.Codigo, FListaAlmacenesCodigo,FListaCodigosAlmacen);
for i:=0 to FListaAlmacenesCodigo.Count-1 do
cbxDestino.Items.Add(FListaAlmacenesCodigo.Names[i]);
cbxOrigen.ItemIndex := 0;
cbxDestino.ItemIndex := 0;
CodigoAlmacenOrigen := FListaAlmacenesCodigo.Values[cbxOrigen.Text];
CodigoAlmacenDestino := FListaAlmacenesCodigo.Values[cbxDestino.Text];
end;
end;
inherited;
end;
function TfrMovimientoAlmacenes.ComprobarDatos: Boolean;
begin
Result := False;
if (TablaDetalleMem.RecordCount = 0) then
begin
VerMensaje(msgMovNoArticulos);
Exit;
end;
case Modo of
Entrada : begin
if EsCadenaVacia(CodigoAlmacenDestino) then
begin
VerMensaje(msgMovFaltaAlmacenDestino);
Exit;
end;
end;
EntradaPedido : begin
if EsCadenaVacia(CodigoAlmacenDestino) then
begin
VerMensaje(msgMovFaltaAlmacenDestino);
CodigoAlmacen.SetFocus;
Exit;
end;
if EsCadenaVacia(FechaRecepcion.Text) then
begin
VerMensaje(msgPedFaltaFecRecepcion);
FechaRecepcion.SetFocus;
Exit;
end;
end;
Salida : begin
if EsCadenaVacia(CodigoAlmacenOrigen) then
begin
VerMensaje(msgMovFaltaAlmacenOrigen);
Exit;
end;
end;
SalidaDevolucion: begin
if EsCadenaVacia(CodigoAlmacenOrigen) then
begin
VerMensaje(msgMovFaltaAlmacenOrigen);
CodigoAlmacen.SetFocus;
Exit;
end;
end;
Traslado : begin
if EsCadenaVacia(CodigoAlmacenDestino) then
begin
VerMensaje(msgMovFaltaAlmacenDestino);
cbxDestino.SetFocus;
Exit;
end;
if EsCadenaVacia(CodigoAlmacenOrigen) then
begin
VerMensaje(msgMovFaltaAlmacenOrigen);
cbxOrigen.SetFocus;
Exit;
end;
if (CodigoAlmacenOrigen = CodigoAlmacenDestino) then
begin
VerMensaje(msgMovMismoAlmacen);
cbxOrigen.SetFocus;
Exit;
end;
end;
end;
Result:= True;
end;
procedure TfrMovimientoAlmacenes.ActivarCamposDetalle;
{Activa las columnas del grid de detalle que nos interesan}
begin
//Si ya están activados salimos
if gridDetalles.ColumnByFieldName('CANTIDAD').DisableEditor then
begin
// Para todos los modos Cantidad la activamos
gridDetalles.ColumnByFieldName('CANTIDAD').DisableEditor := False;
if Modo = Entrada then
begin
// StockMin, StockMax
gridDetalles.ColumnByFieldName('STOCKMIN').DisableEditor := False;
gridDetalles.ColumnByFieldName('STOCKMAX').DisableEditor := False;
end;
end;
end;
procedure TfrMovimientoAlmacenes.DesactivarCamposDetalle;
{Desactiva las columnas del grid de detalle que nos interesan}
begin
// Para todos los modos Cantidad la desactivamos
gridDetalles.ColumnByFieldName('DESCRIPCION').DisableEditor := True;
gridDetalles.ColumnByFieldName('EXISTENCIAS').DisableEditor := True;
gridDetalles.ColumnByFieldName('CANTIDAD').DisableEditor := True;
gridDetalles.ColumnByFieldName('STOCKMIN').DisableEditor := True;
gridDetalles.ColumnByFieldName('STOCKMAX').DisableEditor := True;
end;
procedure TfrMovimientoAlmacenes.GridBotonClick(Sender: TObject);
{Controla cuando se introduce mediante el boton derecho un articulo en el grid detalle}
var
Campo : TField;
NombreCampo : String;
begin
TablaDetalleMem.Edit;
Case Modo of
Entrada,
EntradaPedido : begin
EntidadModal := entArticulo;
ContenidoModal := TfrArticulos.Create(Self);
end;
Salida,
SalidaDevolucion,
Traslado : begin
if VarIsNull(CodigoAlmacenOrigen) or EsCadenaVacia(CodigoAlmacenOrigen) then
begin
VerMensaje(msgMovFaltaAlmacenOrigen);
Exit;
end;
//dependiendo del tipo de entidad en el que nos encontremos
//entAlmacen,AlmacenFisico o de obra se adaptará
EntidadModal := Entidad;
ContenidoModal := TfrArticulosAlmacen.Create(Self);
end;
end;
end;
procedure TfrMovimientoAlmacenes.CodigoArticuloDetalleSetText(Sender: TField; const Text: String);
{Controla cuando se introduce manualmente un codigo de articulo en el grid detalle}
var
Codigo : String;
DatosArticulo : TDatosArticulo;
begin
Codigo := Trim(Text);
if EsCadenaVacia(Codigo) then
exit;
if (dmTablaArticulos.validarCodigo(Codigo)) then
Codigo := dmTablaArticulos.formatearCodigo(Codigo)
else
raise Exception.CreateFmt(msgArtCodArtIncorrecto, [Codigo]);
DatosArticulo := TDatosArticulo.Create;
DatosArticulo.Codigo := Codigo;
Case Modo of
Entrada,
EntradaPedido : DatosArticulo.CodigoAlmacen := CodigoAlmacenDestino;
Salida,
SalidaDevolucion,
Traslado : Begin
//En el caso de salida se requiere un almacen origen
if VarIsNull(codigoAlmacenOrigen) or EsCadenaVacia(CodigoAlmacenOrigen) then
begin
verMensaje(msgMovFaltaAlmacenOrigen);
Exit;
end;
DatosArticulo.CodigoAlmacen := CodigoAlmacenOrigen;
end;
end;
try
Case Modo of
Entrada,
EntradaPedido: begin
if not dmTablaArticulos.darDatosArticulo(DatosArticulo) then
raise Exception.CreateFmt(msgArtCodArtNoExiste, [Codigo]);
dmTablaArticulosAlmacen.DarDatosArticuloAlmacen(EmpresaActiva.Codigo, DatosArticulo);
end;
Salida,
SalidaDevolucion,
Traslado : begin
dmTablaArticulos.darDatosArticulo(DatosArticulo);
if not dmTablaArticulosAlmacen.DarDatosArticuloAlmacen(EmpresaActiva.Codigo, DatosArticulo) then
raise Exception.CreateFmt(msgMovCodArtAlmNoExiste,[DatosArticulo.Codigo, DatosArticulo.Descripcion, FListaCodigosAlmacen.Values[CodigoAlmacenOrigen]]);
end;
end;
with TablaDetalleMem do
begin
FieldByName('CODIGOARTICULO').AsString := DatosArticulo.Codigo;
FieldByName('FAMILIA').AsString := DatosArticulo.Familia;
FieldByName('DESCRIPCION').AsString := DatosArticulo.Descripcion;
FieldByName('UNIDADESMEDIDA').AsString := DatosArticulo.Unidadesmedida;
FieldByName('EXISTENCIAS').AsString := DatosArticulo.Existencias;
FieldByName('CANTIDAD').AsString := '0';
FieldByName('STOCKMIN').AsString := DatosArticulo.StockMin;
FieldByName('STOCKMAX').AsString := DatosArticulo.StockMax;
FieldByName('PRECIO').AsString := DatosArticulo.PrecioRecepcion;
FieldByName('PRECIORECEPCION').AsString := DatosArticulo.PrecioRecepcion;
FieldByName('FECHARECEPCION').AsString := DatosArticulo.FechaRecepcion;
end;
Sender.AsString := Codigo;
finally
DatosArticulo.Free;
end;
ActivarCamposDetalle;
//Para que el campo introducido se guarde
TablaDetalleMem.Append;
TablaDetalleMem.Cancel;
gridDetalles.SetFocus;
end;
procedure TfrMovimientoAlmacenes.CantidadDetalleSetText(Sender: TField; const Text: String);
{Controla cuando se introduce manualmente una cantidad en el grid detalle}
begin
try
if Length(Text) = 0 then
begin
Sender.AsString := '0';
Exit;
end;
if StrToFloat(Text) < 0 then
raise Exception.Create(msgMovCantMayorCero);
if Modo in [Salida, SalidaDevolucion, Traslado] then
if StrToFloat(Text) > TablaDetalleMem.FieldByName('EXISTENCIAS').AsFloat then
raise Exception.Create(msgMovNoExistencias);
if Modo = EntradaPedido then
if StrToFloat(Text) > TablaDetalleMem.FieldByName('PENDIENTES').AsFloat then
raise Exception.CreateFmt(msgMovCantRecibidaMayor,[TablaDetalleMem.FieldByName('PENDIENTES').AsString]);
Sender.AsString := Text
except
on E : EConvertError do
VerMensaje(msgCantidadNoValida);
on E : EDataBaseError do
VerMensaje(msgCantidadNoValida);
end;
end;
procedure TfrMovimientoAlmacenes.RecalcularExistencias;
var
DatosArticulo : TDatosArticulo;
begin
if (TablaDetalleMem.RecordCount = 0) then
Exit;
DatosArticulo := TDatosArticulo.Create;
case Modo of
Entrada,
EntradaPedido: begin
if (VarIsNull(CodigoAlmacenDestino)) then
Exit;
DatosArticulo.CodigoAlmacen := CodigoAlmacenDestino;
end;
Salida,
SalidaDevolucion,
Traslado: begin
if (VarIsNull(CodigoAlmacenOrigen)) then
Exit;
DatosArticulo.CodigoAlmacen := CodigoAlmacenOrigen;
end;
end;
//En el caso de que el almacén no este asignado
if length(DatosArticulo.CodigoAlmacen) = 0 then
begin
TablaDetalleMem.DisableControls;
TablaDetalleMem.first;
while not TablaDetalleMem.Eof do
begin
TablaDetalleMem.Edit;
TablaDetalleMem.FieldByName('EXISTENCIAS').AsString := '0';
TablaDetalleMem.FieldByName('STOCKMIN').AsString := '0';
TablaDetalleMem.FieldByName('STOCKMAX').AsString := '1000';
TablaDetalleMem.FieldByName('PRECIORECEPCION').AsString := '0';
TablaDetalleMem.FieldByName('FECHARECEPCION').AsString := '';
TablaDetalleMem.Post;
TablaDetalleMem.Next;
end;
TablaDetalleMem.First;
TablaDetalleMem.EnableControls;
Exit;
end;
//Reestablece los valores actuales de todos los artículo de la lista en el
//almacén dado
TablaDetalleMem.DisableControls;
TablaDetalleMem.First;
while not TablaDetalleMem.Eof do
begin
DatosArticulo.Codigo := TablaDetalleMem.FieldByName('CODIGOARTICULO').AsString;
DatosArticulo.Descripcion := TablaDetalleMem.FieldByName('DESCRIPCION').AsString;
dmTablaArticulosAlmacen.darDatosArticuloAlmacen(EmpresaActiva.Codigo, DatosArticulo);
TablaDetalleMem.Edit;
TablaDetalleMem.FieldByName('EXISTENCIAS').AsString := DatosArticulo.Existencias;
TablaDetalleMem.FieldByName('STOCKMIN').AsString := DatosArticulo.StockMin;
TablaDetalleMem.FieldByName('STOCKMAX').AsString := DatosArticulo.StockMax;
if Modo = Traslado then
begin
DatosArticulo.CodigoAlmacen := CodigoAlmacenDestino;
dmTablaArticulosAlmacen.darDatosArticuloAlmacen(EmpresaActiva.Codigo, DatosArticulo);
TablaDetalleMem.FieldByName('PRECIORECEPCION').AsString := DatosArticulo.PrecioRecepcion;
TablaDetalleMem.FieldByName('FECHARECEPCION').AsString := DatosArticulo.FechaRecepcion;
DatosArticulo.CodigoAlmacen := CodigoAlmacenOrigen;
end
else
begin
TablaDetalleMem.FieldByName('PRECIORECEPCION').AsString := DatosArticulo.PrecioRecepcion;
TablaDetalleMem.FieldByName('FECHARECEPCION').AsString := DatosArticulo.FechaRecepcion;
end;
TablaDetalleMem.Post;
TablaDetalleMem.Next;
end;
TablaDetalleMem.First;
TablaDetalleMem.EnableControls;
end;
procedure TfrMovimientoAlmacenes.StocksDetalleSetText(Sender: TField;const Text: String);
begin
try
if Length(Text) = 0 then
begin
Sender.AsString := '0';
Exit;
end;
if StrToFloat(Text) < 0 then
raise Exception.Create(msgMovStockMayorCero);
Sender.AsString := Text
except
on E : EConvertError do
VerMensaje(msgMovStockNoValido);
on E : EDataBaseError do
VerMensaje(msgMovStockNoValido);
end;
end;
procedure TfrMovimientoAlmacenes.gridDetallesExit(Sender: TObject);
begin
if TablaDetalleMem.State in [dsEdit, dsInsert] then
TablaDetalleMem.Post;
end;
function TfrMovimientoAlmacenes.EjecutarEntrada: Boolean;
{Se utiliza una misma transaccion para todas las operaciones, se comprueba si
el almacén destino sigue existiendo (por si en el periodo de introduccion de
los articulos otro usuario a eliminado el almacen y todos sus articulos), para
cada articulo comprobamos si existe articulos por si al igual que en el caso
anterior ha sido dado de baja en cuyo caso se avisara al usuario y se saltará
el movimiento de ese artículo, en el caso que la cantidad del articulo a insertar
sea 0 se insertará con dicha cantidad}
begin
Result := False;
if Transaccion = NIL then
exit;
try
TablaDetalleMem.DisableControls;
if not RealizarEntrada then
begin
Rollback;
TablaDetalleMem.EnableControls;
Exit
end;
Commit;
BorrarLineasDetalle;
Result := True;
except
on E : EIBError do
begin
case E.IBErrorCode of
isc_foreign_key : begin
Rollback;
VerMensaje(msgMovNoRealizado);
end;
isc_lock_conflict : begin
Rollback;
VerMensaje(msgAlmBloqueado);
end
else begin
Rollback;
TratarExcepcion(E);
end;
end;
end;
on E : Exception do begin
Rollback;
TratarExcepcion(E);
end;
end;
TablaDetalleMem.EnableControls;
end;
function TfrMovimientoAlmacenes.EjecutarSalida: Boolean;
begin
Result := False;
if Transaccion = NIL then
exit;
try
TablaDetalleMem.DisableControls;
if not RealizarSalida then
begin
Rollback;
TablaDetalleMem.EnableControls;
Exit
end;
Commit;
BorrarLineasDetalle;
Result := True;
except
on E : EIBError do
begin
case E.IBErrorCode of
isc_lock_conflict : begin
Rollback;
VerMensaje(msgAlmBloqueado);
end
else begin
Rollback;
TratarExcepcion(E);
end;
end;
end;
on E : Exception do begin
Rollback;
TratarExcepcion(E);
end;
end;
TablaDetalleMem.EnableControls;
end;
procedure TfrMovimientoAlmacenes.ActivarCampoCodigo;
begin
gridDetalles.ColumnByFieldName('CODIGOARTICULO').DisableEditor := False;
// gridDetalles.InsertKey := True;
// gridDetalles.DeleteKey := True;
end;
procedure TfrMovimientoAlmacenes.DesactivarCampoCodigo;
begin
gridDetalles.ColumnByFieldName('CODIGOARTICULO').DisableEditor := True;
// gridDetalles.InsertKey := False;
// gridDetalles.DeleteKey := False;
end;
procedure TfrMovimientoAlmacenes.AfterRefreshPedidos(DataSet: TDataSet);
var
FechaTabla : String;
begin
FechaTabla := DataSet.FieldByName('FECHARECEPCION').AsString;
if Modo = SalidaDevolucion then
begin
FechaRecepcion.Date := DataSet.FieldByName('FECHARECEPCION').AsDateTime;
FechaRecepcion.Properties.ReadOnly := True;
Exit;
end;
if not EsCadenaVacia(FechaTabla) then
begin
FechaRecepcion.Date := DataSet.FieldByName('FECHARECEPCION').AsDateTime;
FechaRecepcion.Properties.ReadOnly := True;
end
else begin
FechaRecepcion.Properties.ReadOnly := False;
if EsFechaNula(FechaRecepcion.Date) then
FechaRecepcion.Date := Date;
end;
end;
function TfrMovimientoAlmacenes.CambiarEntidad(EntidadAnterior,Entidad: TRdxEntidad): Boolean;
begin
if not inherited CambiarEntidad(EntidadAnterior, Entidad) then
Exit;
ConfigurarFrame(Self, Self.Entidad);
Case Entidad of
entArticulosAlmacenObra : begin
cAlmacen.Caption := 'Obra';
eAlmacen.Caption := 'Obra:';
end;
entArticulosAlmacen : begin
cAlmacen.Caption := 'Almacén/Obra';
eAlmacen.Caption := 'Almacén/Obra:';
end;
end;
end;
procedure TfrMovimientoAlmacenes.CodPedidoPropertiesButtonClick(
Sender: TObject; AButtonIndex: Integer);
begin
ModoModal := Recibir;
ContenidoModal := TfrPedidosProveedores.Create(Self);
end;
procedure TfrMovimientoAlmacenes.CodigoAlmacenPropertiesButtonClick(
Sender: TObject; AButtonIndex: Integer);
begin
Case Entidad of
entArticulosAlmacenFisico: EntidadModal := entAlmacenFisico;
entArticulosAlmacenObra: EntidadModal := entAlmacenObra;
entArticulosAlmacen: EntidadModal := entAlmacen;
end;
ContenidoModal := TfrAlmacenes.Create(Self);
end;
procedure TfrMovimientoAlmacenes.CodigoAlmacenPropertiesValidate(
Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption;
var Error: Boolean);
begin
//Por si se deja vacio el campo
if EsCadenaVacia(DisplayValue) then
begin
case Modo of
EntradaPedido: CodigoAlmacenDestino := '';
SalidaDevolucion: CodigoAlmacenOrigen := '';
end;
Exit;
end;
//Valida que el codigo introducido es numérico
if (not dmTablaAlmacenes.ValidarCodigo(DisplayValue)) then
begin
VerMensajeFmt(msgAlmCodAlmIncorrecto,[DisplayValue]);
CodigoAlmacen.SetFocus;
end;
//Comprueba que le numero es lo sufucientemente pequeño para ser un entero
if not EsSmallInt(DisplayValue) then
begin
VerMensajeFmt(msgAlmCodAlmIncorrecto,[DisplayValue]);
DisplayValue := '0';
CodigoAlmacen.SetFocus;
Exit;
end;
case Modo of
EntradaPedido : CodigoAlmacenDestino := DisplayValue;
SalidaDevolucion : CodigoAlmacenOrigen := DisplayValue;
end;
end;
procedure TfrMovimientoAlmacenes.CodClientePropertiesButtonClick(
Sender: TObject; AButtonIndex: Integer);
begin
ContenidoModal := TfrClientes.Create(Self);
end;
procedure TfrMovimientoAlmacenes.CodClientePropertiesValidate(
Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption;
var Error: Boolean);
begin
if EsCadenaVacia(DisplayValue) then
begin
NifCifCliente.Text := '';
NombreCliente.Text := '';
Exit
end;
if (dmTablaClientes.validarCodigo(DisplayValue)) then begin
//Comprueba que le numero es lo sufucientemente pequeño para ser un entero
if not EsInteger(DisplayValue) then
begin
VerMensajeFmt(msgCliCodCliIncorrecto,[DisplayValue]);
DisplayValue := '0';
CodCliente.SetFocus;
end
else
begin
DisplayValue := dmTablaClientes.formatearCodigo(DisplayValue);
if not (dmTablaClientes.ExisteCodigo(DisplayValue)) then
begin
VerMensajeFmt(msgCliCodCliNoExiste, [DisplayValue]);
CodCliente.SetFocus;
end
else
CodigoCliente := DisplayValue;
end;
end
else begin
VerMensajeFmt(msgCliCodCliIncorrecto, [DisplayValue]);
CodCliente.SetFocus;
end;
end;
end.