unit uPresupuestosClienteController; interface uses Classes, uROTypes, SysUtils, uDADataTable, uEditorDBItem, uControllerBase, uIDataModulePresupuestosCliente, uClientesController, uDetallesPresupuestoClienteController, uGestorDocumentosController, uBizPresupuestosCliente, uBizDireccionesContacto, uBizDetallesPresupuestoCliente, uIntegerListUtils; type IPresupuestosClienteController = interface(IControllerBase) ['{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; //GESTION_DOCUMENTOS function GetGestorDocumentosController: IGestorDocumentosController; procedure SetGestorDocumentosController(const Value: IGestorDocumentosController); property GestorDocumentosController: IGestorDocumentosController read GetGestorDocumentosController write SetGestorDocumentosController; procedure RecuperarCliente(APresupuesto : IBizPresupuestoCliente); function Buscar(const ID: Integer): IBizPresupuestoCliente; overload; function Buscar(const ListaID: TIntegerList): IBizPresupuestoCliente; overload; function BuscarTodos: IBizPresupuestoCliente; overload; function BuscarTodos(const ID_Cliente: Integer): IBizPresupuestoCliente; overload; function BuscarAceptados : IBizPresupuestoCliente; function BuscarSinFacturar : IBizPresupuestoCliente; procedure Ver(APresupuesto : IBizPresupuestoCliente); procedure VerTodos(APresupuestos: IBizPresupuestoCliente; const AVerModal : Boolean = False; const AWindowCaption: String = ''; const AHeaderText: String = ''); 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 QuitarDireccionEnvio(APresupuesto: IBizPresupuestoCliente); procedure RecalcularImportes(APresupuesto : IBizPresupuestoCliente); function EsModificable(APresupuesto : IBizPresupuestoCliente): Boolean; function EsEliminable(APresupuesto : IBizPresupuestoCliente): Boolean; procedure Preview(APresupuesto : IBizPresupuestoCliente; AllItems: Boolean = false; Const AVerSello: Integer = 1); procedure Print(APresupuesto : IBizPresupuestoCliente; AllItems: Boolean = false; Const AVerSello: Integer = 1); function GenerarCertificados(APresupuesto : IBizPresupuestoCliente; AllItems: Boolean = false): Boolean; function CambiarSituacion(APresupuesto : IBizPresupuestoCliente; Situacion: String; FechaDecision: TDateTime; AllItems: Boolean = false): Boolean; function EnviarPresupuestoPorEMail(APresupuesto : IBizPresupuestoCliente; const AEnviarDirectamente: Boolean = True; const ADireccionEMail: String = ''; const AAsuntoEMail: String = ''; const ATextoEMail: String = ''): Boolean; function EnviarEmailPresupuestos(APresupuestos : IBizPresupuestoCliente): Boolean; function GenerarEmailPresupuesto(APresupuesto : IBizPresupuestoCliente): Boolean; procedure BorrarBonificacion(APresupuesto : IBizPresupuestoCliente); function DarListaAnosPresupuestos: TStringList; procedure FiltrarAno(APresupuesto: IBizPresupuestoCliente; ADynWhereDataTable: WideString; const Ano: String); end; TPresupuestosClienteController = class(TControllerBase, IPresupuestosClienteController) protected FDataModule : IDataModulePresupuestosCliente; FClienteController : IClientesController; FDetallesController : IDetallesPresupuestoClienteController; FGestorDocumentosController : IGestorDocumentosController; function GetClienteController: IClientesController; procedure SetClienteController(const Value: IClientesController); function GetDetallesController: IDetallesPresupuestoClienteController; procedure SetDetallesController(const Value: IDetallesPresupuestoClienteController); //GESTION_DOCUMENTOS function GetGestorDocumentosController: IGestorDocumentosController; procedure SetGestorDocumentosController(const Value: IGestorDocumentosController); //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; property GestorDocumentosController: IGestorDocumentosController read GetGestorDocumentosController write SetGestorDocumentosController; 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 ListaID: TIntegerList): IBizPresupuestoCliente; overload; function Buscar(const ID: Integer): IBizPresupuestoCliente; overload; function BuscarTodos: IBizPresupuestoCliente; overload; function BuscarTodos(const ID_Cliente: Integer): IBizPresupuestoCliente; overload; function BuscarAceptados : IBizPresupuestoCliente; function BuscarSinFacturar : IBizPresupuestoCliente; function Nuevo : IBizPresupuestoCliente; procedure Ver(APresupuesto : IBizPresupuestoCliente); procedure VerTodos(APresupuestos: IBizPresupuestoCliente; const AVerModal : Boolean = False; const AWindowCaption: String = ''; const AHeaderText: String = ''); procedure VerDireccionEntrega(APresupuesto : IBizPresupuestoCliente); function Duplicar(APresupuesto: IBizPresupuestoCliente): 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; Const AVerSello: Integer = 1); procedure Print(APresupuesto : IBizPresupuestoCliente; AllItems: Boolean = false; Const AVerSello: Integer = 1); function GenerarCertificados(APresupuesto : IBizPresupuestoCliente; AllItems: Boolean = false): Boolean; function CambiarSituacion(APresupuesto : IBizPresupuestoCliente; Situacion: String; FechaDecision: TDateTime; AllItems: Boolean = false): Boolean; function EnviarPresupuestoPorEMail(APresupuesto : IBizPresupuestoCliente; const AEnviarDirectamente: Boolean = True; const ADireccionEMail: String = ''; const AAsuntoEMail: String = ''; const ATextoEMail: String = ''): Boolean; function EnviarEmailPresupuestos(APresupuestos : IBizPresupuestoCliente): Boolean; function GenerarEmailPresupuesto(APresupuesto : IBizPresupuestoCliente): Boolean; procedure BorrarBonificacion(APresupuesto : IBizPresupuestoCliente); function DarListaAnosPresupuestos: TStringList; procedure FiltrarAno(APresupuesto: IBizPresupuestoCliente; ADynWhereDataTable: WideString; const Ano: String); end; implementation uses Controls, cxControls, DB, uEditorRegistryUtils, uEditorPreview, DateUtils, uIEditorPresupuestosCliente, uDataModulePresupuestosCliente, Variants, uBizContactos, uDataTableUtils, uDataModuleUsuarios, uFactuGES_App, schPresupuestosClienteClient_Intf, uDAInterfaces, uDateUtils, uIEditorPresupuestoCliente, uIEditorElegirPresupuestosCliente, uIEditorDireccionEntregaPresupuestoCliente, schContactosClient_Intf, uPresupuestosClienteReportController, uSistemaFunc, uEMailUtils, uDialogElegirEMail, Dialogs, uStringsUtils, uIDialogListaPresupuestosEnvioEMail; { 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.SincronizarDocumentos(const ID: Integer; FListaDocumentos: TStringList; Directorio: String); var ListaDocumentosServidor: TStringList; ANombreFichero: String; AFichero: Binary; i, j: Integer; begin //Eliminamos todos los documentos del servidor que ya no existan en el cliente. ListaDocumentosServidor := DarListaDocumentos(ID); for i:= 0 to ListaDocumentosServidor.Count - 1 do if not FListaDocumentos.Find(ListaDocumentosServidor.Strings[i], j) then if not FDataModule.EliminarFichero(ID, ListaDocumentosServidor.Strings[i]) then showmessage('Error al borrar fichero' + ListaDocumentosServidor.Strings[i]); //Subimos todos los ficheros que halla al servidor (de momento no se miran fechas) for i := 0 to FListaDocumentos.Count - 1 do begin ANombreFichero := Directorio + FListaDocumentos.Strings[i]; if FileExists(ANombreFichero) then begin AFichero := Binary.Create; AFichero.LoadFromFile(ANombreFichero); SubirFichero(ID, ExtractFileName(ANombreFichero), AFichero); end; end; end; } procedure TPresupuestosClienteController.AsignarDataModule; begin FDataModule := TDataModulePresupuestosCliente.Create(Nil); end; procedure TPresupuestosClienteController.BorrarBonificacion(APresupuesto: IBizPresupuestoCliente); var EnEdicion: Boolean; begin if Assigned(APresupuesto) then begin EnEdicion := APresupuesto.DataTable.Editing; if not EnEdicion then APresupuesto.DataTable.Edit; APresupuesto.DESCRIPCION_BONIFICACIONIsNull := True; APresupuesto.IMPORTE_BONIFICACIONIsNull := True; APresupuesto.DataTable.Post; if EnEdicion then APresupuesto.DataTable.Edit; end; 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.Buscar( const ListaID: TIntegerList): IBizPresupuestoCliente; begin Result := FDataModule.GetItems(ListaID); FiltrarEmpresa(Result); end; function TPresupuestosClienteController.BuscarAceptados: 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_ACEPTADO, datString), dboEqual); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Expression, Condicion, dboAnd); end; finally HideHourglassCursor; end; end; function TPresupuestosClienteController.BuscarSinFacturar: IBizPresupuestoCliente; var Condicion: TDAWhereExpression; begin ShowHourglassCursor; try Result := BuscarAceptados; with Result.DataTable.DynamicWhere do begin // (ID_FACTURA = NULL) Condicion := NewBinaryExpression(NewField('', fld_PresupuestosClienteID_FACTURA), NewNull(), dboEqual); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Expression, Condicion, dboAnd); end; finally HideHourglassCursor; end; end; function TPresupuestosClienteController.BuscarTodos( const ID_Cliente: Integer): IBizPresupuestoCliente; var Condicion: TDAWhereExpression; begin ShowHourglassCursor; try Result := BuscarTodos; with Result.DataTable.DynamicWhere do begin // ID_CLIENTE Condicion := NewBinaryExpression(NewField('', fld_PresupuestosClienteID_CLIENTE), NewConstant(ID_Cliente, datInteger), dboEqual); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Expression, Condicion, dboAnd); end; finally HideHourglassCursor; end; end; function TPresupuestosClienteController.CambiarSituacion(APresupuesto: IBizPresupuestoCliente; Situacion: String; FechaDecision: TDateTime; AllItems: Boolean): Boolean; // En el caso de cambiar almenos un elemento del conjunto se devuelve true begin 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 cambiaremos de situacion el seleccionado if APresupuesto.SITUACION <> Situacion then begin APresupuesto.DataTable.Edit; APresupuesto.SITUACION := Situacion; APresupuesto.FECHA_DECISION := FechaDecision; APresupuesto.DataTable.Post; 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 APresupuesto.SITUACION <> Situacion then begin APresupuesto.DataTable.Edit; APresupuesto.SITUACION := Situacion; APresupuesto.FECHA_DECISION := FechaDecision; APresupuesto.DataTable.Post; end; Next; end; end; end; APresupuesto.DataTable.ApplyUpdates; Result := True; finally HideHourglassCursor; end; end; constructor TPresupuestosClienteController.Create; begin inherited; AsignarDataModule; FClienteController := TClientesController.Create; FDetallesController := TDetallesPresupuestoClienteController.Create; //GESTION_DOCUMENTOS FGestorDocumentosController := TGestorDocumentosController.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; { function TPresupuestosClienteController.DarListaDocumentos(const ID: Integer): TStringList; begin Result := FDataModule.DarListaDocumentos(ID); end; function TPresupuestosClienteController.DescargarFichero(const ID: Integer; const NombreFichero: String; const DestinoFichero: String): Boolean; begin Result := FDataModule.DescargarFichero(ID, NombreFichero, DestinoFichero); end; } function TPresupuestosClienteController.DarListaAnosPresupuestos: TStringList; begin Result := FDataModule.GetAnosItems; 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; //GESTION_DOCUMENTOS FGestorDocumentosController := 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; INCIDENCIASIsNull := True; ID_FACTURAIsNull := True; FECHA_DECISIONIsNull := True; REFERENCIA := ''; SITUACION := SITUACION_PRESUPUESTO_PENDIENTE; end; Result.Post; finally HideHourglassCursor; end; end; function TPresupuestosClienteController.ValidarPresupuesto( APresupuesto: IBizPresupuestoCliente): Boolean; begin 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) then // Si hay altas automáticas no hay objeto Cliente pero sí hay ID_CLIENTE { (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'); FDetallesController.ValidarDetalles(APresupuesto.Detalles); { 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; RecuperarObjetos(APresupuesto); CreateEditor('EditorPresupuestoCliente', IEditorPresupuestoCliente, AEditor); if Assigned(AEditor) then try AEditor.Controller := Self; //OJO ORDEN MUY IMPORTANTE AEditor.Presupuesto := APresupuesto; //MODO CONSULTAR if not EsModificable(APresupuesto) then begin SetDataTableReadOnly(APresupuesto.DataTable, True); AEditor.ReadOnly := True; end; AEditor.ShowModal; //MODO CONSULTAR (Se deja la tabla como estaba) if AEditor.ReadOnly then SetDataTableReadOnly(APresupuesto.DataTable, False); finally AEditor.Release; AEditor := NIL; end; end; procedure TPresupuestosClienteController.VerDireccionEntrega( APresupuesto: IBizPresupuestoCliente); {var AEditor : IEditorDireccionEntregaPresupuestoCliente;} begin { AEditor := NIL; //RecuperarObjetos(APresupuesto); <- No descomentar. No hace falta CreateEditor('EditorDireccionEntregaPresupuestoCliente', IEditorDireccionEntregaPresupuestoCliente, AEditor); if Assigned(AEditor) then with (AEditor as IEditorDireccionEntregaPresupuestoCliente) do begin try Presupuesto := APresupuesto; ShowModal; finally AEditor.Release; AEditor := NIL; end; end; } end; procedure TPresupuestosClienteController.VerTodos(APresupuestos: IBizPresupuestoCliente; const AVerModal : Boolean = False; const AWindowCaption: String = ''; const AHeaderText: String = ''); var AEditor : IEditorPresupuestosCliente; begin AEditor := NIL; CreateEditor('EditorPresupuestosCliente', IEditorPresupuestosCliente, AEditor); if Assigned(AEditor) then try if not EsCadenaVacia(AWindowCaption) then AEditor.WindowCaption := AWindowCaption; if not EsCadenaVacia(AHeaderText) then AEditor.HeaderText := AHeaderText; AEditor.Controller := Self; //OJO ORDEN MUY IMPORTANTE AEditor.Presupuestos := APresupuestos; AEditor.MultiSelect := True; if AVerModal then AEditor.ShowModal else AEditor.ShowEmbedded; finally if AVerModal then AEditor.Release; AEditor := NIL; 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; CreateEditor('EditorElegirPresupuestosCliente', IEditorElegirPresupuestosCliente, AEditor); if Assigned(AEditor) then try AEditor.Controller := Self; AEditor.Presupuestos := APresupuesto; AEditor.MultiSelect := AMultiSelect; AEditor.Mensaje := AMensaje; if IsPositiveResult(AEditor.ShowModal) then Result := AEditor.PresupuestosClienteSeleccionados; finally AEditor.Release; AEditor := NIL; 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 //GESTION_DOCUMENTOS FGestorDocumentosController.EliminarDirectorio(APresupuesto.ID); 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 //GESTION_DOCUMENTOS FGestorDocumentosController.EliminarDirectorio(APresupuesto.ID); 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.EnviarEmailPresupuestos(APresupuestos: IBizPresupuestoCliente): Boolean; var ADialog : IDialogListaPresupuestosEnvioEMail; ARespuesta : Integer; begin ADialog := NIL; if not Assigned(APresupuestos) then raise Exception.Create ('Presupuestos no asignadas (EnviarPresupuestosPorEMail)'); if APresupuestos.DataTable.Active then APresupuestos.DataTable.Active := True; ShowHourglassCursor; try CreateEditor('DialogListaPresupuestosEnvioEMail', IDialogListaPresupuestosEnvioEMail, ADialog); if Assigned(ADialog) then begin try ADialog.Presupuestos := APresupuestos; ARespuesta := ADialog.ShowModal; Result := (ARespuesta = mrOK) finally ADialog.Release; end; end; finally ADialog := NIL; HideHourglassCursor; end; end; function TPresupuestosClienteController.EnviarPresupuestoPorEMail(APresupuesto: IBizPresupuestoCliente; const AEnviarDirectamente: Boolean = True; const ADireccionEMail: String = ''; const AAsuntoEMail: String = ''; const ATextoEMail: String = ''): Boolean; var AReportController : IPresupuestosClienteReportController; AFicheroTMP : TFileName; AEMail : String; AListaEmail : TStringList; begin if not Assigned(APresupuesto) then raise Exception.Create ('Presupuesto no asignado (EnviarPresupuestoPorEMail)'); if APresupuesto.DataTable.Active then APresupuesto.DataTable.Active := True; RecuperarCliente(APresupuesto); APresupuesto.Cliente.DataTable.Active := True; AFicheroTMP := DarFicheroPDFTemporal(EscapeIllegalChars(APresupuesto.REFERENCIA)); if not EsCadenaVacia(ADireccionEMail) then AEMail := ADireccionEMail else begin AListaEmail := TStringList.Create; try if not APresupuesto.Cliente.EMAIL_1IsNull then AListaEmail.Add(APresupuesto.Cliente.EMAIL_1); if not APresupuesto.Cliente.EMAIL_2IsNull then AListaEmail.Add(APresupuesto.Cliente.EMAIL_2); if not ElegirEMail(AListaEmail, AEMail) then Exit; finally FreeANDNIL(AListaEmail); end; end; ShowHourglassCursor; AReportController := TPresupuestosClienteReportController.Create; try AReportController.ExportToPDF(APresupuesto.ID, AFicheroTMP); Result := EnviarEMailMAPI('Presupuesto ' + APresupuesto.REFERENCIA, '', AFicheroTMP, '', '', APresupuesto.Cliente.NOMBRE, AEMail, AEnviarDirectamente); finally DeleteFile(AFicheroTMP); AReportController := NIL; 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); Result := True; 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); CopyDataTableDA5(APresupuesto.DataTable, ASeleccionados.DataTable, True); Result := ASeleccionados; end; procedure TPresupuestosClienteController.FiltrarAno(APresupuesto: IBizPresupuestoCliente; ADynWhereDataTable: WideString;const Ano: String); var Condicion: TDAWhereExpression; FechaIni: String; FechaFin: String; begin APresupuesto.DataTable.DynamicWhere.Clear; APresupuesto.DataTable.DynamicWhere.Xml := ADynWhereDataTable; if (Ano <> 'Todos') then begin // Filtrar las facturas actuales por empresa FechaIni := '01/01/' + Ano; FechaFin := '31/12/' + Ano; with APresupuesto.DataTable.DynamicWhere do begin // (FECHA_INICIO between FECHA_FIN) Condicion := NewBinaryExpression(NewField('', fld_PresupuestosClienteFECHA_PRESUPUESTO), NewConstant(FechaIni, datString), dboGreaterOrEqual); Condicion := NewBinaryExpression(NewBinaryExpression(NewField('', fld_PresupuestosClienteFECHA_PRESUPUESTO), NewConstant(FechaFin, datString), dboLessOrEqual), Condicion, dboAnd); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Condicion, Expression, dboAnd); end; end; 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; procedure TPresupuestosClienteController.SetGestorDocumentosController( const Value: IGestorDocumentosController); begin FGestorDocumentosController := Value; end; { function TPresupuestosClienteController.SubirFichero(const ID: Integer; const NombreFichero: String; const Fichero: Binary): Boolean; begin Result := FDataModule.SubirFichero(ID, NombreFichero, Fichero); end; } function TPresupuestosClienteController.Guardar(APresupuesto: IBizPresupuestoCliente): Boolean; 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; Const AVerSello: Integer = 1); var AReportController : IPresupuestosClienteReportController; ID_Presupuestos: TIntegerList; begin AReportController := TPresupuestosClienteReportController.Create; try ID_Presupuestos := TIntegerList.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(APresupuesto.ID); Next; end; end; end //Solo previsualizamos el item seleccionado else ID_Presupuestos.Add(APresupuesto.ID); AReportController.Preview(ID_Presupuestos, AVerSello); finally AReportController := NIL; FreeAndNil(ID_Presupuestos); end; end; procedure TPresupuestosClienteController.Print(APresupuesto: IBizPresupuestoCliente; AllItems: Boolean = false; Const AVerSello: Integer= 1); var AReportController : IPresupuestosClienteReportController; ID_Presupuestos: TIntegerList; begin AReportController := TPresupuestosClienteReportController.Create; ID_Presupuestos := TIntegerList.Create; try //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(APresupuesto.ID); Next; end; end; end //Solo imprimimos el item seleccionado else ID_Presupuestos.Add(APresupuesto.ID); AReportController.Print(ID_Presupuestos, AVerSello); finally AReportController := NIL; FreeANDNIL(ID_Presupuestos); end; end; function TPresupuestosClienteController.GenerarCertificados( APresupuesto: IBizPresupuestoCliente; AllItems: Boolean): Boolean; var AReportController : IPresupuestosClienteReportController; ID_Presupuestos: TStringList; ATitulo : String; AComentario : String; ARuta : String; function _GenerarCertificado: Boolean; var AFile: string; begin AFile := ARuta + PathDelim + EscapeIllegalChars(APresupuesto.REFERENCIA + '.doc'); Result := AReportController.GenerarCertificados(APresupuesto.ID, AFile); end; begin Result := False; AReportController := TPresupuestosClienteReportController.Create; ID_Presupuestos := TStringList.Create; try //Si deseamos imprimimos todos los items del objeto presupuesto if AllItems then begin ATitulo := 'Generar certificados de trabajos en PDF'; AComentario := 'Indique la carpeta donde se guardarán los certificados' + #13#10 + 'Se generarán como ficheros PDF.'; end else begin ATitulo := 'Generar certificado de trabajo en PDF'; AComentario := 'Indique la carpeta donde se guardará el certificado.' + #13#10 + 'Se generará como fichero PDF.'; end; if PreguntarRuta(ATitulo, AComentario, ARuta) then begin if AllItems then begin APresupuesto.DataTable.First; while not APresupuesto.DataTable.EOF do begin if (APresupuesto.SITUACION = SITUACION_PRESUPUESTO_ACEPTADO) then _GenerarCertificado; APresupuesto.DataTable.Next; end; end else begin if (APresupuesto.SITUACION = SITUACION_PRESUPUESTO_ACEPTADO) then _GenerarCertificado; end; Result := True; end; finally AReportController := NIL; FreeANDNIL(ID_Presupuestos); end; end; function TPresupuestosClienteController.GenerarEmailPresupuesto(APresupuesto: IBizPresupuestoCliente): Boolean; begin if not Assigned(APresupuesto) then raise Exception.Create ('Presupuesto no asignadas (GenerarEmailPresupuesto)'); if APresupuesto.DataTable.Active then APresupuesto.DataTable.Active := True; ShowHourglassCursor; try RecuperarCliente(APresupuesto); EnviarPresupuestoPorEMail(APresupuesto, False); finally HideHourglassCursor; end; end; function TPresupuestosClienteController.GetClienteController: IClientesController; begin Result := FClienteController; end; function TPresupuestosClienteController.GetDetallesController: IDetallesPresupuestoClienteController; begin Result := FDetallesController; end; function TPresupuestosClienteController.GetGestorDocumentosController: IGestorDocumentosController; begin Result := FGestorDocumentosController; end; end.