ConstruccionesCNJ_FactuGES/Modulos/Presupuestos/Controller/uDetallesPresupuestoController.pas
2007-06-21 15:50:59 +00:00

409 lines
13 KiB
ObjectPascal
Raw Blame History

unit uDetallesPresupuestoController;
interface
uses
Classes, uDADataTable,
uControllerDetallesBase, uBizDetallesPresupuesto, uIDataModulePresupuestos;
const
CAMPO_DESCUENTO = 'DESCUENTO';
TIPO_DETALLE_DTO = 'Descuento';
type
IDetallesPresupuestoController = interface(IControllerDetallesBase)
['{30AE4357-BA51-49D1-8113-A03C97B78F32}']
procedure AsignarID(ADetalles: IBizDetallesPresupuesto; IDNuevo: Integer; AEsNuevo:Boolean);
procedure AddCapitulo(ADataTable: IDAStronglyTypedDataTable);
end;
TDetallesPresupuestoController = class(TControllerDetallesBase, IDetallesPresupuestoController)
private
FDataModule : IDataModulePresupuestos;
FImporteSubtotal: Double;
protected
procedure TratamientoDetalleDTO(DataTable: TDADataTable); virtual;
procedure CalculoDetalleDTO(DataTable: TDADataTable; var ImporteAcumulado : Double; var ImporteTotal : Double); virtual;
procedure TratamientoDetalleSalto(DataTable: TDADataTable); override;
procedure TratamientoDetalleTitulo(DataTable: TDADataTable); override;
procedure TratamientoDetalleSubtotal(DataTable: TDADataTable); override;
procedure TratamientoDetalleConcepto(DataTable: TDADataTable); override;
procedure validarCampos(DataTable: TDADataTable); override;
procedure CalculoDetalleSubtotal(DataTable: TDADataTable; var ImporteAcumulado : Double;
var ImporteTotal : Double); override;
function CalcularTotalesHijos(Modificar: Boolean; DataTable: TDADataTable;
var ImporteAcumulado: Double; var ImporteTotal: Double): Double; override;
public
procedure Move(ADataTable: IDAStronglyTypedDataTable; Posicion: TIntegerArray; Posiciones: Integer); override;
procedure Add(ADataTable: IDAStronglyTypedDataTable; TipoConcepto: Variant); override;
procedure Delete(ADataTable: IDAStronglyTypedDataTable; Posicion: TIntegerArray); override;
procedure AddCapitulo(ADataTable: IDAStronglyTypedDataTable);
procedure AsignarID(ADetalles: IBizDetallesPresupuesto; IDNuevo: Integer; AEsNuevo:Boolean);
constructor Create; override;
destructor Destroy; override;
function DarListaTiposDetalle: TStringList; override;
end;
implementation
uses
SysUtils, uDAInterfaces, Variants, uDataModulePresupuestos;
{ TDetallesPresupuestoController }
procedure TDetallesPresupuestoController.Add(ADataTable: IDAStronglyTypedDataTable; TipoConcepto: Variant);
var
AuxNumOrden : Variant;
begin
//Sobreescribimos el m<>todo porque si a<>adimos teniendo el puntero en un registro
//de tipo subtotal, comprobamos si tiene descuento para a<>adir el nuevo registro
//despues de dicho concepto y no entre medias.
//inherited;
AuxNumOrden := Null;
BeginUpdate(ADataTable);
try
with ADataTable do
begin
if not DataTable.IsEmpty then
begin
AuxNumOrden := DataTable.FieldByName(CAMPO_POSICION).AsVariant;
if (getTipo(ADataTable, AuxNumOrden) = TIPO_DETALLE_SUBTOTAL)
and (getTipo(ADataTable, (AuxNumOrden + 1)) = TIPO_DETALLE_DTO) then
Inc(AuxNumOrden);
end;
AuxNumOrden := desplazarNPosiciones(DataTable, AuxNumOrden, 1);
DataTable.Insert;
DataTable.FieldByName(CAMPO_POSICION).AsInteger := AuxNumOrden;
DataTable.FieldByName(CAMPO_TIPO).AsString := TipoConcepto;
if (TipoConcepto = TIPO_DETALLE_TITULO)
then DataTable.FieldByName(CAMPO_CONCEPTO).AsVariant := '{\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fnil\fcharset0 Comic Sans MS;}}\viewkind4\uc1\pard\lang3082\ul\b\f0\fs20 Cap\''edtulo de ...\par}'
else if (TipoConcepto = TIPO_DETALLE_SUBTOTAL)
then DataTable.FieldByName(CAMPO_CONCEPTO).AsVariant := '{\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fnil\fcharset0 Comic Sans MS;}{\f1\fnil Tahoma;}}\viewkind4\uc1\pard\lang3082\b\f0\fs20 Total cap\''edtulo de ...\b0\f1\fs16\par}'
else if (TipoConcepto = TIPO_DETALLE_DTO)
then DataTable.FieldByName(CAMPO_CONCEPTO).AsVariant := '{\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fnil\fcharset0 Comic Sans MS;}{\f1\fnil Tahoma;}}\viewkind4\uc1\pard\lang3082\b\f0\fs20 Descuento especial ...\b0\f1\fs16\par}';
DataTable.post;
end;
finally
EndUpdate(ADataTable);
end;
end;
procedure TDetallesPresupuestoController.AddCapitulo(ADataTable: IDAStronglyTypedDataTable);
begin
BeginUpdate(ADataTable);
try
with ADataTable do
begin
Add(ADataTable, TIPO_DETALLE_TITULO);
Add(ADataTable, TIPO_DETALLE_CONCEPTO);
Add(ADataTable, TIPO_DETALLE_CONCEPTO);
Add(ADataTable, TIPO_DETALLE_CONCEPTO);
Add(ADataTable, TIPO_DETALLE_SUBTOTAL);
Add(ADataTable, TIPO_DETALLE_DTO);
end;
finally
EndUpdate(ADataTable);
end;
end;
procedure TDetallesPresupuestoController.AsignarID(ADetalles: IBizDetallesPresupuesto;
IDNuevo: Integer; AEsNuevo:Boolean);
begin
with ADetalles do
begin
DataTable.DisableControls;
try
if not DataTable.Active then
DataTable.Active := True;
{ <20><><EFBFBD><EFBFBD> OJO !!!!
Para asignar el ID en los detalles hay
que tener en cuenta una cosa:
Si se cambia el ID, ese detalle ya no
pertenece a esa cabecera porque ya no se
cumple la condici<63>n de la relacion:
Master.ID = Detail.ID_PRESUPUESTO.
Por esa raz<61>n no sirve hacer un recorrido
desde el principio hasta el final porque
las detalles van desapareciendo seg<65>n asignamos
el valor al campo ID y nos mueve aleatoriamente
la posici<63>n del registro actual.
Es mejor hacer un bucle sencillo hasta que
"se gasten" todos los detalles. Cuando el
RecordCount llegue a 0 quiere decir que hemos
tratado todos los detalles.
El bucle cambia en el caso de ser llamada esta funcion desde modificar
un presupuesto ya que en ese caso s<> que hay que hacer un recorrido
total de las tuplas de detalle.
}
if AEsNuevo then
begin
while RecordCount > 0 do
begin
DataTable.First;
Edit;
ID := FDataModule.GetNextID(DataTable.LogicalName);
ID_PRESUPUESTO := IDNuevo;
Post
end
end
else
begin
DataTable.First;
while not DataTable.EOF do
begin
if not EsNuevo then
begin
Edit;
ID := FDataModule.GetNextID(DataTable.LogicalName);
ID_PRESUPUESTO := IDNuevo;
Post
end;
DataTable.Next
end;
end;
finally
DataTable.EnableControls;
end;
end;
end;
function TDetallesPresupuestoController.CalcularTotalesHijos(Modificar: Boolean;
DataTable: TDADataTable;
var ImporteAcumulado, ImporteTotal: Double): Double;
begin
if (DataTable.FieldByName(CAMPO_TIPO).AsString = TIPO_DETALLE_DTO) then
begin
if Modificar then
TratamientoDetalleDTO(DataTable);
CalculoDetalleDTO(DataTable, ImporteAcumulado, ImporteTotal);
end
end;
procedure TDetallesPresupuestoController.CalculoDetalleDTO(DataTable: TDADataTable; var ImporteAcumulado, ImporteTotal: Double);
var
ImporteDto: Double;
begin
ImporteDto := (-1)*((FImporteSubtotal * DataTable.FieldByName(CAMPO_DESCUENTO).AsFloat) / 100);
with DataTable do
begin
if not Editing then Edit;
FieldByName(CAMPO_IMPORTE_TOTAL).AsFloat := ImporteDto;
Post;
end;
FImporteSubtotal := 0;
ImporteTotal := ImporteTotal + ImporteDto;
end;
procedure TDetallesPresupuestoController.CalculoDetalleSubtotal(
DataTable: TDADataTable; var ImporteAcumulado, ImporteTotal: Double);
begin
FImporteSubtotal := ImporteAcumulado;
inherited;
end;
constructor TDetallesPresupuestoController.Create;
begin
inherited;
FDataModule := TDataModulePresupuestos.Create(Nil);
FImporteSubtotal := 0;
end;
function TDetallesPresupuestoController.DarListaTiposDetalle: TStringList;
begin
Result := inherited DarListaTiposDetalle;
Result.Values[TIPO_DETALLE_DTO] := 'Descuento';
end;
procedure TDetallesPresupuestoController.Delete(ADataTable: IDAStronglyTypedDataTable; Posicion: TIntegerArray);
var
i: integer;
AField: TDAField;
DeletePosicion: Integer;
begin
//inherited
AField := ADataTable.DataTable.FindField(CAMPO_POSICION);
if not Assigned(AField) then
raise Exception.Create('Campo ' + CAMPO_POSICION + ' no encontrado (Delete)');
BeginUpdate(ADataTable);
try
with ADataTable do
begin
for i := 0 to High(POSICION) do
begin
DataTable.First;
DeletePosicion := POSICION[i];
if DataTable.Locate(CAMPO_POSICION, IntToStr(DeletePosicion), []) then
begin
if (DataTable.FieldByName(CAMPO_TIPO).AsString = TIPO_DETALLE_SUBTOTAL) then
begin
DataTable.Delete;
DataTable.First;
if (DataTable.Locate(CAMPO_POSICION, IntToStr((DeletePosicion + 1)), []))
and (DataTable.FieldByName(CAMPO_TIPO).AsString = TIPO_DETALLE_DTO) then
DataTable.Delete;
end
else DataTable.Delete;
end;
end;
renumerar(DataTable, DeletePosicion);
end;
finally
EndUpdate(ADataTable);
end;
end;
destructor TDetallesPresupuestoController.Destroy;
begin
FDataModule := Nil;
inherited;
end;
procedure TDetallesPresupuestoController.Move(ADataTable: IDAStronglyTypedDataTable; Posicion: TIntegerArray;
Posiciones: Integer);
var
i:Integer;
AField: TDAField;
PosicionesAux: Integer;
begin
//Sobreescribimos el m<>todo porque en el caso de mover un concepto y ser un subtitulo
//el concepto a intercambiar posici<63>n comprobamos si tiene descuento para desplazar dos unidades
//el concepto a mover
//inherited;
AField := ADataTable.DataTable.FindField(CAMPO_POSICION);
if not Assigned(AField) then
raise Exception.Create('Campo ' + CAMPO_POSICION + ' no encontrado (Move presupuestos controller)');
BeginUpdate(ADataTable);
try
with ADataTable do
begin
//Empezamos desde abajo
if Posiciones > 0 then
begin
for i:= High(POSICION) downto 0 do
begin
if (getTipo(ADataTable, (POSICION[i]+1)) = TIPO_DETALLE_SUBTOTAL)
and (getTipo(ADataTable, (POSICION[i]+2)) = TIPO_DETALLE_DTO) then
begin
Mover(DataTable, POSICION[i], Posiciones);
Mover(DataTable, POSICION[i]+1, Posiciones)
end
else
Mover(DataTable, POSICION[i], Posiciones);
end;
end
else
//Empezamos desde arriba
for i:= 0 to High(POSICION) do
begin
if (getTipo(ADataTable, (POSICION[i]-1)) = TIPO_DETALLE_DTO)
and (getTipo(ADataTable, (POSICION[i]-2)) = TIPO_DETALLE_SUBTOTAL) then
begin
Mover(DataTable, POSICION[i], Posiciones);
Mover(DataTable, POSICION[i]-1, Posiciones)
end
else
Mover(DataTable, POSICION[i], Posiciones);
end;
end;
finally
EndUpdate(ADataTable);
end;
end;
procedure TDetallesPresupuestoController.TratamientoDetalleConcepto(DataTable: TDADataTable);
begin
inherited;
with DataTable do
begin
if not Editing then Edit;
FieldByName(CAMPO_DESCUENTO).AsVariant := Null;
Post;
end;
end;
procedure TDetallesPresupuestoController.TratamientoDetalleDTO(DataTable: TDADataTable);
begin
with DataTable do
begin
if not Editing then Edit;
if (FieldByName(CAMPO_CONCEPTO).AsString = CTE_DESC_SALTO) then
FieldByName(CAMPO_CONCEPTO).AsVariant := Null;
FieldByName(CAMPO_CANTIDAD).AsVariant := Null;
FieldByName(CAMPO_IMPORTE_UNIDAD).AsVariant := Null;
Post;
end;
end;
procedure TDetallesPresupuestoController.TratamientoDetalleSalto(DataTable: TDADataTable);
begin
inherited;
with DataTable do
begin
if not Editing then Edit;
FieldByName(CAMPO_DESCUENTO).AsVariant := Null;
Post;
end;
end;
procedure TDetallesPresupuestoController.TratamientoDetalleSubtotal(DataTable: TDADataTable);
begin
inherited;
with DataTable do
begin
if not Editing then Edit;
FieldByName(CAMPO_DESCUENTO).AsVariant := Null;
Post;
end;
end;
procedure TDetallesPresupuestoController.TratamientoDetalleTitulo(DataTable: TDADataTable);
begin
inherited;
with DataTable do
begin
if not Editing then Edit;
FieldByName(CAMPO_DESCUENTO).AsVariant := Null;
Post;
end;
end;
procedure TDetallesPresupuestoController.validarCampos(DataTable: TDADataTable);
var
AField: TDAField;
begin
inherited;
//Validamos la existencia de todos los campos necesarios
AField := DataTable.FindField(CAMPO_DESCUENTO);
if not Assigned(AField) then
raise Exception.Create('Campo ' + CAMPO_DESCUENTO + ' no encontrado (validarCampos)');
end;
end.