unit DelphiTestFile;
interface
uses
System.SysUtils, System.Classes, System.Generics.Collections,
System.DateUtils, System.Math, System.StrUtils, System.IOUtils,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
Vcl.ExtCtrls, Vcl.ComCtrls, Vcl.Menus, Vcl.ToolWin, Vcl.ActnList,
Vcl.ImgList, Vcl.Grids, Vcl.DBGrids, Vcl.DBCtrls, Vcl.Mask,
Data.DB, Data.Win.ADODB, FireDAC.Stan.Intf, FireDAC.Stan.Option,
FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf, FireDAC.Stan.Def,
FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys, FireDAC.Phys.MSAcc,
FireDAC.Phys.MSAccDef, FireDAC.VCLUI.Wait, FireDAC.Stan.Param,
FireDAC.DatS, FireDAC.DApt.Intf, FireDAC.DApt, FireDAC.Comp.DataSet,
FireDAC.Comp.Client;
type
TUserRole = (urGuest, urUser, urAdmin, urSupervisor);
TAccessLevel = (alNone = 0, alRead = 1, alWrite = 2, alFull = 3);
TStatusCode = 100..599;
TCustomerID = type Integer;
TPercentage = 0..100;
TFileName = type string;
TEmailAddress = type string;
TPerson = record
FirstName: string;
LastName: string;
BirthDate: TDateTime;
Age: Integer;
Email: TEmailAddress;
Active: Boolean;
Role: TUserRole;
AccessLevel: TAccessLevel;
end;
TAddress = record
Street: string;
City: string;
State: string;
ZipCode: string;
Country: string;
procedure Clear;
function FullAddress: string;
end;
TCustomer = class(TObject)
private
FID: TCustomerID;
FName: string;
FEmail: string;
FPhone: string;
FAddress: TAddress;
FBalance: Currency;
FCreated: TDateTime;
FModified: TDateTime;
FActive: Boolean;
FDiscount: TPercentage;
FTags: TStringList;
procedure SetBalance(const Value: Currency);
procedure SetEmail(const Value: string);
function GetFullName: string;
protected
procedure DoModify; virtual;
function ValidateEmail(const Email: string): Boolean;
public
constructor Create;
destructor Destroy; override;
procedure Assign(Source: TCustomer); virtual;
function Clone: TCustomer;
procedure LoadFromDataset(Dataset: TDataSet);
procedure SaveToDataset(Dataset: TDataSet);
function CalculateDiscount(Amount: Currency): Currency;
class function GetCustomerByID(ID: TCustomerID): TCustomer; static;
property ID: TCustomerID read FID write FID;
property Name: string read FName write FName;
property Email: string read FEmail write SetEmail;
property Phone: string read FPhone write FPhone;
property Address: TAddress read FAddress write FAddress;
property Balance: Currency read FBalance write SetBalance;
property Created: TDateTime read FCreated write FCreated;
property Modified: TDateTime read FModified;
property Active: Boolean read FActive write FActive;
property Discount: TPercentage read FDiscount write FDiscount;
property FullName: string read GetFullName;
property Tags: TStringList read FTags;
end;
TGenericList<T> = class(TObject)
private
FItems: array of T;
FCount: Integer;
FCapacity: Integer;
procedure Grow;
function GetItem(Index: Integer): T;
procedure SetItem(Index: Integer; const Value: T);
public
constructor Create;
destructor Destroy; override;
procedure Add(const Item: T);
procedure Insert(Index: Integer; const Item: T);
procedure Delete(Index: Integer);
function Remove(const Item: T): Integer;
function IndexOf(const Item: T): Integer;
procedure Clear;
procedure Sort(Compare: TComparer<T>); overload;
procedure Sort; overload;
property Count: Integer read FCount;
property Items[Index: Integer]: T read GetItem write SetItem; default;
property Capacity: Integer read FCapacity write FCapacity;
end;
ICustomerService = interface(IInterface)
['{B8F4D4E0-7A3C-4B9E-9F2D-1A5C7E9B8D3F}']
function GetCustomer(ID: TCustomerID): TCustomer;
procedure SaveCustomer(Customer: TCustomer);
procedure DeleteCustomer(ID: TCustomerID);
function GetAllCustomers: TArray<TCustomer>;
function FindCustomers(const Filter: string): TArray<TCustomer>;
function GetCustomerCount: Integer;
end;
TCustomerService = class(TInterfacedObject, ICustomerService)
private
FConnection: TFDConnection;
FQuery: TFDQuery;
procedure PrepareConnection;
procedure ValidateCustomer(Customer: TCustomer);
public
constructor Create;
destructor Destroy; override;
function GetCustomer(ID: TCustomerID): TCustomer;
procedure SaveCustomer(Customer: TCustomer);
procedure DeleteCustomer(ID: TCustomerID);
function GetAllCustomers: TArray<TCustomer>;
function FindCustomers(const Filter: string): TArray<TCustomer>;
function GetCustomerCount: Integer;
end;
TMathHelper = class
private
class var FPI: Double;
class var FEpsilon: Double;
class constructor Create;
public
class function Factorial(N: Integer): Int64;
class function Power(Base, Exponent: Double): Double;
class function IsPrime(Number: Integer): Boolean;
class function Fibonacci(N: Integer): Int64;
class function GCD(A, B: Integer): Integer;
class function LCM(A, B: Integer): Integer;
class property PI: Double read FPI;
class property Epsilon: Double read FEpsilon;
end;
TMainForm = class(TForm)
MainMenu: TMainMenu;
StatusBar: TStatusBar;
ToolBar: TToolBar;
ActionList: TActionList;
ImageList: TImageList;
PageControl: TPageControl;
CustomerTab: TTabSheet;
ReportTab: TTabSheet;
CustomerGrid: TDBGrid;
CustomerNavigator: TDBNavigator;
FilterEdit: TEdit;
FilterLabel: TLabel;
SearchButton: TButton;
ClearButton: TButton;
ExportButton: TButton;
PrintButton: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure SearchButtonClick(Sender: TObject);
procedure ClearButtonClick(Sender: TObject);
procedure ExportButtonClick(Sender: TObject);
procedure PrintButtonClick(Sender: TObject);
procedure FilterEditChange(Sender: TObject);
private
FCustomerService: ICustomerService;
FCurrentCustomer: TCustomer;
FFilterText: string;
procedure InitializeComponents;
procedure SetupDatabase;
procedure LoadCustomers;
procedure UpdateStatusBar;
procedure ShowCustomerDetails(Customer: TCustomer);
function ValidateForm: Boolean;
protected
procedure DoShow; override;
procedure DoHide; override;
public
property CustomerService: ICustomerService read FCustomerService;
property CurrentCustomer: TCustomer read FCurrentCustomer;
end;
TBackgroundWorker = class(TThread)
private
FProgress: Integer;
FMessage: string;
FOnProgress: TNotifyEvent;
FOnMessage: TNotifyEvent;
procedure SetProgress(Value: Integer);
procedure SetMessage(const Value: string);
protected
procedure Execute; override;
procedure DoProgress;
procedure DoMessage;
public
constructor Create(CreateSuspended: Boolean);
property Progress: Integer read FProgress write SetProgress;
property Message: string read FMessage write SetMessage;
property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;
property OnMessage: TNotifyEvent read FOnMessage write FOnMessage;
end;
ECustomerException = class(Exception)
private
FErrorCode: Integer;
FCustomerID: TCustomerID;
public
constructor Create(const Msg: string; ErrorCode: Integer; CustomerID: TCustomerID);
property ErrorCode: Integer read FErrorCode;
property CustomerID: TCustomerID read FCustomerID;
end;
TCharSet = set of Char;
TIntSet = set of 1..100;
TDaySet = set of (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);
TIntArray = array of Integer;
TMatrix = array of array of Double;
TCustomerArray = array of TCustomer;
TFixedArray = array[1..10] of string;
TMultiDimArray = array[1..5, 1..10] of Integer;
PInteger = ^Integer;
PCustomer = ^TCustomer;
PPerson = ^TPerson;
TNotifyInt = procedure(Value: Integer) of object;
TCompareFunc = function(const A, B: string): Integer;
TMathOperation = function(X, Y: Double): Double;
TFilterFunc<T> = function(const Item: T): Boolean;
const
APP_NAME = 'Delphi Test Application';
VERSION = '1.0.0';
MAX_CUSTOMERS = 10000;
DEFAULT_DISCOUNT = 0.05;
COMPANY_NAME = 'Test Company Inc.';
COPYRIGHT_YEAR = 2024;
PI_VALUE = 3.141592653589793;
E_VALUE = 2.718281828459045;
resourcestring
SWelcomeMessage = 'Welcome to %s version %s';
SErrorLoadingData = 'Error loading data: %s';
SConfirmDelete = 'Are you sure you want to delete this customer?';
SFileNotFound = 'File "%s" not found';
SInvalidEmail = 'Invalid email address: %s';
SSuccessMessage = 'Operation completed successfully';
var
GlobalCustomerList: TGenericList<TCustomer>;
GlobalSettings: TStringList;
ApplicationPath: string;
IsInitialized: Boolean = False;
implementation
procedure TAddress.Clear;
begin
Street := '';
City := '';
State := '';
ZipCode := '';
Country := '';
end;
function TAddress.FullAddress: string;
begin
Result := Format('%s, %s, %s %s, %s', [Street, City, State, ZipCode, Country]);
end;
constructor TCustomer.Create;
begin
inherited;
FTags := TStringList.Create;
FCreated := Now;
FModified := Now;
FActive := True;
FDiscount := DEFAULT_DISCOUNT;
end;
destructor TCustomer.Destroy;
begin
FTags.Free;
inherited;
end;
procedure TCustomer.Assign(Source: TCustomer);
begin
if Assigned(Source) then
begin
FID := Source.FID;
FName := Source.FName;
FEmail := Source.FEmail;
FPhone := Source.FPhone;
FAddress := Source.FAddress;
FBalance := Source.FBalance;
FCreated := Source.FCreated;
FModified := Source.FModified;
FActive := Source.FActive;
FDiscount := Source.FDiscount;
FTags.Assign(Source.FTags);
end;
end;
function TCustomer.Clone: TCustomer;
begin
Result := TCustomer.Create;
Result.Assign(Self);
end;
procedure TCustomer.SetBalance(const Value: Currency);
begin
if FBalance <> Value then
begin
FBalance := Value;
DoModify;
end;
end;
procedure TCustomer.SetEmail(const Value: string);
begin
if FEmail <> Value then
begin
if ValidateEmail(Value) then
begin
FEmail := Value;
DoModify;
end
else
raise ECustomerException.CreateFmt(SInvalidEmail, [Value], 1001, FID);
end;
end;
function TCustomer.GetFullName: string;
begin
Result := Format('%s %s', [FName, FEmail]);
end;
procedure TCustomer.DoModify;
begin
FModified := Now;
end;
function TCustomer.ValidateEmail(const Email: string): Boolean;
var
Regex: TPerlRegEx;
begin
Regex := TPerlRegEx.Create;
try
Regex.RegEx := '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$';
Regex.Subject := Email;
Result := Regex.Match;
finally
Regex.Free;
end;
end;
procedure TCustomer.LoadFromDataset(Dataset: TDataSet);
begin
if Assigned(Dataset) and not Dataset.IsEmpty then
begin
FID := Dataset.FieldByName('ID').AsInteger;
FName := Dataset.FieldByName('Name').AsString;
FEmail := Dataset.FieldByName('Email').AsString;
FPhone := Dataset.FieldByName('Phone').AsString;
FAddress.Street := Dataset.FieldByName('Street').AsString;
FAddress.City := Dataset.FieldByName('City').AsString;
FAddress.State := Dataset.FieldByName('State').AsString;
FAddress.ZipCode := Dataset.FieldByName('ZipCode').AsString;
FAddress.Country := Dataset.FieldByName('Country').AsString;
FBalance := Dataset.FieldByName('Balance').AsCurrency;
FCreated := Dataset.FieldByName('Created').AsDateTime;
FModified := Dataset.FieldByName('Modified').AsDateTime;
FActive := Dataset.FieldByName('Active').AsBoolean;
FDiscount := Dataset.FieldByName('Discount').AsFloat;
FTags.CommaText := Dataset.FieldByName('Tags').AsString;
end;
end;
procedure TCustomer.SaveToDataset(Dataset: TDataSet);
begin
if Assigned(Dataset) then
begin
Dataset.FieldByName('ID').AsInteger := FID;
Dataset.FieldByName('Name').AsString := FName;
Dataset.FieldByName('Email').AsString := FEmail;
Dataset.FieldByName('Phone').AsString := FPhone;
Dataset.FieldByName('Street').AsString := FAddress.Street;
Dataset.FieldByName('City').AsString := FAddress.City;
Dataset.FieldByName('State').AsString := FAddress.State;
Dataset.FieldByName('ZipCode').AsString := FAddress.ZipCode;
Dataset.FieldByName('Country').AsString := FAddress.Country;
Dataset.FieldByName('Balance').AsCurrency := FBalance;
Dataset.FieldByName('Created').AsDateTime := FCreated;
Dataset.FieldByName('Modified').AsDateTime := FModified;
Dataset.FieldByName('Active').AsBoolean := FActive;
Dataset.FieldByName('Discount').AsFloat := FDiscount;
Dataset.FieldByName('Tags').AsString := FTags.CommaText;
end;
end;
function TCustomer.CalculateDiscount(Amount: Currency): Currency;
begin
Result := Amount * (1 - FDiscount);
end;
class function TCustomer.GetCustomerByID(ID: TCustomerID): TCustomer;
var
Service: ICustomerService;
begin
Service := TCustomerService.Create;
Result := Service.GetCustomer(ID);
end;
constructor TGenericList<T>.Create;
begin
inherited;
FCount := 0;
FCapacity := 16;
SetLength(FItems, FCapacity);
end;
destructor TGenericList<T>.Destroy;
begin
SetLength(FItems, 0);
inherited;
end;
procedure TGenericList<T>.Add(const Item: T);
begin
if FCount = FCapacity then
Grow;
FItems[FCount] := Item;
Inc(FCount);
end;
procedure TGenericList<T>.Insert(Index: Integer; const Item: T);
var
I: Integer;
begin
if (Index < 0) or (Index > FCount) then
raise EListError.Create('Index out of bounds');
if FCount = FCapacity then
Grow;
for I := FCount downto Index + 1 do
FItems[I] := FItems[I - 1];
FItems[Index] := Item;
Inc(FCount);
end;
procedure TGenericList<T>.Delete(Index: Integer);
var
I: Integer;
begin
if (Index < 0) or (Index >= FCount) then
raise EListError.Create('Index out of bounds');
for I := Index to FCount - 2 do
FItems[I] := FItems[I + 1];
Dec(FCount);
end;
function TGenericList<T>.Remove(const Item: T): Integer;
begin
Result := IndexOf(Item);
if Result >= 0 then
Delete(Result);
end;
function TGenericList<T>.IndexOf(const Item: T): Integer;
var
I: Integer;
Comparer: IEqualityComparer<T>;
begin
Comparer := TEqualityComparer<T>.Default;
for I := 0 to FCount - 1 do
if Comparer.Equals(FItems[I], Item) then
Exit(I);
Result := -1;
end;
procedure TGenericList<T>.Clear;
begin
FCount := 0;
end;
procedure TGenericList<T>.Sort(Compare: TComparer<T>);
var
Temp: T;
I, J: Integer;
begin
for I := 0 to FCount - 2 do
for J := I + 1 to FCount - 1 do
if Compare.Compare(FItems[I], FItems[J]) > 0 then
begin
Temp := FItems[I];
FItems[I] := FItems[J];
FItems[J] := Temp;
end;
end;
procedure TGenericList<T>.Sort;
begin
Sort(TComparer<T>.Default);
end;
procedure TGenericList<T>.Grow;
begin
FCapacity := FCapacity * 2;
SetLength(FItems, FCapacity);
end;
function TGenericList<T>.GetItem(Index: Integer): T;
begin
if (Index < 0) or (Index >= FCount) then
raise EListError.Create('Index out of bounds');
Result := FItems[Index];
end;
procedure TGenericList<T>.SetItem(Index: Integer; const Value: T);
begin
if (Index < 0) or (Index >= FCount) then
raise EListError.Create('Index out of bounds');
FItems[Index] := Value;
end;
constructor TCustomerService.Create;
begin
inherited;
PrepareConnection;
end;
destructor TCustomerService.Destroy;
begin
FQuery.Free;
FConnection.Free;
inherited;
end;
procedure TCustomerService.PrepareConnection;
begin
FConnection := TFDConnection.Create(nil);
FQuery := TFDQuery.Create(nil);
FQuery.Connection := FConnection;
FConnection.Params.Values['DriverID'] := 'SQLite';
FConnection.Params.Values['Database'] := 'customers.db';
FConnection.LoginPrompt := False;
try
FConnection.Connected := True;
except
on E: Exception do
raise ECustomerException.CreateFmt('Database connection failed: %s', [E.Message], 2001, 0);
end;
end;
function TCustomerService.GetCustomer(ID: TCustomerID): TCustomer;
begin
FQuery.SQL.Text := 'SELECT * FROM Customers WHERE ID = :ID';
FQuery.ParamByName('ID').AsInteger := ID;
FQuery.Open;
try
if not FQuery.IsEmpty then
begin
Result := TCustomer.Create;
Result.LoadFromDataset(FQuery);
end
else
Result := nil;
finally
FQuery.Close;
end;
end;
procedure TCustomerService.SaveCustomer(Customer: TCustomer);
begin
ValidateCustomer(Customer);
if Customer.ID = 0 then
begin
FQuery.SQL.Text :=
'INSERT INTO Customers (Name, Email, Phone, Street, City, State, ZipCode, Country, ' +
'Balance, Created, Modified, Active, Discount, Tags) VALUES ' +
'(:Name, :Email, :Phone, :Street, :City, :State, :ZipCode, :Country, ' +
':Balance, :Created, :Modified, :Active, :Discount, :Tags)';
end
else
begin
FQuery.SQL.Text :=
'UPDATE Customers SET Name = :Name, Email = :Email, Phone = :Phone, ' +
'Street = :Street, City = :City, State = :State, ZipCode = :ZipCode, ' +
'Country = :Country, Balance = :Balance, Modified = :Modified, ' +
'Active = :Active, Discount = :Discount, Tags = :Tags ' +
'WHERE ID = :ID';
FQuery.ParamByName('ID').AsInteger := Customer.ID;
end;
Customer.SaveToDataset(FQuery);
FQuery.ExecSQL;
end;
procedure TCustomerService.DeleteCustomer(ID: TCustomerID);
begin
FQuery.SQL.Text := 'DELETE FROM Customers WHERE ID = :ID';
FQuery.ParamByName('ID').AsInteger := ID;
FQuery.ExecSQL;
if FQuery.RowsAffected = 0 then
raise ECustomerException.Create('Customer not found', 2002, ID);
end;
function TCustomerService.GetAllCustomers: TArray<TCustomer>;
var
Customer: TCustomer;
begin
FQuery.SQL.Text := 'SELECT * FROM Customers ORDER BY Name';
FQuery.Open;
try
SetLength(Result, FQuery.RecordCount);
var I := 0;
while not FQuery.Eof do
begin
Customer := TCustomer.Create;
Customer.LoadFromDataset(FQuery);
Result[I] := Customer;
Inc(I);
FQuery.Next;
end;
finally
FQuery.Close;
end;
end;
function TCustomerService.FindCustomers(const Filter: string): TArray<TCustomer>;
var
Customer: TCustomer;
FilterSQL: string;
begin
FilterSQL := 'SELECT * FROM Customers WHERE Name LIKE :Filter OR Email LIKE :Filter ORDER BY Name';
FQuery.SQL.Text := FilterSQL;
FQuery.ParamByName('Filter').AsString := '%' + Filter + '%';
FQuery.Open;
try
SetLength(Result, FQuery.RecordCount);
var I := 0;
while not FQuery.Eof do
begin
Customer := TCustomer.Create;
Customer.LoadFromDataset(FQuery);
Result[I] := Customer;
Inc(I);
FQuery.Next;
end;
finally
FQuery.Close;
end;
end;
function TCustomerService.GetCustomerCount: Integer;
begin
FQuery.SQL.Text := 'SELECT COUNT(*) FROM Customers';
FQuery.Open;
try
Result := FQuery.Fields[0].AsInteger;
finally
FQuery.Close;
end;
end;
procedure TCustomerService.ValidateCustomer(Customer: TCustomer);
begin
if Customer.Name = '' then
raise ECustomerException.Create('Customer name is required', 2003, Customer.ID);
if not Customer.ValidateEmail(Customer.Email) then
raise ECustomerException.CreateFmt(SInvalidEmail, [Customer.Email], 2004, Customer.ID);
if Customer.Balance < 0 then
raise ECustomerException.Create('Customer balance cannot be negative', 2005, Customer.ID);
end;
class constructor TMathHelper.Create;
begin
FPI := System.PI;
FEpsilon := 1e-10;
end;
class function TMathHelper.Factorial(N: Integer): Int64;
var
I: Integer;
begin
if N < 0 then
raise EMathError.Create('Factorial is not defined for negative numbers');
Result := 1;
for I := 2 to N do
Result := Result * I;
end;
class function TMathHelper.Power(Base, Exponent: Double): Double;
begin
if (Base = 0) and (Exponent <= 0) then
raise EMathError.Create('Invalid power operation');
Result := System.Math.Power(Base, Exponent);
end;
class function TMathHelper.IsPrime(Number: Integer): Boolean;
var
I: Integer;
begin
if Number <= 1 then
Exit(False);
if Number <= 3 then
Exit(True);
if (Number mod 2 = 0) or (Number mod 3 = 0) then
Exit(False);
I := 5;
while I * I <= Number do
begin
if (Number mod I = 0) or (Number mod (I + 2) = 0) then
Exit(False);
Inc(I, 6);
end;
Result := True;
end;
class function TMathHelper.Fibonacci(N: Integer): Int64;
var
A, B, Temp: Int64;
I: Integer;
begin
if N <= 0 then
Exit(0);
if N = 1 then
Exit(1);
A := 0;
B := 1;
for I := 2 to N do
begin
Temp := A + B;
A := B;
B := Temp;
end;
Result := B;
end;
class function TMathHelper.GCD(A, B: Integer): Integer;
var
Temp: Integer;
begin
A := Abs(A);
B := Abs(B);
while B <> 0 do
begin
Temp := B;
B := A mod B;
A := Temp;
end;
Result := A;
end;
class function TMathHelper.LCM(A, B: Integer): Integer;
begin
if (A = 0) or (B = 0) then
Result := 0
else
Result := Abs(A * B) div GCD(A, B);
end;
constructor TBackgroundWorker.Create(CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
FProgress := 0;
FMessage := '';
FreeOnTerminate := True;
end;
procedure TBackgroundWorker.Execute;
var
I: Integer;
begin
try
for I := 1 to 100 do
begin
if Terminated then
Break;
Sleep(50); Progress := I;
Message := Format('Processing item %d of 100', [I]);
end;
Message := 'Background work completed';
except
on E: Exception do
begin
Message := 'Error: ' + E.Message;
end;
end;
end;
procedure TBackgroundWorker.SetProgress(Value: Integer);
begin
if FProgress <> Value then
begin
FProgress := Value;
Synchronize(DoProgress);
end;
end;
procedure TBackgroundWorker.SetMessage(const Value: string);
begin
if FMessage <> Value then
begin
FMessage := Value;
Synchronize(DoMessage);
end;
end;
procedure TBackgroundWorker.DoProgress;
begin
if Assigned(FOnProgress) then
FOnProgress(Self);
end;
procedure TBackgroundWorker.DoMessage;
begin
if Assigned(FOnMessage) then
FOnMessage(Self);
end;
constructor ECustomerException.Create(const Msg: string; ErrorCode: Integer; CustomerID: TCustomerID);
begin
inherited Create(Msg);
FErrorCode := ErrorCode;
FCustomerID := CustomerID;
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
InitializeComponents;
SetupDatabase;
LoadCustomers;
UpdateStatusBar;
end;
procedure TMainForm.FormDestroy(Sender: TObject);
begin
if Assigned(FCurrentCustomer) then
FCurrentCustomer.Free;
end;
procedure TMainForm.InitializeComponents;
begin
Caption := Format('%s - %s', [APP_NAME, VERSION]);
FilterEdit.Text := '';
FilterLabel.Caption := 'Filter:';
SearchButton.Caption := 'Search';
ClearButton.Caption := 'Clear';
ExportButton.Caption := 'Export';
PrintButton.Caption := 'Print';
CustomerGrid.Options := CustomerGrid.Options + [dgRowSelect, dgAlwaysShowSelection];
CustomerGrid.Align := alClient;
end;
procedure TMainForm.SetupDatabase;
begin
FCustomerService := TCustomerService.Create;
end;
procedure TMainForm.LoadCustomers;
var
Customers: TArray<TCustomer>;
I: Integer;
begin
try
if FFilterText <> '' then
Customers := FCustomerService.FindCustomers(FFilterText)
else
Customers := FCustomerService.GetAllCustomers;
for I := 0 to High(Customers) do
begin
if Assigned(Customers[I]) then
Customers[I].Free;
end;
except
on E: Exception do
MessageDlg(Format(SErrorLoadingData, [E.Message]), mtError, [mbOK], 0);
end;
end;
procedure TMainForm.UpdateStatusBar;
begin
StatusBar.Panels[0].Text := Format('Total customers: %d', [FCustomerService.GetCustomerCount]);
StatusBar.Panels[1].Text := Format('Filter: %s', [FFilterText]);
StatusBar.Panels[2].Text := Format('Date: %s', [FormatDateTime('yyyy-mm-dd', Now)]);
end;
procedure TMainForm.SearchButtonClick(Sender: TObject);
begin
FFilterText := FilterEdit.Text;
LoadCustomers;
UpdateStatusBar;
end;
procedure TMainForm.ClearButtonClick(Sender: TObject);
begin
FilterEdit.Text := '';
FFilterText := '';
LoadCustomers;
UpdateStatusBar;
end;
procedure TMainForm.ExportButtonClick(Sender: TObject);
begin
ShowMessage('Export functionality would be implemented here');
end;
procedure TMainForm.PrintButtonClick(Sender: TObject);
begin
ShowMessage('Print functionality would be implemented here');
end;
procedure TMainForm.FilterEditChange(Sender: TObject);
begin
end;
procedure TMainForm.DoShow;
begin
inherited;
ShowMessage(Format(SWelcomeMessage, [APP_NAME, VERSION]));
end;
procedure TMainForm.DoHide;
begin
inherited;
end;
procedure TMainForm.ShowCustomerDetails(Customer: TCustomer);
begin
if Assigned(Customer) then
begin
if Assigned(FCurrentCustomer) then
FCurrentCustomer.Free;
FCurrentCustomer := Customer.Clone;
end;
end;
function TMainForm.ValidateForm: Boolean;
begin
Result := True;
end;
initialization
GlobalCustomerList := TGenericList<TCustomer>.Create;
GlobalSettings := TStringList.Create;
ApplicationPath := ExtractFilePath(ParamStr(0));
IsInitialized := True;
finalization
if Assigned(GlobalCustomerList) then
GlobalCustomerList.Free;
if Assigned(GlobalSettings) then
GlobalSettings.Free;
end.