unit uEditorPresupuestoCliente; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, uEditorDBItem, DB, uDADataTable, JvAppStorage, JvAppRegistryStorage, JvComponent, JvFormPlacement, ImgList, PngImageList, StdActns, ActnList, ComCtrls, TBX, TB2Item, TB2Dock, TB2Toolbar, ExtCtrls, JvExControls, JvNavigationPane, uCustomView, uViewBase, JvComponentBase, StdCtrls, pngimage, AppEvnts, cxControls, cxContainer, cxEdit, cxTextEdit, cxMemo, cxDBEdit, uViewIncidencias, uPresupuestosClienteController, uViewDetallesBase, dxLayoutLookAndFeels, JvExComCtrls, JvStatusBar, uViewTotales, uIEditorPresupuestoCliente, uBizPresupuestosCliente, uViewPresupuestoCliente, uViewDetallesDTO, uViewDetallesArticulos, uViewDetallesPresupuestoCliente, uDAInterfaces, cxRichEdit, cxDBRichEdit, JvGIF, cxPC, uViewDocumentos, uViewDocumentosPresupuestoCliente, uViewDatosYSeleccionClientePresupuesto, cxLabel, uBizTiposIVA, uTiposIVAController, uViewTotalesPresupuesto, DBCtrls, cxGraphics, cxMaskEdit, cxDropDownEdit, cxCurrencyEdit; type TfEditorPresupuestoCliente = class(TfEditorDBItem, IEditorPresupuestoCliente) pagContenido: TTabSheet; pagInicidencias: TTabSheet; frViewIncidenciasCli: TfrViewIncidencias; dxLayoutLookAndFeelList1: TdxLayoutLookAndFeelList; dxLayoutOfficeLookAndFeel1: TdxLayoutOfficeLookAndFeel; TBXSubmenuItem2: TTBXSubmenuItem; TBXSeparatorItem6: TTBXSeparatorItem; TBXItem33: TTBXItem; actEnviarPorEMail: TAction; TBXItem34: TTBXItem; TBXItem35: TTBXItem; pagDocumentos: TTabSheet; frViewDocumentosPresupuestoCliente1: TfrViewDocumentosPresupuestoCliente; frViewDetallesPresupuestoCliente1: TfrViewDetallesPresupuestoCliente; frViewTotales1: TfrViewTotalesPresupuesto; frViewPresupuestoCliente1: TfrViewPresupuestoCliente; actRecalcularPrecioPunto: TAction; procedure FormShow(Sender: TObject); procedure CustomEditorClose(Sender: TObject; var Action: TCloseAction); procedure frViewTotales1ePortePropertiesValidate(Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); procedure pgPaginasChanging(Sender: TObject; var AllowChange: Boolean); procedure actEnviarPorEMailExecute(Sender: TObject); procedure actEnviarPorEMailUpdate(Sender: TObject); procedure actEliminarUpdate(Sender: TObject); procedure frViewTotales1bTiposIVAClick(Sender: TObject); procedure frViewTotales1eIVAPropertiesValidate(Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); procedure OnRecargoEquivalenciaPropertiesValidate(Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); procedure actRecalcularPrecioPuntoExecute(Sender: TObject); procedure OnPrecioPuntoPropertiesEditValueChanged(Sender: TObject); procedure onPrecioPuntoPropertiesValidate(Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); private procedure RecalcularPortePorUnidad; procedure frViewDetallesPresupuestoCliente1edtPrecioPuntoPropertiesEditValueChanged( Sender: TObject); protected FPresupuesto: IBizPresupuestoCliente; FTiposIVAController : ITiposIVAController; FTiposIVA: IBizTipoIVA; FViewPresupuesto: IViewPresupuestoCliente; FViewClientePresupuesto :IViewDatosYSeleccionClientePresupuesto; FController : IPresupuestosClienteController; function GetController : IPresupuestosClienteController; procedure SetController (const Value : IPresupuestosClienteController); virtual; function GetPresupuesto: IBizPresupuestoCliente; procedure SetPresupuesto(const Value: IBizPresupuestoCliente); virtual; function GetViewPresupuesto: IViewPresupuestoCliente; procedure SetViewPresupuesto(const Value: IViewPresupuestoCliente); procedure PrevisualizarInterno; override; procedure ImprimirInterno; override; procedure GuardarInterno; override; procedure EliminarInterno; override; procedure RefrescarInterno; override; property ViewPresupuesto: IViewPresupuestoCliente read GetViewPresupuesto write SetViewPresupuesto; procedure OnClienteChanged(Sender : TObject); //Si queremos crear otra vista para el editor heredado solo tendriamos que //sobreescribir este metodo // procedure AsignarVista; virtual; procedure PonerTitulos(const ATitulo: string = ''); override; function GetModified: Boolean; override; procedure SetModified(const Value : Boolean); override; function PuedoImprimir: Boolean; override; public property Controller : IPresupuestosClienteController read GetController write SetController; property Presupuesto: IBizPresupuestoCliente read GetPresupuesto write SetPresupuesto; constructor Create(AOwner: TComponent); override; destructor Destroy; override; end; implementation uses Dialogs, uDialogOpcionesImpresionPresupuestosCliente, uViewDatosYSeleccionCliente, uDataModuleUsuarios, uClientesController, uBizDireccionesContacto, uDialogUtils, uFactuGES_App, uDataTableUtils; {$R *.dfm} { TfEditorPresupuestoCliente } { **************************** TfEditorPresupuestoCliente **************************** } procedure TfEditorPresupuestoCliente.actEliminarUpdate(Sender: TObject); begin inherited; if (Sender as TAction).Enabled then (Sender as TAction).Enabled := (FPresupuesto.SITUACION = SITUACION_PRESUPUESTO_PENDIENTE); end; procedure TfEditorPresupuestoCliente.actEnviarPorEMailExecute(Sender: TObject); begin inherited; FController.EnviarPresupuestoPorEMail(Presupuesto); end; procedure TfEditorPresupuestoCliente.actEnviarPorEMailUpdate(Sender: TObject); begin inherited; (Sender as TAction).Enabled := HayDatos; end; procedure TfEditorPresupuestoCliente.actRecalcularPrecioPuntoExecute(Sender: TObject); begin ShowHourglassCursor; try inherited; //Esta lógica se llamará en el editor porque es para facilitar el rellenado de información del documento //no puede ir en la clase de negocio porque no es una lógica que tenga sentido fuera del editor. if (Presupuesto.Detalles.Datatable.State <> dsInactive) and (not Presupuesto.Detalles.DataTable.IsEmpty) and Assigned(Controller) and Assigned(Controller.DetallesController) then begin Controller.DetallesController.PrecioPunto := FPresupuesto.PRECIO_PUNTO; Controller.DetallesController.RecalcularPrecioPuntoDetalles(FPresupuesto.PRECIO_PUNTO, FPresupuesto.Detalles) end; finally HideHourglassCursor; end; end; constructor TfEditorPresupuestoCliente.Create(AOwner: TComponent); begin inherited; pgPaginas.ActivePageIndex := 0; ViewPresupuesto := frViewPresupuestoCliente1; FTiposIVAController := TTiposIVAController.Create; end; procedure TfEditorPresupuestoCliente.CustomEditorClose(Sender: TObject; var Action: TCloseAction); begin frViewTotales1.cbRecargoEquivalencia.Properties.OnValidate := Nil; //PRECIO_PUNTO EVENTOS frViewDetallesPresupuestoCliente1.edtPrecioPunto.Properties.OnValidate := Nil; frViewDetallesPresupuestoCliente1.edtPrecioPunto.Properties.OnEditValueChanged := Nil; inherited; //GESTION_DOCUMENTOS //Este método eliminará el directorio temporal si se ha creado frViewDocumentosPresupuestoCliente1.actEliminarTodo.Execute; FViewPresupuesto := NIL; FViewClientePresupuesto := NIL; FPresupuesto := NIL; FTiposIVAController := Nil; end; destructor TfEditorPresupuestoCliente.Destroy; begin // Utilizar mejor OnClose; inherited; end; procedure TfEditorPresupuestoCliente.EliminarInterno; begin //PRECIO_PUNTO EVENTOS frViewDetallesPresupuestoCliente1.edtPrecioPunto.Properties.OnValidate := Nil; frViewDetallesPresupuestoCliente1.edtPrecioPunto.Properties.OnEditValueChanged := Nil; if (ShowConfirmMessage('¿Desea borrar este presupuesto de cliente?', '') = IDYES) then begin FController.Eliminar(FPresupuesto); inherited end end; procedure TfEditorPresupuestoCliente.FormShow(Sender: TObject); begin inherited; if not Assigned(FViewPresupuesto) then raise Exception.Create('No hay ninguna vista asignada'); if not Assigned(Presupuesto) then raise Exception.Create('No hay ningún presupuesto asignado'); frViewTotales1.cbRecargoEquivalencia.Properties.OnValidate := OnRecargoEquivalenciaPropertiesValidate; //PRECIO_PUNTO EVENTOS frViewDetallesPresupuestoCliente1.edtPrecioPunto.Properties.OnValidate := onPrecioPuntoPropertiesValidate; frViewDetallesPresupuestoCliente1.edtPrecioPunto.Properties.OnEditValueChanged := OnPrecioPuntoPropertiesEditValueChanged; pgPaginas.ActivePage := pagGeneral; Presupuesto.DataTable.Active := True; end; procedure TfEditorPresupuestoCliente.frViewDetallesPresupuestoCliente1edtPrecioPuntoPropertiesEditValueChanged( Sender: TObject); begin inherited; end; procedure TfEditorPresupuestoCliente.onPrecioPuntoPropertiesValidate(Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); begin inherited; if (ShowConfirmMessage('Va ha cambiar el precio punto, esto ocasionará el recalculo de todos los artículos del presupuesto que estén en el catálogo, los conceptos libres no se verán afectados', '¿Desea actualizar los importes de todos los articulos del presupuesto, que estén en el catálogo?') = IDNO) then DisplayValue := frViewDetallesPresupuestoCliente1.edtPrecioPunto.Value; end; procedure TfEditorPresupuestoCliente.frViewTotales1bTiposIVAClick( Sender: TObject); begin inherited; FTiposIVAController.VerTodos(FTiposIVA); end; procedure TfEditorPresupuestoCliente.frViewTotales1eIVAPropertiesValidate( Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); begin inherited; Presupuesto.Edit; Presupuesto.ID_TIPO_IVA := FTiposIVA.ID; // ((frViewTotales1.dsTiposIVA.DataTable) as IBizTipoIVA).ID; end; procedure TfEditorPresupuestoCliente.frViewTotales1ePortePropertiesValidate( Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); begin inherited; { if (not VarIsNull(DisplayValue)) and (Length(DisplayValue) > 0) then FPresupuesto.IMPORTE_PORTE := DisplayValue else FPresupuesto.IMPORTE_PORTE := 0; } // RecalcularPortePorUnidad; En los documentos de cliente no se desglosa el porte por articulo end; function TfEditorPresupuestoCliente.GetController: IPresupuestosClienteController; begin Result := FController; end; function TfEditorPresupuestoCliente.GetModified: Boolean; begin // inherited; <- No llamar al padre porque queremos tratamiento especial. if ReadOnly then Result := False else begin Result := DataTableModified(dsDataTable.DataTable); if not Result then Result := frViewDocumentosPresupuestoCliente1.Modified; end; end; function TfEditorPresupuestoCliente.GetPresupuesto: IBizPresupuestoCliente; begin Result := FPresupuesto; end; function TfEditorPresupuestoCliente.GetViewPresupuesto: IViewPresupuestoCliente; begin Result := FViewPresupuesto; end; procedure TfEditorPresupuestoCliente.GuardarInterno; var bEsNuevo : Boolean; begin //PRECIO_PUNTO EVENTOS frViewDetallesPresupuestoCliente1.edtPrecioPunto.Properties.OnValidate := Nil; frViewDetallesPresupuestoCliente1.edtPrecioPunto.Properties.OnEditValueChanged := Nil; inherited; ShowHourglassCursor; // frViewDetallesPresupuestoCliente1.SaveGridStatus; frViewDetallesPresupuestoCliente1.BeginUpdate; try bEsNuevo := FPresupuesto.EsNuevo; //GESTION_DOCUMENTOS if FController.Guardar(FPresupuesto) then frViewDocumentosPresupuestoCliente1.actActualizarServidor.Execute; finally frViewDetallesPresupuestoCliente1.EndUpdate; // frViewDetallesPresupuestoCliente1.RestoreGridStatus; HideHourglassCursor; end; if bEsNuevo then ShowInfoMessage('El presupuesto se ha dado de alta con el código ' + FPresupuesto.REFERENCIA); Modified := False; //PRECIO_PUNTO EVENTOS frViewDetallesPresupuestoCliente1.edtPrecioPunto.Properties.OnValidate := onPrecioPuntoPropertiesValidate; frViewDetallesPresupuestoCliente1.edtPrecioPunto.Properties.OnEditValueChanged := OnPrecioPuntoPropertiesEditValueChanged; end; procedure TfEditorPresupuestoCliente.ImprimirInterno; var FVerLogotipo: Boolean; FImprimirPrecios : Boolean; FImprimirTotales : Boolean; FImprimirTotalesCapitulos : Boolean; FImprimirObservaciones: Boolean; FImprimirIncidencias: Boolean; begin inherited; FVerLogotipo := True; FImprimirPrecios := False; FImprimirTotales := True; FImprimirTotalesCapitulos := True; FImprimirObservaciones := False; FImprimirIncidencias := False; if not Modified then if ElegirOpcionesImpresionPresupuestoCliente(FVerLogotipo, FImprimirPrecios, FImprimirTotales, FImprimirTotalesCapitulos, FImprimirObservaciones, FImprimirIncidencias) then FController.Print(FPresupuesto, False, FVerLogotipo, FImprimirPrecios, FImprimirTotales, FImprimirTotalesCapitulos, FImprimirObservaciones, FImprimirIncidencias); end; procedure TfEditorPresupuestoCliente.OnClienteChanged(Sender: TObject); var APrimerCliente : Boolean; begin if Assigned(FPresupuesto) then begin APrimerCliente := (FPresupuesto.Cliente.ID = 0); FPresupuesto.Cliente := ViewPresupuesto.ViewClientePresupuesto.Cliente; Controller.DetallesController.PrecioPunto := FPresupuesto.Cliente.PRECIO_PUNTO; if (ShowConfirmMessage('Cambio forma de pago y tipo de IVA', '¿Desea actualizar la forma de pago y el tipo de IVA a la asignada en la ficha del cliente seleccionado?') = IDYES) then FController.ActualizarFormaDePago(FPresupuesto, FPresupuesto.Cliente.ID_FORMA_PAGO); if (not APrimerCliente) and (FPresupuesto.Detalles.RecordCount > 0) then begin if (ShowConfirmMessage('Actualizar los descuentos de las líneas', '¿Desea actualizar las líneas de detalle con el descuento del cliente?' + #10#13 + 'Sólo se cambiarán las líneas que tengan cantidades.') = IDYES) then begin FController.DetallesController.ActualizarDetalles(FPresupuesto.Detalles, FPresupuesto.Cliente); ShowInfoMessage('Se han actualizado las líneas con el descuento del cliente seleccionado'); end; end; end; end; procedure TfEditorPresupuestoCliente.OnPrecioPuntoPropertiesEditValueChanged(Sender: TObject); begin if not FPresupuesto.EsNuevo then actRecalcularPrecioPunto.Execute; end; procedure TfEditorPresupuestoCliente.OnRecargoEquivalenciaPropertiesValidate( Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); begin if frViewTotales1.cbRecargoEquivalencia.Checked then Presupuesto.RECARGO_EQUIVALENCIA := 1 else Presupuesto.RECARGO_EQUIVALENCIA := 0; end; procedure TfEditorPresupuestoCliente.pgPaginasChanging(Sender: TObject; var AllowChange: Boolean); var ACadena : String; begin inherited; if (not Assigned(FPresupuesto)) or (FPresupuesto.ID_CLIENTE = 0) then begin ACadena := 'Antes de introducir conceptos debe elegir un cliente para este presupuesto'; ShowWarningMessage(ACadena); AllowChange := False; end end; procedure TfEditorPresupuestoCliente.PonerTitulos(const ATitulo: string); var FTitulo : String; begin FTitulo := ATitulo; if (FTitulo = '') and Assigned(FPresupuesto) then begin if FPresupuesto.EsNuevo then FTitulo := 'Nuevo presupuesto de cliente' else FTitulo := 'Presupuesto de cliente' + ' - ' + FPresupuesto.Cliente.Nombre + ' - ' + FPresupuesto.SITUACION; end; inherited PonerTitulos(FTitulo); Self.Caption := FTitulo + ' (' + AppFactuGES.EmpresaActiva.NOMBRE + ')'; end; procedure TfEditorPresupuestoCliente.PrevisualizarInterno; var FVerLogotipo: Boolean; FImprimirPrecios : Boolean; FImprimirTotales : Boolean; FImprimirTotalesCapitulos : Boolean; FImprimirObservaciones: Boolean; FImprimirIncidencias: Boolean; begin inherited; FVerLogotipo := True; FImprimirPrecios := False; FImprimirTotales := True; FImprimirTotalesCapitulos := True; FImprimirObservaciones := False; FImprimirIncidencias := False; if not Modified then if ElegirOpcionesImpresionPresupuestoCliente(FVerLogotipo, FImprimirPrecios, FImprimirTotales, FImprimirTotalesCapitulos, FImprimirObservaciones, FImprimirIncidencias) then FController.Preview(FPresupuesto, False, FVerLogotipo, FImprimirPrecios, FImprimirTotales, FImprimirTotalesCapitulos, FImprimirObservaciones, FImprimirIncidencias); end; function TfEditorPresupuestoCliente.PuedoImprimir: Boolean; begin Result := inherited PuedoImprimir and (not Presupuesto.Cliente.IDIsNull); end; procedure TfEditorPresupuestoCliente.RecalcularPortePorUnidad; begin //Esta lógica se llamará en el editor porque es para facilitar el rellenado de información del documento //no puede ir en la clase de negocio porque no es una lógica que tenga sentido fuera del editor. if Assigned(Controller) and Assigned(Controller.DetallesController) then Controller.DetallesController.DesglosarPorteDetalles(FPresupuesto.IMPORTE_PORTE, FPresupuesto.Detalles) end; procedure TfEditorPresupuestoCliente.RefrescarInterno; begin //PRECIO_PUNTO EVENTOS frViewDetallesPresupuestoCliente1.edtPrecioPunto.Properties.OnValidate := Nil; frViewDetallesPresupuestoCliente1.edtPrecioPunto.Properties.OnEditValueChanged := Nil; inherited; //PRECIO_PUNTO EVENTOS frViewDetallesPresupuestoCliente1.edtPrecioPunto.Properties.OnValidate := onPrecioPuntoPropertiesValidate; frViewDetallesPresupuestoCliente1.edtPrecioPunto.Properties.OnEditValueChanged := OnPrecioPuntoPropertiesEditValueChanged; end; procedure TfEditorPresupuestoCliente.SetController(const Value: IPresupuestosClienteController); begin FController := Value; if Assigned(FController) then begin // ViewPresupuesto.ViewClientePresupuesto.Controller := Controller.ClienteController; frViewDetallesPresupuestoCliente1.Controller := Controller.DetallesController; //GESTION_DOCUMENTOS frViewDocumentosPresupuestoCliente1.Controller := Controller; // frViewTotales1.Controller := FController; end; end; procedure TfEditorPresupuestoCliente.SetModified(const Value: Boolean); begin inherited; frViewDocumentosPresupuestoCliente1.Modified := Value; end; procedure TfEditorPresupuestoCliente.SetPresupuesto(const Value: IBizPresupuestoCliente); begin FPresupuesto := Value; if Assigned(FPresupuesto) then begin dsDataTable.DataTable := FPresupuesto.DataTable; frViewIncidenciasCli.DADataSource.DataTable := dsDataTable.DataTable; frViewTotales1.DADataSource.DataTable := FPresupuesto.DataTable; FTiposIVA := FTiposIVAController.BuscarTodos; frViewTotales1.dsTiposIVA.DataTable := FTiposIVA.DataTable; FTiposIVA.DataTable.Active := True; if Assigned(FViewPresupuesto) then begin ViewPresupuesto.ViewClientePresupuesto.OnClienteChanged := NIL; try FViewPresupuesto.Presupuesto := FPresupuesto; Controller.DetallesController.PrecioPunto := FPresupuesto.PRECIO_PUNTO; frViewDetallesPresupuestoCliente1.Detalles := FPresupuesto.Detalles; frViewDetallesPresupuestoCliente1.Presupuesto := FPresupuesto; //Para poder sacar los descuento del articulos segun el cliente seleccionado //GESTION_DOCUMENTOS frViewDocumentosPresupuestoCliente1.Presupuesto := FPresupuesto; finally ViewPresupuesto.ViewClientePresupuesto.OnClienteChanged := OnClienteChanged; end; end; end; end; procedure TfEditorPresupuestoCliente.SetViewPresupuesto(const Value: IViewPresupuestoCliente); begin FViewPresupuesto := Value; if Assigned(FViewPresupuesto) then begin FViewClientePresupuesto := FViewPresupuesto.ViewClientePresupuesto; if Assigned(Presupuesto) then FViewPresupuesto.Presupuesto := Presupuesto; end; end; end.