unit frm_EnviosList;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, Vcl.Grids,
  Vcl.DBGrids, Data.DB, Vcl.Buttons, uAppTheme, FireDAC.Stan.Param, FireDAC.Comp.Client,
  frm_BaseList, Vcl.ComCtrls;

type
  TfrmEnviosList = class(TfrmBaseList)
    btnFirmar: TSpeedButton;
    procedure FormShow(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btnRefreshClick(Sender: TObject); override;
    procedure btnNewClick(Sender: TObject); override;
    procedure btnEditClick(Sender: TObject); override;
    procedure btnPrintClick(Sender: TObject); override;
    procedure btnFirmarClick(Sender: TObject);
  private
    chkAnulada: TCheckBox;
  protected
    procedure ApplyAllFilters; override;
  public
    { Public declarations }
  end;

var
  frmEnviosList: TfrmEnviosList;

implementation

uses
  dmg_Main, uDbErrorHandler, frm_FirmaRecogida, frm_AlbaranEnvioEditor,
  frm_SelectPedidoPreparado, frm_EnviosRecogida, Winapi.ShellAPI;

{$R *.dfm}

procedure TfrmEnviosList.FormShow(Sender: TObject);
begin
  DateFilterField := 'fecha_recogida';
  StatusFilterField := 'firmado';
  StatusValues.Clear;
  StatusValues.Add('SÍ');
  StatusValues.Add('NO');

  inherited;
  
  chkAnulada := TCheckBox.Create(Self);
  chkAnulada.Tag := 999;
  chkAnulada.Parent := grpStatuses;
  chkAnulada.Align := alTop;
  chkAnulada.Caption := 'ANULADAS';
  chkAnulada.Checked := False; // Desmarcado por defecto
  chkAnulada.OnClick := StatusFilterClick;
  chkAnulada.Padding.Top := 3;
  chkAnulada.Padding.Bottom := 3;
  
  grpStatuses.Height := grpStatuses.Height + 25;

  if Assigned(rbDateAll) then
    rbDateAll.Checked := True;

  ApplyAllFilters;

  frmEnviosList := Self;
  OnDestroy := FormDestroy;
  pnlSearch.Visible := True;
  lblSearch.Caption := 'Buscar por pedido/código:';
end;

procedure TfrmEnviosList.FormDestroy(Sender: TObject);
begin
  if frmEnviosList = Self then
    frmEnviosList := nil;
end;

procedure TfrmEnviosList.btnRefreshClick(Sender: TObject);
var
  LSql: string;
begin
  if dmgMain.CurrentCompanyId = '' then Exit;

  FQryMain.Close;
  LSql := 'SELECT r.id, COALESCE(p.numero_pedido, '''') as numero_pedido, ' +
          '  COALESCE(t.nombre, '''') as transportista_nombre, r.cod_recogida, ' +
          '  r.fecha_recogida, r.hora_ini, r.hora_fin, r.num_bultos, ' +
          '  r.matricula, r.conductor, r.estado_descripcion, ' +
          '  (CASE WHEN r.firma_imagen IS NOT NULL THEN ''SÍ'' ELSE ''NO'' END) as firmado, ' +
          '  CONCAT(COALESCE(a.serie, ''A''), ''/'', COALESCE(a.numero, '''')) as albaran_numero, ' +
          '  COALESCE(r.persona_contacto, d.descripcion, cli.nombre_fiscal, '''') as cliente_destino ' +
          'FROM ge_envios_recogidas r ' +
          'LEFT JOIN ge_pedidos p ON r.pedido_id = p.id ' +
          'LEFT JOIN ge_envios_config c ON r.config_id = c.id ' +
          'LEFT JOIN ge_envios_transportistas t ON c.transportista_id = t.id ' +
          'LEFT JOIN ge_albaranes a ON r.albaran_id = a.id ' +
          'LEFT JOIN ge_clientes cli ON p.cliente_id = cli.id ' +
          'LEFT JOIN ge_clientes_destinos d ON p.clientedestino_id = d.id ' +
          'WHERE (r.empresa_id = :emp OR r.empresa_id = 0 OR r.empresa_id IS NULL) ';
          
  if Trim(edtSearch.Text) <> '' then
  begin
    LSql := LSql + 'AND (p.numero_pedido LIKE :search OR r.cod_recogida LIKE :search OR r.conductor LIKE :search OR r.matricula LIKE :search OR cli.nombre_fiscal LIKE :search OR r.persona_contacto LIKE :search) ';
  end;
  LSql := LSql + 'ORDER BY r.fecha_recogida DESC, r.id DESC';
  
  FQryMain.SQL.Text := LSql;
  FQryMain.ParamByName('emp').AsString := dmgMain.CurrentCompanyId;
  
  if Trim(edtSearch.Text) <> '' then
    FQryMain.ParamByName('search').AsString := '%' + Trim(edtSearch.Text) + '%';
    
  FQryMain.Open;
  
  dbGridMain.Columns.Clear;
  with dbGridMain.Columns.Add do
  begin
    FieldName := 'albaran_numero';
    Title.Caption := 'Albarán Envío';
    Width := 100;
  end;
  with dbGridMain.Columns.Add do
  begin
    FieldName := 'numero_pedido';
    Title.Caption := 'Pedido';
    Width := 100;
  end;
  with dbGridMain.Columns.Add do
  begin
    FieldName := 'cliente_destino';
    Title.Caption := 'Cliente / Destino';
    Width := 200;
  end;
  with dbGridMain.Columns.Add do
  begin
    FieldName := 'transportista_nombre';
    Title.Caption := 'Transportista';
    Width := 130;
  end;
  with dbGridMain.Columns.Add do
  begin
    FieldName := 'cod_recogida';
    Title.Caption := 'Código Recogida';
    Width := 140;
  end;
  with dbGridMain.Columns.Add do
  begin
    FieldName := 'fecha_recogida';
    Title.Caption := 'Fecha Recogida';
    Width := 100;
  end;
  with dbGridMain.Columns.Add do
  begin
    FieldName := 'num_bultos';
    Title.Caption := 'Bultos';
    Width := 60;
    Alignment := taRightJustify;
  end;
  with dbGridMain.Columns.Add do
  begin
    FieldName := 'conductor';
    Title.Caption := 'Conductor';
    Width := 140;
  end;
  with dbGridMain.Columns.Add do
  begin
    FieldName := 'matricula';
    Title.Caption := 'Matrícula';
    Width := 80;
  end;
  with dbGridMain.Columns.Add do
  begin
    FieldName := 'estado_descripcion';
    Title.Caption := 'Estado';
    Width := 100;
  end;
  with dbGridMain.Columns.Add do
  begin
    FieldName := 'firmado';
    Title.Caption := 'Firmado';
    Width := 70;
    Alignment := taCenter;
  end;
end;

procedure TfrmEnviosList.btnNewClick(Sender: TObject);
var
  LSelect: TfrmSelectPedidoPreparado;
  LPedId: Integer;
begin
  LSelect := TfrmSelectPedidoPreparado.Create(Self);
  try
    if LSelect.ShowModal = mrOk then
    begin
      LPedId := StrToIntDef(LSelect.SelectedId, 0);
      if LPedId > 0 then
      begin
        if not Assigned(frmEnviosRecogida) then
          Application.CreateForm(TfrmEnviosRecogida, frmEnviosRecogida);
          
        frmEnviosRecogida.PedidoId := LPedId;
        if frmEnviosRecogida.ShowModal = mrOk then
          btnRefreshClick(nil);
      end;
    end;
  finally
    LSelect.Free;
  end;
end;

procedure TfrmEnviosList.btnFirmarClick(Sender: TObject);
begin
  if not Assigned(FQryMain) or FQryMain.IsEmpty then
  begin
    ShowMessage('Seleccione un envío del listado para registrar la firma.');
    Exit;
  end;
  
  if not Assigned(frmFirmaRecogida) then
    Application.CreateForm(TfrmFirmaRecogida, frmFirmaRecogida);
    
  frmFirmaRecogida.RecogidaId := FQryMain.FieldByName('id').AsInteger;
  if frmFirmaRecogida.ShowModal = mrOk then
    btnRefreshClick(nil);
end;

procedure TfrmEnviosList.btnEditClick(Sender: TObject);
begin
  if FQryMain.IsEmpty then Exit;
  
  if not Assigned(frmAlbaranEnvioEditor) then
    Application.CreateForm(TfrmAlbaranEnvioEditor, frmAlbaranEnvioEditor);
    
  frmAlbaranEnvioEditor.RecogidaId := FQryMain.FieldByName('id').AsInteger;
  frmAlbaranEnvioEditor.ShowModal;
  btnRefreshClick(nil);
end;

procedure TfrmEnviosList.btnPrintClick(Sender: TObject);
var
  QryMaster, QryDetail: TFDQuery;
  LReportPath: string;
begin
  if FQryMain.IsEmpty then Exit;

  QryMaster := TFDQuery.Create(nil);
  QryDetail := TFDQuery.Create(nil);
  try
    QryMaster.Connection := dmgMain.dbConn;
    QryMaster.SQL.Text := 
      'SELECT r.cod_recogida, COALESCE(t.nombre, '''') AS transportista_nombre, COALESCE(p.numero_pedido, '''') as numero_pedido, ' +
      '       COALESCE(p.numero_pedido, '''') AS albaran_numero, r.fecha_recogida, ' +
      '       CONCAT(TIME_FORMAT(r.hora_ini, ''%H:%i''), '' - '', TIME_FORMAT(r.hora_fin, ''%H:%i'')) AS hora_ini_fin, ' +
      '       r.num_bultos, COALESCE(r.persona_contacto, c.nombre_fiscal, '''') AS cliente_nombre, ' +
      '       COALESCE(r.direccion, d.direccion, c.domicilio, '''') AS cliente_direccion, ' +
      '       COALESCE(r.cp, d.cp, c.codigo_postal, '''') AS cliente_cp, ' +
      '       COALESCE(r.telefono, c.telefono, '''') AS cliente_telefono, r.persona_contacto AS cliente_contacto ' +
      'FROM ge_envios_recogidas r ' +
      'LEFT JOIN ge_pedidos p ON r.pedido_id = p.id ' +
      'LEFT JOIN ge_envios_config ec ON r.config_id = ec.id ' +
      'LEFT JOIN ge_envios_transportistas t ON ec.transportista_id = t.id ' +
      'LEFT JOIN ge_clientes c ON p.cliente_id = c.id ' +
      'LEFT JOIN ge_clientes_destinos d ON p.clientedestino_id = d.id ' +
      'WHERE r.id = :id';
    QryMaster.ParamByName('id').AsInteger := FQryMain.FieldByName('id').AsInteger;
    QryMaster.Open;
    
    QryDetail.Connection := dmgMain.dbConn;
    QryDetail.SQL.Text := 
      'SELECT pl.descripcion, pl.cantidad ' +
      'FROM ge_pedidos_lineas pl ' +
      'JOIN ge_envios_recogidas r ON r.pedido_id = pl.id_pedido ' +
      'WHERE r.id = :id';
    QryDetail.ParamByName('id').AsInteger := FQryMain.FieldByName('id').AsInteger;
    QryDetail.Open;

    LReportPath := ExtractFilePath(ParamStr(0)) + 'reportes\AlbaranCarga.fr3';
    if not FileExists(LReportPath) then
    begin
      LReportPath := ExtractFilePath(ParamStr(0)) + '..\reportes\AlbaranCarga.fr3';
      if not FileExists(LReportPath) then
        LReportPath := 'reportes\AlbaranCarga.fr3';
    end;
    
    dmgMain.frxInforme.LoadFromFile(LReportPath);
    
    dmgMain.frxDBMaster.DataSet := QryMaster;
    dmgMain.frxDBDetalle.DataSet := QryDetail;
    
    dmgMain.frxInforme.DataSets.Clear;
    dmgMain.frxInforme.DataSets.Add(dmgMain.frxDBMaster);
    dmgMain.frxInforme.DataSets.Add(dmgMain.frxDBDetalle);
    
    dmgMain.frxInforme.EnabledDataSets.Clear;
    dmgMain.frxInforme.EnabledDataSets.Add(dmgMain.frxDBMaster);
    dmgMain.frxInforme.EnabledDataSets.Add(dmgMain.frxDBDetalle);
    
    dmgMain.frxInforme.ShowReport;
  finally
    QryMaster.Free;
    QryDetail.Free;
  end;
end;

procedure TfrmEnviosList.ApplyAllFilters;
begin
  inherited ApplyAllFilters;

  if not Assigned(FQryMain) or not FQryMain.Active then Exit;

  // Si no está marcado "ANULADAS", excluir las anuladas del filtro
  if Assigned(chkAnulada) and not chkAnulada.Checked then
  begin
    if FQryMain.Filter <> '' then
      FQryMain.Filter := '(' + FQryMain.Filter + ') AND (estado_descripcion <> ''ANULADA'')'
    else
    begin
      FQryMain.Filter := '(estado_descripcion <> ''ANULADA'')';
      FQryMain.Filtered := True;
    end;
    lblRecordCount.Caption := Format('Registros: %d', [FQryMain.RecordCount]);
  end;
end;

end.
