unit uCalculosUtils; interface uses uDADataTable, uDAInterfaces; const CAMPO_ID = 'ID'; CAMPO_POSICION = 'POSICION'; CAMPO_TIPO = 'TIPO_DETALLE'; CAMPO_ID_ARTICULOS = 'ID_ARTICULO'; CAMPO_CONCEPTO = 'CONCEPTO'; CAMPO_CANTIDAD = 'CANTIDAD'; CAMPO_IMPORTE_UNIDAD = 'IMPORTE_UNIDAD'; CAMPO_IMPORTE_TOTAL = 'IMPORTE_TOTAL'; CAMPO_DESCUENTO = 'DESCUENTO'; CAMPO_IMPORTE_PORTE = 'IMPORTE_PORTE'; CAMPO_VISIBLE = 'VISIBLE'; //Se usará para saber si un concepto se debe sumar o no CAMPO_VISIBLE2 = 'VISIBLE2'; //Se usará para saber si un concepto se muestra o no function CalcularLineaConcepto (const ADataTable : TDADataTable): Double; procedure ValidarCamposLineaConcepto(DataTable: TDADataTable); procedure DesglosarPorte(ImportePorte: Currency; ADetalles: IDAStronglyTypedDataTable); function DarTotalPorte(ADetalles: IDAStronglyTypedDataTable): Double; implementation uses SysUtils, DB, Variants, cxControls, uNumUtils; function CalcularLineaConcepto (const ADataTable : TDADataTable): Double; var ImporteTotal : Double; begin with ADataTable do begin if (VarIsNull(FieldByName(CAMPO_DESCUENTO).AsVariant)) then ImporteTotal := FieldByName(CAMPO_CANTIDAD).asFloat * FieldByName(CAMPO_IMPORTE_UNIDAD).AsFloat else ImporteTotal := FieldByName(CAMPO_CANTIDAD).asFloat * RoundCurrency((FieldByName(CAMPO_IMPORTE_UNIDAD).AsFloat - (FieldByName(CAMPO_IMPORTE_UNIDAD).AsFloat * (FieldByName(CAMPO_DESCUENTO).AsFloat/100)))); if (VarIsNull(FieldByName(CAMPO_IMPORTE_PORTE).AsVariant)) then ImporteTotal := ImporteTotal else ImporteTotal := ImporteTotal + (FieldByName(CAMPO_CANTIDAD).asFloat * FieldByName(CAMPO_IMPORTE_PORTE).AsFloat); end; Result := ImporteTotal; end; procedure ValidarCamposLineaConcepto(DataTable: TDADataTable); var AField: TDAField; begin //Validamos la existencia de todos los campos necesarios AField := DataTable.FindField(CAMPO_DESCUENTO); if not Assigned(AField) then raise Exception.Create('Campo ' + CAMPO_DESCUENTO + ' no encontrado (validarCampos)'); AField := DataTable.FindField(CAMPO_IMPORTE_PORTE); if not Assigned(AField) then raise Exception.Create('Campo ' + CAMPO_IMPORTE_PORTE + ' no encontrado (validarCampos)'); end; procedure DesglosarPorte(ImportePorte: Currency; ADetalles: IDAStronglyTypedDataTable); var Unidades: Double; ImporteUnidad: Currency; ImporteSobrante: Currency; ABookmark : TBookmark; begin ImporteUnidad := 0; ImporteSobrante := 0; ABookmark := ADetalles.DataTable.GetBookMark; try ADetalles.DataTable.DisableControls; ADetalles.DataTable.DisableEventHandlers; ADetalles.DataTable.First; Unidades := 0; while not ADetalles.DataTable.eof do begin if (ADetalles.DataTable.FieldByName(CAMPO_ID_ARTICULOS).AsInteger > 0) then Unidades := Unidades + ADetalles.DataTable.FieldByName(CAMPO_CANTIDAD).AsFloat; ADetalles.DataTable.Next; end; if Unidades > 0 then begin ImporteUnidad := StrToCurr(FormatFloat('0000000000.00', (ImportePorte / Unidades))); ImporteSobrante := ((ImportePorte / Unidades) - ImporteUnidad) * Unidades; end; ADetalles.DataTable.First; while not ADetalles.DataTable.eof do begin if (ADetalles.DataTable.FieldByName(CAMPO_ID_ARTICULOS).AsInteger > 0) then begin ADetalles.DataTable.Edit; ADetalles.DataTable.FieldByName(CAMPO_IMPORTE_PORTE).AsCurrency := ImporteUnidad; ADetalles.DataTable.Post; end; ADetalles.DataTable.Next; end; ADetalles.DataTable.Edit; ADetalles.DataTable.FieldByName(CAMPO_IMPORTE_PORTE).AsCurrency := ImporteUnidad + ImporteSobrante; ADetalles.DataTable.Post; finally ADetalles.DataTable.EnableEventHandlers; ADetalles.DataTable.GotoBookmark(ABookmark); ADetalles.DataTable.FreeBookmark(ABookmark); ADetalles.DataTable.EnableControls; end; end; function DarTotalPorte(ADetalles: IDAStronglyTypedDataTable): Double; var ImporteTotal: Currency; AuxPosicionIni : Integer; begin AuxPosicionIni := ADetalles.DataTable.FieldByName(CAMPO_POSICION).AsInteger; ShowHourglassCursor; try ADetalles.DataTable.DisableControls; ADetalles.DataTable.DisableEventHandlers; ADetalles.DataTable.First; ImporteTotal := 0; while not ADetalles.DataTable.eof do begin if (ADetalles.DataTable.FieldByName(CAMPO_ID_ARTICULOS).AsInteger > 0) then ImporteTotal := ImporteTotal + (ADetalles.DataTable.FieldByName(CAMPO_CANTIDAD).AsFloat * ADetalles.DataTable.FieldByName(CAMPO_IMPORTE_PORTE).AsFloat); ADetalles.DataTable.Next; end; finally ADetalles.DataTable.Locate(CAMPO_POSICION, IntToStr(AuxPosicionIni), []); ADetalles.DataTable.EnableEventHandlers; ADetalles.DataTable.EnableControls; HideHourglassCursor; end; Result := ImporteTotal; end; end.