unit uPresupuestosClienteController; interface uses SysUtils, uDADataTable, uEditorDBItem, uControllerBase, uIDataModulePresupuestosCliente, uClientesController, uDetallesPresupuestoClienteController, uBizPresupuestosCliente, uBizDireccionesContacto, uBizDetallesPresupuestoCliente; type IPresupuestosClienteController = interface(IObservador) ['{21ED0332-F0E0-468D-8D53-8CA362757191}'] function GetClienteController: IClientesController; procedure SetClienteController(const Value: IClientesController); property ClienteController: IClientesController read GetClienteController write SetClienteController; function GetDetallesController: IDetallesPresupuestoClienteController; procedure SetDetallesController(const Value: IDetallesPresupuestoClienteController); property DetallesController: IDetallesPresupuestoClienteController read GetDetallesController write SetDetallesController; procedure RecuperarCliente(APresupuesto : IBizPresupuestoCliente); function Buscar(const ID: Integer): IBizPresupuestoCliente; function BuscarTodos: IBizPresupuestoCliente; function BuscarPendientes : IBizPresupuestoCliente; procedure Ver(APresupuesto : IBizPresupuestoCliente); procedure VerTodos(APresupuestos: IBizPresupuestoCliente); procedure VerDireccionEntrega(APresupuesto : IBizPresupuestoCliente); function Nuevo : IBizPresupuestoCliente; function Anadir(APresupuesto : IBizPresupuestoCliente) : Boolean; function Eliminar(const ID : Integer): Boolean; overload; function Eliminar(APresupuesto : IBizPresupuestoCliente; AllItems: Boolean = false): Boolean; overload; function Guardar(APresupuesto : IBizPresupuestoCliente): Boolean; procedure DescartarCambios(APresupuesto : IBizPresupuestoCliente); function Existe(const ID: Integer) : Boolean; function Duplicar(APresupuesto: IBizPresupuestoCliente): IBizPresupuestoCliente; function Localizar(APresupuestos: IBizPresupuestoCliente; const ID : Integer): Boolean; function ExtraerSeleccionados(APresupuesto: IBizPresupuestoCliente) : IBizPresupuestoCliente; function ElegirPresupuestos(APresupuesto: IBizPresupuestoCliente; AMensaje: String; AMultiSelect: Boolean): IBizPresupuestoCliente; procedure CopiarDireccionEnvio (const ADireccionEnvio: IBizDireccionesContacto; APresupuesto: IBizPresupuestoCliente); procedure QuitarDireccionEnvio(APresupuesto: IBizPresupuestoCliente); procedure RecalcularImportes(APresupuesto : IBizPresupuestoCliente); function EsModificable(APresupuesto : IBizPresupuestoCliente): Boolean; function EsEliminable(APresupuesto : IBizPresupuestoCliente): Boolean; procedure Preview(APresupuesto : IBizPresupuestoCliente; AllItems: Boolean = false); procedure Print(APresupuesto : IBizPresupuestoCliente; AllItems: Boolean = false); end; TPresupuestosClienteController = class(TObservador, IPresupuestosClienteController) protected FDataModule : IDataModulePresupuestosCliente; FClienteController : IClientesController; FDetallesController : IDetallesPresupuestoClienteController; function GetClienteController: IClientesController; procedure SetClienteController(const Value: IClientesController); function GetDetallesController: IDetallesPresupuestoClienteController; procedure SetDetallesController(const Value: IDetallesPresupuestoClienteController); //Estos son los tres métodos a sobre escribir si se desea heredar toda la logica de //este controller procedure AsignarDataModule; virtual; procedure RecuperarObjetos(APresupuesto: IBizPresupuestoCliente); virtual; procedure RecibirAviso(ASujeto: ISujeto; ADataTable: IDAStronglyTypedDataTable); override; function CreateEditor(const AName : String; const IID: TGUID; out Intf): Boolean; procedure FiltrarEmpresa(APresupuesto: IBizPresupuestoCliente); function _Vacio : IBizPresupuestoCliente; function ValidarPresupuesto(APresupuesto: IBizPresupuestoCliente): Boolean; public property ClienteController: IClientesController read GetClienteController write SetClienteController; property DetallesController: IDetallesPresupuestoClienteController read GetDetallesController write SetDetallesController; constructor Create; override; destructor Destroy; override; function Localizar(APresupuestos: IBizPresupuestoCliente; const ID : Integer): Boolean; procedure RecuperarCliente(APresupuesto : IBizPresupuestoCliente); function Eliminar(const ID : Integer): Boolean; overload; function Eliminar(APresupuesto : IBizPresupuestoCliente; AllItems: Boolean = false): Boolean; overload; function Guardar(APresupuesto : IBizPresupuestoCliente): Boolean; procedure DescartarCambios(APresupuesto : IBizPresupuestoCliente); virtual; function Existe(const ID: Integer) : Boolean; virtual; function Anadir(APresupuesto : IBizPresupuestoCliente) : Boolean; function Buscar(const ID: Integer): IBizPresupuestoCliente; function BuscarTodos: IBizPresupuestoCliente; function BuscarPendientes : IBizPresupuestoCliente; function Nuevo : IBizPresupuestoCliente; procedure Ver(APresupuesto : IBizPresupuestoCliente); procedure VerTodos(APresupuestos: IBizPresupuestoCliente); procedure VerDireccionEntrega(APresupuesto : IBizPresupuestoCliente); function Duplicar(APresupuesto: IBizPresupuestoCliente): IBizPresupuestoCliente; procedure CopiarDireccionEnvio (const ADireccionEnvio: IBizDireccionesContacto; APresupuesto: IBizPresupuestoCliente); procedure QuitarDireccionEnvio(APresupuesto: IBizPresupuestoCliente); function ExtraerSeleccionados(APresupuesto: IBizPresupuestoCliente) : IBizPresupuestoCliente; function ElegirPresupuestos(APresupuesto: IBizPresupuestoCliente; AMensaje: String; AMultiSelect: Boolean): IBizPresupuestoCliente; procedure RecalcularImportes(APresupuesto : IBizPresupuestoCliente); function EsModificable(APresupuesto : IBizPresupuestoCliente): Boolean; function EsEliminable(APresupuesto : IBizPresupuestoCliente): Boolean; procedure Preview(APresupuesto : IBizPresupuestoCliente; AllItems: Boolean = false); procedure Print(APresupuesto : IBizPresupuestoCliente; AllItems: Boolean = false); end; implementation uses uROTypes, Controls, cxControls, DB, uEditorRegistryUtils, uEditorPreview, DateUtils, uIEditorPresupuestosCliente, uDataModulePresupuestosCliente, Variants, uBizContactos, uDataTableUtils, uDataModuleUsuarios, Classes, uFactuGES_App, schPresupuestosClienteClient_Intf, uDAInterfaces, uDateUtils, uIEditorPresupuestoCliente, uIEditorElegirPresupuestosCliente, uIEditorDireccionEntregaPresupuestoCliente, schContactosClient_Intf, uPresupuestosClienteReportController; { TPresupuestosClienteController } function TPresupuestosClienteController.Anadir(APresupuesto: IBizPresupuestoCliente): Boolean; begin if not Assigned(APresupuesto) then raise Exception.Create ('Presupuesto no asignado (Anadir)'); APresupuesto.Insert; Result := True; end; procedure TPresupuestosClienteController.AsignarDataModule; begin FDataModule := TDataModulePresupuestosCliente.Create(Nil); end; function TPresupuestosClienteController.Buscar(const ID: Integer): IBizPresupuestoCliente; begin Result := FDataModule.GetItem(ID); FiltrarEmpresa(Result); end; function TPresupuestosClienteController.BuscarTodos: IBizPresupuestoCliente; begin Result := FDataModule.GetItems; FiltrarEmpresa(Result); end; function TPresupuestosClienteController.BuscarPendientes: IBizPresupuestoCliente; var Condicion: TDAWhereExpression; begin ShowHourglassCursor; try Result := BuscarTodos; // Filtrar los presupuesto pendientes de recepcion with Result.DataTable.DynamicWhere do begin // (SITUACION <> RECIBIDO) Condicion := NewBinaryExpression(NewField('', fld_PresupuestosClienteSITUACION), NewConstant(SITUACION_PRESUPUESTO_PENDIENTE, datString), dboNotEqual); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Expression, Condicion, dboAnd); end; finally HideHourglassCursor; end; end; procedure TPresupuestosClienteController.CopiarDireccionEnvio( const ADireccionEnvio: IBizDireccionesContacto; APresupuesto: IBizPresupuestoCliente); var bEnEdicion : Boolean; begin { if not Assigned(APresupuesto) then raise Exception.Create ('Presupuesto no asignado (CopiarDireccionEnvio)'); if not Assigned(ADireccionEnvio) then raise Exception.Create ('No se ha indicado la dirección (CopiarDireccionEnvio)'); if APresupuesto.DataTable.Active then APresupuesto.DataTable.Active := True; if ADireccionEnvio.DataTable.Active then ADireccionEnvio.DataTable.Active := True; bEnEdicion := (APresupuesto.DataTable.State in dsEditModes); if not bEnEdicion then APresupuesto.Edit; ShowHourglassCursor; APresupuesto.Edit; try APresupuesto.CALLE := ADireccionEnvio.CALLE; APresupuesto.POBLACION := ADireccionEnvio.POBLACION; APresupuesto.CODIGO_POSTAL := ADireccionEnvio.CODIGO_POSTAL; APresupuesto.PROVINCIA := ADireccionEnvio.PROVINCIA; APresupuesto.TELEFONO := ADireccionEnvio.TELEFONO; APresupuesto.PERSONA_CONTACTO := ADireccionEnvio.PERSONA_CONTACTO; if not bEnEdicion then APresupuesto.Post; finally HideHourglassCursor; end; } end; constructor TPresupuestosClienteController.Create; begin inherited; AsignarDataModule; FClienteController := TClientesController.Create; FDetallesController := TDetallesPresupuestoClienteController.Create; FDetallesController.addObservador(Self); end; function TPresupuestosClienteController.CreateEditor(const AName: String; const IID: TGUID; out Intf): Boolean; begin Result := Supports(EditorRegistry.CreateEditor(AName), IID, Intf); end; procedure TPresupuestosClienteController.DescartarCambios(APresupuesto: IBizPresupuestoCliente); begin if not Assigned(APresupuesto) then raise Exception.Create ('Presupuesto no asignada'); ShowHourglassCursor; try if (APresupuesto.State in dsEditModes) then APresupuesto.Cancel; APresupuesto.DataTable.CancelUpdates; finally HideHourglassCursor; end; end; destructor TPresupuestosClienteController.Destroy; begin FDataModule := Nil; FClienteController := Nil; FDetallesController := Nil; inherited; end; function TPresupuestosClienteController.Duplicar( APresupuesto: IBizPresupuestoCliente): IBizPresupuestoCliente; begin Result := Self._Vacio; ShowHourglassCursor; try DuplicarRegistros(APresupuesto.DataTable, Result.DataTable, mdrActual); DuplicarRegistros(APresupuesto.Detalles.DataTable, Result.Detalles.DataTable, mdrTodos); // Hay que dejar algunos campos como si fuera un presupuesto nuevo Result.Edit; with Result do begin ID_EMPRESA := AppFactuGES.EmpresaActiva.ID; USUARIO := AppFactuGES.UsuarioActivo.UserName; FECHA_PRESUPUESTO := DateOf(Now); INCIDENCIAS_ACTIVAS := 0; DataTable.FieldByName('INCIDENCIAS').AsVariant := Null; REFERENCIA := ''; end; Result.Post; finally HideHourglassCursor; end; end; function TPresupuestosClienteController.ValidarPresupuesto( APresupuesto: IBizPresupuestoCliente): Boolean; begin Result := False; if not Assigned(APresupuesto) then raise Exception.Create ('Presupuesto no asignado'); if (APresupuesto.DataTable.State in dsEditModes) then APresupuesto.DataTable.Post; //Tambien hacemos post de sus tablas hija if (APresupuesto.Detalles.DataTable.State in dsEditModes) then APresupuesto.Detalles.DataTable.Post; // Abrir el cliente para la validación if Assigned(APresupuesto.Cliente) then APresupuesto.Cliente.DataTable.Active := True; if (APresupuesto.ID_Cliente < 0) or (not Assigned(APresupuesto.Cliente)) or (APresupuesto.Cliente.IsEmpty) then raise Exception.Create('Debe indicar el cliente de este presupuesto'); if (EsFechaVacia(APresupuesto.FECHA_PRESUPUESTO)) then raise Exception.Create('Debe indicar la fecha de este presupuesto'); if (APresupuesto.Detalles.DataTable.RecordCount = 0) then raise Exception.Create('El presupuesto debe tener en su contenido al menos un concepto'); { Asegurarse de valores en campos "automáticos" tanto en MODIFICACIÓN como en INSERCIÓN. } APresupuesto.Edit; try APresupuesto.USUARIO := AppFactuGES.UsuarioActivo.UserName; if Assigned(APresupuesto.Cliente) and (APresupuesto.ID_CLIENTE <> APresupuesto.Cliente.ID) then APresupuesto.ID_CLIENTE := APresupuesto.Cliente.ID; Result := True; finally APresupuesto.Post; end; end; procedure TPresupuestosClienteController.Ver(APresupuesto: IBizPresupuestoCliente); var AEditor : IEditorPresupuestoCliente; begin AEditor := NIL; ShowHourglassCursor; try RecuperarObjetos(APresupuesto); CreateEditor('EditorPresupuestoCliente', IEditorPresupuestoCliente, AEditor); if Assigned(AEditor) then with AEditor do begin Controller := Self; //OJO ORDEN MUY IMPORTANTE Presupuesto := APresupuesto; //MODO CONSULTAR if not EsModificable(APresupuesto) then begin SetDataTableReadOnly(APresupuesto.DataTable, True); ReadOnly := True; end; ShowModal; //MODO CONSULTAR (Se deja la tabla como estaba) if ReadOnly then SetDataTableReadOnly(APresupuesto.DataTable, False); AEditor.Release; end; finally AEditor := NIL; HideHourglassCursor; end; end; procedure TPresupuestosClienteController.VerDireccionEntrega( APresupuesto: IBizPresupuestoCliente); var AEditor : IEditorDireccionEntregaPresupuestoCliente; begin { AEditor := NIL; ShowHourglassCursor; try //RecuperarObjetos(APresupuesto); <- No descomentar. No hace falta CreateEditor('EditorDireccionEntregaPresupuestoCliente', IEditorDireccionEntregaPresupuestoCliente, AEditor); if Assigned(AEditor) then with (AEditor as IEditorDireccionEntregaPresupuestoCliente) do begin Presupuesto := APresupuesto; ShowModal; Release; end; finally AEditor := NIL; HideHourglassCursor; end; } end; procedure TPresupuestosClienteController.VerTodos(APresupuestos: IBizPresupuestoCliente); var AEditor : IEditorPresupuestosCliente; begin AEditor := NIL; ShowHourglassCursor; try CreateEditor('EditorPresupuestosCliente', IEditorPresupuestosCliente, AEditor); if Assigned(AEditor) then with AEditor do begin Controller := Self; //OJO ORDEN MUY IMPORTANTE Presupuestos := APresupuestos; MultiSelect := True; ShowEmbedded; end; finally AEditor := NIL; HideHourglassCursor; end; end; function TPresupuestosClienteController._Vacio: IBizPresupuestoCliente; begin Result := Buscar(ID_NULO); end; function TPresupuestosClienteController.Eliminar(const ID: Integer): Boolean; var APresupuesto : IBizPresupuestoCliente; begin APresupuesto := Buscar(ID); if not Assigned(APresupuesto) then raise Exception.Create(Format('No se ha encontrado el presupuesto con ID = %d', [ID])); Result := Eliminar(APresupuesto); APresupuesto := NIL; end; function TPresupuestosClienteController.ElegirPresupuestos(APresupuesto: IBizPresupuestoCliente; AMensaje: String; AMultiSelect: Boolean): IBizPresupuestoCliente; var AEditor : IEditorElegirPresupuestosCliente; begin Result := NIL; ShowHourglassCursor; try CreateEditor('EditorElegirPresupuestosCliente', IEditorElegirPresupuestosCliente, AEditor); if Assigned(AEditor) then with AEditor do begin Controller := Self; Presupuestos := APresupuesto; MultiSelect := AMultiSelect; Mensaje := AMensaje; if IsPositiveResult(ShowModal) then Result := PresupuestosClienteSeleccionados; Release; end; finally AEditor := NIL; HideHourglassCursor; end; end; function TPresupuestosClienteController.Eliminar(APresupuesto: IBizPresupuestoCliente; AllItems: Boolean = false): Boolean; //En el caso de eliminar almenos un elemento del conjunto se devuelve true var bEliminado: Boolean; begin bEliminado := False; if not Assigned(APresupuesto) then raise Exception.Create ('APresupuesto no asignado'); ShowHourglassCursor; try if not APresupuesto.DataTable.Active then APresupuesto.DataTable.Active := True; if (APresupuesto.State in dsEditModes) then APresupuesto.Cancel; //Siempre eliminaremos el seleccionado if EsEliminable(APresupuesto) then begin APresupuesto.Delete; bEliminado := True; end; //En el caso de querer eliminar todos los items del objeto APresupuesto if AllItems then begin with APresupuesto.DataTable do begin First; while not EOF do begin if EsEliminable(APresupuesto) then begin APresupuesto.Delete; bEliminado := True end else Next; end; end; end; if bEliminado then begin APresupuesto.DataTable.ApplyUpdates; Result := True; end else Result := False; finally HideHourglassCursor; end; end; function TPresupuestosClienteController.EsEliminable(APresupuesto: IBizPresupuestoCliente): Boolean; begin if not Assigned(APresupuesto) then raise Exception.Create ('Presupuesto no asignado: EsEliminable'); Result := (APresupuesto.SITUACION = SITUACION_PRESUPUESTO_PENDIENTE); end; function TPresupuestosClienteController.EsModificable(APresupuesto: IBizPresupuestoCliente): Boolean; begin if not Assigned(APresupuesto) then raise Exception.Create ('Presupuesto no asignado: EsModificable'); Result := (APresupuesto.SITUACION = SITUACION_PRESUPUESTO_PENDIENTE); end; procedure TPresupuestosClienteController.RecalcularImportes( APresupuesto: IBizPresupuestoCliente); var bEnEdicion : Boolean; ADetallePosAct : Integer; begin if not Assigned(APresupuesto) then raise Exception.Create ('Presupuesto no asignado (RecalcularImportes)'); if APresupuesto.DataTable.Active then APresupuesto.DataTable.Active := True; { Hay que guardar la posición en la que estamos en los detalles por que la asignación de valores a los campos IMPORTE_NETO e IMPORTE_PORTE (ver más adelante) colocan el puntero en la tabla detalle al principio. No he encontrado la razón por la que mueve el puntero. } ADetallePosAct := APresupuesto.Detalles.POSICION; bEnEdicion := (APresupuesto.DataTable.State in dsEditModes); if not bEnEdicion then APresupuesto.Edit; ShowHourglassCursor; try APresupuesto.IMPORTE_NETO := FDetallesController.DarTotalImporteTotal(APresupuesto.Detalles); APresupuesto.IMPORTE_PORTE := FDetallesController.DarTotalPorteTotal(APresupuesto.Detalles); if not bEnEdicion then APresupuesto.Post; finally HideHourglassCursor; // Restaurar la posición que teníamos en los detalles. FDetallesController.LocalizarPosicion(APresupuesto.Detalles, ADetallePosAct); end; end; procedure TPresupuestosClienteController.RecibirAviso(ASujeto: ISujeto; ADataTable: IDAStronglyTypedDataTable); var APresupuesto : IBizPresupuestoCliente; ADetalles : IBizDetallesPresupuestoCliente; begin inherited; if Supports(ADataTable, IBizDetallesPresupuestoCliente, ADetalles) and Supports(ADetalles.DataTable.MasterSource.DataTable, IBizPresupuestoCliente, APresupuesto) then begin RecalcularImportes(APresupuesto); end; end; procedure TPresupuestosClienteController.RecuperarObjetos(APresupuesto: IBizPresupuestoCliente); begin RecuperarCliente(APresupuesto); end; procedure TPresupuestosClienteController.RecuperarCliente( APresupuesto: IBizPresupuestoCliente); begin APresupuesto._Cliente := (FClienteController.Buscar(APresupuesto.ID_Cliente) as IBizCliente); end; function TPresupuestosClienteController.Existe(const ID: Integer): Boolean; var APresupuesto : IBizPresupuestoCliente; begin try APresupuesto := Buscar(ID); Result := Assigned(APresupuesto) and (APresupuesto.ID = ID); finally APresupuesto := NIL; end; end; function TPresupuestosClienteController.ExtraerSeleccionados(APresupuesto: IBizPresupuestoCliente): IBizPresupuestoCliente; var ASeleccionados : IBizPresupuestoCliente; begin ASeleccionados := (Self.Buscar(ID_NULO) as IBizPresupuestoCliente); CopyDataTableDA3(APresupuesto.DataTable, ASeleccionados.DataTable, True); Result := ASeleccionados; end; procedure TPresupuestosClienteController.FiltrarEmpresa(APresupuesto: IBizPresupuestoCliente); var Condicion: TDAWhereExpression; begin if APresupuesto.DataTable.Active then APresupuesto.DataTable.Active := False; // Filtrar los presupuestos actuales por empresa with APresupuesto.DataTable.DynamicWhere do begin // (ID_EMPRESA >= ID) Condicion := NewBinaryExpression(NewField('', fld_PresupuestosClienteID_EMPRESA), NewConstant(AppFactuGES.EmpresaActiva.ID, datInteger), dboEqual); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Expression, Condicion, dboAnd); end; end; procedure TPresupuestosClienteController.SetClienteController(const Value: IClientesController); begin FClienteController := Value; end; procedure TPresupuestosClienteController.SetDetallesController(const Value: IDetallesPresupuestoClienteController); begin FDetallesController := Value; end; function TPresupuestosClienteController.Guardar(APresupuesto: IBizPresupuestoCliente): Boolean; var IDNuevo: Integer; begin Result := False; if not Assigned(APresupuesto) then raise Exception.Create ('Presupuesto no asignada'); if not Assigned(FDetallesController) then raise Exception.Create ('Controller detalles no asignado'); if ValidarPresupuesto(APresupuesto) then begin ShowHourglassCursor; // Asegurarnos de que todos los importes están bien. RecalcularImportes(APresupuesto); try APresupuesto.DataTable.ApplyUpdates; Result := True; finally HideHourglassCursor; end; end; end; function TPresupuestosClienteController.Localizar(APresupuestos: IBizPresupuestoCliente; const ID: Integer): Boolean; begin Result := True; ShowHourglassCursor; try with APresupuestos.DataTable do begin DisableControls; First; if not Locate(fld_PresupuestosClienteID, ID, []) then Result := False; EnableControls; end; finally HideHourglassCursor; end; end; function TPresupuestosClienteController.Nuevo: IBizPresupuestoCliente; var APresupuesto : IBizPresupuestoCliente; begin APresupuesto := FDataModule.NewItem; FiltrarEmpresa(APresupuesto); APresupuesto.DataTable.Active := True; APresupuesto.Insert; Result := APresupuesto; end; procedure TPresupuestosClienteController.QuitarDireccionEnvio( APresupuesto: IBizPresupuestoCliente); var bEnEdicion : Boolean; begin { if not Assigned(APresupuesto) then raise Exception.Create ('Presupuesto no asignado (QuitarDireccionEnvio)'); if APresupuesto.DataTable.Active then APresupuesto.DataTable.Active := True; bEnEdicion := (APresupuesto.DataTable.State in dsEditModes); if not bEnEdicion then APresupuesto.Edit; ShowHourglassCursor; APresupuesto.Edit; try APresupuesto.DataTable.FieldByName(fld_PresupuestosClienteCALLE).Clear; APresupuesto.DataTable.FieldByName(fld_PresupuestosClientePOBLACION).Clear; APresupuesto.DataTable.FieldByName(fld_PresupuestosClienteCODIGO_POSTAL).Clear; APresupuesto.DataTable.FieldByName(fld_PresupuestosClientePROVINCIA).Clear; APresupuesto.DataTable.FieldByName(fld_PresupuestosClienteTELEFONO).Clear; APresupuesto.DataTable.FieldByName(fld_PresupuestosClientePERSONA_CONTACTO).Clear; if not bEnEdicion then APresupuesto.Post; finally HideHourglassCursor; end; } end; procedure TPresupuestosClienteController.Preview(APresupuesto: IBizPresupuestoCliente; AllItems: Boolean = false); var AReportController : IPresupuestosClienteReportController; ID_Presupuestos: TStringList; begin AReportController := TPresupuestosClienteReportController.Create; try ID_Presupuestos := TStringList.Create; //Si deseamos previsualizar todos los items del objeto presupuesto if AllItems then begin with APresupuesto.DataTable do begin First; while not EOF do begin ID_Presupuestos.Add(IntToStr(APresupuesto.ID)); Next; end; end; end //Solo previsualizamos el item seleccionado else ID_Presupuestos.Add(IntToStr(APresupuesto.ID)); AReportController.Preview(ID_Presupuestos.CommaText); finally AReportController := NIL; FreeAndNil(ID_Presupuestos); end; end; procedure TPresupuestosClienteController.Print(APresupuesto: IBizPresupuestoCliente; AllItems: Boolean = false); var AReportController : IPresupuestosClienteReportController; ID_Presupuestos: TStringList; begin AReportController := TPresupuestosClienteReportController.Create; try ID_Presupuestos := TStringList.Create; //Si deseamos imprimimos todos los items del objeto presupuesto if AllItems then begin with APresupuesto.DataTable do begin First; while not EOF do begin ID_Presupuestos.Add(IntToStr(APresupuesto.ID)); Next; end; end; end //Solo imprimimos el item seleccionado else ID_Presupuestos.Add(IntToStr(APresupuesto.ID)); AReportController.Print(ID_Presupuestos.CommaText); finally AReportController := NIL; ID_Presupuestos.Free; end; end; function TPresupuestosClienteController.GetClienteController: IClientesController; begin Result := FClienteController; end; function TPresupuestosClienteController.GetDetallesController: IDetallesPresupuestoClienteController; begin Result := FDetallesController; end; end.