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 ...@@ -208,7 +208,7 @@ object FViewOrders: TFViewOrders
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
end end
object btnPDF: TWebButton object btnPDF: TWebButton
Left = 328 Left = 332
Top = 79 Top = 79
Width = 96 Width = 96
Height = 25 Height = 25
......
...@@ -83,6 +83,7 @@ type ...@@ -83,6 +83,7 @@ type
[async] procedure GetOrders(searchOptions: string); [async] procedure GetOrders(searchOptions: string);
[async] procedure getUser(); [async] procedure getUser();
procedure GeneratePDF(OrderID: string); procedure GeneratePDF(OrderID: string);
[async] procedure GenerateReportPDF;
var var
PageNumber: integer; PageNumber: integer;
PageSize: integer; PageSize: integer;
...@@ -109,33 +110,19 @@ uses ...@@ -109,33 +110,19 @@ uses
{$R *.dfm} {$R *.dfm}
procedure TFViewOrders.btnPDFClick(Sender: TObject); procedure TFViewOrders.btnPDFClick(Sender: TObject);
begin
GenerateReportPDF;
end;
[async] procedure TFViewOrders.GenerateReportPDF;
var var
SelectedOrderID: string; searchOptions: string;
PDFButton: TJSHTMLElement;
begin begin
PDFButton := TJSHTMLElement(document.getElementById('btngeneratepdf')); searchOptions := GenerateSearchOptions;
// Check if an order is selected // Call the server method to generate the PDF
if not xdwdsOrders.IsEmpty then await(XDataWebClient1.RawInvokeAsync('ILookupService.GenerateReportPDF', [searchOptions]));
begin ShowMessage('PDF Report Generated Successfully');
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;
end; end;
......
...@@ -47,7 +47,7 @@ object FData: TFData ...@@ -47,7 +47,7 @@ object FData: TFData
object DBAdvGrid1: TDBAdvGrid object DBAdvGrid1: TDBAdvGrid
Left = 6 Left = 6
Top = 84 Top = 84
Width = 632 Width = 689
Height = 154 Height = 154
ColCount = 11 ColCount = 11
DrawingStyle = gdsClassic DrawingStyle = gdsClassic
...@@ -628,7 +628,7 @@ object FData: TFData ...@@ -628,7 +628,7 @@ object FData: TFData
object DBAdvGrid2: TDBAdvGrid object DBAdvGrid2: TDBAdvGrid
Left = 6 Left = 6
Top = 237 Top = 237
Width = 631 Width = 985
Height = 199 Height = 199
ColCount = 20 ColCount = 20
DrawingStyle = gdsClassic DrawingStyle = gdsClassic
...@@ -1495,6 +1495,15 @@ object FData: TFData ...@@ -1495,6 +1495,15 @@ object FData: TFData
TabOrder = 10 TabOrder = 10
TextHint = 'Email Address' TextHint = 'Email Address'
end end
object btnPDF: TButton
Left = 330
Top = 38
Width = 75
Height = 25
Caption = 'Preview PDF'
TabOrder = 11
OnClick = btnPDFClick
end
object dsUsers: TDataSource object dsUsers: TDataSource
DataSet = uqUsers DataSet = uqUsers
Left = 482 Left = 482
......
...@@ -34,14 +34,15 @@ type ...@@ -34,14 +34,15 @@ type
edtFullName: TEdit; edtFullName: TEdit;
edtPhoneNumber: TEdit; edtPhoneNumber: TEdit;
edtEmailAddress: TEdit; edtEmailAddress: TEdit;
btnPDF: TButton;
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
procedure btnFindClick(Sender: TObject); procedure btnFindClick(Sender: TObject);
procedure btnPDFClick(Sender: TObject);
private private
{ Private declarations }
accountSID: string; accountSID: string;
authHeader: string; authHeader: string;
public public
{ Public declarations } function GetReportPDF(OrderID: string): string;
end; end;
var var
...@@ -51,7 +52,13 @@ implementation ...@@ -51,7 +52,13 @@ implementation
{$R *.dfm} {$R *.dfm}
uses KGOrders.Database, uLibrary; uses KGOrders.Database, uLibrary, rOrders;
procedure TFData.btnPDFClick(Sender: TObject);
begin
GetReportPDF('');
end;
procedure TFData.FormCreate(Sender: TObject); procedure TFData.FormCreate(Sender: TObject);
begin begin
...@@ -76,4 +83,30 @@ begin ...@@ -76,4 +83,30 @@ begin
end; 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. end.
...@@ -209,6 +209,8 @@ type ...@@ -209,6 +209,8 @@ type
[HttpGet] function GetOrder(orderInfo: string): TFullOrder; [HttpGet] function GetOrder(orderInfo: string): TFullOrder;
[HttpGet] function GetCustomers(): TCustomerList; [HttpGet] function GetCustomers(): TCustomerList;
[HttpGet] function GetCustomer(ID: string): TCustomerItem; [HttpGet] function GetCustomer(ID: string): TCustomerItem;
[HttpGet] procedure GenerateReportPDF(searchOptions: string);
function AddUser(userInfo: string): string; function AddUser(userInfo: string): string;
function AddItem(itemInfo: string): string; function AddItem(itemInfo: string): string;
...@@ -216,7 +218,6 @@ type ...@@ -216,7 +218,6 @@ type
function EditUser(const editOptions: string): string; function EditUser(const editOptions: string): string;
function AddCorrugatedOrder(orderInfo: string): TJSONObject; function AddCorrugatedOrder(orderInfo: string): TJSONObject;
function AddStatusSchedule(StatusType: string; order: TJSONObject; ORDER_ID: integer): string; function AddStatusSchedule(StatusType: string; order: TJSONObject; ORDER_ID: integer): string;
function GenerateOrderPDF(OrderID: string): string;
end; end;
implementation implementation
......
...@@ -12,7 +12,13 @@ uses ...@@ -12,7 +12,13 @@ uses
XData.Server.Module, XData.Server.Module,
XData.Service.Common, XData.Service.Common,
KGOrders.Database, Data.DB, frxClass, frxExportPDF, 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 type
...@@ -29,6 +35,8 @@ type ...@@ -29,6 +35,8 @@ type
function GetCustomer(ID: string): TCustomerItem; function GetCustomer(ID: string): TCustomerItem;
function EditUser(const editOptions: string): string; function EditUser(const editOptions: string): string;
function Search(phoneNum: string): TOrderList; function Search(phoneNum: string): TOrderList;
procedure GenerateReportPDF(searchOptions: string);
function BuildOrderQuery(searchOptions: string): string;
function AddUser(userInfo: string): string; function AddUser(userInfo: string): string;
function AddItem(itemInfo: string): string; function AddItem(itemInfo: string): string;
function DelUser(username: string): string; function DelUser(username: string): string;
...@@ -39,13 +47,11 @@ type ...@@ -39,13 +47,11 @@ type
function EditStatusSchedule(StatusType: string; order: TJSONObject; ORDER_ID: string): string; function EditStatusSchedule(StatusType: string; order: TJSONObject; ORDER_ID: string): string;
procedure AfterConstruction; override; procedure AfterConstruction; override;
procedure BeforeDestruction; override; procedure BeforeDestruction; override;
function GenerateOrderPDF(OrderID: string): string;
end; end;
implementation implementation
uses uses
System.SysUtils,
System.Generics.Collections, System.Generics.Collections,
XData.Sys.Exceptions, uLibrary; XData.Sys.Exceptions, uLibrary;
...@@ -157,6 +163,113 @@ begin ...@@ -157,6 +163,113 @@ begin
end; 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; function TLookupService.generateSelectSQL(filterType, startDate, endDate: string): string;
begin begin
...@@ -521,11 +634,9 @@ begin ...@@ -521,11 +634,9 @@ begin
result.general_special_instructions := ordersDB.UniQuery1.FieldByName('general_special_instructions').AsString result.general_special_instructions := ordersDB.UniQuery1.FieldByName('general_special_instructions').AsString
else else
//result.specialInstructions := ordersDB.UniQuery1.FieldByName('general_comments').AsString //result.specialInstructions := ordersDB.UniQuery1.FieldByName('general_comments').AsString
end; end;
function TLookupService.GetItems(searchOptions: string): TItemList; function TLookupService.GetItems(searchOptions: string): TItemList;
var var
params: TStringList; params: TStringList;
...@@ -990,37 +1101,6 @@ begin ...@@ -990,37 +1101,6 @@ begin
end; 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 initialization
RegisterServiceType(TLookupService); 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 ...@@ -20,7 +20,8 @@ uses
Auth.ServiceImpl in 'Source\Auth.ServiceImpl.pas', Auth.ServiceImpl in 'Source\Auth.ServiceImpl.pas',
Lookup.ServiceImpl in 'Source\Lookup.ServiceImpl.pas', Lookup.ServiceImpl in 'Source\Lookup.ServiceImpl.pas',
App.Server.Module in 'Source\App.Server.Module.pas' {AppServerModule: TDataModule}, 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 type
TMemoLogAppender = class( TInterfacedObject, ILogAppender ) TMemoLogAppender = class( TInterfacedObject, ILogAppender )
......
...@@ -164,6 +164,11 @@ ...@@ -164,6 +164,11 @@
<Form>FData</Form> <Form>FData</Form>
<FormType>dfm</FormType> <FormType>dfm</FormType>
</DCCReference> </DCCReference>
<DCCReference Include="Source\rOrders.pas">
<Form>rptOrders</Form>
<FormType>dfm</FormType>
<DesignClass>TDataModule</DesignClass>
</DCCReference>
<BuildConfiguration Include="Base"> <BuildConfiguration Include="Base">
<Key>Base</Key> <Key>Base</Key>
</BuildConfiguration> </BuildConfiguration>
......
[Settings] [Settings]
MemoLogLevel=5 MemoLogLevel=5
FileLogLevel=5 FileLogLevel=5
LogFileNum=28 LogFileNum=69
webClientVersion=1.0.0 webClientVersion=1.0.0
[Database] [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