unit frm_MonitorFabricacion;

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, Vcl.ComCtrls, Vcl.Buttons, Data.DB, FireDAC.Comp.Client,
  FireDAC.Stan.Param;

type
  TfrmMonitorFabricacion = class(TForm)
    pnlTop: TPanel;
    lblTitle: TLabel;
    pnlFiltros: TPanel;
    lblFecha: TLabel;
    dtpFecha: TDateTimePicker;
    lblObrador: TLabel;
    cbbObrador: TComboBox;
    btnRefrescar: TSpeedButton;
    chkAutoRefresh: TCheckBox;
    pnlKPIs: TPanel;
    pnlKpiTotal: TPanel;
    lblKpiTotalNum: TLabel;
    lblKpiTotalTit: TLabel;
    pnlKpiPend: TPanel;
    lblKpiPendNum: TLabel;
    lblKpiPendTit: TLabel;
    pnlKpiAmasando: TPanel;
    lblKpiAmasandoNum: TLabel;
    lblKpiAmasandoTit: TLabel;
    pnlKpiFin: TPanel;
    lblKpiFinNum: TLabel;
    lblKpiFinTit: TLabel;
    pnlGrid: TPanel;
    dbgMonitor: TDBGrid;
    dsMonitor: TDataSource;
    qryMonitor: TFDQuery;
    tmrAutoRefresh: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btnRefrescarClick(Sender: TObject);
    procedure chkAutoRefreshClick(Sender: TObject);
    procedure tmrAutoRefreshTimer(Sender: TObject);
    procedure dtpFechaChange(Sender: TObject);
    procedure cbbObradorChange(Sender: TObject);
    procedure dbgMonitorDblClick(Sender: TObject);
    procedure dbgMonitorDrawColumnCell(Sender: TObject; const Rect: TRect;
      DataCol: Integer; Column: TColumn; State: TGridDrawState);
  private
    procedure CargarObradores;
    procedure CargarDatosMonitor;
    procedure CalcularKPIs;
  public
  end;

var
  frmMonitorFabricacion: TfrmMonitorFabricacion;

implementation

uses
  dmg_Main, frm_OrdenesFabricacionEditor;

{$R *.dfm}

procedure TfrmMonitorFabricacion.FormCreate(Sender: TObject);
begin
  Tag := 999;
  dtpFecha.Tag := 999;
  cbbObrador.Tag := 999;
  chkAutoRefresh.Tag := 999;
  btnRefrescar.Tag := 999;

  dtpFecha.Date := Date;
  CargarObradores;
end;

procedure TfrmMonitorFabricacion.FormShow(Sender: TObject);
begin
  CargarDatosMonitor;
end;

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

procedure TfrmMonitorFabricacion.CargarObradores;
var
  LQry: TFDQuery;
begin
  cbbObrador.Items.Clear;
  cbbObrador.Items.AddObject('TODOS LOS OBRADORES', TObject(IntPtr(0)));

  LQry := TFDQuery.Create(nil);
  try
    LQry.Connection := dmgMain.dbConn;
    LQry.SQL.Text := 'SELECT id, nombre FROM ge_obradores ORDER BY nombre';
    LQry.Open;
    while not LQry.Eof do
    begin
      cbbObrador.Items.AddObject(
        LQry.FieldByName('nombre').AsString,
        TObject(IntPtr(LQry.FieldByName('id').AsInteger))
      );
      LQry.Next;
    end;
  finally
    LQry.Free;
  end;

  cbbObrador.ItemIndex := 0;
end;

procedure TfrmMonitorFabricacion.CargarDatosMonitor;
var
  LSql: string;
  LObradorId: Integer;
begin
  LObradorId := 0;
  if cbbObrador.ItemIndex > 0 then
    LObradorId := Integer(IntPtr(cbbObrador.Items.Objects[cbbObrador.ItemIndex]));

  qryMonitor.DisableControls;
  try
    qryMonitor.Close;
    qryMonitor.Connection := dmgMain.dbConn;
    LSql :=
      'SELECT e.id, e.fecha, o.nombre AS obrador_nombre, ' +
      '       r.descripcion AS receta_nombre, ' +
      '       e.numero_masas, e.multiplicador, ' +
      '       e.hora_inicio, e.hora_fin, e.temp_obrador, e.temp_masa_final, ' +
      '       e.tiempo_real_minutos, e.ok_visual, e.observaciones, ' +
      '       CASE ' +
      '         WHEN e.hora_fin IS NOT NULL THEN ''FINALIZADA'' ' +
      '         WHEN e.hora_inicio IS NOT NULL THEN ''EN AMASADO'' ' +
      '         ELSE ''PENDIENTE'' ' +
      '       END AS estado_nombre, ' +
      '       (SELECT COUNT(*) FROM ob_lotes_consumidos c WHERE c.elaboracion_id = e.id) AS consumos_count ' +
      'FROM ob_elaboraciones e ' +
      'LEFT JOIN ob_recetas r ON e.id_receta = r.id ' +
      'LEFT JOIN ge_obradores o ON e.id_obrador = o.id ' +
      'WHERE e.fecha = :fecha ';

    if LObradorId > 0 then
      LSql := LSql + 'AND e.id_obrador = :obrador ';

    LSql := LSql + 'ORDER BY CASE ' +
      '  WHEN e.hora_inicio IS NOT NULL AND e.hora_fin IS NULL THEN 1 ' +
      '  WHEN e.hora_inicio IS NULL THEN 2 ' +
      '  ELSE 3 END, e.id DESC';

    qryMonitor.SQL.Text := LSql;
    qryMonitor.ParamByName('fecha').AsDate := dtpFecha.Date;
    if LObradorId > 0 then
      qryMonitor.ParamByName('obrador').AsInteger := LObradorId;

    qryMonitor.Open;
    CalcularKPIs;
  finally
    qryMonitor.EnableControls;
  end;
end;

procedure TfrmMonitorFabricacion.CalcularKPIs;
var
  LTotal, LPend, LAmasando, LFin: Integer;
begin
  LTotal := 0;
  LPend := 0;
  LAmasando := 0;
  LFin := 0;

  qryMonitor.First;
  while not qryMonitor.Eof do
  begin
    Inc(LTotal);
    if qryMonitor.FieldByName('estado_nombre').AsString = 'PENDIENTE' then
      Inc(LPend)
    else if qryMonitor.FieldByName('estado_nombre').AsString = 'EN AMASADO' then
      Inc(LAmasando)
    else if qryMonitor.FieldByName('estado_nombre').AsString = 'FINALIZADA' then
      Inc(LFin);

    qryMonitor.Next;
  end;

  lblKpiTotalNum.Caption := IntToStr(LTotal);
  lblKpiPendNum.Caption := IntToStr(LPend);
  lblKpiAmasandoNum.Caption := IntToStr(LAmasando);
  lblKpiFinNum.Caption := IntToStr(LFin);
end;

procedure TfrmMonitorFabricacion.btnRefrescarClick(Sender: TObject);
begin
  CargarDatosMonitor;
end;

procedure TfrmMonitorFabricacion.dtpFechaChange(Sender: TObject);
begin
  CargarDatosMonitor;
end;

procedure TfrmMonitorFabricacion.cbbObradorChange(Sender: TObject);
begin
  CargarDatosMonitor;
end;

procedure TfrmMonitorFabricacion.chkAutoRefreshClick(Sender: TObject);
begin
  tmrAutoRefresh.Enabled := chkAutoRefresh.Checked;
end;

procedure TfrmMonitorFabricacion.tmrAutoRefreshTimer(Sender: TObject);
begin
  CargarDatosMonitor;
end;

procedure TfrmMonitorFabricacion.dbgMonitorDblClick(Sender: TObject);
begin
  if qryMonitor.IsEmpty then Exit;

  if not Assigned(frmOrdenesFabricacionEditor) then
    Application.CreateForm(TfrmOrdenesFabricacionEditor, frmOrdenesFabricacionEditor);

  frmOrdenesFabricacionEditor.ElaboracionId := qryMonitor.FieldByName('id').AsString;
  if frmOrdenesFabricacionEditor.ShowModal = mrOk then
    CargarDatosMonitor;
end;

procedure TfrmMonitorFabricacion.dbgMonitorDrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
  LEstado: string;
begin
  if qryMonitor.Active and not qryMonitor.IsEmpty then
  begin
    LEstado := qryMonitor.FieldByName('estado_nombre').AsString;
    if Column.FieldName = 'estado_nombre' then
    begin
      if LEstado = 'PENDIENTE' then
      begin
        dbgMonitor.Canvas.Brush.Color := $00E0E0E0;
        dbgMonitor.Canvas.Font.Color := clBlack;
      end
      else if LEstado = 'EN AMASADO' then
      begin
        dbgMonitor.Canvas.Brush.Color := $00FFF3D6;
        dbgMonitor.Canvas.Font.Color := $00663300;
      end
      else if LEstado = 'FINALIZADA' then
      begin
        dbgMonitor.Canvas.Brush.Color := $00D4FCD4;
        dbgMonitor.Canvas.Font.Color := $00004400;
      end;
    end;
  end;

  dbgMonitor.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;

end.
