2008-08-21 12:09:21 +00:00
unit uGenerarFacturasProvPedUtils;
interface
uses
Windows, SysUtils, Classes, uBizPedidosProveedor, uBizFacturasProveedor, pngimage, JSDialog;
type
TdmGenerarFacturasProvPed = class( TDataModule)
JsListaFacturasGeneradas: TJSDialog;
end ;
function GenerarFacturaProvPed( const IDPedido : Integer ; const CopiarDetalles: Boolean = True ) : Boolean ; overload ;
function GenerarFacturaProvPed( APedidos : IBizPedidoProveedor; const CopiarDetalles: Boolean = True ) : Boolean ; overload ;
function GenerarFacturaProvPed : Boolean ; overload ;
function GenerarFacturas( AFacturas : IBizFacturaProveedor; AListaPedidos : IBizPedidoProveedor; const CopiarDetalles: Boolean = True ) : Boolean ;
implementation
{$R *.dfm}
uses
uDialogUtils, uDADataTable,
uBizDetallesPedidoProveedor,
uPedidosProveedorController, uDetallesPedidoProveedorController,
uFacturasProveedorController, uControllerDetallesBase,
schPedidosProveedorClient_Intf, schFacturasProveedorClient_Intf,
uBizDetallesFacturaProveedor, uDetallesFacturaProveedorController;
// ,
// , uProveedoresController,
// ,
// , uBizContactos,
// schPedidosProveedorClient_Intf;
var
dmGenerarFacturasProvPed: TdmGenerarFacturasProvPed;
APedidosProveedorController : IPedidosProveedorController;
ADetallesPedidosProveedorController : IDetallesPedidoProveedorController;
AFacturasProveedorController : IFacturasProveedorController;
// AProveedoresController : IProveedoresController;
{ M<> todos auxiliares }
{ procedure CopiarPedidoAPedido( APedido: IBizPedidoCliente;
APedido : IBizFacturaProveedor) ;
begin
if not Assigned( APedido) then
raise Exception. Create ( 'Albar<61> n no asignado (CopiarPedidoAPedido)' ) ;
if not Assigned( APedido) then
raise Exception. Create ( 'Pedido no asignado (CopiarPedidoAPedido)' ) ;
if not APedido. DataTable. Active then
APedido. DataTable. Active : = True ;
// El albar<61> n tiene que venir ya abierto y posicionado donde hay que copiar
APedido. ID_CLIENTE : = APedido. ID_CLIENTE;
APedido. ID_PEDIDO : = APedido. ID;
APedido. CALLE : = APedido. CALLE;
APedido. CODIGO_POSTAL : = APedido. CODIGO_POSTAL;
APedido. POBLACION : = APedido. POBLACION;
APedido. PROVINCIA : = APedido. PROVINCIA;
APedido. PERSONA_CONTACTO : = APedido. PERSONA_CONTACTO;
APedido. TELEFONO : = APedido. TELEFONO;
APedido. IMPORTE_NETO : = APedido. IMPORTE_NETO;
APedido. IMPORTE_PORTE : = APedido. IMPORTE_PORTE;
APedido. DESCUENTO : = APedido. DESCUENTO;
APedido. IMPORTE_DESCUENTO : = APedido. IMPORTE_DESCUENTO;
APedido. BASE_IMPONIBLE : = APedido. BASE_IMPONIBLE;
APedido. IVA : = APedido. IVA;
APedido. IMPORTE_IVA : = APedido. IMPORTE_IVA;
APedido. IMPORTE_TOTAL : = APedido. IMPORTE_TOTAL;
APedido. DataTable. FieldByName( fld_PedidosClienteOBSERVACIONES) . AsVariant : = APedido. DataTable. FieldByName( fld_PedidosClienteOBSERVACIONES) . AsVariant;
APedido. ID_FORMA_PAGO : = APedido. ID_FORMA_PAGO;
end ;
procedure CopiarArticulosPendAPedido(
APedido: IBizPedidoCliente;
APedido: IBizFacturaProveedor;
AArticulosPendientes: IBizPedidoClienteArticulosPend) ;
var
i : integer ;
ADetalles : IBizDetallesFacturaProveedor;
ADetallesController : IDetallesFacturaProveedorController;
begin
if not Assigned( APedido) then
raise Exception. Create ( 'Albar<61> n no asignado (CopiarArticulosPendAPedido)' ) ;
if not Assigned( APedido) then
raise Exception. Create ( 'Pedido no asignado (CopiarArticulosPendAPedido)' ) ;
if not Assigned( AArticulosPendientes) then
raise Exception. Create ( 'Art<72> culos pendientes no asignado (CopiarArticulosPendAPedido)' ) ;
if not AArticulosPendientes. DataTable. Active then
AArticulosPendientes. DataTable. Active : = True ;
// El albar<61> n tiene que venir ya abierto y posicionado donde hay que copiar
ADetalles : = APedido. Detalles;
ADetallesController : = TDetallesFacturaProveedorController. Create;
try
//OJO IMPORTANTE
//Siempre que vayamos a trabajar con los detalles debemos hacer un beginupdate de los mismos y un endupdate para
//obligarle siempre a recalcular los detalles una sola vez
ADetallesController. BeginUpdate( ADetalles) ;
AArticulosPendientes. DataTable. First;
for i : = 0 to AArticulosPendientes. DataTable. RecordCount - 1 do
begin
APedido. Detalles. First;
if ( APedido. Detalles. Locate( 'ID_ARTICULO' , AArticulosPendientes. ID_ARTICULO, [ ] ) ) then
if ( AArticulosPendientes. CANTIDAD_PENDIENTE > 0 ) then
begin
ADetallesController. Add( ADetalles, TIPO_DETALLE_CONCEPTO) ;
ADetalles. Edit;
ADetalles. REFERENCIA : = APedido. Detalles. REFERENCIA;
ADetalles. ID_ARTICULO : = APedido. Detalles. ID_ARTICULO;
ADetalles. CONCEPTO : = APedido. Detalles. CONCEPTO;
ADetalles. CANTIDAD : = AArticulosPendientes. CANTIDAD_PENDIENTE;
ADetalles. IMPORTE_UNIDAD : = APedido. Detalles. IMPORTE_UNIDAD;
ADetalles. IMPORTE_TOTAL : = APedido. Detalles. IMPORTE_TOTAL;
ADetalles. DESCUENTO : = APedido. Detalles. DESCUENTO;
ADetalles. IMPORTE_PORTE : = APedido. Detalles. IMPORTE_PORTE;
ADetalles. VISIBLE : = APedido. Detalles. VISIBLE;
ADetalles. REFERENCIA_PROVEEDOR : = APedido. Detalles. REFERENCIA_PROVEEDOR;
ADetalles. Post;
AArticulosPendientes. Next;
end ;
end ;
finally
ADetallesController. EndUpdate( ADetalles) ;
ADetallesController : = NIL ;
end ;
end ; }
procedure CopiarArticulosPedido( AOrigen: IBizDetallesPedidoProveedor;
ADestino : IBizDetallesFacturaProveedor) ;
var
i : integer ;
ADetallesController : IDetallesFacturaProveedorController;
begin
if not Assigned( AOrigen) then
raise Exception. Create ( 'Origen no asignado (CopiarArticulosPedido)' ) ;
if not Assigned( ADestino) then
raise Exception. Create ( 'Destino no asignado (CopiarArticulosPedido)' ) ;
if not AOrigen. DataTable. Active then
AOrigen. DataTable. Active : = True ;
if not ADestino. DataTable. Active then
ADestino. DataTable. Active : = True ;
ADetallesController : = TDetallesFacturaProveedorController. Create;
try
//OJO IMPORTANTE
//Siempre que vayamos a trabajar con los detalles debemos hacer un beginupdate de los mismos y un endupdate para
//obligarle siempre a recalcular los detalles una sola vez
ADetallesController. BeginUpdate( ADestino) ;
AOrigen. DataTable. First;
for i : = 0 to AOrigen. DataTable. RecordCount - 1 do
begin
ADetallesController. Add( ADestino, TIPO_DETALLE_CONCEPTO) ;
ADestino. Edit;
ADestino. REFERENCIA : = AOrigen. REFERENCIA;
if AOrigen. ID_ARTICULO > 0 then
ADestino. ID_ARTICULO : = AOrigen. ID_ARTICULO;
ADestino. CONCEPTO : = AOrigen. CONCEPTO;
ADestino. CANTIDAD : = AOrigen. CANTIDAD;
ADestino. IMPORTE_UNIDAD : = AOrigen. IMPORTE_UNIDAD;
ADestino. IMPORTE_TOTAL : = AOrigen. IMPORTE_TOTAL;
ADestino. DESCUENTO : = AOrigen. DESCUENTO;
ADestino. IMPORTE_PORTE : = AOrigen. IMPORTE_PORTE;
ADestino. VISIBLE : = AOrigen. VISIBLE;
ADestino. REFERENCIA_PROVEEDOR : = AOrigen. REFERENCIA_PROVEEDOR;
ADestino. Post;
AOrigen. Next;
end ;
finally
ADetallesController. EndUpdate( ADestino) ;
ADetallesController : = NIL ;
end ;
end ;
procedure Inicializar;
begin
dmGenerarFacturasProvPed : = TdmGenerarFacturasProvPed. Create( nil ) ;
APedidosProveedorController : = TPedidosProveedorController. Create;
ADetallesPedidosProveedorController : = TDetallesPedidoProveedorController. Create;
AFacturasProveedorController : = TFacturasProveedorController. Create;
end ;
procedure Finalizar;
begin
FreeAndNIL( dmGenerarFacturasProvPed) ;
APedidosProveedorController : = nil ;
ADetallesPedidosProveedorController : = nil ;
AFacturasProveedorController : = nil ;
end ;
function GenerarFacturaProvPed( const IDPedido : Integer ; const CopiarDetalles: Boolean = True ) : Boolean ; overload ;
var
APedido : IBizPedidoProveedor;
begin
Result : = False ;
2008-08-21 15:19:52 +00:00
try
if not Assigned( APedidosProveedorController) then
Inicializar;
2008-08-21 12:09:21 +00:00
2008-08-21 15:19:52 +00:00
APedido : = APedidosProveedorController. Buscar( IDPedido) ;
if Assigned( APedido) then
Result : = GenerarFacturaProvPed( APedido, CopiarDetalles) ;
2008-08-21 12:09:21 +00:00
2008-08-21 15:19:52 +00:00
if Assigned( APedidosProveedorController) then
Finalizar;
finally
APedido : = Nil ;
end ;
2008-08-21 12:09:21 +00:00
end ;
function GenerarFacturaProvPed( APedidos : IBizPedidoProveedor; const CopiarDetalles: Boolean = True ) : Boolean ; overload ;
var
AFacturasNuevas : IBizFacturaProveedor;
i: Integer ;
begin
Result : = False ;
if not Assigned( APedidos) then
raise Exception. Create( 'Pedido de proveedor no asignado (GenerarFacturaProvPed)' ) ;
if not APedidos. DataTable. Active then
APedidos. DataTable. Active : = True ;
if not Assigned( APedidosProveedorController) then
Inicializar;
try
AFacturasNuevas : = AFacturasProveedorController. Nuevo( False ) ;
if GenerarFacturas( AFacturasNuevas, APedidos, CopiarDetalles) then
begin
if AFacturasNuevas. DataTable. RecordCount = 1 then
begin
if AFacturasNuevas. TIPO = CTE_TIPO_FACTURA then
ShowInfoMessage( 'La factura se ha dado de alta con el c<> digo ' + AFacturasNuevas. REFERENCIA)
else
ShowInfoMessage( 'El abono se ha dado de alta con el c<> digo ' + AFacturasNuevas. REFERENCIA) ;
end
else begin
with dmGenerarFacturasProvPed. JsListaFacturasGeneradas. Content do
begin
Clear;
AFacturasNuevas. DataTable. Last;
for i : = 0 to AFacturasNuevas. DataTable. RecordCount - 1 do
begin
if Length( AFacturasNuevas. REFERENCIA) > 0 then
Add( AFacturasNuevas. REFERENCIA + ': ' + AFacturasNuevas. NOMBRE) ;
AFacturasNuevas. DataTable. Prior;
end ;
end ;
dmGenerarFacturasProvPed. JsListaFacturasGeneradas. Execute;
end ;
Result : = True ;
end ;
finally
AFacturasNuevas : = NIL ;
if Assigned( APedidosProveedorController) then
Finalizar;
end ;
end ;
function GenerarFacturaProvPed : Boolean ; overload ;
var
APedidos : IBizPedidoProveedor;
begin
Result : = False ;
if not Assigned( APedidosProveedorController) then
Inicializar;
APedidos : = APedidosProveedorController. ElegirPedidos( APedidosProveedorController. BuscarSinFacturar,
'Elija el pedido o pedidos de proveedor que desea utilizar para dar de alta la factura.'
+ #10 #13 + 'Si elige Pedidos de proveedores diferentes se dar<61> de alta una factura por cada uno de ellos.' , True ) ;
2008-08-21 15:19:52 +00:00
if Assigned( APedidos) then
begin
if ( ShowConfirmMessage( 'Generar factura' , Format( '<27> Desea copiar todos los conceptos de/los pedido/s seleccionados a sus facturas correspondientes?' , [ ] ) ) = IDYES) then
Result : = GenerarFacturaProvPed( APedidos)
else
Result : = GenerarFacturaProvPed( APedidos, False ) ;
end ;
2008-08-21 12:09:21 +00:00
if Assigned( APedidosProveedorController) then
Finalizar;
end ;
function GenerarFacturas( AFacturas : IBizFacturaProveedor; AListaPedidos : IBizPedidoProveedor; const CopiarDetalles: Boolean = True ) : Boolean ;
var
AFacturaActual : IBizFacturaProveedor;
APedidosController : IPedidosProveedorController;
I: Integer ;
bEnEdicion : Boolean ;
begin
// ATENCI<43> N!!! AFacturas tiene que estar vacio para no pisar facturas
// ya generadas.
if not Assigned( AFacturas) then
raise Exception. Create ( 'Factura no asignado (Anadir)' ) ;
if not Assigned( AListaPedidos) then
raise Exception. Create ( 'Pedidos no asignados (Anadir)' ) ;
if not AFacturas. DataTable. Active then
AFacturas. DataTable. Active : = True ;
if not AListaPedidos. DataTable. Active then
AListaPedidos. DataTable. Active : = True ;
APedidosController : = TPedidosProveedorController. Create;
try
// Ordenar por fecha de albaran
AListaPedidos. DataTable. Sort( [ fld_PedidosProveedorFECHA_PEDIDO] , [ uDADataTable. sdAscending] ) ;
AListaPedidos. First;
for I : = 0 to AListaPedidos. DataTable. RecordCount - 1 do
begin
AListaPedidos. _Proveedor : = NIL ;
AFacturaActual : = NIL ;
// Busco si hay alguna factura ya hecha de ese Proveedor
AFacturas. DataTable. First;
if AFacturas. DataTable. Locate( fld_FacturasProveedorID_PROVEEDOR, AListaPedidos. ID_PROVEEDOR, [ ] ) then
begin
AFacturaActual : = AFacturas;
AFacturasProveedorController. RecuperarProveedor( AFacturaActual) ;
AFacturaActual. Proveedor. DataTable. Active : = True ;
end
else begin
// No hay factura de ese Proveedor. Creo una nueva
AFacturasProveedorController. Anadir( AFacturas) ;
APedidosController. RecuperarProveedor( AListaPedidos) ;
2008-08-21 15:19:52 +00:00
AListaPedidos. Proveedor. DataTable. Active : = True ;
2008-08-21 12:09:21 +00:00
AFacturas. Proveedor : = AListaPedidos. Proveedor;
AFacturaActual : = AFacturas;
end ;
// Ya tengo la factura. Le a<> ado los conceptos del pedido
AFacturaActual. Detalles. DataTable. Last;
//Se pone la referencia del pedido y el total y nos olvidamos de los detalles
if not CopiarDetalles then
begin
AFacturasProveedorController. DetallesController. Add( AFacturaActual. Detalles, TIPO_DETALLE_CONCEPTO) ;
with AFacturaActual. Detalles do
begin
Edit;
CONCEPTO : = 'Pedido ' + AListaPedidos. REFERENCIA;
CANTIDAD : = 1 ;
IMPORTE_UNIDAD : = AListaPedidos. IMPORTE_TOTAL; //Tecsitel no utiliza el IVA en los pedidos por lo tanto el
//importe total es lo que queremos (IMPORTE_NETO+IMPORTE_PORTE)
Post;
end ;
end
//Se copian los detalles del pedido a la factura
else
begin
// A<> ado el t<> tulo
AFacturasProveedorController. DetallesController. Add( AFacturaActual. Detalles, TIPO_DETALLE_TITULO) ;
with AFacturaActual. Detalles do
begin
Edit;
CONCEPTO : = 'Pedido ' + AListaPedidos. REFERENCIA + ' del ' + DateToStr( AListaPedidos. FECHA_PEDIDO) ;
Post;
end ;
// A<> ado el contenido del presupuesto
CopiarArticulosPedido( AListaPedidos. Detalles, AFacturaActual. Detalles) ;
//En el caso de tener porte el presupuesto se a<> ade una fila con el importe
if ( AListaPedidos. IMPORTE_PORTE > 0 ) then
begin
AFacturasProveedorController. DetallesController. Add( AFacturaActual. Detalles, TIPO_DETALLE_CONCEPTO) ;
with AFacturaActual. Detalles do
begin
Edit;
CONCEPTO : = 'Porte del pedido' ;
CANTIDAD : = 1 ;
IMPORTE_UNIDAD : = AListaPedidos. IMPORTE_PORTE;
Post;
end ;
end ;
//En el caso de tener descuento (bonificaci<63> n) el presupuesto se a<> ade una fila con el importe
{ if ( AListaPresupuestos. IMPORTE_DESCUENTO > 0 ) then
begin
AFacturasClienteController. DetallesController. Add( AFacturaActual. Detalles, TIPO_DETALLE_CONCEPTO) ;
with AFacturaActual. Detalles do
begin
Edit;
CONCEPTO : = 'Bonificaci<63> n ' + FloatToStr( AListaPresupuestos. DESCUENTO) + '%' ;
CANTIDAD : = - 1 ;
IMPORTE_UNIDAD : = AListaPresupuestos. IMPORTE_DESCUENTO;
Post;
end ;
end ;
}
// A<> ado el resumen
AFacturasProveedorController. DetallesController. Add( AFacturaActual. Detalles, TIPO_DETALLE_SUBTOTAL) ;
with AFacturaActual. Detalles do
begin
Edit;
CONCEPTO : = 'Total del pedido ' + AListaPedidos. REFERENCIA;
Post;
end ;
end ;
// A<> ado una l<> nea en blanco
AFacturasProveedorController. 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;
AFacturasProveedorController. Guardar( AFacturaActual) ;
// Asocio la factura con el presupuesto
AListaPedidos. Edit;
AListaPedidos. ID_FACTURA : = AFacturaActual. ID;
AListaPedidos. Post;
APedidosController. Guardar( AListaPedidos) ;
AListaPedidos. Next;
end ;
Result : = True ;
finally
APedidosController : = NIL ;
end ;
end ;
end .