{ =============================================================================== 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.0.7 Fecha versión actual: 07-03-2004 =============================================================================== Modificaciones: Fecha Comentarios --------------------------------------------------------------------------- 02-11-2001 Funcion 'EliminarArticulosAlmacen', que elimina todos los artículos de un determinado almacen, es para la opcion 'Finalizar obra'. 18-01-2002 Ordenar por descripción el grid de materiales. 02-03-2002 Se ha añadido la funcion 'DarListaArticulos' para devolver una lista de codigos de material a partir de un bookmark de filas seleccionadas de la tabla de articulos. 07-04-2002 Cambio de todos los procedimientos en los que se utiliza una transaccion nueva, por una unica transacción. Se ha eliminado el procedimiento darExistenciasArticuloAlmacen sobrecargado que utilizaba una transaccion pasada por parametro Se han modificado las funciones ModificarExistenciasEntrada, ModificarExistenciasSalida, RealizarMovimiento para que no utilicen transaccion pasada por parametro sino que cojan la de la Base de datos general. 11-08-2002 P223. Histórico de obras. 16-11-2002 p250. Poner el número total de artículos dados de alta en la inicialización del grid. 07-03-2004 P272. Adaptación a multiempresa. =============================================================================== } unit TablaArticulosAlmacen; interface uses SysUtils, Windows, Messages, Classes, Graphics, Controls, Forms, Dialogs, DBTables, DB, IBCustomDataSet, IBSQL, BaseDatos, IBDatabase, IBStoredProc, Mensajes, IB, dxDBGrid, dxDBCtrl, dbgrids, StrFunc, //TablaArticulos es usada por el Tipo TDatosArticulo, TDatosAlmacen, TDatosMovimiento TablaArticulos, TablaAlmacenes, TablaMovimientos, TablaArticulosObraHistorica; type TdmTablaArticulosAlmacen = class(TDataModule) private procedure IniciarSQL; public sqlConsultar : TStrings; sqlEliminar : TStrings; sqlGrid : TStrings; constructor Create (AOwner : TComponent); override; destructor Destroy; override; function ExisteArticuloEnAlmacen(CodigoEmpresa: Integer; CodigoArticulo: String): Boolean; function ArticuloAlmacenTieneExistencias(CodigoEmpresa, CodigoAlmacen: Integer; CodigoArticulo: String): Boolean; function ExisteArticuloAlmacen(CodigoEmpresa, CodigoAlmacen : Integer; CodigoArticulo: String): Boolean; function DarDatosArticuloAlmacen(CodigoEmpresa: Integer; var Datos: TDatosArticulo): Boolean; function DarListaArticulos(Grid : TdxDBGrid; Tabla: TPTabla) : TStringList; function DarExistenciasArticuloAlmacen(CodigoEmpresa, CodigoAlmacen: Integer; CodigoArticulo: String): String; overload; function DarUnidadesPendRecibirArticuloAlmacen(CodigoEmpresa, CodigoAlmacen: Integer; CodigoArticulo: String): String; function ModificarExistenciasEntrada(CodigoEmpresa: Integer; Datos: TDatosArticuloAlmacen): Boolean; function ModificarExistenciasSalida(CodigoEmpresa: Integer; Datos: TDatosArticuloAlmacen): Boolean; function RealizarMovimiento(CodigoEmpresa: Integer; Datos: TDatosArticuloAlmacen):Boolean; function EliminarArticulosAlmacen(CodigoEmpresa, CodigoAlmacen: Integer): Boolean; function FinalizarObra(CodigoEmpresa: Integer; CodigoObra: Integer; Fecha: String): Boolean; procedure InicializarTablaArticulosAlmacen(Tabla : TPTabla); procedure InicializarGridArticulosAlmacen(var Grid: TdxDBGrid); end; var dmTablaArticulosAlmacen: TdmTablaArticulosAlmacen; implementation {$R *.DFM} uses Excepciones, dxTL, RdxEmpresaActiva, Literales, Constantes; constructor TdmTablaArticulosAlmacen.Create (AOwner : TComponent); begin inherited; sqlConsultar := TStringList.Create; sqlEliminar := TStringList.Create; sqlGrid := TStringList.Create; IniciarSQL; end; destructor TdmTablaArticulosAlmacen.Destroy; begin sqlConsultar.Free; sqlEliminar.Free; sqlGrid.Free; inherited; end; procedure TdmTablaArticulosAlmacen.IniciarSQL; begin with sqlConsultar do begin Add('select CODIGOALMACEN, CODIGOARTICULO, '); Add('FAMILIA, DESCRIPCION, UNIDADESMEDIDA, PRECIO, OBSERVACIONES, '); Add('EXISTENCIAS, STOCKMAX, STOCKMIN '); Add('from ESTADOALMACEN , ARTICULOS '); Add('where (CODIGOALMACEN = :CODIGOALMACEN) and '); Add('(CODIGOEMPRESA = :CODIGOEMPRESA) and '); Add('(CODIGOARTICULO = :CODIGOARTICULO) and '); Add('(CODIGOARTICULO = CODIGO)'); end; with sqlEliminar do begin Add('delete from ESTADOALMACEN '); Add('where (CODIGOALMACEN = :CODIGOALMACEN) '); Add('and (CODIGOARTICULO = :CODIGOARTICULO) '); Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) '); end; with sqlGrid do begin Add('select CODIGOALMACEN, CODIGOARTICULO, FAMILIA, DESCRIPCION, '); Add('UNIDADESMEDIDA, EXISTENCIAS, (EXISTENCIAS * PRECIORECEPCION) as TOTAL'); Add('from ESTADOALMACEN, ARTICULOS '); Add('where (CODIGOALMACEN = :CODIGOALMACEN) '); Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) '); Add('and (CODIGO = CODIGOARTICULO) '); Add('order by DESCRIPCION'); end; end; { Tanto ExisteArticulosAlmacen como DarDatosArticuloAlmacen esta bien que tengan su propia transaccion ya que se hace una consulta en un momento determinado, sin dependencia de otras operaciones} function TdmTablaArticulosAlmacen.ExisteArticuloAlmacen(CodigoEmpresa, CodigoAlmacen : Integer; CodigoArticulo: String): Boolean; {Comprueba si existe un articulo en un determinado almacen, pasandole por parametro el codigo de articulo y el del almacen, devuelve true o false dependiendo si existe o no} var oSQL : TIBSQL; Codigo : String; begin Result := False; if (Length(Trim(CodigoArticulo)) = 0) then Exit; oSQL := TIBSQL.Create(Self); with oSQL do begin Database := dmBaseDatos.BD; Transaction := dmBaseDatos.Transaccion; SQL.Add('select CODIGOARTICULO '); SQL.Add('from ESTADOALMACEN '); SQL.Add('where (CODIGOALMACEN = :CODIGOALMACEN) '); SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) '); SQL.Add('and (CODIGOARTICULO = :CODIGOARTICULO) '); ParamByName('CODIGOALMACEN').AsInteger := CodigoAlmacen; ParamByName('CODIGOARTICULO').AsString := CodigoArticulo; ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa; try Prepare; ExecQuery; Codigo := FieldByName('CODIGOARTICULO').AsString; Result := (CodigoArticulo = Codigo); finally Close; Transaction := NIL; Free; end; end; end; function TdmTablaArticulosAlmacen.existeArticuloEnAlmacen(CodigoEmpresa: Integer; CodigoArticulo: String): Boolean; {Comprueba si existe un articulo en un determinado almacen, pasandole por parametro el codigo de articulo y el del almacen, devuelve true o false dependiendo si existe o no} var oSQL : TIBSQL; Codigo : String; begin Result := True; if (Length(Trim(CodigoArticulo)) = 0) then Exit; oSQL := TIBSQL.Create(Self); with oSQL do begin Database := dmBaseDatos.BD; Transaction := dmBaseDatos.Transaccion; SQL.Add('select CODIGOARTICULO '); SQL.Add('from ESTADOALMACEN '); SQL.Add('where (CODIGOARTICULO = :CODIGOARTICULO) '); SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) '); ParamByName('CODIGOARTICULO').AsString := CodigoArticulo; ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa; try Prepare; ExecQuery; if (RecordCount = 0) then Result := False; finally Close; Transaction := NIL; Free; end; end; end; function TdmTablaArticulosAlmacen.DarDatosArticuloAlmacen(CodigoEmpresa: Integer; var Datos: TDatosArticulo): Boolean; {Devuelve los datos del articulo pasado por parametro si este existe en el almacen correspondiente, en caso de no existir devuelve false y rellena dichos datos con 0,0 y 1000 respectibamente} var oSQL : TIBSQL; begin Result := False; if (length(Datos.Codigo) = 0) or VarIsNull(Datos.CodigoAlmacen) then begin //Para que cuando un articulo libre que no encuentra las existencias en //el almacen esten a cero Datos.Existencias := '0'; Datos.PrecioRecepcion := '0'; Datos.FechaRecepcion := ''; Exit; end; oSQL := TIBSQL.Create(Self); with oSQL do begin Database := dmBaseDatos.BD; Transaction := dmBaseDatos.Transaccion; SQL.Add('select * '); SQL.Add('from ESTADOALMACEN '); SQL.Add('where (CODIGOALMACEN = :CODIGOALMACEN) '); SQL.Add('and (CODIGOARTICULO = :CODIGOARTICULO) '); SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) '); ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa; ParamByName('CODIGOALMACEN').AsInteger := Datos.CodigoAlmacen; ParamByName('CODIGOARTICULO').AsString := Datos.Codigo; try Prepare; ExecQuery; if (RecordCount > 0) then begin Datos.Existencias := FieldByName('EXISTENCIAS').AsString; Datos.StockMin := FieldByName('STOCKMIN').AsString; Datos.StockMax := FieldByName('STOCKMAX').AsString; Datos.PrecioRecepcion := FieldByName('PRECIORECEPCION').AsString; Datos.FechaRecepcion := FieldByName('FECHARECEPCION').AsString; Result := True; end else begin Datos.Existencias := '0'; Datos.StockMin := '0'; Datos.StockMax := '1000'; Datos.PrecioRecepcion := '0'; Datos.FechaRecepcion := ''; end; finally Close; Transaction := NIL; Free; end; end; end; { Las operaciones de Insertar, ModificarIncrementar, ModificarDecrementar, dependenran en sus llamadas de otras operaciones por lo tanto se les pasará la transaccion por parámetro} function TdmTablaArticulosAlmacen.ModificarExistenciasEntrada(CodigoEmpresa: Integer; Datos: TDatosArticuloAlmacen): Boolean; {Además de Modificar las existencias del articulo dado por parametro incrementandolas, también restablece los StockMin y StockMax con los nuevos dados por parametro, si algo sale mal devuelve false} var oSQL : TIBSQL; begin Result := False; //Aunque ya lo compruebo fuera, y siempre va ha ser <> 0 asi es más robusto if length(Datos.Codigo)= 0 then Exit; oSQL := TIBSQL.Create(Self); with oSQL do begin Database := dmBaseDatos.BD; Transaction := dmBaseDatos.Transaccion; SQL.Add('update ESTADOALMACEN '); SQL.Add('set EXISTENCIAS = EXISTENCIAS + :CANTIDAD, '); SQL.Add('STOCKMIN = :STOCKMIN, '); SQL.Add('STOCKMAX = :STOCKMAX, '); SQL.Add('PRECIORECEPCION = :PRECIORECEPCION, '); SQL.Add('FECHARECEPCION = :FECHARECEPCION '); SQL.Add('where (CODIGOALMACEN = :CODIGOALMACEN) '); SQL.Add('and (CODIGOARTICULO = :CODIGOARTICULO) '); SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) '); ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa; ParamByName('CODIGOALMACEN').AsInteger := Datos.CodigoAlmacen; ParamByName('CODIGOARTICULO').AsString := Datos.Codigo; ParamByName('CANTIDAD').AsFloat := StrToFloat(Datos.Existencias); ParamByName('STOCKMIN').AsInteger := StrToInt(Datos.StockMin); ParamByName('STOCKMAX').AsInteger := StrToInt(Datos.StockMax); ParamByName('PRECIORECEPCION').AsFloat := StrToFloat(Datos.PrecioRecepcion); ParamByName('FECHARECEPCION').AsString := Datos.FechaRecepcion; try Prepare; ExecQuery; if RowsAffected = 0 then begin SQL.Clear; SQL.Add('insert into ESTADOALMACEN '); SQL.Add('(CODIGOEMPRESA, CODIGOALMACEN, CODIGOARTICULO, EXISTENCIAS, STOCKMIN,'); SQL.Add('STOCKMAX, PRECIORECEPCION, FECHARECEPCION) '); SQL.Add('values (:CODIGOEMPRESA, :CODIGOALMACEN, :CODIGOARTICULO, :EXISTENCIAS, '); SQL.Add(':STOCKMIN, :STOCKMAX, :PRECIORECEPCION, :FECHARECEPCION)'); ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa; ParamByName('CODIGOALMACEN').AsInteger := Datos.CodigoAlmacen; ParamByName('CODIGOARTICULO').AsString := Datos.Codigo; ParamByName('EXISTENCIAS').AsFloat := StrToFloat(Datos.Existencias); ParamByName('STOCKMIN').AsInteger := StrToInt(Datos.StockMin); ParamByName('STOCKMAX').AsInteger := StrToInt(Datos.StockMax); ParamByName('PRECIORECEPCION').AsFloat := StrToFloat(Datos.PrecioRecepcion); ParamByName('FECHARECEPCION').AsString := Datos.FechaRecepcion; Prepare; ExecQuery; end; if RealizarMovimiento(CodigoEmpresa, Datos) then Result := True; finally Close; Transaction := NIL; Free; end; end; end; procedure TdmTablaArticulosAlmacen.InicializarGridArticulosAlmacen(var Grid: TdxDBGrid); var Columna : TdxDBTreeListColumn; begin with Grid do begin DestroyColumns; ShowSummaryFooter := True; {Columna CODIGO} Columna := CreateColumn(TdxDBTreeListColumn); Columna.FieldName := 'CODIGOARTICULO'; Columna.Caption := 'Código'; Columna.Width := tamColCodigo2; Columna.SummaryFooterType := cstCount; Columna.SummaryFooterFormat := 'Total: 0 artículos'; {Columna FAMILIA} Columna := CreateColumn(TdxDBTreeListColumn); Columna.FieldName := 'FAMILIA'; Columna.Caption := 'Familia'; Columna.Width := tamColFamilias2; Columna.Visible := False; {Columna DESCRIPCION} Columna := CreateColumn(TdxDBTreeListColumn); Columna.Sorted := csUp; Columna.FieldName := 'DESCRIPCION'; Columna.Caption := 'Descripción'; Columna.Width := tamColDescripcion4; {Columna UNIDADESMEDIDA} Columna := CreateColumn(TdxDBTreeListColumn); Columna.FieldName := 'UNIDADESMEDIDA'; Columna.Caption := 'Unidades de medida'; Columna.Width := tamColUnidadesMedida2; {Columna EXISTENCIAS} Columna := CreateColumn(TdxDBTreeListColumn); Columna.FieldName := 'EXISTENCIAS'; Columna.Caption := 'Existencias'; Columna.Width := tamColExistencias2; {Columna TOTAL} Columna := CreateColumn(TdxDBTreeListColumn); Columna.FieldName := 'TOTAL'; Columna.Caption := 'Coste total'; Columna.Width := tamColPrecio3; Columna.SummaryFooterType := cstSum; Columna.SummaryFooterFormat := 'Total: 0.00 €'; {Columna PENDIENTESRECIBIR} { Columna := Add; Columna.Visible := True; Columna.FieldName := ''; Columna.Title.Caption := 'U. pendientes recibir';} end; end; function TdmTablaArticulosAlmacen.DarExistenciasArticuloAlmacen(CodigoEmpresa, CodigoAlmacen: Integer; CodigoArticulo: String): String; { Esta funcion devuelve las existencias actuales del articulo en el almacen pasados por parametro, si el articulo no existe devuelve -1} var oSQL : TIBSQL; begin Result := '-1'; if (length(CodigoArticulo)= 0) then Exit; oSQL := TIBSQL.Create(Self); with oSQL do begin Database := dmBaseDatos.BD; Transaction := dmBaseDatos.Transaccion; SQL.Add('select EXISTENCIAS '); SQL.Add('from ESTADOALMACEN '); SQL.Add('where (CODIGOALMACEN = :CODIGOALMACEN) '); SQL.Add('and (CODIGOARTICULO = :CODIGOARTICULO) '); SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) '); ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa; ParamByName('CODIGOALMACEN').AsInteger := CodigoAlmacen; ParamByName('CODIGOARTICULO').AsString := CodigoArticulo; try Prepare; ExecQuery; if (RecordCount > 0) then Result := FieldByName('EXISTENCIAS').AsString; finally Close; Transaction := NIL; Free; end; end; end; function TdmTablaArticulosAlmacen.ArticuloAlmacenTieneExistencias(CodigoEmpresa, CodigoAlmacen: Integer; CodigoArticulo: String): Boolean; var oSQL : TIBSQL; begin Result := True; if (length(CodigoArticulo)= 0) then Exit; oSQL := TIBSQL.Create(Self); with oSQL do begin Database := dmBaseDatos.BD; Transaction := dmBaseDatos.Transaccion; SQL.Add('select EXISTENCIAS '); SQL.Add('from ESTADOALMACEN '); SQL.Add('where (CODIGOALMACEN = :CODIGOALMACEN) '); SQL.Add('and (CODIGOARTICULO = :CODIGOARTICULO) '); SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) '); ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa; ParamByName('CODIGOALMACEN').AsInteger := CodigoAlmacen; ParamByName('CODIGOARTICULO').AsString := CodigoArticulo; try Prepare; ExecQuery; if (RecordCount > 0) and (FieldByName('EXISTENCIAS').AsString = '0') then Result := False; finally Close; Transaction := NIL; Free; end; end; end; function TdmTablaArticulosAlmacen.DarUnidadesPendRecibirArticuloAlmacen(CodigoEmpresa, CodigoAlmacen: Integer; CodigoArticulo: String): String; var oSQL : TIBSQL; begin if (length(CodigoArticulo)= 0) then Exit; oSQL := TIBSQL.Create(Self); with oSQL do begin Database := dmBaseDatos.BD; Transaction := dmBaseDatos.Transaccion; SQL.Add('select distinct E.CODIGOARTICULO, sum(PENDIENTES) as "PENDIENTE" '); SQL.Add('from ESTADOALMACEN E '); SQL.Add('left outer join PEDIDOSPROVEEDOR P '); SQL.Add('on ((P.CODIGOALMACEN = E.CODIGOALMACEN) and (P.CODIGOEMPRESA = E.CODIGOEMPRESA)) '); SQL.Add('left outer join DETALLESPEDIDOSPROVEEDOR D '); SQL.Add('on ((D.CODIGOPEDIDO = P.CODIGO) and (D.CODIGOEMPRESA = P.CODIGOEMPRESA) and (D.CODIGOARTICULO = E.CODIGOARTICULO)) '); SQL.Add('where E.CODIGOALMACEN = :CODIGOALMACEN '); SQL.Add('and E.CODIGOARTICULO = :CODIGOARTICULO '); SQL.Add('and E.CODIGOEMPRESA = :CODIGOEMPRESA '); SQL.Add('group by E.CODIGOARTICULO '); SQL.Add('order by E.CODIGOARTICULO '); ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa; ParamByName('CODIGOALMACEN').AsInteger := CodigoAlmacen; ParamByName('CODIGOARTICULO').AsString := CodigoArticulo; try Prepare; ExecQuery; if (RecordCount <> 0) then if EsCadenaVacia(FieldByName('PENDIENTE').AsString) then Result := '0' else Result := FieldByName('PENDIENTE').AsString; finally Close; Transaction := NIL; Free; end; end; end; function TdmTablaArticulosAlmacen.EliminarArticulosAlmacen(CodigoEmpresa, CodigoAlmacen: Integer): Boolean; var oSQL : TIBSQL; begin Result := False; oSQL := TIBSQL.Create(Self); with oSQL do begin Database := dmBaseDatos.BD; Transaction := dmBaseDatos.Transaccion; SQL.Add('delete from ESTADOALMACEN '); SQL.Add('where (CODIGOALMACEN = :CODIGOALMACEN) '); SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) '); SQL.Add('and CODIGOALMACEN in '); SQL.Add('(select CODIGO from ALMACENES '); SQL.Add('where (TIPO = ''O'') '); SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA)) '); ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa; ParamByName('CODIGOALMACEN').AsInteger := CodigoAlmacen; try Prepare; ExecQuery; Result := True; finally Close; Transaction := NIL; Free; end; end; end; function TdmTablaArticulosAlmacen.FinalizarObra(CodigoEmpresa: Integer; CodigoObra: Integer; Fecha: String): Boolean; var oSQL : TIBSQL; begin Result := False; if not dmTablaArticulosObraHistorica.InsertarObraHistorica(CodigoEmpresa, CodigoObra, Fecha) then Exit; if not dmTablaArticulosObraHistorica.InsertarPresupuestosObraHistorica(CodigoEmpresa, CodigoObra, Fecha) then Exit; if not dmTablaArticulosObraHistorica.EliminarPresupuestosObra(CodigoEmpresa, CodigoObra) then Exit; if not dmTablaArticulosObraHistorica.InsertarArticulosObraHistorica(CodigoEmpresa, CodigoObra, Fecha) then Exit; if not EliminarArticulosAlmacen(CodigoEmpresa, CodigoObra) then Exit; Result := True; end; function TdmTablaArticulosAlmacen.RealizarMovimiento(CodigoEmpresa: Integer; Datos: TDatosArticuloAlmacen): Boolean; var DatosMovimiento : TDatosMovimiento; DatosArticulo : TDatosArticulo; DatosAlmacen : TDatosAlmacen; begin Result := False; try DatosArticulo := TDatosArticulo.Create; DatosArticulo.Codigo := Datos.Codigo; //Aprovechamos y de paso tratamos si el articulo ya no existe if not dmTablaArticulos.darDatosArticulo(DatosArticulo) then raise Exception.CreateFmt(msgMovNoExisteArticulo, [DatosArticulo.Codigo]); DatosAlmacen := TDatosAlmacen.Create; DatosAlmacen.Codigo := Datos.CodigoAlmacen; DatosAlmacen.CodigoEmpresa := EmpresaActiva.Codigo; //Aprovechamos y de paso tratamos si el almacen ya no existe if not dmTablaAlmacenes.darDatosAlmacen(DatosAlmacen) then raise Exception.CreateFmt(msgMovNoExisteAlmacen, [DatosAlmacen.Codigo]); DatosMovimiento := TDatosMovimiento.Create; DatosMovimiento.CodigoAlmacen := DatosAlmacen.Codigo; DatosMovimiento.NombreAlmacen := DatosAlmacen.Nombre; DatosMovimiento.CodigoArticulo := DatosArticulo.Codigo; DatosMovimiento.DescripcionArticulo := DatosArticulo.Descripcion; DatosMovimiento.Familia := DatosArticulo.Familia; DatosMovimiento.Unidades := DatosArticulo.Unidadesmedida; DatosMovimiento.Cantidad := Datos.Existencias; DatosMovimiento.TipoOperacion := Datos.TipoOperacion; DatosMovimiento.TipoMovimiento := Datos.TipoMovimiento; DatosMovimiento.Causa := Datos.Causa; DatosMovimiento.NombreCliente := Datos.NombreCliente; //Aqui ya esta bloqueado el registro de este articulo en estado almacen DatosMovimiento.StockNuevo := DarExistenciasArticuloAlmacen(CodigoEmpresa, Datos.CodigoAlmacen, Datos.Codigo); if DatosMovimiento.TipoOperacion = etiMovEntrada then DatosMovimiento.StockAntiguo := FloatToStr(StrToFloat(DatosMovimiento.StockNuevo) - StrToFloat(DatosMovimiento.Cantidad)) else DatosMovimiento.StockAntiguo := FloatToStr(StrToFloat(DatosMovimiento.StockNuevo) + StrToFloat(DatosMovimiento.Cantidad)); //Si las unidades de entrada o salida son 0, o el articulo a tratar es //libre no quedará registrado el movimiento if (DatosMovimiento.StockAntiguo <> DatosMovimiento.StockNuevo) and (length(DatosMovimiento.CodigoArticulo) <> 0) then begin DatosMovimiento.Codigo := dmTablaMovimientos.DarNuevoCodigo; dmTablaMovimientos.InsertarMovimiento(DatosMovimiento); dmTablaMovimientos.IncrementarCodigo end; Result := True; finally DatosMovimiento.Free; DatosArticulo.Free; DatosAlmacen.Free; end; end; function TdmTablaArticulosAlmacen.ModificarExistenciasSalida(CodigoEmpresa: Integer; Datos: TDatosArticuloAlmacen): Boolean; {Además de Modificar las existencias del articulo dado por parametro incrementandolas, también restablece los StockMin y StockMax con los nuevos dados por parametro, si algo sale mal devuelve false} var oSQL : TIBSQL; begin Result := False; //Aunque ya lo compruebo fuera, y siempre va ha ser <> 0 asi es más robusto if length(Datos.Codigo)= 0 then Exit; oSQL := TIBSQL.Create(Self); with oSQL do begin Database := dmBaseDatos.BD; Transaction := dmBaseDatos.Transaccion; SQL.Add('update ESTADOALMACEN '); SQL.Add('set EXISTENCIAS = EXISTENCIAS - :CANTIDAD, '); SQL.Add('STOCKMIN = :STOCKMIN, '); SQL.Add('STOCKMAX = :STOCKMAX '); SQL.Add('where (CODIGOALMACEN = :CODIGOALMACEN) '); SQL.Add('and (CODIGOARTICULO = :CODIGOARTICULO) '); SQL.Add('and (EXISTENCIAS - :CANTIDAD >= 0) '); SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) '); ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa; ParamByName('CODIGOALMACEN').AsInteger := Datos.CodigoAlmacen; ParamByName('CODIGOARTICULO').AsString := Datos.Codigo; ParamByName('CANTIDAD').AsFloat := StrToFloat(Datos.Existencias); ParamByName('STOCKMIN').AsInteger := StrToInt(Datos.StockMin); ParamByName('STOCKMAX').AsInteger := StrToInt(Datos.StockMax); try Prepare; ExecQuery; if RowsAffected = 0 then raise Exception.Create(msgMovNoExisteArtExistencias); if RealizarMovimiento(CodigoEmpresa, Datos) then Result := True; finally Close; Transaction := NIL; Free; end; end; end; function TdmTablaArticulosAlmacen.DarListaArticulos(Grid : TdxDBGrid; Tabla: TPTabla): TStringList; var i: integer; ListaArticulos : TStringList; begin ListaArticulos := Nil; if Grid.SelectedCount = 0 then begin Result := ListaArticulos; exit end; ListaArticulos := TStringList.Create; Tabla^.DisableControls; for i:=0 to Grid.SelectedCount-1 do begin Tabla^.GotoBookmark(Pointer(Grid.SelectedRows[i])); ListaArticulos.Add(Tabla^.FieldByName('CODIGOARTICULO').AsString); end; Tabla^.EnableControls; Result := ListaArticulos; end; procedure TdmTablaArticulosAlmacen.InicializarTablaArticulosAlmacen( Tabla: TPTabla); begin with Tabla^.Fields do begin with (FieldByName('TOTAL') as TFloatField) do begin DisplayFormat := DISPLAY_EUROS2; EditFormat := EDIT_EUROS2; end; end; end; end.