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, SpTBXItem, TB2Item, TB2Dock, TB2Toolbar,
  pngimage, ExtCtrls, JvExControls, JvComponent, JvNavigationPane, uIEditorReciboCliente,
  uCustomView, uViewBase, uViewReciboCliente, uRecibosClienteController,
  uBizRecibosCliente, uViewPagosCliente, dxLayoutLookAndFeels, cxCustomData,
  uViewDetallesGenerico, uViewReciboCliImportes, uViewRecibosCliCompensados,
  uDAInterfaces, cxControls, cxContainer, cxEdit, cxLabel;

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);

  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;

  public
    property Recibo: IBizRecibosCliente read GetRecibo write SetRecibo;
    constructor Create(AOwner: TComponent); override;
  end;

implementation

uses schRecibosClienteClient_Intf, uEditorFechaPago, uEditorBase, uFactuGES_App;

{$R *.dfm}

procedure TfEditorReciboCliente.CalcularTotal;
var
  ImporteAux: Double;
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;
  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;
  CalcularTotal;
end;

procedure TfEditorReciboCliente.frViewPagosCliente1actAnadirExecute(Sender: TObject);
begin
  inherited;

  FController.AnadirPago(Recibo);

  //Solo podremos modificar el recibo si esta pendiente o devuelto
  if (Recibo.SITUACION = CTE_COBRADO) then
     DeshabilitarRecibo
  else
     HabilitarRecibo;
end;

procedure TfEditorReciboCliente.frViewPagosCliente1actAnadirUpdate(Sender: TObject);
begin
  inherited;
  (Sender as TAction).Enabled := not (Recibo.ID_RECIBO_COMPENSADO > 0);
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;
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);
begin
  inherited;
  FController.ModificarPago(Recibo);
end;

procedure TfEditorReciboCliente.frViewPagosCliente1actModificarUpdate(Sender: TObject);
begin
  inherited;
  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.PonerTitulos(const ATitulo: string);
var
  FTitulo : String;
begin
  if Assigned(Recibo) then
  begin
    if Recibo.EsNuevo then
      FTitulo := 'Nuevo recibo de cliente'
    else
      FTitulo := 'Recibo de cliente';

    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
     frViewRecibosCliCompensados1.Controller := FController;
//    (ViewRecibo as IViewReciboCliente).Controller := (FController as IRecibosClienteController);
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;
    frViewPagosCliente1.Pagos := Recibo.Pagos;
    frViewRecibosCliCompensados1.ReciboCliente := FRecibo;

    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.
