unit frm_OrdenesFabricacionEditor;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls,
  Vcl.Buttons, Vcl.ComCtrls, Data.DB, FireDAC.Comp.Client, uAppTheme,
  FireDAC.Stan.Param, uBaseForm, Vcl.Grids, Vcl.DBGrids, FireDAC.Stan.Intf,
  FireDAC.Stan.Option, FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf,
  FireDAC.DApt.Intf, FireDAC.Stan.Async, FireDAC.DApt, FireDAC.Comp.DataSet;

type
  TfrmOrdenesFabricacionEditor = class(TfrmBase)
    pnlCabecera: TPanel;
    lblId: TLabel;
    edtId: TEdit;
    lblFecha: TLabel;
    dtpFecha: TDateTimePicker;
    lblObrador: TLabel;
    cbbObrador: TComboBox;
    lblReceta: TLabel;
    cbbReceta: TComboBox;
    lblNumeroMasas: TLabel;
    edtNumeroMasas: TEdit;
    lblMultiplicador: TLabel;
    edtMultiplicador: TEdit;

    pnlEstadoTaller: TPanel;
    lblTallerTitulo: TLabel;
    lblHoraInicio: TLabel;
    edtHoraInicio: TEdit;
    lblHoraFin: TLabel;
    edtHoraFin: TEdit;
    lblTempObrador: TLabel;
    edtTempObrador: TEdit;
    lblTempMasa: TLabel;
    edtTempMasa: TEdit;
    lblTiempoReal: TLabel;
    edtTiempoReal: TEdit;
    chkOkVisual: TCheckBox;
    lblObservaciones: TLabel;
    edtObservaciones: TEdit;

    mtConsumos: TFDMemTable;
    dsConsumos: TDataSource;

    procedure FormShow(Sender: TObject);
    procedure btnGuardarClick(Sender: TObject);
    procedure btnSalirClick(Sender: TObject);
  protected
    procedure DoAnadir; override;
    procedure DoModificar; override;
  private
    FElaboracionId: string;
    procedure CargarCombos;
    procedure LoadData;
    procedure CargarConsumosLotes;
  public
    property ElaboracionId: string read FElaboracionId write FElaboracionId;
  end;

var
  frmOrdenesFabricacionEditor: TfrmOrdenesFabricacionEditor;

implementation

uses
  dmg_Main;

{$R *.dfm}

procedure TfrmOrdenesFabricacionEditor.FormShow(Sender: TObject);
begin
  inherited;
  CargarCombos;
  if FElaboracionId <> '' then
    LoadData
  else
    DoAnadir;
end;

procedure TfrmOrdenesFabricacionEditor.CargarCombos;
var
  LQry: TFDQuery;
begin
  cbbObrador.Items.Clear;
  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;

    cbbReceta.Items.Clear;
    LQry.Close;
    LQry.SQL.Text := 'SELECT id, descripcion FROM ob_recetas WHERE activo = 1 ORDER BY descripcion';
    LQry.Open;
    while not LQry.Eof do
    begin
      cbbReceta.Items.AddObject(
        LQry.FieldByName('descripcion').AsString,
        TObject(IntPtr(LQry.FieldByName('id').AsInteger))
      );
      LQry.Next;
    end;
  finally
    LQry.Free;
  end;

  if cbbObrador.Items.Count > 0 then
    cbbObrador.ItemIndex := 0;
  if cbbReceta.Items.Count > 0 then
    cbbReceta.ItemIndex := 0;
end;

procedure TfrmOrdenesFabricacionEditor.DoAnadir;
begin
  inherited;
  edtId.Text := '(Nueva)';
  dtpFecha.Date := Date;
  edtNumeroMasas.Text := '1';
  edtMultiplicador.Text := '1.0';
  edtHoraInicio.Text := '';
  edtHoraFin.Text := '';
  edtTempObrador.Text := '';
  edtTempMasa.Text := '';
  edtTiempoReal.Text := '';
  chkOkVisual.Checked := True;
  edtObservaciones.Text := '';

  if cbbObrador.Items.Count > 0 then
    cbbObrador.ItemIndex := 0;
  if cbbReceta.Items.Count > 0 then
    cbbReceta.ItemIndex := 0;

  mtConsumos.Close;
  mtConsumos.FieldDefs.Clear;
  mtConsumos.FieldDefs.Add('id', ftInteger);
  mtConsumos.FieldDefs.Add('materia_prima', ftString, 100);
  mtConsumos.FieldDefs.Add('lote_codigo', ftString, 50);
  mtConsumos.FieldDefs.Add('cantidad', ftFloat);
  mtConsumos.FieldDefs.Add('unidad', ftString, 10);
  mtConsumos.CreateDataSet;

  dsConsumos.DataSet := mtConsumos;
  dbgItems.DataSource := dsConsumos;
end;

procedure TfrmOrdenesFabricacionEditor.DoModificar;
begin
  inherited;
end;

procedure TfrmOrdenesFabricacionEditor.LoadData;
var
  LQry: TFDQuery;
  I: Integer;
  LObradorId, LRecetaId: Integer;
begin
  if (FElaboracionId = '') or (FElaboracionId = '0') then Exit;

  LQry := TFDQuery.Create(nil);
  try
    LQry.Connection := dmgMain.dbConn;
    LQry.SQL.Text := 'SELECT * FROM ob_elaboraciones WHERE id = :id';
    LQry.ParamByName('id').AsString := FElaboracionId;
    LQry.Open;

    if not LQry.IsEmpty then
    begin
      edtId.Text := LQry.FieldByName('id').AsString;
      dtpFecha.Date := LQry.FieldByName('fecha').AsDateTime;
      LObradorId := LQry.FieldByName('id_obrador').AsInteger;
      LRecetaId := LQry.FieldByName('id_receta').AsInteger;
      edtNumeroMasas.Text := LQry.FieldByName('numero_masas').AsString;
      edtMultiplicador.Text := FormatFloat('0.00', LQry.FieldByName('multiplicador').AsFloat);

      edtHoraInicio.Text := LQry.FieldByName('hora_inicio').AsString;
      edtHoraFin.Text := LQry.FieldByName('hora_fin').AsString;
      edtTempObrador.Text := LQry.FieldByName('temp_obrador').AsString;
      edtTempMasa.Text := LQry.FieldByName('temp_masa_final').AsString;
      edtTiempoReal.Text := LQry.FieldByName('tiempo_real_minutos').AsString;
      chkOkVisual.Checked := (LQry.FieldByName('ok_visual').AsInteger = 1);
      edtObservaciones.Text := LQry.FieldByName('observaciones').AsString;

      for I := 0 to cbbObrador.Items.Count - 1 do
      begin
        if Integer(IntPtr(cbbObrador.Items.Objects[I])) = LObradorId then
        begin
          cbbObrador.ItemIndex := I;
          Break;
        end;
      end;

      for I := 0 to cbbReceta.Items.Count - 1 do
      begin
        if Integer(IntPtr(cbbReceta.Items.Objects[I])) = LRecetaId then
        begin
          cbbReceta.ItemIndex := I;
          Break;
        end;
      end;
    end;
  finally
    LQry.Free;
  end;

  CargarConsumosLotes;
end;

procedure TfrmOrdenesFabricacionEditor.CargarConsumosLotes;
var
  LQry: TFDQuery;
begin
  mtConsumos.Close;
  mtConsumos.FieldDefs.Clear;
  mtConsumos.FieldDefs.Add('id', ftInteger);
  mtConsumos.FieldDefs.Add('materia_prima', ftString, 100);
  mtConsumos.FieldDefs.Add('lote_codigo', ftString, 50);
  mtConsumos.FieldDefs.Add('cantidad', ftFloat);
  mtConsumos.FieldDefs.Add('unidad', ftString, 10);
  mtConsumos.CreateDataSet;

  LQry := TFDQuery.Create(nil);
  try
    LQry.Connection := dmgMain.dbConn;
    LQry.SQL.Text :=
      'SELECT c.id, c.cantidad, c.unidad, ' +
      '       COALESCE(emp.descripcion, mp.descripcion, ''Materia Prima'') AS materia_prima, ' +
      '       COALESCE(emp.lote, CAST(c.lote_consumido_id AS CHAR)) AS lote_codigo ' +
      'FROM ob_lotes_consumidos c ' +
      'LEFT JOIN ge_entradas_materias_primas emp ON c.lote_consumido_id = emp.id ' +
      'LEFT JOIN ge_materias_primas mp ON emp.id_materia_prima = mp.id ' +
      'WHERE c.elaboracion_id = :id';
    LQry.ParamByName('id').AsString := FElaboracionId;
    LQry.Open;

    while not LQry.Eof do
    begin
      mtConsumos.Append;
      mtConsumos.FieldByName('id').AsInteger := LQry.FieldByName('id').AsInteger;
      mtConsumos.FieldByName('materia_prima').AsString := LQry.FieldByName('materia_prima').AsString;
      mtConsumos.FieldByName('lote_codigo').AsString := LQry.FieldByName('lote_codigo').AsString;
      mtConsumos.FieldByName('cantidad').AsFloat := LQry.FieldByName('cantidad').AsFloat;
      mtConsumos.FieldByName('unidad').AsString := LQry.FieldByName('unidad').AsString;
      mtConsumos.Post;
      LQry.Next;
    end;
  finally
    LQry.Free;
  end;

  dsConsumos.DataSet := mtConsumos;
  dbgItems.DataSource := dsConsumos;

  dbgItems.Columns.Clear;
  with dbgItems.Columns.Add do
  begin
    FieldName := 'materia_prima';
    Title.Caption := 'Materia Prima Consumida';
    Width := 300;
  end;
  with dbgItems.Columns.Add do
  begin
    FieldName := 'lote_codigo';
    Title.Caption := 'Lote Real';
    Width := 140;
  end;
  with dbgItems.Columns.Add do
  begin
    FieldName := 'cantidad';
    Title.Caption := 'Cantidad Pesada';
    Width := 120;
  end;
  with dbgItems.Columns.Add do
  begin
    FieldName := 'unidad';
    Title.Caption := 'Unidad';
    Width := 70;
  end;
end;

procedure TfrmOrdenesFabricacionEditor.btnGuardarClick(Sender: TObject);
var
  LQry: TFDQuery;
  LObradorId, LRecetaId: Integer;
  LMasas: Integer;
  LMultiplicador: Double;
begin
  if cbbObrador.ItemIndex < 0 then
  begin
    ShowMessage('Debe seleccionar un obrador.');
    Exit;
  end;

  if cbbReceta.ItemIndex < 0 then
  begin
    ShowMessage('Debe seleccionar una receta.');
    Exit;
  end;

  LObradorId := Integer(IntPtr(cbbObrador.Items.Objects[cbbObrador.ItemIndex]));
  LRecetaId := Integer(IntPtr(cbbReceta.Items.Objects[cbbReceta.ItemIndex]));
  LMasas := StrToIntDef(edtNumeroMasas.Text, 1);
  LMultiplicador := StrToFloatDef(StringReplace(edtMultiplicador.Text, ',', '.', [rfReplaceAll]), 1.0);

  LQry := TFDQuery.Create(nil);
  try
    LQry.Connection := dmgMain.dbConn;

    if (FElaboracionId = '') or (FElaboracionId = '(Nueva)') then
    begin
      // INSERT
      LQry.SQL.Text :=
        'INSERT INTO ob_elaboraciones (' +
        '  tipo, fecha, id_obrador, id_receta, lote_id, multiplicador, numero_masas, ' +
        '  observaciones' +
        ') VALUES (' +
        '  ''primer_empaste'', :fecha, :id_obrador, :id_receta, 1, :multiplicador, :numero_masas, ' +
        '  :observaciones' +
        ')';
      LQry.ParamByName('fecha').AsDate := dtpFecha.Date;
      LQry.ParamByName('id_obrador').AsInteger := LObradorId;
      LQry.ParamByName('id_receta').AsInteger := LRecetaId;
      LQry.ParamByName('multiplicador').AsFloat := LMultiplicador;
      LQry.ParamByName('numero_masas').AsInteger := LMasas;
      LQry.ParamByName('observaciones').AsString := edtObservaciones.Text;
      LQry.ExecSQL;
    end
    else
    begin
      // UPDATE
      LQry.SQL.Text :=
        'UPDATE ob_elaboraciones SET ' +
        '  fecha = :fecha, id_obrador = :id_obrador, id_receta = :id_receta, ' +
        '  multiplicador = :multiplicador, numero_masas = :numero_masas, ' +
        '  observaciones = :observaciones ' +
        'WHERE id = :id';
      LQry.ParamByName('id').AsString := FElaboracionId;
      LQry.ParamByName('fecha').AsDate := dtpFecha.Date;
      LQry.ParamByName('id_obrador').AsInteger := LObradorId;
      LQry.ParamByName('id_receta').AsInteger := LRecetaId;
      LQry.ParamByName('multiplicador').AsFloat := LMultiplicador;
      LQry.ParamByName('numero_masas').AsInteger := LMasas;
      LQry.ParamByName('observaciones').AsString := edtObservaciones.Text;
      LQry.ExecSQL;
    end;

    ShowMessage('Orden de fabricación guardada correctamente.');
    ModalResult := mrOk;
  finally
    LQry.Free;
  end;
end;

procedure TfrmOrdenesFabricacionEditor.btnSalirClick(Sender: TObject);
begin
  ModalResult := mrCancel;
end;

end.
