unit uEmpresasController; interface uses Windows, Forms, Classes, Controls, Contnrs, SysUtils, uBizEmpresas, uIDataModuleEmpresas, uDADataTable; type IEmpresasController = interface ['{2F0AB21C-4F19-446E-87C4-B9C1038850FC}'] function Buscar(const ID: Integer): IBizEmpresa; function BuscarTodos: IBizEmpresa; procedure Ver(AEmpresa : IBizEmpresa); procedure VerTodos(AEmpresas: IBizEmpresa); function Nuevo : IBizEmpresa; procedure Anadir(AEmpresa : IBizEmpresa); function Eliminar(const ID : Integer): Boolean; overload; function Eliminar(AEmpresa : IBizEmpresa): Boolean; overload; function Guardar(AEmpresa : IBizEmpresa): Boolean; procedure DescartarCambios(AEmpresa : IBizEmpresa); function Existe(const ID: Integer) : Boolean; function ToStringList(AEmpresa : IBizEmpresa) : TStringList; end; TEmpresasController = class(TInterfacedObject, IEmpresasController) protected FDataModule : IDataModuleEmpresas; procedure AsignarID(AEmpresa: IBizEmpresa; const IDNuevo : Integer); virtual; procedure AsignarIDDetalles(AEmpresa: IBizEmpresa; const IDCabecera : Integer; ADataTable : TDADataTable); function ValidarEmpresa(AEmpresa : IBizEmpresa): Boolean; virtual; public constructor Create; virtual; destructor Destroy; override; function Eliminar(const ID : Integer): Boolean; overload; function Eliminar(AEmpresa : IBizEmpresa): Boolean; overload; function Guardar(AEmpresa : IBizEmpresa): Boolean; procedure DescartarCambios(AEmpresa : IBizEmpresa); virtual; function Existe(const ID: Integer) : Boolean; virtual; procedure Anadir(AEmpresa : IBizEmpresa); virtual; function Buscar(const ID: Integer): IBizEmpresa; virtual; function BuscarTodos: IBizEmpresa; virtual; function Nuevo : IBizEmpresa; virtual; procedure Ver(AEmpresa : IBizEmpresa); virtual; procedure VerTodos(AEmpresas: IBizEmpresa); virtual; function ToStringList(AEmpresa : IBizEmpresa) : TStringList; virtual; end; implementation uses uEditorRegistryUtils, cxControls, DB, uDataModuleEmpresas, uIEditorEmpresa; { TEmpresasController } procedure TEmpresasController.Anadir(AEmpresa: IBizEmpresa); begin AEmpresa.Insert; end; procedure TEmpresasController.AsignarID(AEmpresa: IBizEmpresa; const IDNuevo: Integer); var AContador : Integer; begin if not Assigned(AEmpresa) then raise Exception.Create ('Empresa no asignada'); { Los datos bancarios hay que comprobarlos siempre tanto en inserción como en modificación. } if Assigned(AEmpresa.DatosBancarios) then AsignarIDDetalles(AEmpresa, IDNuevo, AEmpresa.DatosBancarios.DataTable); if AEmpresa.EsNuevo then begin AEmpresa.Edit; AEmpresa.ID := IDNuevo; AEmpresa.Post; end; end; procedure TEmpresasController.AsignarIDDetalles(AEmpresa: IBizEmpresa; const IDCabecera: Integer; ADataTable: TDADataTable); var AContador : Integer; begin if not ADataTable.Active then ADataTable.Active := True; if AEmpresa.EsNuevo then begin { ¡¡¡¡ 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 AEmpresa esa cabecera porque ya no se cumple la condición de la relacion: Master.ID = Detail.ID_CONTACTO. Por esa razón no sirve hacer un recorrido desde el principio hasta el final porque las detalles van desapareciendo según asignamos el valor al campo ID y nos mueve aleatoriamente la posición del registro actual. Es mejor hacer un bucle sencillo hasta que "se gasten" todos los detalles. Cuando el RecordCount llegue AEmpresa 0 quiere decir que hemos tratado todos los detalles. } while ADataTable.RecordCount > 0 do begin ADataTable.First; ADataTable.Edit; ADataTable.FieldByName('ID').AsInteger := FDataModule.GetNextID(ADataTable.LogicalName); ADataTable.FieldByName('ID_EMPRESA').AsInteger := IDCabecera; ADataTable.Post; end; end else begin { En este caso es un recorrido normal y corriente. } ADataTable.First; AContador := ADataTable.RecordCount; while (AContador > 0) do begin // ¿Es nuevo? if (ADataTable.FieldByName('ID').AsInteger < 0) then begin ADataTable.Edit; ADataTable.FieldByName('ID').AsInteger := FDataModule.GetNextID(ADataTable.LogicalName); ADataTable.Post; end; AContador := AContador - 1; ADataTable.Next; end; ADataTable.First; end; end; function TEmpresasController.Buscar(const ID: Integer): IBizEmpresa; begin Result := FDataModule.GetItem(ID) end; function TEmpresasController.BuscarTodos: IBizEmpresa; begin Result := FDataModule.GetItems; end; constructor TEmpresasController.Create; begin FDataModule := TDataModuleEmpresas.Create(Nil); end; procedure TEmpresasController.DescartarCambios(AEmpresa: IBizEmpresa); begin if not Assigned(AEmpresa) then raise Exception.Create ('Empresa no asignada'); ShowHourglassCursor; try if (AEmpresa.State in dsEditModes) then AEmpresa.Cancel; AEmpresa.DataTable.CancelUpdates; finally HideHourglassCursor; end; end; destructor TEmpresasController.Destroy; begin FDataModule := NIL; inherited; end; function TEmpresasController.Eliminar(AEmpresa: IBizEmpresa): Boolean; begin Result := False; if not Assigned(AEmpresa) then raise Exception.Create ('Empresa no asignada'); ShowHourglassCursor; try if (AEmpresa.State in dsEditModes) then AEmpresa.Cancel; AEmpresa.Delete; AEmpresa.DataTable.ApplyUpdates; Result := True; finally HideHourglassCursor; end; end; function TEmpresasController.Eliminar(const ID: Integer): Boolean; var AEmpresa : IBizEmpresa; begin AEmpresa := Buscar(ID); if not Assigned(AEmpresa) then raise Exception.Create(Format('No se ha encontrado la empresa con ID = %d', [ID])); Result := Eliminar(AEmpresa); AEmpresa := NIL; end; function TEmpresasController.Existe(const ID: Integer): Boolean; var AEmpresa : IBizEmpresa; begin try AEmpresa := Buscar(ID); Result := Assigned(AEmpresa) and (AEmpresa.ID = ID); finally AEmpresa := NIL; end; end; function TEmpresasController.Guardar(AEmpresa: IBizEmpresa): Boolean; var NuevoID : Integer; begin Result := False; if ValidarEmpresa(AEmpresa) then begin ShowHourglassCursor; try if AEmpresa.EsNuevo then NuevoID := FDataModule.GetNextID(AEmpresa.DataTable.LogicalName) else NuevoID := AEmpresa.ID; AsignarID(AEmpresa, NuevoID); AEmpresa.DataTable.ApplyUpdates; Result := True; finally HideHourglassCursor; end; end; end; function TEmpresasController.Nuevo: IBizEmpresa; begin Result := FDataModule.NewItem; end; function TEmpresasController.ToStringList(AEmpresa: IBizEmpresa): TStringList; begin Result := TStringList.Create; with Result do begin AEmpresa.DataTable.Active := True; AEmpresa.First; while not AEmpresa.EOF do begin Add(AEmpresa.NOMBRE); AEmpresa.Next; end; end; end; function TEmpresasController.ValidarEmpresa(AEmpresa: IBizEmpresa): Boolean; begin Result := False; if not Assigned(AEmpresa) then raise Exception.Create ('Empresa no asignada'); if (AEmpresa.DataTable.State in dsEditModes) then AEmpresa.DataTable.Post; if Length(AEmpresa.NOMBRE) = 0 then raise Exception.Create('Debe indicar al menos el nombre de la empresa.'); // Asegurarse de valores en campos "automáticos" { AEmpresa.Edit; AEmpresa.USUARIO := dmUsuarios.LoginInfo.Usuario; AEmpresa.Post;} Result := True; end; procedure TEmpresasController.Ver(AEmpresa: IBizEmpresa); var AEditor : IEditorEmpresa; begin AEditor := NIL; ShowHourglassCursor; try CreateEditor('EditorEmpresa', IEditorEmpresa, AEditor); with AEditor do begin Empresa := AEmpresa; Controller := Self; end; finally HideHourglassCursor; end; if Assigned(AEditor) then try AEditor.ShowModal; AEditor.Release; finally AEditor := NIL; end; end; procedure TEmpresasController.VerTodos(AEmpresas: IBizEmpresa); {var AEditor : IEditorClientes;} begin { CreateEditor('EditorEmpresas', IEditorClientes, AEditor); with AEditor do begin Contactos := AContactos; Controller := Self; ShowEmbedded; end;} end; end.