/** * Handler for report Sanitation Material * $Id$ * $HeadURL$ * $Author$ * Created by Hanna E. Rathje, SLSE, 2016-12-20 */ #include "handler_report_data.h" #include #include #include using namespace ReportManagement; // ------------------------------------------------------------------------------------------------------------------ bool HandlerReportData::generateSanitationMaterialResult(const CreateModifyReportRequest &request, int reportId) { INFO_LOG(m_logger) << "Start generateSanitationMaterialResult "; DBTransaction trans(m_db->database()); NSqlQuery qInsert(m_db->database()); NSqlQuery qSelect(m_db->database()); NSqlQuery qDelete(m_db->database()); // find all sanitation unique ids QSet sanitationIds; QString stmt = QLatin1String("SELECT DISTINCT sanitation_unique_id FROM rep_sanitation_material_data " " WHERE (event_time BETWEEN ") + QString::number(request.startTime()) + QLatin1String(" AND ") + QString::number(request.endTime()) + QLatin1String(") "); stmt += QLatin1String(" AND material_id != 0 "); if (request.chargeTypeIds().size() > 0) { const QString chargeTypeIds = intVecToString(request.chargeTypeIds()); stmt += QLatin1String(" AND (material_id IN (") + chargeTypeIds + QLatin1String("))"); } if (request.participantIds().size() > 0) { const QString participants = intVecToString(request.participantIds()); stmt += QStringLiteral(" AND participant_id IN (%1)").arg(participants); } //TODO: read from TAB or PPM enum. Skip qualification 0 = NotAsigned const QSet qualifications = {1,2,3}; stmt += QLatin1String(" AND qualification IN (1,2,3) "); DEBUG_LOG(m_logger) << " stmt: " << stmt; if (!qSelect.exec(stmt)) { ERROR_LOG(m_logger) << "Couldn't select sanitation unique ids "; return false; } while (qSelect.next()) sanitationIds += qSelect.value(0).toInt(); if (sanitationIds.isEmpty()) { DEBUG_LOG(m_logger) << "No available sanitation unique ids for this report"; return true; } qInsert.prepare(QLatin1String("INSERT INTO rep_sanitation_material_result (report_id, sanitation_unique_id, qualification, material_id ) VALUES (:reportId, :uqId, :qualif, :materialId )")); qInsert.bindValue(QLatin1String(":reportId"), reportId); for (qint64 sanitationId : qAsConst(sanitationIds)) { qInsert.bindValue(QLatin1String(":uqId"), sanitationId); for (int qualif : qualifications) { qInsert.bindValue(QLatin1String(":qualif"), qualif); for (auto it = request.chargeTypeIds().begin(); it != request.chargeTypeIds().end(); ++it) { int materialId = *it; if (materialId == 0) continue; // skip 0 qInsert.bindValue(QLatin1String(":materialId"), materialId); if (!qInsert.exec()) { ERROR_LOG(m_logger) << "Error inserting report id, sanitationUniqueId, qualif, materialId = " << reportId << " , " << sanitationId << " , " << qualif << " , "<< materialId; return false; } if (!calculateSanitationMaterialStock(sanitationId, materialId, request.startTime(), request.endTime(), request.partyId(), reportId, qualif)) return false; } } } // delete empty records qDelete.prepare(QLatin1String("DELETE FROM rep_sanitation_material_result WHERE report_id = :reportId AND amount_start = 0 AND amount_resupplied = 0 AND amount_end = 0 AND amount_used = 0")); qDelete.bindValue(QLatin1String(":reportId"), reportId); if (!qDelete.exec()) WARNING_LOG(m_logger) << "Couldn't delete empty records "; trans.commit(); INFO_LOG(m_logger) << " END generateSanitationMaterialResult"; return true; } // ------------------------------------------------------------------------------------------------------------------ bool HandlerReportData::calculateSanitationMaterialStock(int uniqueId, int materialId, qint64 startTime, qint64 endTime, int partyId, int reportId, int qualif) { SanitationMaterialData sanMatData; sanMatData.uniqueId = uniqueId; sanMatData.materialId = materialId; sanMatData.qualification = qualif; NSqlQuery qSelect(m_db->database()); NSqlQuery qInit(m_db->database()); NSqlQuery qUpdate(m_db->database()); QString stmt = QLatin1String("SELECT material_amount, event_time, material_id, sanitation_unique_id, qualification " " FROM rep_sanitation_material_data " " WHERE event_time > 0 AND event_time < ") + QString::number(startTime) + QLatin1String(" AND party_id = ") + QString::number(partyId) + QLatin1String(" AND material_id = ") + QString::number(materialId) + QLatin1String(" AND sanitation_unique_id = ") + QString::number(uniqueId) + QLatin1String(" AND qualification = ") + QString::number(qualif) + QLatin1String(" ORDER BY event_time DESC LIMIT 1"); DEBUG_LOG(m_logger) << "Start Statement: " << stmt; if (!qInit.exec(stmt)) { ERROR_LOG(m_logger) << "Error while selecting start-data for materialId, uniqueId " << materialId << ", " << uniqueId << ", qualification " << qualif << ", stmt='" << stmt << "'"; return false; } if (!qInit.next()) // not found a valid record { INFO_LOG(m_logger) << "No start entry for materialId = " << materialId << ", sanitation id = " << uniqueId << ", qualification = " << qualif <<" -> assuming 0"; //return true; sanMatData.amount = 0; sanMatData.amountStart = 0; sanMatData.used = 0; sanMatData.resupplied = 0; sanMatData.duration = 0; } else { qInit.first(); sanMatData.amount = qInit.value(0).toInt(); sanMatData.amountStart = sanMatData.amount; sanMatData.used = 0; sanMatData.resupplied = 0; sanMatData.duration = 0; } DEBUG_LOG(m_logger) << "START materialId = " << QString::number(materialId) << " , " << "sanitation id " << uniqueId << ", qualification " << qualif << " amountStart = " << sanMatData.amountStart; stmt = QLatin1String("SELECT material_amount, event_time FROM rep_sanitation_material_data " " WHERE event_time >= ") + QString::number(startTime) + QLatin1String(" AND event_time <= ") + QString::number(endTime) + QLatin1String(" AND party_id = ") + QString::number(partyId) + QLatin1String(" AND material_id = ") + QString::number(materialId) + QLatin1String(" AND sanitation_unique_id = ") + QString::number(uniqueId) + QLatin1String(" AND qualification = ") + QString::number(qualif) + QLatin1String(" ORDER BY event_time "); if (!qSelect.exec(stmt)) { ERROR_LOG(m_logger) << "Error while selecting data for materialId " << materialId << ", sanitation id " << uniqueId << ", qualification " << qualif; return false; } DEBUG_LOG(m_logger) << "Select statement: " << stmt; int amount = 0; int amountOld = sanMatData.amountStart; int duration = 0; long long lastTime = 0; if (amountOld == 0) lastTime = startTime; while (qSelect.next()) { amount = qSelect.value(0).toInt(); long long crtTime = qSelect.value(1).toLongLong(); if (amount == 0 || amountOld == 0) { duration += crtTime - lastTime; DEBUG_LOG(m_logger) << "## Adding (" << crtTime << " - " << lastTime << ") = " << crtTime - lastTime; DEBUG_LOG(m_logger) << "## New duration = " << duration; } int diff = amount - amountOld; if (diff > 0) sanMatData.resupplied += diff; else if (diff < 0) sanMatData.used += qAbs(diff); amountOld = amount; lastTime = crtTime; } sanMatData.amount = amount; sanMatData.duration = duration; DEBUG_LOG(m_logger) << "UPDATING stock for materialId: " << materialId << ", sanitation id " << uniqueId << ", qualification " << qualif; stmt = QLatin1String("UPDATE rep_sanitation_material_result SET " " amount_start = ") + QString::number(sanMatData.amountStart) + QLatin1String(", ") + QLatin1String(" amount_resupplied = ") + QString::number(sanMatData.resupplied) + QLatin1String(", ") + QLatin1String(" amount_end = ") + QString::number(sanMatData.amount) + QLatin1String(", ") + QLatin1String(" amount_used = ") + QString::number(sanMatData.used) + QLatin1String(", ") + QLatin1String(" duration = ") + QString::number(sanMatData.duration) + QLatin1String(" WHERE report_id = ") + QString::number(reportId) + QLatin1String(" AND material_id = ") + QString::number(sanMatData.materialId) + QLatin1String(" AND sanitation_unique_id = ") + QString::number(sanMatData.uniqueId) + QLatin1String(" AND qualification = ") + QString::number(sanMatData.qualification); DEBUG_LOG(m_logger) << "Update statement: " << stmt; if (!qUpdate.exec(stmt)) { ERROR_LOG(m_logger) << "Error while updating stock for materialId, uniqueId, qualification " << materialId << ", " << uniqueId << ", " << qualif; return false; } return true; }