Tecsitel_FactuGES2/Source/Base/Utiles/uCalculosUtils.pas
2009-12-15 18:10:16 +00:00

164 lines
5.2 KiB
ObjectPascal

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';
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;
function CalcularLineaConcepto (const ADataTable : TDADataTable): Double;
var
ImporteTotal : Double;
ImporteA: Double;
ImporteB: Double;
begin
with ADataTable do
begin
if (VarIsNull(FieldByName(CAMPO_DESCUENTO).AsVariant)) then
ImporteTotal := FieldByName(CAMPO_CANTIDAD).asfloat * FieldByName(CAMPO_IMPORTE_UNIDAD).AsFloat
else
begin
//Importe descuento con todos los decimales
ImporteA := FieldByName(CAMPO_IMPORTE_UNIDAD).AsFloat * (FieldByName(CAMPO_DESCUENTO).AsFloat/100);
//Importe descuento redondeado a solo dos decimales, porque en grandes cantidades hay fluctuación
//(importe unidad - 0,6732 no es lo mismo que importe unidad - 0,67 sobre todo cuando trabajamos con grandes cantidades)
ImporteB := round(ImporteA*100)/100;
ImporteTotal := FieldByName(CAMPO_CANTIDAD).asfloat * (FieldByName(CAMPO_IMPORTE_UNIDAD).AsFloat - ImporteB);
end;
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;
ADetalles.DataTable.DisableControls;
ADetalles.DataTable.DisableEventHandlers;
try
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.