This commit is contained in:
Torsten (PC)
2026-01-14 14:36:57 +01:00
parent cd739fb52e
commit 1fe77c0905
21 changed files with 1267 additions and 0 deletions

172
src/produce_worker.cpp Normal file
View File

@@ -0,0 +1,172 @@
#include "produce_worker.h"
#include "connection_guard.h" // Include for ConnectionGuard
#include <iostream>
#include <algorithm>
#include <thread>
#include <nlohmann/json.hpp>
ProduceWorker::ProduceWorker(ConnectionPool &pool, MessageBroker &broker)
: Worker(pool, broker, "ProduceWorker")
{
}
ProduceWorker::~ProduceWorker() {
}
void ProduceWorker::run() {
auto lastIterationTime = std::chrono::steady_clock::now();
while (runningWorker) {
setCurrentStep("Check runningWorker Variable");
{
std::lock_guard<std::mutex> lock(activityMutex);
if (!runningWorker) {
break;
}
}
setCurrentStep("Calculate elapsed time");
auto now = std::chrono::steady_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - lastIterationTime);
if (elapsed < std::chrono::milliseconds(200)) {
std::this_thread::sleep_for(std::chrono::milliseconds(200) - elapsed);
}
lastIterationTime = std::chrono::steady_clock::now();
setCurrentStep("Process Productions");
processProductions();
setCurrentStep("Signal Activity");
signalActivity();
setCurrentStep("Loop Done");
}
}
void ProduceWorker::processProductions() {
try {
setCurrentStep("Get Database Connection");
ConnectionGuard connGuard(pool);
auto &db = connGuard.get();
setCurrentStep("Fetch Finished Productions");
auto finishedProductions = getFinishedProductions(db);
setCurrentStep("Process Finished Productions");
for (const auto &production : finishedProductions) {
if (production.find("branch_id") == production.end() ||
production.find("product_id") == production.end() ||
production.find("quantity") == production.end() ||
production.find("quality") == production.end() ||
production.find("user_id") == production.end()) {
continue;
}
int branchId = std::stoi(production.at("branch_id"));
int productId = std::stoi(production.at("product_id"));
int quantity = std::stoi(production.at("quantity"));
int quality = std::stoi(production.at("quality"));
int userId = std::stoi(production.at("user_id"));
if (addToInventory(db, branchId, productId, quantity, quality, userId)) {
}
deleteProduction(db, production.at("production_id"));
}
} catch (const std::exception &e) {
std::cerr << "[ProduceWorker] Fehler in processProductions: " << e.what() << std::endl;
}
}
std::vector<std::unordered_map<std::string, std::string>> ProduceWorker::getFinishedProductions(Database &db) {
try {
db.prepare("get_finished_productions", QUERY_GET_FINISHED_PRODUCTIONS);
return db.execute("get_finished_productions");
} catch (const std::exception &e) {
std::cerr << "[ProduceWorker] Fehler beim Abrufen abgeschlossener Produktionen: "
<< e.what() << std::endl;
}
return {};
}
bool ProduceWorker::addToInventory(Database &db,
int branchId,
int productId,
int quantity,
int quality,
int userId)
{
try {
db.prepare("get_stocks", QUERY_GET_AVAILABLE_STOCKS);
auto stocks = db.execute("get_stocks", {std::to_string(branchId)});
int remainingQuantity = quantity;
for (const auto &stock : stocks) {
int stockId = std::stoi(stock.at("id"));
int totalCapacity = std::stoi(stock.at("total_capacity"));
int filledCapacity = std::stoi(stock.at("filled"));
int freeCapacity = totalCapacity - filledCapacity;
if (freeCapacity <= 0) {
continue;
}
int toStore = std::min(remainingQuantity, freeCapacity);
if (!storeInStock(db, stockId, productId, toStore, quality)) {
return false;
}
remainingQuantity -= toStore;
sendProductionReadyEvent(userId, productId, quantity, quality, branchId);
if (remainingQuantity <= 0) {
break;
}
}
return (remainingQuantity == 0);
} catch (const std::exception &e) {
std::cerr << "[ProduceWorker] Fehler in addToInventory: " << e.what() << std::endl;
}
return false;
}
bool ProduceWorker::storeInStock(Database &db,
int stockId,
int productId,
int quantity,
int quality)
{
try {
db.prepare("insert_inventory", QUERY_INSERT_INVENTORY);
db.execute("insert_inventory", {std::to_string(stockId),
std::to_string(productId),
std::to_string(quantity),
std::to_string(quality)});
return true;
} catch (const std::exception &e) {
std::cerr << "[ProduceWorker] Fehler in storeInStock: " << e.what() << std::endl;
}
return false;
}
void ProduceWorker::deleteProduction(Database &db, const std::string &productionId) {
try {
db.prepare("delete_production", QUERY_DELETE_PRODUCTION);
db.execute("delete_production", {productionId});
} catch (const std::exception &e) {
std::cerr << "[ProduceWorker] Fehler beim Löschen der Produktion: " << e.what() << std::endl;
}
}
void ProduceWorker::sendProductionReadyEvent(int userId,
int productId,
int quantity,
int quality,
int branchId)
{
try {
nlohmann::json message = {
{"event", "production_ready"},
{"user_id", userId},
{"product_id", productId},
{"quantity", quantity},
{"quality", quality},
{"branch_id", branchId}
};
broker.publish(message.dump());
} catch (const std::exception &e) {
std::cerr << "[ProduceWorker] Fehler beim Senden des Production Ready Events: "
<< e.what() << std::endl;
}
}