Converts accessor calls to plain member access across the residual service set.
428 lines
16 KiB
C++
Executable File
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
|