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

937 lines
31 KiB
ObjectPascal
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
procedure Ver(AFactura : IBizFacturaProveedor);
procedure VerTodos(AFacturas: IBizFacturaProveedor);
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;
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;
// function BuscarTodasPendientesComision(IdAgente: Integer; IdComision: Integer; IdFacturasAsociadas: String): IBizFacturaProveedor;
function Nuevo (withInsert: Boolean = True): IBizFacturaProveedor;
procedure Ver(AFactura : IBizFacturaProveedor);
procedure VerTodos(AFacturas: IBizFacturaProveedor);
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;
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;
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.Buscar(const ID: Integer): IBizFacturaProveedor;
begin
Result := (FDataModule as IDataModuleFacturasProveedor).GetItem(ID);
FiltrarEmpresa(Result);
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;
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;
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');}
//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;
ShowHourglassCursor;
try
RecuperarProveedor(AFactura);
CreateEditor('EditorFacturaProveedor', IEditorFacturaProveedor, AEditor);
if Assigned(AEditor) then
with AEditor do
begin
Controller := Self; //OJO ORDEN MUY IMPORTANTE
Factura := AFactura;
//MODO CONSULTAR
if not EsModificable(AFactura) then
begin
SetDataTableReadOnly(AFactura.DataTable, True);
ReadOnly := True;
end;
ShowModal;
//MODO CONSULTAR (Se deja la tabla como estaba)
if ReadOnly then
SetDataTableReadOnly(AFactura.DataTable, False);
AEditor.Release;
end;
finally
AEditor := NIL;
HideHourglassCursor;
end;
end;
procedure TFacturasProveedorController.VerTodos(AFacturas: IBizFacturaProveedor);
var
AEditor : IEditorFacturasProveedor;
begin
AEditor := NIL;
ShowHourglassCursor;
try
CreateEditor('EditorFacturasProveedor', IEditorFacturasProveedor, AEditor);
with AEditor do
begin
Controller := Self; //OJO ORDEN MUY IMPORTANTE
Facturas := AFacturas;
MultiSelect := True;
ShowEmbedded;
end;
finally
AEditor := Nil;
HideHourglassCursor;
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;
{
ShowHourglassCursor;
try
CreateEditor('EditorElegirFacturasProveedor', IEditorElegirFacturasProveedor, AEditor);
if Assigned(AEditor) then
with AEditor do
begin
Controller := Self;
Facturas := AFacturas;
MultiSelect := AMultiSelect;
Mensaje := AMensaje;
if IsPositiveResult(ShowModal) then
Result := FacturasProveedoreSeleccionados;
Release;
end;
finally
AEditor := NIL;
HideHourglassCursor;
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;
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);
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.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;
begin
if not Assigned(AFactura) then
Exit;
AFormasPagoController := TFormasPagoController.Create;
AFormaPago := AFormasPagoController.Buscar(AFactura.ID_FORMA_PAGO);
AFormaPago.DataTable.Active := True;
if AFormaPago.DataTable.RecordCount <> 1 then
Exit; //No hay forma de pago en la factura y por lo tanto no se generan recibos
//raise Exception.Create('No existe la forma de pago de la factura');
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);
//Vamos a generar todos los recibos necesarios para la factura
With AFormaPago.Plazos.DataTable do
begin
i := 1;
First;
while not eof do
begin
ARecibos := ARecibosProveedorController.Nuevo;
ARecibos.Edit;
ARecibos.ID_FACTURA := AFactura.ID;
ARecibos.REFERENCIA := AFactura.REFERENCIA + ' - ' + IntToStr(i);
ARecibos.FECHA_EMISION := AFactura.FECHA_FACTURA;
AFechaVencimiento := AFactura.FECHA_FACTURA + AFormaPago.Plazos.NUM_DIAS;
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);
ADiasMas := 0;
while (ADiaVencimiento <> AFactura.Proveedor.VENCIMIENTO_FACTURAS_1)
and (ADiaVencimiento <> AFactura.Proveedor.VENCIMIENTO_FACTURAS_2)
and (ADiaVencimiento <> AFactura.Proveedor.VENCIMIENTO_FACTURAS_3) do
begin
Inc(ADiaVencimiento);
Inc(ADiasMas);
if ADiaVencimiento = DaysInMonth(AFechaVencimiento) then
ADiaVencimiento := 0;
end;
end;
AFechaVencimiento := IncDay(AFechaVencimiento, ADiasMas);
ARecibos.FECHA_VENCIMIENTO := AFechaVencimiento;
ARecibos.IMPORTE := AFactura.IMPORTE_TOTAL * (AFormaPago.Plazos.PORCENTAJE / 100);
ARecibos.DESCRIPCION := 'Pago de factura ' + AFactura.REFERENCIA + ': son ' + CifraToLetras(ARecibos.IMPORTE);
ARecibosProveedorController.Guardar(ARecibos);
Inc(i);
Next;
end;
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.