Tecsitel_FactuGES2/Source/Modulos/Facturas de proveedor/Controller/uFacturasProveedorController.pas

1188 lines
40 KiB
ObjectPascal
Raw Blame History

unit uFacturasProveedorController;
interface
uses
Classes, SysUtils, uDADataTable, uControllerBase, uIDataModuleFacturasProveedor,
uProveedoresController, uDetallesFacturaProveedorController, uBizFacturasProveedor,
uBizAlbaranesProveedor;
type
IFacturasProveedorController = interface(IControllerBase)
['{3868267C-E61A-4B79-AF61-648B2D627F56}']
function GetProveedorController: IProveedoresController;
procedure SetProveedorController(const Value: IProveedoresController);
property ProveedorController: IProveedoresController read GetProveedorController write SetProveedorController;
function GetDetallesController: IDetallesFacturaProveedorController;
procedure SetDetallesController(const Value: IDetallesFacturaProveedorController);
property DetallesController: IDetallesFacturaProveedorController read GetDetallesController write SetDetallesController;
function Buscar(const ID: Integer): IBizFacturaProveedor;
function BuscarTodos: IBizFacturaProveedor; overload;
function BuscarTodos(const ID_Proveedor : Integer): IBizFacturaProveedor; overload;
function BuscarTodosDelPedido(const ID_Pedido : Integer): IBizFacturaProveedor;
procedure Ver(AFactura : IBizFacturaProveedor);
procedure VerTodos(AFacturas: IBizFacturaProveedor;
const AVerModal : Boolean = False; const AWindowCaption: String = '';
const AHeaderText: String = '');
function Nuevo (withInsert: Boolean = True) : IBizFacturaProveedor;
function Anadir(AFactura : IBizFacturaProveedor) : Boolean; overload;
function AnadirAbono(AFactura : IBizFacturaProveedor) : Boolean;
// function Anadir(AFacturas : IBizFacturaProveedor; AListaAlbaranes : IBizAlbaranProveedor): Boolean; overload;
function Anadir(AFactura : IBizFacturaProveedor; const IDPedido : Integer): Boolean; overload;
function Eliminar(const ID : Integer): Boolean; overload;
function Eliminar(AFactura : IBizFacturaProveedor; AllItems: Boolean = false): Boolean; overload;
function Guardar(AFactura : IBizFacturaProveedor): Boolean;
procedure DescartarCambios(AFactura : IBizFacturaProveedor);
function Existe(const ID: Integer) : Boolean;
procedure RecuperarProveedor(AFactura : IBizFacturaProveedor);
function Duplicar(AFactura: IBizFacturaProveedor): IBizFacturaProveedor;
function GenerarAbono(AFactura: IBizFacturaProveedor): IBizFacturaProveedor;
procedure Preview(AFactura : IBizFacturaProveedor; AllItems: Boolean = false);
procedure Print(AFactura : IBizFacturaProveedor; AllItems: Boolean = false);
procedure RecalcularImportes(FFactura: IBizFacturaProveedor);
function EsModificable(AFactura: IBizFacturaProveedor): Boolean;
function EsEliminable(AFactura: IBizFacturaProveedor): Boolean;
function ElegirFacturas(AFacturas : IBizFacturaProveedor; AMensaje: String; AMultiSelect: Boolean): IBizFacturaProveedor;
function ExtraerSeleccionados(ARecibosProveedor: IBizFacturaProveedor) : IBizFacturaProveedor;
function DarListaAnosFacturas: TStringList;
procedure FiltrarAno(AFactura: IBizFacturaProveedor; ADynWhereDataTable: WideString; const Ano: String);
function AsignarCuentaBancaria(AFacturas: IBizFacturaProveedor): TStringList;
function AsignarVencimiento(AFacturas: IBizFacturaProveedor): TStringList;
end;
TFacturasProveedorController = class(TControllerBase, IFacturasProveedorController)
private
FDataModule : IDataModuleFacturasProveedor;
FProveedorController : IProveedoresController;
FDetallesController : IDetallesFacturaProveedorController;
function GetProveedorController: IProveedoresController;
procedure SetProveedorController(const Value: IProveedoresController);
function GetDetallesController: IDetallesFacturaProveedorController;
procedure SetDetallesController(const Value: IDetallesFacturaProveedorController);
function CreateEditor(const AName : String; const IID: TGUID; out Intf): Boolean;
function _Vacio : IBizFacturaProveedor;
procedure FiltrarEmpresa(AFactura: IBizFacturaProveedor);
function ValidarFactura(AFactura: IBizFacturaProveedor): Boolean;
procedure GenerarRecibos(AFactura: IBizFacturaProveedor);
protected
procedure RecibirAviso(ASujeto: ISujeto; ADataTable: IDAStronglyTypedDataTable); override;
public
property ProveedorController: IProveedoresController read GetProveedorController write SetProveedorController;
property DetallesController: IDetallesFacturaProveedorController read GetDetallesController write SetDetallesController;
constructor Create; override;
destructor Destroy; override;
function Eliminar(const ID : Integer): Boolean; overload;
function Eliminar(AFactura : IBizFacturaProveedor; AllItems: Boolean = false): Boolean; overload;
function Guardar(AFactura : IBizFacturaProveedor): Boolean;
procedure DescartarCambios(AFactura : IBizFacturaProveedor); virtual;
function Existe(const ID: Integer) : Boolean; virtual;
function Anadir(AFactura : IBizFacturaProveedor) : Boolean; overload;
function AnadirAbono(AFactura : IBizFacturaProveedor) : Boolean;
// function Anadir(AFacturas : IBizFacturaProveedor; AListaAlbaranes : IBizAlbaranProveedor): Boolean; overload;
function Anadir(AFactura : IBizFacturaProveedor; const IDPedido : Integer): Boolean; overload;
function Buscar(const ID: Integer): IBizFacturaProveedor;
function BuscarTodos: IBizFacturaProveedor; overload;
function BuscarTodos(const ID_Proveedor : Integer): IBizFacturaProveedor; overload;
function BuscarTodosDelPedido(const ID_Pedido : Integer): IBizFacturaProveedor;
// function BuscarTodasPendientesComision(IdAgente: Integer; IdComision: Integer; IdFacturasAsociadas: String): IBizFacturaProveedor;
function Nuevo (withInsert: Boolean = True): IBizFacturaProveedor;
procedure Ver(AFactura : IBizFacturaProveedor);
procedure VerTodos(AFacturas: IBizFacturaProveedor;
const AVerModal : Boolean = False; const AWindowCaption: String = '';
const AHeaderText: String = '');
function Duplicar(AFactura: IBizFacturaProveedor): IBizFacturaProveedor;
function GenerarAbono(AFactura: IBizFacturaProveedor): IBizFacturaProveedor;
procedure RecuperarProveedor(AFactura : IBizFacturaProveedor);
procedure Preview(AFactura : IBizFacturaProveedor; AllItems: Boolean = false);
procedure Print(AFactura : IBizFacturaProveedor; AllItems: Boolean = false);
procedure RecalcularImportes(FFactura: IBizFacturaProveedor);
function EsModificable(AFactura: IBizFacturaProveedor): Boolean;
function EsEliminable(AFactura: IBizFacturaProveedor): Boolean;
function ElegirFacturas(AFacturas : IBizFacturaProveedor; AMensaje: String; AMultiSelect: Boolean): IBizFacturaProveedor;
function ExtraerSeleccionados(AFacturasProveedor: IBizFacturaProveedor) : IBizFacturaProveedor;
function DarListaAnosFacturas: TStringList;
procedure FiltrarAno(AFactura: IBizFacturaProveedor; ADynWhereDataTable: WideString; const Ano: String);
function AsignarCuentaBancaria(AFacturas: IBizFacturaProveedor): TStringList;
function AsignarVencimiento(AFacturas: IBizFacturaProveedor): TStringList;
end;
implementation
uses
Windows, Controls, cxControls, DB, uEditorRegistryUtils, schFacturasProveedorClient_Intf,
uBizContactos, uIEditorFacturasProveedor, uIEditorFacturaProveedor, uFactuGES_App,
uDataModuleFacturasProveedor, uBizDetallesFacturaProveedor, uControllerDetallesBase,
uDataModuleUsuarios, uDAInterfaces, uDataTableUtils, uDateUtils, uROTypes,
uAlbaranesProveedorController, schAlbaranesProveedorClient_Intf, uDetallesAlbaranProveedorController,
uBizPedidosProveedor, uPedidosProveedorController, uBizDetallesPedidoProveedor,
uRecibosProveedorController, uBizRecibosProveedor, uNumUtils,
uFacturasProveedorReportController, DateUtils, Forms, Dialogs,
uFormasPagoController, uBizFormasPago, uStringsUtils,
uIEditorElegirDomiciliacion, uIEditorElegirFechaVencimiento,
cxEdit;
procedure CopiarArticulosPedido(AOrigen: IBizDetallesPedidoProveedor;
ADestino : IBizDetallesFacturaProveedor);
var
i : integer;
ADetallesController : IDetallesFacturaProveedorController;
begin
if not Assigned(AOrigen) then
raise Exception.Create ('Origen no asignado (CopiarArticulosPedido)');
if not Assigned(ADestino) then
raise Exception.Create ('Destino no asignado (CopiarArticulosPedido)');
if not AOrigen.DataTable.Active then
AOrigen.DataTable.Active := True;
if not ADestino.DataTable.Active then
ADestino.DataTable.Active := True;
ADetallesController := TDetallesFacturaProveedorController.Create;
try
//OJO IMPORTANTE
//Siempre que vayamos a trabajar con los detalles debemos hacer un beginupdate de los mismos y un endupdate para
//obligarle siempre a recalcular los detalles una sola vez
ADetallesController.BeginUpdate(ADestino);
AOrigen.DataTable.First;
for i := 0 to AOrigen.DataTable.RecordCount - 1 do
begin
ADetallesController.Add(ADestino, TIPO_DETALLE_CONCEPTO);
ADestino.Edit;
ADestino.REFERENCIA := AOrigen.REFERENCIA;
if AOrigen.ID_ARTICULO > 0 then
ADestino.ID_ARTICULO := AOrigen.ID_ARTICULO;
ADestino.CONCEPTO := AOrigen.CONCEPTO;
ADestino.CANTIDAD := AOrigen.CANTIDAD;
ADestino.IMPORTE_UNIDAD := AOrigen.IMPORTE_UNIDAD;
ADestino.IMPORTE_TOTAL := AOrigen.IMPORTE_TOTAL;
ADestino.DESCUENTO := AOrigen.DESCUENTO;
ADestino.IMPORTE_PORTE := AOrigen.IMPORTE_PORTE;
ADestino.VISIBLE := AOrigen.VISIBLE;
ADestino.REFERENCIA_PROVEEDOR := AOrigen.REFERENCIA_PROVEEDOR;
ADestino.Post;
AOrigen.Next;
end;
finally
ADetallesController.EndUpdate(ADestino);
ADetallesController := NIL;
end;
end;
{ TFacturasProveedorController }
function TFacturasProveedorController.Anadir(AFactura: IBizFacturaProveedor) : Boolean;
begin
if not Assigned(AFactura) then
raise Exception.Create ('Factura no asignada (Anadir)');
AFactura.Insert;
Result := True;
end;
function TFacturasProveedorController.Anadir(AFactura: IBizFacturaProveedor;
const IDPedido: Integer): Boolean;
var
APedidosController : IPedidosProveedorController;
APedido : IBizPedidoProveedor;
begin
Result := False;
if not Assigned(AFactura) then
raise Exception.Create ('Factura no asignada (Anadir)');
if (IDPedido < 0) or (IDPedido = 0) then
raise Exception.Create (Format('ID de pedido (%d) incorrecto (Anadir)', [IDPedido]));
if not AFactura.DataTable.Active then
AFactura.DataTable.Active := True;
ShowHourglassCursor;
Application.ProcessMessages;
APedido := NIL;
APedidosController := TPedidosProveedorController.Create;
try
APedido := APedidosController.Buscar(IDPedido);
if not Assigned(APedido) then
raise Exception.Create (Format('No se ha encontrado un pedido de Proveedor con ID %d (Anadir)', [IDPedido]));
APedido.DataTable.Active := True;
APedidosController.RecuperarProveedor(APedido);
Self.Anadir(AFactura);
AFactura.Proveedor := APedido.Proveedor;
CopiarArticulosPedido(APedido.Detalles, AFactura.Detalles);
// Guardo la factura que acabo de generar
AFactura.CalcularImporteTotal;
Self.Guardar(AFactura);
Result := True;
finally
APedido := NIL;
APedidosController := NIL;
HideHourglassCursor;
Application.ProcessMessages;
end;
end;
function TFacturasProveedorController.AnadirAbono(AFactura: IBizFacturaProveedor): Boolean;
begin
Result := Anadir(AFactura);
AFactura.TIPO := CTE_TIPO_ABONO;
end;
function TFacturasProveedorController.AsignarCuentaBancaria(AFacturas: IBizFacturaProveedor): TStringList;
//Devolver<65> la lista de facturas que no han podido ser modificadas referencia=nombreproveedor
var
AEditor : IEditorElegirDomiciliacion;
ACuentaBancaria: String;
begin
Result := TStringList.Create;
if Assigned(AFacturas) then
begin
CreateEditor('EditorElegirDomiciliacion', IEditorElegirDomiciliacion, AEditor);
if Assigned(AEditor) then
try
if (AEditor.ShowModal = mrOk) then
ACuentaBancaria := AEditor.CuentaBancaria;
finally
AEditor.Release;
AEditor := NIL;
end;
with AFacturas.DataTable do
begin
First;
while not EOF do
begin
if (AFacturas.SITUACION = CTE_PENDIENTE) then
begin
Edit;
AFacturas.DATOS_BANCARIOS := ACuentaBancaria;
Post;
//Se generan los recibos autom<6F>ticamente a partir de la forma de pago
GenerarRecibos(AFacturas);
end
else
Result.Add(Format('%s=%s', [AFacturas.REFERENCIA, AFacturas.NOMBRE]));
Next;
end;
ApplyUpdates;
end;
end;
end;
function TFacturasProveedorController.AsignarVencimiento(AFacturas: IBizFacturaProveedor): TStringList;
//Devolver<65> la lista de facturas que no han podido ser modificadas referencia=nombreproveedor
var
AEditor : IEditorElegirFechaVencimiento;
AFechaVencimiento: Datetime;
begin
Result := TStringList.Create;
if Assigned(AFacturas) then
begin
CreateEditor('EditorElegirFechaVencimiento', IEditorElegirFechaVencimiento, AEditor);
if Assigned(AEditor) then
try
if (AEditor.ShowModal = mrOk) then
AFEchaVencimiento := AEditor.FechaVencimiento;
finally
AEditor.Release;
AEditor := NIL;
end;
with AFacturas.DataTable do
begin
First;
while not EOF do
begin
if (AFacturas.SITUACION = CTE_PENDIENTE) then
begin
Edit;
AFacturas.FECHA_VENCIMIENTO := AFechaVencimiento;
Post;
//Se generan los recibos autom<6F>ticamente a partir de la forma de pago
GenerarRecibos(AFacturas);
end
else
Result.Add(Format('%s=%s', [AFacturas.REFERENCIA, AFacturas.NOMBRE]));
Next;
end;
ApplyUpdates;
end;
end;
end;
function TFacturasProveedorController.Buscar(const ID: Integer): IBizFacturaProveedor;
begin
Result := (FDataModule as IDataModuleFacturasProveedor).GetItem(ID);
FiltrarEmpresa(Result);
end;
function TFacturasProveedorController.BuscarTodos(
const ID_Proveedor: Integer): IBizFacturaProveedor;
var
Condicion: TDAWhereExpression;
begin
ShowHourglassCursor;
try
Result := BuscarTodos;
with Result.DataTable.DynamicWhere do
begin
// ID_CLIENTE
Condicion := NewBinaryExpression(NewField('', fld_FacturasProveedorID_PROVEEDOR),
NewConstant(ID_Proveedor, datInteger), dboEqual);
if IsEmpty then
Expression := Condicion
else
Expression := NewBinaryExpression(Expression, Condicion, dboAnd);
end;
finally
HideHourglassCursor;
end;
end;
function TFacturasProveedorController.BuscarTodosDelPedido(
const ID_Pedido: Integer): IBizFacturaProveedor;
var
Condicion: TDAWhereExpression;
begin
ShowHourglassCursor;
try
Result := BuscarTodos;
with Result.DataTable.DynamicWhere do
begin
// ID_CLIENTE
Condicion := NewBinaryExpression(NewField('', fld_FacturasProveedorID_PEDIDO),
NewConstant(ID_Pedido, datInteger), dboEqual);
if IsEmpty then
Expression := Condicion
else
Expression := NewBinaryExpression(Expression, Condicion, dboAnd);
end;
finally
HideHourglassCursor;
end;
end;
{REPASARRRRR
function TFacturasProveedorController.BuscarTodasPendientesComision(IdAgente:Integer; IdComision: Integer; IdFacturasAsociadas: String): IBizFacturaProveedor;
begin
ShowHourglassCursor;
try
Result := BuscarTodos;
with Result.DataTable.Where do
begin
if NotEmpty then
AddOperator(opAND);
//Todas las facturas de un agente determinado
OpenBraket;
AddText(fld_FacturasProveedorID_AGENTE + ' = ' + IntToStr(IdAgente));
CloseBraket;
//Todas aquellas que no esten asociadas a ninguna comisi<73>n o asociadas a la comisi<73>n,
//pero no asociadas en el editor de la comision, esto es porque se puede agregar y quitar
//facturas y todos los cambios estan el cache y por lo tanto al pedir las facturas a seleccionar
//debemos tener en cuenta dichso cambios en cache
AddOperator(opAND);
OpenBraket;
OpenBraket;
//En el caso de ser facturas sin asociar
OpenBraket;
AddText(fld_FacturasProveedorID_COMISION_LIQUIDADA + ' IS NULL ');
CloseBraket;
//Quitamos aquellas que ya est<73>n asociadas
if length(IdFacturasAsociadas) > 0 then
begin
AddOperator(opAND);
OpenBraket;
AddText(fld_FacturasProveedorID + ' not in (' + IdFacturasAsociadas + ')');
CloseBraket;
end;
CloseBraket;
AddOperator(opOR);
OpenBraket;
//En caso de ser facturas ya asociadas lo limitamos a la comision actual
//ya que no debemos poder elegir facturas asociadas a otras comisiones
OpenBraket;
AddText(fld_FacturasProveedorID_COMISION_LIQUIDADA + ' = ' + IntToStr(IdComision));
CloseBraket;
//En el caso de que halla facturas asociadas
if length(IdFacturasAsociadas) > 0 then
begin
AddOperator(opAND);
OpenBraket;
AddText(fld_FacturasProveedorID + ' not in (' + IdFacturasAsociadas + ')');
CloseBraket;
end;
CloseBraket;
CloseBraket;
end;
finally
HideHourglassCursor;
end;
end;
}
function TFacturasProveedorController.BuscarTodos: IBizFacturaProveedor;
begin
Result := FDataModule.GetItems;
FiltrarEmpresa(Result);
end;
constructor TFacturasProveedorController.Create;
begin
inherited;
FDataModule := TDataModuleFacturasProveedor.Create(Nil);
FProveedorController := TProveedoresController.Create;
FDetallesController := TDetallesFacturaProveedorController.Create;
FDetallesController.addObservador(Self);
end;
function TFacturasProveedorController.CreateEditor(const AName: String;
const IID: TGUID; out Intf): Boolean;
begin
Result := Supports(EditorRegistry.CreateEditor(AName), IID, Intf);
end;
function TFacturasProveedorController.DarListaAnosFacturas: TStringList;
begin
Result := FDataModule.GetAnosItems;
end;
procedure TFacturasProveedorController.DescartarCambios(AFactura: IBizFacturaProveedor);
begin
if not Assigned(AFactura) then
raise Exception.Create ('Factura no asignada');
ShowHourglassCursor;
try
if (AFactura.State in dsEditModes) then
AFactura.Cancel;
AFactura.DataTable.CancelUpdates;
finally
HideHourglassCursor;
end;
end;
destructor TFacturasProveedorController.Destroy;
begin
FDataModule := Nil;
FProveedorController := Nil;
FDetallesController := Nil;
inherited;
end;
function TFacturasProveedorController.Duplicar(AFactura: IBizFacturaProveedor): IBizFacturaProveedor;
begin
Result := Self._Vacio;
ShowHourglassCursor;
try
DuplicarRegistros(AFactura.DataTable, Result.DataTable, mdrActual);
DuplicarRegistros(AFactura.Detalles.DataTable, Result.Detalles.DataTable, mdrTodos);
// Hay que dejar algunos campos como si fuera una factura nueva
Result.Edit;
with Result do
begin
ID_EMPRESA := AppFactuGES.EmpresaActiva.ID;
USUARIO := AppFactuGES.UsuarioActivo.UserName;
REFERENCIA := ''; //Para que se asigne una nueva
SITUACION := CTE_PENDIENTE; //Una factura nueva debe estar pendiente
FECHA_FACTURA := DateOf(Now);
end;
Result.Post;
finally
HideHourglassCursor;
end;
end;
function TFacturasProveedorController.ValidarFactura(AFactura: IBizFacturaProveedor): Boolean;
var
AFormaPago: IBizFormaPago;
begin
Result := False;
if not Assigned(AFactura) then
raise Exception.Create ('Factura no asignada');
if (AFactura.DataTable.State in dsEditModes) then
AFactura.DataTable.Post;
//Tambien hacemos post de sus tablas hija
if (AFactura.Detalles.DataTable.State in dsEditModes) then
AFactura.Detalles.DataTable.Post;
if (AFactura.ID_PROVEEDOR < 0) or (AFactura.ID_PROVEEDOR = 0) then
// No comprobar el objeto Proveedor por que puede fallar la validaci<63>n
// cuando se generan facturas autom<6F>ticamente.
{ (not Assigned(AFactura.Proveedor)) or
(AFactura.Proveedor.IsEmpty) then}
raise Exception.Create('Debe indicar el Proveedor de esta factura');
if (EsFechaVacia(AFactura.FECHA_FACTURA)) then
raise Exception.Create('Debe indicar la fecha de esta factura');
if (AFactura.Detalles.DataTable.RecordCount = 0) then
raise Exception.Create('La factura debe tener al menos un concepto en su contenido');
{ Esta validaci<63>n puede saltar cuando se generan facturas autom<6F>ticamente
por albaranes o pedidos y el Proveedor no tiene Tipo de IVA puesto. }
{ if (AFactura.ID_TIPO_IVA = 0) then
raise Exception.Create('Debe indicar un tipo de IVA para esta factura');}
//De esta forma obligaremos siempre a tener un recibo asociado a la factura,
//porque si la forma de pago no tiene plazos es obligatorio la fecha de vencimiento
with TFormasPagoController.Create do
begin
try
AFormaPago := Buscar(AFactura.ID_FORMA_PAGO);
AFormaPago.DataTable.Active := True;
if (AFormaPago.Plazos.RecordCount = 0)
and (EsFechaVacia(AFactura.FECHA_VENCIMIENTO)) then
raise Exception.Create('Debe indicar una fecha de vencimiento para esta factura');
finally
AFormaPago := NIL;
Free;
end;
end;
//En caso de ser un Abono no podra tener un importe total positivo
if (AFactura.TIPO = CTE_TIPO_ABONO) then
if (AFactura.IMPORTE_TOTAL >= 0) then
raise Exception.Create('Un abono nunca no puede tener un importe positivo');
{ Asegurarse de valores en campos "autom<6F>ticos" tanto
en MODIFICACI<43>N como en INSERCI<43>N. }
AFactura.Edit;
try
AFactura.USUARIO := AppFactuGES.UsuarioActivo.UserName;
if Assigned(AFactura.Proveedor)
and (AFactura.ID_Proveedor <> AFactura.Proveedor.ID) then
AFactura.ID_Proveedor := AFactura.Proveedor.ID;
Result := True;
finally
AFactura.Post;
end;
end;
procedure TFacturasProveedorController.Ver(AFactura: IBizFacturaProveedor);
var
AEditor : IEditorFacturaProveedor;
begin
AEditor := NIL;
RecuperarProveedor(AFactura);
CreateEditor('EditorFacturaProveedor', IEditorFacturaProveedor, AEditor);
if Assigned(AEditor) then
try
AEditor.Controller := Self; //OJO ORDEN MUY IMPORTANTE
AEditor.Factura := AFactura;
//MODO CONSULTAR
if not EsModificable(AFactura) then
begin
SetDataTableReadOnly(AFactura.DataTable, True);
AEditor.ReadOnly := True;
end;
AEditor.ShowModal;
//MODO CONSULTAR (Se deja la tabla como estaba)
if AEditor.ReadOnly then
SetDataTableReadOnly(AFactura.DataTable, False);
finally
AEditor.Release;
AEditor := NIL;
end;
end;
procedure TFacturasProveedorController.VerTodos(AFacturas: IBizFacturaProveedor;
const AVerModal : Boolean = False; const AWindowCaption: String = '';
const AHeaderText: String = '');
var
AEditor : IEditorFacturasProveedor;
begin
AEditor := NIL;
CreateEditor('EditorFacturasProveedor', IEditorFacturasProveedor, AEditor);
try
if not EsCadenaVacia(AWindowCaption) then
AEditor.WindowCaption := AWindowCaption;
if not EsCadenaVacia(AHeaderText) then
AEditor.HeaderText := AHeaderText;
AEditor.Controller := Self; //OJO ORDEN MUY IMPORTANTE
AEditor.Facturas := AFacturas;
AEditor.MultiSelect := True;
if AVerModal then
AEditor.ShowModal
else
AEditor.ShowEmbedded;
finally
if AVerModal then
AEditor.Release;
AEditor := Nil;
end;
end;
function TFacturasProveedorController._Vacio: IBizFacturaProveedor;
begin
Result := Buscar(ID_NULO);
end;
function TFacturasProveedorController.Eliminar(const ID: Integer): Boolean;
var
AFactura : IBizFacturaProveedor;
begin
AFactura := Buscar(ID);
if not Assigned(AFactura) then
raise Exception.Create(Format('No se ha encontrado la factura con ID = %d', [ID]));
Result := Eliminar(AFactura);
AFactura := NIL;
end;
function TFacturasProveedorController.ElegirFacturas(AFacturas: IBizFacturaProveedor; AMensaje: String;
AMultiSelect: Boolean): IBizFacturaProveedor;
{var
AEditor : IEditorElegirFacturasProveedor;}
begin
Result := NIL;
{
CreateEditor('EditorElegirFacturasProveedor', IEditorElegirFacturasProveedor, AEditor);
if Assigned(AEditor) then
with AEditor do
begin
try
Controller := Self;
Facturas := AFacturas;
MultiSelect := AMultiSelect;
Mensaje := AMensaje;
if IsPositiveResult(ShowModal) then
Result := FacturasProveedoreSeleccionados;
finally
AEditor.Release;
AEditor := NIL;
end;
end;
}
end;
function TFacturasProveedorController.Eliminar(AFactura: IBizFacturaProveedor; AllItems: Boolean = false): Boolean;
//En el caso de eliminar almenos un elemento del conjunto se devuelve true
var
bEliminado: Boolean;
begin
bEliminado := False;
if not Assigned(AFactura) then
raise Exception.Create ('Factura no asignada');
ShowHourglassCursor;
try
if not AFactura.DataTable.Active then
AFactura.DataTable.Active := True;
if (AFactura.State in dsEditModes) then
AFactura.Cancel;
//Siempre eliminaremos el seleccionado
if EsEliminable(AFactura) then
begin
AFactura.Delete;
bEliminado := True;
end;
//En el caso de querer eliminar todos los items del objeto AAlbaran
if AllItems then
begin
with AFactura.DataTable do
begin
First;
while not EOF do
begin
if EsEliminable(AFactura) then
begin
AFactura.Delete;
bEliminado := True
end
else Next;
end;
end;
end;
if bEliminado then
begin
try
AFactura.DataTable.ApplyUpdates;
Result := True
except
//En el caso de una factura que tiene recibos con devoluciones hechas no se puede borrar aunque la factura este en situacion de pendiente
AFactura.DataTable.CancelUpdates;
Result := False;
end;
end
else
Result := False;
finally
HideHourglassCursor;
end;
end;
function TFacturasProveedorController.EsEliminable(AFactura: IBizFacturaProveedor): Boolean;
begin
Result := EsModificable(AFactura);
end;
function TFacturasProveedorController.EsModificable(AFactura: IBizFacturaProveedor): Boolean;
begin
if not Assigned(AFactura) then
raise Exception.Create ('Factura no asignado: EsModificable');
Result := (AFactura.SITUACION = CTE_PENDIENTE);
end;
procedure TFacturasProveedorController.RecalcularImportes(
FFactura: IBizFacturaProveedor);
var
bEnEdicion : Boolean;
ADetallePosAct : Integer;
AListaIVAs : TImporteIVADetallesArray;
begin
if not Assigned(FFactura) then
raise Exception.Create ('Factura no asignada (RecalcularImportes)');
if FFactura.DataTable.Active then
FFactura.DataTable.Active := True;
{ Hay que guardar la posici<63>n en la que estamos en los detalles por que
la asignaci<63>n de valores a los campos IMPORTE_NETO e IMPORTE_PORTE
(ver m<>s adelante) colocan el puntero en la tabla detalle al principio.
No he encontrado la raz<61>n por la que mueve el puntero. }
ADetallePosAct := FFactura.Detalles.POSICION;
bEnEdicion := (FFactura.DataTable.State in dsEditModes);
if not bEnEdicion then
FFactura.Edit;
ShowHourglassCursor;
try
FFactura.IMPORTE_NETO := FDetallesController.DarTotalImporteTotal(FFactura.Detalles);
FFactura.IMPORTE_PORTE := FDetallesController.DarTotalPorteTotal(FFactura.Detalles);
{AListaIVAs := FDetallesController.CalcularTotalesIVA(FFactura.Detalles.DataTable);
FFactura.IMPORTE_IVA := FDetallesController.CalcularSumaIVA(AListaIVAs);
FFactura.DataTable.FieldByName('IVA').Clear;}
if not bEnEdicion then
FFactura.Post;
finally
HideHourglassCursor;
// Restaurar la posici<63>n que ten<65>amos en los detalles.
FDetallesController.LocalizarPosicion(FFactura.Detalles, ADetallePosAct);
end;
end;
procedure TFacturasProveedorController.RecibirAviso(ASujeto: ISujeto; ADataTable: IDAStronglyTypedDataTable);
var
AFactura : IBizFacturaProveedor;
ADetalles : IBizDetallesFacturaProveedor;
begin
inherited;
if Supports(ADataTable, IBizDetallesFacturaProveedor, ADetalles) and
Supports(ADetalles.DataTable.MasterSource.DataTable, IBizFacturaProveedor, AFactura) then
begin
RecalcularImportes(AFactura);
end;
end;
procedure TFacturasProveedorController.RecuperarProveedor(AFactura: IBizFacturaProveedor);
begin
AFactura._Proveedor := (FProveedorController.Buscar(AFactura.ID_Proveedor) as IBizProveedor);
end;
function TFacturasProveedorController.Existe(const ID: Integer): Boolean;
var
AFactura : IBizFacturaProveedor;
begin
try
AFactura := Buscar(ID);
Result := Assigned(AFactura) and (AFactura.ID = ID);
finally
AFactura := NIL;
end;
end;
function TFacturasProveedorController.ExtraerSeleccionados(AFacturasProveedor: IBizFacturaProveedor): IBizFacturaProveedor;
var
ASeleccionados : IBizFacturaProveedor;
begin
ASeleccionados := (Self.Buscar(ID_NULO) as IBizFacturaProveedor);
CopyDataTableDA5(AFacturasProveedor.DataTable, ASeleccionados.DataTable, True);
Result := ASeleccionados;
end;
procedure TFacturasProveedorController.FiltrarAno(AFactura: IBizFacturaProveedor; ADynWhereDataTable: WideString; const Ano: String);
var
Condicion: TDAWhereExpression;
FechaIni: String;
FechaFin: String;
begin
AFactura.DataTable.DynamicWhere.Clear;
AFactura.DataTable.DynamicWhere.Xml := ADynWhereDataTable;
if (Ano <> 'Todos') then
begin
// Filtrar las facturas actuales por empresa
FechaIni := '01/01/' + Ano;
FechaFin := '31/12/' + Ano;
with AFactura.DataTable.DynamicWhere do
begin
// (FECHA_INICIO between FECHA_FIN)
Condicion := NewBinaryExpression(NewField('', fld_FacturasProveedorFECHA_FACTURA), NewConstant(FechaIni, datString), dboGreaterOrEqual);
Condicion := NewBinaryExpression(NewBinaryExpression(NewField('', fld_FacturasProveedorFECHA_FACTURA), NewConstant(FechaFin, datString), dboLessOrEqual), Condicion, dboAnd);
if IsEmpty then
Expression := Condicion
else
Expression := NewBinaryExpression(Condicion, Expression, dboAnd);
end;
end;
end;
procedure TFacturasProveedorController.FiltrarEmpresa(AFactura: IBizFacturaProveedor);
var
Condicion: TDAWhereExpression;
begin
if AFactura.DataTable.Active then
AFactura.DataTable.Active := False;
// Filtrar las facturas actuales por empresa
with AFactura.DataTable.DynamicWhere do
begin
// (ID_EMPRESA >= ID)
Condicion := NewBinaryExpression(NewField('', fld_FacturasProveedorID_EMPRESA), NewConstant(AppFactuGES.EmpresaActiva.ID, datInteger), dboEqual);
if IsEmpty then
Expression := Condicion
else
Expression := NewBinaryExpression(Expression, Condicion, dboAnd);
end;
end;
procedure TFacturasProveedorController.SetProveedorController(const Value: IProveedoresController);
begin
FProveedorController := Value;
end;
procedure TFacturasProveedorController.SetDetallesController(const Value: IDetallesFacturaProveedorController);
begin
FDetallesController := Value;
end;
function TFacturasProveedorController.Guardar(AFactura: IBizFacturaProveedor): Boolean;
begin
Result := False;
if not Assigned(AFactura) then
raise Exception.Create ('Factura no asignada');
if not Assigned(FDetallesController) then
raise Exception.Create ('Controller detalles no asignado');
if ValidarFactura(AFactura) then
begin
ShowHourglassCursor;
// Asegurarnos de que todos los importes est<73>n bien.
RecalcularImportes(AFactura);
try
AFactura.DataTable.ApplyUpdates;
//Se generan los recibos autom<6F>ticamente a partir de la forma de pago
GenerarRecibos(AFactura);
Result := True;
finally
HideHourglassCursor;
end;
end;
end;
function TFacturasProveedorController.Nuevo(withInsert: Boolean = True): IBizFacturaProveedor;
var
AFactura : IBizFacturaProveedor;
begin
AFactura := FDataModule.NewItem;
FiltrarEmpresa(AFactura);
AFactura.DataTable.Active := True;
if withInsert then
AFactura.Insert;
Result := AFactura;
end;
procedure TFacturasProveedorController.Preview(AFactura: IBizFacturaProveedor; AllItems: Boolean = false);
var
AReportController : IFacturasProveedorReportController;
ID_Facturas: TStringList;
begin
AReportController := TFacturasProveedorReportController.Create;
try
ID_Facturas := TStringList.Create;
//Si deseamos previsualizar todos los items del objeto albaran
if AllItems then
begin
with AFactura.DataTable do
begin
First;
while not EOF do
begin
ID_Facturas.Add(IntToStr(AFactura.ID));
Next;
end;
end;
end
//Solo previsualizamos el item seleccionado
else
ID_Facturas.Add(IntToStr(AFactura.ID));
AReportController.Preview(ID_Facturas.CommaText);
finally
AReportController := NIL;
FreeANDNIL(ID_Facturas);
end;
end;
procedure TFacturasProveedorController.Print(AFactura: IBizFacturaProveedor; AllItems: Boolean = false);
var
AReportController : IFacturasProveedorReportController;
ID_Facturas: TStringList;
begin
AReportController := TFacturasProveedorReportController.Create;
try
ID_Facturas := TStringList.Create;
//Si deseamos previsualizar todos los items del objeto albaran
if AllItems then
begin
with AFactura.DataTable do
begin
First;
while not EOF do
begin
ID_Facturas.Add(IntToStr(AFactura.ID));
Next;
end;
end;
end
//Solo previsualizamos el item seleccionado
else
ID_Facturas.Add(IntToStr(AFactura.ID));
AReportController.Print(ID_Facturas.CommaText);
finally
AReportController := NIL;
FreeANDNIL(ID_Facturas);
end;
end;
function TFacturasProveedorController.GenerarAbono(AFactura: IBizFacturaProveedor): IBizFacturaProveedor;
begin
ShowHourglassCursor;
try
Result := Duplicar(AFactura);
//A<>ade un concepto con los datos de la factura asociada al abono
FDetallesController.AnadirDetalleFacturaAsociadaAbono(Result.Detalles, AFactura.REFERENCIA, DateToStr(AFactura.FECHA_FACTURA));
//Convierte todos los articulos de la factura a negativos por se un abono
FDetallesController.CambiarSignoDetalles(Result.Detalles);
// Hay que dejar algunos campos como si fuera una factura nueva
Result.Edit;
Result.TIPO := CTE_TIPO_ABONO;
Result.Post;
finally
HideHourglassCursor;
end;
end;
procedure TFacturasProveedorController.GenerarRecibos(AFactura: IBizFacturaProveedor);
var
AFormasPagoController : IFormasPagoController;
AFormaPago: IBizFormaPago;
ARecibosProveedorController: IRecibosProveedorController;
ARecibos: IBizRecibosProveedor;
AFechaVencimiento: TDateTime;
i: Integer;
ADiaVencimiento: Integer;
ADiasMas: Integer;
BSemaforo: Boolean;
begin
if not Assigned(AFactura) then
Exit;
AFormasPagoController := TFormasPagoController.Create;
AFormaPago := AFormasPagoController.Buscar(AFactura.ID_FORMA_PAGO);
AFormaPago.DataTable.Active := True;
ARecibosProveedorController := TRecibosProveedorController.Create;
//Eliminamos todos los recibos que tuviera la factura porque sabemos que todos
//estar<61>n pendientes (solo permitiremos modificar y eliminar facturas pendientes,
//parcialmente pagadas o pagadas no
ARecibos := ARecibosProveedorController.BuscarRecibosFactura(AFactura.ID);
ARecibosProveedorController.EliminarTodo(ARecibos);
//Se cambia la l<>gica a peticion de tecsitel, en el caso de meter una fecha de vencimiento,
//los plazos de la forma de pago no tendr<64>n efecto, se generar<61> un recibo con el 100% y fecha de vencimiento
//de la factura.
With AFormaPago.Plazos.DataTable do
begin
i := 1;
First;
repeat
ARecibos := ARecibosProveedorController.Nuevo;
ARecibos.Edit;
ARecibos.ID_FACTURA := AFactura.ID;
ARecibos.REFERENCIA := AFactura.REFERENCIA + ' - ' + IntToStr(i);
ARecibos.FECHA_EMISION := AFactura.FECHA_FACTURA;
ARecibos.DATOS_BANCARIOS := AFactura.DATOS_BANCARIOS;
if AFormaPago.Plazos.RecordCount < 1 then
begin
ARecibos.FECHA_VENCIMIENTO := AFactura.FECHA_VENCIMIENTO;
ARecibos.IMPORTE := AFactura.IMPORTE_TOTAL;
end
else
begin
AFechaVencimiento := AFactura.FECHA_FACTURA + AFormaPago.Plazos.NUM_DIAS;
ADiasMas := 0;
BSemaforo := False;
if (AFactura.Proveedor.VENCIMIENTO_FACTURAS_1 <> 0)
or (AFactura.Proveedor.VENCIMIENTO_FACTURAS_2 <> 0)
or (AFactura.Proveedor.VENCIMIENTO_FACTURAS_3 <> 0) then
begin
ADiaVencimiento := DayOf(AFechaVencimiento);
while (ADiaVencimiento <> AFactura.Proveedor.VENCIMIENTO_FACTURAS_1)
and (ADiaVencimiento <> AFactura.Proveedor.VENCIMIENTO_FACTURAS_2)
and (ADiaVencimiento <> AFactura.Proveedor.VENCIMIENTO_FACTURAS_3) do
begin
if ADiaVencimiento = DaysInMonth(AFechaVencimiento) then
begin
ADiaVencimiento := 1;
//Controlamos con una variable semaforo que no nos quedemos en un bucle infinito
//intentando encontrar el dia de pago establecido para el cliente (es el caso de tener
//asignado el dia de pago 30 y llegar febrero en el que no se encuentra dicho dia, o
//tener como dia de pago los d<>as 31 y en el caso de meses de 30 dias no encontrarlo.
if BSemaforo then
begin
ADiasMas := 0;
Break
end
else
BSemaforo := True;
end
else
Inc(ADiaVencimiento);
Inc(ADiasMas);
end;
end;
AFechaVencimiento := IncDay(AFechaVencimiento, ADiasMas);
ARecibos.FECHA_VENCIMIENTO := AFechaVencimiento;
ARecibos.IMPORTE := AFactura.IMPORTE_TOTAL * (AFormaPago.Plazos.PORCENTAJE / 100);
end;
ARecibos.DESCRIPCION := 'Pago de factura ' + AFactura.REFERENCIA + ': son ' + CifraToLetras(ARecibos.IMPORTE);
ARecibosProveedorController.Guardar(ARecibos);
Inc(i);
Next;
until (eof);
end;
//Liberamos
AFormasPagoController := Nil;
AFormaPago := Nil;
ARecibosProveedorController := Nil;
ARecibos := Nil;
end;
function TFacturasProveedorController.GetProveedorController: IProveedoresController;
begin
Result := FProveedorController;
end;
function TFacturasProveedorController.GetDetallesController: IDetallesFacturaProveedorController;
begin
Result := FDetallesController;
end;
end.