2011-11-14 17:40:41 +00:00
unit uFacturasClienteController;
interface
2011-11-18 17:12:39 +00:00
2011-11-14 17:40:41 +00:00
uses
Classes, SysUtils, Variants, uDADataTable, uControllerBase, uIDataModuleFacturasCliente,
uClientesController, uDetallesFacturaClienteController, uBizAlbaranesCliente,
uBizFacturasCliente, uBizDireccionesContacto;
type
IFacturasClienteController = interface( IControllerBase)
[ '{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 ( WithInsert: Boolean = True ) : IBizFacturaCliente;
function Anadir( AFactura : IBizFacturaCliente) : Boolean ; overload ;
function AnadirAbono( AFactura : IBizFacturaCliente) : Boolean ;
function Anadir( AFacturas : IBizFacturaCliente; AListaAlbaranes : IBizAlbaranCliente) : Boolean ; overload ;
function Eliminar( const ID : Integer ) : Boolean ; overload ;
function Eliminar( AFactura : IBizFacturaCliente; AllItems: Boolean = false ; AListaCausas: TStringList = nil ) : Boolean ; overload ;
function Guardar( AFactura : IBizFacturaCliente) : Boolean ;
procedure DescartarCambios( AFactura : IBizFacturaCliente) ;
function Existe( const ID: Integer ) : Boolean ;
procedure RecuperarCliente( AFactura : IBizFacturaCliente) ;
2013-09-25 17:13:02 +00:00
procedure ActualizarFormaDePago( AFactura : IBizFacturaCliente; ID_FORMA_PAGO: Integer ) ;
2011-11-14 17:40:41 +00:00
function Duplicar( AFactura: IBizFacturaCliente) : IBizFacturaCliente;
function GenerarAbono( AFactura: IBizFacturaCliente) : IBizFacturaCliente;
2011-11-23 16:45:58 +00:00
procedure Preview( AFactura : IBizFacturaCliente; AllItems: Boolean = false ; VerLogotipo: Boolean = true ) ;
procedure Print( AFactura : IBizFacturaCliente; AllItems: Boolean = false ; VerLogotipo: Boolean = true ) ;
2011-11-14 17:40:41 +00:00
procedure RecalcularImportes( AFactura: IBizFacturaCliente) ;
function ElegirFacturas( AFacturas : IBizFacturaCliente; AMensaje: String ; AMultiSelect: Boolean ) : IBizFacturaCliente;
function ExtraerSeleccionados( ARecibosCliente: IBizFacturaCliente) : IBizFacturaCliente;
procedure CopiarDireccion ( const ADireccionEnvio: IBizDireccionesContacto; AFactura: IBizFacturaCliente) ;
procedure SetIgnorarContabilidad ( AFactura: IBizFacturaCliente; const Ignorar: Integer ) ;
function DarListaAnosFacturas: TStringList;
procedure FiltrarAno( AFactura: IBizFacturaCliente; ADynWhereDataTable: WideString ; const Ano: String ) ;
end ;
TFacturasClienteController = class( TControllerBase, 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; override ;
destructor Destroy; override ;
function Eliminar( const ID : Integer ) : Boolean ; overload ;
function Eliminar( AFactura : IBizFacturaCliente; AllItems: Boolean = false ; AListaCausas: TStringList = nil ) : 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 Buscar( const ID: Integer ) : IBizFacturaCliente;
function BuscarTodos: IBizFacturaCliente;
function BuscarTodasPendientesComision( IdAgente: Integer ; IdComision: Integer ; IdFacturasAsociadas: String ) : IBizFacturaCliente;
function Nuevo ( WithInsert: Boolean = True ) : IBizFacturaCliente;
procedure Ver( AFactura : IBizFacturaCliente) ;
procedure VerTodos( AFacturas: IBizFacturaCliente) ;
function Duplicar( AFactura: IBizFacturaCliente) : IBizFacturaCliente;
function GenerarAbono( AFactura: IBizFacturaCliente) : IBizFacturaCliente;
procedure RecuperarCliente( AFactura : IBizFacturaCliente) ;
2013-09-25 17:13:02 +00:00
procedure ActualizarFormaDePago( AFactura : IBizFacturaCliente; ID_FORMA_PAGO: Integer ) ;
2011-11-14 17:40:41 +00:00
2011-11-23 16:45:58 +00:00
procedure Preview( AFactura : IBizFacturaCliente; AllItems: Boolean = false ; VerLogotipo: Boolean = true ) ;
procedure Print( AFactura : IBizFacturaCliente; AllItems: Boolean = false ; VerLogotipo: Boolean = true ) ;
2011-11-14 17:40:41 +00:00
procedure RecalcularImportes( AFactura: IBizFacturaCliente) ;
function EsModificable( AFactura: IBizFacturaCliente; var AComentario: Variant ) : Boolean ;
function EsEliminable( AFactura: IBizFacturaCliente; var AComentario: Variant ) : Boolean ;
function ElegirFacturas( AFacturas : IBizFacturaCliente; AMensaje: String ; AMultiSelect: Boolean ) : IBizFacturaCliente;
function ExtraerSeleccionados( AFacturasCliente: IBizFacturaCliente) : IBizFacturaCliente;
procedure CopiarDireccion ( const ADireccionEnvio: IBizDireccionesContacto; AFactura: IBizFacturaCliente) ;
procedure SetIgnorarContabilidad ( AFactura: IBizFacturaCliente; const Ignorar: Integer ) ;
function DarListaAnosFacturas: TStringList;
procedure FiltrarAno( AFactura: IBizFacturaCliente; ADynWhereDataTable: WideString ; const Ano: String ) ;
end ;
implementation
2011-11-18 17:12:39 +00:00
{$INCLUDE ..\..\..\FactuGES.inc}
2011-11-14 17:40:41 +00:00
uses
Windows, uDateUtils, uNumUtils, Controls, cxControls, DB, uEditorRegistryUtils, schFacturasClienteClient_Intf,
uBizContactos, uIEditorFacturasCliente, uIEditorFacturaCliente, uFactuGES_App,
uDataModuleFacturasCliente, uBizDetallesFacturaCliente, uControllerDetallesBase,
uDataModuleUsuarios, uDAInterfaces, uDataTableUtils, uAlbaranesClienteController,
schAlbaranesClienteClient_Intf, uROTypes, uDetallesAlbaranClienteController,
uBizDetallesAlbaranCliente, uFacturasClienteReportController, DateUtils, Forms,
2015-12-04 12:18:02 +00:00
Dialogs, uIntegerListUtils, uIEditorElegirFacturasCliente,
uFormasPagoController, uBizFormasPago, uTiposIVAController, uBizTiposIVA,
2011-11-14 17:40:41 +00:00
uBizEjercicios, uRecibosClienteController, uBizRecibosCliente;
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
//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;
2021-02-26 08:52:27 +00:00
//En el caso de descuento de capitulo debemos a<> adirlo como una linea detalle con un descuento
if ( AOrigen. TIPO_DETALLE = TIPO_DETALLE_DESCUENTO)
and ( AOrigen. DESCUENTO > 0 ) then
begin
ADestino. CONCEPTO : = AOrigen. CONCEPTO + AOrigen. DataTable. FieldByName( fld_AlbaranesCliente_DetallesDESCUENTO) . AsString + ' %' ;
ADestino. CANTIDAD : = 1 ;
ADestino. IMPORTE_UNIDAD : = AOrigen. IMPORTE_TOTAL;
end
else
begin
ADestino. CONCEPTO : = AOrigen. CONCEPTO;
ADestino. CANTIDAD : = AOrigen. CANTIDAD;
ADestino. DESCUENTO : = AOrigen. DESCUENTO;
ADestino. IMPORTE_UNIDAD : = AOrigen. IMPORTE_UNIDAD;
end ;
2011-11-14 17:40:41 +00:00
ADestino. IMPORTE_TOTAL : = AOrigen. IMPORTE_TOTAL;
ADestino. IMPORTE_PORTE : = AOrigen. IMPORTE_PORTE;
ADestino. VISIBLE : = AOrigen. VISIBLE;
2021-02-26 08:52:27 +00:00
ADestino. VALORADO : = AOrigen. VALORADO;
2011-11-14 17:40:41 +00:00
// ADestino.REFERENCIA_PROVEEDOR := AOrigen.REFERENCIA_PROVEEDOR;
ADestino. Post;
AOrigen. Next;
end ;
finally
ADetallesController. EndUpdate( ADestino) ;
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 ;
2013-09-25 17:13:02 +00:00
procedure TFacturasClienteController. ActualizarFormaDePago(
AFactura: IBizFacturaCliente; ID_FORMA_PAGO: Integer ) ;
var
AFormasPago : IBizFormaPago;
AFormasPagoController : IFormasPagoController;
2015-12-04 12:18:02 +00:00
ATiposIVA : IBizTipoIVA;
ATiposIVAController : ITiposIVAController;
2013-10-08 16:59:28 +00:00
bEnEdicion : Boolean ;
2013-09-25 17:13:02 +00:00
begin
AFormasPagoController : = TFormasPagoController. Create;
AFormasPago : = AFormasPagoController. Buscar( ID_FORMA_PAGO) ;
AFormasPago. Open;
2015-12-04 12:18:02 +00:00
//Se cambia tambien el tipo de IVA por el de la ficha a peticion de Angelica
ATiposIVAController : = TTiposIVAController. Create;
ATiposIVA : = ATiposIVAController. Buscar( AFactura. Cliente. ID_TIPO_IVA) ;
ATiposIVA. Open;
2013-10-08 16:59:28 +00:00
bEnEdicion : = ( AFactura. DataTable. State in dsEditModes) ;
if not bEnEdicion then
AFactura. Edit;
2013-09-25 17:13:02 +00:00
AFactura. ID_FORMA_PAGO : = AFormasPago. ID;
// AFactura.DataTable.FieldByName(fld_FacturasClienteFORMA_PAGO).AsString := AFormasPago.DESCRIPCION;
2015-12-04 12:18:02 +00:00
AFactura. ID_TIPO_IVA : = ATiposIva. ID;
2013-09-25 17:13:02 +00:00
2013-10-08 16:59:28 +00:00
if not bEnEdicion then
AFactura. Post;
2013-09-25 17:13:02 +00:00
AFormasPago : = NIL ;
AFormasPagoController : = NIL ;
2015-12-04 12:18:02 +00:00
ATiposIVA : = NIL ;
ATiposIVAController : = NIL ;
2013-09-25 17:13:02 +00:00
end ;
2011-11-14 17:40:41 +00:00
function TFacturasClienteController. Anadir( AFacturas: IBizFacturaCliente;
AListaAlbaranes: IBizAlbaranCliente) : Boolean ;
var
AFacturaActual : IBizFacturaCliente;
AAlbaranesController : IAlbaranesClienteController;
2020-06-24 17:13:35 +00:00
ACadena: String ;
2021-02-26 08:52:27 +00:00
I, x: Integer ;
2011-11-14 17:40:41 +00:00
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 ;
2014-05-08 15:04:53 +00:00
//En este caso no queremos el descuento general del cliente asociado a su ficha, ya que partimos del valor que tengan las olbaranes
bEnEdicion : = ( AFacturaActual. DataTable. State in dsEditModes) ;
if not bEnEdicion then
AFacturaActual. Edit;
AFacturaActual. DESCUENTOIsNull : = True ;
AFacturaActual. Post;
if bEnEdicion then
AFacturaActual. Edit;
2011-11-14 17:40:41 +00:00
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;
2020-12-14 11:14:43 +00:00
//Establecemos la forma de pago establecido en la ficha del cliente
if AFacturas. Cliente. ID_FORMA_PAGO > 0 then
AFacturas. ID_FORMA_PAGO : = AFacturas. Cliente. ID_FORMA_PAGO;
// if AFacturas.Cliente.ID_TIPO_IVA > 0 then
// AFacturas.ID_TIPO_IVA := AFacturas.Cliente.ID_TIPO_IVA;
2014-05-08 15:04:53 +00:00
//En este caso no queremos el descuento general del cliente asociado a su ficha, ya que partimos del valor que tengan las olbaranes
bEnEdicion : = ( AFacturas. DataTable. State in dsEditModes) ;
if not bEnEdicion then
AFacturas. Edit;
AFacturas. DESCUENTOIsNull : = True ;
AFacturas. Post;
if bEnEdicion then
AFacturas. Edit;
2011-11-14 17:40:41 +00:00
//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
2021-02-26 08:52:27 +00:00
AFacturaActual. Detalles. DataTable. Sort( [ fld_FacturasCliente_DetallesPOSICION] , [ uDADataTable. sdAscending] ) ;
2011-11-14 17:40:41 +00:00
AFacturaActual. Detalles. DataTable. Last;
2020-06-24 17:13:35 +00:00
2021-02-26 08:52:27 +00:00
2020-06-24 17:13:35 +00:00
// A<> ado el t<> tulo, se cambia a petici<63> n por linea de concepto con resumen del albaran correspondiente, SE SOLICITA QUITAR POR M<> NICA 16/06/2020
Self. DetallesController. Add( AFacturaActual. Detalles, TIPO_DETALLE_CONCEPTO) ;
2011-11-14 17:40:41 +00:00
with AFacturaActual. Detalles do
begin
2020-06-24 17:13:35 +00:00
ACadena : = '' ;
ACadena : = 'Albar<61> n ' + AListaAlbaranes. REFERENCIA + ' de ' + DateToStr( AListaAlbaranes. FECHA_ALBARAN) ;
2011-11-14 17:40:41 +00:00
Edit;
2020-06-24 17:13:35 +00:00
CONCEPTO : = ACadena;
2011-11-14 17:40:41 +00:00
Post;
end ;
2021-02-26 08:52:27 +00:00
2011-11-14 17:40:41 +00:00
// A<> ado el contenido del albar<61> n
CopiarArticulosAlbaran( AListaAlbaranes. Detalles, AFacturaActual. Detalles) ;
2021-02-26 08:52:27 +00:00
//MUCHO CUIDADO NOS TENEMOS QUE ASEGURAR DE A<> ADIR AL FINAL DEL TODO, podr<64> a calcular mal los descuentos de capitulo de la factura si los hubiera
AFacturaActual. Detalles. DataTable. Sort( [ fld_FacturasCliente_DetallesPOSICION] , [ uDADataTable. sdAscending] ) ;
AFacturaActual. Detalles. DataTable. Last;
2014-05-08 15:04:53 +00:00
//Sacamos el importe del porte en el caso de tener
if ( AListaAlbaranes. IMPORTE_PORTE > 0 ) then
2011-11-14 17:40:41 +00:00
begin
2014-05-08 15:04:53 +00:00
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 ;
end ;
//Sacamos el descuento total del albaran en el caso de tener
if ( AListaAlbaranes. IMPORTE_DESCUENTO > 0 ) then
begin
Self. DetallesController. Add( AFacturaActual. Detalles, TIPO_DETALLE_CONCEPTO) ;
with AFacturaActual. Detalles do
begin
Edit;
2021-02-26 08:52:27 +00:00
CONCEPTO : = 'Descuento del albar<61> n ' + AListaAlbaranes. REFERENCIA + ' - ' + AListaAlbaranes. DataTable. FieldByName( fld_AlbaranesClienteDESCUENTO) . AsString + '%' ;
2014-05-08 15:04:53 +00:00
CANTIDAD : = - 1 ;
IMPORTE_UNIDAD : = AListaAlbaranes. IMPORTE_DESCUENTO;
Post;
end ;
2011-11-14 17:40:41 +00:00
end ;
2020-06-24 17:13:35 +00:00
// A<> ado el resumen SE SOLICITA QUITAR POR M<> NICA 16/06/2020
// Self.DetallesController.Add(AFacturaActual.Detalles, TIPO_DETALLE_SUBTOTAL);
// with AFacturaActual.Detalles do
// begin
// Edit;
// CONCEPTO := 'Total del albar<61> n ' + AListaAlbaranes.REFERENCIA;
// Post;
// end;
2011-11-14 17:40:41 +00:00
// 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;
var
Condicion: TDAWhereExpression;
Condicion1: TDAWhereExpression;
Condicion2: TDAWhereExpression;
Condicion3: TDAWhereExpression;
Condicion4: TDAWhereExpression;
Cadena : TStringList;
i: Integer ;
begin
ShowHourglassCursor;
try
Result : = BuscarTodos;
with Result . DataTable. DynamicWhere do
begin
//Todas las facturas que sean comisionables
Condicion : = NewBinaryExpression( NewField( '' , fld_FacturasClienteSIN_COMISION) , NewConstant( 0 , datInteger) , dboEqual) ;
if IsEmpty then
Expression : = Condicion
else
Expression : = NewBinaryExpression( Expression, Condicion, dboAnd) ;
end ;
with Result . DataTable. DynamicWhere do
begin
//Todas las facturas de esta liquidaci<63> n
Condicion1 : = NewBinaryExpression( NewField( '' , fld_FacturasClienteID_COMISION_LIQUIDADA) , NewConstant( IdComision, datInteger) , dboEqual) ;
//Todas aquellas facturas que ya esten asociadas a la liquidaci<63> n actual no deben salir
if ( Length( IdFacturasAsociadas) > 0 ) then
begin
Cadena : = TStringList. Create;
Cadena. CommaText : = IdFacturasAsociadas;
Condicion2 : = nil ;
//Vamos generando todas las where de cada uno de los ID recibidos por parametro
for i : = 0 to Cadena. Count - 1 do
with Result . DataTable. DynamicWhere do
begin
Condicion4 : = NewBinaryExpression( NewField( '' , fld_FacturasClienteID) , NewConstant( StrToInt( Cadena. Strings[ i] ) , datInteger) , dboNotEqual) ;
if Condicion2 = nil then
Condicion2 : = Condicion4
else
Condicion2 : = NewBinaryExpression( Condicion2, Condicion4, dboAnd) ;
end ;
Cadena. Free;
end ;
//Todas aquellas que no esten asociadas a ninguna liquidaci<63> n, y que tampoco esten en el editor, ya que en cache estan
//asociadas a la liquidadcion pero en datos me viene como nula
Condicion3 : = NewBinaryExpression( NewField( '' , fld_FacturasClienteID_COMISION_LIQUIDADA) , NewNull( ) , dboEqual) ;
//Si no hay facturas en el editor no las tenemos en cuenta
if ( Condicion2 < > nil ) then
begin
Condicion1 : = NewBinaryExpression( Condicion1, Condicion2, dboAnd) ;
Condicion3 : = NewBinaryExpression( Condicion3, Condicion2, dboAnd) ;
end ;
// Todas aquellas facturas asociadas a la comisi<73> n actual y que no est<73> n asociadas al editor (IdFacturasAsociadas)
//esto es porque se puede agregar y quitar facturas y todos los cambios estan en cache
// y por lo tanto al pedir las facturas a seleccionar debemos tener en cuenta que en el
//almac<61> n dichos cambios cache todav<61> a no se han producido
Condicion : = NewBinaryExpression( Condicion1, Condicion3, dboOr) ;
if IsEmpty then
Expression : = Condicion
else
Expression : = NewBinaryExpression( Expression, Condicion, dboAnd) ;
end ;
finally
HideHourglassCursor;
end ;
end ;
function TFacturasClienteController. BuscarTodos: IBizFacturaCliente;
begin
Result : = FDataModule. GetItems;
FiltrarEmpresa( Result ) ;
end ;
procedure TFacturasClienteController. CopiarDireccion(
const ADireccionEnvio: IBizDireccionesContacto; AFactura: IBizFacturaCliente) ;
var
bEnEdicion : Boolean ;
begin
if not Assigned( AFactura) then
raise Exception. Create ( 'Factura no asignado (CopiarDireccionEnvio)' ) ;
if not Assigned( ADireccionEnvio) then
raise Exception. Create ( 'No se ha indicado la direcci<63> n (CopiarDireccionEnvio)' ) ;
if AFactura. DataTable. Active then
AFactura. DataTable. Active : = True ;
if ADireccionEnvio. DataTable. Active then
ADireccionEnvio. DataTable. Active : = True ;
bEnEdicion : = ( AFactura. DataTable. State in dsEditModes) ;
if not bEnEdicion then
AFactura. Edit;
ShowHourglassCursor;
AFactura. Edit;
try
AFactura. CALLE : = ADireccionEnvio. CALLE;
AFactura. POBLACION : = ADireccionEnvio. POBLACION;
AFactura. CODIGO_POSTAL : = ADireccionEnvio. CODIGO_POSTAL;
AFactura. PROVINCIA : = ADireccionEnvio. PROVINCIA;
AFactura. NIF_CIF : = ADireccionEnvio. NIF_CIF;
AFactura. NOMBRE : = ADireccionEnvio. NOMBRE;
if not bEnEdicion then
AFactura. Post;
finally
HideHourglassCursor;
end ;
end ;
constructor TFacturasClienteController. Create;
begin
inherited ;
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 ;
function TFacturasClienteController. DarListaAnosFacturas: TStringList;
begin
Result : = FDataModule. GetAnosItems;
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;
2012-01-23 17:02:46 +00:00
ID_TIENDA : = AppFactuGES. TiendaActiva. ID;
2011-11-14 17:40:41 +00:00
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 ;
2011-11-18 17:12:39 +00:00
{$IFDEF CONTABILIDAD}
2011-11-14 17:40:41 +00:00
ID_EJERCICIO : = AppFactuGES. EjercicioActivo. ID;
ESTADO_EJERCICIO : = AppFactuGES. EjercicioActivo. ESTADO;
ASIENTO_PUNTEADO : = - 1 ;
//En el caso de que el ejercicio este cerrado dejamos duplicar factura sin asociar a contabilidad.
if ESTADO_EJERCICIO = CTE_CERRADO then
begin
IGNORAR_CONTABILIDAD : = 1 ;
ESTADO_EJERCICIO : = '' ;
end ;
2011-11-18 17:12:39 +00:00
{$ENDIF}
2011-11-14 17:40:41 +00:00
end ;
Result . Post;
finally
HideHourglassCursor;
end ;
end ;
function TFacturasClienteController. ValidarFactura( AFactura: IBizFacturaCliente) : 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_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' ) ;
2016-01-12 10:46:50 +00:00
//En el caso de asignar una retenci<63> n a la factura ser<65> obligatorio meter la fecha de retenci<63> n.
if ( AFactura. IMPORTE_RETENCION > 0 ) then
if ( EsFechaVacia( AFactura. FECHA_RETENCION) ) then
raise Exception. Create( 'Debe indicar la fecha de vencimiento de la retenci<63> n, para poder asociarla al recibo que contendr<64> el importe de la retenci<63> n.' ) ;
2011-11-14 17:40:41 +00:00
if ( AFactura. Detalles. DataTable. RecordCount = 0 ) then
raise Exception. Create( 'La factura debe tener al menos un concepto en su contenido' ) ;
if ( AFactura. ID_FORMA_PAGO = 0 ) then
raise Exception. Create( 'Debe indicar una forma de pago 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
//OJO-----En facturas de cliente para acana no es obligatorio porque deben de poder generar facturas sin recibos asociados
{ 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 ;
}
2011-11-18 17:12:39 +00:00
{$IFDEF CONTABILIDAD}
2011-11-14 17:40:41 +00:00
if ( AFactura. IGNORAR_CONTABILIDAD = 0 ) then
begin
if ( AppFactuGES. EjercicioActivo. ESTADO = CTE_CERRADO) then
raise Exception. Create( 'Para que la factura pueda pasar a la parte contable el ejercicio activo debe esta ABIERTO' ) ;
if ( ( AFactura. Cliente. SubCuentas. ID < 1 ) or ( AFactura. Cliente. SubCuentas. ID_EJERCICIO < > AppFactuGES. EjercicioActivo. ID) ) then
raise Exception. Create( 'Para que la factura pueda pasar la parte contable es necesario que el cliente tenga asignada una subcuenta' ) ;
end ;
2011-11-18 17:12:39 +00:00
{$ENDIF}
2011-11-14 17:40:41 +00:00
//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, asegurese que las cantidades sean negativas' ) ;
{ Esta validaci<EFBFBD> n puede saltar cuando se generan facturas autom<EFBFBD> ticamente
por albaranes o pedidos y el cliente no tiene Tipo de IVA puesto, se cambia,
para signar autom<EFBFBD> ticamente por defecto a la factura la primera forma de pago,
e iva disponible ( CONTADO, IVA16) , en la clase de negocio }
{ if ( AFactura. ID_TIPO_IVA = 0 ) then
raise Exception. Create( 'Debe indicar un tipo de IVA para esta factura' ) ; }
{ Asegurarse de valores en campos "autom<6F> ticos" tanto
en MODIFICACI<EFBFBD> N como en INSERCI<EFBFBD> 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;
AComentario : Variant ;
begin
AEditor : = NIL ;
RecuperarCliente( AFactura) ;
CreateEditor( 'EditorFacturaCliente' , IEditorFacturaCliente, AEditor) ;
if Assigned( AEditor) then
try
AEditor. Controller : = Self; //OJO ORDEN MUY IMPORTANTE
AEditor. Factura : = AFactura;
//MODO CONSULTAR
if not EsModificable( AFactura, AComentario) then
begin
SetDataTableReadOnly( AFactura. DataTable, True ) ;
AEditor. ReadOnly : = True ;
AEditor. Comentario : = AComentario;
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 TFacturasClienteController. VerTodos( AFacturas: IBizFacturaCliente) ;
var
AEditor : IEditorFacturasCliente;
begin
AEditor : = NIL ;
CreateEditor( 'EditorFacturasCliente' , IEditorFacturasCliente, AEditor) ;
if Assigned( AEditor) then
with AEditor do
begin
Controller : = Self; //OJO ORDEN MUY IMPORTANTE
Facturas : = AFacturas;
MultiSelect : = True ;
ShowEmbedded;
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) ;
if Assigned( AEditor) then
try
AEditor. Controller : = Self;
AEditor. Facturas : = AFacturas;
AEditor. MultiSelect : = AMultiSelect;
AEditor. Mensaje : = AMensaje;
if IsPositiveResult( AEditor. ShowModal) then
Result : = AEditor. FacturasClienteSeleccionados;
finally
AEditor. Release;
AEditor : = NIL ;
end ;
end ;
function TFacturasClienteController. Eliminar( AFactura: IBizFacturaCliente; AllItems: Boolean = false ; AListaCausas: TStringList = nil ) : Boolean ;
//Solo devolver<65> true en el caso de eliminar todos y cada uno de los elementos a eliminar
var
bEliminado: Boolean ;
ACausa: Variant ;
begin
bEliminado : = True ;
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 tanto si es una lista de facturas a eliminar como si es la propia lista del editor.
if not EsEliminable( AFactura, ACausa) then
begin
if Assigned( AListaCausas) then
AListaCausas. Add( Format( '%d=%s' , [ AFactura. ID, ACausa] ) ) ;
bEliminado : = False ;
end
else
AFactura. Delete;
//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 not EsEliminable( AFactura, ACausa) then
begin
if Assigned( AListaCausas) then
AListaCausas. Add( Format( '%d=%s' , [ AFactura. ID, ACausa] ) ) ;
bEliminado : = False ;
Next;
end
else
AFactura. Delete;
end ;
end ;
end ;
try
AFactura. DataTable. ApplyUpdates;
Result : = bEliminado;
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 ;
finally
HideHourglassCursor;
end ;
end ;
function TFacturasClienteController. EsEliminable( AFactura: IBizFacturaCliente; var AComentario: Variant ) : Boolean ;
begin
Result : = True ;
if not Assigned( AFactura) then
raise Exception. Create ( 'Factura no asignado: EsEliminable' ) ;
2013-05-30 09:06:45 +00:00
2011-11-14 17:40:41 +00:00
if ( AFactura. SITUACION < > CTE_PENDIENTE) then
begin
Result : = False ;
AComentario : = 'La factura esta parcial o totalmente pagada, por lo que no puede ser eliminada' ;
2013-05-30 09:06:45 +00:00
end ;
{
2011-11-14 17:40:41 +00:00
else if ( AFactura. ESTADO_EJERCICIO = CTE_CERRADO) then
begin
Result : = False ;
AComentario : = 'La factura tiene un asiento asociado en la parte contable cuyo ejercicio esta cerrado, por lo que no puede ser eliminada' ;
end
else if ( AFactura. ASIENTO_PUNTEADO > 0 ) then
begin
Result : = False ;
AComentario : = 'La factura tiene un asiento asociado en la parte contable y est<73> punteado, por lo que no puede ser eliminada' ;
end ;
2012-02-07 17:19:35 +00:00
}
2011-11-14 17:40:41 +00:00
end ;
function TFacturasClienteController. EsModificable( AFactura: IBizFacturaCliente; var AComentario: Variant ) : Boolean ;
2013-05-30 09:06:45 +00:00
var
AFormaPago: IBizFormaPago;
bFacturaConRecibos: Boolean ;
2011-11-14 17:40:41 +00:00
begin
2013-05-30 09:06:45 +00:00
Result : = True ;
2011-11-14 17:40:41 +00:00
AComentario : = Null;
if not Assigned( AFactura) then
raise Exception. Create ( 'Factura no asignado: EsModificable' ) ;
2013-05-30 09:06:45 +00:00
bFacturaConRecibos : = not AFactura. FECHA_VENCIMIENTOIsNull;
if not bFacturaConRecibos then
with TFormasPagoController. Create do
begin
try
AFormaPago : = Buscar( AFactura. ID_FORMA_PAGO) ;
AFormaPago. DataTable. Active : = True ;
bFacturaConRecibos : = ( AFormaPago. Plazos. RecordCount > 0 ) ;
finally
AFormaPago : = NIL ;
Free;
end ;
end ;
if ( bFacturaConRecibos and ( AFactura. SITUACION < > CTE_PENDIENTE) ) then
2011-11-14 17:40:41 +00:00
begin
Result : = False ;
AComentario : = 'La factura esta parcial o totalmente pagada, por lo que no puede ser modificada' ;
2013-05-30 09:06:45 +00:00
end ;
{
2011-11-14 17:40:41 +00:00
else if ( AFactura. ESTADO_EJERCICIO = CTE_CERRADO) then
begin
Result : = False ;
AComentario : = 'La factura tiene un asiento asociado en la parte contable cuyo ejercicio esta cerrado, por lo que no puede ser modificada' ;
end
else if ( AFactura. ASIENTO_PUNTEADO > 0 ) then
begin
Result : = False ;
AComentario : = 'La factura tiene un asiento asociado en la parte contable y est<73> punteado, por lo que no puede ser modificada' ;
end ;
2012-02-07 17:19:35 +00:00
}
2011-11-14 17:40:41 +00:00
end ;
procedure TFacturasClienteController. RecalcularImportes(
AFactura: IBizFacturaCliente) ;
var
bEnEdicion : Boolean ;
ADetallePosAct : Integer ;
begin
if not Assigned( AFactura) then
raise Exception. Create ( 'Factura no asignado (RecalcularImportes)' ) ;
if AFactura. DataTable. Active then
AFactura. DataTable. Active : = True ;
{ Hay que guardar la posici<EFBFBD> n en la que estamos en los detalles por que
la asignaci<EFBFBD> n de valores a los campos IMPORTE_NETO e IMPORTE_PORTE
( ver m<EFBFBD> s adelante) colocan el puntero en la tabla detalle al principio.
No he encontrado la raz<EFBFBD> n por la que mueve el puntero. }
ADetallePosAct : = AFactura. Detalles. POSICION;
bEnEdicion : = ( AFactura. DataTable. State in dsEditModes) ;
if not bEnEdicion then
AFactura. Edit;
ShowHourglassCursor;
try
AFactura. IMPORTE_NETO : = FDetallesController. DarTotalImporteTotal( AFactura. Detalles) ;
AFactura. IMPORTE_PORTE : = FDetallesController. DarTotalPorteTotal( AFactura. Detalles) ;
if not bEnEdicion then
AFactura. Post;
finally
HideHourglassCursor;
// Restaurar la posici<63> n que ten<65> amos en los detalles.
FDetallesController. LocalizarPosicion( AFactura. Detalles, ADetallePosAct) ;
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) ;
CopyDataTableDA5( AFacturasCliente. DataTable, ASeleccionados. DataTable, True ) ;
Result : = ASeleccionados;
end ;
procedure TFacturasClienteController. FiltrarAno( AFactura: IBizFacturaCliente; 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_FacturasClienteFECHA_FACTURA) , NewConstant( FechaIni, datString) , dboGreaterOrEqual) ;
Condicion : = NewBinaryExpression( NewBinaryExpression( NewField( '' , fld_FacturasClienteFECHA_FACTURA) , NewConstant( FechaFin, datString) , dboLessOrEqual) , Condicion, dboAnd) ;
if IsEmpty then
Expression : = Condicion
else
Expression : = NewBinaryExpression( Condicion, Expression, dboAnd) ;
end ;
end ;
end ;
procedure TFacturasClienteController. FiltrarEmpresa( AFactura: IBizFacturaCliente) ;
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_FacturasClienteID_EMPRESA) , NewConstant( AppFactuGES. EmpresaActiva. ID, datInteger) , dboEqual) ;
if IsEmpty then
Expression : = Condicion
else
Expression : = NewBinaryExpression( Expression, Condicion, dboAnd) ;
end ;
end ;
procedure TFacturasClienteController. SetClienteController( const Value: IClientesController) ;
begin
FClienteController : = Value;
end ;
procedure TFacturasClienteController. SetDetallesController( const Value: IDetallesFacturaClienteController) ;
begin
FDetallesController : = Value;
end ;
procedure TFacturasClienteController. SetIgnorarContabilidad( AFactura: IBizFacturaCliente; const Ignorar: Integer ) ;
var
EnEdicion: Boolean ;
begin
if Assigned( AFactura) then
begin
EnEdicion : = AFactura. DataTable. Editing;
if not AFactura. DataTable. Editing then
AFactura. DataTable. Edit;
AFactura. IGNORAR_CONTABILIDAD : = Ignorar;
AFactura. DataTable. Post;
if EnEdicion then
AFactura. DataTable. Edit;
end ;
end ;
function TFacturasClienteController. Guardar( AFactura: IBizFacturaCliente) : Boolean ;
var
IDNuevo : Integer ;
2014-06-18 11:06:58 +00:00
2011-11-14 17:40:41 +00:00
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 ( WithInsert: Boolean = True ) : IBizFacturaCliente;
var
AFactura : IBizFacturaCliente;
begin
AFactura : = FDataModule. NewItem;
FiltrarEmpresa( AFactura) ;
AFactura. DataTable. Active : = True ;
if WithInsert then
AFactura. Insert;
Result : = AFactura;
end ;
2011-11-23 16:45:58 +00:00
procedure TFacturasClienteController. Preview( AFactura: IBizFacturaCliente; AllItems: Boolean = false ; VerLogotipo: Boolean = true ) ;
2011-11-14 17:40:41 +00:00
var
AReportController : IFacturasClienteReportController;
ID_Facturas: TIntegerList;
begin
AReportController : = TFacturasClienteReportController. Create;
ID_Facturas : = TIntegerList. Create;
try
//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( AFactura. ID) ;
Next;
end ;
end ;
end
//Solo previsualizamos el item seleccionado
else
ID_Facturas. Add( AFactura. ID) ;
2011-11-23 16:45:58 +00:00
AReportController. Preview( ID_Facturas, VerLogotipo) ;
2011-11-14 17:40:41 +00:00
finally
AReportController : = NIL ;
FreeANDNIL( ID_Facturas) ;
end ;
end ;
2011-11-23 16:45:58 +00:00
procedure TFacturasClienteController. Print( AFactura: IBizFacturaCliente; AllItems: Boolean = false ; VerLogotipo: Boolean = true ) ;
2011-11-14 17:40:41 +00:00
var
AReportController : IFacturasClienteReportController;
ID_Facturas: TIntegerList;
begin
AReportController : = TFacturasClienteReportController. Create;
ID_Facturas : = TIntegerList. Create;
try
//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( AFactura. ID) ;
Next;
end ;
end ;
end
//Solo previsualizamos el item seleccionado
else
ID_Facturas. Add( AFactura. ID) ;
2011-11-23 16:45:58 +00:00
AReportController. Print( ID_Facturas, VerLogotipo) ;
2011-11-14 17:40:41 +00:00
finally
AReportController : = NIL ;
FreeANDNIL( ID_Facturas) ;
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 ;
ADiaVencimiento: Integer ;
ADiasMas: Integer ;
BSemaforo: Boolean ;
2014-06-18 11:06:58 +00:00
AImporteAcumulado : Double ;
2016-01-12 10:46:50 +00:00
AImporteTotal: Double ;
2011-11-14 17:40:41 +00:00
begin
if not Assigned( AFactura) then
Exit;
AFormasPagoController : = TFormasPagoController. Create;
AFormaPago : = AFormasPagoController. Buscar( AFactura. ID_FORMA_PAGO) ;
AFormaPago. DataTable. Active : = True ;
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) ;
2016-01-12 10:46:50 +00:00
//Si hay retenci<63> n, se generar<61> un recibo por ese importe, y el resto se generar<61> n recibos
//seg<65> n forma de pago
AImporteTotal : = AFactura. IMPORTE_TOTAL - AFactura. IMPORTE_RETENCION;
2011-11-14 17:40:41 +00:00
//Se cambia la l<> gica a peticion de acana, 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. (Se permitir<69> para acana poder dar de alta facturas sin recibos asociados)
With AFormaPago. Plazos. DataTable do
begin
i : = 1 ;
2014-06-18 11:06:58 +00:00
AImporteAcumulado : = 0 ;
2011-11-14 17:40:41 +00:00
First;
repeat
//SOLO PARA ACANA (Leer comentario anterior
if ( AFormaPago. Plazos. RecordCount > 0 )
or ( AFactura. FECHA_VENCIMIENTO < > 0 ) then
begin
ARecibos : = ARecibosClienteController. Nuevo;
ARecibos. Edit;
ARecibos. ID_FACTURA : = AFactura. ID;
ARecibos. ID_EMPRESA : = AFactura. ID_EMPRESA;
ARecibos. ID_CLIENTE : = AFactura. ID_CLIENTE;
ARecibos. ID_TIENDA : = AFactura. ID_TIENDA;
ARecibos. REFERENCIA : = AFactura. REFERENCIA + ' - ' + IntToStr( i) ;
ARecibos. NOMBRE : = AFactura. NOMBRE; //Es la razon social de la factura
ARecibos. CALLE : = AFactura. CALLE;
ARecibos. NIF_CIF : = AFactura. NIF_CIF;
ARecibos. POBLACION : = AFactura. POBLACION;
ARecibos. PROVINCIA : = AFactura. PROVINCIA;
ARecibos. CODIGO_POSTAL : = AFactura. CODIGO_POSTAL;
ARecibos. FECHA_EMISION : = AFactura. FECHA_FACTURA;
if AFormaPago. Plazos. RecordCount < 1 then
begin
ARecibos. FECHA_VENCIMIENTO : = AFactura. FECHA_VENCIMIENTO;
2016-01-12 10:46:50 +00:00
ARecibos. IMPORTE : = AImporteTotal;
2014-06-18 11:06:58 +00:00
AImporteAcumulado : = AImporteAcumulado + ARecibos. IMPORTE;
2011-11-14 17:40:41 +00:00
end
else
begin
AFechaVencimiento : = AFactura. FECHA_FACTURA + AFormaPago. Plazos. NUM_DIAS;
ADiasMas : = 0 ;
BSemaforo : = False ;
if ( AFactura. Cliente. VENCIMIENTO_FACTURAS_1 < > 0 )
or ( AFactura. Cliente. VENCIMIENTO_FACTURAS_2 < > 0 )
or ( AFactura. Cliente. VENCIMIENTO_FACTURAS_3 < > 0 ) then
begin
ADiaVencimiento : = DayOf( AFechaVencimiento) ;
while ( ADiaVencimiento < > AFactura. Cliente. VENCIMIENTO_FACTURAS_1)
and ( ADiaVencimiento < > AFactura. Cliente. VENCIMIENTO_FACTURAS_2)
and ( ADiaVencimiento < > AFactura. Cliente. 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;
2014-06-18 11:06:58 +00:00
2016-01-12 10:46:50 +00:00
ARecibos. IMPORTE : = RoundCurrency( RoundCurrency( AImporteTotal) * ( AFormaPago. Plazos. PORCENTAJE / 1 0 0 ) ) ;
2014-06-18 11:06:58 +00:00
AImporteAcumulado : = AImporteAcumulado + ARecibos. IMPORTE;
if ( i = AFormaPago. Plazos. RecordCount) then
begin
2016-01-12 10:46:50 +00:00
if ( AImporteAcumulado < RoundCurrency( AImporteTotal) ) then
ARecibos. IMPORTE : = ARecibos. IMPORTE + ( RoundCurrency( AImporteTotal) - AImporteAcumulado)
else if ( AImporteAcumulado > RoundCurrency( AImporteTotal) ) then
ARecibos. IMPORTE : = ARecibos. IMPORTE - ( AImporteAcumulado - RoundCurrency( AImporteTotal) ) ;
2014-06-18 11:06:58 +00:00
end ;
2011-11-14 17:40:41 +00:00
end ;
2021-02-07 17:20:37 +00:00
ARecibos. DESCRIPCION : = 'RECIBO ' + ARecibos. REFERENCIA + ' - ' + ARecibos. NOMBRE; // CifraToLetras(ARecibos.IMPORTE);
2011-11-14 17:40:41 +00:00
ARecibosClienteController. Guardar( ARecibos) ;
end ;
Inc( i) ;
Next;
until ( eof) ;
end ;
2016-01-12 10:46:50 +00:00
//Si hay retenci<63> n generaremos un recibo para dicha retenci<63> n
if AFactura. IMPORTE_RETENCION > 0 then
begin
ARecibos : = ARecibosClienteController. Nuevo;
ARecibos. Edit;
ARecibos. ID_FACTURA : = AFactura. ID;
2019-01-22 15:09:00 +00:00
ARecibos. ID_EMPRESA : = AFactura. ID_EMPRESA;
ARecibos. ID_CLIENTE : = AFactura. ID_CLIENTE;
ARecibos. ID_TIENDA : = AFactura. ID_TIENDA;
2016-01-12 10:46:50 +00:00
ARecibos. REFERENCIA : = AFactura. REFERENCIA + ' - ' + IntToStr( i) ;
2019-01-22 15:09:00 +00:00
ARecibos. NOMBRE : = AFactura. NOMBRE; //Es la razon social de la factura
ARecibos. CALLE : = AFactura. CALLE;
ARecibos. NIF_CIF : = AFactura. NIF_CIF;
ARecibos. POBLACION : = AFactura. POBLACION;
ARecibos. PROVINCIA : = AFactura. PROVINCIA;
ARecibos. CODIGO_POSTAL : = AFactura. CODIGO_POSTAL;
2016-01-12 10:46:50 +00:00
ARecibos. FECHA_EMISION : = AFactura. FECHA_FACTURA;
ARecibos. FECHA_VENCIMIENTO : = AFactura. FECHA_RETENCION;
ARecibos. IMPORTE : = AFactura. IMPORTE_RETENCION;
2021-02-07 17:20:37 +00:00
ARecibos. DESCRIPCION : = 'Pago de factura de retenci<63> n ' + AFactura. REFERENCIA + ' - ' + ARecibos. NOMBRE; // CifraToLetras(ARecibos.IMPORTE);
2016-01-12 10:46:50 +00:00
ARecibosClienteController. Guardar( ARecibos) ;
end ;
2011-11-14 17:40:41 +00:00
//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 .