This repository has been archived on 2024-11-28. You can view files and clone it, but cannot push or open issues or pull requests.
LuisLeon_FactuGES/Source/Modulos/Articulos/Controller/uControllerDetallesArticulos.pas

423 lines
14 KiB
ObjectPascal
Raw Blame History

unit uControllerDetallesArticulos;
interface
uses Classes, Variants, uDACDSDataTable, uDADataTable, uControllerDetallesBase,
uBizArticulos, uArticulosController;
const
CAMPO_REFERENCIA = 'REFERENCIA'; //Campo ficticio
CAMPO_REFERENCIA_PROVEEDOR = 'REFERENCIA_PROVEEDOR'; //Campo ficticio
type
TEnumReferencia = (tCliente, tProveedor);
IControllerDetallesArticulos = interface(IControllerDetallesBase)
['{6E156796-DB1F-4727-BBFB-FBAEF2E5C098}']
procedure AsignarID(ADetalles: IDAStronglyTypedDataTable; IDCabecera: Integer; AEsNuevo:Boolean);
procedure AnadirArticulos(ADetalles: IDAStronglyTypedDataTable; const ANuevaFila :Boolean = True);
function AnadirArticulo(ADetalles: IDAStronglyTypedDataTable; Referencia: String; TipoReferencia: TEnumReferencia; AClienteID: Integer = -1; const ACantidad: Integer = 1): Boolean; overload;
function AnadirArticulo(ADetalles: IDAStronglyTypedDataTable; IDArticulo: Integer; AClienteID: Integer = -1; const ACantidad: Integer = 1): Boolean; overload;
procedure ActualizarDetalles(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo);
procedure CambiarSignoDetalles(ADetalles: IDAStronglyTypedDataTable);
procedure AnadirConceptoInicial(ADetalles: IDAStronglyTypedDataTable; AConcepto: String);
end;
TControllerDetallesArticulos = class (TControllerDetallesBase, IControllerDetallesArticulos)
protected
FArticulosController: IArticulosController;
procedure EliminarArticulosProveedor(ADetalles: IDAStronglyTypedDataTable);
procedure AsignarDatos(ADetalles: IDAStronglyTypedDataTable; IDCabecera: Integer); virtual;
procedure RellenarOtros(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); virtual;
procedure RellenarImportes(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); virtual;
procedure RellenarGenerales(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); virtual;
procedure RellenarCantidad(ADetalles: IDAStronglyTypedDataTable; const ACantidad: Integer); virtual;
procedure RellenarDetalle(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo; const ACantidad: Integer = 1); virtual;
procedure Add(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo; const ACantidad: Integer = 1); overload;
procedure AsignarController; virtual;
public
procedure AsignarID(ADetalles: IDAStronglyTypedDataTable; IDCabecera: Integer; AEsNuevo:Boolean);
function AnadirArticulo(ADetalles: IDAStronglyTypedDataTable; Referencia: String; TipoReferencia: TEnumReferencia; AClienteID: Integer = -1; const ACantidad: Integer = 1): Boolean; overload;
function AnadirArticulo(ADetalles: IDAStronglyTypedDataTable; IDArticulo: Integer; AClienteID: Integer = -1; const ACantidad: Integer = 1): Boolean; overload;
procedure AnadirArticulos(ADetalles: IDAStronglyTypedDataTable; const ANuevaFila :Boolean = True); 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 DB, Dialogs, cxControls, SysUtils, uDAInterfaces, uCalculosUtils, schArticulosClient_Intf;
{ TControllerDetallesArticulos }
procedure TControllerDetallesArticulos.ActualizarDetalles(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo);
var
ACantidad: 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
begin
ACantidad := ADetalles.DataTable.FieldByName(CAMPO_CANTIDAD).AsInteger;
RellenarDetalle(ADetalles, AArticulos, ACantidad);
end
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; const ACantidad: Integer);
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, ACantidad);
Next;
end;
end;
finally
EndUpdate(ADetalles);
HideHourglassCursor;
end;
end;
end;
function TControllerDetallesArticulos.AnadirArticulo(ADetalles: IDAStronglyTypedDataTable; IDArticulo: Integer; AClienteID: Integer = -1; const ACantidad: Integer = 1): Boolean;
var
AArticulo: IBizArticulo;
begin
{
A<>ade el art<72>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, ACantidad);
Result := True;
end;
end;
finally
EndUpdate(ADetalles);
HideHourglassCursor;
end;
end;
procedure TControllerDetallesArticulos.AnadirArticulos(ADetalles: IDAStronglyTypedDataTable; const ANuevaFila :Boolean = True);
var
AArticulos: IBizArticulo;
begin
if Assigned(ADetalles) then
begin
try
AArticulos := (FArticulosController.BuscarTodos as IBizArticulo);
//Si nueva fila es false, quiere decir que se sustituye un determinado art<72>culo, por ello la lista a seleccionar no debe ser multiselect
if ANuevaFila then
begin
AArticulos := FArticulosController.ElegirArticulos(AArticulos, 'Elija los art<72>culos que desea a<>adir', True);
Add(ADetalles, AArticulos)
end
else
begin
AArticulos := FArticulosController.ElegirArticulos(AArticulos, 'Elija el art<72>culo que desea a<>adir', False);
RellenarDetalle(ADetalles, AArticulos);
end;
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;
{ <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;
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) * FieldByName(CAMPO_CANTIDAD).AsInteger;
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; const ACantidad: Integer = 1): Boolean;
var
AArticulo: IBizArticulo;
begin
{
A<>ade el art<72>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, ACantidad);
Result := True;
end;
end;
finally
EndUpdate(ADetalles);
HideHourglassCursor;
end;
end;
procedure TControllerDetallesArticulos.RellenarCantidad(ADetalles: IDAStronglyTypedDataTable; const ACantidad: Integer);
begin
if Assigned(ADetalles) then
begin
ADetalles.DataTable.FieldByName(CAMPO_CANTIDAD).AsInteger := ACantidad;
end;
end;
procedure TControllerDetallesArticulos.RellenarOtros(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo);
begin
// Procedimiento que en los hijos se sobreescribir<69> para rellenar otros campos seg<65>n necesidades
end;
procedure TControllerDetallesArticulos.RellenarDetalle(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo; const ACantidad: Integer = 1);
begin
if Assigned(ADetalles) then
begin
BeginUpdate(ADetalles);
try
if not ADetalles.DataTable.Editing then
ADetalles.DataTable.Edit;
RellenarGenerales(ADetalles, AArticulos);
RellenarCantidad(ADetalles, ACantidad);
RellenarImportes(ADetalles, AArticulos);
RellenarOtros(ADetalles, AArticulos);
ADetalles.DataTable.Post;
finally
EndUpdate(ADetalles);
end;
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;
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.