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/Presupuestos/Reglas/uBizPresupuestosCliente.pas

630 lines
19 KiB
ObjectPascal

unit uBizPresupuestosCliente;
interface
uses
uDAInterfaces, uDADataTable, schPresupuestosClient_Intf, Classes,
uBizContacto, uDBSelectionList, Controls, uBizImportesDetalleBase,
uBizImportesCabeceraBase, uExceptions, uBizInformesBase, DB,
uBizDocumentosAsociados;
const
BIZ_PRESUPUESTOCLIENTE = 'Client.PresupuestoCliente';
BIZ_DETALLESPRESUPUESTOCLIENTE = 'Client.DetallesPresupuestoCliente';
SITUACION_PENDIENTE = 'Pendiente';
SITUACION_ACEPTADO = 'Aceptado';
SITUACION_RECHAZADO = 'Rechazado';
TIPO_COCINA = 'Cocina';
TIPO_BANO = 'Baño';
TIPO_ARREGLO_C = 'Arreglo C';
TIPO_ARREGLO_B = 'Arreglo B';
TIPO_INCIDENCIA = 'Inciencia';
type
IBizDetallesPresupuesto = interface(IDetallesPresupuestos)
['{7233E1B0-5B76-4AE4-AB05-4F12EF74FBDD}']
procedure CopyFrom(ADetallesPresupuesto : IBizDetallesPresupuesto);
end;
IBizPresupuestos = interface(IPresupuestos)
['{C699A849-3F52-486B-93AC-1EB0E6B5632F}']
function GetDetalles: IBizDetallesPresupuesto;
procedure SetDetalles(Value: IBizDetallesPresupuesto);
property Detalles: IBizDetallesPresupuesto read GetDetalles write
SetDetalles;
function GetCliente: IBizCliente;
procedure SetCliente(Value: IBizCliente);
property Cliente: IBizCliente read GetCliente write SetCliente;
//DOCUMENTOS ASOCIADOS
function GetGestorDocumentos: TGestorDocumentos;
procedure SetGestorDocumentos(Value: TGestorDocumentos);
property GestorDocumentos: TGestorDocumentos read GetGestorDocumentos write SetGestorDocumentos;
procedure Show;
procedure CopyFrom(APresupuesto : IBizPresupuestos);
function ShowForSelect : TModalResult;
end;
TBizDetallesPresupuesto = class(TDetallesPresupuestosDataTableRules,
IBizDetallesPresupuesto,
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;
procedure SetPUNTOSValue(const aValue: Integer); override;
procedure SetIMPORTEPUNTOSValue(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 CopyFrom(ADetallesPresupuesto : IBizDetallesPresupuesto);
procedure RecalcularImporte;
function DarSumaTotalImportes : Currency;
constructor Create(aDataTable: TDADataTable); override;
end;
TBizPresupuestos = class(TPresupuestosDataTableRules, IBizPresupuestos,
IBizImportesCabecera, ISelectedRowList,
IApplyUpdateFailedException, IBizInformesAware,
IBizDocumentosAsociados)
private
FCliente : IBizCliente;
FDetalles: IBizDetallesPresupuesto;
FDetallesLink: TDADataSource;
FSelectedRows : TSelectedRowList;
//DOCUMENTOS ASOCIADOS
FGestorDocumentos: TGestorDocumentos;
function GetGestorDocumentos: TGestorDocumentos;
procedure SetGestorDocumentos(Value: TGestorDocumentos);
procedure BeforeDelete(Sender: TDADataTable); override;
procedure BeforeCancel(Sender: TDADataTable); override;
protected
procedure ShowApplyUpdateFailed (const Error: EDAApplyUpdateFailed);
function GetDetalles: IBizDetallesPresupuesto;
procedure SetDetalles(Value: IBizDetallesPresupuesto);
function GetCliente: IBizCliente;
procedure SetCliente(Value: IBizCliente);
procedure BeforeApplyUpdates(Sender : TDADataTable; const Delta : IDADelta);
procedure OnNewRecord(Sender: TDADataTable); override;
function GetSelectedRows : TSelectedRowList;
procedure AfterDelete(Sender: TDADataTable); override;
procedure OnPostError(DataTable: TDADataTable; Error: EDatabaseError;
var Action: TDataAction); override;
public
constructor Create(aDataTable: TDADataTable); override;
destructor Destroy; override;
procedure RecalcularImporte;
procedure Show;
function ShowForSelect : TModalResult;
procedure Preview;
procedure Print;
procedure CopyFrom(APresupuesto : IBizPresupuestos);
property Cliente: IBizCliente read GetCliente write SetCliente;
property Detalles: IBizDetallesPresupuesto read GetDetalles write SetDetalles;
property SelectedRows : TSelectedRowList read GetSelectedRows;
//DOCUMENTOS ASOCIADOS
property GestorDocumentos: TGestorDocumentos read GetGestorDocumentos write SetGestorDocumentos;
end;
procedure ValidarPresupuesto (const APresupuesto : IBizPresupuestos);
implementation
uses
Windows, Dialogs, uDACDSDataTable, SysUtils, uEditorUtils,
uDataModulePresupuestos, uDataModuleContactos, Variants, Math,
uDataModuleBase, uDataModuleUsuarios, FactuGES_Intf, uDataTableUtils;
var
FMasterDeleting : Boolean;
FCancelInsert : Boolean;
cadena1, cadena2 : string;
procedure ValidarPresupuesto (const APresupuesto : IBizPresupuestos);
begin
if (FloatToStr(APresupuesto.FECHAPRESUPUESTO) = '0') then
raise Exception.Create('Debe indicar la fecha de este presupuesto');
if not Assigned(APresupuesto.Cliente) or
(APresupuesto.Cliente.DataTable.IsEmpty) then
raise Exception.Create('Debe indicar el cliente de este presupuesto');
if (FloatToStr(APresupuesto.FECHADECISION) <> '0') and
(APresupuesto.SITUACION <> SITUACION_PENDIENTE) and
(APresupuesto.FECHADECISION < APresupuesto.FECHAPRESUPUESTO) then
raise Exception.Create('La fecha de decisición debe ser posterior a la fecha del presupuesto');
if ((APresupuesto.Tipo = TIPO_INCIDENCIA) and
(APresupuesto.BASEIMPONIBLE <> 0)) then
raise Exception.Create('Una incidencia debe tener importe 0 para el cliente');
if (APresupuesto.SITUACION <> SITUACION_PENDIENTE) and
(FloatToStr(APresupuesto.FECHADECISION) = '0') then
begin
APresupuesto.Edit;
APresupuesto.FECHADECISION := Date;
APresupuesto.Post;
end;
end;
procedure TBizPresupuestos.RecalcularImporte;
begin
RecalcularImportesCabecera(Self.DataTable, Detalles.DataTable);
end;
constructor TBizPresupuestos.Create(aDataTable: TDADataTable);
var
Ruta: Variant;
begin
inherited;
FCliente := NIL;
FDetallesLink := TDADataSource.Create(NIL);
FSelectedRows := TSelectedRowList.Create(aDataTable);
aDataTable.OnBeforeApplyUpdates := BeforeApplyUpdates;
//DOCUMENTOS ASOCIADOS
//En caso de no poder acceder a la ruta de red (Caso de dos tiendas conectadas por internet)
//deshabilitamos el gestor de documentos
Ruta := dmBase.darRutaDocumentos;
if VarIsNull(Ruta) then
FGestorDocumentos := Nil
else
begin
FGestorDocumentos := TGestorDocumentos.Create;
FGestorDocumentos.RootDocumentos := dmBase.darRutaDocumentos;
aDataTable.BeforeCancel := BeforeCancel;
end;
end;
destructor TBizPresupuestos.Destroy;
begin
FCliente := NIL;
FDetalles := NIL;
FDetallesLink.Free;
FSelectedRows.Free;
FreeAndNil(FGestorDocumentos);
inherited;
end;
function TBizPresupuestos.GetDetalles: IBizDetallesPresupuesto;
begin
Result := FDetalles;
end;
function TBizPresupuestos.GetSelectedRows: TSelectedRowList;
begin
Result := FSelectedRows;
end;
procedure TBizPresupuestos.OnNewRecord(Sender: TDADataTable);
begin
inherited;
CODIGOEMPRESA := dmBase.CodigoEmpresa;
USUARIO := dmUsuarios.LoginInfo.UserID;
FECHAALTA := Date;
FECHAPRESUPUESTO := Date;
VIGENCIAPRESUPUESTO := Date + 30; // 30 días de validez por defecto
SITUACION := SITUACION_PENDIENTE;
TIPO := TIPO_COCINA;
CODIGO := dmPresupuestos.GetNextAutoinc;
OPCION := 'OPCIÓN 1';
Self.DataTable.FieldByName('OBSERVACIONES').AsString := 'No está incluido ningún trabajo de electricidad y fontanería. Se presupuesta aparte.';
end;
procedure TBizPresupuestos.Preview;
begin
dmPresupuestos.Preview(CODIGO);
end;
function TBizPresupuestos.GetCliente: IBizCliente;
begin
if not Assigned(FCliente) then
FCliente := dmContactos.GetCliente(CODIGOCONTACTO)
else
if (CODIGOCONTACTO <> FCliente.Codigo) and
not (FCliente.DataTable.State in dsEditModes) then
dmContactos.GetContacto(FCliente, CODIGOCONTACTO);
if not FCliente.DataTable.Active then
FCliente.DataTable.Active := True;
Result := FCliente;
end;
procedure TBizPresupuestos.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;
Post;
if bEnEdicion then
Edit;
end
end;
procedure TBizPresupuestos.SetDetalles(
Value: IBizDetallesPresupuesto);
begin
FDetalles := Value;
FDetallesLink.DataTable := Self.DataTable;
FDetalles.DataTable.MasterSource := FDetallesLink;
end;
procedure TBizPresupuestos.Show;
begin
ShowEditor(IBizPresupuestos, Self, etItem);
end;
procedure TBizDetallesPresupuesto.ActivarEventos;
begin
FPuedoLanzarEvento := True;
end;
procedure TBizDetallesPresupuesto.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 TBizDetallesPresupuesto.AfterInsert(Sender: TDADataTable);
begin
inherited;
// PARCHE *******************
if not PuedoLanzarEvento then
Exit;
FIsAppend := DataTable.EOF;
Post; // Para lanzar AfterPost y asigne posición
Edit; // Para volver a dejarlo en modo de edición
end;
procedure TBizDetallesPresupuesto.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 TBizDetallesPresupuesto.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 = CODIGOPRESUPUESTO);
end;
procedure TBizDetallesPresupuesto.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 TBizDetallesPresupuesto.CopyFrom(
ADetallesPresupuesto: IBizDetallesPresupuesto);
begin
DeleteAllTable(Self.DataTable);
ADetallesPresupuesto.First;
while not ADetallesPresupuesto.EOF do
begin
DataTable.Append;
DataTable.DisableEventHandlers;
try
POSICION := ADetallesPresupuesto.POSICION;
TIPO := ADetallesPresupuesto.TIPO;
DESCRIPCION := ADetallesPresupuesto.DESCRIPCION;
CANTIDAD := ADetallesPresupuesto.CANTIDAD;
IMPORTEUNIDAD := ADetallesPresupuesto.IMPORTEUNIDAD;
IMPORTETOTAL := ADetallesPresupuesto.IMPORTETOTAL;
PUNTOS := ADetallesPresupuesto.PUNTOS;
IMPORTEPUNTOS := ADetallesPresupuesto.IMPORTEPUNTOS;
VISIBLE := ADetallesPresupuesto.VISIBLE;
VALORADO := ADetallesPresupuesto.VALORADO;
finally
DataTable.EnableEventHandlers;
end;
DataTable.Post;
ADetallesPresupuesto.Next;
end;
end;
constructor TBizDetallesPresupuesto.Create(aDataTable: TDADataTable);
begin
inherited;
FPosicionNueva := 1; // Los conceptos empiezan a contar en 1
// PARCHE *******************
FPuedoLanzarEvento := True;
end;
function TBizDetallesPresupuesto.DarSumaTotalImportes: Currency;
begin
Result := DarTotalDetalles(Self.DataTable, True, True);
end;
procedure TBizDetallesPresupuesto.DesactivarEventos;
begin
FPuedoLanzarEvento := False
end;
procedure TBizDetallesPresupuesto.OnNewRecord(Sender: TDADataTable);
begin
inherited;
// PARCHE *******************
if not PuedoLanzarEvento then
Exit;
POSICION := FPosicionNueva;
NUMCONCEPTO := -1;
TIPO := TIPODETALLE_CONCEPTO;
VISIBLE := VISIBLE_TRUE;
VALORADO := VALORADO_TRUE;
Self.DataTable.DisableEventHandlers;
try
CANTIDAD := 1;
finally
Self.DataTable.EnableEventHandlers;
end;
end;
function TBizPresupuestos.ShowForSelect : TModalResult;
begin
Result := ShowEditor(IBizPresupuestos, Self, etSelectItems);
end;
procedure TBizPresupuestos.ShowApplyUpdateFailed(
const Error: EDAApplyUpdateFailed);
begin
if (Pos(AUF_FKVIOLATION, Error.Message) > 0) then
MessageBox(0, 'No se puede borrar este presupuesto porque tiene un montaje o un montaje o albarán asociado', 'Atención', MB_ICONWARNING or MB_OK);
end;
procedure TBizPresupuestos.BeforeDelete(Sender: TDADataTable);
begin
inherited;
if not dmPresupuestos.PuedoEliminarPresupuesto(CODIGO) then
raise Exception.Create('No se puede borrar este presupuesto porque tiene un montaje o albarán asociado');
FMasterDeleting := True; // Para que los detalles se borren de golpe y no recalcule posiciones ni totales
//DOCUMENTOS ASOCIADOS
if Assigned(GestorDocumentos) then
begin
GestorDocumentos.Directorio := CODIGO;
GestorDocumentos.procesarDeleteTable;
end;
end;
procedure TBizPresupuestos.AfterDelete(Sender: TDADataTable);
begin
inherited;
FMasterDeleting := False;
end;
procedure TBizPresupuestos.Print;
begin
dmPresupuestos.Print(CODIGO);
end;
procedure TBizPresupuestos.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 : ValidarPresupuesto(Self);
//ctDelete :
end;
end;
procedure TBizPresupuestos.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 este presupuesto', 'Atención', MB_ICONWARNING or MB_OK);
if (Pos('Fecha presupuesto', Error.Message) > 0) then
MessageBox(0, 'Debe indicar la fecha de este presupuesto', 'Atención', MB_ICONWARNING or MB_OK);
end
else
raise Error;
end;
function TBizDetallesPresupuesto.PuedoLanzarEvento: Boolean;
begin
Result := FPuedoLanzarEvento;
end;
procedure TBizDetallesPresupuesto.RecalcularImporte;
begin
RecalcularImporteDetalle(Self.DataTable, True, True);
end;
procedure TBizPresupuestos.CopyFrom(APresupuesto: IBizPresupuestos);
begin
DataTable.DisableEventHandlers;
try
if not APresupuesto.DataTable.Active then
APresupuesto.DataTable.Active := True;
CODIGOEMPRESA := APresupuesto.CODIGOEMPRESA;
TIPO := APresupuesto.TIPO;
CODIGOCONTACTO := APresupuesto.CODIGOCONTACTO;
NOMBRE := APresupuesto.NOMBRE;
Cliente := APresupuesto.Cliente;
BASEIMPONIBLE := APresupuesto.BASEIMPONIBLE;
DESCUENTO := APresupuesto.DESCUENTO;
IMPORTEDESCUENTO := APresupuesto.IMPORTEDESCUENTO;
IVA := APresupuesto.IVA;
IMPORTEIVA := APresupuesto.IMPORTEIVA;
IMPORTETOTAL := APresupuesto.IMPORTETOTAL;
OBSERVACIONES := APresupuesto.OBSERVACIONES;
PLAZOENTREGA := APresupuesto.PLAZOENTREGA;
FORMAPAGO := APresupuesto.FORMAPAGO;
finally
DataTable.EnableEventHandlers;
end;
Post;
Detalles.CopyFrom(APresupuesto.Detalles);
end;
procedure TBizDetallesPresupuesto.Refrescar;
begin
DataTable.Refresh;
end;
procedure TBizDetallesPresupuesto.SetCANTIDADValue(const aValue: Integer);
begin
if aValue = 0
then DataTable.Fields[idx_DetallesPresupuestosCANTIDAD].AsVariant := Null
else inherited;
end;
procedure TBizDetallesPresupuesto.SetIMPORTEPUNTOSValue(const aValue: Currency);
begin
if aValue = 0
then DataTable.Fields[idx_DetallesPresupuestosIMPORTEPUNTOS].AsVariant := Null
else inherited;
end;
procedure TBizDetallesPresupuesto.SetIMPORTETOTALValue(const aValue: Currency);
begin
if aValue = 0
then DataTable.Fields[idx_DetallesPresupuestosIMPORTETOTAL].AsVariant := Null
else inherited;
end;
procedure TBizDetallesPresupuesto.SetIMPORTEUNIDADValue(const aValue: Currency);
begin
if aValue = 0
then DataTable.Fields[idx_DetallesPresupuestosIMPORTEUNIDAD].AsVariant := Null
else inherited;
end;
procedure TBizDetallesPresupuesto.SetPUNTOSValue(const aValue: Integer);
begin
if aValue = 0
then DataTable.Fields[idx_DetallesPresupuestosPUNTOS].AsVariant := Null
else inherited;
end;
procedure TBizPresupuestos.BeforeCancel(Sender: TDADataTable);
begin
if Assigned(GestorDocumentos) then
GestorDocumentos.procesarCancelTable;
end;
function TBizPresupuestos.GetGestorDocumentos: TGestorDocumentos;
begin
if Assigned(FGestorDocumentos) then
FGestorDocumentos.Directorio := CODIGO;
Result := FGestorDocumentos;
end;
procedure TBizPresupuestos.SetGestorDocumentos(Value: TGestorDocumentos);
begin
FGestorDocumentos := Value;
end;
initialization
FMasterDeleting := False;
RegisterDataTableRules(BIZ_DETALLESPRESUPUESTOCLIENTE, TBizDetallesPresupuesto);
RegisterDataTableRules(BIZ_PRESUPUESTOCLIENTE, TBizPresupuestos);
finalization
end.