unit uGenerarFacturasCliFacProformaUtils; interface uses Windows, SysUtils, Classes, uBizFacturasProforma, uBizFacturasCliente, pngimage, JSDialog; type TdmGenerarFacturasCliFacProforma = class(TDataModule) JsListaFacturasGeneradas: TJSDialog; end; function GenerarFacturaCliFacProforma(const IDFacturaProforma : Integer; const CopiarDetalles: Boolean = True) : Boolean; overload; function GenerarFacturaCliFacProforma(AFacturaProforma : IBizFacturaProforma; FechaFacturaNueva:TDateTime; const CopiarDetalles: Boolean = True) : Boolean; overload; function GenerarFacturaCliFacProforma : Boolean; overload; //Siempre se hará una relación 1 a 1 entre facturas proforma y facturas function GenerarFacturas(AFacturas : IBizFacturaCliente; AFacturaProforma : IBizFacturaProforma; FechaFacturaNueva:TDateTime; const CopiarDetalles: Boolean = True): Boolean; implementation {$R *.dfm} uses DB, uDialogUtils, uDADataTable, uControllerDetallesBase, uEditorFechaFacturaFinal, uBizDetallesFacturaCliente, uBizDetallesFacturaProforma, uFacturasProformaController, uDetallesFacturaClienteController, uFacturasClienteController, schFacturasClienteClient_Intf, schFacturasProformaClient_Intf; var dmGenerarFacturasCliFacProforma: TdmGenerarFacturasCliFacProforma; AFacturasClienteController : IFacturasClienteController; AFacturasProformaController : IFacturasProformaController; ADetallesAlbaranesClienteController : IDetallesFacturaClienteController; procedure CopiarArticulosFacturaProforma(AOrigen: IBizDetallesFacturaProforma; ADestino : IBizDetallesFacturaCliente); var i : integer; ADetallesController : IDetallesFacturaClienteController; begin if not Assigned(AOrigen) then raise Exception.Create ('Origen no asignado (CopiarArticulosFacturaProforma)'); if not Assigned(ADestino) then raise Exception.Create ('Destino no asignado (CopiarArticulosFacturaProforma)'); 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; 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 dmGenerarFacturasCliFacProforma := TdmGenerarFacturasCliFacProforma.Create(nil); AFacturasClienteController := TFacturasClienteController.Create; AFacturasProformaController := TFacturasProformaController.Create; // ADetallesAlbaranesClienteController := TDetallesFacturaClienteController.Create; end; procedure Finalizar; begin FreeAndNIL(dmGenerarFacturasCliFacProforma); AFacturasClienteController := nil; AFacturasProformaController := nil; // ADetallesAlbaranesClienteController := nil; end; function GenerarFacturaCliFacProforma(const IDFacturaProforma : Integer; const CopiarDetalles: Boolean = True) : Boolean; overload; var AFacturaProforma : IBizFacturaProforma; AFechaFactura: TDateTime; begin Result := False; { try if not Assigned(AFacturasProformaController) then Inicializar; AFacturaProforma := AFacturasProformaController.Buscar(IDFacturaProforma); if Assigned(AFacturaProforma) then begin //Preguntamos la fecha que deseamos tengan la factura a generar with TfEditorFechaFacturaFinal.Create(Nil) do begin ShowModal; AFechaFactura := eFechaFactura.Date; Free; end; Result := GenerarFacturaCliFacProforma(AFacturaProforma, AFechaFactura); end; if Assigned(AFacturasProformaController) then Finalizar; finally AFacturaProforma := NIL; end; } end; function GenerarFacturaCliFacProforma(AFacturaProforma : IBizFacturaProforma; FechaFacturaNueva:TDateTime; const CopiarDetalles: Boolean = True) : Boolean; overload; var AFacturasNuevas : IBizFacturaCliente; i: Integer; begin Result := False; if not Assigned(AFacturaProforma) then raise Exception.Create('Factura proforma no asignada (GenerarFacturaCliFacProforma)'); if not AFacturaProforma.DataTable.Active then AFacturaProforma.DataTable.Active := True; if not Assigned(AFacturasProformaController) then Inicializar; try AFacturasNuevas := AFacturasClienteController.Nuevo(False); if GenerarFacturas(AFacturasNuevas, AFacturaProforma, FechaFacturaNueva, CopiarDetalles) then begin if AFacturasNuevas.DataTable.RecordCount = 1 then ShowInfoMessage('La factura se ha dado de alta con el código ' + AFacturasNuevas.REFERENCIA) else begin with dmGenerarFacturasCliFacProforma.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; dmGenerarFacturasCliFacProforma.JsListaFacturasGeneradas.Execute; end; Result := True; end; finally AFacturasNuevas := NIL; if Assigned(AFacturasProformaController) then Finalizar; end; end; function GenerarFacturaCliFacProforma : Boolean; overload; var AFacturasProforma : IBizFacturaProforma; AFechaFactura: TDateTime; begin Result := False; { try if not Assigned(AFacturasProformaController) then Inicializar; // AFacturasProforma := AFacturasProformaController.ElegirFacturasProforma(AFacturasProformaController.BuscarSinFacturar, // 'Elija la factura proforma que desea utilizar para dar de alta la factura.' , True); if Assigned(AFacturasProforma) then begin //Preguntamos la fecha que deseamos tengan las facturas a generar with TfEditorFechaFacturaFinal.Create(Nil) do begin ShowModal; AFechaFactura := eFechaFactura.Date; Free; end; Result := GenerarFacturaCliFacProforma(AFacturasProforma, AFechaFactura); end; if Assigned(AFacturasProformaController) then Finalizar; finally AFacturasProforma := Nil; end; } end; function GenerarFacturas(AFacturas : IBizFacturaCliente; AFacturaProforma : IBizFacturaProforma; FechaFacturaNueva:TDateTime; const CopiarDetalles: Boolean = True): Boolean; var AFacturaActual : IBizFacturaCliente; AFacturasProformaController : IFacturasProformaController; I: Integer; bEnEdicion : Boolean; begin { // ATENCIÓ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(AFacturaProforma) then raise Exception.Create ('FacturaProforma no asignada (Anadir)'); if not AFacturas.DataTable.Active then AFacturas.DataTable.Active := True; if not AFacturaProforma.DataTable.Active then AFacturaProforma.DataTable.Active := True; AFacturasProformaController := TFacturasProformaController.Create; try // Ordenar por fecha de albaran AFacturaProforma.DataTable.Sort([fld_FacturasProformaFECHA_FACTURA], [uDADataTable.sdAscending]); AFacturaProforma.First; for I := 0 to AFacturaProforma.DataTable.RecordCount - 1 do begin AFacturaProforma._Cliente := NIL; AFacturaActual := NIL; // Creo una factura nueva AFacturasClienteController.Anadir(AFacturas); //Asignamos a la factura la fecha pasada por parametro AFacturas.FECHA_FACTURA := FechaFacturaNueva; AFacturas.BASE_IMPONIBLE := AFacturaProforma.BASE_IMPONIBLE; AFacturas.DESCUENTO := AFacturaProforma.DESCUENTO; AFacturas.IMPORTE_DESCUENTO := AFacturaProforma.IMPORTE_DESCUENTO; AFacturas.IVA := AFacturaProforma.IVA; AFacturas.IMPORTE_IVA := AFacturaProforma.IMPORTE_IVA; AFacturas.RE := AFacturaProforma.RE; AFacturas.IMPORTE_RE := AFacturaProforma.IMPORTE_RE; AFacturas.IMPORTE_TOTAL := AFacturaProforma.IMPORTE_TOTAL; // AFacturas.OBSERVACIONES := AFacturaProforma.OBSERVACIONES; AFacturas.ID_CLIENTE := AFacturaProforma.ID_CLIENTE; AFacturas.NIF_CIF := AFacturaProforma.NIF_CIF; AFacturas.NOMBRE := AFacturaProforma.NOMBRE; AFacturas.ID_DIRECCION := AFacturaProforma.ID_DIRECCION; AFacturas.CALLE := AFacturaProforma.CALLE; AFacturas.POBLACION := AFacturaProforma.POBLACION; AFacturas.CODIGO_POSTAL := AFacturaProforma.CODIGO_POSTAL; AFacturas.ID_FORMA_PAGO := AFacturaProforma.ID_FORMA_PAGO; AFacturas.IMPORTE_NETO := AFacturaProforma.IMPORTE_NETO; AFacturas.IMPORTE_PORTE := AFacturaProforma.IMPORTE_PORTE; AFacturas.ID_TIPO_IVA := AFacturaProforma.ID_TIPO_IVA; AFacturas.RECARGO_EQUIVALENCIA := AFacturaProforma.RECARGO_EQUIVALENCIA; AFacturaActual := AFacturas; //Importante recuperamos el objeto cliente para que no nos falle el procesamiento de la factura AFacturasClienteController.RecuperarCliente(AFacturaActual); AFacturaActual.Cliente.DataTable.Active := True; // Ya tengo la factura. Le añado los conceptos de la factura proforma AFacturaActual.Detalles.DataTable.Last; //Se pone la referencia de la factura proforma y el total y nos olvidamos de los detalles if not CopiarDetalles then begin AFacturasClienteController.DetallesController.Add(AFacturaActual.Detalles, TIPO_DETALLE_CONCEPTO); with AFacturaActual.Detalles do begin Edit; CONCEPTO := 'Factura proforma ' + AFacturaProforma.REFERENCIA + ' - ' + DateToStr(AFacturaProforma.FECHA_FACTURA); CANTIDAD := 1; IMPORTE_UNIDAD := AFacturaProforma.IMPORTE_TOTAL; Post; end; end //Se copian los detalles de la factura proforma a la factura else // Añado el contenido de la factura proforma CopiarArticulosFacturaProforma(AFacturaProforma.Detalles, AFacturaActual.Detalles); // Guardo la factura que acabo de generar o editar AFacturaActual.CalcularImporteTotal; AFacturasClienteController.Guardar(AFacturaActual); // Asocio la factura con la factura proforma AFacturaProforma.Edit; AFacturaProforma.ID_FACTURA_FINAL := AFacturaActual.ID; AFacturaProforma.Post; AFacturasProformaController.Guardar(AFacturaProforma); AFacturaProforma.Next; end; Result := True; finally AFacturasProformaController := NIL; // HideHourglassCursor end; } end; end.