404 lines
13 KiB
ObjectPascal
404 lines
13 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; AClienteID: Integer = -1): Boolean; overload;
|
|||
|
|
function AnadirArticulo(ADetalles: IDAStronglyTypedDataTable; IDArticulo: Integer; AClienteID: Integer = -1): Boolean; overload;
|
|||
|
|
procedure ActualizarDetalles(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo);
|
|||
|
|
procedure CambiarSignoDetalles(ADetalles: IDAStronglyTypedDataTable);
|
|||
|
|
procedure AnadirConceptoInicial(ADetalles: IDAStronglyTypedDataTable; AConcepto: String);
|
|||
|
|
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; AClienteID: Integer = -1): Boolean; overload;
|
|||
|
|
function AnadirArticulo(ADetalles: IDAStronglyTypedDataTable; IDArticulo: Integer; AClienteID: Integer = -1): Boolean; overload;
|
|||
|
|
procedure AnadirArticulos(ADetalles: IDAStronglyTypedDataTable); virtual;
|
|||
|
|
procedure ActualizarDetalles(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo);
|
|||
|
|
procedure CambiarSignoDetalles(ADetalles: IDAStronglyTypedDataTable);
|
|||
|
|
procedure AnadirConceptoInicial(ADetalles: IDAStronglyTypedDataTable; AConcepto: String);
|
|||
|
|
|
|||
|
|
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);
|
|||
|
|
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; AClienteID: Integer = -1): Boolean;
|
|||
|
|
var
|
|||
|
|
AArticulo: IBizArticulo;
|
|||
|
|
begin
|
|||
|
|
{
|
|||
|
|
A<EFBFBD>ade el art<EFBFBD>culo con la referencia pasada por parametro a los detalles pasados por parametro
|
|||
|
|
En el caso de asignar un AClienteID el articulo debe contener el descuento para ese cliente
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Result := False;
|
|||
|
|
BeginUpdate(ADetalles);
|
|||
|
|
ShowHourglassCursor;
|
|||
|
|
try
|
|||
|
|
AArticulo := FArticulosController.Buscar(IDArticulo, AClienteID);
|
|||
|
|
|
|||
|
|
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.AnadirConceptoInicial(ADetalles: IDAStronglyTypedDataTable; AConcepto: String);
|
|||
|
|
begin
|
|||
|
|
if Assigned(ADetalles) then
|
|||
|
|
begin
|
|||
|
|
With ADetalles.DataTable do
|
|||
|
|
begin
|
|||
|
|
First;
|
|||
|
|
Add(ADetalles, TIPO_DETALLE_TITULO);
|
|||
|
|
Edit;
|
|||
|
|
FieldByName(CAMPO_CONCEPTO).AsString := AConcepto;
|
|||
|
|
Post;
|
|||
|
|
//Subimos la linea insertada al inicio de los detalles
|
|||
|
|
Self.Mover(ADetalles.DataTable, 1, -1);
|
|||
|
|
//A<>adimos linea en blanco
|
|||
|
|
Add(ADetalles, TIPO_DETALLE_CONCEPTO);
|
|||
|
|
Edit;
|
|||
|
|
FieldByName(CAMPO_CONCEPTO).AsString := '';
|
|||
|
|
Post;
|
|||
|
|
// First;
|
|||
|
|
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;
|
|||
|
|
|
|||
|
|
{ <EFBFBD><EFBFBD><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<EFBFBD>n de la relacion:
|
|||
|
|
Master.ID = Detail.ID_PRESUPUESTO.
|
|||
|
|
|
|||
|
|
Por esa raz<EFBFBD>n no sirve hacer un recorrido
|
|||
|
|
desde el principio hasta el final porque
|
|||
|
|
las detalles van desapareciendo seg<EFBFBD>n asignamos
|
|||
|
|
el valor al campo ID y nos mueve aleatoriamente
|
|||
|
|
la posici<EFBFBD>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;
|
|||
|
|
|
|||
|
|
procedure TControllerDetallesArticulos.CambiarSignoDetalles(ADetalles: IDAStronglyTypedDataTable);
|
|||
|
|
begin
|
|||
|
|
//Cambia de signo los detalles de la pasados por par<61>metro
|
|||
|
|
if Assigned(ADetalles) then
|
|||
|
|
begin
|
|||
|
|
try
|
|||
|
|
BeginUpdate(ADetalles);
|
|||
|
|
|
|||
|
|
if not ADetalles.DataTable.Active then
|
|||
|
|
ADetalles.DataTable.Active := True;
|
|||
|
|
|
|||
|
|
with ADetalles.DataTable do
|
|||
|
|
begin
|
|||
|
|
First;
|
|||
|
|
while not EOF do
|
|||
|
|
begin
|
|||
|
|
if (FieldByName(CAMPO_CANTIDAD).AsInteger <> 0) then
|
|||
|
|
begin
|
|||
|
|
Edit;
|
|||
|
|
FieldByName(CAMPO_CANTIDAD).AsInteger := -1;
|
|||
|
|
end;
|
|||
|
|
Next;
|
|||
|
|
end;
|
|||
|
|
end;
|
|||
|
|
finally
|
|||
|
|
EndUpdate(ADetalles);
|
|||
|
|
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; AClienteID: Integer = -1): Boolean;
|
|||
|
|
var
|
|||
|
|
AArticulo: IBizArticulo;
|
|||
|
|
begin
|
|||
|
|
{
|
|||
|
|
A<EFBFBD>ade el art<EFBFBD>culo con la referencia pasada por parametro a los detalles pasados por parametro
|
|||
|
|
En el caso de asignar un AClienteID el articulo debe contener el descuento para ese cliente
|
|||
|
|
}
|
|||
|
|
Result := False;
|
|||
|
|
BeginUpdate(ADetalles);
|
|||
|
|
ShowHourglassCursor;
|
|||
|
|
try
|
|||
|
|
case TipoReferencia of
|
|||
|
|
tCliente: AArticulo := FArticulosController.BuscarReferencia(Referencia, AClienteID);
|
|||
|
|
tProveedor: AArticulo := FArticulosController.BuscarReferenciaProveedor(Referencia, AClienteID)
|
|||
|
|
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.
|