{ =============================================================================== 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.