ProGestion/Base/uBizImportesDetalleBase.pas

1004 lines
30 KiB
ObjectPascal
Raw Permalink Normal View History

unit uBizImportesDetalleBase;
interface
uses
uDAInterfaces, uDADataTable;
const
TIPODETALLE_CONCEPTO = 'C';
TIPODETALLE_TITULO = 'T';
TIPODETALLE_SUBTOTAL = 'S';
VISIBLE_TRUE = 'S';
VISIBLE_FALSE = 'N';
fld_NUMCONCEPTO = 'NUMCONCEPTO';
fld_POSICION = 'POSICION';
fld_TIPODETALLE = 'TIPO';
fld_IMPORTETOTAL = 'IMPORTETOTAL';
fld_CANTIDAD = 'CANTIDAD';
fld_IMPORTEUNIDAD = 'IMPORTEUNIDAD';
fld_VISIBLE = 'VISIBLE';
fld_DESCRIPCION = 'DESCRIPCION';
fld_PUNTOS = 'PUNTOS';
fld_IMPORTEPUNTOS = 'IMPORTEPUNTOS';
type
{ IMPORTANTE **********************************************************
PARCHE TEMPORAL -> Para evitar que se disparen los eventos de la clase
de negocio cuando se hace el CancelUpdates de los detalles (se restaura
la tabla a partir de los deltas y esto provoca que se disparen los eventos y
se producen muchos fallos }
IParche = interface
['{275F080F-054E-4E5A-BDF2-FE3494790388}']
procedure ActivarEventos;
procedure DesactivarEventos;
procedure Refrescar;
function PuedoLanzarEvento : Boolean;
end;
IBizImportesDetalle = interface(IDAStronglyTypedDataTable)
['{16A36AC3-FABD-4809-A238-A806F1D02B95}']
procedure RecalcularImporte;
function DarSumaTotalImportes : Currency;
end;
IBizPuntosDetalle = interface(IBizImportesDetalle)
['{72002878-BD11-4BB8-AB85-73E321A6D595}']
end;
IBizVisibleDetalle = interface(IDAStronglyTypedDataTable)
['{6BA5B3BF-2E92-4465-A328-60F90F7EA3D2}']
end;
TBizCantidadFieldRules = class(TDAFieldRules)
protected
procedure OnChange(Sender: TDACustomField); override;
end;
TBizImporteUnidadFieldRules = class(TDAFieldRules)
protected
procedure OnChange(Sender: TDACustomField); override;
end;
TBizTipoDetalleFieldRules = class(TDAFieldRules)
protected
procedure OnChange(Sender: TDACustomField); override;
end;
TBizPuntosFieldRules = class(TDAFieldRules)
protected
procedure OnChange(Sender: TDACustomField); override;
end;
TBizImportePuntosFieldRules = class(TDAFieldRules)
protected
procedure OnChange(Sender: TDACustomField); override;
end;
TBizVisibleFieldRules = class(TDAFieldRules)
protected
procedure OnChange(Sender: TDACustomField); override;
end;
function DarMaximoNumConcepto(aDataTable : TDADataTable): integer;
function DarMaximaPosicion(aDataTable : TDADataTable): integer;
procedure IntercambiarPosiciones(aDataTable : TDADataTable; Pos1, Pos2 : Integer);
procedure ReasignarPosiciones(aDataTable : TDADataTable);
procedure AsignarPosicion(aDataTable : TDADataTable; IsAppend : Boolean);
procedure AsignarNumConcepto(aDataTable : TDADataTable);
procedure RecalcularImporteDetalle(aDataTable : TDADataTable; TieneSubtotales : Boolean; TienePuntos : Boolean);
procedure RecalcularSubtotales(aDataTable : TDADataTable);
function DarTotalDetalles(aDataTable : TDADataTable; TieneSubtotales : Boolean; TienePuntos : Boolean) : Currency;
procedure RellenarImportePuntosEnCapitulo(aDataTable : TDADataTable);
procedure RellenarVisibleEnCapitulo(aDataTable : TDADataTable);
implementation
uses
SysUtils, DB, uBizImportesCabeceraBase, Controls, Forms, Dialogs, variants;
procedure IntercambiarPosiciones(aDataTable : TDADataTable; Pos1, Pos2 : Integer);
{ Intercambia los valores del campo 'POSICION' de dos filas }
var
ABookmark : Pointer;
AField : TDAField;
AFieldTipo : TDAField;
ACursor: TCursor;
bRecalcularSubtotales : Boolean;
begin
if not Assigned(aDataTable) then
raise Exception.Create('Tabla no asignada (IntercambiarPosicion)');
AField := aDataTable.FindField(fld_POSICION);
if not Assigned(AField) then
raise Exception.Create('Campo POSICION no encontrado (IntercambiarPosicion)');
// No importa si el TIPO no est<73> en la lista de columnas
AFieldTipo := aDataTable.FindField(fld_TIPODETALLE);
if (aDataTable.State in dsEditModes) then
aDataTable.Post;
bRecalcularSubtotales := False;
ACursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
//aDataTable.DisableEventHandlers; <- No descomentar
aDataTable.DisableControls;
ABookmark := aDataTable.GetBookMark;
try
aDataTable.First;
if aDataTable.Locate(fld_POSICION, Pos1, []) then
begin
// Si alguna de las dos filas es un subtotal, hay que recalcular todo
if Assigned(AFieldTipo) and ((AFieldTipo.AsString = TIPODETALLE_SUBTOTAL) or
(AFieldTipo.AsString = TIPODETALLE_TITULO)) then
bRecalcularSubtotales := True;
aDataTable.Edit;
AField.AsInteger := 0; // Ponemos el 0 temporalmente
aDataTable.Post;
aDataTable.First;
if aDataTable.Locate(fld_POSICION, Pos2, []) then
begin
// Si alguna de las dos filas es un subtotal, hay que recalcular todo
if Assigned(AFieldTipo) and ((AFieldTipo.AsString = TIPODETALLE_SUBTOTAL) or
(AFieldTipo.AsString = TIPODETALLE_TITULO)) then
bRecalcularSubtotales := True;
aDataTable.Edit;
AField.AsInteger := Pos1;
aDataTable.Post;
aDataTable.First;
aDataTable.Locate(fld_POSICION, 0, []);
aDataTable.Edit;
AField.AsInteger := Pos2;
aDataTable.Post;
end
else
raise Exception.Create('No se ha encontrado posici<63>n 2 (IntercambiarPosicion)');
end
else
raise Exception.Create('No se ha encontrado posici<63>n 1 (IntercambiarPosicion)');
finally
aDataTable.GotoBookmark(ABookmark);
aDataTable.EnableControls;
//aDataTable.EnableEventHandlers; <- No descomentar
if bRecalcularSubtotales then
RecalcularSubtotales(aDataTable);
Screen.Cursor := ACursor;
end;
end;
function DarMaximoNumConcepto(aDataTable : TDADataTable): integer;
{ Devuelve el valor m<>ximo del campo 'NUMCONCEPTO' }
var
ABookmark : Pointer;
AField : TDAField;
ACursor: TCursor;
begin
Result := 0;
if not Assigned(aDataTable) then
raise Exception.Create('Tabla no asignada (DarMaximoNumConcepto)');
if aDataTable.RecordCount < 1 then
Exit;
AField := aDataTable.FindField(fld_NUMCONCEPTO);
if not Assigned(AField) then
raise Exception.Create('Campo NUMCONCEPTO no encontrado (DarMaximoNumConcepto)');
ACursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
ABookmark := aDataTable.GetBookMark;
try
aDataTable.DisableControls;
aDataTable.DisableEventHandlers;
aDataTable.First;
while not aDataTable.Eof do
begin
if AField.AsInteger > Result then
Result := AField.AsInteger;
aDataTable.Next;
end;
finally
aDataTable.GotoBookmark(ABookmark);
aDataTable.EnableControls;
aDataTable.EnableEventHandlers;
Screen.Cursor := ACursor;
end;
end;
function DarMaximaPosicion(aDataTable : TDADataTable): integer;
{ Devuelve el valor m<>ximo del campo 'POSICION' }
var
ABookmark : Pointer;
AField : TDAField;
ACursor: TCursor;
begin
//Sort(['ForeignKeyFieldofMasterDetailRelation','YourSortField'],[sdAscending, NeededOrder ]);
Result := 0;
if not Assigned(aDataTable) then
raise Exception.Create('Tabla no asignada (DarMaximaPosicion)');
if aDataTable.RecordCount < 1 then
Exit;
AField := aDataTable.FindField(fld_POSICION);
if not Assigned(AField) then
raise Exception.Create('Campo POSICION no encontrado (DarMaximaPosicion)');
ACursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
ABookmark := aDataTable.GetBookMark;
try
aDataTable.DisableControls;
aDataTable.DisableEventHandlers;
aDataTable.First;
while not aDataTable.Eof do
begin
if AField.AsInteger > Result then
Result := AField.AsInteger;
aDataTable.Next;
end;
finally
aDataTable.GotoBookmark(ABookmark);
aDataTable.EnableControls;
aDataTable.EnableEventHandlers;
Screen.Cursor := ACursor;
end;
end;
procedure ReasignarPosiciones(aDataTable : TDADataTable);
{ Recalcula el valor del campo 'POSICION' de todas las filas
para eliminar huecos }
var
AField : TDAField;
ABookmark : Pointer;
Contador : Integer;
NumCon : Integer;
TotalConceptos : Integer;
DetallesEditados : Integer;
ACursor: TCursor;
begin
if not Assigned(aDataTable) then
raise Exception.Create('Tabla no asignada (ReasignarNumConceptos)');
if aDataTable.RecordCount < 1 then
Exit;
AField := aDataTable.FindField(fld_POSICION);
if not Assigned(AField) then
raise Exception.Create('Campo POSICION no encontrado (ReasignarNumConceptos)');
Contador := 1;
NumCon := 1;
TotalConceptos := aDataTable.RecordCount;
DetallesEditados := 0;
ACursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
ABookmark := aDataTable.GetBookMark;
aDataTable.DisableControls;
//aDataTable.DisableEventHandlers; <-- No descomentar
try
aDataTable.First;
while DetallesEditados < TotalConceptos do
begin
if aDataTable.Locate(fld_POSICION, Contador, []) then
begin
aDataTable.Edit;
AField.Value := NumCon;
Inc(NumCon);
aDataTable.Post;
Inc(DetallesEditados);
aDataTable.First;
end;
Inc(Contador);
end;
finally
aDataTable.GotoBookmark(ABookmark);
//aDataTable.EnableEventHandlers; <-- No descomentar
aDataTable.EnableControls;
Screen.Cursor := ACursor;
end;
end;
procedure AsignarPosicion(aDataTable : TDADataTable; IsAppend : Boolean);
{ Calcula el valor del campo 'POSICION' para una fila nueva. Incrementa en 1
a las filas que est<EFBFBD>n por debajo de esa fila nueva }
var
AField : TDAField;
ABookmark : Pointer;
NumPosicion : Integer;
MaxPosicion : Integer;
ACursor: TCursor;
begin
if not Assigned(aDataTable) then
raise Exception.Create('Tabla no asignada (AsignarPosicion)');
if aDataTable.RecordCount < 1 then
Exit;
AField := aDataTable.FindField(fld_POSICION);
if not Assigned(AField) then
raise Exception.Create('Campo POSICION no encontrado (AsignarPosicion)');
if not IsAppend then
begin
if not aDataTable.IsEmpty then
begin
ACursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
aDataTable.DisableControls;
// Mover las filas que est<73>n por debajo de la actual
MaxPosicion := DarMaximaPosicion(aDataTable);
NumPosicion := (AField.AsInteger * (-1));
ABookmark := aDataTable.GetBookMark;
try
aDataTable.First;
while aDataTable.Locate(fld_POSICION, MaxPosicion, []) do
begin
aDataTable.Edit;
AField.Value := MaxPosicion + 1;
aDataTable.Post;
aDataTable.First;
if MaxPosicion = NumPosicion then
Break
else
Dec(MaxPosicion);
end
finally
aDataTable.GotoBookmark(ABookmark);
aDataTable.EnableControls;
Screen.Cursor := ACursor;
end;
end;
NumPosicion := (AField.AsInteger * (-1));
end
else begin
if aDataTable.RecordCount > 1 then
NumPosicion := DarMaximaPosicion(aDataTable) + 1
else
// S<>lo hay una fila en toda la tabla
NumPosicion := (AField.AsInteger * (-1));
end;
// Asignar posici<63>n a la nueva fila
aDataTable.Edit;
AField.Value := NumPosicion;
aDataTable.Post;
end;
procedure AsignarNumConcepto(aDataTable : TDADataTable);
{ Asigna el valor del campo 'NUMCONCEPTO' para una fila nueva }
var
AField : TDAField;
MaxConcepto : Integer;
ACursor: TCursor;
EnEdicion : Boolean;
begin
if not Assigned(aDataTable) then
raise Exception.Create('Tabla no asignada (AsignarNumConcepto)');
if aDataTable.RecordCount < 1 then
Exit;
AField := aDataTable.FindField(fld_NUMCONCEPTO);
if not Assigned(AField) then
raise Exception.Create('Campo NUMCONCEPTO no encontrado (AsignarNumConcepto)');
// <20>Viene en modo edici<63>n?
EnEdicion := (aDataTable.State in dsEditModes);
MaxConcepto := DarMaximoNumConcepto(aDataTable);
if not aDataTable.IsEmpty then
begin
ACursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
aDataTable.DisableControls;
try
if not EnEdicion then
aDataTable.Edit;
AField.AsInteger := MaxConcepto + 1;
aDataTable.Post;
if EnEdicion then
aDataTable.Edit;
finally
Screen.Cursor := ACursor;
aDataTable.EnableControls;
end;
end;
end;
procedure RecalcularImporteDetalle(aDataTable : TDADataTable; TieneSubtotales : Boolean; TienePuntos : Boolean);
var
TipoField : TDAField;
TotalField : TDAField;
CantidadField : TDAField;
ImporteUnidadField : TDAField;
PuntosField : TDAField;
ImportePuntosField : TDAField;
EnEdicion : Boolean;
begin
if not Assigned(aDataTable) then
raise Exception.Create('Tabla no asignada (RecalcularImporteDetalle)');
if aDataTable.RecordCount < 1 then
Exit;
// <20>Viene en modo edici<63>n?
EnEdicion := (aDataTable.State in dsEditModes);
TotalField := aDataTable.FindField(fld_IMPORTETOTAL);
if not Assigned(TotalField) then
raise Exception.Create('Campo IMPORTETOTAL no encontrado (RecalcularImporteDetalle)');
CantidadField := aDataTable.FindField(fld_CANTIDAD);
if not Assigned(CantidadField) then
raise Exception.Create('Campo CANTIDAD no encontrado (RecalcularImporteDetalle)');
ImporteUnidadField := aDataTable.FindField(fld_IMPORTEUNIDAD);
if not Assigned(ImporteUnidadField) then
raise Exception.Create('Campo IMPORTEUNIDAD no encontrado (RecalcularImporteDetalle)');
if TienePuntos then
begin
PuntosField := aDataTable.FindField(fld_PUNTOS);
if not Assigned(PuntosField) then
raise Exception.Create('Campo PUNTOS no encontrado (RecalcularImporteDetalle)');
ImportePuntosField := aDataTable.FindField(fld_IMPORTEPUNTOS);
if not Assigned(ImportePuntosField) then
raise Exception.Create('Campo IMPORTEPUNTOS no encontrado (RecalcularImporteDetalle)');
end;
if TieneSubtotales then
begin
TipoField := aDataTable.FindField(fld_TIPODETALLE);
if not Assigned(TipoField) then
raise Exception.Create('Campo TIPO no encontrado (RecalcularImporteDetalle)');
end;
//
if not EnEdicion then
aDataTable.Edit;
aDataTable.DisableEventHandlers;
// Calcular el importe de la l<>nea
try
if (TieneSubtotales) and ((TipoField.AsString = TIPODETALLE_SUBTOTAL) or
(TipoField.AsString = TIPODETALLE_TITULO)) then
begin
CantidadField.Value := NULL;
ImporteUnidadField.Value := NULL;
TotalField.Value := NULL;
if (TienePuntos) then
begin
PuntosField.Value := NULL;
if (TipoField.AsString = TIPODETALLE_SUBTOTAL) then
ImportePuntosField.Value := NULL;
end;
end
else begin
if TienePuntos and
((PuntosField.Value <> NULL) and (ImportePuntosField.Value <> NULL)) then
ImporteUnidadField.Value := PuntosField.AsInteger * ImportePuntosField.AsCurrency;
TotalField.Value := CantidadField.AsCurrency * ImporteUnidadField.AsCurrency;
end;
finally
aDataTable.EnableEventHandlers;
if not EnEdicion then
aDataTable.Post;
end;
end;
procedure RecalcularSubtotales(aDataTable : TDADataTable);
{ Recalcula el valor de todos los subtotales de la tabla }
var
ABookmark : Pointer;
APosicion : Integer;
MaxPos : Integer;
Total : Currency;
Subtotal : Currency;
TipoField : TDAField;
TotalField : TDAField;
ACursor: TCursor;
begin
if not Assigned(aDataTable) then
raise Exception.Create('Tabla no asignada (RecalcularTodosSubtotales)');
if aDataTable.RecordCount < 1 then
Exit;
TipoField := aDataTable.FindField(fld_TIPODETALLE);
if not Assigned(TipoField) then
raise Exception.Create('Campo TIPO no encontrado (RecalcularTodosSubtotales)');
TotalField := aDataTable.FindField(fld_IMPORTETOTAL);
if not Assigned(TotalField) then
raise Exception.Create('Campo IMPORTETOTAL no encontrado (RecalcularTodosSubtotales)');
ABookmark := aDataTable.GetBookMark;
ACursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
aDataTable.DisableControls;
// aDataTable.DisableEventHandlers; <- No descomentar
if (aDataTable.State in dsEditModes) then
aDataTable.Post;
APosicion := 1;
Total := 0;
Subtotal := 0;
try
MaxPos := DarMaximaPosicion(aDataTable);
while (APosicion <= MaxPos) do
begin
aDataTable.First;
if aDataTable.Locate(fld_POSICION, APosicion, []) then
begin
if (TipoField.AsString = TIPODETALLE_TITULO) then
Subtotal := 0
else if (TipoField.AsString = TIPODETALLE_SUBTOTAL) then
begin
try
aDataTable.Edit;
TotalField.Value := SubTotal;
aDataTable.Post;
Total := Total + SubTotal;
Subtotal := 0;
except
on E : Exception do
ShowMessage(E.Message);
end;
end
else begin
Subtotal := Subtotal + TotalField.AsCurrency;
if (APosicion = MaxPos) then
Total := Total + SubTotal;
end;
Inc(APosicion);
end
else
Break;
end;
finally
aDataTable.GotoBookmark(ABookmark);
aDataTable.EnableControls;
// aDataTable.EnableEventHandlers; <- No descomentar
Screen.Cursor := ACursor;
end;
end;
function DarTotalDetalles(aDataTable : TDADataTable; TieneSubtotales : Boolean; TienePuntos : Boolean) : Currency;
{ Calcula el total de todos los detalles a partir del importe total de cada uno }
var
EnEdicion : Boolean;
ABookmark : Pointer;
APosicion : Integer;
MaxPos : Integer;
Total : Currency;
Subtotal : Currency;
TipoField : TDAField;
TotalField : TDAField;
ACursor: TCursor;
begin
Result := 0;
if not Assigned(aDataTable) then
raise Exception.Create('Tabla no asignada (DarTotalDetalles)');
if aDataTable.RecordCount < 1 then
Exit;
if TieneSubtotales then
begin
TipoField := aDataTable.FindField(fld_TIPODETALLE);
if not Assigned(TipoField) then
raise Exception.Create('Campo TIPO no encontrado (DarTotalDetalles)');
end;
TotalField := aDataTable.FindField(fld_IMPORTETOTAL);
if not Assigned(TotalField) then
raise Exception.Create('Campo IMPORTETOTAL no encontrado (DarTotalDetalles)');
ABookmark := aDataTable.GetBookMark;
ACursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
aDataTable.DisableControls;
// aDataTable.DisableEventHandlers; <- No descomentar
// <20>Viene en modo edici<63>n?
EnEdicion := (aDataTable.State in dsEditModes);
if EnEdicion then
aDataTable.Post;
APosicion := 1;
Total := 0;
Subtotal := 0;
try
MaxPos := DarMaximaPosicion(aDataTable);
while (APosicion <= MaxPos) do
begin
aDataTable.First;
if aDataTable.Locate(fld_POSICION, APosicion, []) then
begin
if TieneSubtotales and (TipoField.AsString = TIPODETALLE_SUBTOTAL) then
begin
Total := Total + SubTotal;
Subtotal := 0;
end
else begin
Subtotal := Subtotal + TotalField.AsCurrency;
if (APosicion = MaxPos) then
Total := Total + SubTotal;
end;
Inc(APosicion);
end
else
Break;
end;
finally
Result := Total;
aDataTable.GotoBookmark(ABookmark);
aDataTable.EnableControls;
// aDataTable.EnableEventHandlers; <- No descomentar
if EnEdicion then
aDataTable.Edit;
Screen.Cursor := ACursor;
end;
end;
procedure RellenarImportePuntosEnCapitulo(aDataTable : TDADataTable);
{ Rellena el importe de puntos a todos los conceptos de un cap<EFBFBD>tulo. El cursor
est<EFBFBD> puesto en la fila que es el t<EFBFBD>tulo. }
var
ABookmark : Pointer;
APosicion : Integer;
MaxPos : Integer;
ImportePuntos : Currency;
TipoField : TDAField;
PosicionField : TDAField;
ImportePuntosField : TDAField;
ACursor: TCursor;
EnEdicion : Boolean;
ADetalle : IBizImportesDetalle;
begin
if not Assigned(aDataTable) then
raise Exception.Create('Tabla no asignada (RellenarImportePuntosEnCapitulo)');
if aDataTable.RecordCount < 1 then
Exit;
if not Supports(aDataTable, IBizImportesDetalle, ADetalle) then
raise Exception.Create('La tabla no soporta la interfaz requerida (RellenarImportePuntosEnCapitulo)');
PosicionField := aDataTable.FindField(fld_POSICION);
if not Assigned(PosicionField) then
raise Exception.Create('Campo POSICION no encontrado (RellenarImportePuntosEnCapitulo)');
TipoField := aDataTable.FindField(fld_TIPODETALLE);
if not Assigned(TipoField) then
raise Exception.Create('Campo TIPO no encontrado (RellenarImportePuntosEnCapitulo)');
ImportePuntosField := aDataTable.FindField(fld_IMPORTEPUNTOS);
if not Assigned(ImportePuntosField) then
raise Exception.Create('Campo IMPORTEPUNTOS no encontrado (RellenarImportePuntosEnCapitulo)');
ABookmark := aDataTable.GetBookMark;
ACursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
aDataTable.DisableControls;
EnEdicion := (aDataTable.State in dsEditModes);
if EnEdicion then
aDataTable.Post;
APosicion := PosicionField.Value + 1; // La posici<63>n siguiente a la fila de TITULO
ImportePuntos := aDataTable.FindField(fld_IMPORTEPUNTOS).AsCurrency; // Importe de puntos de la fila de TITULO
try
MaxPos := DarMaximaPosicion(aDataTable);
while (APosicion <= MaxPos) do
begin
if aDataTable.Locate(fld_POSICION, APosicion, []) then
begin
if (TipoField.AsString = TIPODETALLE_CONCEPTO) then
begin
aDataTable.Edit;
aDataTable.DisableEventHandlers; // Para que no salten otros eventos
try
ImportePuntosField.AsCurrency := ImportePuntos;
ADetalle.RecalcularImporte;
finally
aDataTable.EnableEventHandlers;
end;
aDataTable.Post;
Inc(APosicion);
end
else
break; // Es una fila de SUBTOTAL o de TITULO
end
else
raise Exception.Create('Hay un hueco en la numeraci<63>n de posiciones');
end;
finally
aDataTable.GotoBookmark(ABookmark);
aDataTable.EnableControls;
Screen.Cursor := ACursor;
if EnEdicion then
aDataTable.Edit;
end;
end;
procedure RellenarVisibleEnCapitulo(aDataTable : TDADataTable);
{ Rellena VISIBLE de todos los conceptos de un cap<EFBFBD>tulo. El cursor
est<EFBFBD> puesto en la fila que es el t<EFBFBD>tulo. }
var
ABookmark : Pointer;
APosicion : Integer;
MaxPos : Integer;
TipoField : TDAField;
PosicionField : TDAField;
VisibleField : TDAField;
ACursor: TCursor;
EnEdicion : Boolean;
EsVisible : String;
begin
if not Assigned(aDataTable) then
raise Exception.Create('Tabla no asignada (RellenarVisibleEnCapitulo)');
if aDataTable.RecordCount < 1 then
Exit;
PosicionField := aDataTable.FindField(fld_POSICION);
if not Assigned(PosicionField) then
raise Exception.Create('Campo POSICION no encontrado (RellenarVisibleEnCapitulo)');
TipoField := aDataTable.FindField(fld_TIPODETALLE);
if not Assigned(TipoField) then
raise Exception.Create('Campo TIPO no encontrado (RellenarVisibleEnCapitulo)');
VisibleField := aDataTable.FindField(fld_VISIBLE);
if not Assigned(VisibleField) then
raise Exception.Create('Campo VISIBLE no encontrado (RellenarVisibleEnCapitulo)');
ABookmark := aDataTable.GetBookMark;
ACursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
aDataTable.DisableControls;
EnEdicion := (aDataTable.State in dsEditModes);
if EnEdicion then
aDataTable.Post;
APosicion := PosicionField.Value + 1; // La posici<63>n siguiente a la fila de TITULO
EsVisible := VisibleField.AsString; // Valor de VISIBLE de la fila de TITULO
try
MaxPos := DarMaximaPosicion(aDataTable);
while (APosicion <= MaxPos) do
begin
if aDataTable.Locate(fld_POSICION, APosicion, []) then
begin
if (TipoField.AsString = TIPODETALLE_CONCEPTO) then
begin
aDataTable.Edit;
aDataTable.DisableEventHandlers; // Para que no salten otros eventos
try
VisibleField.AsString := EsVisible;
finally
aDataTable.EnableEventHandlers;
end;
aDataTable.Post;
Inc(APosicion);
end
else
break; // Es una fila de SUBTOTAL o de TITULO
end
else
raise Exception.Create('Hay un hueco en la numeraci<63>n de posiciones');
end;
finally
aDataTable.GotoBookmark(ABookmark);
aDataTable.EnableControls;
Screen.Cursor := ACursor;
if EnEdicion then
aDataTable.Edit;
end;
end;
{ TBizCantidadFieldRules }
procedure TBizCantidadFieldRules.OnChange(Sender: TDACustomField);
var
aDetalle : IBizImportesDetalle;
aCabecera : IBizImportesCabecera;
aParche : IParche;
begin
inherited;
{ PARCHE ********************************** }
if Supports(DataTable, IParche, aParche) and
not (aParche.PuedoLanzarEvento) then
Exit;
if Supports(DataTable, IBizImportesDetalle, aDetalle) then
begin
if Sender.Value = 0 then
Sender.Value := Null;
aDetalle.RecalcularImporte;
RecalcularSubtotales(aDetalle.DataTable);
if Assigned(aDetalle.DataTable.MasterSource) and
Supports(aDetalle.DataTable.MasterSource.DataTable, IBizImportesCabecera, ACabecera) then
ACabecera.RecalcularImporte;
end;
end;
procedure TBizImporteUnidadFieldRules.OnChange(Sender: TDACustomField);
var
aDetalle : IBizImportesDetalle;
aCabecera : IBizImportesCabecera;
aParche : IParche;
begin
inherited;
{ PARCHE ********************************** }
if Supports(DataTable, IParche, aParche) and
not (aParche.PuedoLanzarEvento) then
Exit;
if Supports(DataTable, IBizImportesDetalle, aDetalle) then
begin
if Sender.Value = 0 then
Sender.Value := Null;
aDetalle.RecalcularImporte;
RecalcularSubtotales(aDetalle.DataTable);
if Assigned(aDetalle.DataTable.MasterSource) and
Supports(aDetalle.DataTable.MasterSource.DataTable, IBizImportesCabecera, ACabecera) then
ACabecera.RecalcularImporte;
end;
end;
procedure TBizTipoDetalleFieldRules.OnChange(Sender: TDACustomField);
var
aDetalle : IBizImportesDetalle;
aCabecera : IBizImportesCabecera;
aParche : IParche;
begin
inherited;
{ PARCHE ********************************** }
if Supports(DataTable, IParche, aParche) and
not (aParche.PuedoLanzarEvento) then
Exit;
if (Sender.AsString = TIPODETALLE_SUBTOTAL) or
(Sender.AsString = TIPODETALLE_TITULO) then
if Supports(DataTable, IBizImportesDetalle, aDetalle) then
begin
aDetalle.RecalcularImporte;
RecalcularSubtotales(aDetalle.DataTable);
if Assigned(aDetalle.DataTable.MasterSource) and
Supports(aDetalle.DataTable.MasterSource.DataTable, IBizImportesCabecera, ACabecera) then
ACabecera.RecalcularImporte;
end;
end;
procedure TBizPuntosFieldRules.OnChange(Sender: TDACustomField);
var
aDetalle : IBizPuntosDetalle;
aCabecera : IBizImportesCabecera;
aParche : IParche;
begin
inherited;
{ PARCHE ********************************** }
if Supports(DataTable, IParche, aParche) and
not (aParche.PuedoLanzarEvento) then
Exit;
if Supports(DataTable, IBizPuntosDetalle, aDetalle) then
begin
if Sender.Value = 0 then
Sender.Value := Null;
aDetalle.RecalcularImporte;
RecalcularSubtotales(aDetalle.DataTable);
if Assigned(aDetalle.DataTable.MasterSource) and
Supports(aDetalle.DataTable.MasterSource.DataTable, IBizImportesCabecera, ACabecera) then
ACabecera.RecalcularImporte;
end;
end;
procedure TBizImportePuntosFieldRules.OnChange(
Sender: TDACustomField);
var
aDetalle : IBizPuntosDetalle;
aCabecera : IBizImportesCabecera;
aParche : IParche;
begin
inherited;
{ PARCHE ********************************** }
if Supports(DataTable, IParche, aParche) and
not (aParche.PuedoLanzarEvento) then
Exit;
if Supports(DataTable, IBizPuntosDetalle, aDetalle) then
begin
if Sender.Value = 0 then
Sender.Value := Null;
aDetalle.RecalcularImporte;
if Assigned(aDetalle.DataTable.FindField(fld_TIPODETALLE)) then
if (aDetalle.DataTable.FindField(fld_TIPODETALLE).AsString = TIPODETALLE_TITULO) then
RellenarImportePuntosEnCapitulo(aDetalle.DataTable);
RecalcularSubtotales(aDetalle.DataTable);
if Assigned(aDetalle.DataTable.MasterSource) and
Supports(aDetalle.DataTable.MasterSource.DataTable, IBizImportesCabecera, ACabecera) then
ACabecera.RecalcularImporte;
end;
end;
{ TBizVisibleFieldRules }
procedure TBizVisibleFieldRules.OnChange(Sender: TDACustomField);
var
aDetalle : IBizVisibleDetalle;
aParche : IParche;
begin
inherited;
{ PARCHE ********************************** }
if Supports(DataTable, IParche, aParche) and
not (aParche.PuedoLanzarEvento) then
Exit;
if Supports(DataTable, IBizVisibleDetalle, aDetalle) then
begin
if Assigned(aDetalle.DataTable.FindField(fld_TIPODETALLE)) then
if (aDetalle.DataTable.FindField(fld_TIPODETALLE).AsString = TIPODETALLE_TITULO) then
RellenarVisibleEnCapitulo(aDetalle.DataTable);
end;
end;
initialization
RegisterFieldRules('Client.Field.Cantidad', TBizCantidadFieldRules);
RegisterFieldRules('Client.Field.ImporteUnidad', TBizImporteUnidadFieldRules);
RegisterFieldRules('Client.Field.TipoDetalle', TBizTipoDetalleFieldRules);
RegisterFieldRules('Client.Field.ImportePuntos', TBizImportePuntosFieldRules);
RegisterFieldRules('Client.Field.Puntos', TBizPuntosFieldRules);
RegisterFieldRules('Client.Field.Visible', TBizVisibleFieldRules);
finalization
end.