added clockhistory and get command

This commit is contained in:
Tim G. | SnapixLP 2025-06-06 09:06:59 +02:00
parent c2608f4bf6
commit 8630c4c346
4 changed files with 175 additions and 4 deletions

View File

@ -6,3 +6,16 @@ public enum EmployeeState
IN,
BREAK,
}
public static class EmployeeStateExtensions
{
public static string ToFriendlyString(this EmployeeState state)
{
return state switch
{
EmployeeState.OUT => "Clocked Out",
EmployeeState.IN => "Clocked In",
EmployeeState.BREAK => "On Break",
_ => state.ToString()
};
}
}

View File

@ -139,9 +139,9 @@ public class Server
// Implement logic to get a worker by ID or code
if (id != null)
commandResult = ExecuteCommandAsync("get worker byid " + id).Result;
commandResult = ExecuteCommandAsync("get employee byid " + id).Result;
else
commandResult = ExecuteCommandAsync("get worker bycode " + id).Result;
commandResult = ExecuteCommandAsync("get employee bycode " + code).Result;
// Deserialize the command result to an Employee object
try
@ -233,4 +233,6 @@ public class Server
return Task.FromException<string>(new Exception("Failed to clock break."));
}
}
}

View File

@ -295,8 +295,159 @@ public class CommandLibrary
#region Administration Commands
[Command("get")]
public static string GetCommand(string[] args, TcpClient? client, TcpServer? socket) =>
$"not implemented yet, args: {string.Join(", ", args)}";
public static string GetCommand(string[] args, TcpClient? client, TcpServer? socket)
{
// Usage: get employee byid <id>
// get employee bycode <code>
if (args.Length < 3)
throw new CommandException("Usage: get employee byid <id> OR get employee bycode <code>");
string entity = args[0].ToLowerInvariant();
string mode = args[1].ToLowerInvariant();
string key = args[2];
if (entity != "employee")
throw new CommandException("Usage: get employee byid <id> OR get employee bycode <code>");
var filter = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
if (mode == "byid")
{
if (!int.TryParse(key, out var id))
throw new CommandException("Invalid id format. Must be an integer.");
filter["Id"] = id;
}
else if (mode == "bycode")
{
filter["Code"] = key;
}
else
{
throw new CommandException("Usage: get employee byid <id> OR get employee bycode <code>");
}
// Query the database
string empResultJson = Program.mySql.Get("employees", filter);
using var doc = JsonDocument.Parse(empResultJson);
bool dbError = doc.RootElement.GetProperty("error").GetBoolean();
if (dbError)
{
string dbMsg = doc.RootElement.GetProperty("data").GetString() ?? "Unknown DB error";
Program.messageSender.Error($"[GetCommand] DB error: {dbMsg}");
throw new CommandException("Internal error while fetching employee.");
}
var dataArray = doc.RootElement.GetProperty("data");
if (dataArray.GetArrayLength() == 0)
throw new CommandException("Employee not found.");
// Return the first (and expected single) matching employee as JSON object
var firstEmp = dataArray[0];
return firstEmp.GetRawText();
}
[Command("clockHistory")]
public static string ClockHistoryCommand(string[] args, TcpClient? client, TcpServer? socket)
{
// 1) Argument check
if (args.Length < 1)
throw new CommandException("Missing argument: usage is clockHistory <employeeCode>");
string employeeCode = args[0];
// 2) Look up the employee by Code
var empParams = new Dictionary<string, object> { { "Code", employeeCode } };
string empResultJson = Program.mySql.Get("employees", empParams);
using var empDoc = JsonDocument.Parse(empResultJson);
bool empError = empDoc.RootElement.GetProperty("error").GetBoolean();
if (empError)
{
string dbMsg = empDoc.RootElement.GetProperty("data").GetString() ?? "Unknown DB error";
Program.messageSender.Error($"[ClockHistoryCommand] DB error when looking up employee: {dbMsg}");
throw new CommandException("Internal error while fetching employee data.");
}
var empArray = empDoc.RootElement.GetProperty("data");
if (empArray.GetArrayLength() == 0)
throw new CommandException("Employee not found in database.");
// 3) Extract Id from the first row
var empRow = empArray[0];
int employeeId = empRow.GetProperty("Id").GetInt32();
// 4) Query the history for that employeeId
var histParams = new Dictionary<string, object> { { "EmployeeId", employeeId } };
string histResultJson = Program.mySql.Get("employee_state_history", histParams);
using var histDoc = JsonDocument.Parse(histResultJson);
bool histError = histDoc.RootElement.GetProperty("error").GetBoolean();
if (histError)
{
string dbMsg = histDoc.RootElement.GetProperty("data").GetString() ?? "Unknown DB error";
Program.messageSender.Error($"[ClockHistoryCommand] DB error when fetching history: {dbMsg}");
throw new CommandException("Internal error while fetching clock history.");
}
return histDoc.RootElement.GetProperty("data").GetRawText();
}
[Command("fullClockHistory")]
public static string FullClockHistoryCommand(string[] args, TcpClient? client, TcpServer? socket)
{
// 1) Determine maxHistoryLength (default = 50)
int maxHistoryLength;
if (args.Length >= 1 && int.TryParse(args[0], out var parsed))
{
maxHistoryLength = parsed;
}
else
{
maxHistoryLength = 50;
}
// 2) Verify client/socket
if (client == null || socket == null)
throw new CommandException("No client connection detected.");
if (!socket.LoggedInClients.TryGetValue(client, out var employeeCode))
throw new CommandException("User not logged in.");
// 3) Look up the employee to get its Id
var empParams = new Dictionary<string, object> { { "Code", employeeCode } };
string empResultJson = Program.mySql.Get("employees", empParams);
using var empDoc = JsonDocument.Parse(empResultJson);
bool empError = empDoc.RootElement.GetProperty("error").GetBoolean();
if (empError)
{
string dbMsg = empDoc.RootElement.GetProperty("data").GetString() ?? "Unknown DB error";
Program.messageSender.Error($"[FullClockHistory] DB error when looking up employee: {dbMsg}");
throw new CommandException("Internal error while fetching user data.");
}
var empArray = empDoc.RootElement.GetProperty("data");
if (empArray.GetArrayLength() == 0)
throw new CommandException("Logged-in user not found in database.");
int employeeId = empArray[0].GetProperty("Id").GetInt32();
// 4) Query the history table for this employeeId, ordered by ChangeTime DESC, limited to maxHistoryLength
string sql = @"
SELECT `EmployeeId`, `NewState`, `ChangeTime`
FROM `employee_state_history`
WHERE `EmployeeId` = ?
ORDER BY `ChangeTime` DESC
LIMIT ?
";
var values = new List<object> { employeeId, maxHistoryLength };
string historyJson = Program.mySql.Query(sql, null, values);
// 5) Return the JSON from Query (the client will receive {"error":…, "data":[…]} )
return historyJson;
}
#endregion

View File

@ -15,6 +15,10 @@ public class Tester
Console.Write("Enter the server IP address: ");
string ip = Console.ReadLine();
if (ip == "devsrv")
ip = "185.113.120.99";
else if (ip == "local")
ip = "127.0.0.1";
Console.Write("Enter the port: ");
int port = int.Parse(Console.ReadLine());
@ -77,6 +81,7 @@ public class Tester
$"Code: {employee.Code}",
$"Surname: {employee.Surname}",
$"Forename: {employee.Forename}",
$"clocked: {employee.EmployeeState.ToFriendlyString()}",
});
}
else if (command == "clock in")