unit uEditorReciboCliente; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, uEditorDBItem, JvAppStorage, JvAppRegistryStorage, DB, uDADataTable, JvComponentBase, JvFormPlacement, ImgList, PngImageList, StdActns, ActnList, ComCtrls, JvExComCtrls, JvStatusBar, TBX, TB2Item, TB2Dock, TB2Toolbar, pngimage, ExtCtrls, JvExControls, JvComponent, JvNavigationPane, uIEditorReciboCliente, uCustomView, uViewBase, uViewReciboCliente, uRecibosClienteController, uBizRecibosCliente, uViewPagosCliente, dxLayoutLookAndFeels, cxCustomData, uViewDetallesGenerico, uViewReciboCliImportes, uViewRecibosCliCompensados, uDAInterfaces, StdCtrls; type TfEditorReciboCliente = class(TfEditorDBItem, IEditorReciboCliente) DADataSource1: TDADataSource; frViewReciboCliente1: TfrViewReciboCliente; pagCompensados: TTabSheet; pagPagos: TTabSheet; frViewPagosCliente1: TfrViewPagosCliente; frViewRecibosCliCompensados1: TfrViewRecibosCliCompensados; frViewReciboCliImportes1: TfrViewReciboCliImportes; procedure FormShow(Sender: TObject); procedure dsDataTableDataChange(Sender: TObject; Field: TField); procedure CustomEditorClose(Sender: TObject; var Action: TCloseAction); procedure frViewReciboCliente1eImportePropertiesValidate(Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); procedure frViewPagosCliente1actAnadirExecute(Sender: TObject); procedure frViewPagosCliente1actEliminarExecute(Sender: TObject); procedure frViewPagosCliente1actEliminarUpdate(Sender: TObject); procedure frViewPagosCliente1actModificarUpdate(Sender: TObject); procedure frViewPagosCliente1actModificarExecute(Sender: TObject); procedure HabilitarRecibo; procedure DeshabilitarRecibo; procedure JvFormStorageRestorePlacement(Sender: TObject); procedure JvFormStorageSavePlacement(Sender: TObject); procedure frViewReciboCliImportes1eImportePropertiesEditValueChanged(Sender: TObject); procedure frViewRecibosCompensados1cxGridViewDataControllerSummaryAfterSummary(ASender: TcxDataSummary); procedure frViewPagosCliente1actAnadirUpdate(Sender: TObject); procedure pgPaginasChanging(Sender: TObject; var AllowChange: Boolean); private FController : IRecibosClienteController; FRecibo: IBizRecibosCliente; FViewRecibo : IViewReciboCliente; FImporteRestante : Double; function GetController : IRecibosClienteController; procedure SetController (const Value : IRecibosClienteController); virtual; function GetRecibo: IBizRecibosCliente; procedure SetRecibo(const Value: IBizRecibosCliente); function GetViewRecibo: IViewReciboCliente; procedure SetViewRecibo(const Value: IViewReciboCliente); property ViewRecibo: IViewReciboCliente read GetViewRecibo write SetViewRecibo; procedure CalcularTotal; protected procedure PrevisualizarInterno; override; procedure ImprimirInterno; override; procedure GuardarInterno; override; procedure PonerTitulos(const ATitulo: string = ''); override; procedure OnClienteChanged(Sender: TObject); function PuedoImprimir: Boolean; override; public property Recibo: IBizRecibosCliente read GetRecibo write SetRecibo; constructor Create(AOwner: TComponent); override; end; implementation uses uDialogUtils, schRecibosClienteClient_Intf, uEditorFechaPago, uEditorBase, uFactuGES_App, uBizEjercicios, uClientesController, uBizDireccionesContacto, uViewClienteRecibo; {$R *.dfm} procedure TfEditorReciboCliente.CalcularTotal; var ImporteAux: Double; EnEdicion: Boolean; begin ImporteAux := 0; if not VarIsNull(frViewRecibosCliCompensados1.cxGridView.DataController.Summary.FooterSummaryValues[0]) then ImporteAux := frViewRecibosCliCompensados1.cxGridView.DataController.Summary.FooterSummaryValues[0]; frViewReciboCliImportes1.eImporteTotalRecibo.Value := frViewReciboCliImportes1.eImporte.Value + frViewReciboCliImportes1.eOtrosGastos.Value + ImporteAux; end; constructor TfEditorReciboCliente.Create(AOwner: TComponent); begin inherited; FImporteRestante := 0; pgPaginas.ActivePageIndex := 0; //RECIBOS COMPENSADOS DESHABILITADOS pagCompensados.TabVisible := False; pagPagos.TabVisible := False; ViewRecibo := frViewReciboCliente1; end; procedure TfEditorReciboCliente.CustomEditorClose(Sender: TObject; var Action: TCloseAction); begin inherited; dsDataTable.DataTable := NIL; FViewRecibo := NIL; FRecibo := NIL; end; procedure TfEditorReciboCliente.DeshabilitarRecibo; begin frViewReciboCliente1.edtFechaVencimiento.Enabled := False; frViewReciboCliImportes1.eImporte.Enabled := False; frViewReciboCliImportes1.eOtrosGastos.Enabled := False; end; procedure TfEditorReciboCliente.dsDataTableDataChange(Sender: TObject; Field: TField); begin inherited; if Assigned(FRecibo) and (not (FRecibo.DataTable.Fetching) or not (FRecibo.DataTable.Opening) or not (FRecibo.DataTable.Closing)) then PonerTitulos; end; procedure TfEditorReciboCliente.FormShow(Sender: TObject); begin inherited; if not Assigned(FViewRecibo) then raise Exception.Create('No hay ninguna vista asignada'); if not Assigned(Recibo) then raise Exception.Create('No hay ningún almacén asignado'); Recibo.DataTable.Active := True; Recibo.Pagos.Last; //Nos posicionamos siempre en el último pago CalcularTotal; end; function TfEditorReciboCliente.PuedoImprimir: Boolean; begin Result := inherited PuedoImprimir and (not Recibo.Cliente.IDIsNull); end; procedure TfEditorReciboCliente.frViewPagosCliente1actAnadirExecute(Sender: TObject); var AFechaPago: String; AIgnorarContabilidad: Integer; AIdSubCuenta: Integer; ASubCuenta: String; begin inherited; if (Length(Recibo.REFERENCIA_REMESA) = 0) or (Application.MessageBox(PChar('Este recibo está remesado en la remesa de referencia ' + Recibo.REFERENCIA_REMESA + '.' + #10#13 + 'Si añade una devolución, el recibo quedará libre y podrá ser incluido en otra remesa diferente.' + #10#13 + '¿Desea continuar?'), 'Atención', MB_YESNO) = IDYES) then begin with TfEditorFechaPago.Create(Nil) do try //En el caso de que el cliente del recibo no tenga aignada subcuenta contable el pago no podrá contabilizarse if (Recibo.Cliente.SubCuentas.ID < 1) then begin IgnorarContabilidad := 1; DeshabilitarContabilidad; end; if (ShowModal = mrOk) then begin AFechaPago := DateToStr(FechaPago); AIgnorarContabilidad := IgnorarContabilidad; AIdSubCuenta := IdSubcuenta; ASubcuenta := frViewListaSubcuentas1.cbSubCuentas.Text; end finally Release; end; end; FController.AnadirPago(Recibo, AFechaPago, AIgnorarContabilidad, AIdSubCuenta, ASubCuenta); //Solo podremos modificar el recibo si esta pendiente o devuelto if (Recibo.SITUACION = CTE_COBRADO) then DeshabilitarRecibo else HabilitarRecibo; frViewPagosCliente1.ListaPagosClienteDBTableView1.DataController.GotoLast; end; procedure TfEditorReciboCliente.frViewPagosCliente1actAnadirUpdate(Sender: TObject); begin inherited; (Sender as TAction).Enabled := not (Recibo.ID_RECIBO_COMPENSADO > 0) and (FRecibo.Pagos.DataTable.RecordCount < 1) end; procedure TfEditorReciboCliente.frViewPagosCliente1actEliminarExecute(Sender: TObject); begin inherited; //En el caso de eliminar un pago el recibo queda como devuelto o pendiente y por tanto se puede modificar if (FController.EliminarPago(Recibo)) then begin FRecibo.Edit; if FRecibo.Pagos.DataTable.RecordCount > 0 then FRecibo.SITUACION := CTE_DEVUELTO else FRecibo.SITUACION := CTE_PENDIENTE; HabilitarRecibo; end //No podremos modificar si anulamos una devolución porque el recibo queda cobrado else begin FRecibo.Edit; FRecibo.SITUACION := CTE_COBRADO; DeshabilitarRecibo; end; frViewPagosCliente1.ListaPagosClienteDBTableView1.DataController.GotoLast; end; procedure TfEditorReciboCliente.frViewPagosCliente1actEliminarUpdate(Sender: TObject); begin if Assigned(FRecibo) and Assigned(FRecibo.Pagos) then begin //Si el recibo tiene una remesa asociada, el cobro generado por la remesa no se podrá eliminar if (Length(FRecibo.REFERENCIA_REMESA) = 0) then frViewPagosCliente1.actEliminar.Enabled := (FRecibo.Pagos.DataTable.RecordCount > 0) else //En el caso de que el recibo este remesado no se podrán eliminar pagos, //solo será posible en el caso de ser un recibo libre de remesa frViewPagosCliente1.actEliminar .Enabled := False; end; end; procedure TfEditorReciboCliente.frViewPagosCliente1actModificarExecute(Sender: TObject); var AFechaPago: String; AIgnorarContabilidad: Integer; AIdSubCuenta: Integer; ASubCuenta: String; begin inherited; with TfEditorFechaPago.Create(Nil) do try FechaPago := Recibo.Pagos.FECHA_PAGO; IgnorarContabilidad := Recibo.Pagos.IGNORAR_CONTABILIDAD; if IgnorarContabilidad = 0 then IdSubCuenta := StrToInt(Recibo.Pagos.CUENTA); //En el caso de que el cliente del recibo no tenga aignada subcuenta contable el pago no podrá contabilizarse if (Recibo.Cliente.SubCuentas.ID < 1) then begin IgnorarContabilidad := 1; DeshabilitarContabilidad; end; //En el caso de que el ejercicio asociado al asiento del pago este cerrado o el asiento punteado //se podrá o no modificar el pago. if (Recibo.Pagos.ESTADO_EJERCICIO = CTE_CERRADO) then begin Comentario := 'El asiento asociado a este pago tiene el ejercicio cerrado, por lo que no se puede modificar'; SoloLectura := true; end else if (Recibo.Pagos.ASIENTO_PUNTEADO > 0) then begin Comentario := 'El asiento asociado a este pago esta punteado, por lo que no se puede modificar'; SoloLectura := true; end; if (ShowModal = mrOk) then begin AFechaPago := DateToStr(FechaPago); AIgnorarContabilidad := IgnorarContabilidad; AIdSubCuenta := IdSubcuenta; ASubcuenta := frViewListaSubcuentas1.cbSubCuentas.Text; if not SoloLectura then FController.ModificarPago(Recibo, AFechaPago, AIgnorarContabilidad, AIdSubCuenta, ASubcuenta); end; finally Release; end; end; procedure TfEditorReciboCliente.frViewPagosCliente1actModificarUpdate(Sender: TObject); begin inherited; //Si el ejercicio al que pertenece la factura esta cerrado no se podrá modificar if Assigned(FRecibo) and Assigned(FRecibo.Pagos) then frViewPagosCliente1.actModificar.Enabled := (FRecibo.Pagos.DataTable.RecordCount > 0) end; procedure TfEditorReciboCliente.frViewReciboCliente1eImportePropertiesValidate( Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); begin inherited; if (DisplayValue > frViewReciboCliImportes1.eImporte.DataBinding.Field.Value) then begin DisplayValue := frViewReciboCliImportes1.eImporte.DataBinding.Field.Value; ErrorText := 'El importe debe ser menor o igual que el actual'; Error := True; end; end; procedure TfEditorReciboCliente.frViewReciboCliImportes1eImportePropertiesEditValueChanged( Sender: TObject); begin inherited; CalcularTotal; end; procedure TfEditorReciboCliente.frViewRecibosCompensados1cxGridViewDataControllerSummaryAfterSummary(ASender: TcxDataSummary); begin inherited; CalcularTotal; end; function TfEditorReciboCliente.GetController: IRecibosClienteController; begin Result := FController; end; function TfEditorReciboCliente.GetRecibo: IBizRecibosCliente; begin Result := FRecibo; end; function TfEditorReciboCliente.GetViewRecibo: IViewReciboCliente; begin Result := FViewRecibo; end; procedure TfEditorReciboCliente.GuardarInterno; begin inherited; FController.Guardar(FRecibo); Modified := False; end; procedure TfEditorReciboCliente.HabilitarRecibo; begin //Si el recibo tiene sociado una remesa no se podrá cambiar nada if (Length(FRecibo.REFERENCIA_REMESA) = 0) then begin frViewReciboCliente1.edtFechaVencimiento.Enabled := True; frViewReciboCliImportes1.eImporte.Enabled := True; frViewReciboCliImportes1.eOtrosGastos.Enabled := True; end; end; procedure TfEditorReciboCliente.ImprimirInterno; begin inherited; FController.Print(FRecibo); end; procedure TfEditorReciboCliente.JvFormStorageRestorePlacement(Sender: TObject); begin inherited; frViewPagosCliente1.ListaPagosCliente.ActiveView.RestoreFromRegistry(JvAppRegistryStorage.Root); end; procedure TfEditorReciboCliente.JvFormStorageSavePlacement(Sender: TObject); begin inherited; frViewPagosCliente1.ListaPagosCliente.ActiveView.StoreToRegistry(JvAppRegistryStorage.Root); end; procedure TfEditorReciboCliente.OnClienteChanged(Sender: TObject); var AClientesController : IClientesController; ADireccion : IBizDireccionesContacto; begin FRecibo.Cliente := frViewReciboCliente1.frViewClienteRecibo1.Cliente; if not (FRecibo.DataTable.State in dsEditModes) then FRecibo.DataTable.Edit; // En el caso de tener direcciones asociadas, se debe dar la posibilidad de elegir la dirección principal o las secundarias para el recibo AClientesController := TClientesController.Create; try case FRecibo.Cliente.Direcciones.RecordCount of 0 : //No hay direcciones secundarias asociadas else ADireccion := AClientesController.ElegirDireccion(FRecibo.Cliente, 'Seleccione la dirección del cliente que quiere utilizar como dirección fiscal de este recibo.'); end; // Si hay dirección seleccionada, copiarla al albarán y poner el coste del porte if Assigned(ADireccion) then begin if not ADireccion.IDIsNull then try FRecibo.Edit; FController.CopiarDireccion(ADireccion, FRecibo); finally ADireccion := NIL; end; end finally AClientesController := Nil; end; end; procedure TfEditorReciboCliente.pgPaginasChanging(Sender: TObject; var AllowChange: Boolean); begin inherited; if (not Assigned(FRecibo)) or (FRecibo.ID_CLIENTE = 0) then begin ShowWarningMessage('Antes de introducir los pagos debe elegir un cliente para este recibo'); AllowChange := False; end; end; procedure TfEditorReciboCliente.PonerTitulos(const ATitulo: string); var FTitulo : String; begin if Assigned(Recibo) then begin if Recibo.EsNuevo then begin if Recibo.SinFactura then FTitulo := 'Nuevo recibo libre de cliente' else FTitulo := 'Nuevo recibo de factura de cliente' end else begin if Recibo.SinFactura then FTitulo := 'Recibo libre de cliente' else FTitulo := 'Recibo de factura de cliente' end; if (Recibo.ID_RECIBO_COMPENSADO > 0) then FTitulo := FTitulo + ' (compensado)'; if Length(Recibo.NOMBRE_CLIENTE) > 0 then FTitulo := FTitulo + ' - ' + Recibo.NOMBRE_CLIENTE; end; inherited PonerTitulos(FTitulo); end; procedure TfEditorReciboCliente.PrevisualizarInterno; begin inherited; FController.Preview(FRecibo); end; procedure TfEditorReciboCliente.SetController(const Value: IRecibosClienteController); begin FController := Value; if Assigned(FController) then begin frViewRecibosCliCompensados1.Controller := FController; (ViewRecibo as IViewReciboCliente).Controller := (FController as IRecibosClienteController); end; end; procedure TfEditorReciboCliente.SetRecibo(const Value: IBizRecibosCliente); begin FRecibo := Value; dsDataTable.DataTable := FRecibo.DataTable; if Assigned(FViewRecibo) and Assigned(Recibo) then begin FViewRecibo.Recibo := Recibo; frViewReciboCliente1.frViewClienteRecibo1.Cliente := FRecibo.Cliente; frViewReciboCliente1.frViewClienteRecibo1.OnClienteChanged := OnClienteChanged; frViewPagosCliente1.Pagos := Recibo.Pagos; frViewRecibosCliCompensados1.ReciboCliente := FRecibo; if FRecibo.EsNuevo and FRecibo.SinFactura then FRecibo.FECHA_VENCIMIENTO := Date; if (FRecibo.SITUACION = CTE_COBRADO) then DeshabilitarRecibo else HabilitarRecibo; end; end; procedure TfEditorReciboCliente.SetViewRecibo(const Value: IViewReciboCliente); begin FViewRecibo := Value; if Assigned(FViewRecibo) and Assigned(Recibo) then FViewRecibo.Recibo := Recibo; end; end.