354 lines
13 KiB
ObjectPascal
354 lines
13 KiB
ObjectPascal
unit uGenerarFacturasProvPedProvUtils;
|
|
|
|
interface
|
|
|
|
uses
|
|
Windows, SysUtils, Classes, uBizPedidosProveedor, uBizFacturasProveedor, pngimage, JSDialog;
|
|
|
|
type
|
|
TdmGenerarFacturasProv = class(TDataModule)
|
|
JsListaFacturasGeneradas: TJSDialog;
|
|
end;
|
|
|
|
function GenerarFacturaProv(const IDPedido : Integer) : Boolean; overload;
|
|
function GenerarFacturasProv : Boolean; overload;
|
|
function GenerarFacturasProv(APedidos : IBizPedidoProveedor) : Boolean; overload;
|
|
function GenerarFacturasdeListaPedidos(AFacturas: IBizFacturaProveedor; AListaPedidos: IBizPedidoProveedor): Boolean;
|
|
|
|
implementation
|
|
|
|
{$R *.dfm}
|
|
|
|
uses
|
|
uDialogUtils, uControllerDetallesBase, DB, uDADataTable, schFacturasProveedorClient_Intf,
|
|
uBizDetallesPedidoProveedor, schPedidosProveedorClient_Intf,
|
|
uPedidosProveedorController, uDetallesPedidoProveedorController,
|
|
uFacturasProveedorController, uBizDetallesFacturaProveedor;
|
|
|
|
var
|
|
dmGenerarFacturasProv: TdmGenerarFacturasProv;
|
|
APedidosProveedorController : IPedidosProveedorController;
|
|
ADetallesPedidosProveedorController : IDetallesPedidoProveedorController;
|
|
AFacturasProveedorController : IFacturasProveedorController;
|
|
|
|
{ Métodos auxiliares }
|
|
procedure CopiarPedidoAFactura(APedido: IBizPedidoProveedor; AFactura : IBizFacturaProveedor);
|
|
begin
|
|
if not Assigned(AFactura) then
|
|
raise Exception.Create ('Albarán no asignado (CopiarPedidoAAlbaran)');
|
|
|
|
if not Assigned(APedido) then
|
|
raise Exception.Create ('Pedido no asignado (CopiarPedidoAAlbaran)');
|
|
|
|
if not APedido.DataTable.Active then
|
|
APedido.DataTable.Active := True;
|
|
|
|
APedidosProveedorController.RecuperarProveedor(APedido);
|
|
if not APedido.Proveedor.DataTable.Active then
|
|
APedido.Proveedor.DataTable.active := true;
|
|
|
|
// La factura tiene que venir ya abierta y posicionado donde hay que copiar
|
|
AFactura.ID_PROVEEDOR := APedido.ID_PROVEEDOR;
|
|
AFactura.CALLE := APedido.CALLE;
|
|
AFactura.CODIGO_POSTAL := APedido.CODIGO_POSTAL;
|
|
AFactura.POBLACION := APedido.POBLACION;
|
|
AFactura.PROVINCIA := APedido.PROVINCIA;
|
|
AFactura.IMPORTE_NETO := APedido.IMPORTE_NETO;
|
|
AFactura.IMPORTE_PORTE := APedido.IMPORTE_PORTE;
|
|
AFactura.DESCUENTO := APedido.DESCUENTO;
|
|
AFactura.IMPORTE_DESCUENTO := APedido.IMPORTE_DESCUENTO;
|
|
AFactura.BASE_IMPONIBLE := APedido.BASE_IMPONIBLE;
|
|
AFactura.IVA := APedido.IVA;
|
|
AFactura.IMPORTE_IVA := APedido.IMPORTE_IVA;
|
|
AFactura.IMPORTE_TOTAL := APedido.IMPORTE_TOTAL;
|
|
AFactura.DataTable.FieldByName(fld_FacturasProveedorOBSERVACIONES).AsVariant := APedido.DataTable.FieldByName(fld_PedidosProveedorOBSERVACIONES).AsVariant;
|
|
AFactura.NIF_CIF := APedido.Proveedor.NIF_CIF;
|
|
AFactura.NOMBRE_COMERCIAL_PROVEEDOR := APedido.Proveedor.NOMBRE_COMERCIAL;
|
|
AFactura.ID_FORMA_PAGO := APedido.Proveedor.ID_FORMA_PAGO;
|
|
end;
|
|
|
|
procedure CopiarArticulosAFactura(APedido: IBizPedidoProveedor; AFactura: IBizFacturaProveedor);
|
|
var
|
|
i : integer;
|
|
ADetalles : IBizDetallesFacturaProveedor;
|
|
|
|
begin
|
|
if not Assigned(AFactura) then
|
|
raise Exception.Create ('Factura no asignada (CopiarArticulosAFactura)');
|
|
|
|
if not Assigned(APedido) then
|
|
raise Exception.Create ('Factura no asignada (CopiarArticulosAFactura)');
|
|
|
|
// La factura tiene que venir ya abierta y posicionada donde hay que copiar
|
|
|
|
ADetalles := AFactura.Detalles;
|
|
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
|
|
AFacturasProveedorController.DetallesController.BeginUpdate(ADetalles);
|
|
|
|
APedido.Detalles.DataTable.First;
|
|
for i := 0 to APedido.Detalles.DataTable.RecordCount - 1 do
|
|
begin
|
|
AFacturasProveedorController.DetallesController.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.IMPORTE_UNIDAD := APedido.Detalles.IMPORTE_UNIDAD;
|
|
ADetalles.DESCUENTO := APedido.Detalles.DESCUENTO;
|
|
ADetalles.IMPORTE_PORTE := APedido.Detalles.IMPORTE_PORTE;
|
|
ADetalles.CANTIDAD := APedido.Detalles.CANTIDAD;
|
|
ADetalles.IMPORTE_TOTAL := APedido.Detalles.IMPORTE_TOTAL;
|
|
ADetalles.REFERENCIA_PROVEEDOR := APedido.Detalles.REFERENCIA_PROVEEDOR;
|
|
ADetalles.Post;
|
|
APedido.Detalles.Next;
|
|
end;
|
|
|
|
finally
|
|
AFacturasProveedorController.DetallesController.EndUpdate(ADetalles);
|
|
// AFacturasProveedorController.DetallesController.ActualizarTotales(ADetalles);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
procedure Inicializar;
|
|
begin
|
|
dmGenerarFacturasProv := TdmGenerarFacturasProv.Create(nil);
|
|
APedidosProveedorController := TPedidosProveedorController.Create;
|
|
ADetallesPedidosProveedorController := TDetallesPedidoProveedorController.Create;
|
|
AFacturasProveedorController := TFacturasProveedorController.Create;
|
|
// AProveedoresController := TProveedoresController.Create;
|
|
end;
|
|
|
|
procedure Finalizar;
|
|
begin
|
|
FreeAndNIL(dmGenerarFacturasProv);
|
|
APedidosProveedorController := nil;
|
|
ADetallesPedidosProveedorController := nil;
|
|
AFacturasProveedorController := nil;
|
|
// AProveedoresController := nil;
|
|
end;
|
|
|
|
|
|
function GenerarFacturaProv(const IDPedido : Integer) : Boolean; overload;
|
|
var
|
|
APedido : IBizPedidoProveedor;
|
|
begin
|
|
Result := False;
|
|
if not Assigned(APedidosProveedorController) then
|
|
Inicializar;
|
|
|
|
APedido := APedidosProveedorController.Buscar(IDPedido);
|
|
Result := GenerarFacturasProv(APedido);
|
|
|
|
if Assigned(APedidosProveedorController) then
|
|
Finalizar;
|
|
end;
|
|
|
|
function GenerarFacturasProv : Boolean; overload;
|
|
var
|
|
APedidos : IBizPedidoProveedor;
|
|
begin
|
|
Result := False;
|
|
if not Assigned(APedidosProveedorController) then
|
|
Inicializar;
|
|
|
|
APedidos := APedidosProveedorController.ElegirPedidos(APedidosProveedorController.BuscarSinFacturar,
|
|
'Elija el pedido/s de proveedor que desea utilizar para dar de alta la factura.'
|
|
+ #10#13 + 'Si elige Pedidos de proveedores diferentes se dará de alta una factura por cada uno de ellos.' , True);
|
|
|
|
if Assigned(APedidos) then
|
|
Result := GenerarFacturasProv(APedidos);
|
|
|
|
if Assigned(APedidosProveedorController) then
|
|
Finalizar;
|
|
end;
|
|
|
|
function GenerarFacturasProv(APedidos : IBizPedidoProveedor) : Boolean; overload;
|
|
var
|
|
AFacturasNuevas : IBizFacturaProveedor;
|
|
i: Integer;
|
|
ARespuesta : Integer;
|
|
|
|
begin
|
|
Result := False;
|
|
|
|
if not Assigned(APedidosProveedorController) then
|
|
Inicializar;
|
|
|
|
if not Assigned(APedidos) then
|
|
raise Exception.Create('Pedidos de proveedor no asignado (GenerarFacturasProv)');
|
|
|
|
if not APedidos.DataTable.Active then
|
|
APedidos.DataTable.Active := True;
|
|
|
|
try
|
|
AFacturasNuevas := AFacturasProveedorController.Nuevo(False);
|
|
if GenerarFacturasdeListaPedidos(AFacturasNuevas, APedidos) then
|
|
begin
|
|
if AFacturasNuevas.DataTable.RecordCount = 1 then
|
|
begin
|
|
with dmGenerarFacturasProv.JsListaFacturasGeneradas do
|
|
begin
|
|
Content.Clear;
|
|
Content.Add(Format('Se ha generado correctamente la factura %s a partir del pedido de proveedor' + #10#13, [AFacturasNuevas.REFERENCIA]));
|
|
end;
|
|
end
|
|
else begin
|
|
dmGenerarFacturasProv.JsListaFacturasGeneradas.CustomButtons[1].Destroy;
|
|
with dmGenerarFacturasProv.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;
|
|
end;
|
|
|
|
dmGenerarFacturasProv.JsListaFacturasGeneradas.Execute;
|
|
ARespuesta := dmGenerarFacturasProv.JsListaFacturasGeneradas.CustomButtonResult;
|
|
case ARespuesta of
|
|
100 : begin
|
|
// Ver la factura
|
|
AFacturasProveedorController.Ver(AFacturasNuevas);
|
|
end;
|
|
200 : // Continuar;
|
|
end;
|
|
end;
|
|
|
|
finally
|
|
AFacturasNuevas := NIL;
|
|
end;
|
|
end;
|
|
|
|
function GenerarFacturasdeListaPedidos(AFacturas: IBizFacturaProveedor; AListaPedidos: IBizPedidoProveedor): Boolean;
|
|
var
|
|
AFacturaActual : IBizFacturaProveedor;
|
|
APedidosController : IPedidosProveedorController;
|
|
AArticulosPendientes : IBizDetallesPedidoProveedorPend;
|
|
I: Integer;
|
|
bEnEdicion : Boolean;
|
|
begin
|
|
Result := False;
|
|
|
|
// ATENCIÓN!!! AFacturas tiene que estar vacio para no pisar facturas
|
|
// ya generados.
|
|
if not Assigned(AFacturas) then
|
|
raise Exception.Create ('Facturas 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 pedido
|
|
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
|
|
AFacturaActual := AFacturas
|
|
else
|
|
begin
|
|
// No hay factura de ese proveedor. Creo una nueva
|
|
AFacturasProveedorController.Anadir(AFacturas);
|
|
AFacturaActual := AFacturas;
|
|
end;
|
|
|
|
//Asignamos el proveedor del pedido en la factura siempre
|
|
APedidosController.RecuperarProveedor(AListaPedidos);
|
|
AFacturaActual.Proveedor := AListaPedidos.Proveedor;
|
|
|
|
//Tanto si es nueva como ya existe añadimos la referencia del pedido a añadir
|
|
bEnEdicion := (AFacturaActual.DataTable.State in dsEditModes);
|
|
if not bEnEdicion then
|
|
AFacturaActual.Edit;
|
|
//Por cada pedido a añadir lo asignamos al campo manual de referencias de pedidos asociados REF_PEDIDOS_PROV
|
|
AFacturaActual.REF_PEDIDOS_PROV := AFacturaActual.REF_PEDIDOS_PROV + ' ' + AListaPedidos.REFERENCIA;
|
|
AFacturaActual.Post;
|
|
if bEnEdicion then
|
|
AFacturaActual.Edit;
|
|
|
|
|
|
AFacturaActual.Detalles.DataTable.Last;
|
|
// 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 pedido
|
|
CopiarArticulosAFactura(AListaPedidos, AFacturaActual);
|
|
|
|
{En los albaranes a proveedor el porte es a nivel del artículo
|
|
Self.DetallesController.Add(AFacturaActual.Detalles, TIPO_DETALLE_CONCEPTO);
|
|
with AFacturaActual.Detalles do
|
|
begin
|
|
Edit;
|
|
CONCEPTO := 'Porte del albarán';
|
|
CANTIDAD := 1;
|
|
IMPORTE_UNIDAD := AListaAlbaranes.IMPORTE_PORTE;
|
|
Post;
|
|
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;
|
|
|
|
// 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 el albaran que acabo de generar o editar
|
|
AFacturaActual.CalcularImporteTotal;
|
|
AFacturasProveedorController.Guardar(AFacturaActual);
|
|
// No se asocia la factura al pedido ya que un pedido, solo puede estar asociado a una factura y una factura puede tener asociados varios pedidos
|
|
//09/06/2025 ahora Stefy nos dice que puede venir un pedido en varias facturas diferentes por lo que no podemos asociar la factura al pedido
|
|
AListaPedidos.Edit;
|
|
AListaPedidos.ID_FACTURA := AFacturaActual.ID;
|
|
AListaPedidos.REF_FACTURA := AFacturaActual.REFERENCIA;
|
|
AListaPedidos.Post;
|
|
APedidosController.Guardar(AListaPedidos);
|
|
|
|
AListaPedidos.Next;
|
|
end;
|
|
Result := True;
|
|
finally
|
|
APedidosController := NIL;
|
|
end;
|
|
end;
|
|
|
|
end.
|