unit uDetallesPresupuestoClienteController; interface uses uDADataTable, uControllerDetallesBase, uControllerDetallesArticulos, uBizDetallesPresupuestoCliente, uIDataModulePresupuestosCliente, uBizArticulos, uBizContactos; type IDetallesPresupuestoClienteController = interface(IControllerDetallesArticulos) ['{8D1D3559-E695-4962-9999-404B26B50D6C}'] procedure AnadirArticulos(ADetalles: IDAStronglyTypedDataTable; ACliente: IBizCliente; const ANuevaFila :Boolean = True); overload; procedure ActualizarDetalles(ADetalles: IDAStronglyTypedDataTable; ACliente: IBizCliente); overload; procedure DesglosarPorteDetalles(ImportePorte: Currency; ADetalles: IDAStronglyTypedDataTable); function DarTotalPorteTotal(ADetalles: IDAStronglyTypedDataTable): Double; function PedirDescuento: Variant; procedure RecalcularPrecioPuntoDetalles(PrecioPunto: Currency; ADetalles: IDAStronglyTypedDataTable); function DarPropiedades: IBizPropiedades; procedure AnadirCapitulo (const Tipo: String; const Descripcion: String; const Descuento:Boolean; ADetalles: IDAStronglyTypedDataTable); function BuscarCapitulo (const Tipo: String): IBizCapitulo; procedure SetTipoArticulo(ADetalles: IDAStronglyTypedDataTable; ATipo: String); procedure SetPrecioPunto (const AValue: Currency); function GetPrecioPunto: Currency; property PrecioPunto : Currency read GetPrecioPunto write SetPrecioPunto; end; TDetallesPresupuestoClienteController = class(TControllerDetallesArticulos, IDetallesPresupuestoClienteController) private FPrecioPunto: Currency; FDataModule : IDataModulePresupuestosCliente; function CreateEditor(const AName : String; const IID: TGUID; out Intf): Boolean; protected // procedure AsignarDatos(ADetalles: IDAStronglyTypedDataTable; IDCabecera: Integer); override; procedure RellenarOtros(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); overload; override; procedure RellenarImportes(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); override; procedure AsignarController; override; //Si sobreescribimos este método podremos tener en cuenta otras columnas para el calculo del importe total de un concepto function CalcularImporteTotalConcepto(DataTable: TDADataTable): Double; override; procedure ValidarCampos(DataTable: TDADataTable); override; procedure DesglosarPorteDetalles(ImportePorte: Currency; ADetalles: IDAStronglyTypedDataTable); function DarTotalPorteTotal(ADetalles: IDAStronglyTypedDataTable): Double; procedure RecalcularPrecioPuntoDetalles(PrecioPunto: Currency; ADetalles: IDAStronglyTypedDataTable); procedure SetPrecioPunto (const AValue: Currency); function GetPrecioPunto: Currency; public function PedirDescuento: Variant; procedure AnadirArticulos(ADetalles: IDAStronglyTypedDataTable; ACliente: IBizCliente; const ANuevaFila :Boolean = True); reintroduce; overload; procedure ActualizarDetalles(ADetalles: IDAStronglyTypedDataTable; ACliente: IBizCliente); overload; constructor Create; override; destructor Destroy; override; function DarPropiedades: IBizPropiedades; procedure AnadirCapitulo (const Tipo: String; const Descripcion: String; const Descuento:Boolean; ADetalles: IDAStronglyTypedDataTable); function BuscarCapitulo (const Tipo: String): IBizCapitulo; //Se sobre escribe para hacer otro recorrido y rellenar el tipo_articulo a todos los conceptos de los capitulos procedure ValidarDetalles(ADataTable: IDAStronglyTypedDataTable); override; procedure SetTipoArticulo(ADetalles: IDAStronglyTypedDataTable; ATipo: String); property PrecioPunto : Currency read GetPrecioPunto write SetPrecioPunto; end; implementation uses DB, Controls, SysUtils, Dialogs, uDAInterfaces, uDialogUtils, Variants, uDataModulePresupuestosCliente, uArticulosPresupuestoClienteController, schPresupuestosClienteClient_Intf, uNumUtils, uDataTableUtils, uCalculosUtils, uIEditorAsignarDescuento, uEditorRegistryUtils, uFactuGES_App, Windows; { TDetallesPresupuestoClienteController } procedure TDetallesPresupuestoClienteController.ActualizarDetalles(ADetalles: IDAStronglyTypedDataTable; ACliente: IBizCliente); begin if Assigned(ADetalles) then ActualizarDetalles(ADetalles, ACliente.DESCUENTO_LINEA); end; procedure TDetallesPresupuestoClienteController.AnadirArticulos(ADetalles: IDAStronglyTypedDataTable; ACliente: IBizCliente; const ANuevaFila :Boolean); var AArticulos: IBizArticulo; begin if Assigned(ADetalles) then begin try AArticulos := (FArticulosController.BuscarTodos(ACliente) as IBizArticulo); //Si nueva fila es false, quiere decir que se sustituye un determinado artículo, por ello la lista a seleccionar no debe ser multiselect if ANuevaFila then begin AArticulos := (FArticulosController as IArticulosPresupuestoClienteController).ElegirArticulos(AArticulos, 'Elija los artículos que desea añadir a este presupuesto de cliente', True); Add(ADetalles, AArticulos) end else begin AArticulos := (FArticulosController as IArticulosPresupuestoClienteController).ElegirArticulos(AArticulos, 'Elija el artículo que desea añadir a este presupuesto de cliente', False); RellenarDetalle(ADetalles, AArticulos); end; finally AArticulos := Nil; end; end; end; procedure TDetallesPresupuestoClienteController.AnadirCapitulo(const Tipo: String;const Descripcion: String; const Descuento:Boolean; ADetalles: IDAStronglyTypedDataTable); var ACapitulo: IBizCapitulo; begin Self.Add(ADetalles, TIPO_DETALLE_TITULO); if not ADetalles.DataTable.Editing then ADetalles.DataTable.Edit; ADetalles.DataTable.FieldByName(fld_PresupuestosCliente_DetallesTIPO_ARTICULO).AsString := Tipo; ADetalles.DataTable.FieldByName(fld_PresupuestosCliente_DetallesCONCEPTO).AsString := Descripcion; ADetalles.DataTable.FieldByName(fld_PresupuestosCliente_DetallesDESCUENTO).AsVariant := Null; //Rellenamos con las propiedades del capitulo ACapitulo := FDataModule.GetCapitulo(Tipo); ACapitulo.DataTable.Active := True; with ACapitulo.DataTable do begin First; repeat Self.Add(ADetalles, TIPO_DETALLE_CONCEPTO); if not ADetalles.DataTable.Editing then ADetalles.DataTable.Edit; ADetalles.DataTable.FieldByName(fld_PresupuestosCliente_DetallesTIPO_ARTICULO).AsString := Tipo; ADetalles.DataTable.FieldByName(fld_PresupuestosCliente_DetallesPROPIEDAD).AsString := ACapitulo.CONCEPTO; Next; until EOF; end; Self.Add(ADetalles, TIPO_DETALLE_SUBTOTAL); if not ADetalles.DataTable.Editing then ADetalles.DataTable.Edit; ADetalles.DataTable.FieldByName(fld_PresupuestosCliente_DetallesTIPO_ARTICULO).AsString := Tipo; ADetalles.DataTable.FieldByName(fld_PresupuestosCliente_DetallesCONCEPTO).AsString := 'SUBTOTAL ' + Descripcion; ADetalles.DataTable.FieldByName(fld_PresupuestosCliente_DetallesDESCUENTO).AsVariant := Null; if Descuento then begin Self.Add(ADetalles, TIPO_DETALLE_DESCUENTO); if not ADetalles.DataTable.Editing then ADetalles.DataTable.Edit; ADetalles.DataTable.FieldByName(fld_PresupuestosCliente_DetallesTIPO_ARTICULO).AsString := Tipo; ADetalles.DataTable.FieldByName(fld_PresupuestosCliente_DetallesCONCEPTO).AsString := 'DESCUENTO '; end; Self.Add(ADetalles, TIPO_DETALLE_CONCEPTO); end; procedure TDetallesPresupuestoClienteController.AsignarController; begin FArticulosController := TArticulosPresupuestoClienteController.Create; end; function TDetallesPresupuestoClienteController.BuscarCapitulo( const Tipo: String): IBizCapitulo; begin Result := FDataModule.GetCapitulo(Tipo); end; function TDetallesPresupuestoClienteController.PedirDescuento: Variant; var AEditor: IEditorAsignarDescuento; begin CreateEditor('EditorAsignarDescuento', IEditorAsignarDescuento, AEditor); if Assigned(AEditor) then try if (AEditor.ShowModal = mrOk) then Result := AEditor.Descuento; finally AEditor.Release; AEditor := NIL; end; end; { procedure TDetallesPresupuestoClienteController.AsignarDatos(ADetalles: IDAStronglyTypedDataTable; IDCabecera: Integer); begin inherited; with (ADetalles as IBizDetallesPresupuestoCliente) do begin Edit; ID := FDataModule.GetNextID(DataTable.LogicalName); ID_PEDIDO := IDCabecera; Post end; end; } function TDetallesPresupuestoClienteController.CalcularImporteTotalConcepto(DataTable: TDADataTable): Double; begin Result := CalcularLineaConcepto(DataTable); end; constructor TDetallesPresupuestoClienteController.Create; begin inherited; FPrecioPunto:= AppFactuGES.EmpresaActiva.PRECIO_PUNTO; FDataModule := TDataModulePresupuestosCliente.Create(Nil); end; function TDetallesPresupuestoClienteController.CreateEditor(const AName: String; const IID: TGUID; out Intf): Boolean; begin Result := Supports(EditorRegistry.CreateEditor(AName), IID, Intf); end; function TDetallesPresupuestoClienteController.DarPropiedades: IBizPropiedades; begin Result := FDataModule.GetPropiedades; end; function TDetallesPresupuestoClienteController.DarTotalPorteTotal(ADetalles: IDAStronglyTypedDataTable): Double; begin Result := DarTotalPorte(ADetalles); end; procedure TDetallesPresupuestoClienteController.DesglosarPorteDetalles(ImportePorte: Currency; ADetalles: IDAStronglyTypedDataTable); begin DesglosarPorte(ImportePorte, ADetalles); ActualizarTotales(ADetalles); end; destructor TDetallesPresupuestoClienteController.Destroy; begin FDataModule := Nil; inherited; end; function TDetallesPresupuestoClienteController.GetPrecioPunto: Currency; begin Result := FPrecioPunto; end; procedure TDetallesPresupuestoClienteController.RellenarOtros(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); var ACadena : String; begin ACadena := ADetalles.DataTable.FieldByName('PROPIEDAD').AsString; if (AArticulos.REFERENCIA_PROV <> '') then ACadena := AArticulos.REFERENCIA_PROV + ' ' + ACadena; if (AArticulos.FAMILIA <> '') then ACadena := AArticulos.FAMILIA + ' ' + ACadena; ADetalles.DataTable.FieldByName('PROPIEDAD').AsString := ACadena; //El descuento que hemos puesto a la vista de articulos es el del cliente seleccionado en el documento if Assigned(AArticulos) then ADetalles.DataTable.FieldByName(CAMPO_DESCUENTO).AsFloat := AArticulos.DESCUENTO else ADetalles.DataTable.FieldByName(CAMPO_DESCUENTO).AsFloat := 0; end; procedure TDetallesPresupuestoClienteController.SetPrecioPunto(const AValue: Currency); begin FPrecioPunto := AValue; FArticulosController.PrecioPunto := FPrecioPunto; end; procedure TDetallesPresupuestoClienteController.SetTipoArticulo( ADetalles: IDAStronglyTypedDataTable; ATipo: String); begin if assigned(ADetalles) then begin ADetalles.DataTable.Edit; ADetalles.DataTable.FieldByName('TIPO_ARTICULO').AsString := ATipo; ADetalles.DataTable.Post; end; end; procedure TDetallesPresupuestoClienteController.ValidarCampos(DataTable: TDADataTable); begin inherited; ValidarCamposLineaConcepto(DataTable); end; procedure TDetallesPresupuestoClienteController.ValidarDetalles(ADataTable: IDAStronglyTypedDataTable); var AuxTipoArticulo : String; AuxPosicionIni : Integer; AuxPosicion : Integer; begin inherited; AuxTipoArticulo := ''; AuxPosicionIni := ADataTable.DataTable.FieldByName(CAMPO_POSICION).AsInteger; AuxPosicion := 0; BeginUpdate(ADataTable); try ADataTable.DataTable.First; while ADataTable.DataTable.Locate(CAMPO_POSICION, AuxPosicion, []) do begin if (ADataTable.DataTable.FieldByName(CAMPO_TIPO).AsString = TIPO_DETALLE_TITULO) then AuxTipoArticulo := ADataTable.DataTable.FieldByName(fld_CapitulosPresupuestoTIPO_ARTICULO).AsString else if (ADataTable.DataTable.FieldByName(CAMPO_TIPO).AsString = TIPO_DETALLE_SUBTOTAL) then AuxTipoArticulo := '' else if (ADataTable.DataTable.FieldByName(CAMPO_TIPO).AsString = TIPO_DETALLE_CONCEPTO) then if (Length(AuxTipoArticulo) > 0) then begin if not ADataTable.DataTable.Editing then ADataTable.DataTable.Edit; ADataTable.DataTable.FieldByName(fld_CapitulosPresupuestoTIPO_ARTICULO).AsString := AuxTipoArticulo; ADataTable.DataTable.Post; end; Inc(AuxPosicion); ADataTable.DataTable.First; end; finally //Dejamos el puntero en la misma posición que la que partió ADataTable.DataTable.Locate(CAMPO_POSICION, AuxPosicionIni, []); EndUpdate(ADataTable); end; end; procedure TDetallesPresupuestoClienteController.RecalcularPrecioPuntoDetalles(PrecioPunto: Currency; ADetalles: IDAStronglyTypedDataTable); var AArticulo: IBizArticulo; ABookmark : TBookmark; begin ABookmark := ADetalles.DataTable.GetBookMark; try ADetalles.DataTable.DisableControls; ADetalles.DataTable.DisableEventHandlers; ADetalles.DataTable.First; while not ADetalles.DataTable.eof do begin if (ADetalles.DataTable.FieldByName(CAMPO_ID_ARTICULOS).AsInteger > 0) then begin AArticulo := (FArticulosController.Buscar(ADetalles.DataTable.FieldByName(CAMPO_ID_ARTICULOS).AsInteger) as IBizArticulo); AArticulo.DataTable.Open; //Buscamos el punto del articulo y lo recalculamos ADetalles.DataTable.Edit; ADetalles.DataTable.FieldByName(CAMPO_IMPORTE_UNIDAD).AsCurrency := AArticulo.PRECIO_COSTE * PrecioPunto; ADetalles.DataTable.Post; AArticulo := Nil; end; ADetalles.DataTable.Next; end; finally ADetalles.DataTable.EnableEventHandlers; ADetalles.DataTable.GotoBookmark(ABookmark); ADetalles.DataTable.FreeBookmark(ABookmark); ADetalles.DataTable.EnableControls; end; ActualizarTotales(ADetalles); end; procedure TDetallesPresupuestoClienteController.RellenarImportes(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); begin if ADetalles.DataTable.FieldByName(CAMPO_IMPORTE_UNIDAD).IsNull then if Assigned(AArticulos) then ADetalles.DataTable.FieldByName(CAMPO_IMPORTE_UNIDAD).AsVariant := RoundCurrency(AArticulos.PRECIO_COSTE * FPrecioPunto) else ADetalles.DataTable.FieldByName(CAMPO_IMPORTE_UNIDAD).AsVariant := Null; end; end.