Tecsitel_FactuGES2/Source/Modulos/Facturas de cliente/Controller/uFacturasClienteController.pas

1069 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 uFacturasClienteController;
interface
uses
Classes, SysUtils, uDADataTable, uControllerBase, uIDataModuleFacturasCliente,
uClientesController, uDetallesFacturaClienteController, uBizAlbaranesCliente,
uBizFacturasCliente;
type
IFacturasClienteController = interface(IObservador)
['{CAD20B4E-6D0B-4A1C-9306-B195824B6CAD}']
function GetClienteController: IClientesController;
procedure SetClienteController(const Value: IClientesController);
property ClienteController: IClientesController read GetClienteController write SetClienteController;
function GetDetallesController: IDetallesFacturaClienteController;
procedure SetDetallesController(const Value: IDetallesFacturaClienteController);
property DetallesController: IDetallesFacturaClienteController read GetDetallesController write SetDetallesController;
function Buscar(const ID: Integer): IBizFacturaCliente;
function BuscarTodos: IBizFacturaCliente;
function BuscarTodasPendientesComision(IdAgente: Integer; IdComision: Integer; IdFacturasAsociadas: String): IBizFacturaCliente;
procedure Ver(AFactura : IBizFacturaCliente);
procedure VerTodos(AFacturas: IBizFacturaCliente);
function Nuevo : IBizFacturaCliente;
function Anadir(AFactura : IBizFacturaCliente) : Boolean; overload;
function AnadirAbono(AFactura : IBizFacturaCliente) : Boolean;
function Anadir(AFacturas : IBizFacturaCliente; AListaAlbaranes : IBizAlbaranCliente): Boolean; overload;
// function Anadir(AFactura : IBizFacturaCliente; const IDPedido : Integer): Boolean; overload;
function Eliminar(const ID : Integer): Boolean; overload;
function Eliminar(AFactura : IBizFacturaCliente; AllItems: Boolean = false): Boolean; overload;
function Guardar(AFactura : IBizFacturaCliente): Boolean;
procedure DescartarCambios(AFactura : IBizFacturaCliente);
function Existe(const ID: Integer) : Boolean;
procedure RecuperarCliente(AFactura : IBizFacturaCliente);
function Duplicar(AFactura: IBizFacturaCliente): IBizFacturaCliente;
function GenerarAbono(AFactura: IBizFacturaCliente): IBizFacturaCliente;
procedure Preview(AFactura : IBizFacturaCliente; AllItems: Boolean = false);
procedure Print(AFactura : IBizFacturaCliente; AllItems: Boolean = false);
procedure RecalcularImportes(AFactura: IBizFacturaCliente);
function EsModificable(AFactura: IBizFacturaCliente): Boolean;
function EsEliminable(AFactura: IBizFacturaCliente): Boolean;
function ElegirFacturas(AFacturas : IBizFacturaCliente; AMensaje: String; AMultiSelect: Boolean): IBizFacturaCliente;
function ExtraerSeleccionados(ARecibosCliente: IBizFacturaCliente) : IBizFacturaCliente;
end;
TFacturasClienteController = class(TObservador, IFacturasClienteController)
private
FDataModule : IDataModuleFacturasCliente;
FClienteController : IClientesController;
FDetallesController : IDetallesFacturaClienteController;
function GetClienteController: IClientesController;
procedure SetClienteController(const Value: IClientesController);
function GetDetallesController: IDetallesFacturaClienteController;
procedure SetDetallesController(const Value: IDetallesFacturaClienteController);
function CreateEditor(const AName : String; const IID: TGUID; out Intf): Boolean;
function _Vacio : IBizFacturaCliente;
procedure FiltrarEmpresa(AFactura: IBizFacturaCliente);
function ValidarFactura(AFactura: IBizFacturaCliente): Boolean;
procedure GenerarRecibos(AFactura: IBizFacturaCliente);
protected
procedure RecibirAviso(ASujeto: ISujeto; ADataTable: IDAStronglyTypedDataTable); override;
public
property ClienteController: IClientesController read GetClienteController write SetClienteController;
property DetallesController: IDetallesFacturaClienteController read GetDetallesController write SetDetallesController;
constructor Create; virtual;
destructor Destroy; override;
function Eliminar(const ID : Integer): Boolean; overload;
function Eliminar(AFactura : IBizFacturaCliente; AllItems: Boolean = false): Boolean; overload;
function Guardar(AFactura : IBizFacturaCliente): Boolean;
procedure DescartarCambios(AFactura : IBizFacturaCliente); virtual;
function Existe(const ID: Integer) : Boolean; virtual;
function Anadir(AFactura : IBizFacturaCliente): Boolean; overload;
function AnadirAbono(AFactura : IBizFacturaCliente) : Boolean;
function Anadir(AFacturas : IBizFacturaCliente; AListaAlbaranes : IBizAlbaranCliente): Boolean; overload;
// function Anadir(AFactura : IBizFacturaCliente; const IDPedido : Integer): Boolean; overload;
function Buscar(const ID: Integer): IBizFacturaCliente;
function BuscarTodos: IBizFacturaCliente;
function BuscarTodasPendientesComision(IdAgente: Integer; IdComision: Integer; IdFacturasAsociadas: String): IBizFacturaCliente;
function Nuevo : IBizFacturaCliente;
procedure Ver(AFactura : IBizFacturaCliente);
procedure VerTodos(AFacturas: IBizFacturaCliente);
function Duplicar(AFactura: IBizFacturaCliente): IBizFacturaCliente;
function GenerarAbono(AFactura: IBizFacturaCliente): IBizFacturaCliente;
procedure RecuperarCliente(AFactura : IBizFacturaCliente);
procedure Preview(AFactura : IBizFacturaCliente; AllItems: Boolean = false);
procedure Print(AFactura : IBizFacturaCliente; AllItems: Boolean = false);
procedure RecalcularImportes(AFactura: IBizFacturaCliente);
function EsModificable(AFactura: IBizFacturaCliente): Boolean;
function EsEliminable(AFactura: IBizFacturaCliente): Boolean;
function ElegirFacturas(AFacturas : IBizFacturaCliente; AMensaje: String; AMultiSelect: Boolean): IBizFacturaCliente;
function ExtraerSeleccionados(AFacturasCliente: IBizFacturaCliente) : IBizFacturaCliente;
end;
implementation
uses
Windows, Controls, cxControls, DB, uEditorRegistryUtils, schFacturasClienteClient_Intf,
uBizContactos, uIEditorFacturasCliente, uIEditorFacturaCliente, uFactuGES_App,
uDataModuleFacturasCliente, uBizDetallesFacturaCliente, uControllerDetallesBase,
uDataModuleUsuarios, uDAInterfaces, uDataTableUtils, uDateUtils,
uAlbaranesClienteController, schAlbaranesClienteClient_Intf, uROTypes, uDetallesAlbaranClienteController,
uBizDetallesAlbaranCliente, uFacturasClienteReportController,
// uBizPedidosCliente, uPedidosClienteController, uBizDetallesPedidoCliente,
DateUtils, Forms, Dialogs,
uFormasPagoController, uBizFormasPago, uIEditorElegirFacturasCliente,
uRecibosClienteController, uBizRecibosCliente;
{procedure CopiarArticulosPedido(AOrigen: IBizDetallesPedidoCliente;
ADestino : IBizDetallesFacturaCliente);
var
i : integer;
ADetallesController : IDetallesFacturaClienteController;
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 := TDetallesFacturaClienteController.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: IBizDetallesAlbaranCliente;
ADestino : IBizDetallesFacturaCliente);
var
i : integer;
ADetallesController : IDetallesFacturaClienteController;
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 := TDetallesFacturaClienteController.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;
{ TFacturasClienteController }
function TFacturasClienteController.Anadir(AFactura: IBizFacturaCliente) : Boolean;
begin
if not Assigned(AFactura) then
raise Exception.Create ('Factura no asignada (Anadir)');
AFactura.Insert;
Result := True;
end;
function TFacturasClienteController.AnadirAbono(AFactura: IBizFacturaCliente): Boolean;
begin
Anadir(AFactura);
AFactura.TIPO := CTE_TIPO_ABONO;
Result := True;
end;
function TFacturasClienteController.Anadir(AFacturas: IBizFacturaCliente;
AListaAlbaranes: IBizAlbaranCliente): Boolean;
var
AFacturaActual : IBizFacturaCliente;
AAlbaranesController : IAlbaranesClienteController;
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 := TAlbaranesClienteController.Create;
try
// Ordenar por fecha de albaran
AListaAlbaranes.DataTable.Sort([fld_AlbaranesClienteFECHA_ALBARAN], [uDADataTable.sdAscending]);
AListaAlbaranes.First;
for I := 0 to AListaAlbaranes.DataTable.RecordCount - 1 do
begin
AListaAlbaranes._Cliente := NIL;
AFacturaActual := NIL;
// Busco si hay alguna factura ya hecha de ese cliente
AFacturas.DataTable.First;
if AFacturas.DataTable.Locate(fld_FacturasClienteID_CLIENTE, AListaAlbaranes.ID_CLIENTE, []) then
begin
AFacturaActual := AFacturas;
RecuperarCliente(AFacturaActual);
AFacturaActual.Cliente.DataTable.Active := True;
end
else begin
// No hay factura de ese cliente. Creo una nueva
Anadir(AFacturas);
AAlbaranesController.RecuperarCliente(AListaAlbaranes);
AListaAlbaranes.Cliente.DataTable.Active := True;
AFacturas.Cliente := AListaAlbaranes.Cliente;
//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);
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 TFacturasClienteController.Anadir(AFactura: IBizFacturaCliente;
const IDPedido: Integer): Boolean;
var
APedidosController : IPedidosClienteController;
APedido : IBizPedidoCliente;
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 := TPedidosClienteController.Create;
try
APedido := APedidosController.Buscar(IDPedido);
if not Assigned(APedido) then
raise Exception.Create (Format('No se ha encontrado un pedido de cliente con ID %d (Anadir)', [IDPedido]));
APedido.DataTable.Active := True;
APedidosController.RecuperarCliente(APedido);
Self.Anadir(AFactura);
AFactura.Cliente := APedido.Cliente;
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 TFacturasClienteController.Buscar(const ID: Integer): IBizFacturaCliente;
begin
Result := (FDataModule as IDataModuleFacturasCliente).GetItem(ID);
FiltrarEmpresa(Result);
end;
function TFacturasClienteController.BuscarTodasPendientesComision(IdAgente:Integer; IdComision: Integer; IdFacturasAsociadas: String): IBizFacturaCliente;
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_FacturasClienteID_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_FacturasClienteID_COMISION_LIQUIDADA + ' IS NULL ');
CloseBraket;
//Quitamos aquellas que ya est<73>n asociadas
if length(IdFacturasAsociadas) > 0 then
begin
AddOperator(opAND);
OpenBraket;
AddText(fld_FacturasClienteID + ' 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_FacturasClienteID_COMISION_LIQUIDADA + ' = ' + IntToStr(IdComision));
CloseBraket;
//En el caso de que halla facturas asociadas
if length(IdFacturasAsociadas) > 0 then
begin
AddOperator(opAND);
OpenBraket;
AddText(fld_FacturasClienteID + ' not in (' + IdFacturasAsociadas + ')');
CloseBraket;
end;
CloseBraket;
CloseBraket;
end;
finally
HideHourglassCursor;
end;
// showmessage(Result.DataTable.Where.Clause);
end;
function TFacturasClienteController.BuscarTodos: IBizFacturaCliente;
begin
Result := FDataModule.GetItems;
FiltrarEmpresa(Result);
end;
constructor TFacturasClienteController.Create;
begin
FDataModule := TDataModuleFacturasCliente.Create(Nil);
FClienteController := TClientesController.Create;
FDetallesController := TDetallesFacturaClienteController.Create;
FDetallesController.addObservador(Self);
end;
function TFacturasClienteController.CreateEditor(const AName: String;
const IID: TGUID; out Intf): Boolean;
begin
Result := Supports(EditorRegistry.CreateEditor(AName), IID, Intf);
end;
procedure TFacturasClienteController.DescartarCambios(AFactura: IBizFacturaCliente);
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 TFacturasClienteController.Destroy;
begin
FDataModule := Nil;
FClienteController := Nil;
FDetallesController := Nil;
inherited;
end;
function TFacturasClienteController.Duplicar(AFactura: IBizFacturaCliente): IBizFacturaCliente;
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; //Al ser una nueva debe de estar pendiente
FECHA_FACTURA := DateOf(Now);
ID_COMISION_LIQUIDADA := 0;
end;
Result.Post;
finally
HideHourglassCursor;
end;
end;
function TFacturasClienteController.ValidarFactura(AFactura: IBizFacturaCliente): 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_CLIENTE < 0) or (AFactura.ID_CLIENTE = 0) then
// No comprobar el objeto Cliente por que puede fallar la validaci<63>n
// cuando se generan facturas autom<6F>ticamente.
{ (not Assigned(AFactura.Cliente)) or
(AFactura.Cliente.IsEmpty) then}
raise Exception.Create('Debe indicar el cliente 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 cliente 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.Cliente)
and (AFactura.ID_CLIENTE <> AFactura.Cliente.ID) then
AFactura.ID_CLIENTE := AFactura.Cliente.ID;
Result := True;
finally
AFactura.Post;
end;
end;
procedure TFacturasClienteController.Ver(AFactura: IBizFacturaCliente);
var
AEditor : IEditorFacturaCliente;
begin
AEditor := NIL;
ShowHourglassCursor;
try
RecuperarCliente(AFactura);
CreateEditor('EditorFacturaCliente', IEditorFacturaCliente, 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);
Release;
end;
finally
AEditor := NIL;
HideHourglassCursor;
end;
end;
procedure TFacturasClienteController.VerTodos(AFacturas: IBizFacturaCliente);
var
AEditor : IEditorFacturasCliente;
begin
AEditor := NIL;
ShowHourglassCursor;
try
CreateEditor('EditorFacturasCliente', IEditorFacturasCliente, AEditor);
if Assigned(AEditor) then
with AEditor do
begin
Controller := Self; //OJO ORDEN MUY IMPORTANTE
Facturas := AFacturas;
MultiSelect := True;
ShowEmbedded;
end;
finally
AEditor := Nil;
HideHourglassCursor;
end;
end;
function TFacturasClienteController._Vacio: IBizFacturaCliente;
begin
Result := Buscar(ID_NULO);
end;
function TFacturasClienteController.Eliminar(const ID: Integer): Boolean;
var
AFactura : IBizFacturaCliente;
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 TFacturasClienteController.ElegirFacturas(AFacturas: IBizFacturaCliente; AMensaje: String;
AMultiSelect: Boolean): IBizFacturaCliente;
var
AEditor : IEditorElegirFacturasCliente;
begin
Result := NIL;
CreateEditor('EditorElegirFacturasCliente', IEditorElegirFacturasCliente, AEditor);
try
with AEditor do
begin
Controller := Self;
Facturas := AFacturas;
MultiSelect := AMultiSelect;
Mensaje := AMensaje;
if IsPositiveResult(ShowModal) then
Result := FacturasClienteSeleccionados;
Release;
end;
finally
AEditor := NIL;
end;
end;
function TFacturasClienteController.Eliminar(AFactura: IBizFacturaCliente; 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 TFacturasClienteController.EsEliminable(AFactura: IBizFacturaCliente): Boolean;
begin
Result := EsModificable(AFactura);
end;
function TFacturasClienteController.EsModificable(AFactura: IBizFacturaCliente): Boolean;
begin
if not Assigned(AFactura) then
raise Exception.Create ('Factura no asignado: EsModificable');
Result := (AFactura.SITUACION = CTE_PENDIENTE);
end;
procedure TFacturasClienteController.RecalcularImportes(
AFactura: IBizFacturaCliente);
var
bEnEdicion : Boolean;
begin
if not Assigned(AFactura) then
raise Exception.Create ('Factura no asignado (RecalcularImportes)');
if AFactura.DataTable.Active then
AFactura.DataTable.Active := True;
bEnEdicion := (AFactura.DataTable.State in dsEditModes);
if not bEnEdicion then
AFactura.Edit;
ShowHourglassCursor;
AFactura.Edit;
try
AFactura.IMPORTE_NETO := FDetallesController.DarTotalImporteTotal(AFactura.Detalles);
AFactura.IMPORTE_PORTE := FDetallesController.DarTotalPorteTotal(AFactura.Detalles);
if not bEnEdicion then
AFactura.Post;
finally
HideHourglassCursor;
end;
end;
procedure TFacturasClienteController.RecibirAviso(ASujeto: ISujeto; ADataTable: IDAStronglyTypedDataTable);
var
AFactura : IBizFacturaCliente;
ADetalles : IBizDetallesFacturaCliente;
begin
inherited;
if Supports(ADataTable, IBizDetallesFacturaCliente, ADetalles) and
Supports(ADetalles.DataTable.MasterSource.DataTable, IBizFacturaCliente, AFactura) then
begin
RecalcularImportes(AFactura);
end;
end;
procedure TFacturasClienteController.RecuperarCliente(
AFactura: IBizFacturaCliente);
begin
AFactura._Cliente := (FClienteController.Buscar(AFactura.ID_CLIENTE) as IBizCliente);
end;
function TFacturasClienteController.Existe(const ID: Integer): Boolean;
var
AFactura : IBizFacturaCliente;
begin
try
AFactura := Buscar(ID);
Result := Assigned(AFactura) and (AFactura.ID = ID);
finally
AFactura := NIL;
end;
end;
function TFacturasClienteController.ExtraerSeleccionados(AFacturasCliente: IBizFacturaCliente): IBizFacturaCliente;
var
ASeleccionados : IBizFacturaCliente;
begin
ASeleccionados := (Self.Buscar(ID_NULO) as IBizFacturaCliente);
CopyDataTableDA3(AFacturasCliente.DataTable, ASeleccionados.DataTable, True);
Result := ASeleccionados;
end;
procedure TFacturasClienteController.FiltrarEmpresa(AFactura: IBizFacturaCliente);
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_FacturasClienteID_EMPRESA, cEqual, dmUsuarios.IDEmpresaActual);
end;
}
end;
procedure TFacturasClienteController.SetClienteController(const Value: IClientesController);
begin
FClienteController := Value;
end;
procedure TFacturasClienteController.SetDetallesController(const Value: IDetallesFacturaClienteController);
begin
FDetallesController := Value;
end;
function TFacturasClienteController.Guardar(AFactura: IBizFacturaCliente): 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 TFacturasClienteController.Nuevo: IBizFacturaCliente;
var
AFactura : IBizFacturaCliente;
begin
AFactura := FDataModule.NewItem;
FiltrarEmpresa(AFactura);
AFactura.DataTable.Active := True;
AFactura.Insert;
Result := AFactura;
end;
procedure TFacturasClienteController.Preview(AFactura: IBizFacturaCliente; AllItems: Boolean = false);
var
AReportController : IFacturasClienteReportController;
ID_Facturas: TStringList;
begin
AReportController := TFacturasClienteReportController.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;
ID_Facturas.Free;
end;
end;
procedure TFacturasClienteController.Print(AFactura: IBizFacturaCliente; AllItems: Boolean = false);
var
AReportController : IFacturasClienteReportController;
ID_Facturas: TStringList;
begin
AReportController := TFacturasClienteReportController.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;
ID_Facturas.Free;
end;
end;
function TFacturasClienteController.GenerarAbono(AFactura: IBizFacturaCliente): IBizFacturaCliente;
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 TFacturasClienteController.GenerarRecibos(AFactura: IBizFacturaCliente);
var
AFormasPagoController : IFormasPagoController;
AFormaPago: IBizFormaPago;
ARecibosClienteController: IRecibosClienteController;
ARecibos: IBizRecibosCliente;
AFechaVencimiento: TDateTime;
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');
ARecibosClienteController := TRecibosClienteController.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 := ARecibosClienteController.BuscarRecibosFactura(AFactura.ID);
ARecibosClienteController.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 := ARecibosClienteController.Nuevo;
ARecibos.Edit;
ARecibos.ID_FACTURA := AFactura.ID;
ARecibos.REFERENCIA := AFactura.REFERENCIA + ' - ' + IntToStr(i);
AFechaVencimiento := AFactura.FECHA_FACTURA + AFormaPago.Plazos.NUM_DIAS;
if (AFactura.Cliente.VENCIMIENTO_FACTURAS <> 0) then
begin
if DayOf(AFechaVencimiento) > AFactura.Cliente.VENCIMIENTO_FACTURAS then
begin
AFechaVencimiento := IncDay(AFechaVencimiento, (DaysInMonth(AFechaVencimiento) - DayOf(AFechaVencimiento)));
AFechaVencimiento := IncDay(AFechaVencimiento, AFactura.Cliente.VENCIMIENTO_FACTURAS);
end
else
AFechaVencimiento := IncDay(AFechaVencimiento, (AFactura.Cliente.VENCIMIENTO_FACTURAS - DayOf(AFechaVencimiento)));
end;
ARecibos.FECHA_VENCIMIENTO := AFechaVencimiento;
ARecibos.IMPORTE := AFactura.IMPORTE_TOTAL * (AFormaPago.Plazos.PORCENTAJE / 100);
ARecibosClienteController.Guardar(ARecibos);
Inc(i);
Next;
end;
end;
//Liberamos
AFormasPagoController := Nil;
AFormaPago := Nil;
ARecibosClienteController := Nil;
ARecibos := Nil;
end;
function TFacturasClienteController.GetClienteController: IClientesController;
begin
Result := FClienteController;
end;
function TFacturasClienteController.GetDetallesController: IDetallesFacturaClienteController;
begin
Result := FDetallesController;
end;
end.