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

1061 lines
35 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(IObservador)
['{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 : 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(TObservador, 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; virtual;
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 : 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,
uBizDetallesAlbaranProveedor,
uBizPedidosProveedor, uPedidosProveedorController, uBizDetallesPedidoProveedor,
uRecibosProveedorController, uBizRecibosProveedor,
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
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 := NIL;
end;
end;
procedure CopiarArticulosAlbaran(AOrigen: IBizDetallesAlbaranProveedor;
ADestino : IBizDetallesFacturaProveedor);
var
i : integer;
ADetallesController : IDetallesFacturaProveedorController;
begin
if not Assigned(AOrigen) then
raise Exception.Create ('Origen no asignado (CopiarArticulosAlbaran)');
if not Assigned(ADestino) then
raise Exception.Create ('Destino no asignado (CopiarArticulosAlbaran)');
if not AOrigen.DataTable.Active then
AOrigen.DataTable.Active := True;
if not ADestino.DataTable.Active then
ADestino.DataTable.Active := True;
ADetallesController := TDetallesFacturaProveedorController.Create;
try
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 := 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(AFacturas: IBizFacturaProveedor;
AListaAlbaranes: IBizAlbaranProveedor): Boolean;
var
AFacturaActual : IBizFacturaProveedor;
AAlbaranesController : IAlbaranesProveedorController;
I: Integer;
bEnEdicion : Boolean;
begin
Result := False;
// ATENCI<43>N!!! AFacturas tiene que estar vacio para no pisar facturas
// ya generadas.
if not Assigned(AFacturas) then
raise Exception.Create ('Factura no asignada (Anadir)');
if not Assigned(AListaAlbaranes) then
raise Exception.Create ('Albaranes no asignados (Anadir)');
if not AFacturas.DataTable.Active then
AFacturas.DataTable.Active := True;
if not AListaAlbaranes.DataTable.Active then
AListaAlbaranes.DataTable.Active := True;
ShowHourglassCursor;
Application.ProcessMessages;
AAlbaranesController := TAlbaranesProveedorController.Create;
try
// Ordenar por fecha de albaran
AListaAlbaranes.DataTable.Sort([fld_AlbaranesProveedorFECHA_ALBARAN], [uDADataTable.sdAscending]);
AListaAlbaranes.First;
for I := 0 to AListaAlbaranes.DataTable.RecordCount - 1 do
begin
AListaAlbaranes._Proveedor := NIL;
AFacturaActual := NIL;
// Busco si hay alguna factura ya hecha de ese Proveedor
AFacturas.DataTable.First;
if AFacturas.DataTable.Locate(fld_FacturasProveedorID_Proveedor, AListaAlbaranes.ID_Proveedor, []) then
begin
AFacturaActual := AFacturas;
RecuperarProveedor(AFacturaActual);
AFacturaActual.Proveedor.DataTable.Active := True;
end
else begin
// No hay factura de ese Proveedor. Creo una nueva
Anadir(AFacturas);
AAlbaranesController.RecuperarProveedor(AListaAlbaranes);
AFacturas.Proveedor := AListaAlbaranes.Proveedor;
//Siempre asignaremos por defecto la referencia de factura de proveedor que tenga el primer albaran del proveedor
bEnEdicion := (AFacturas.DataTable.State in dsEditModes);
if not bEnEdicion then
AFacturas.Edit;
AFacturas.REFERENCIA_PROVEEDOR := AListaAlbaranes.REF_FACTURA_PROV;
AFacturas.Post;
if bEnEdicion then
AFacturas.Edit;
//Si el albaran es de tipo devoluci<63>n hacemos la factura de tipo abono
if (AListaAlbaranes.TIPO = CTE_TIPO_ALBARAN_DEV) then
begin
bEnEdicion := (AFacturas.DataTable.State in dsEditModes);
if not bEnEdicion then
AFacturas.Edit;
AFacturas.TIPO := CTE_TIPO_ABONO;
AFacturas.Post;
if bEnEdicion then
AFacturas.Edit;
end;
AFacturaActual := AFacturas;
end;
// Ya tengo la factura. Le a<>ado los conceptos del albar<61>n
AFacturaActual.Detalles.DataTable.Last;
// A<>ado el t<>tulo
Self.DetallesController.Add(AFacturaActual.Detalles, TIPO_DETALLE_TITULO);
with AFacturaActual.Detalles do
begin
Edit;
CONCEPTO := 'Albar<61>n ' + AListaAlbaranes.REFERENCIA + ' del ' + DateToStr(AListaAlbaranes.FECHA_ALBARAN);
Post;
end;
// A<>ado el contenido del albar<61>n
CopiarArticulosAlbaran(AListaAlbaranes.Detalles, AFacturaActual.Detalles);
{En los albaranes a proveedor el porte es a nivel del art<72>culo
Self.DetallesController.Add(AFacturaActual.Detalles, TIPO_DETALLE_CONCEPTO);
with AFacturaActual.Detalles do
begin
Edit;
CONCEPTO := 'Porte del albar<61>n';
CANTIDAD := 1;
IMPORTE_UNIDAD := AListaAlbaranes.IMPORTE_PORTE;
Post;
end;
}
// A<>ado el resumen
Self.DetallesController.Add(AFacturaActual.Detalles, TIPO_DETALLE_SUBTOTAL);
with AFacturaActual.Detalles do
begin
Edit;
CONCEPTO := 'Total del albar<61>n ' + AListaAlbaranes.REFERENCIA;
Post;
end;
// A<>ado una l<>nea en blanco
Self.DetallesController.Add(AFacturaActual.Detalles, TIPO_DETALLE_CONCEPTO);
with AFacturaActual.Detalles do
begin
Edit;
CONCEPTO := '';
Post;
end;
// Guardo la factura que acabo de generar o editar
AFacturaActual.CalcularImporteTotal;
Self.Guardar(AFacturaActual);
// Asocio la factura con el albar<61>n
AListaAlbaranes.Edit;
AListaAlbaranes.ID_FACTURA := AFacturaActual.ID;
AListaAlbaranes.Post;
AAlbaranesController.Guardar(AListaAlbaranes);
AListaAlbaranes.Next;
end;
Result := True;
finally
AAlbaranesController := NIL;
HideHourglassCursor
end;
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;
{
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;
// showmessage(Result.DataTable.Where.Clause);
end;
}
function TFacturasProveedorController.BuscarTodos: IBizFacturaProveedor;
begin
Result := FDataModule.GetItems;
FiltrarEmpresa(Result);
end;
constructor TFacturasProveedorController.Create;
begin
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;
{ CreateEditor('EditorElegirFacturasProveedor', IEditorElegirFacturasProveedor, AEditor);
try
with AEditor do
begin
Controller := Self;
Facturas := AFacturas;
MultiSelect := AMultiSelect;
Mensaje := AMensaje;
if IsPositiveResult(ShowModal) then
Result := FacturasProveedoreSeleccionados;
Release;
end;
finally
AEditor := NIL;
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
AFactura.DataTable.ApplyUpdates;
Result := True;
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;
begin
if not Assigned(FFactura) then
raise Exception.Create ('Factura no asignada (RecalcularImportes)');
if FFactura.DataTable.Active then
FFactura.DataTable.Active := True;
bEnEdicion := (FFactura.DataTable.State in dsEditModes);
if not bEnEdicion then
FFactura.Edit;
ShowHourglassCursor;
FFactura.Edit;
try
FFactura.IMPORTE_NETO := FDetallesController.DarTotalImporteTotal(FFactura.Detalles);
FFactura.IMPORTE_PORTE := FDetallesController.DarTotalPorteTotal(FFactura.Detalles);
if not bEnEdicion then
FFactura.Post;
finally
HideHourglassCursor;
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);
CopyDataTableDA3(AFacturasProveedor.DataTable, ASeleccionados.DataTable, True);
Result := ASeleccionados;
end;
procedure TFacturasProveedorController.FiltrarEmpresa(AFactura: IBizFacturaProveedor);
begin
if AFactura.DataTable.Active then
AFactura.DataTable.Active := False;
// Filtrar las facturas actuales por empresa
{ with AFactura.DataTable.Where do
begin
if NotEmpty then
AddOperator(opAND);
AddCondition(fld_FacturasProveedorID_EMPRESA, cEqual, dmUsuarios.IDEmpresaActual);
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;
var
IDNuevo : Integer;
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: IBizFacturaProveedor;
var
AFactura : IBizFacturaProveedor;
begin
AFactura := FDataModule.NewItem;
FiltrarEmpresa(AFactura);
AFactura.DataTable.Active := True;
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;
i: 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_VENCIMIENTO := AFactura.FECHA_FACTURA + AFormaPago.Plazos.NUM_DIAS;
ARecibos.IMPORTE := AFactura.IMPORTE_TOTAL * (AFormaPago.Plazos.PORCENTAJE / 100);
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.