Initial commit: Kareer, a Kirigami job application tracker
C++/Qt6/KDE Frameworks 6 app with a SQLite-backed data layer, a Sankey-diagram dashboard, and a full CLI (add/list/show/update/stage/ delete/stats/stages) for scripting from other tools.
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
#include "statsmodel.h"
|
||||
#include "jobstage.h"
|
||||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
StatsModel::StatsModel(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
refresh();
|
||||
}
|
||||
|
||||
void StatsModel::refresh()
|
||||
{
|
||||
m_jobs = m_db.allJobs();
|
||||
Q_EMIT changed();
|
||||
}
|
||||
|
||||
int StatsModel::totalApplications() const
|
||||
{
|
||||
return m_jobs.size();
|
||||
}
|
||||
|
||||
int StatsModel::activeApplications() const
|
||||
{
|
||||
int count = 0;
|
||||
for (const Job &job : m_jobs) {
|
||||
if (!JobStage::isTerminal(job.stage)) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int StatsModel::offerCount() const
|
||||
{
|
||||
int count = 0;
|
||||
for (const Job &job : m_jobs) {
|
||||
if (job.stage == QLatin1String("Offer") || job.stage == QLatin1String("Accepted")) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int StatsModel::acceptedCount() const
|
||||
{
|
||||
int count = 0;
|
||||
for (const Job &job : m_jobs) {
|
||||
if (job.stage == QLatin1String("Accepted")) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int StatsModel::rejectedCount() const
|
||||
{
|
||||
int count = 0;
|
||||
for (const Job &job : m_jobs) {
|
||||
if (job.stage == QLatin1String("Rejected")) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
double StatsModel::responseRate() const
|
||||
{
|
||||
if (m_jobs.isEmpty()) {
|
||||
return 0.0;
|
||||
}
|
||||
int responded = 0;
|
||||
for (const Job &job : m_jobs) {
|
||||
if (job.stage != QLatin1String("Applied")) {
|
||||
++responded;
|
||||
}
|
||||
}
|
||||
return 100.0 * responded / m_jobs.size();
|
||||
}
|
||||
|
||||
double StatsModel::offerRate() const
|
||||
{
|
||||
if (m_jobs.isEmpty()) {
|
||||
return 0.0;
|
||||
}
|
||||
return 100.0 * offerCount() / m_jobs.size();
|
||||
}
|
||||
|
||||
QVariantMap StatsModel::stageCounts() const
|
||||
{
|
||||
QVariantMap counts;
|
||||
for (const QString &stage : JobStage::canonicalStages()) {
|
||||
counts.insert(stage, 0);
|
||||
}
|
||||
for (const Job &job : m_jobs) {
|
||||
counts[job.stage] = counts.value(job.stage, 0).toInt() + 1;
|
||||
}
|
||||
return counts;
|
||||
}
|
||||
Reference in New Issue
Block a user