unit uEditorFacturaProforma; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, uEditorDBItem, DB, uDADataTable, JvAppStorage, JvAppRegistryStorage, JvComponent, JvFormPlacement, ImgList, PngImageList, StdActns, ActnList, ComCtrls, TBX, TB2Item, TB2Dock, TB2Toolbar, ExtCtrls, JvExControls, JvNavigationPane, uViewFacturaProforma, uCustomView, uViewBase, uViewTotales, StdCtrls, pngimage, AppEvnts, JvComponentBase, uBizFacturasProforma, uBizTiposIVA, uIEditorFacturaProforma, uFacturasProformaController, uViewDetallesBase, uViewDetallesFacturaProforma, dxLayoutLookAndFeels, JvExComCtrls, JvStatusBar, uViewDetallesDTO, uViewDetallesArticulos, uTiposIVAController, uDAInterfaces, cxControls, cxContainer, cxEdit, cxTextEdit, cxDBEdit, Grids, DBGrids, uViewDetallesArticulosParaVenta, cxLabel; type TfEditorFacturaProforma = class(TfEditorDBItem, IEditorFacturaProforma) frViewTotales1: TfrViewTotales; actEnviarEMail: TAction; TBXSeparatorItem6: TTBXSeparatorItem; TBXItem7: TTBXItem; TBXSubmenuItem2: TTBXSubmenuItem; TBXItem33: TTBXItem; frViewDetallesFacturaProforma1: TfrViewDetallesFacturaProforma; frViewFacturaProforma1: TfrViewFacturaProforma; procedure FormShow(Sender: TObject); procedure frViewClienteFactura1edtlNombrePropertiesEditValueChanged(Sender: TObject); procedure dsDataTableDataChange(Sender: TObject; Field: TField); procedure CustomEditorClose(Sender: TObject; var Action: TCloseAction); procedure frViewClienteFacturaedtlNombrePropertiesChange(Sender: TObject); procedure pgPaginasChanging(Sender: TObject; var AllowChange: Boolean); // procedure frViewTotales1edtDescuentoPropertiesValidate(Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); procedure frViewTotales1bTiposIVAClick(Sender: TObject); // procedure frViewTotales1eIVAPropertiesValidate(Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); // procedure frViewTotales1cbRecargoEquivalenciaPropertiesEditValueChanged(Sender: TObject); // procedure frViewTotales1ePortePropertiesValidate(Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); procedure frViewTotales1ePorteEditing(Sender: TObject; var CanEdit: Boolean); procedure actEnviarEMailExecute(Sender: TObject); procedure actEnviarEMailUpdate(Sender: TObject); private procedure RecalcularPortePorUnidad; protected FController : IFacturasProformaController; FFactura: IBizFacturaProforma; FTiposIVAController : ITiposIVAController; FTiposIVA: IBizTipoIVA; FViewFactura: IViewFacturaProforma; function GetController : IFacturasProformaController; procedure SetController (const Value : IFacturasProformaController); function GetFactura: IBizFacturaProforma; procedure SetFactura(const Value: IBizFacturaProforma); function GetViewFactura: IViewFacturaProforma; procedure SetViewFactura(const Value: IViewFacturaProforma); property ViewFacturaProforma: IViewFacturaProforma read GetViewFactura write SetViewFactura; procedure OnClienteChanged(Sender: TObject); procedure GuardarInterno; override; procedure EliminarInterno; override; procedure ImprimirInterno; override; procedure PrevisualizarInterno; override; procedure PonerTitulos(const ATitulo: string = ''); override; function PuedoImprimir: Boolean; override; function PuedoEnviar: Boolean; virtual; public destructor Destroy; override; property Controller : IFacturasProformaController read GetController write SetController; property Factura: IBizFacturaProforma read GetFactura write SetFactura; constructor Create(AOwner: TComponent); override; procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); override; //Importante en este punto se deben de quitar los eventos que puedan afectar a la tabla una vez se cierre el editor. end; implementation {$R *.dfm} uses uBizContactos, uDataModuleUsuarios, uFactuGES_App, uDetallesFacturaProformaController, uDialogUtils, uDataTableUtils, uDialogOpcionesImpresionFacturasProforma; // uGenerarAlbaranesCliFacCliUtils; { TfEditorFacturaProforma } { **************************** TfEditorFacturaProforma **************************** } procedure TfEditorFacturaProforma.actEnviarEMailExecute(Sender: TObject); begin if actEnviarEMail.Enabled then begin if Modified then begin if (ShowConfirmMessage('Se han producido cambios', 'Se han producido cambios y no se puede enviar por email hasta que no se guarden.' + #10#13 + '¿Desea guardarlos ahora?') = IDYES) then begin GuardarInterno; FController.GenerarEmailFactura(Factura); end else ShowInfoMessage('Recuerde guardar los cambios si quiere enviar por email.'); end else FController.GenerarEmailFactura(Factura); end; end; procedure TfEditorFacturaProforma.actEnviarEMailUpdate(Sender: TObject); begin inherited; (Sender as TAction).Enabled := HayDatos and PuedoEnviar; end; constructor TfEditorFacturaProforma.Create(AOwner: TComponent); begin inherited; pgPaginas.ActivePageIndex := 0; ViewFacturaProforma := frViewFacturaProforma1; FTiposIVAController := TTiposIVAController.Create; end; procedure TfEditorFacturaProforma.CustomEditorClose(Sender: TObject; var Action: TCloseAction); begin inherited; Factura := NIL; FTiposIVA := NIL; FTiposIVAController := Nil; FController := NIL; FViewFactura := NIL; end; destructor TfEditorFacturaProforma.Destroy; begin inherited; end; procedure TfEditorFacturaProforma.dsDataTableDataChange(Sender: TObject; Field: TField); begin inherited; if Assigned(FFactura) and (not (FFactura.DataTable.Fetching) or not (FFactura.DataTable.Opening) or not (FFactura.DataTable.Closing)) then PonerTitulos; end; procedure TfEditorFacturaProforma.EliminarInterno; var ACadena : String; begin if (Application.MessageBox('¿Desea borrar esta factura proforma?', 'Atención', MB_YESNO) = IDYES) then begin //Es el caso de querer borrar una factura pendiente cuyos recibos tienen devoluciones if not FController.Eliminar(Factura) then Application.MessageBox('La factura no ha podido ser eliminada porque tiene recibos con pagos o devoluciones emitidas.', 'Atención', MB_OK); inherited; end; end; procedure TfEditorFacturaProforma.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin inherited; frViewTotales1.cbRecargoEquivalencia.Properties.OnEditValueChanged := nil; frViewTotales1.eIVA.Properties.OnValidate := nil; frViewTotales1.ePorte.Properties.OnValidate := nil; end; procedure TfEditorFacturaProforma.FormShow(Sender: TObject); begin inherited; if not Assigned(FViewFactura) then raise Exception.Create('No hay ninguna vista asignada'); if not Assigned(Factura) then raise Exception.Create('No hay ninguna factura asignada'); Factura.DataTable.Active := True; end; procedure TfEditorFacturaProforma.frViewClienteFactura1edtlNombrePropertiesEditValueChanged(Sender: TObject); begin inherited; with (Sender as TcxDBTextEdit) do Enabled := (FFactura.ID <> 0) end; procedure TfEditorFacturaProforma.frViewClienteFacturaedtlNombrePropertiesChange( Sender: TObject); begin inherited; PonerTitulos; end; procedure TfEditorFacturaProforma.frViewTotales1bTiposIVAClick(Sender: TObject); begin inherited; FTiposIVAController.VerTodos(FTiposIVA); end; { procedure TfEditorFacturaProforma.frViewTotales1cbRecargoEquivalenciaPropertiesEditValueChanged( Sender: TObject); begin inherited; if Assigned(Factura) then begin Factura.Edit; if frViewTotales1.cbRecargoEquivalencia.Checked then Factura.RECARGO_EQUIVALENCIA := 1 else Factura.RECARGO_EQUIVALENCIA := 0; end; end; } { procedure TfEditorFacturaProforma.frViewTotales1edtDescuentoPropertiesValidate( Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); begin inherited; Factura.DESCUENTO := DisplayValue; end; } { procedure TfEditorFacturaProforma.frViewTotales1eIVAPropertiesValidate( Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); begin inherited; Factura.Edit; Factura.ID_TIPO_IVA := ((frViewTotales1.dsTiposIVA.DataTable) as IBizTipoIVA).ID; end; } procedure TfEditorFacturaProforma.frViewTotales1ePorteEditing(Sender: TObject; var CanEdit: Boolean); begin inherited; end; { procedure TfEditorFacturaProforma.frViewTotales1ePortePropertiesValidate( Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); begin inherited; if (not VarIsNull(DisplayValue)) and (Length(DisplayValue) > 0) then FFactura.IMPORTE_PORTE := DisplayValue else FFactura.IMPORTE_PORTE := 0; // RecalcularPortePorUnidad; En los documentos de cliente el porte no se desglosa por articulo end; } function TfEditorFacturaProforma.GetController: IFacturasProformaController; begin Result := FController; end; function TfEditorFacturaProforma.GetFactura: IBizFacturaProforma; begin Result := FFactura; end; function TfEditorFacturaProforma.GetViewFactura: IViewFacturaProforma; begin Result := FViewFactura; end; procedure TfEditorFacturaProforma.GuardarInterno; var bEsNuevo : Boolean; begin inherited; ShowHourglassCursor; //frViewDetallesFacturaProforma1.SaveGridStatus; // Para guardar estado del grid frViewDetallesFacturaProforma1.BeginUpdate; // Para que no se mueva el foco try bEsNuevo := FFactura.EsNuevo; FController.Guardar(FFactura); finally frViewDetallesFacturaProforma1.EndUpdate; //frViewDetallesFacturaProforma1.RestoreGridStatus; HideHourglassCursor; end; if bEsNuevo then begin ShowInfoMessage('La factura se ha dado de alta con el código ' + FFactura.REFERENCIA); //Preguntamos is desea hacer una orden de devolución asociada // if (Application.MessageBox('¿Desea crear una orden de devolución para el abono?', 'Atención', MB_YESNO) = IDYES) then // GenerarAlbaranCli(FFactura); end; Modified := False; end; procedure TfEditorFacturaProforma.ImprimirInterno; var AVerSello: Boolean; AVerCopia: Boolean; AllItems: Boolean; begin inherited; AllItems := False; AVerSello := True; AVerCopia := True; //Preguntamos si desea que en las facturas se vea el Sello // if ElegirOpcionesImpresionFacturaProforma(AVerSello, AVerCopia) then FController.Print(FFactura, AllItems, AVerSello, AVerCopia); end; procedure TfEditorFacturaProforma.OnClienteChanged(Sender: TObject); begin FFactura.Cliente := ViewFacturaProforma.ViewClienteFactura.Cliente; if not (FFactura.DataTable.State in dsEditModes) then FFactura.DataTable.Edit; // Actualizar IVA y RE a partir del tipo de IVA del cliente. Factura.IVA := ((frViewTotales1.dsTiposIVA.DataTable) as IBizTipoIVA).IVA; if FFactura.Cliente.RECARGO_EQUIVALENCIA = 1 then Factura.RE := ((frViewTotales1.dsTiposIVA.DataTable) as IBizTipoIVA).RE else Factura.RE := 0; //Desactivado porque en presupuestos no utilizan el catálogo de clientes // Si la factura tiene detalles hay que mirar si los descuentos y otros campos // para los artículos hay que cambiarlos. // if (FFactura.Detalles.RecordCount > 0) then // FController.DetallesController.ActualizarDetalles(FFactura.Detalles, FFactura.Cliente); end; procedure TfEditorFacturaProforma.pgPaginasChanging(Sender: TObject; var AllowChange: Boolean); begin inherited; if (not Assigned(FFactura)) or (FFactura.ID_CLIENTE = ID_NULO) then begin ShowWarningMessage('Antes debe elegir un cliente para esta factura'); AllowChange := False; end; end; function TfEditorFacturaProforma.PuedoEnviar: Boolean; begin Result := not Factura.Cliente.IDIsNull; end; function TfEditorFacturaProforma.PuedoImprimir: Boolean; begin Result := inherited PuedoImprimir and (not Factura.Cliente.IDIsNull); end; procedure TfEditorFacturaProforma.PonerTitulos(const ATitulo: string); var FTitulo : String; begin FTitulo := ATitulo; if (FTitulo = '') and Assigned(Factura) then begin if Factura.EsNuevo then FTitulo := 'Nueva factura proforma' else FTitulo := 'Factura proforma' + ' - ' + FFactura.Cliente.Nombre end; inherited PonerTitulos(FTitulo); Self.Caption := FTitulo + ' (' + AppFactuGES.EmpresaActiva.NOMBRE + ')'; end; procedure TfEditorFacturaProforma.PrevisualizarInterno; var AVerSello: Boolean; AVerCopia: Boolean; AllItems: Boolean; begin inherited; AllItems := False; AVerSello := True; AVerCopia := True; //Preguntamos si desea que en las facturas se vea el Sello // if ElegirOpcionesImpresionFacturaProforma(AVerSello, AVerCopia) then FController.Preview(FFactura, AllItems, AVerSello, AVerCopia); end; procedure TfEditorFacturaProforma.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(FFactura.IMPORTE_PORTE, FFactura.Detalles) end; procedure TfEditorFacturaProforma.SetController(const Value: IFacturasProformaController); begin FController := Value; if Assigned(FController) then begin ViewFacturaProforma.Controller := FController; frViewDetallesFacturaProforma1.Controller := Controller.DetallesController; end; end; procedure TfEditorFacturaProforma.SetFactura(const Value: IBizFacturaProforma); begin FFactura := Value; if Assigned(FFactura) then begin dsDataTable.DataTable := FFactura.DataTable; frViewTotales1.DADataSource.DataTable := FFactura.DataTable; FTiposIVA := FTiposIVAController.BuscarTodos; frViewTotales1.dsTiposIVA.DataTable := FTiposIVA.DataTable; FTiposIVA.DataTable.Active := True; if Assigned(FViewFactura) then begin ViewFacturaProforma.ViewClienteFactura.OnClienteChanged := NIL; try FViewFactura.Factura := FFactura; frViewDetallesFacturaProforma1.Detalles := FFactura.Detalles; frViewDetallesFacturaProforma1.Factura := FFactura; //Para poder sacar los descuento del articulos segun el cliente seleccionado finally ViewFacturaProforma.ViewClienteFactura.OnClienteChanged := OnClienteChanged; end; end; end else begin ViewFacturaProforma.ViewClienteFactura.OnClienteChanged := NIL; dsDataTable.DataTable := NIL; frViewTotales1.DADataSource.DataTable := NIL; frViewTotales1.dsTiposIVA.DataTable := NIL; end end; procedure TfEditorFacturaProforma.SetViewFactura(const Value: IViewFacturaProforma); begin FViewFactura := Value; if Assigned(FViewFactura) and Assigned(Factura) then FViewFactura.Factura := Factura; end; end.