This repository has been archived on 2024-12-02. You can view files and clone it, but cannot push or open issues or pull requests.
AlonsoYSal_FactuGES/Modulos/Facturas de cliente/Reglas/uBizFacturasCliente.pas

672 lines
19 KiB
ObjectPascal
Raw Blame History

unit uBizFacturasCliente;
interface
uses
uDAInterfaces, uDADataTable, Classes, uBizContacto, DB,
uBizImportesDetalleBase,
uBizImportesCabeceraBase, uBizPresupuestosCliente, uDBSelectionList,
uExceptions, uBizInformesBase, schFacturasClienteClient_Intf,
uBizAlbaranesCliente;
const
BIZ_FACTURASCLIENTE = 'Client.FacturasCliente';
BIZ_DETALLESFACTURASCLIENTE = 'Client.DetallesFacturasCliente';
SITUACION_PENDIENTE = 'Pendiente';
SITUACION_PAGADO = 'Pagado';
CTE_IVA1 = 16;
CTE_IVA2 = 1.16;
type
IBizDetallesFacturasCliente = interface(IDetallesFacturasCliente)
['{A628B3DE-2EF0-4A6E-AAFD-8BE582BDEE9A}']
procedure CopyFrom(ADetallesAlbaranes : IBizDetallesAlbaranCliente); overload;
procedure CopyFrom(ADetallesFacturas : IBizDetallesFacturasCliente); overload;
procedure DesglosarIVA(IVA : Double);
end;
IBizFacturasCliente = interface(IFacturasCliente)
['{CE8B2685-0FA5-404C-B8FA-90618A815BFF}']
function GetDetalles: IBizDetallesFacturasCliente;
procedure SetDetalles(Value: IBizDetallesFacturasCliente);
property Detalles: IBizDetallesFacturasCliente read GetDetalles write
SetDetalles;
function GetCliente: IBizCliente;
procedure SetCliente(Value: IBizCliente);
property Cliente: IBizCliente read GetCliente write SetCliente;
procedure Show;
procedure CopyFrom(AFacturaCliente : IBizFacturasCliente); overload;
procedure CopyFrom(AAlbaranCliente : IBizAlbaranesCliente); overload;
procedure DesglosarIVA;
end;
TBizDetallesFacturasCliente = class(TDetallesFacturasClienteDataTableRules,
IBizDetallesFacturasCliente,
IBizImportesDetalle,
IBizPuntosDetalle,
IBizVisibleDetalle,
IBizValoradoDetalle,
IParche) // PARCHE ***********************
private
FIsAppend : Boolean;
FPosicionNueva : Integer;
FPuedoLanzarEvento : Boolean; // PARCHE ***********************
procedure SetCANTIDADValue(const aValue: Integer); override;
procedure SetIMPORTEUNIDADValue(const aValue: Currency); override;
procedure SetIMPORTETOTALValue(const aValue: Currency); override;
protected
procedure OnNewRecord(Sender: TDADataTable); override;
procedure BeforeInsert(Sender: TDADataTable); override;
procedure AfterPost(Sender: TDADataTable); override;
procedure AfterInsert(Sender: TDADataTable); override;
procedure AfterDelete(Sender: TDADataTable); override;
procedure BeforeDelete(Sender: TDADataTable); override;
// PARCHE ***********************
procedure ActivarEventos;
procedure DesactivarEventos;
procedure Refrescar;
function PuedoLanzarEvento : Boolean;
public
procedure RecalcularImporte;
function DarSumaTotalImportes : Currency;
constructor Create(aDataTable: TDADataTable); override;
procedure CopyFrom(ADetallesAlbaranes : IBizDetallesAlbaranCliente); overload;
procedure CopyFrom(ADetallesFacturas : IBizDetallesFacturasCliente); overload;
procedure DesglosarIVA(IVA : Double);
end;
TBizFacturasCliente = class(TFacturasClienteDataTableRules, IBizFacturasCliente,
IBizImportesCabecera, ISelectedRowList,
IApplyUpdateFailedException, IBizInformesAware)
private
FCliente : IBizCliente;
FDetalles: IBizDetallesFacturasCliente;
FDetallesLink: TDADataSource;
FSelectedRows : TSelectedRowList;
protected
procedure ShowApplyUpdateFailed (const Error: EDAApplyUpdateFailed);
function GetDetalles: IBizDetallesFacturasCliente;
procedure SetDetalles(Value: IBizDetallesFacturasCliente);
function GetCliente: IBizCliente;
procedure SetCliente(Value: IBizCliente);
procedure OnNewRecord(Sender: TDADataTable); override;
function GetSelectedRows : TSelectedRowList;
procedure BeforeDelete(Sender: TDADataTable); override;
procedure AfterDelete(Sender: TDADataTable); override;
procedure OnPostError(DataTable: TDADataTable; Error: EDatabaseError;
var Action: TDataAction); override;
procedure BeforeApplyUpdates(Sender : TDADataTable; const Delta : IDADelta);
public
procedure RecalcularImporte;
property Cliente: IBizCliente read GetCliente write SetCliente;
property Detalles: IBizDetallesFacturasCliente read GetDetalles write
SetDetalles;
procedure Show;
procedure Preview;
procedure Print;
procedure CopyFrom(AFacturaCliente : IBizFacturasCliente); overload;
procedure CopyFrom(AAlbaranCliente : IBizAlbaranesCliente); overload;
procedure DesglosarIVA;
constructor Create(aDataTable: TDADataTable); override;
destructor Destroy; override;
property SelectedRows : TSelectedRowList read GetSelectedRows;
end;
procedure ValidarFacturaCliente (const AFacturaCliente : IBizFacturasCliente);
implementation
uses
Windows, Dialogs, uDACDSDataTable, SysUtils, uEditorUtils, Variants, Math,
uDataModuleContactos, Controls, Forms,
uDataModuleBase, uDataModuleUsuarios,
uDataTableUtils, uDataModuleFacturasCliente, uEditarPreguntarIVA;
var
FMasterDeleting : Boolean;
FCancelInsert : Boolean;
procedure ValidarFacturaCliente (const AFacturaCliente : IBizFacturasCliente);
begin
if (FloatToStr(AFacturaCliente.FECHAFACTURA) = '0') then
raise Exception.Create('Debe indicar la fecha de esta factura');
if not Assigned(AFacturaCliente.Cliente) or
(AFacturaCliente.Cliente.DataTable.IsEmpty) then
raise Exception.Create('Debe indicar el cliente de esta factura');
{ AFacturaCliente.Edit;
if (FloatToStr(AFacturaCliente.FECHAPAGO) = '0') then
AFacturaCliente.SITUACION := SITUACION_PENDIENTE
else
AFacturaCliente.SITUACION := SITUACION_PAGADO;
AFacturaCliente.Post;}
if (Length(AFacturaCliente.REFERENCIA) = 0) then
begin
AFacturaCliente.Edit;
AFacturaCliente.REFERENCIA := dmFacturasCliente.DarNuevaReferencia;
AFacturaCliente.Post;
ShowMessage('A esta factura se le ha asignado la referencia ' + AFacturaCliente.REFERENCIA);
end;
end;
constructor TBizFacturasCliente.Create(aDataTable: TDADataTable);
begin
inherited;
FCliente := NIL;
FDetallesLink := TDADataSource.Create(NIL);
FSelectedRows := TSelectedRowList.Create(aDataTable);
aDataTable.OnBeforeApplyUpdates := BeforeApplyUpdates;
end;
destructor TBizFacturasCliente.Destroy;
begin
FCliente := NIL;
FDetalles := NIL;
FDetallesLink.Free;
FSelectedRows.Free;
inherited;
end;
function TBizFacturasCliente.GetCliente: IBizCliente;
begin
if not Assigned(FCliente) or
((CODIGOCONTACTO <> FCliente.Codigo) and
not (FCliente.DataTable.State in dsEditModes)) then
begin
FCliente := dmContactos.GetCliente(CODIGOCONTACTO);
if not FCliente.DataTable.Active then
FCliente.DataTable.Active := True;
if not FCliente.DataTable.IsEmpty then // Est<73> vac<61>o si la factura es nueva y no tiene cliente
begin
FCliente.Edit;
FCliente.NOMBRE := NOMBRE;
FCliente.NIFCIF := NIFCIF;
FCliente.CALLE := CALLE;
FCliente.CODIGOPOSTAL := CODIGOPOSTAL;
FCliente.PROVINCIA := PROVINCIA;
FCliente.POBLACION := POBLACION;
FCliente.Post;
end;
end;
Result := FCliente;
end;
function TBizFacturasCliente.GetDetalles: IBizDetallesFacturasCliente;
begin
Result := FDetalles;
end;
procedure TBizFacturasCliente.CopyFrom(AFacturaCliente : IBizFacturasCliente);
var
ACursor: TCursor;
begin
{ if not (State in dsEditModes) then
Edit;
ACursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
Application.ProcessMessages;
try
CODIGOEMPRESA := APresupuesto.CODIGOEMPRESA;
CODIGOCONTACTO := APresupuesto.CODIGOCONTACTO;
BASEIMPONIBLE := APresupuesto.BASEIMPONIBLE;
DESCUENTO := APresupuesto.DESCUENTO;
IVA := APresupuesto.IVA;
OBSERVACIONES := APresupuesto.OBSERVACIONES;
FORMAPAGO := APresupuesto.FORMAPAGO;
CODIGOPRESUPUESTO := APresupuesto.CODIGO;
Cliente := APresupuesto.Cliente;
Detalles.CopyFrom(APresupuesto.Detalles);
RecalcularImporte;
MessageBox(0, 'Se ha copiado correctamente el presupuesto elegido en este albar<61>n.', 'Presupuesto copiado', MB_ICONWARNING or MB_OK);
finally
Screen.Cursor := ACursor;
end;}
end;
procedure TBizFacturasCliente.OnNewRecord(Sender: TDADataTable);
begin
inherited;
CODIGOEMPRESA := dmBase.CodigoEmpresa;
USUARIO := dmUsuarios.LoginInfo.UserID;
FECHAALTA := Date;
FECHAFACTURA := Date;
CODIGO := dmFacturasCliente.GetNextAutoinc;
end;
procedure TBizFacturasCliente.Preview;
begin
dmFacturasCliente.Preview(Self.CODIGO);
end;
procedure TBizFacturasCliente.SetCliente(Value: IBizCliente);
var
bEnEdicion : Boolean;
begin
bEnEdicion := (DataTable.State in dsEditModes);
if not bEnEdicion then
Edit;
FCliente := Value;
if Assigned(FCliente) then
begin
CODIGOCONTACTO := FCliente.CODIGO;
NOMBRE := FCliente.NOMBRE;
NIFCIF := FCliente.NIFCIF;
CALLE := FCliente.CALLE;
CODIGOPOSTAL := FCliente.CODIGOPOSTAL;
PROVINCIA := FCliente.PROVINCIA;
POBLACION := FCliente.POBLACION;
if not bEnEdicion then
Post;
end
end;
procedure TBizFacturasCliente.SetDetalles(Value: IBizDetallesFacturasCliente);
begin
FDetalles := Value;
FDetallesLink.DataTable := Self.DataTable;
FDetalles.DataTable.MasterSource := FDetallesLink;
end;
procedure TBizFacturasCliente.Show;
begin
ShowEditor(IBizFacturasCliente, Self, etItem);
end;
procedure TBizDetallesFacturasCliente.ActivarEventos;
begin
FPuedoLanzarEvento := True;
end;
procedure TBizDetallesFacturasCliente.AfterDelete(Sender: TDADataTable);
var
ACabecera : IBizImportesCabecera;
begin
inherited;
// PARCHE *******************
if not PuedoLanzarEvento then
Exit;
if (not FMasterDeleting) and (not FCancelInsert) then
begin
ReasignarPosiciones(Self.DataTable);
if Assigned(DataTable.MasterSource) and
Supports(DataTable.MasterSource.DataTable, IBizImportesCabecera, ACabecera) then
ACabecera.RecalcularImporte;
end;
FCancelInsert := False;
end;
procedure TBizDetallesFacturasCliente.AfterInsert(Sender: TDADataTable);
begin
inherited;
// PARCHE *******************
if not PuedoLanzarEvento then
Exit;
FIsAppend := DataTable.EOF;
Post;
Edit; // Para volver a dejarlo en modo de edici<63>n
end;
procedure TBizDetallesFacturasCliente.AfterPost(Sender: TDADataTable);
begin
inherited;
// PARCHE *******************
if not PuedoLanzarEvento then
Exit;
if POSICION < 0 then
AsignarPosicion(Self.DataTable, FIsAppend);
if NUMCONCEPTO < 0 then
AsignarNumConcepto(Self.DataTable);
FIsAppend := False;
end;
procedure TBizDetallesFacturasCliente.BeforeDelete(Sender: TDADataTable);
begin
inherited;
// PARCHE *******************
if not PuedoLanzarEvento then
Exit;
if (DataTable.State in dsEditModes) then
DataTable.Cancel;
if not FMasterDeleting then
FCancelInsert := not (DataTable.MasterSource.DataTable.FieldByName('CODIGO').AsInteger = CODIGOFACTURA);
end;
procedure TBizDetallesFacturasCliente.BeforeInsert(Sender: TDADataTable);
begin
inherited;
// PARCHE *******************
if not PuedoLanzarEvento then
Exit;
if Assigned(DataTable.MasterSource) and
(DataTable.MasterSource.DataTable.State in dsEditModes) then
DataTable.MasterSource.DataTable.Post;
if GetRecordCount = 0 then
FPosicionNueva := -1
else
FPosicionNueva := POSICION * (-1);
end;
procedure TBizDetallesFacturasCliente.CopyFrom(ADetallesFacturas : IBizDetallesFacturasCliente);
begin
//
end;
procedure TBizDetallesFacturasCliente.CopyFrom(ADetallesAlbaranes : IBizDetallesAlbaranCliente);
var
ImporteSinIva : Double;
AcumulaSobrante : Double;
ImporteSinIvaRedondeado : Currency;
begin
DeleteAllTable(Self.DataTable);
AcumulaSobrante := 0;
ADetallesAlbaranes.First;
while not ADetallesAlbaranes.EOF do
begin
Append;
DataTable.DisableControls;
DataTable.DisableEventHandlers;
try
TIPO := ADetallesAlbaranes.TIPO;
DESCRIPCION := ADetallesAlbaranes.DESCRIPCION;
CANTIDAD := ADetallesAlbaranes.CANTIDAD;
IMPORTEUNIDAD := ADetallesAlbaranes.IMPORTEUNIDAD;
VISIBLE := ADetallesAlbaranes.VISIBLE;
VALORADO := ADetallesAlbaranes.VALORADO;
finally
DataTable.EnableControls;
DataTable.EnableEventHandlers;
end;
RecalcularImporte;
Post;
ADetallesAlbaranes.Next;
end;
RecalcularSubtotales(DataTable);
end;
constructor TBizDetallesFacturasCliente.Create(aDataTable: TDADataTable);
begin
inherited;
FPosicionNueva := 1; // Los conceptos empiezan a contar en 1
// PARCHE *******************
FPuedoLanzarEvento := True;
end;
function TBizDetallesFacturasCliente.DarSumaTotalImportes: Currency;
begin
Result := DarTotalDetalles(Self.DataTable, True, False);
end;
procedure TBizDetallesFacturasCliente.DesactivarEventos;
begin
FPuedoLanzarEvento := False;
end;
procedure TBizDetallesFacturasCliente.DesglosarIVA(IVA : Double);
var
ImporteSinIva : Double;
AcumulaSobrante : Double;
ImporteSinIvaRedondeado : Currency;
begin
AcumulaSobrante := 0;
if DataTable.IsEmpty then
Exit;
DataTable.First;
while not DataTable.EOF do
begin
DataTable.Edit;
DataTable.DisableControls;
DataTable.DisableEventHandlers;
try
ImporteSinIva := IMPORTEUNIDAD / (1 + IVA/100);
ImporteSinIvaRedondeado := RoundTo(ImporteSinIva, -2);
if ImporteSinIva < ImporteSinIvaRedondeado then
AcumulaSobrante := AcumulaSobrante - (CANTIDAD*(ImporteSinIvaRedondeado - ImporteSinIva))
else
AcumulaSobrante := AcumulaSobrante + (CANTIDAD*(ImporteSinIva - ImporteSinIvaRedondeado));
IMPORTEUNIDAD := ImporteSinIvaRedondeado;
finally
DataTable.EnableControls;
DataTable.EnableEventHandlers;
end;
RecalcularImporte;
DataTable.Post;
DataTable.Next;
end;
// Agregamos al <20>ltimo concepto de los detalles los decimales
// que hemos ido acumulando
while (not DataTable.BOF) and (TIPO <> TIPODETALLE_CONCEPTO) do
DataTable.Prior;
Edit;
IMPORTEUNIDAD := IMPORTEUNIDAD + AcumulaSobrante;
RecalcularSubtotales(DataTable);
end;
procedure TBizDetallesFacturasCliente.OnNewRecord(Sender: TDADataTable);
begin
inherited;
// PARCHE *******************
if not PuedoLanzarEvento then
Exit;
POSICION := FPosicionNueva;
NUMCONCEPTO := -1;
TIPO := TIPODETALLE_CONCEPTO;
VISIBLE := VISIBLE_TRUE;
VALORADO := VALORADO_TRUE;
end;
function TBizFacturasCliente.GetSelectedRows: TSelectedRowList;
begin
Result := FSelectedRows;
end;
procedure TBizFacturasCliente.ShowApplyUpdateFailed(
const Error: EDAApplyUpdateFailed);
begin
if (Pos(AUF_FKVIOLATION, Error.Message) > 0) then
MessageBox(0, 'No se puede borrar esta factura porque...', 'Atenci<63>n', MB_ICONWARNING or MB_OK);
end;
procedure TBizFacturasCliente.BeforeDelete(Sender: TDADataTable);
begin
inherited;
if not dmFacturasCliente.PuedoEliminarFactura(CODIGO) then
raise Exception.Create('No se puede borrar esta factura porque...');
FMasterDeleting := True; // Para que los detalles de borren de golpe y no recalcule posiciones ni totales
end;
procedure TBizFacturasCliente.AfterDelete(Sender: TDADataTable);
begin
inherited;
FMasterDeleting := False;
end;
procedure TBizFacturasCliente.Print;
begin
dmFacturasCliente.Print(Self.CODIGO);
end;
procedure TBizFacturasCliente.OnPostError(DataTable: TDADataTable;
Error: EDatabaseError; var Action: TDataAction);
begin
inherited;
Action := daAbort;
if (Pos(AUF_HAVEVALUE, Error.Message) > 0) then
begin
if (Pos('contacto', Error.Message) > 0) then
MessageBox(0, 'Debe indicar el cliente de esta factura', 'Atenci<63>n', MB_ICONWARNING or MB_OK)
else
if (Pos('Fecha', Error.Message) > 0) then
MessageBox(0, 'Debe indicar la fecha de esta factura', 'Atenci<63>n', MB_ICONWARNING or MB_OK)
else
raise Error;
end
else
raise Error;
end;
procedure TBizFacturasCliente.BeforeApplyUpdates(Sender: TDADataTable;
const Delta: IDADelta);
var
i : integer;
begin
for i := 0 to Delta.Count - 1 do
case Delta.Changes[i].ChangeType of
ctInsert, ctUpdate : ValidarFacturaCliente(Self);
//ctDelete :
end;
end;
function TBizDetallesFacturasCliente.PuedoLanzarEvento: Boolean;
begin
Result := FPuedoLanzarEvento;
end;
procedure TBizDetallesFacturasCliente.RecalcularImporte;
begin
RecalcularImporteDetalle(Self.DataTable, True, False);
end;
procedure TBizFacturasCliente.RecalcularImporte;
begin
RecalcularImportesCabecera(Self.DataTable, Detalles.DataTable);
end;
procedure TBizFacturasCliente.CopyFrom(AAlbaranCliente: IBizAlbaranesCliente);
var
ACursor: TCursor;
begin
if not (State in dsEditModes) then
Edit;
if not (AAlbaranCliente.DataTable.Active) then
AAlbaranCliente.DataTable.Active := True;
ACursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
Application.ProcessMessages;
try
CODIGOEMPRESA := AAlbaranCliente.CODIGOEMPRESA;
CODIGOCONTACTO := AAlbaranCliente.CODIGOCONTACTO;
NOMBRE := AAlbaranCliente.Cliente.NOMBRE;
BASEIMPONIBLE := AAlbaranCliente.BASEIMPONIBLE;
DESCUENTO := AAlbaranCliente.DESCUENTO;
IVA := AAlbaranCliente.IVA;
OBSERVACIONES := AAlbaranCliente.OBSERVACIONES;
FORMAPAGO := AAlbaranCliente.FORMAPAGO;
CODIGOALBARAN := AAlbaranCliente.CODIGO;
Cliente := AAlbaranCliente.Cliente;
Detalles.CopyFrom(AAlbaranCliente.Detalles);
RecalcularImporte;
finally
Screen.Cursor := ACursor;
end;
end;
procedure TBizDetallesFacturasCliente.Refrescar;
begin
DataTable.Refresh;
end;
procedure TBizDetallesFacturasCliente.SetCANTIDADValue(const aValue: Integer);
begin
if aValue = 0
then DataTable.Fields[idx_DetallesFacturasClienteCANTIDAD].AsVariant := Null
else inherited;
end;
procedure TBizDetallesFacturasCliente.SetIMPORTETOTALValue(const aValue: Currency);
begin
if aValue = 0
then DataTable.Fields[idx_DetallesFacturasClienteIMPORTETOTAL].AsVariant := Null
else inherited;
end;
procedure TBizDetallesFacturasCliente.SetIMPORTEUNIDADValue(const aValue: Currency);
begin
if aValue = 0 then
DataTable.Fields[idx_DetallesFacturasClienteIMPORTEUNIDAD].AsVariant := Null
else
inherited;
end;
procedure TBizFacturasCliente.DesglosarIVA;
var
aIVA : Double;
ACursor: TCursor;
begin
if (Self.IVA = 0) then
aIVA := 21;
if PreguntarIVA(aIVA) then
begin
ACursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
Application.ProcessMessages;
try
DataTable.Edit;
Self.IVA := aIVA;
Detalles.DesglosarIVA(aIVA);
RecalcularImporte;
finally
Screen.Cursor := ACursor;
end;
MessageBox(0, 'Se ha desglosado el IVA de la factura', 'Informaci<63>n', MB_ICONINFORMATION or MB_OK)
end;
end;
initialization
FMasterDeleting := False;
RegisterDataTableRules(BIZ_DETALLESFACTURASCLIENTE, TBizDetallesFacturasCliente);
RegisterDataTableRules(BIZ_FACTURASCLIENTE, TBizFacturasCliente);
finalization
end.