unit uViewDetallesPresupuestoCliente;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, uViewDetallesArticulos, cxStyles, cxCustomData, cxGraphics, cxFilter,
  cxData, cxDataStorage, cxEdit, DB, cxDBData, ImgList, PngImageList,
  uDADataTable, ActnList, ComCtrls, ToolWin, cxGridLevel, cxClasses, cxControls,
  cxGridCustomView, cxGridCustomTableView, cxGridTableView, cxGridDBTableView,
  cxGrid, cxImageComboBox, cxTextEdit, cxMaskEdit, cxCheckBox, cxCurrencyEdit,
  Grids, DBGrids, StdCtrls, ExtCtrls, cxRichEdit, ExtActns, StdActns,
  JvExStdCtrls, JvCombobox, JvColorCombo, TB2Item, TBX, TB2Dock, TB2Toolbar,
  uControllerDetallesArticulos, uBizPresupuestosCliente, uDAInterfaces, Buttons,
  Mask, DBCtrls, cxButtonEdit, cxDropDownEdit, Menus, cxGridCustomPopupMenu,
  cxGridPopupMenu, cxDBLookupComboBox, cxCalc, cxEditRepositoryItems,
  cxContainer, cxLookupEdit, cxDBLookupEdit, uBizDetallesPresupuestoCliente,
  cxMemo, cxDBEditRepository, cxExtEditRepositoryItems;

type
  IViewDetallesPresupuestoCliente = interface(IViewDetallesArticulos)
  ['{3AF39FF4-291E-4E87-AF9A-93C240A744CD}']
    function GetPresupuesto: IBizPresupuestoCliente;
    procedure SetPresupuesto(const Value: IBizPresupuestoCliente);
    property Presupuesto: IBizPresupuestoCliente read GetPresupuesto write SetPresupuesto;
  end;

  TfrViewDetallesPresupuestoCliente = class(TfrViewDetallesArticulos, IViewDetallesPresupuestoCliente)
    actAsignarDescuento: TAction;
    TBXItem18: TTBXItem;
    TBXSeparatorItem9: TTBXSeparatorItem;
    DAPropiedades: TDADataSource;
    cxLookupComboBox1: TcxLookupComboBox;
    DAValores: TDADataSource;
    cxRichEdit1: TcxRichEdit;
    cxGridViewTIPO_ARTICULO: TcxGridDBColumn;
    TBXSubmenuItem1: TTBXSubmenuItem;
    TBXSeparatorItem6: TTBXSeparatorItem;
    TBXItem14: TTBXItem;
    actCapituloCocina: TAction;
    actCapituloArmarioF: TAction;
    actCapituloBano: TAction;
    TBXItem15: TTBXItem;
    TBXItem16: TTBXItem;
    actCapituloArmarioI: TAction;
    TBXItem17: TTBXItem;
    actCapituloElectrodomesticos: TAction;
    actCapituloVarios: TAction;
    TBXItem19: TTBXItem;
    TBXItem20: TTBXItem;
    TBXSeparatorItem7: TTBXSeparatorItem;
    TBXSeparatorItem8: TTBXSeparatorItem;
    TBXSeparatorItem10: TTBXSeparatorItem;
    actCapituloImportes: TAction;
    TBXSeparatorItem11: TTBXSeparatorItem;
    TBXItem21: TTBXItem;
    TBXItem22: TTBXItem;
    actCapituloObra: TAction;
    cxGridViewPROPIEDAD: TcxGridDBColumn;
    cxLookupComboBox2: TcxLookupComboBox;
    procedure actAsignarDescuentoExecute(Sender: TObject);
    procedure actAsignarDescuentoUpdate(Sender: TObject);
    procedure CustomViewShow(Sender: TObject);
    procedure cxGridViewDESCRIPCIONGetPropertiesForEdit(Sender: TcxCustomGridTableItem; ARecord: TcxCustomGridRecord;
      var AProperties: TcxCustomEditProperties);
    procedure cxGridViewPROPIEDADGetPropertiesForEdit(Sender: TcxCustomGridTableItem; ARecord: TcxCustomGridRecord;
      var AProperties: TcxCustomEditProperties);
    procedure actCapituloBanoExecute(Sender: TObject);
    procedure actCapituloArmarioFExecute(Sender: TObject);
    procedure actCapituloArmarioIExecute(Sender: TObject);
    procedure actCapituloCocinaExecute(Sender: TObject);
    procedure actCapituloElectrodomesticosExecute(Sender: TObject);
    procedure actCapituloVariosExecute(Sender: TObject);
    procedure actAnadirExecute(Sender: TObject);
    procedure actCapituloImportesExecute(Sender: TObject);
    procedure OnVISIBLEPropertiesEditValueChanged(Sender: TObject);
    procedure OnVISIBLE2PropertiesEditValueChanged(Sender: TObject);        
    procedure CustomViewDestroy(Sender: TObject);
    procedure actCapituloObraExecute(Sender: TObject);
    procedure cxLookupComboBox1PropertiesEditValueChanged(Sender: TObject);

  private
    procedure AnadirCapitulo(const Tipo: String;const Descripcion: String; const Descuento:Boolean = false);

  protected
    FPresupuesto: IBizPresupuestoCliente;
    FPropiedades: IBizPropiedades;
    function GetPresupuesto: IBizPresupuestoCliente;
    procedure SetPresupuesto(const Value: IBizPresupuestoCliente);

    procedure AnadirArticulosInterno; override;
    procedure RellenarArticulosInterno; override;
    function AnadirArticulo(pReferencia: String; TipoReferencia: TEnumReferencia): Boolean; override;

    function EsTipoEditable(AItem: TcxCustomGridTableItem): Boolean; override;

  public
    property Presupuesto: IBizPresupuestoCliente read GetPresupuesto write SetPresupuesto;
  end;

implementation
{$R *.dfm}

uses
  uControllerDetallesBase, uDetallesPresupuestoClienteController, schPresupuestosClienteClient_Intf,
  uCalculosUtils, cxVariants, cxDataUtils;

{ TfrViewDetallesPresupuestoProveedor }

procedure TfrViewDetallesPresupuestoCliente.actAnadirExecute(Sender: TObject);
var
  AuxTipo: String;
begin
  AuxTipo := '';
  //En el caso de estar dentro de un capitulo almacenamos el tipo de articulo del capitulo
  if FPresupuesto.Detalles.TIPO_DETALLE = TIPO_DETALLE_CONCEPTO then
     AuxTipo := FPresupuesto.Detalles.TIPO_ARTICULO;

  inherited;

  //Asignamos el tipo de articulo del capitulo
  (Controller as IDetallesPresupuestoClienteController).SetTipoArticulo(Detalles, AuxTipo);
end;

procedure TfrViewDetallesPresupuestoCliente.actAsignarDescuentoExecute(Sender: TObject);
{var
  AuxTop, AuxRow:Integer;
  ADescuento: Variant;
}
begin
{
  ADescuento := (Controller as IDetallesPresupuestoClienteController).PedirDescuento;

  ShowHourglassCursor;
  _FocusedView.BeginUpdate;
  try

    if Assigned(Controller) and Assigned(FPresupuesto.Detalles) then
    begin
      AuxTop := cxGridView.Controller.TopRowIndex;
      AuxRow := cxGridView.DataController.FocusedRowIndex;

      (Controller as IDetallesPresupuestoClienteController).AsignarDescuento(FPresupuesto.Detalles, darListaSeleccionados, ADescuento);

       _FocusedView.DataController.SelectRows(AuxRow,AuxRow);
       _FocusedView.Controller.TopRowIndex := AuxTop;
    end
  finally
    _FocusedView.EndUpdate;
    HideHourglassCursor;
  end;
}  
end;

procedure TfrViewDetallesPresupuestoCliente.actAsignarDescuentoUpdate(Sender: TObject);
begin
  inherited;

  if not DADataSource.DataTable.IsEmpty then
    (Sender as TAction).Enabled := not (DADataSource.DataTable.State in dsEditModes)
    and (_FocusedView.DataController.GetSelectedCount > 0)
    and (FPresupuesto.Detalles.TIPO_DETALLE = TIPO_DETALLE_CONCEPTO)
  else
    (Sender as TAction).Enabled := False;
end;

procedure TfrViewDetallesPresupuestoCliente.actCapituloArmarioFExecute(Sender: TObject);
begin
  AnadirCapitulo(TIPO_CAPITULO_AF, 'FRENTE DE ARMARIO Nº ');
end;

procedure TfrViewDetallesPresupuestoCliente.actCapituloArmarioIExecute(Sender: TObject);
begin
  AnadirCapitulo(TIPO_CAPITULO_AI, 'INTERIOR DE ARMARIO Nº ');
end;

procedure TfrViewDetallesPresupuestoCliente.actCapituloBanoExecute(Sender: TObject);
begin
  AnadirCapitulo(TIPO_CAPITULO_B, 'MUEBLE DE BAÑO Nº ');
  AnadirCapitulo(TIPO_CAPITULO_V, 'IMPORTES ', True);
end;

procedure TfrViewDetallesPresupuestoCliente.actCapituloCocinaExecute(Sender: TObject);
begin
  AnadirCapitulo(TIPO_CAPITULO_C_VACIO, 'MUEBLES DE COCINA ');
//  AnadirCapitulo(TIPO_CAPITULO_V, 'IMPORTES ', True);
//  AnadirCapitulo(TIPO_CAPITULO_V, 'AUMENTO POR ');
end;

procedure TfrViewDetallesPresupuestoCliente.actCapituloElectrodomesticosExecute(Sender: TObject);
begin
  AnadirCapitulo(TIPO_CAPITULO_E, 'ELECTRODOMÉSTICOS ');
end;

procedure TfrViewDetallesPresupuestoCliente.actCapituloImportesExecute(Sender: TObject);
begin
  AnadirCapitulo(TIPO_CAPITULO_V, 'IMPORTES ');
end;

procedure TfrViewDetallesPresupuestoCliente.actCapituloObraExecute(
  Sender: TObject);
begin
  AnadirCapitulo(TIPO_CAPITULO_O, 'OBRA ');
end;

procedure TfrViewDetallesPresupuestoCliente.actCapituloVariosExecute(Sender: TObject);
begin
  AnadirCapitulo(TIPO_CAPITULO_V, 'VARIOS ');
end;

function TfrViewDetallesPresupuestoCliente.AnadirArticulo(pReferencia: String; TipoReferencia: TEnumReferencia): Boolean;
begin
  Result := (Controller as IDetallesPresupuestoClienteController).AnadirArticulo(Detalles, pReferencia, TipoReferencia, Presupuesto.Cliente.ID);
end;

procedure TfrViewDetallesPresupuestoCliente.AnadirArticulosInterno;
begin
  (Controller as IDetallesPresupuestoClienteController).AnadirArticulos(Detalles, Presupuesto.Cliente);
end;

procedure TfrViewDetallesPresupuestoCliente.AnadirCapitulo(const Tipo: String;const  Descripcion: String; const Descuento:Boolean = false);
var
  bEsMultiSelect : Boolean;
begin
  // Debo quitar el multiselect porque provoca que se quede seleccionado
  // el registro actual y no el nuevo registro que voy a añadir
  bEsMultiSelect := _FocusedView.OptionsSelection.MultiSelect;
  if bEsMultiSelect then
    _FocusedView.OptionsSelection.MultiSelect := False;

  ShowHourglassCursor;
  _FocusedView.BeginUpdate;
  try
    if _FocusedView.Controller.EditingController.IsEditing then
       _FocusedView.Controller.EditingController.Edit.PostEditValue;

    if Assigned(Controller) and Assigned(Detalles) then
       (Controller as IDetallesPresupuestoClienteController).AnadirCapitulo(Tipo, Descripcion, Descuento, Detalles)
  finally
    _FocusedView.EndUpdate;
    HideHourglassCursor;

    // Dejo la propiedad MultiSelect como estaba
    if bEsMultiSelect then
       _FocusedView.OptionsSelection.MultiSelect := bEsMultiSelect;
  end;
end;

procedure TfrViewDetallesPresupuestoCliente.CustomViewDestroy(Sender: TObject);
begin
  cxGridViewVISIBLE2.Properties.OnEditValueChanged := Nil;
  cxGridViewVISIBLE.Properties.OnEditValueChanged := Nil;
  inherited;
end;

procedure TfrViewDetallesPresupuestoCliente.CustomViewShow(Sender: TObject);
begin
  inherited;
  if not Assigned(FPropiedades) then
  begin
    FPropiedades := (Controller as IDetallesPresupuestoClienteController).DarPropiedades;
    FPropiedades.DataTable.Active := True;
    DAPropiedades.DataTable := FPropiedades.DataTable;
    DAValores.DataTable := FPropiedades.Valores.DataTable;

    cxGridViewVISIBLE2.Properties.OnEditValueChanged := OnVISIBLE2PropertiesEditValueChanged;
    cxGridViewVISIBLE.Properties.OnEditValueChanged := OnVISIBLEPropertiesEditValueChanged;
  end;
end;

procedure TfrViewDetallesPresupuestoCliente.cxGridViewDESCRIPCIONGetPropertiesForEdit(
  Sender: TcxCustomGridTableItem; ARecord: TcxCustomGridRecord;
  var AProperties: TcxCustomEditProperties);
begin
  inherited;

  //OJO sin esto no se refresca el filtro en tabla detalle "VALORES".
   DAPropiedades.DataTable.Locate(fld_PropiedadesDESCRIPCION, cxGridViewPROPIEDAD.DataBinding.Field.AsVariant,[]);

  if (ARecord.DisplayTexts[cxGridViewTIPO.Index] = TIPO_DETALLE_CONCEPTO)
  and (ARecord.DisplayTexts[cxGridViewPROPIEDAD.Index] <> '') then
  begin
     AProperties := cxLookupComboBox1.Properties;
  end
  else begin
     AProperties := cxRichEdit1.Properties;
  end;
end;

procedure TfrViewDetallesPresupuestoCliente.cxGridViewPROPIEDADGetPropertiesForEdit(
  Sender: TcxCustomGridTableItem; ARecord: TcxCustomGridRecord;
  var AProperties: TcxCustomEditProperties);
begin
  inherited;

  if (ARecord.DisplayTexts[cxGridViewTIPO.Index] = TIPO_DETALLE_CONCEPTO) then
  begin
     AProperties := cxLookupComboBox2.Properties
  end
  else
     AProperties := cxRichEdit1.Properties;
end;

procedure TfrViewDetallesPresupuestoCliente.cxLookupComboBox1PropertiesEditValueChanged(
  Sender: TObject);
var
  AEdit: TcxCustomEdit;
  AValue: Variant;
begin
  inherited;
  AEdit := Sender as TcxCustomEdit;

  if (AEdit.EditValue = DAValores.DataTable.FieldByName('DESCRIPCION').AsString) then
  begin
    AValue := DAValores.DataTable.FieldByName('PRECIO_PVP').Value;
    AEdit.PostEditValue;  // To 'stick' the new value in the active cell
    cxGridView.DataController.SetEditValue(cxGridViewIMPORTEUNIDAD.Index, AValue, evsValue);
    Controller.actualizarTotales(Detalles);
  end;
end;

procedure TfrViewDetallesPresupuestoCliente.OnVISIBLE2PropertiesEditValueChanged(
  Sender: TObject);
var
  Orden: Integer;
begin
  inherited;
  Orden := 1;
  if (cxGridView.DataController.GetItemByFieldName(CAMPO_TIPO).EditValue = TIPO_DETALLE_TITULO)
  or (cxGridView.DataController.GetItemByFieldName(CAMPO_TIPO).EditValue = TIPO_DETALLE_TITULO_OPCIONAL)
  or (cxGridView.DataController.GetItemByFieldName(CAMPO_TIPO).EditValue = TIPO_DETALLE_SUBTOTAL) then
  begin
     cxGridView.BeginUpdate;

     if (cxGridView.DataController.GetItemByFieldName(CAMPO_TIPO).EditValue = TIPO_DETALLE_SUBTOTAL) then
        Orden := 0;
     (Controller as IDetallesPresupuestoClienteController).SetVisible2(Detalles, cxGridView.DataController.GetItemByFieldName(CAMPO_VISIBLE2).EditValue, Orden);

     cxGridView.EndUpdate;
  end;
end;

procedure TfrViewDetallesPresupuestoCliente.OnVISIBLEPropertiesEditValueChanged(Sender: TObject);
var
  Orden: Integer;
begin
  inherited;
  Orden := 1;
  if (cxGridView.DataController.GetItemByFieldName(CAMPO_TIPO).EditValue = TIPO_DETALLE_TITULO)
  or (cxGridView.DataController.GetItemByFieldName(CAMPO_TIPO).EditValue = TIPO_DETALLE_TITULO_OPCIONAL)
  or (cxGridView.DataController.GetItemByFieldName(CAMPO_TIPO).EditValue = TIPO_DETALLE_SUBTOTAL) then
  begin
     cxGridView.BeginUpdate;

     if (cxGridView.DataController.GetItemByFieldName(CAMPO_TIPO).EditValue = TIPO_DETALLE_SUBTOTAL) then
        Orden := 0;
     (Controller as IDetallesPresupuestoClienteController).SetVisible(Detalles, cxGridView.DataController.GetItemByFieldName(CAMPO_VISIBLE).EditValue, Orden);

     cxGridView.EndUpdate;
  end;
  (Controller as IDetallesPresupuestoClienteController).ActualizarTotales(Detalles);
end;

function TfrViewDetallesPresupuestoCliente.EsTipoEditable(AItem: TcxCustomGridTableItem): Boolean;
var
  IndiceCol : Integer;
begin
  Result := True;

  if (AItem.Index in [cxGridViewDESCUENTO.Index]) then
  begin
//Esto es para que solo sea editable la columna dto en las lineas de tipo descuento (para hacer descuento por capitulo),
//además descuentos a nivel de lineas de detalle
    IndiceCol := cxGridView.GetColumnByFieldName(CAMPO_TIPO).Index;
    if (AItem.GridView.Items[IndiceCol].EditValue <> TIPO_DETALLE_DESCUENTO)
    and (AItem.GridView.Items[IndiceCol].EditValue <> TIPO_DETALLE_CONCEPTO)  then
       Result := False
  end
  else if (AItem.Index in [cxGridViewPROPIEDAD.Index, cxGridViewTIPO_ARTICULO.Index]) then
  begin
    IndiceCol := cxGridView.GetColumnByFieldName(CAMPO_TIPO).Index;
    if ((AItem.GridView.Items[IndiceCol].EditValue = TIPO_DETALLE_SALTO) or
        (AItem.GridView.Items[IndiceCol].EditValue = TIPO_DETALLE_SUBTOTAL) or
        (AItem.GridView.Items[IndiceCol].EditValue = TIPO_DETALLE_DESCUENTO) or
        (AItem.GridView.Items[IndiceCol].EditValue = TIPO_DETALLE_TITULO) or
        (AItem.GridView.Items[IndiceCol].EditValue = TIPO_DETALLE_TITULO_OPCIONAL)) then
      Result := False
    else
    begin
    IndiceCol := cxGridView.GetColumnByFieldName(fld_PresupuestosCliente_DetallesTIPO_ARTICULO).Index;
    if ((AItem.GridView.Items[IndiceCol].EditValue <> TIPO_CAPITULO_AF) and
        (AItem.GridView.Items[IndiceCol].EditValue <> TIPO_CAPITULO_AI) and
        (AItem.GridView.Items[IndiceCol].EditValue <> TIPO_CAPITULO_C) and
        (AItem.GridView.Items[IndiceCol].EditValue <> TIPO_CAPITULO_O) and
        (AItem.GridView.Items[IndiceCol].EditValue <> TIPO_CAPITULO_V) and
        (AItem.GridView.Items[IndiceCol].EditValue <> TIPO_CAPITULO_E) and                                
        (AItem.GridView.Items[IndiceCol].EditValue <> TIPO_CAPITULO_B)) then
      Result := False
    end;
  end
  else
    Result := inherited EsTipoEditable(AItem);
end;

function TfrViewDetallesPresupuestoCliente.GetPresupuesto: IBizPresupuestoCliente;
begin
  Result := FPresupuesto;
end;

procedure TfrViewDetallesPresupuestoCliente.RellenarArticulosInterno;
begin
  (Controller as IDetallesPresupuestoClienteController).AnadirArticulos(Detalles, Presupuesto.Cliente, False);
end;

procedure TfrViewDetallesPresupuestoCliente.SetPresupuesto(const Value: IBizPresupuestoCliente);
begin
  FPresupuesto := Value;
end;

end.
