341 lines
11 KiB
ObjectPascal
341 lines
11 KiB
ObjectPascal
unit uControllerDetallesArticulos;
|
||
|
||
interface
|
||
|
||
uses Classes, Variants, uDACDSDataTable, uDADataTable, uControllerDetallesDTO,
|
||
uBizArticulos, uArticulosController;
|
||
|
||
const
|
||
CAMPO_ID_ARTICULOS = 'ID_ARTICULO';
|
||
CAMPO_REFERENCIA = 'REFERENCIA'; //Campo ficticio
|
||
CAMPO_REFERENCIA_PROVEEDOR = 'REFERENCIA_PROVEEDOR'; //Campo ficticio
|
||
|
||
type
|
||
TEnumReferencia = (tCliente, tProveedor);
|
||
|
||
IControllerDetallesArticulos = interface(IControllerDetallesDTO)
|
||
['{6E156796-DB1F-4727-BBFB-FBAEF2E5C098}']
|
||
procedure AsignarID(ADetalles: IDAStronglyTypedDataTable; IDCabecera: Integer; AEsNuevo:Boolean);
|
||
procedure AnadirArticulos(ADetalles: IDAStronglyTypedDataTable);
|
||
function AnadirArticulo(ADetalles: IDAStronglyTypedDataTable; Referencia: String; TipoReferencia: TEnumReferencia): Boolean; overload;
|
||
function AnadirArticulo(ADetalles: IDAStronglyTypedDataTable; IDArticulo: Integer): Boolean; overload;
|
||
procedure ActualizarDetalles(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo);
|
||
end;
|
||
|
||
TControllerDetallesArticulos = class (TControllerDetallesDTO, IControllerDetallesArticulos)
|
||
protected
|
||
FArticulosController: IArticulosController;
|
||
|
||
procedure EliminarArticulosProveedor(ADetalles: IDAStronglyTypedDataTable);
|
||
procedure RellenarDescuento(ADetalles: IDAStronglyTypedDataTable; ADescuento : Float);
|
||
|
||
procedure AsignarDatos(ADetalles: IDAStronglyTypedDataTable; IDCabecera: Integer); virtual;
|
||
procedure RellenarDescuentos(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); virtual;
|
||
procedure RellenarImportes(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); virtual;
|
||
procedure RellenarGenerales(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); virtual;
|
||
procedure RellenarDetalle(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); virtual;
|
||
procedure Add(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); overload;
|
||
|
||
procedure AsignarController; virtual;
|
||
|
||
public
|
||
procedure AsignarID(ADetalles: IDAStronglyTypedDataTable; IDCabecera: Integer; AEsNuevo:Boolean);
|
||
function AnadirArticulo(ADetalles: IDAStronglyTypedDataTable; Referencia: String; TipoReferencia: TEnumReferencia): Boolean; overload;
|
||
function AnadirArticulo(ADetalles: IDAStronglyTypedDataTable; IDArticulo: Integer): Boolean; overload;
|
||
procedure AnadirArticulos(ADetalles: IDAStronglyTypedDataTable); virtual;
|
||
procedure ActualizarDetalles(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo);
|
||
|
||
constructor Create; override;
|
||
destructor Destroy; override;
|
||
end;
|
||
|
||
|
||
implementation
|
||
|
||
{ TControllerDetallesArticulos }
|
||
|
||
uses Dialogs, cxControls, SysUtils, uDAInterfaces, uControllerDetallesBase, schArticulosClient_Intf;
|
||
|
||
|
||
{ TControllerDetallesArticulos }
|
||
|
||
procedure TControllerDetallesArticulos.ActualizarDetalles(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo);
|
||
var
|
||
i, j : Integer;
|
||
begin
|
||
if (Assigned(ADetalles) and Assigned(AArticulos)) then
|
||
begin
|
||
if not AArticulos.DataTable.Active then
|
||
AArticulos.DataTable.Active := True;
|
||
|
||
BeginUpdate(ADetalles);
|
||
try
|
||
ADetalles.DataTable.First;
|
||
with ADetalles.DataTable do
|
||
begin
|
||
while not Eof do
|
||
begin
|
||
Edit;
|
||
AArticulos.DataTable.First;
|
||
try
|
||
if AArticulos.DataTable.Locate(CAMPO_ID, FieldByName(CAMPO_ID_ARTICULOS).AsVariant, []) then
|
||
RellenarDetalle(ADetalles, AArticulos)
|
||
else
|
||
RellenarDetalle(ADetalles, Nil);
|
||
except
|
||
on E: Exception do
|
||
ShowMessage(E.Message);
|
||
end;
|
||
Next;
|
||
end;
|
||
//Volvemos a dejarlo al principio
|
||
ADetalles.DataTable.First;
|
||
end;
|
||
finally
|
||
EndUpdate(ADetalles);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TControllerDetallesArticulos.Add(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo);
|
||
begin
|
||
if Assigned(ADetalles) and Assigned(AArticulos) then
|
||
begin
|
||
try
|
||
ShowHourglassCursor;
|
||
BeginUpdate(ADetalles);
|
||
|
||
if not ADetalles.DataTable.Active then
|
||
ADetalles.DataTable.Active := True;
|
||
|
||
if not AArticulos.DataTable.Active then
|
||
AArticulos.DataTable.Active := True;
|
||
|
||
with AArticulos.DataTable do
|
||
begin
|
||
First;
|
||
while not EOF do
|
||
begin
|
||
Self.Add(ADetalles, TIPO_DETALLE_CONCEPTO);
|
||
RellenarDetalle(ADetalles, AArticulos);
|
||
Next;
|
||
end;
|
||
end;
|
||
finally
|
||
EndUpdate(ADetalles);
|
||
HideHourglassCursor;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TControllerDetallesArticulos.AnadirArticulo(
|
||
ADetalles: IDAStronglyTypedDataTable; IDArticulo: Integer): Boolean;
|
||
var
|
||
AArticulo: IBizArticulo;
|
||
begin
|
||
Result := False;
|
||
BeginUpdate(ADetalles);
|
||
ShowHourglassCursor;
|
||
try
|
||
AArticulo := FArticulosController.Buscar(IDArticulo);
|
||
|
||
if Assigned(AArticulo) then
|
||
begin
|
||
AArticulo.DataTable.Active := True;
|
||
if (AArticulo.RecordCount > 0) then
|
||
begin
|
||
RellenarDetalle(ADetalles, AArticulo);
|
||
Result := True;
|
||
end;
|
||
end;
|
||
finally
|
||
EndUpdate(ADetalles);
|
||
HideHourglassCursor;
|
||
end;
|
||
end;
|
||
|
||
procedure TControllerDetallesArticulos.AnadirArticulos(ADetalles: IDAStronglyTypedDataTable);
|
||
var
|
||
AArticulos: IBizArticulo;
|
||
begin
|
||
if Assigned(ADetalles) then
|
||
begin
|
||
try
|
||
AArticulos := (FArticulosController.BuscarTodos as IBizArticulo);
|
||
AArticulos := FArticulosController.ElegirArticulos(AArticulos, 'Elija los art<72>culos que desea a<>adir', True);
|
||
Add(ADetalles, AArticulos);
|
||
finally
|
||
AArticulos := Nil;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TControllerDetallesArticulos.AsignarController;
|
||
begin
|
||
FArticulosController := TArticulosController.Create;
|
||
end;
|
||
|
||
procedure TControllerDetallesArticulos.AsignarDatos(ADetalles: IDAStronglyTypedDataTable; IDCabecera: Integer);
|
||
begin
|
||
//
|
||
end;
|
||
|
||
procedure TControllerDetallesArticulos.AsignarID(ADetalles: IDAStronglyTypedDataTable; IDCabecera: Integer; AEsNuevo: Boolean);
|
||
begin
|
||
with ADetalles do
|
||
begin
|
||
DataTable.DisableControls;
|
||
try
|
||
begin
|
||
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 si que hay que hacer un recorrido
|
||
total de las tuplas de detalle.
|
||
}
|
||
|
||
if AEsNuevo then
|
||
begin
|
||
while RecordCount > 0 do
|
||
begin
|
||
DataTable.First;
|
||
AsignarDatos(ADetalles, IDCabecera);
|
||
end
|
||
end
|
||
else
|
||
begin
|
||
DataTable.First;
|
||
while not DataTable.EOF do
|
||
begin
|
||
if DataTable.FieldByName('ID').AsInteger < 0 then
|
||
AsignarDatos(ADetalles, IDCabecera);
|
||
DataTable.Next
|
||
end;
|
||
end;
|
||
end;
|
||
finally
|
||
DataTable.EnableControls;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
constructor TControllerDetallesArticulos.Create;
|
||
begin
|
||
inherited;
|
||
AsignarController;
|
||
end;
|
||
|
||
destructor TControllerDetallesArticulos.Destroy;
|
||
begin
|
||
FArticulosController := Nil;
|
||
inherited;
|
||
end;
|
||
|
||
procedure TControllerDetallesArticulos.EliminarArticulosProveedor(ADetalles: IDAStronglyTypedDataTable);
|
||
begin
|
||
if Assigned(ADetalles) then
|
||
begin
|
||
with ADetalles.DataTable do
|
||
begin
|
||
First;
|
||
while not Eof do
|
||
if not FieldByName(CAMPO_ID_ARTICULOS).IsNull then
|
||
Delete
|
||
else
|
||
Next;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TControllerDetallesArticulos.AnadirArticulo(ADetalles: IDAStronglyTypedDataTable; Referencia: String; TipoReferencia: TEnumReferencia): Boolean;
|
||
var
|
||
AArticulo: IBizArticulo;
|
||
begin
|
||
Result := False;
|
||
BeginUpdate(ADetalles);
|
||
ShowHourglassCursor;
|
||
try
|
||
case TipoReferencia of
|
||
tCliente: AArticulo := FArticulosController.BuscarReferencia(Referencia);
|
||
tProveedor: AArticulo := FArticulosController.BuscarReferenciaProveedor(Referencia)
|
||
end;
|
||
|
||
if Assigned(AArticulo) then
|
||
begin
|
||
AArticulo.DataTable.Active := True;
|
||
if (AArticulo.RecordCount > 0) then
|
||
begin
|
||
RellenarDetalle(ADetalles, AArticulo);
|
||
Result := True;
|
||
end;
|
||
end;
|
||
finally
|
||
EndUpdate(ADetalles);
|
||
HideHourglassCursor;
|
||
end;
|
||
end;
|
||
|
||
procedure TControllerDetallesArticulos.RellenarDescuento(ADetalles: IDAStronglyTypedDataTable; ADescuento: Float);
|
||
begin
|
||
ADetalles.DataTable.FieldByName(CAMPO_DESCUENTO).AsFloat := ADescuento;
|
||
end;
|
||
|
||
procedure TControllerDetallesArticulos.RellenarDescuentos(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo);
|
||
begin
|
||
// Procedimiento que en los hijos se sobreescribir<69> para rellenar el campo descuento seg<65>n necesidades
|
||
end;
|
||
|
||
procedure TControllerDetallesArticulos.RellenarDetalle(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo);
|
||
begin
|
||
if Assigned(ADetalles) then
|
||
begin
|
||
if not ADetalles.DataTable.Editing then
|
||
ADetalles.DataTable.Edit;
|
||
|
||
RellenarGenerales(ADetalles, AArticulos);
|
||
RellenarImportes(ADetalles, AArticulos);
|
||
RellenarDescuentos(ADetalles, AArticulos);
|
||
|
||
ADetalles.DataTable.Post;
|
||
end;
|
||
end;
|
||
|
||
procedure TControllerDetallesArticulos.RellenarGenerales(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo);
|
||
begin
|
||
if Assigned(AArticulos) then
|
||
begin
|
||
ADetalles.DataTable.FieldByName(CAMPO_ID_ARTICULOS).AsVariant := AArticulos.ID;
|
||
ADetalles.DataTable.FieldByName(CAMPO_REFERENCIA).AsVariant := AArticulos.REFERENCIA;
|
||
ADetalles.DataTable.FieldByName(CAMPO_REFERENCIA_PROVEEDOR).AsVariant := AArticulos.REFERENCIA_PROV;
|
||
ADetalles.DataTable.FieldByName(CAMPO_CONCEPTO).AsVariant := AArticulos.DESCRIPCION;
|
||
ADetalles.DataTable.FieldByName(CAMPO_CANTIDAD).AsInteger := 1;
|
||
end;
|
||
end;
|
||
|
||
procedure TControllerDetallesArticulos.RellenarImportes(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo);
|
||
begin
|
||
// Procedimiento que en los hijos se sobreescribir<69> para rellenar el campo importe seg<65>n necesidades
|
||
end;
|
||
|
||
end.
|