unit uRptFacturasCliente_Server; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, frxClass, frxDBSet, uDAScriptingProvider, uDADataTable, uDACDSDataTable, DB, uDAClasses, frxChart, frxGradient, frxChBox, frxCross, frxOLE, frxBarcode, frxRich, uDABINAdapter, uROTypes, uDAInterfaces, uDADataStreamer, IBCustomDataSet, IBQuery, IBDatabase, uDAMemDataTable, FactuGES_Intf, frxExportPDF; type TRptFacturasCliente = class(TDataModule) frxDBCabecera: TfrxDBDataset; frxDBDetalles: TfrxDBDataset; DataDictionary: TDADataDictionary; IBDatabase1: TIBDatabase; IBTransaction1: TIBTransaction; DataSource1: TDataSource; DataSource2: TDataSource; cabecera: TIBQuery; detalles: TIBQuery; DABINAdapter: TDABINAdapter; DADSCabecera: TDADataSource; DADSDetalles: TDADataSource; tbl_Detalles: TDAMemDataTable; tbl_Cabecera: TDAMemDataTable; frxCheckBoxObject1: TfrxCheckBoxObject; frxChartObject1: TfrxChartObject; frxGradientObject1: TfrxGradientObject; frxCrossObject1: TfrxCrossObject; frxOLEObject1: TfrxOLEObject; frxBarCodeObject1: TfrxBarCodeObject; frxRichObject1: TfrxRichObject; frxReport: TfrxReport; cabeceraID: TIntegerField; cabeceraID_EMPRESA: TIntegerField; cabeceraREFERENCIA: TIBStringField; cabeceraTIPO: TIBStringField; cabeceraFECHA_FACTURA: TDateField; cabeceraBASE_IMPONIBLE: TIBBCDField; cabeceraSITUACION: TIBStringField; cabeceraDESCUENTO: TFloatField; cabeceraIMPORTE_DESCUENTO: TIBBCDField; cabeceraIVA: TFloatField; cabeceraIMPORTE_IVA: TIBBCDField; cabeceraRE: TFloatField; cabeceraIMPORTE_RE: TIBBCDField; cabeceraIMPORTE_TOTAL: TIBBCDField; cabeceraOBSERVACIONES: TMemoField; cabeceraNIF_CIF: TIBStringField; cabeceraID_CLIENTE: TIntegerField; cabeceraNOMBRE: TIBStringField; cabeceraCALLE: TIBStringField; cabeceraPROVINCIA: TIBStringField; cabeceraPOBLACION: TIBStringField; cabeceraCODIGO_POSTAL: TIBStringField; cabeceraRECARGO_EQUIVALENCIA: TSmallintField; cabeceraIMPORTE_NETO: TIBBCDField; cabeceraIMPORTE_PORTE: TIBBCDField; cabeceraFORMA_PAGO: TIBStringField; detallesID: TIntegerField; detallesID_FACTURA: TIntegerField; detallesPOSICION: TIntegerField; detallesTIPO_DETALLE: TIBStringField; detallesCONCEPTO: TIBStringField; detallesCANTIDAD: TIntegerField; detallesIMPORTE_UNIDAD: TIBBCDField; detallesDESCUENTO: TFloatField; detallesIMPORTE_TOTAL: TIBBCDField; detallesVISIBLE: TSmallintField; detallesREFERENCIA: TIBStringField; frxDBVencimientos: TfrxDBDataset; DADSVencimientos: TDADataSource; tbl_Vencimientos: TDAMemDataTable; vencimientos: TIBQuery; DataSource3: TDataSource; cabeceraDATOS_BANCARIOS: TIBStringField; vencimientosFECHA_VENCIMIENTO: TDateField; vencimientosIMPORTE_TOTAL: TIBBCDField; frxPDFExport1: TfrxPDFExport; tbl_InformeListadoFacturas: TDAMemDataTable; DADSInformeListadoFacturas: TDADataSource; frxDBInformeListadoFacturas: TfrxDBDataset; frxDBInformeListadoFacturasPendientes: TfrxDBDataset; DADSInformeListadoFacturasPendientes: TDADataSource; tbl_InformeListadoFacturasPendientes: TDAMemDataTable; schReport: TDASchema; procedure DataModuleCreate(Sender: TObject); private FConnection: IDAConnection; //Genera cada una de las facturas a imprimir procedure _GenerarFactura(const ID: Integer; const VerSello: Boolean = True); function _GenerarInforme(ATabla: TDAMemDataTable; const TipoInforme: String; const IdEmpresa: Integer; const FechaInicio: Variant; const FechaFin: Variant; const FechaVenInicio: Variant; const FechaVenFin: Variant; const ListaIDClientes: TIntegerArray; const ImporteMinimo: Currency): Binary; public function GenerarFactura(const ListaID : TIntegerArray; const VerSello: Boolean = True): Binary; function GenerarFacturaEnPDF(const ListaID : TIntegerArray; const VerSello: Boolean = True): Binary; function GenerarInformeIVA(const IdEmpresa: Integer; const FechaInicio: Variant; const FechaFin: Variant; const ListaIDClientes: TIntegerArray; const Desglosado: Boolean; const ImporteMinimo: Currency): Binary; function GenerarInformeListadoFacturas(const IdEmpresa: Integer; const FechaInicio: Variant; const FechaFin: Variant; const FechaVenInicio: Variant; const FechaVenFin: Variant; const ListaIDClientes: TIntegerArray; const Desglosado: Boolean; const ImporteMinimo: Currency): Binary; function GenerarInformeListadoFacturasPendientes(const IdEmpresa: Integer; const FechaInicio: Variant; const FechaFin: Variant; const FechaVenInicio: Variant; const FechaVenFin: Variant; const ListaIDClientes: TIntegerArray; const Desglosado: Boolean; const ImporteMinimo: Currency): Binary; end; implementation {$R *.dfm} uses uSistemaFunc, uDataModuleServer, schFacturasClienteClient_Intf; const rptFacturaCliente = 'InfFacturaCliente.fr3'; rptInformeIVA = 'InformeIVAClientes.fr3'; rptInformeIVADesglosado = 'InformeIVAClientesDesglosado.fr3'; rptInformeListadoFacturasCliente = 'InformeListadoFacturasCliente.fr3'; rptInformeListadoFacturasClienteDesglosado = 'InformeListadoFacturasClienteDesglosado.fr3'; rptInformeListadoFactuasClientePendiente = 'InformeListadoFacturasClientePendientes.fr3'; rptInformeListadoFactuasClientePendienteDesglosado = 'InformeListadoFacturasClientePendientesDesglosado.fr3'; { Dataset names for schReport } // ds_InformeFacturasCliente = 'InformeFacturasCliente'; // ds_InformeFacturasCliente_Detalles = 'InformeFacturasCliente_Detalles'; // ds_InformeFacturasCliente_Vencimientos = 'InformeFacturasCliente_Vencimientos'; { TRptFacturasCliente } procedure TRptFacturasCliente.DataModuleCreate(Sender: TObject); begin schReport.ConnectionManager := dmServer.ConnectionManager; FConnection := dmServer.DarNuevaConexion; frxReport.EngineOptions.NewSilentMode := simReThrow; frxDBCabecera.DataSource := DADSCabecera; frxDBDetalles.DataSource := DADSDetalles; frxDBVencimientos.DataSource := DADSVencimientos; end; function TRptFacturasCliente.GenerarFactura(const ListaID: TIntegerArray; const VerSello: Boolean = True): Binary; var i: Integer; begin Result := Binary.Create; try //Vamos generando todos y cada una de las facturas recibidas for i := 0 to ListaID.Count - 1 do _GenerarFactura(ListaID.Items[i], VerSello); frxReport.PreviewPages.SaveToStream(Result); finally end; end; function TRptFacturasCliente.GenerarFacturaEnPDF(const ListaID: TIntegerArray; const VerSello: Boolean = True): Binary; var i: Integer; begin Result := Binary.Create; try //Vamos generando todos y cada una de las facturas recibidas for i := 0 to ListaID.Count - 1 do _GenerarFactura(ListaID.Items[i], VerSello); frxPDFExport1.Stream := Result; frxReport.Export(frxPDFExport1) finally end; end; function TRptFacturasCliente.GenerarInformeIVA(const IdEmpresa: Integer; const FechaInicio: Variant; const FechaFin: Variant; const ListaIDClientes: TIntegerArray; const Desglosado: Boolean; const ImporteMinimo: Currency): Binary; var ATipoInforme: String; begin //DESGLOSADO POR CLIENTE EN ESTE INFORME NO SE DESGLOSARÁ POR CLIENTE if Desglosado then ATipoInforme := rptInformeIVADesglosado else ATipoInforme := rptInformeIVA; Result := _GenerarInforme(tbl_InformeListadoFacturas, ATipoInforme, IdEmpresa, FechaInicio, FechaFin, Null, Null, ListaIDClientes, ImporteMinimo); end; function TRptFacturasCliente.GenerarInformeListadoFacturas(const IdEmpresa: Integer; const FechaInicio, FechaFin: Variant; const FechaVenInicio: Variant; const FechaVenFin: Variant; const ListaIDClientes: TIntegerArray; const Desglosado: Boolean; const ImporteMinimo: Currency): Binary; var ATipoInforme: String; begin //DESGLOSADO POR CLIENTE EN ESTE INFORME NO SE DESGLOSARÁ POR CLIENTE if Desglosado then ATipoInforme := rptInformeListadoFacturasClienteDesglosado else ATipoInforme := rptInformeListadoFacturasCliente; Result := _GenerarInforme(tbl_InformeListadoFacturas, ATipoInforme, IdEmpresa, FechaInicio, FechaFin, FechaVenInicio, FechaVenFin, ListaIDClientes, ImporteMinimo); end; function TRptFacturasCliente.GenerarInformeListadoFacturasPendientes( const IdEmpresa: Integer; const FechaInicio, FechaFin: Variant; const FechaVenInicio: Variant; const FechaVenFin: Variant; const ListaIDClientes: TIntegerArray; const Desglosado: Boolean; const ImporteMinimo: Currency): Binary; var Condicion: TDAWhereExpression; ATipoInforme: String; begin if tbl_InformeListadoFacturasPendientes.Active then tbl_InformeListadoFacturasPendientes.Active := False; // Filtrar el informe por situacion with tbl_InformeListadoFacturasPendientes.DynamicWhere do begin // (ID_EMPRESA >= ID) Condicion := NewBinaryExpression(NewField('', fld_FacturasClienteSITUACION), NewConstant('PAGADA', datString), dboNotEqual); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Expression, Condicion, dboAnd); end; //DESGLOSADO POR CLIENTE EN ESTE INFORME NO SE DESGLOSARÁ POR CLIENTE if Desglosado then ATipoInforme := rptInformeListadoFactuasClientePendienteDesglosado else ATipoInforme := rptInformeListadoFactuasClientePendiente; Result := _GenerarInforme(tbl_InformeListadoFacturasPendientes, ATipoInforme, IdEmpresa, FechaInicio, FechaFin, FechaVenInicio, FechaVenFin, ListaIDClientes, ImporteMinimo); end; procedure TRptFacturasCliente._GenerarFactura(const ID: Integer; const VerSello: Boolean = True); var AInforme: Variant; begin FConnection.BeginTransaction; //<--- Creo que no va a hacer falta. "PUES SI ES NECESARIO" try tbl_Cabecera.Active := False; tbl_Detalles.Active := False; tbl_Vencimientos.Active := False; tbl_Cabecera.ParamByName('ID').AsInteger := ID; tbl_Detalles.ParamByName('ID_FACTURA').AsInteger := ID; tbl_Vencimientos.ParamByName('ID_FACTURA').AsInteger := ID; tbl_Cabecera.Active := True; tbl_Detalles.Active := True; tbl_Vencimientos.Active := True; AInforme := DarRutaFichero(DarRutaInformes, rptFacturaCliente, tbl_Cabecera.FieldByName('ID_EMPRESA').AsString); if VarIsNull(AInforme) then raise Exception.Create (('Error Servidor: _GenerarFactura, no encuentra informe ' + rptFacturaCliente)); frxReport.LoadFromFile(AInforme, True); if VerSello then frxReport.Variables.Variables['VerSello'] := 1 else frxReport.Variables.Variables['VerSello'] := 0; frxReport.PrepareReport(False); finally FConnection.RollbackTransaction; //<--- Creo que no va a hacer falta. "PUES SI ES NECESARIO" end; end; function TRptFacturasCliente._GenerarInforme(ATabla: TDAMemDataTable; const TipoInforme: String; const IdEmpresa: Integer; const FechaInicio, FechaFin: Variant; const FechaVenInicio: Variant; const FechaVenFin: Variant; const ListaIDClientes: TIntegerArray; const ImporteMinimo: Currency): Binary; var Condicion: TDAWhereExpression; i: Integer; AInforme: Variant; begin Result := Binary.Create; FConnection.BeginTransaction; //<--- Creo que no va a hacer falta. "PUES SI ES NECESARIO" try if ATabla.Active then ATabla.Active := False; // Filtrar el informe por empresa with ATabla.DynamicWhere do begin // (ID_EMPRESA >= ID) Condicion := NewBinaryExpression(NewField('', fld_FacturasClienteID_EMPRESA), NewConstant(IdEmpresa, datInteger), dboEqual); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Expression, Condicion, dboAnd); end; // Filtrar el informe por fechas if not VarIsNull(FechaInicio) and not VarIsNull(FechaFin) then begin with ATabla.DynamicWhere do begin // (FECHA_INICIO between FECHA_FIN) Condicion := NewBinaryExpression(NewField('', fld_FacturasClienteFECHA_FACTURA), NewConstant(FechaInicio, datDateTime), dboGreaterOrEqual); Condicion := NewBinaryExpression(NewBinaryExpression(NewField('', fld_FacturasClienteFECHA_FACTURA), NewConstant(FechaFin, datDateTime), dboLessOrEqual), Condicion, dboAnd); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Expression, Condicion, dboAnd); end; end; // Filtrar el informe por fechas de vencimiento if not VarIsNull(FechaVenInicio) and not VarIsNull(FechaVenFin) then begin with ATabla.DynamicWhere do begin // (FECHA_VENCIMIENTO_INICIO between FECHA_VENCIMIENTO_FIN) Condicion := NewBinaryExpression(NewField('', fld_FacturasClienteFECHA_VENCIMIENTO), NewConstant(FechaVenInicio, datDateTime), dboGreaterOrEqual); Condicion := NewBinaryExpression(NewBinaryExpression(NewField('', fld_FacturasClienteFECHA_VENCIMIENTO), NewConstant(FechaVenFin, datDateTime), dboLessOrEqual), Condicion, dboAnd); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Expression, Condicion, dboAnd); end; end; // Filtrar el informe por cliente if Assigned(ListaIDClientes) then begin with ATabla.DynamicWhere do begin for i := 0 to ListaIDClientes.Count - 1 do begin // (ID_CLIENTE = ID) Condicion := NewBinaryExpression(NewField('', fld_FacturasClienteID_CLIENTE), NewConstant(ListaIDClientes.Items[i], datInteger), dboEqual); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Expression, Condicion, dboAnd); end; end; end; // Filtrar el informe por importe minimo if (ImporteMinimo > 0) then begin with ATabla.DynamicWhere do begin // (IMPORTE_TOTAL > ImporteMinimo) Condicion := NewBinaryExpression(NewField('', fld_FacturasClienteIMPORTE_TOTAL), NewConstant(ImporteMinimo, datCurrency), dboGreaterOrEqual); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Expression, Condicion, dboAnd); end; end; ATabla.Active := True; // showmessage(inttostr(ATabla.RecordCount)); AInforme := DarRutaFichero(DarRutaInformes, TipoInforme, IntToStr(IdEmpresa)); if VarIsNull(AInforme) then raise Exception.Create (('Error Servidor: _GenerarInforme, no encuentra informe ' + TipoInforme)); frxReport.LoadFromFile(AInforme, True); frxReport.Variables.Variables['FechaInicio'] := FechaInicio; frxReport.Variables.Variables['FechaFin'] := FechaFin; frxReport.PrepareReport(False); frxReport.PreviewPages.SaveToStream(Result); finally FConnection.RollbackTransaction; //<--- Creo que no va a hacer falta. "PUES SI ES NECESARIO" end; end; end.