git-svn-id: https://192.168.0.254/svn/Proyectos.EstudioCarnicero_ProGestion/trunk@4 1b8572a8-2d6b-b84e-8c90-20ed86fa4eca
1004 lines
30 KiB
ObjectPascal
1004 lines
30 KiB
ObjectPascal
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<73>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<61>tulo. El cursor
|
||
est<73> puesto en la fila que es el t<>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<61>tulo. El cursor
|
||
est<73> puesto en la fila que es el t<>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.
|