Commit 0565250e by Mac Stephens

Working on adding fast report pdf

parent 1e7d3289
No preview for this file type
No preview for this file type
......@@ -208,7 +208,7 @@ object FViewOrders: TFViewOrders
WidthPercent = 100.000000000000000000
end
object btnPDF: TWebButton
Left = 328
Left = 332
Top = 79
Width = 96
Height = 25
......
......@@ -83,6 +83,7 @@ type
[async] procedure GetOrders(searchOptions: string);
[async] procedure getUser();
procedure GeneratePDF(OrderID: string);
[async] procedure GenerateReportPDF;
var
PageNumber: integer;
PageSize: integer;
......@@ -109,33 +110,19 @@ uses
{$R *.dfm}
procedure TFViewOrders.btnPDFClick(Sender: TObject);
begin
GenerateReportPDF;
end;
[async] procedure TFViewOrders.GenerateReportPDF;
var
SelectedOrderID: string;
PDFButton: TJSHTMLElement;
searchOptions: string;
begin
PDFButton := TJSHTMLElement(document.getElementById('btngeneratepdf'));
searchOptions := GenerateSearchOptions;
// Check if an order is selected
if not xdwdsOrders.IsEmpty then
begin
SelectedOrderID := xdwdsOrdersID.Value;
if SelectedOrderID <> '' then
begin
GeneratePDF(SelectedOrderID);
// Remove invalid state if it exists
PDFButton.classList.remove('is-invalid');
end
else
begin
// Add the 'is-invalid' class to trigger Bootstrap validation styling
PDFButton.classList.add('is-invalid');
end;
end
else
begin
// Add the 'is-invalid' class to trigger Bootstrap validation styling
PDFButton.classList.add('is-invalid');
end;
// Call the server method to generate the PDF
await(XDataWebClient1.RawInvokeAsync('ILookupService.GenerateReportPDF', [searchOptions]));
ShowMessage('PDF Report Generated Successfully');
end;
......
......@@ -47,7 +47,7 @@ object FData: TFData
object DBAdvGrid1: TDBAdvGrid
Left = 6
Top = 84
Width = 632
Width = 689
Height = 154
ColCount = 11
DrawingStyle = gdsClassic
......@@ -628,7 +628,7 @@ object FData: TFData
object DBAdvGrid2: TDBAdvGrid
Left = 6
Top = 237
Width = 631
Width = 985
Height = 199
ColCount = 20
DrawingStyle = gdsClassic
......@@ -1495,6 +1495,15 @@ object FData: TFData
TabOrder = 10
TextHint = 'Email Address'
end
object btnPDF: TButton
Left = 330
Top = 38
Width = 75
Height = 25
Caption = 'Preview PDF'
TabOrder = 11
OnClick = btnPDFClick
end
object dsUsers: TDataSource
DataSet = uqUsers
Left = 482
......
......@@ -34,14 +34,15 @@ type
edtFullName: TEdit;
edtPhoneNumber: TEdit;
edtEmailAddress: TEdit;
btnPDF: TButton;
procedure FormCreate(Sender: TObject);
procedure btnFindClick(Sender: TObject);
procedure btnPDFClick(Sender: TObject);
private
{ Private declarations }
accountSID: string;
authHeader: string;
public
{ Public declarations }
function GetReportPDF(OrderID: string): string;
end;
var
......@@ -51,7 +52,13 @@ implementation
{$R *.dfm}
uses KGOrders.Database, uLibrary;
uses KGOrders.Database, uLibrary, rOrders;
procedure TFData.btnPDFClick(Sender: TObject);
begin
GetReportPDF('');
end;
procedure TFData.FormCreate(Sender: TObject);
begin
......@@ -76,4 +83,30 @@ begin
end;
function TFData.GetReportPDF(OrderID: string): string;
var
rptOrders: TrptOrders; // Local instance
OrderIDList: TStringList;
begin
rptOrders := TrptOrders.Create(nil); // Always create locally
try
// Create a list of hardcoded OrderIDs for testing
OrderIDList := TStringList.Create;
try
OrderIDList.Add('18995');
OrderIDList.Add('18994');
OrderIDList.Add('18993'); // Add more OrderIDs as needed
// Generate the PDF Report with the list of OrderIDs
rptOrders.GenerateSimpleReport(350);
finally
OrderIDList.Free; // Free the TStringList
end;
finally
rptOrders.Free; // Ensure rptOrders is freed
end;
end;
end.
......@@ -209,6 +209,8 @@ type
[HttpGet] function GetOrder(orderInfo: string): TFullOrder;
[HttpGet] function GetCustomers(): TCustomerList;
[HttpGet] function GetCustomer(ID: string): TCustomerItem;
[HttpGet] procedure GenerateReportPDF(searchOptions: string);
function AddUser(userInfo: string): string;
function AddItem(itemInfo: string): string;
......@@ -216,7 +218,6 @@ type
function EditUser(const editOptions: string): string;
function AddCorrugatedOrder(orderInfo: string): TJSONObject;
function AddStatusSchedule(StatusType: string; order: TJSONObject; ORDER_ID: integer): string;
function GenerateOrderPDF(OrderID: string): string;
end;
implementation
......
......@@ -12,7 +12,13 @@ uses
XData.Server.Module,
XData.Service.Common,
KGOrders.Database, Data.DB, frxClass, frxExportPDF,
Lookup.Service, System.Hash, System.Classes, System.JSON;
Lookup.Service, System.Hash, System.JSON, Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, MemDS, DBAccess, Uni,
hyiedefs, hyieutils, iexBitmaps, iesettings, iexLayers, iexRulers,
iexToolbars, iexUserInteractions, imageenio, imageenproc, QuickRpt, QRCtrls,
dbimageen, Vcl.ExtCtrls, ieview, imageenview, IdBaseComponent, IdComponent,
IdTCPConnection, IdTCPClient, IdExplicitTLSClientServerBase, IdFTP,
iexProcEffects, frxDBSet, frxExportBaseDialog, frCoreClasses, rOrders, Common.Logging;
type
......@@ -29,6 +35,8 @@ type
function GetCustomer(ID: string): TCustomerItem;
function EditUser(const editOptions: string): string;
function Search(phoneNum: string): TOrderList;
procedure GenerateReportPDF(searchOptions: string);
function BuildOrderQuery(searchOptions: string): string;
function AddUser(userInfo: string): string;
function AddItem(itemInfo: string): string;
function DelUser(username: string): string;
......@@ -39,13 +47,11 @@ type
function EditStatusSchedule(StatusType: string; order: TJSONObject; ORDER_ID: string): string;
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
function GenerateOrderPDF(OrderID: string): string;
end;
implementation
uses
System.SysUtils,
System.Generics.Collections,
XData.Sys.Exceptions, uLibrary;
......@@ -157,6 +163,113 @@ begin
end;
procedure TLookupService.GenerateReportPDF(searchOptions: string);
var
SQL: string;
rptOrders: TrptOrders; // Local instance of rptOrders
begin
// Create instance of rptOrders
rptOrders := TrptOrders.Create(nil);
try
// Generate SQL dynamically using the existing GetOrders logic
SQL := BuildOrderQuery(searchOptions);
// Prepare the report dataset
rptOrders.PrepareReport(SQL);
// Generate the PDF report
rptOrders.GeneratePDF;
// Optionally, log success
Logger.log(5, 'PDF Report successfully generated for searchOptions: ' + searchOptions);
finally
rptOrders.Free; // Ensure proper cleanup
end;
end;
function TLookupService.BuildOrderQuery(searchOptions: string): string;
var
params: TStringList;
PageNum, PageSize: integer;
startDate, endDate, filterType, statusType, statusSuffix: string;
statusTableShort, statusTableLong, whereSQL, SQL: string;
begin
params := TStringList.Create;
try
params.StrictDelimiter := true;
params.Delimiter := '&';
params.DelimitedText := searchOptions;
// Parse parameters
PageNum := StrToIntDef(params.Values['pagenumber'], 1);
PageSize := StrToIntDef(params.Values['pagesize'], 50);
startDate := params.Values['startDate'];
endDate := params.Values['endDate'];
filterType := params.Values['filterType'];
statusType := '';
statusSuffix := '';
if filterType <> '' then
begin
statusType := filterType.Split(['_'])[0];
statusSuffix := filterType.Split(['_'])[1];
filterType := statusType + '_' + statusSuffix;
end;
// Determine status table
if statusSuffix = 'DUE' then
begin
statusTableShort := 'oss';
statusTableLong := 'orders_status_schedule';
end
else
begin
statusTableShort := 'os';
statusTableLong := 'orders_status';
end;
// Build the SELECT query with dynamically generated subqueries
SQL := 'SELECT o.ORDER_ID, c.NAME AS COMPANY_NAME, o.JOB_NAME, o.ORDER_DATE, o.ORDER_TYPE, ';
// Add dynamically generated subqueries
SQL := SQL + generateSubQuery(filterType, statusType, 'PROOF');
SQL := SQL + generateSubQuery(filterType, statusType, 'ART');
SQL := SQL + generateSubQuery(filterType, statusType, 'PLATE');
SQL := SQL + generateSubQuery(filterType, statusType, 'MOUNT');
SQL := SQL + generateSubQuery(filterType, statusType, 'SHIP');
// Include additional static fields
SQL := SQL + 'o.PRICE, qb.QB_REF_NUM ';
// FROM clause
SQL := SQL + 'FROM orders o ' +
'JOIN customers c ON o.COMPANY_ID = c.CUSTOMER_ID ' +
'LEFT JOIN qb_sales_orders qb ON qb.ORDER_ID = o.ORDER_ID ';
// WHERE clause
whereSQL := 'WHERE 1=1 ';
if startDate <> '' then
whereSQL := whereSQL + ' AND o.ORDER_DATE >= ' + QuotedStr(startDate);
if endDate <> '' then
whereSQL := whereSQL + ' AND o.ORDER_DATE <= ' + QuotedStr(endDate);
if statusType <> '' then
whereSQL := whereSQL + ' AND ' + statusTableShort + '.ORDER_STATUS = ' + QuotedStr(statusType);
// Add WHERE and ORDER clauses
SQL := SQL + whereSQL +
' ORDER BY o.ORDER_DATE DESC ' +
' LIMIT ' + IntToStr(PageSize) +
' OFFSET ' + IntToStr((PageNum - 1) * PageSize);
Result := SQL;
Logger.log(5, 'Generated SQL in Build order Query: ' + SQL);
finally
params.Free;
end;
end;
function TLookupService.generateSelectSQL(filterType, startDate, endDate: string): string;
begin
......@@ -521,11 +634,9 @@ begin
result.general_special_instructions := ordersDB.UniQuery1.FieldByName('general_special_instructions').AsString
else
//result.specialInstructions := ordersDB.UniQuery1.FieldByName('general_comments').AsString
end;
function TLookupService.GetItems(searchOptions: string): TItemList;
var
params: TStringList;
......@@ -990,37 +1101,6 @@ begin
end;
function TLookupService.GenerateOrderPDF(OrderID: string): string;
var
ReportFileName: string;
Stream: TMemoryStream;
Base64PDF: string;
begin
// try
// // Create an instance of the rptOrders DataModule
// rptOrders := TrptOrders.Create(nil);
// Stream := TMemoryStream.Create;
//
// // Prepare the report using the rptOrders DataModule
// rptOrders.PrepareReport(OrderID);
//
// // Export the report to a PDF file in memory
// rptOrders.frxReport.Export(rptOrders.frxReport.FindComponent('frxPDFExport') as TfrxPDFExport, Stream);
//
// // Optionally save PDF to a file (optional)
// ReportFileName := TPath.Combine('C:\Reports\', 'Order_' + OrderID + '.pdf');
// Stream.SaveToFile(ReportFileName);
//
// // Convert to Base64 if you want to send it back as a string
// Stream.Position := 0;
// Base64PDF := TNetEncoding.Base64.EncodeBytesToString(Stream.Memory, Stream.Size);
// Result := Base64PDF;
// finally
// rptOrders.Free;
// Stream.Free;
// end;
end;
initialization
RegisterServiceType(TLookupService);
......
unit rOrders;
interface
uses
System.SysUtils, System.Classes, frxClass, frxExportBaseDialog, frxExportPDF,
Data.DB, DBAccess, Uni, UniProvider, MySQLUniProvider, System.IniFiles, Vcl.Forms,
MemDS, frxDBSet, frxTableObject, frCoreClasses, Common.Logging, System.IOUtils;
type
TrptOrders = class(TDataModule)
frxOrders: TfrxReport;
frxPDFExport1: TfrxPDFExport;
ucKG: TUniConnection;
uqOrders: TUniQuery;
frxReportTableObject1: TfrxReportTableObject;
frxDBOrders: TfrxDBDataset;
procedure DataModuleCreate(Sender: TObject);
private
public
procedure GenerateSimpleReport(OrderID: Integer);
procedure PrepareReport(const SQL: string);
procedure GeneratePDF;
end;
var
rptOrders: TrptOrders;
implementation
{%CLASSGROUP 'Vcl.Controls.TControl'}
{$R *.dfm}
procedure TrptOrders.DataModuleCreate(Sender: TObject);
var
iniFile: TIniFile;
begin
// Load database connection settings from INI file
iniFile := TIniFile.Create(ExtractFilePath(Application.ExeName) + 'kgOrdersServer.ini');
try
ucKG.Server := iniFile.ReadString('Database', 'Server', '');
ucKG.Connect;
finally
iniFile.Free;
end;
end;
procedure TrptOrders.GenerateSimpleReport(OrderID: Integer);
begin
try
Logger.Log(5, 'Generating Report for Order ID: ' + OrderID.ToString);
uqOrders.Close;
uqOrders.SQL.Text := 'SELECT ORDER_ID FROM corrugated_plate_orders WHERE ORDER_ID = :OrderID';
uqOrders.ParamByName('OrderID').AsInteger := OrderID;
try
uqOrders.Open;
except
on E: Exception do
begin
Logger.Log(1, 'Error executing query: ' + E.Message);
Exit;
end;
end;
frxOrders.PrepareReport;
frxOrders.ShowReport;
finally
uqOrders.Close;
frxOrders.Clear;
Logger.Log(5, 'Report generation complete for Order ID: ' + OrderID.ToString);
end;
end;
procedure TrptOrders.PrepareReport(const SQL: string);
begin
// Prepare and load data into the query
uqOrders.Close;
uqOrders.SQL.Text := SQL;
uqOrders.Open;
end;
procedure TrptOrders.GeneratePDF;
var
ReportDir, ReportFileName: string;
begin
ReportDir := 'C:\Projects\KGOrders\Reports';
// Define output file
ReportFileName := TPath.Combine(ReportDir, 'OrderReport_' + FormatDateTime('yyyymmdd_hhnnss', Now) + '.pdf');
// Prepare and export the report
frxOrders.PrepareReport;
frxPDFExport1.FileName := ReportFileName;
frxPDFExport1.ShowDialog := False;
frxOrders.Export(frxPDFExport1);
frxOrders.ShowPreparedReport;
Logger.Log(5, 'PDF saved to: ' + ReportFileName);
end;
end.
......@@ -20,7 +20,8 @@ uses
Auth.ServiceImpl in 'Source\Auth.ServiceImpl.pas',
Lookup.ServiceImpl in 'Source\Lookup.ServiceImpl.pas',
App.Server.Module in 'Source\App.Server.Module.pas' {AppServerModule: TDataModule},
Data in 'Source\Data.pas' {FData};
Data in 'Source\Data.pas' {FData},
rOrders in 'Source\rOrders.pas' {rptOrders: TDataModule};
type
TMemoLogAppender = class( TInterfacedObject, ILogAppender )
......
......@@ -164,6 +164,11 @@
<Form>FData</Form>
<FormType>dfm</FormType>
</DCCReference>
<DCCReference Include="Source\rOrders.pas">
<Form>rptOrders</Form>
<FormType>dfm</FormType>
<DesignClass>TDataModule</DesignClass>
</DCCReference>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
......
[Settings]
MemoLogLevel=5
FileLogLevel=5
LogFileNum=28
LogFileNum=69
webClientVersion=1.0.0
[Database]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment