unit uEditorFacturaProveedor; 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, uCustomView, uViewBase, uViewTotales, StdCtrls, pngimage, AppEvnts, JvComponentBase, uBizFacturasProveedor, uIEditorFacturaProveedor, uFacturasProveedorController, uViewDetallesBase, dxLayoutLookAndFeels, JvExComCtrls, JvStatusBar, uBizTiposIVA, uViewDetallesDTO, uViewDetallesArticulos, uTiposIVAController, uViewDetallesFacturaProveedor, uViewFacturaProveedor, uDAInterfaces, cxControls, cxContainer, cxEdit, cxCheckBox, cxDBEdit, uViewListaSubCuentas, uViewDetallesGenerico, uViewContratosFacturaProveedor; type TfEditorFacturaProveedor = class(TfEditorDBItem, IEditorFacturaProveedor) frViewTotales1: TfrViewTotales; frViewFacturaProveedor1: TfrViewFacturaProveedor; frViewDetallesFacturaProveedor1: TfrViewDetallesFacturaProveedor; pagContabilidad: TTabSheet; frViewListaSubcuentas1: TfrViewListaSubcuentas; PagContratos: TTabSheet; frViewContratosFacturaProveedor1: TfrViewContratosFacturaProveedor; procedure FormShow(Sender: TObject); procedure frViewProveedorFactura1edtlNombrePropertiesEditValueChanged( Sender: TObject); procedure dsDataTableDataChange(Sender: TObject; Field: TField); procedure CustomEditorClose(Sender: TObject; var Action: TCloseAction); procedure frViewProveedorFacturaedtlNombrePropertiesChange(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 frViewTotales1ePortePropertiesValidate(Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); procedure frViewTotales1ePorteEditing(Sender: TObject; var CanEdit: Boolean); procedure OnRecargoEquivalenciaPropertiesValidate(Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); //Importante en este punto se deben de quitar los eventos que puedan afectar a la tabla una vez se cierre el editor. private procedure RecalcularPortePorUnidad; protected FController : IFacturasProveedorController; FFactura: IBizFacturaProveedor; FViewFactura: IViewFacturaProveedor; FTiposIVAController : ITiposIVAController; FTiposIVA: IBizTipoIVA; function GetController : IFacturasProveedorController; procedure SetController (const Value : IFacturasProveedorController); function GetFactura: IBizFacturaProveedor; procedure SetFactura(const Value: IBizFacturaProveedor); function GetViewFactura: IViewFacturaProveedor; procedure SetViewFactura(const Value: IViewFacturaProveedor); property ViewFacturaProveedor: IViewFacturaProveedor read GetViewFactura write SetViewFactura; procedure OnProveedorChanged(Sender: TObject); procedure GuardarInterno; override; procedure EliminarInterno; override; procedure ImprimirInterno; override; procedure PrevisualizarInterno; override; procedure PonerTitulos(const ATitulo: string = ''); override; public destructor Destroy; override; property Controller : IFacturasProveedorController read GetController write SetController; property Factura: IBizFacturaProveedor read GetFactura write SetFactura; constructor Create(AOwner: TComponent); override; end; implementation {$R *.dfm} {$INCLUDE ..\..\..\FactuGES.inc} uses uBizContactos, uDataModuleUsuarios, uFactuGES_App, uSubCuentasController, uDetallesFacturaProveedorController, uProveedoresController, uDialogUtils, uDataTableUtils, uBizDireccionesContacto, uViewProveedorFactura; // uGenerarAlbaranesProvFacProvUtils; { TfEditorFacturaProveedor } { **************************** TfEditorFacturaProveedor **************************** } constructor TfEditorFacturaProveedor.Create(AOwner: TComponent); begin inherited; pgPaginas.ActivePageIndex := 0; ViewFacturaProveedor := frViewFacturaProveedor1; FTiposIVAController := TTiposIVAController.Create; {$IFDEF CONTABILIDAD} frViewListaSubcuentas1.TipoSubCuenta := tCompras; {$ENDIF} end; procedure TfEditorFacturaProveedor.CustomEditorClose(Sender: TObject; var Action: TCloseAction); begin inherited; dsDataTable.DataTable := NIL; frViewTotales1.DADataSource.DataTable := NIL; frViewTotales1.cbRecargoEquivalencia.Properties.OnValidate := nil; FTiposIVA := NIL; FTiposIVAController := Nil; FController := NIL; FViewFactura := NIL; Factura := NIL; end; destructor TfEditorFacturaProveedor.Destroy; begin inherited; end; procedure TfEditorFacturaProveedor.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 TfEditorFacturaProveedor.EliminarInterno; var AMensaje : String; begin if FFactura.TIPO = CTE_TIPO_ABONO then AMensaje := '¿Desea borrar esta factura de proveedor?' else AMensaje := '¿Desea borrar este abono de proveedor?'; if (Application.MessageBox(PChar(AMensaje), '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 TfEditorFacturaProveedor.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'); frViewTotales1.cbRecargoEquivalencia.Properties.OnValidate := OnRecargoEquivalenciaPropertiesValidate; Factura.DataTable.Active := True; end; procedure TfEditorFacturaProveedor.frViewProveedorFactura1edtlNombrePropertiesEditValueChanged(Sender: TObject); begin inherited; with (Sender as TcxDBTextEdit) do Enabled := (FFactura.ID <> 0) end; procedure TfEditorFacturaProveedor.frViewProveedorFacturaedtlNombrePropertiesChange( Sender: TObject); begin inherited; PonerTitulos; end; procedure TfEditorFacturaProveedor.frViewTotales1bTiposIVAClick(Sender: TObject); begin inherited; FTiposIVAController.VerTodos(FTiposIVA); end; procedure TfEditorFacturaProveedor.frViewTotales1edtDescuentoPropertiesValidate( Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); begin inherited; Factura.DESCUENTO := DisplayValue; end; procedure TfEditorFacturaProveedor.frViewTotales1eIVAPropertiesValidate( Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); begin inherited; Factura.Edit; Factura.ID_TIPO_IVA := FTiposIVA.ID; //((frViewTotales1.dsTiposIVA.DataTable) as IBizTipoIVA).ID; end; procedure TfEditorFacturaProveedor.frViewTotales1ePorteEditing(Sender: TObject; var CanEdit: Boolean); begin inherited; if FFactura.TIPO = CTE_TIPO_ABONO then CanEdit := False; end; procedure TfEditorFacturaProveedor.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; end; function TfEditorFacturaProveedor.GetController: IFacturasProveedorController; begin Result := FController; end; function TfEditorFacturaProveedor.GetFactura: IBizFacturaProveedor; begin Result := FFactura; end; function TfEditorFacturaProveedor.GetViewFactura: IViewFacturaProveedor; begin Result := FViewFactura; end; procedure TfEditorFacturaProveedor.GuardarInterno; var bEsNuevo : Boolean; begin inherited; ShowHourglassCursor; //frViewDetallesFacturaProveedor1.SaveGridStatus; // Para guardar estado del grid frViewDetallesFacturaProveedor1.BeginUpdate; // Para que no se mueva el foco try bEsNuevo := FFactura.EsNuevo; {$IFDEF CONTABILIDAD} FFactura.Edit; FController.SetIgnorarContabilidad(FFactura, frViewListaSubCuentas1.eContabilizar.EditValue); FFactura.ID_SUBCUENTA := frViewListaSubCuentas1.IdSubCuenta; {$ENDIF} FController.Guardar(FFactura); finally frViewDetallesFacturaProveedor1.EndUpdate; //frViewDetallesFacturaProveedor1.RestoreGridStatus; HideHourglassCursor; end; if bEsNuevo then begin if FFactura.TIPO = CTE_TIPO_FACTURA then ShowInfoMessage('La factura se ha dado de alta con el código ' + FFactura.REFERENCIA) else begin ShowInfoMessage('El abono 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 // GenerarAlbaranProv(FFactura); end; end; Modified := False; end; procedure TfEditorFacturaProveedor.ImprimirInterno; begin { inherited; FController.Print(FFactura); } end; procedure TfEditorFacturaProveedor.OnProveedorChanged(Sender: TObject); var FDetallesController : IDetallesFacturaProveedorController; AProveedoresController : IProveedoresController; ADireccion : IBizDireccionesContacto; begin FFactura.Proveedor := frViewFacturaProveedor1.frViewProveedorFactura1.Proveedor; if not (FFactura.DataTable.State in dsEditModes) then FFactura.DataTable.Edit; //En el caso de Acana no se cambia para que el IVA y la FORMA DE PAGO por defecto sea el de la empresa. // Actualizar IVA y RE a partir del tipo de IVA del proveedor. { Factura.IVA := FTiposIVA.IVA; //((frViewTotales1.dsTiposIVA.DataTable) as IBizTipoIVA).IVA; // if FFactura.Proveedor.RECARGO_EQUIVALENCIA = 1 then // Factura.RE := ((frViewTotales1.dsTiposIVA.DataTable) as IBizTipoIVA).RE // else // Factura.RE := 0; } // En el caso de tener direcciones asociadas, se debe dar la posibilidad de elegir la dirección principal o las secundarias para la factura AProveedoresController := TProveedoresController.Create; try case FFactura.Proveedor.Direcciones.RecordCount of 0 : //No hay direcciones secundarias asociadas else ADireccion := AProveedoresController.ElegirDireccion(FFactura.Proveedor, 'Seleccione la dirección del proveedor que quiere utilizar como dirección fiscal de esta factura.'); end; // Si hay dirección de envio, copiarla al albarán y poner el coste del porte if Assigned(ADireccion) then begin if not ADireccion.IDIsNull then try FFactura.Edit; FFactura.IMPORTE_PORTE := ADireccion.PORTE; FController.CopiarDireccion(ADireccion, FFactura); finally ADireccion := NIL; end; end finally AProveedoresController := Nil; end; // 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.Proveedor); end; procedure TfEditorFacturaProveedor.OnRecargoEquivalenciaPropertiesValidate( Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); begin if frViewTotales1.cbRecargoEquivalencia.Checked then Factura.RECARGO_EQUIVALENCIA := 1 else Factura.RECARGO_EQUIVALENCIA := 0; end; procedure TfEditorFacturaProveedor.pgPaginasChanging(Sender: TObject; var AllowChange: Boolean); var AMensaje : String; begin inherited; if (not Assigned(FFactura)) or (FFactura.ID_PROVEEDOR = ID_NULO) then begin if FFactura.TIPO = CTE_TIPO_FACTURA then AMensaje := 'Antes debe elegir un proveedor para esta factura' else AMensaje := 'Antes debe elegir un proveedor para este abono'; ShowWarningMessage(AMensaje); AllowChange := False; end; end; procedure TfEditorFacturaProveedor.PonerTitulos(const ATitulo: string); var FTitulo : String; begin FTitulo := ATitulo; if (FTitulo = '') and Assigned(Factura) then begin if Factura.EsNuevo then if Factura.TIPO = CTE_TIPO_FACTURA then FTitulo := 'Nueva factura de proveedor' else FTitulo := 'Nuevo abono de proveedor' else if Factura.TIPO = CTE_TIPO_FACTURA then FTitulo := 'Factura de proveedor' + ' - ' + FFactura.Proveedor.Nombre else FTitulo := 'Abono de proveedor' + ' - ' + FFactura.Proveedor.Nombre end; inherited PonerTitulos(FTitulo); Self.Caption := FTitulo + ' (' + AppFactuGES.EmpresaActiva.NOMBRE + ')'; end; procedure TfEditorFacturaProveedor.PrevisualizarInterno; begin { inherited; FController.Preview(FFactura); } end; procedure TfEditorFacturaProveedor.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 TfEditorFacturaProveedor.SetController(const Value: IFacturasProveedorController); begin FController := Value; if Assigned(FController) then begin ViewFacturaProveedor.Controller := FController; frViewDetallesFacturaProveedor1.Controller := Controller.DetallesController; frViewContratosFacturaProveedor1.Controller := Controller.ContratosController; end; end; procedure TfEditorFacturaProveedor.SetFactura(const Value: IBizFacturaProveedor); 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 frViewFacturaProveedor1.frViewProveedorFactura1.Proveedor := FFactura.Proveedor; frViewFacturaProveedor1.frViewProveedorFactura1.OnProveedorChanged := OnProveedorChanged; FViewFactura.Factura := FFactura; frViewDetallesFacturaProveedor1.Detalles := FFactura.Detalles; frViewDetallesFacturaProveedor1.Factura := FFactura; //Para poder sacar los descuento del articulos segun el proveedor seleccionado frViewContratosFacturaProveedor1.Contratos := FFactura.Contratos; end; {$IFDEF CONTABILIDAD} frViewListaSubCuentas1.eContabilizar.EditValue := FFactura.IGNORAR_CONTABILIDAD; frViewListaSubCuentas1.ElegirSubCuenta(FFactura.ID_SUBCUENTA); {$ENDIF} end else begin frViewFacturaProveedor1.frViewProveedorFactura1.OnProveedorChanged := NIL; frViewFacturaProveedor1.frViewProveedorFactura1.Proveedor := NIL; dsDataTable.DataTable := NIL; frViewTotales1.DADataSource.DataTable := NIL; frViewTotales1.dsTiposIVA.DataTable := NIL; end end; procedure TfEditorFacturaProveedor.SetViewFactura(const Value: IViewFacturaProveedor); begin FViewFactura := Value; if Assigned(FViewFactura) and Assigned(Factura) then FViewFactura.Factura := Factura; end; end.