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.