unit uBizFechasObra; interface uses uDAInterfaces, uDADataTable; const TIPODETALLE_CONCEPTO = 'Concepto'; TIPODETALLE_SUBTOTAL = 'S'; TIPODETALLE_COMENTARIO = 'Comentario'; fld_POSICION = 'POSICION'; fld_TIPODETALLE = 'TIPO'; fld_IMPORTETOTAL = 'IMPORTETOTAL'; fld_CANTIDAD = 'CANTIDAD'; fld_IMPORTEUNIDAD = 'IMPORTEUNIDAD'; type TBizFechaIniFieldRules = class(TDAFieldRules) protected procedure OnChange(Sender: TDACustomField); override; end; TBizFechaFinFieldRules = class(TDAFieldRules) protected procedure OnChange(Sender: TDACustomField); override; end; {function DarMaximaPosicion(aDataTable : TDADataTable): integer; procedure ReasignarPosiciones(aDataTable : TDADataTable); procedure AsignarPosicion(aDataTable : TDADataTable; IsAppend : Boolean); function DarTotalDetalles(aDataTable : TDADataTable; TieneSubtotales : Boolean) : Currency; procedure IntercambiarPosiciones(aDataTable : TDADataTable; Pos1, Pos2 : Integer); } implementation uses SysUtils, DB, Controls, Forms, Dialogs, schObrasClient_Intf, uBizObra; { procedure IntercambiarPosiciones(aDataTable : TDADataTable; Pos1, Pos2 : Integer); var ABookmark : Pointer; AField : TDAField; AFieldTipo : TDAField; ACursor: TCursor; bRecalcular : Boolean; begin if not Assigned(aDataTable) then raise Exception.Create('Tabla no asignada (IntercambiarPosicion)'); AField := aDataTable.FindField(fld_POSICION); if not Assigned(AField) then raise Exception.Create('Campo POSICION no encontrado (IntercambiarPosicion)'); // No importa si el TIPO no está en la lista de columnas AFieldTipo := aDataTable.FindField(fld_TIPODETALLE); bRecalcular := False; ACursor := Screen.Cursor; Screen.Cursor := crHourGlass; aDataTable.DisableEventHandlers; aDataTable.DisableControls; ABookmark := aDataTable.GetBookMark; try aDataTable.First; if aDataTable.Locate(fld_POSICION, Pos1, []) then begin // Si alguna de las dos filas es un subtotal, hay que recalcular todo if Assigned(AFieldTipo) and (AFieldTipo.AsString = TIPODETALLE_SUBTOTAL) then bRecalcular := True; aDataTable.Edit; AField.AsInteger := -1; aDataTable.Post; aDataTable.First; if aDataTable.Locate(fld_POSICION, Pos2, []) then begin // Si alguna de las dos filas es un subtotal, hay que recalcular todo if Assigned(AFieldTipo) and (AFieldTipo.AsString = TIPODETALLE_SUBTOTAL) then bRecalcular := True; aDataTable.Edit; AField.AsInteger := Pos1; aDataTable.Post; aDataTable.First; aDataTable.Locate(fld_POSICION, -1, []); aDataTable.Edit; AField.AsInteger := Pos2; aDataTable.Post; end else raise Exception.Create('No se ha encontrado posición 2 (IntercambiarPosicion)'); end else raise Exception.Create('No se ha encontrado posición 1 (IntercambiarPosicion)'); finally aDataTable.GotoBookmark(ABookmark); aDataTable.EnableControls; aDataTable.EnableEventHandlers; if bRecalcular then DarTotalDetalles(aDataTable, True); Screen.Cursor := ACursor; end; end; {function DarMaximaPosicion(aDataTable : TDADataTable): integer; var ABookmark : Pointer; AField : TDAField; ACursor: TCursor; begin //Sort(['ForeignKeyFieldofMasterDetailRelation','YourSortField'],[sdAscending, NeededOrder ]); Result := 0; if not Assigned(aDataTable) then raise Exception.Create('Tabla no asignada (DarMaximaPosicion)'); AField := aDataTable.FindField(fld_POSICION); if not Assigned(AField) then raise Exception.Create('Campo POSICION no encontrado (DarMaximaPosicion)'); ACursor := Screen.Cursor; Screen.Cursor := crHourGlass; ABookmark := aDataTable.GetBookMark; try aDataTable.DisableControls; aDataTable.First; while not aDataTable.Eof do begin if AField.AsInteger > Result then Result := AField.AsInteger; aDataTable.Next; end; finally aDataTable.GotoBookmark(ABookmark); aDataTable.EnableControls; Screen.Cursor := ACursor; end; end;} {procedure ReasignarPosiciones(aDataTable : TDADataTable); var AField : TDAField; ABookmark : Pointer; Contador : Integer; NumCon : Integer; TotalConceptos : Integer; DetallesEditados : Integer; ACursor: TCursor; begin if not Assigned(aDataTable) then raise Exception.Create('Tabla no asignada (ReasignarNumConceptos)'); AField := aDataTable.FindField(fld_POSICION); if not Assigned(AField) then raise Exception.Create('Campo POSICION no encontrado (ReasignarNumConceptos)'); Contador := 1; NumCon := 1; TotalConceptos := aDataTable.RecordCount; DetallesEditados := 0; ACursor := Screen.Cursor; Screen.Cursor := crHourGlass; ABookmark := aDataTable.GetBookMark; aDataTable.DisableControls; try aDataTable.First; while DetallesEditados < TotalConceptos do begin if aDataTable.Locate(fld_POSICION, Contador, []) then begin aDataTable.Edit; AField.Value := NumCon; Inc(NumCon); aDataTable.Post; Inc(DetallesEditados); aDataTable.First; end; Inc(Contador); end; finally aDataTable.EnableControls; aDataTable.GotoBookmark(ABookmark); Screen.Cursor := ACursor; end; end; procedure AsignarPosicion(aDataTable : TDADataTable; IsAppend : Boolean); var AField : TDAField; ABookmark : Pointer; NumPosicion : Integer; MaxPosicion : Integer; ACursor: TCursor; begin if not Assigned(aDataTable) then raise Exception.Create('Tabla no asignada (AsignarPosicion)'); AField := aDataTable.FindField(fld_POSICION); if not Assigned(AField) then raise Exception.Create('Campo POSICION no encontrado (AsignarPosicion)'); if not IsAppend then begin if not aDataTable.IsEmpty then begin ACursor := Screen.Cursor; Screen.Cursor := crHourGlass; // Mover las filas que están por debajo de la actual MaxPosicion := DarMaximaPosicion(aDataTable); NumPosicion := (AField.AsInteger * (-1)); ABookmark := aDataTable.GetBookMark; try aDataTable.First; while aDataTable.Locate(fld_POSICION, MaxPosicion, []) do begin aDataTable.Edit; AField.Value := MaxPosicion + 1; aDataTable.Post; aDataTable.First; if MaxPosicion = NumPosicion then Break else Dec(MaxPosicion); end finally aDataTable.GotoBookmark(ABookmark); Screen.Cursor := ACursor; end; end; NumPosicion := (AField.AsInteger * (-1)); end else begin if aDataTable.RecordCount > 1 then NumPosicion := DarMaximaPosicion(aDataTable) + 1 else // Sólo hay una fila en toda la tabla NumPosicion := (AField.AsInteger * (-1)); end; // Asignar posición a la nueva fila aDataTable.Edit; AField.Value := NumPosicion; aDataTable.Post; end; procedure CalcularImportesLinea(aDataTable : TDADataTable; TieneSubtotales : Boolean); var ACabecera : IBizImportesCabecera; TipoField : TDAField; TotalField : TDAField; CantidadField : TDAField; ImporteUnidadField : TDAField; begin if not Assigned(aDataTable) then raise Exception.Create('Tabla no asignada (CalcularImportesLinea)'); TotalField := aDataTable.FindField(fld_IMPORTETOTAL); if not Assigned(TotalField) then raise Exception.Create('Campo IMPORTETOTAL no encontrado (CalcularImportesLinea)'); CantidadField := aDataTable.FindField(fld_CANTIDAD); if not Assigned(CantidadField) then raise Exception.Create('Campo CANTIDAD no encontrado (CalcularImportesLinea)'); ImporteUnidadField := aDataTable.FindField(fld_IMPORTEUNIDAD); if not Assigned(ImporteUnidadField) then raise Exception.Create('Campo IMPORTEUNIDAD no encontrado (CalcularImportesLinea)'); if TieneSubtotales then begin TipoField := aDataTable.FindField(fld_TIPODETALLE); if not Assigned(TipoField) then raise Exception.Create('Campo TIPO no encontrado (CalcularImportesLinea)'); if TipoField.AsString = TIPODETALLE_SUBTOTAL then Exit; end; aDataTable.Edit; TotalField.Value := CantidadField.AsCurrency * ImporteUnidadField.AsCurrency; aDataTable.Post; if Assigned(aDataTable.MasterSource) and Supports(aDataTable.MasterSource.DataTable, IBizImportesCabecera, ACabecera) then ACabecera.CalcularImportes; end; function DarTotalDetalles(aDataTable : TDADataTable; TieneSubtotales : Boolean) : Currency; var ABookmark : Pointer; APosicion : Integer; MaxPos : Integer; Total : Currency; Subtotal : Currency; TipoField : TDAField; TotalField : TDAField; ACursor: TCursor; begin Result := 0; if not Assigned(aDataTable) then raise Exception.Create('Tabla no asignada (DarTotalDetalles)'); if TieneSubtotales then begin TipoField := aDataTable.FindField(fld_TIPODETALLE); if not Assigned(TipoField) then raise Exception.Create('Campo TIPO no encontrado (DarTotalDetalles)'); { if TipoField.AsString = TIPODETALLE_SUBTOTAL then Exit;} { end; TotalField := aDataTable.FindField(fld_IMPORTETOTAL); if not Assigned(TotalField) then raise Exception.Create('Campo IMPORTETOTAL no encontrado (DarTotalDetalles)'); ABookmark := aDataTable.GetBookMark; ACursor := Screen.Cursor; Screen.Cursor := crHourGlass; aDataTable.DisableControls; APosicion := 1; Total := 0; Subtotal := 0; try MaxPos := DarMaximaPosicion(aDataTable); while (APosicion <= MaxPos) do begin aDataTable.First; if aDataTable.Locate(fld_POSICION, APosicion, []) then begin if TieneSubtotales and (TipoField.AsString = TIPODETALLE_SUBTOTAL) then begin aDataTable.Edit; TotalField.Value := SubTotal; aDataTable.Post; Total := Total + SubTotal; Subtotal := 0; end else begin Subtotal := Subtotal + TotalField.AsCurrency; if (APosicion = MaxPos) then Total := Total + SubTotal; end; Inc(APosicion); end else Break; end; finally Result := Total; aDataTable.GotoBookmark(ABookmark); aDataTable.EnableControls; Screen.Cursor := ACursor; end; end; } { TBizCantidadFieldRules } procedure TBizFechaIniFieldRules.OnChange(Sender: TDACustomField); //var // aDetalle : IBizImportesDetalle; begin inherited; showmessage('Hola Ini'); // if Supports(DataTable, IBizImportesDetalle, aDetalle) then // CalcularImportesLinea(aDetalle.DataTable, True); end; procedure TBizFechaFinFieldRules.OnChange(Sender: TDACustomField); var AObj : IBizFechasObra; AFechaIni: TDAField; AFechaFin: TDAField; begin inherited; // showmessage('Hola Fin'); //Sender.AsDateTime // ComprobarFecha if Supports(DataTable, IBizFechasObra, AObj) then begin AFechaIni := AObj.DataTable.FindField(fld_ObrasFECHAINIOBR); AFechaFin := AObj.DataTable.FindField(fld_ObrasFECHAFINOBR); case ComprobarFecha(AFechaIni.AsDateTime, AFechaFin.AsDateTime) of 0: showmessage('son Iguales'); 1: showmessage('FechaIni es una fecha posterior a fechaFin'); 2: showmessage('FechaFin es una fecha posterior a fechaIni'); end; end; // CalcularImportesLinea(aDetalle.DataTable, True); end; initialization RegisterFieldRules('Client.Field.FechaIni', TBizFechaIniFieldRules); RegisterFieldRules('Client.Field.FechaFin', TBizFechaFinFieldRules); finalization end.