Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Services/NotificationManagement/object_notification.cpp
T
berrux-dev c3eda18234 Migrates remaining services and plugins to generated rtiddsgen API
Converts accessor calls to plain member access across the residual service set.
2026-09-21 02:47:48 +02:00

428 lines
16 KiB
C++
Executable File

/**
* NomNotification object
* $Id$
* $HeadURL$
* $Author$
* Created by Hanna E. Rathje, ESZS, 2025-06-23
*/
#include "object_notification.h"
#include "dds_handler.h"
#include <ngldb/dbtransaction.h>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
namespace NotificationManagement
{
const QString TRANSLATION_ARGS = QStringLiteral("translationsArgs");
const QString CONTENT_ID = QStringLiteral("id");
const QString CONTENT_ARG = QStringLiteral("contentArg");
ObjectNotification::ObjectNotification(const std::shared_ptr<DdsHandler> &ddsHandler, const std::shared_ptr<DatabaseInterface> &db)
: m_ddsHandler(ddsHandler)
, m_db(db)
, m_logger(getLogger("ObjectNotification"))
{
} // end of ctor()
//-----------------------------------------------------------------------------
ObjectNotification::~ObjectNotification() { m_ddsHandler->dts()->removeNomNotificationByKey(m_dataNotificationObject.id); } // end of dtor()
//-----------------------------------------------------------------------------
Core::FunctionReplyObject ObjectNotification::createObject(const NomNotification &data)
{
m_dataNotificationObject = data;
if (data.id <= 0)
{
Database::NomNotification dbDataNotification = toDbData(data);
dbDataNotification.timeStamp = QDateTime::currentMSecsSinceEpoch();
DBTransaction trans(m_db->database());
if (!m_db->insert(dbDataNotification))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting NomNotification-data into database"));
// Neue DB Id in lokale Struktur uebernehmen
m_dataNotificationObject.id = dbDataNotification.id;
DEBUG_LOG(m_logger) << "New NotificationId: " << dbDataNotification.id;
DEBUG_LOG(m_logger) << "Handle Address for notificationId:" << dbDataNotification.id << " number of depending recipients: " << data.recipientIds.size();
// Behandlung von Recipients
for (size_t i = 0; i < data.recipientIds.size(); ++i)
{
Address &recipientAddress = m_dataNotificationObject.recipientIds[i];
Database::NomAddress dbDataRecipientAddr = toDbData(recipientAddress);
// Struct Address vorbereiten
dbDataRecipientAddr.notificationId = dbDataNotification.id; // FK auf NotificationId
dbDataRecipientAddr.id = 0;
dbDataRecipientAddr.isRead = false;
dbDataRecipientAddr.isSender = false;
if (!m_db->insert(dbDataRecipientAddr))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting RecipientAddress-data into database"));
// Neue DB Id in lokale Struktur uebernehmen
recipientAddress.id = dbDataRecipientAddr.id;
}
Address &senderAddress = m_dataNotificationObject.sender;
Database::NomAddress dbDataSenderAddr = toDbData(senderAddress);
// Struct Address vorbereiten
dbDataSenderAddr.notificationId = dbDataNotification.id; // FK auf NotificationId
dbDataSenderAddr.isRead = false;
dbDataSenderAddr.isSender = true;
dbDataSenderAddr.id = 0;
if (!m_db->insert(dbDataSenderAddr))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting SenderAddress-data into database"));
// Neue DB Id in lokale Struktur uebernehmen
senderAddress.id = dbDataSenderAddr.id;
trans.commit();
}
// Publish Data via DTS
onPublishData();
return Core::FunctionReplyObject(m_dataNotificationObject.id);
} // end of createObject()
//-----------------------------------------------------------------------------
QString ObjectNotification::contentArgsToJson()
{
int i = 1;
QJsonArray jsonArray;
for (const std::string& arg : qAsConst(m_dataNotificationObject.contentArgs))
{
DEBUG_LOG(m_logger) << ".arg() ersetzt immer den kleinsten freien Platzhalter"
<< ", arg=" << arg;
QJsonObject argObj;
argObj[CONTENT_ID] = i;
argObj[CONTENT_ARG] = QString::fromStdString(arg);
jsonArray.append(argObj);
i++;
}
QJsonObject mainObject;
mainObject[TRANSLATION_ARGS] = jsonArray;
QJsonDocument doc(mainObject);
DEBUG_LOG(m_logger) << "ObjectNotification::contentArgsToJson properties=" << QString::fromUtf8(doc.toJson(QJsonDocument::Compact));
return QString::fromUtf8(doc.toJson(QJsonDocument::Compact));
}
std::vector<std::string> ObjectNotification::jsonToContentArgs(const QString &jsonString)
{
//DEBUG_LOG(m_logger) << "jsonToContentArgs jsonString=" << jsonString;
std::vector<std::string> result;
// 1. String parsen
QJsonDocument doc = QJsonDocument::fromJson(jsonString.toUtf8());
if (!doc.isObject()) {
//WARNING_LOG(m_logger) << "properties: Invalid JSON-Object";
return result;
}
QJsonObject hauptObjekt = doc.object();
// 2. Das Array aus "translationsArgs" herausholen
if (!hauptObjekt.contains(TRANSLATION_ARGS) || !hauptObjekt[TRANSLATION_ARGS].isArray()) {
//WARNING_LOG(m_logger) << "Missing or invalid 'translationsArgs' key (must be an array).";
return result;
}
QJsonArray jsonArray = hauptObjekt[TRANSLATION_ARGS].toArray();
for ( int gesuchteId = 1; gesuchteId <= jsonArray.size(); gesuchteId++)
{
// 3. Für schnellen Zugriff nach ID indizieren
QHash<int, QJsonObject> sucheMap;
for (const QJsonValue &wert : qAsConst(jsonArray))
{
QJsonObject obj = wert.toObject();
int id = obj[CONTENT_ID].toInt();
sucheMap[id] = obj;
}
// 4. Zugriff über die ID testen
if (sucheMap.contains(gesuchteId)) {
QJsonObject treffer = sucheMap[gesuchteId];
//DEBUG_LOG(m_logger) << "ID" << gesuchteId << "gefunden!";
//DEBUG_LOG(m_logger) << "Inhalt:" << treffer[CONTENT_ARG].toString();
QString contentStr = treffer[CONTENT_ARG].toString();
result.emplace_back(contentStr.toStdString());
} else {
//qDebug() << "ID" << gesuchteId << "nicht im System.";
}
}
return result;
}
Core::FunctionReplyObject ObjectNotification::readReceipt(const ReadReceipt &data, int notificationId)
{
if (!isValid())
return Core::FunctionReplyObject(notificationId, tr_lts("dds", "Object not valid/blocked"));
Database::NomNotification dbDataNotification = toDbData(m_dataNotificationObject);
Database::NomAddress dbDataAddr;
for (const Address &recipientAddr : qAsConst(m_dataNotificationObject.recipientIds))
{
if (data.operatorId > 0 && recipientAddr.addressType == AddressType::Operator && recipientAddr.addressId != data.operatorId)
continue;
if (data.workstationId > 0 && recipientAddr.addressType == AddressType::Workstation && recipientAddr.addressId != data.workstationId)
continue;
dbDataAddr = toDbData(recipientAddr);
DEBUG_LOG(m_logger) << "Found Operator " << data.operatorId << " with repicpentID " << dbDataAddr.id;
dbDataAddr.notificationId = dbDataNotification.id;
break;
}
if (dbDataAddr.id <= 0)
return Core::FunctionReplyObject(data.addressId, tr_lts("dds", "No Address found"));
dbDataAddr.isRead = true;
DBTransaction trans(m_db->database());
// NomNotification shall be marked as processed
if (data.processed)
{
// but hasn't been so yet
if (dbDataNotification.processed <= 0)
{
dbDataNotification.processed = dbDataAddr.id;
dbDataNotification.processTime = QDateTime::currentMSecsSinceEpoch();
if (dbDataNotification.priorityId != dbDataNotification.processedPriority)
dbDataNotification.priorityId = dbDataNotification.processedPriority;
if (!m_db->update(dbDataNotification))
return Core::FunctionReplyObject(notificationId, tr_lts("dds", "Error updating notification-data"));
}
else
{
DEBUG_LOG(m_logger) << "Notification already processed id=" << notificationId;
return Core::FunctionReplyObject(dbDataNotification.processed, {}, {}, tr_lts("dds", "Notification already processed"));
}
}
if (!m_db->update(dbDataAddr))
return Core::FunctionReplyObject(dbDataAddr.id, tr_lts("dds", "Error updating address-data into database"));
trans.commit();
INFO_LOG(m_logger) << "Data changed for NotificationId: " << m_dataNotificationObject.id;
const std::vector<Address> recipients = m_dataNotificationObject.recipientIds;
const Address sender = m_dataNotificationObject.sender;
m_dataNotificationObject = toDdsData(dbDataNotification);
m_dataNotificationObject.sender = sender;
for (const Address &addr : qAsConst(recipients))
{
if (addr.id == dbDataAddr.id)
m_dataNotificationObject.recipientIds.push_back(toDdsData(dbDataAddr));
else
m_dataNotificationObject.recipientIds.push_back(addr);
}
// Publish Data via DTS
onPublishData();
return Core::FunctionReplyObject(m_dataNotificationObject.id);
} // end of updateObject()
//-----------------------------------------------------------------------------
Core::FunctionReplyObject ObjectNotification::deleteMessage(const DeleteMessage &data, int notificationId)
{
if (!isValid())
return Core::FunctionReplyObject(notificationId, tr_lts("dds", "Object not valid/blocked"));
Database::NomNotification dbDataNotification = toDbData(m_dataNotificationObject);
Database::NomAddress dbDataAddr;
for (const Address &recipientAddr : qAsConst(m_dataNotificationObject.recipientIds))
{
DEBUG_LOG(m_logger) << "recipientAddr="
<< ", id: " << recipientAddr.id << ", addressId: " << recipientAddr.addressId << ", isDeleted: " << recipientAddr.isDeleted;
if (data.operatorId > 0 && recipientAddr.addressType == AddressType::Operator && recipientAddr.addressId != data.operatorId)
continue;
if (data.workstationId > 0 && recipientAddr.addressType == AddressType::Workstation && recipientAddr.addressId != data.workstationId)
continue;
dbDataAddr = toDbData(recipientAddr);
dbDataAddr.notificationId = dbDataNotification.id;
break;
}
if (dbDataAddr.id <= 0)
return Core::FunctionReplyObject(data.addressId, tr_lts("dds", "No Address found"));
dbDataAddr.isDeleted = true;
DBTransaction trans(m_db->database());
if (!m_db->update(dbDataAddr))
return Core::FunctionReplyObject(dbDataAddr.id, tr_lts("dds", "Error updating address-data into database"));
trans.commit();
INFO_LOG(m_logger) << "Data changed for NotificationId: " << m_dataNotificationObject.id;
std::vector<Address> recipients = m_dataNotificationObject.recipientIds;
Address sender = m_dataNotificationObject.sender;
m_dataNotificationObject = toDdsData(dbDataNotification);
m_dataNotificationObject.sender = sender;
for (const Address &addr : qAsConst(recipients))
{
DEBUG_LOG(m_logger) << "addr="
<< ", id: " << addr.id << ", addressId: " << addr.addressId << ", isDeleted: " << addr.isDeleted;
if (addr.id == dbDataAddr.id)
m_dataNotificationObject.recipientIds.push_back(toDdsData(dbDataAddr));
else
m_dataNotificationObject.recipientIds.push_back(addr);
}
// Publish Data via DTS
onPublishData();
return Core::FunctionReplyObject(m_dataNotificationObject.id);
} // end of updateObject()
//-----------------------------------------------------------------------------
Core::FunctionReplyObject ObjectNotification::deleteObject(const DeleteMessage &data, int notificationId)
{
DEBUG_LOG(m_logger) << "ObjectNotification::deleteObject"
<< ", notificationId: " << notificationId << ", addressId: " << data.addressId << ", operatorId: " << data.operatorId
<< ", workstationId: " << data.workstationId;
deleteMessage(data, notificationId);
return Core::FunctionReplyObject(m_dataNotificationObject.id);
}
Core::FunctionReplyObject ObjectNotification::removeObject()
{
if (!m_db->removeNomNotification(m_dataNotificationObject.id))
return Core::FunctionReplyObject(m_dataNotificationObject.id, tr_lts("dds", "NomNotification with id %1 can not be removed from DB"))
.arg(m_dataNotificationObject.id);
if (!m_ddsHandler->dts()->removeNomNotificationByKey(m_dataNotificationObject.id))
return Core::FunctionReplyObject(m_dataNotificationObject.id, tr_lts("dds", "NomNotification with id %1 can not be removed from DDS"))
.arg(m_dataNotificationObject.id);
return Core::FunctionReplyObject(m_dataNotificationObject.id);
} // end of removeObject()
//-----------------------------------------------------------------------------
bool ObjectNotification::isValid() const { return m_dataNotificationObject.id > 0; } // end of isValid()
//-----------------------------------------------------------------------------
void ObjectNotification::onPublishData()
{
INFO_LOG(m_logger) << "Publish NomNotification-data to dds notificationId:" << m_dataNotificationObject.id;
if (!m_ddsHandler->dts()->publish(m_dataNotificationObject))
WARNING_LOG(m_logger) << "Error publishing NomNotification-data to dds";
} // end of onPublishData()
//-----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// convert methods
// ----------------------------------------------------------------------------
// NotificationManagement::NomNotification => Database::NomNotification
Database::NomNotification ObjectNotification::toDbData(const NomNotification &ddsData)
{
Database::NomNotification dbData;
dbData.id = ddsData.id;
dbData.exerciseId = ddsData.exerciseId;
dbData.content = QString::fromStdString(ddsData.content);
QString properties = contentArgsToJson();
dbData.properties = properties;
dbData.title = QString::fromStdString(ddsData.title);
dbData.messageType = ddsData.messageType;
dbData.notificationType = ddsData.notificationType;
dbData.processTime = ddsData.processTime;
dbData.processed = ddsData.processed;
dbData.processedPriority = ddsData.processedPriority;
dbData.expiryTime = ddsData.expiryTime;
dbData.priorityId = ddsData.priority;
dbData.timeStamp = ddsData.timeStamp;
return dbData;
} // end of toDbData()
//-----------------------------------------------------------------------------
// Database::NomNotification => NotificationManagement::NomNotification
NomNotification ObjectNotification::toDdsData(const Database::NomNotification &dbData)
{
NomNotification ddsData;
ddsData.id = dbData.id;
ddsData.content = dbData.content.toStdString();
std::vector< std::string > contentArgs = jsonToContentArgs(dbData.properties);
ddsData.contentArgs = contentArgs;
ddsData.title = dbData.title.toStdString();
ddsData.messageType = static_cast<NotificationManagement::MessageType>(dbData.messageType);
ddsData.notificationType = static_cast<NotificationManagement::NotificationType>(dbData.notificationType);
ddsData.timeStamp = dbData.timeStamp;
ddsData.priority = dbData.priorityId;
ddsData.exerciseId = dbData.exerciseId;
ddsData.expiryTime = dbData.expiryTime;
ddsData.processTime = dbData.processTime;
ddsData.processed = dbData.processed;
ddsData.processedPriority = dbData.processedPriority;
return ddsData;
} // end of toDdsData()
//-----------------------------------------------------------------------------
// NotificationManagement::Address => Database::NomAddress
Database::NomAddress ObjectNotification::toDbData(const Address &ddsData)
{
Database::NomAddress dbData;
dbData.id = ddsData.id;
dbData.addressId = ddsData.addressId;
dbData.addressSubId = ddsData.addressSubId;
dbData.addressSubSubId = ddsData.addressSubSubId;
dbData.addressTypeId = ddsData.addressType;
dbData.isRead = ddsData.isRead;
dbData.isDeleted = ddsData.isDeleted;
dbData.name = QString::fromStdString(ddsData.name);
return dbData;
} // end of toDbData()
//-----------------------------------------------------------------------------
// Database::NomAddress => NotificationManagement::Address
Address ObjectNotification::toDdsData(const Database::NomAddress &dbData)
{
Address ddsData;
ddsData.id = dbData.id;
ddsData.addressType = dbData.addressTypeId;
ddsData.name = dbData.name.toStdString();
ddsData.addressId = dbData.addressId;
ddsData.addressSubId = dbData.addressSubId;
ddsData.addressSubSubId = dbData.addressSubSubId;
ddsData.isRead = dbData.isRead;
ddsData.isDeleted = dbData.isDeleted;
return ddsData;
} // end of toDdsData()
//-----------------------------------------------------------------------------
} // namespace NotificationManagement