2007-06-11 15:29:06 +00:00
unit uContactosController;
interface
uses
Windows, Forms, Classes, Controls, Contnrs, SysUtils, uDADataTable,
2008-07-15 18:09:26 +00:00
uBizContactos, uBizContactosDatosBancarios, uIDataModuleContactos, uViewGridBase;
2007-06-11 15:29:06 +00:00
type
IContactosController = interface
[ '{43F9A4ED-6563-4F95-9A56-330CF9C66731}' ]
function Buscar( const ID: Integer ) : IBizContacto;
function BuscarTodos: IBizContacto;
procedure Ver( AContacto : IBizContacto) ;
procedure VerTodos( AContactos: IBizContacto) ;
function Nuevo : IBizContacto;
procedure Anadir( AContacto : IBizContacto) ;
procedure Eliminar( const ID : Integer ) ; overload ;
function Eliminar( AContacto : IBizContacto) : Boolean ; overload ;
function Guardar( AContacto : IBizContacto) : Boolean ;
procedure DescartarCambios( AContacto : IBizContacto) ;
function Existe( const ID: Integer ) : Boolean ;
function Duplicar( AContacto : IBizContacto) : IBizContacto;
function Localizar( AContactos: IBizContacto; const ID : Integer ) : Boolean ;
2007-10-08 19:31:04 +00:00
function ElegirContacto( AContactos : IBizContacto; AMensaje: String ; AMultiSelect: Boolean ) : IBizContacto;
2007-06-11 15:29:06 +00:00
2008-07-15 18:09:26 +00:00
function ExtraerSeleccionados( AContactos: IBizContacto; Const ViewGrid: IViewGridBase = Nil ) : IBizContacto;
2007-10-08 19:31:04 +00:00
procedure Preview( AContactos : IBizContacto) ;
2008-07-15 18:09:26 +00:00
function Print( AContactos : IBizContacto) : Boolean ;
2007-06-11 15:29:06 +00:00
end ;
TContactosController = class( TInterfacedObject, IContactosController)
protected
FDataModule : IDataModuleContactos;
procedure AsignarID( AContacto: IBizContacto; const IDNuevo : Integer ) ; virtual ;
procedure AsignarIDDetalles( AContacto: IBizContacto;
const IDCabecera : Integer ; ADataTable : TDADataTable) ;
procedure FiltrarEmpresa( AContacto : IBizContacto) ; virtual ;
function _Vacio : IBizContacto; virtual ;
function ValidarContacto( AContacto : IBizContacto) : Boolean ; virtual ;
public
constructor Create; virtual ;
destructor Destroy; override ;
procedure Eliminar( const ID : Integer ) ; overload ; virtual ;
function Eliminar( AContacto : IBizContacto) : Boolean ; overload ; virtual ;
2007-10-08 19:31:04 +00:00
function Guardar( AContacto : IBizContacto) : Boolean ;
2007-06-11 15:29:06 +00:00
procedure DescartarCambios( AContacto : IBizContacto) ; virtual ;
function Existe( const ID: Integer ) : Boolean ; virtual ;
procedure Anadir( AContacto : IBizContacto) ; virtual ;
function Duplicar( AContacto: IBizContacto) : IBizContacto; virtual ;
2008-07-15 18:09:26 +00:00
function ExtraerSeleccionados( AContactos: IBizContacto; Const ViewGrid: IViewGridBase = Nil ) : IBizContacto; virtual ;
2007-06-11 15:29:06 +00:00
function Localizar( AContactos: IBizContacto; const ID : Integer ) : Boolean ;
2007-10-08 19:31:04 +00:00
2007-06-11 15:29:06 +00:00
// Se implementa en los controladores hijos
function Buscar( const ID: Integer ) : IBizContacto; virtual ; abstract ;
function BuscarTodos: IBizContacto; virtual ; abstract ;
function Nuevo : IBizContacto; virtual ; abstract ;
procedure Ver( AContacto : IBizContacto) ; virtual ; abstract ;
procedure VerTodos( AContactos: IBizContacto) ; virtual ; abstract ;
2007-10-08 19:31:04 +00:00
function ElegirContacto( AContactos : IBizContacto; AMensaje: String ; AMultiSelect: Boolean ) : IBizContacto; virtual ; abstract ;
procedure Preview( AContactos : IBizContacto) ;
2008-07-15 18:09:26 +00:00
function Print( AContactos : IBizContacto) : Boolean ;
2007-06-11 15:29:06 +00:00
end ;
implementation
uses
Dialogs, uEditorRegistryUtils, cxControls, DB, uDAInterfaces, uDataTableUtils,
2007-10-08 19:31:04 +00:00
uDataModuleUsuarios, schContactosClient_Intf, uEtiquetasContactosReportController;
2007-06-11 15:29:06 +00:00
{ TContactosController }
procedure TContactosController. Anadir( AContacto: IBizContacto) ;
begin
AContacto. Insert;
end ;
procedure TContactosController. AsignarID( AContacto: IBizContacto; const IDNuevo : Integer ) ;
begin
if not Assigned( AContacto) then
raise Exception. Create ( 'Contacto no asignado' ) ;
if AContacto. EsNuevo then
begin
{ <EFBFBD> <EFBFBD> <EFBFBD> OJO ! ! !
Primero cambiamos el ID de las tablas detalles
porque si cambiamos antes el ID de la cabecera
deja de funcionar la relacion M/ D y no
encontrar<EFBFBD> amos las filas detalle.
- - > MASTER. ID = DETAIL. ID_CONTACTO < - -
}
with AContacto. _Categorias do
begin
if not DataTable. Active then
DataTable. Active : = True ;
Insert;
ID_CONTACTO : = IDNuevo;
ID_CATEGORIA : = AContacto. ID_CATEGORIA;
Post;
end ;
end ;
{ Los datos bancarios hay que comprobarlos siempre
tanto en inserci<EFBFBD> n como en modificaci<EFBFBD> n. }
if Assigned( AContacto. DatosBancarios) then
AsignarIDDetalles( AContacto, IDNuevo, AContacto. DatosBancarios. DataTable) ;
{ Las direcciones extras hay que comprobarlas siempre
tanto en inserci<EFBFBD> n como en modificaci<EFBFBD> n. }
if Assigned( AContacto. Direcciones) then
AsignarIDDetalles( AContacto, IDNuevo, AContacto. Direcciones. DataTable) ;
if AContacto. EsNuevo then
begin
AContacto. Edit;
AContacto. ID : = IDNuevo;
AContacto. ID_EMPRESA : = dmUsuarios. IDEmpresaActual;
AContacto. Post;
end ;
end ;
function TContactosController. Duplicar( AContacto: IBizContacto) : IBizContacto;
begin
Result : = Self. _Vacio;
ShowHourglassCursor;
try
DuplicarRegistros( AContacto. DataTable, Result . DataTable, mdrActual) ;
DuplicarRegistros( AContacto. DatosBancarios. DataTable, Result . DatosBancarios. DataTable, mdrTodos) ;
if Assigned( AContacto. Direcciones) then
DuplicarRegistros( AContacto. Direcciones. DataTable, Result . Direcciones. DataTable, mdrTodos) ;
// Hay que dejar algunos campos como si fuera un contacto nuevo
Result . Edit;
with Result do
begin
ID_EMPRESA : = dmUsuarios. IDEmpresaActual;
USUARIO : = dmUsuarios. LoginInfo. Usuario;
end ;
Result . Post;
finally
HideHourglassCursor;
end ;
end ;
constructor TContactosController. Create;
begin
FDataModule : = NIL ;
end ;
procedure TContactosController. DescartarCambios( AContacto: IBizContacto) ;
begin
if not Assigned( AContacto) then
raise Exception. Create ( 'Contacto no asignado' ) ;
ShowHourglassCursor;
try
if ( AContacto. State in dsEditModes) then
AContacto. Cancel;
AContacto. DataTable. CancelUpdates;
finally
HideHourglassCursor;
end ;
end ;
destructor TContactosController. Destroy;
begin
FDataModule : = NIL ;
inherited ;
end ;
function TContactosController. Eliminar( AContacto: IBizContacto) : Boolean ;
begin
Result : = False ;
if not Assigned( AContacto) then
raise Exception. Create ( 'Contacto no asignado' ) ;
ShowHourglassCursor;
try
if ( AContacto. State in dsEditModes) then
AContacto. Cancel;
AContacto. Delete;
AContacto. DataTable. ApplyUpdates;
HideHourglassCursor;
Result : = True ;
except
on E: Exception do
begin
AContacto. DataTable. CancelUpdates;
HideHourglassCursor;
if ( Pos( 'FOREIGN KEY' , E. Message ) > 0 ) then
MessageBox( 0 , 'No se puede borrar este contacto porque tiene documentos dados de alta (como presupuestos, albaranes, facturas, etc)' , 'Atenci<63> n' , MB_ICONWARNING or MB_OK) ;
end ;
end ;
end ;
procedure TContactosController. Eliminar( const ID: Integer ) ;
var
AContacto : IBizContacto;
begin
AContacto : = Buscar( ID) ;
if not Assigned( AContacto) then
raise Exception. Create( Format( 'No se ha encontrado el contacto con ID = %d' , [ ID] ) ) ;
Eliminar( AContacto) ;
AContacto : = NIL ;
end ;
function TContactosController. Existe( const ID: Integer ) : Boolean ;
var
AContacto : IBizContacto;
begin
try
AContacto : = Buscar( ID) ;
Result : = Assigned( AContacto) and ( AContacto. ID = ID) ;
finally
AContacto : = NIL ;
end ;
end ;
2008-07-15 18:09:26 +00:00
function TContactosController. ExtraerSeleccionados( AContactos: IBizContacto; Const ViewGrid: IViewGridBase = Nil ) : IBizContacto;
2007-06-11 15:29:06 +00:00
var
ASeleccionados : IBizContacto;
begin
2008-07-15 18:09:26 +00:00
if Assigned( ViewGrid) then
begin
//Guardamos la situaci<63> n porque el CopyDataTable nos cambia la posicion
ViewGrid. SaveGridStatus;
ViewGrid. DesactivarGrid;
end ;
2007-06-11 15:29:06 +00:00
ASeleccionados : = Self. Buscar( ID_NULO) ;
CopyDataTable( AContactos. DataTable, ASeleccionados. DataTable, True ) ;
Result : = ASeleccionados;
2008-07-15 18:09:26 +00:00
if Assigned( ViewGrid) then
begin
ViewGrid. ActivarGrid;
ViewGrid. RestoreGridStatus;
end ;
2007-06-11 15:29:06 +00:00
end ;
function TContactosController. Guardar( AContacto: IBizContacto) : Boolean ;
var
NuevoID : Integer ;
begin
Result : = False ;
if ValidarContacto( AContacto) then
begin
ShowHourglassCursor;
try
if AContacto. EsNuevo then
NuevoID : = FDataModule. GetNextID( AContacto. DataTable. LogicalName)
else
NuevoID : = AContacto. ID;
AsignarID( AContacto, NuevoID) ;
AContacto. DataTable. ApplyUpdates;
Result : = True ;
finally
HideHourglassCursor;
end ;
end ;
end ;
function TContactosController. Localizar( AContactos: IBizContacto;
const ID: Integer ) : Boolean ;
begin
Result : = True ;
ShowHourglassCursor;
try
with AContactos. DataTable do
begin
DisableControls;
First;
if not Locate( fld_ContactosID, ID, [ ] ) then
Result : = False ;
EnableControls;
end ;
finally
HideHourglassCursor;
end ;
end ;
2007-10-08 19:31:04 +00:00
procedure TContactosController. Preview( AContactos: IBizContacto) ;
var
AReportController : IEtiquetasContactosReportController;
ID_Contactos: TStringList;
begin
AReportController : = TEtiquetasContactosReportController. Create;
try
ID_Contactos : = TStringList. Create;
with AContactos. DataTable do
begin
First;
while not EOF do
begin
ID_Contactos. Add( IntToStr( AContactos. ID) ) ;
Next;
end ;
end ;
AReportController. Preview( ID_Contactos. CommaText) ;
finally
AReportController : = NIL ;
ID_Contactos. Free;
end ;
end ;
2008-07-15 18:09:26 +00:00
function TContactosController. Print( AContactos: IBizContacto) : Boolean ;
2007-10-08 19:31:04 +00:00
var
AReportController : IEtiquetasContactosReportController;
ID_Contactos: TStringList;
begin
2008-07-15 18:09:26 +00:00
Result : = False ;
2007-10-08 19:31:04 +00:00
AReportController : = TEtiquetasContactosReportController. Create;
try
ID_Contactos : = TStringList. Create;
with AContactos. DataTable do
begin
First;
while not EOF do
begin
ID_Contactos. Add( IntToStr( AContactos. ID) ) ;
Next;
end ;
end ;
2008-07-15 18:09:26 +00:00
Result : = AReportController. Print( ID_Contactos. CommaText) ;
2007-10-08 19:31:04 +00:00
finally
AReportController : = NIL ;
ID_Contactos. Free;
end ;
end ;
2007-06-11 15:29:06 +00:00
procedure TContactosController. AsignarIDDetalles ( AContacto: IBizContacto; const IDCabecera : Integer ; ADataTable : TDADataTable) ;
var
AContador : Integer ;
begin
if not ADataTable. Active then
ADataTable. Active : = True ;
if AContacto. EsNuevo then
begin
{ <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_CONTACTO.
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.
}
while ADataTable. RecordCount > 0 do
begin
ADataTable. First;
ADataTable. Edit;
ADataTable. FieldByName( 'ID' ) . AsInteger : = FDataModule. GetNextID( ADataTable. LogicalName) ;
// ADataTable.FieldByName('ID_CONTACTO').AsInteger := IDCabecera;
//OJO SI UN DIA SON VARIOS LOS CAMPOS FORANEOS, SOLO FUNCIONA CUANDO ES UN <20> NICO CAMPO DE CLAVE FORANEA
ADataTable. FieldByName( ADataTable. DetailFields) . 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
// <20> 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 TContactosController. ValidarContacto( AContacto: IBizContacto) : Boolean ;
begin
Result : = False ;
if not Assigned( AContacto) then
raise Exception. Create ( 'Contacto no asignado' ) ;
if ( AContacto. DataTable. State in dsEditModes) then
AContacto. DataTable. Post;
if Length( AContacto. NOMBRE) = 0 then
raise Exception. Create( 'Debe indicar al menos el nombre de este contacto.' ) ;
// Asegurarse de valores en campos "autom<6F> ticos"
AContacto. Edit;
AContacto. USUARIO : = dmUsuarios. LoginInfo. Usuario;
AContacto. Post;
Result : = True ;
end ;
function TContactosController. _Vacio: IBizContacto;
begin
Result : = Buscar( ID_NULO) ;
end ;
procedure TContactosController. FiltrarEmpresa( AContacto: IBizContacto) ;
begin
if AContacto. DataTable. Active then
AContacto. DataTable. Active : = False ;
// Filtrar los contactos actuales por empresa
with AContacto. DataTable. Where do
begin
if NotEmpty then
AddOperator( opAND) ;
AddCondition( fld_ContactosID_EMPRESA, cEqual, dmUsuarios. IDEmpresaActual) ;
end ;
end ;
end .