From ff6901e3a991e56f1c9409149cdc0095116281a1 Mon Sep 17 00:00:00 2001 From: "E. Kozlovskaya" Date: Tue, 5 Jan 2021 16:01:34 +0700 Subject: [PATCH] Add fully-functional administration panel for administrators and dispatchers --- iFacility/administrationpanel.cpp | 250 ++++++++++ iFacility/administrationpanel.h | 58 +++ iFacility/administrationpanel.ui | 444 ++++++++++++++++++ iFacility/iFacility.pro | 13 +- iFacility/loginwindow.cpp | 13 +- iFacility/loginwindow.h | 1 + iFacility/objects/profession.cpp | 4 + iFacility/objects/profession.h | 1 + iFacility/objects/user.cpp | 28 +- iFacility/objects/user.h | 2 + iFacility/objects/userprofession.cpp | 1 + iFacility/registrationdialog.cpp | 53 ++- iFacility/registrationdialog.h | 1 + iFacility/registrationdialog.ui | 84 +++- .../viewmodels/administrationviewmodel.cpp | 64 +++ .../viewmodels/administrationviewmodel.h | 27 ++ iFacility/viewmodels/professionsviewmodel.cpp | 46 ++ iFacility/viewmodels/professionsviewmodel.h | 18 + .../viewmodels/userprofessionviewmodel.cpp | 48 +- .../viewmodels/userprofessionviewmodel.h | 7 +- iFacility/viewmodels/workersviewmodel.cpp | 103 ++++ iFacility/viewmodels/workersviewmodel.h | 33 ++ 22 files changed, 1257 insertions(+), 42 deletions(-) create mode 100644 iFacility/administrationpanel.cpp create mode 100644 iFacility/administrationpanel.h create mode 100644 iFacility/administrationpanel.ui create mode 100644 iFacility/viewmodels/administrationviewmodel.cpp create mode 100644 iFacility/viewmodels/administrationviewmodel.h create mode 100644 iFacility/viewmodels/professionsviewmodel.cpp create mode 100644 iFacility/viewmodels/professionsviewmodel.h create mode 100644 iFacility/viewmodels/workersviewmodel.cpp create mode 100644 iFacility/viewmodels/workersviewmodel.h diff --git a/iFacility/administrationpanel.cpp b/iFacility/administrationpanel.cpp new file mode 100644 index 0000000..c8d6bbd --- /dev/null +++ b/iFacility/administrationpanel.cpp @@ -0,0 +1,250 @@ +#include "administrationpanel.h" +#include "ui_administrationpanel.h" + +AdministrationPanel::AdministrationPanel(QWidget *parent) : + QMainWindow(parent), ui(new Ui::AdministrationPanel) { + ui->setupUi(this); + + connect(this, &AdministrationPanel::invalidateTables, + this, &AdministrationPanel::onTablesInvalidation); + + avm = new AdministrationViewModel(this); + ui->administrationView->setModel(avm); + wvm = new WorkersViewModel(this); + ui->workersView->setModel(wvm); + pvm = new ProfessionsViewModel(this); + ui->professionsView->setModel(pvm); + + emit invalidateTables(); +} + +AdministrationPanel::~AdministrationPanel() { + delete ui; + + delete avm; + delete wvm; + delete pvm; +} + +void AdministrationPanel::setUser(User *user) { + mUser = user; + ui->user->setText(user->getFullNameShortForm()); + ui->administrationGroup->setVisible(user->getUserType() == UserType::ADMINISTRATOR); +} + +void AdministrationPanel::resizeEvent(QResizeEvent *event) { + int cellWidth = 60; + + ui->administrationView->setColumnWidth(0, cellWidth*4); + ui->administrationView->setColumnWidth(1, cellWidth*1); + ui->administrationView->setColumnWidth(2, cellWidth*4); + ui->administrationView->setColumnWidth(3, cellWidth*2); + + ui->workersView->setColumnWidth(0, cellWidth*4); + ui->workersView->setColumnWidth(1, cellWidth*1); + ui->workersView->setColumnWidth(2, cellWidth*4); + ui->workersView->setColumnWidth(3, cellWidth*4); + ui->workersView->setColumnWidth(4, cellWidth*4); + ui->workersView->setColumnWidth(5, cellWidth*4); + ui->workersView->setColumnWidth(6, cellWidth*4); + + QMainWindow::resizeEvent(event); +} + +void AdministrationPanel::doLogout() { + close(); +} + +void AdministrationPanel::addAdministration() { + QStringList items = { + "Administrator", + "Dispatcher" + }; + bool ok; + QString sel = QInputDialog::getItem(this, "Administration type", "", items, 0, false, &ok); + if (ok) { + UserType t = sel == "Administrator"? UserType::ADMINISTRATOR : UserType::DISPATCHER; + User *user = new User(); + RegistrationDialog rd(this); + rd.setEditMode(false); + rd.setUser(user); + rd.lockUserType(t); + rd.setWindowTitle("New administration"); + if (rd.exec() == RegistrationDialog::Accepted) { + Database::instance()->addUser(*user); + emit invalidateTables(); + return; + } + } + QMessageBox::critical(this, "Error", "Aborted by user"); +} + +void AdministrationPanel::addWorker() { + User *user = new User(); + RegistrationDialog rd(this); + rd.setEditMode(false); + rd.setUser(user); + rd.lockUserType(UserType::WORKER); + rd.setWindowTitle("New worker"); + if (rd.exec() == RegistrationDialog::Accepted) { + Database::instance()->addUser(*user); + emit invalidateTables(); + return; + } +} + +void AdministrationPanel::addProfession() { + QString title = QInputDialog::getText(this, "Input", "Profession title").trimmed(); + if (!title.isEmpty()) { + Profession p = Profession::createProfession(title); + bool ok = Database::instance()->addProfession(p); + if (ok) { + emit invalidateTables(); + } + else { + QMessageBox::critical(this, "Error", "You are trying to add the same job twice"); + } + return; + } + QMessageBox::critical(this, "Error", "Aborted by user"); +} + +void AdministrationPanel::editAdministration() { + auto rows = ui->administrationView->selectionModel()->selectedRows(); + if (rows.isEmpty() || rows.size() > 1) { + return; + } + UID aUID = avm->index(rows[0].row(), 0).data().toString(); + if (aUID == mUser->uID()) { + QMessageBox::critical(this, "Error", "You cannot edit yourself."); + return; + } + editUser(aUID); +} + +void AdministrationPanel::editWorker() { + auto rows = ui->workersView->selectionModel()->selectedRows(); + if (rows.isEmpty() || rows.size() > 1) { + return; + } + UID wUID = wvm->index(rows[0].row(), 0).data().toString(); + editUser(wUID); +} + +void AdministrationPanel::editUser(UID uid) { + User *user = Database::instance()->getUser(uid); + if (user == nullptr) { + QMessageBox::critical(this, "Error", "USer not found"); + return; + } + RegistrationDialog rd(this); + rd.setEditMode(true); + rd.setUser(user); + rd.lockUserType(user->getUserType()); + rd.setWindowTitle("Edit user"); + if (rd.exec() == RegistrationDialog::Accepted) { + Database::instance()->addUser(*user); + emit invalidateTables(); + } +} + +void AdministrationPanel::editProfession() { + QStringList professions; + foreach (auto prof, Database::instance()->professions()) { + professions << prof.title() + "|" + prof.pID().toString(); + } + if (professions.isEmpty()) { + QMessageBox::critical(this, "Error", "No professions found"); + return; + } + bool ok; + QString p = QInputDialog::getItem(this, "Choose profession", "Profession title", + professions, 0, false, &ok); + if (ok) { + PID pid = p.split("|").last(); + QString title = QInputDialog::getText(this, "Input", "New title").trimmed(); + if (!title.isEmpty()) { + Database::instance()->getProfession(pid)->setTitle(title); + emit invalidateTables(); + return; + } + } + QMessageBox::critical(this, "Error", "Aborted by user"); +} + +void AdministrationPanel::removeAdministration() { + auto rows = ui->administrationView->selectionModel()->selectedRows(); + if (rows.isEmpty()) { + return; + } + QMessageBox remconf(this); + remconf.setIcon(QMessageBox::Question); + remconf.setWindowTitle("Remove confirmation"); + remconf.setText("Are you sure you want to remove this worker?"); + remconf.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + remconf.setDefaultButton(QMessageBox::No); + if (remconf.exec() == QMessageBox::No) { + return; + } + for (int i = rows.size() - 1; i >= 0; i--) { + UID aUID = avm->index(rows[i].row(), 0).data().toString(); + if (aUID == mUser->uID()) { + QMessageBox::critical(this, "Error", "You cannot remove yourself."); + } + else { + Database::instance()->removeUser(aUID); + } + } + emit invalidateTables(); +} + +void AdministrationPanel::removeWorker() { + auto rows = ui->workersView->selectionModel()->selectedRows(); + if (rows.isEmpty()) { + return; + } + QMessageBox remconf(this); + remconf.setIcon(QMessageBox::Question); + remconf.setWindowTitle("Remove confirmation"); + remconf.setText("Are you sure you want to remove this worker?"); + remconf.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + remconf.setDefaultButton(QMessageBox::No); + if (remconf.exec() == QMessageBox::No) { + return; + } + for (int i = rows.size() - 1; i >= 0; i--) { + UID wUID = wvm->index(rows[i].row(), 0).data().toString(); + Database::instance()->removeUser(wUID); + } + emit invalidateTables(); +} + +void AdministrationPanel::removeProfession() { + QStringList professions; + foreach (auto prof, Database::instance()->professions()) { + professions << prof.title() + "|" + prof.pID().toString(); + } + if (professions.isEmpty()) { + QMessageBox::critical(this, "Error", "No professions found"); + return; + } + bool ok; + QString p = QInputDialog::getItem(this, "Choose profession", "Profession title", + professions, 0, false, &ok); + if (ok) { + PID pid = p.split("|").last(); + ok = Database::instance()->removeProfession(pid); + if (ok) { + emit invalidateTables(); + return; + } + } + QMessageBox::critical(this, "Error", "Aborted by user or " + "workers depend on selected profession"); +} + +void AdministrationPanel::onTablesInvalidation() { + avm->invalidateData(); + wvm->invalidateData(); + pvm->invalidateData(); +} diff --git a/iFacility/administrationpanel.h b/iFacility/administrationpanel.h new file mode 100644 index 0000000..fdcbad5 --- /dev/null +++ b/iFacility/administrationpanel.h @@ -0,0 +1,58 @@ +#ifndef ADMINISTRATIONPANEL_H +#define ADMINISTRATIONPANEL_H + +#include +#include +#include + +#include "objects/user.h" +#include "objects/profession.h" +#include "db/database.h" +#include "registrationdialog.h" +#include "viewmodels/administrationviewmodel.h" +#include "viewmodels/workersviewmodel.h" +#include "viewmodels/professionsviewmodel.h" + +namespace Ui { class AdministrationPanel; } + +class AdministrationPanel : public QMainWindow { +private: + Q_OBJECT + + Ui::AdministrationPanel *ui; + AdministrationViewModel *avm; + WorkersViewModel *wvm; + ProfessionsViewModel *pvm; + User *mUser; + +public: + explicit AdministrationPanel(QWidget *parent = nullptr); + ~AdministrationPanel(); + + void setUser(User *user); + +signals: + void invalidateTables(); + +public slots: + void resizeEvent(QResizeEvent *event); + + void doLogout(); + + void addAdministration(); + void addWorker(); + void addProfession(); + + void editAdministration(); + void editWorker(); + void editUser(UID uid); + void editProfession(); + + void removeAdministration(); + void removeWorker(); + void removeProfession(); + + void onTablesInvalidation(); +}; + +#endif // ADMINISTRATIONPANEL_H diff --git a/iFacility/administrationpanel.ui b/iFacility/administrationpanel.ui new file mode 100644 index 0000000..27e1bca --- /dev/null +++ b/iFacility/administrationpanel.ui @@ -0,0 +1,444 @@ + + + AdministrationPanel + + + + 0 + 0 + 808 + 679 + + + + + 0 + 0 + + + + + 808 + 503 + + + + + 808 + 679 + + + + MainWindow + + + + + + + + 0 + 0 + + + + Hello,**%user%** + + + Qt::MarkdownText + + + + + + + + 0 + 0 + + + + Logout + + + + + + + + 0 + 0 + + + + Aministration + + + + + + + 0 + 0 + + + + Remove + + + + + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + true + + + + + + + + 0 + 0 + + + + Add + + + + + + + + 0 + 0 + + + + Edit + + + + + + + + + + + 0 + 0 + + + + Workers + + + + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + true + + + + + + + + 0 + 0 + + + + Remove + + + + + + + + 0 + 0 + + + + Add + + + + + + + + 0 + 0 + + + + Edit + + + + + + + + + + + 0 + 0 + + + + Professions + + + + + + + 0 + 0 + + + + Remove + + + + + + + + 0 + 0 + + + + Add + + + + + + + + 0 + 0 + + + + Edit + + + + + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + true + + + + + + + + + + + + + btnLogout + clicked() + AdministrationPanel + doLogout() + + + 137 + 20 + + + 188 + 20 + + + + + btnAddAdministration + clicked() + AdministrationPanel + addAdministration() + + + 747 + 85 + + + 799 + 31 + + + + + btnEditAdministration + clicked() + AdministrationPanel + editAdministration() + + + 733 + 156 + + + 774 + 14 + + + + + btnRemoveAdministration + clicked() + AdministrationPanel + removeAdministration() + + + 740 + 198 + + + 762 + 7 + + + + + btnAddWorker + clicked() + AdministrationPanel + addWorker() + + + 751 + 305 + + + 698 + 28 + + + + + btnEditWorker + clicked() + AdministrationPanel + editWorker() + + + 743 + 352 + + + 652 + 13 + + + + + btnRemoveWorker + clicked() + AdministrationPanel + removeWorker() + + + 742 + 423 + + + 609 + 29 + + + + + btnAddProfession + clicked() + AdministrationPanel + addProfession() + + + 756 + 525 + + + 355 + 6 + + + + + btnEditProfession + clicked() + AdministrationPanel + editProfession() + + + 751 + 578 + + + 374 + 18 + + + + + btnRemoveProfession + clicked() + AdministrationPanel + removeProfession() + + + 762 + 625 + + + 446 + 11 + + + + + + doLogout() + addAdministration() + addWorker() + addProfession() + removeAdministration() + removeWorker() + removeProfession() + editAdministration() + editWorker() + editProfession() + + diff --git a/iFacility/iFacility.pro b/iFacility/iFacility.pro index 59fc8ac..3b9490a 100644 --- a/iFacility/iFacility.pro +++ b/iFacility/iFacility.pro @@ -9,6 +9,7 @@ CONFIG += c++11 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ + administrationpanel.cpp \ main.cpp \ loginwindow.cpp \ objects/profession.cpp \ @@ -16,18 +17,26 @@ SOURCES += \ objects/userprofession.cpp \ db/database.cpp \ registrationdialog.cpp \ - viewmodels/userprofessionviewmodel.cpp + viewmodels/administrationviewmodel.cpp \ + viewmodels/professionsviewmodel.cpp \ + viewmodels/userprofessionviewmodel.cpp \ + viewmodels/workersviewmodel.cpp HEADERS += \ + administrationpanel.h \ loginwindow.h \ objects/profession.h \ objects/user.h \ objects/userprofession.h \ db/database.h \ registrationdialog.h \ - viewmodels/userprofessionviewmodel.h + viewmodels/administrationviewmodel.h \ + viewmodels/professionsviewmodel.h \ + viewmodels/userprofessionviewmodel.h \ + viewmodels/workersviewmodel.h FORMS += \ + administrationpanel.ui \ loginwindow.ui \ registrationdialog.ui diff --git a/iFacility/loginwindow.cpp b/iFacility/loginwindow.cpp index c6eeb1c..0f44e4c 100644 --- a/iFacility/loginwindow.cpp +++ b/iFacility/loginwindow.cpp @@ -42,8 +42,17 @@ void LoginWindow::doLogin() { return; } - QMessageBox::information(this, "Info", "Success"); - // TODO: Open valid window + QWidget *w; + if (user->getUserType() == UserType::WORKER) { + QMessageBox::information(this, "Ok", "Ok"); + return; + } + else { + w = new AdministrationPanel(); + ((AdministrationPanel*)w)->setUser(user); + } + w->show(); + close(); } void LoginWindow::validateForm() { diff --git a/iFacility/loginwindow.h b/iFacility/loginwindow.h index 0542915..8bfda66 100644 --- a/iFacility/loginwindow.h +++ b/iFacility/loginwindow.h @@ -8,6 +8,7 @@ #include "db/database.h" #include "registrationdialog.h" +#include "administrationpanel.h" QT_BEGIN_NAMESPACE namespace Ui { class LoginWindow; } diff --git a/iFacility/objects/profession.cpp b/iFacility/objects/profession.cpp index d0eeec9..9f47a0a 100644 --- a/iFacility/objects/profession.cpp +++ b/iFacility/objects/profession.cpp @@ -4,6 +4,10 @@ QString Profession::title() const { return mTitle; } +void Profession::setTitle(const QString &newTitle) { + mTitle = newTitle; +} + PID Profession::pID() const { return mPID; } diff --git a/iFacility/objects/profession.h b/iFacility/objects/profession.h index 08e1310..7e13770 100644 --- a/iFacility/objects/profession.h +++ b/iFacility/objects/profession.h @@ -16,6 +16,7 @@ public: Profession() = default; QString title() const; + void setTitle(const QString &newTitle); PID pID() const; static Profession createProfession(const QString &title); diff --git a/iFacility/objects/user.cpp b/iFacility/objects/user.cpp index 9fc427f..8580705 100644 --- a/iFacility/objects/user.cpp +++ b/iFacility/objects/user.cpp @@ -29,6 +29,14 @@ QString User::patronymic() const { return mPatronymic; } +QString User::getFullName() const { + return QString("%1 %2 %3").arg(mSecondName).arg(mFirstName).arg(mPatronymic); +} + +QString User::getFullNameShortForm() const { + return QString("%1 %2.%3.").arg(mSecondName).arg(mFirstName[0]).arg(mPatronymic[0]); +} + ProfessionsList User::getProfessions() const { return mProfessions; } @@ -69,11 +77,9 @@ bool User::addProfession(PID pid, ProfRank rank) { if (mProfessions.size() >= 4) { if (mCurrentProfession == mProfessions[0].getProfession()) { - mProfessions.remove(1); - } - else { - mProfessions.remove(0); + return false; } + mProfessions.remove(0); } UserProfession up(pid, rank); @@ -91,12 +97,14 @@ bool User::setCurrentProfession(PID pid) { } void User::removeProfession(PID pid) { - auto pred = [pid](UserProfession p) { - return p.getProfession() == pid; - }; - - mProfessions.erase(std::remove_if(mProfessions.begin(), mProfessions.end(), pred), - mProfessions.end()); + auto pred = [pid](UserProfession p) { return p.getProfession() == pid; }; + if (pid == mCurrentProfession) { + mCurrentProfession = 0; + } + mProfessions.erase( + std::remove_if(mProfessions.begin(), mProfessions.end(), pred), + mProfessions.end() + ); } bool operator==(const User &l, const User &r) { diff --git a/iFacility/objects/user.h b/iFacility/objects/user.h index d17b241..e7aedbe 100644 --- a/iFacility/objects/user.h +++ b/iFacility/objects/user.h @@ -42,6 +42,8 @@ public: QString firstName() const; QString secondName() const; QString patronymic() const; + QString getFullName() const; + QString getFullNameShortForm() const; ProfessionsList getProfessions() const; PID getCurrentProfession() const; diff --git a/iFacility/objects/userprofession.cpp b/iFacility/objects/userprofession.cpp index d29558c..2ef4cf5 100644 --- a/iFacility/objects/userprofession.cpp +++ b/iFacility/objects/userprofession.cpp @@ -3,6 +3,7 @@ UserProfession::UserProfession(PID pid, ProfRank rank) { mProfession = pid; mRank = rank; + mAcquired = QDate::currentDate(); } PID UserProfession::getProfession() const { diff --git a/iFacility/registrationdialog.cpp b/iFacility/registrationdialog.cpp index facfcf4..e98cdff 100644 --- a/iFacility/registrationdialog.cpp +++ b/iFacility/registrationdialog.cpp @@ -7,6 +7,23 @@ RegistrationDialog::RegistrationDialog(QWidget *parent) : upvm = new UserProfessionViewModel(this); ui->userProfessions->setModel(upvm); + + connect(ui->userProfessions->selectionModel(), + &QItemSelectionModel::selectionChanged, + this, + [this]() { + auto rows = ui->userProfessions->selectionModel()->selectedRows(); + ui->btnSetProfessionCurrent->setEnabled(rows.size() == 1); + ui->btnRemoveProfession->setEnabled(rows.size() >= 1); + } + ); + + connect(ui->userGroup, + QOverload::of(&QComboBox::currentIndexChanged), + [this](int newIdx) { + ui->professionsGroup->setVisible((UserType)newIdx == UserType::WORKER); + } + ); } RegistrationDialog::~RegistrationDialog() { @@ -18,10 +35,12 @@ RegistrationDialog::~RegistrationDialog() { void RegistrationDialog::lockUserType(UserType type) { ui->userGroup->setCurrentIndex((int)type); ui->userGroup->setEnabled(false); + ui->professionsGroup->setVisible(type == UserType::WORKER); } void RegistrationDialog::setUser(User *usr) { user = usr; + upvm->setUser(user); if (mEditMode) { ui->firstName->setText(user->firstName()); @@ -33,7 +52,6 @@ void RegistrationDialog::setUser(User *usr) { ui->password->setEnabled(usr->getUserType() == UserType::ADMINISTRATOR); ui->userGroup->setCurrentIndex((int)user->getUserType()); ui->userGroup->setEnabled(false); - upvm->setProfessionsList(user->getProfessions()); } } @@ -63,6 +81,8 @@ void RegistrationDialog::accept() { } else { auto u = User::createUser(login, pass, type, fname, sname, patr); + u->mProfessions = user->mProfessions; + u->setCurrentProfession(user->getCurrentProfession()); std::swap(*user, *u); delete u; } @@ -87,12 +107,39 @@ void RegistrationDialog::addNewProfession() { int r = QInputDialog::getInt(this, "Profession rank", "", 1, 1, 2e5, 1, &ok); if (ok) { user->addProfession(pid, r); + upvm->invalidateData(); return; } } QMessageBox::critical(this, "Error", "Aborted by user or selected non-existant profession"); } -void RegistrationDialog::removeOldProfession() { - +void RegistrationDialog::setCurrentProfession() { + auto rows = ui->userProfessions->selectionModel()->selectedRows(); + if (rows.isEmpty() || rows.size() > 1) { + return; + } + auto uProf = user->getProfessions()[rows[0].row()]; + user->setCurrentProfession(uProf.getProfession()); + upvm->invalidateData(); +} + +void RegistrationDialog::removeOldProfession() { + auto rows = ui->userProfessions->selectionModel()->selectedRows(); + if (rows.isEmpty()) { + return; + } + QMessageBox remconf(this); + remconf.setIcon(QMessageBox::Question); + remconf.setWindowTitle("Remove confirmation"); + remconf.setText("Are you sure you want to remove this profession?"); + remconf.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + remconf.setDefaultButton(QMessageBox::No); + if (remconf.exec() == QMessageBox::No) { + return; + } + for (int i = rows.size() - 1; i >= 0; i--) { + user->removeProfession(user->getProfessions()[rows[i].row()].getProfession()); + } + upvm->invalidateData(); } diff --git a/iFacility/registrationdialog.h b/iFacility/registrationdialog.h index 7166bf5..5b757b3 100644 --- a/iFacility/registrationdialog.h +++ b/iFacility/registrationdialog.h @@ -31,6 +31,7 @@ public slots: void accept() Q_DECL_OVERRIDE; void addNewProfession(); + void setCurrentProfession(); void removeOldProfession(); }; diff --git a/iFacility/registrationdialog.ui b/iFacility/registrationdialog.ui index 140de4e..2f082fb 100644 --- a/iFacility/registrationdialog.ui +++ b/iFacility/registrationdialog.ui @@ -28,6 +28,12 @@ + + + 0 + 0 + + Full name @@ -58,6 +64,12 @@ + + + 0 + 0 + + Login data @@ -84,6 +96,12 @@ + + + 0 + 0 + + User type @@ -111,14 +129,11 @@ - + Professions - - - @@ -132,7 +147,20 @@ - + + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + true + + + + @@ -145,9 +173,38 @@ + + + + false + + + + 0 + 0 + + + + Set current + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -232,9 +289,26 @@ + + btnSetProfessionCurrent + clicked() + RegistrationDialog + setCurrentProfession() + + + 591 + 286 + + + 100 + 183 + + + addNewProfession() removeOldProfession() + setCurrentProfession() diff --git a/iFacility/viewmodels/administrationviewmodel.cpp b/iFacility/viewmodels/administrationviewmodel.cpp new file mode 100644 index 0000000..a4e6829 --- /dev/null +++ b/iFacility/viewmodels/administrationviewmodel.cpp @@ -0,0 +1,64 @@ +#include "administrationviewmodel.h" + +AdministrationViewModel::AdministrationViewModel(QObject *parent) : QAbstractTableModel(parent) { + +} + +int AdministrationViewModel::rowCount(const QModelIndex &/*parent*/) const { + return mUserData.length(); +} + +int AdministrationViewModel::columnCount(const QModelIndex &/*parent*/) const { + return 4; +} + +QVariant AdministrationViewModel::headerData(int section, Qt::Orientation orientation, + int role) const { + if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { + switch (section) { + case 0: + return QString("UID"); + case 1: + return QString("Login"); + case 2: + return QString("Full name"); + case 3: + return QString("Status"); + } + } + return QVariant(); +} + +QVariant AdministrationViewModel::data(const QModelIndex &index, int role) const { + if (role == Qt::DisplayRole) { + auto usr = mUserData[index.row()]; + + int col = index.column(); + switch (col) { + case 0: + return usr.uID(); + case 1: + return usr.getLogin(); + case 2: + return usr.getFullName(); + case 3: + return usr.getUserType() == UserType::ADMINISTRATOR? "Administrator" : "Dispatcher"; + } + + return "UNKNOWN FIELD"; + } + + return QVariant(); +} + +void AdministrationViewModel::invalidateData() { + beginResetModel(); + mUserData.clear(); + foreach (auto u, Database::instance()->getUsersByType(UserType::ADMINISTRATOR)) { + mUserData += *u; + } + foreach (auto u, Database::instance()->getUsersByType(UserType::DISPATCHER)) { + mUserData += *u; + } + endResetModel(); +} diff --git a/iFacility/viewmodels/administrationviewmodel.h b/iFacility/viewmodels/administrationviewmodel.h new file mode 100644 index 0000000..4a2e5f1 --- /dev/null +++ b/iFacility/viewmodels/administrationviewmodel.h @@ -0,0 +1,27 @@ +#ifndef ADMINISTRATIONVIEWMODEL_H +#define ADMINISTRATIONVIEWMODEL_H + +#include +#include + +#include "../objects/user.h" +#include "../db/database.h" + +class AdministrationViewModel : public QAbstractTableModel { +private: + Q_OBJECT + + QVector mUserData; + +public: + AdministrationViewModel(QObject *parent); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + + void invalidateData(); +}; + +#endif // ADMINISTRATIONVIEWMODEL_H diff --git a/iFacility/viewmodels/professionsviewmodel.cpp b/iFacility/viewmodels/professionsviewmodel.cpp new file mode 100644 index 0000000..cb5960c --- /dev/null +++ b/iFacility/viewmodels/professionsviewmodel.cpp @@ -0,0 +1,46 @@ +#include "professionsviewmodel.h" + +ProfessionsViewModel::ProfessionsViewModel(QObject *parent) : QStandardItemModel(parent) { + +} + +void ProfessionsViewModel::invalidateData() { + beginResetModel(); + + clear(); + QStandardItemModel::setHeaderData(0, Qt::Orientation::Horizontal, "Professions"); + QStandardItem *rootNode = invisibleRootItem(); + foreach (auto prof, Database::instance()->professions()) { + QStandardItem *profNode = new QStandardItem("Profession: " + prof.title()); + QStandardItem *profUID = new QStandardItem("PID: " + prof.pID().toString()); + QStandardItem *currentWorkers = new QStandardItem("Current workers"); + QStandardItem *availableWorkers = new QStandardItem("Available workers"); + foreach(auto worker, Database::instance()->getUsersByProfession(prof.pID())) { + QStandardItem *workerNode = new QStandardItem(worker->getFullNameShortForm()); + UserProfession up; + foreach (auto uProf, worker->getProfessions()) { + if (uProf.getProfession() == prof.pID()) { + up = uProf; + } + } + QStandardItem *workerRank = new QStandardItem(tr("%1 rank").arg(up.getRank())); + QStandardItem *acqDateNode = new QStandardItem( + up.getAcquiredDate().toString(Qt::DateFormat::SystemLocaleShortDate)); + workerNode->appendRow(workerRank); + workerNode->appendRow(acqDateNode); + if (worker->getCurrentProfession() == prof.pID()) { + currentWorkers->appendRow(workerNode); + } + else { + availableWorkers->appendRow(workerNode); + } + } + + profNode->appendRow(profUID); + profNode->appendRow(currentWorkers); + profNode->appendRow(availableWorkers); + rootNode->appendRow(profNode); + } + + endResetModel(); +} diff --git a/iFacility/viewmodels/professionsviewmodel.h b/iFacility/viewmodels/professionsviewmodel.h new file mode 100644 index 0000000..5cee9fc --- /dev/null +++ b/iFacility/viewmodels/professionsviewmodel.h @@ -0,0 +1,18 @@ +#ifndef PROFESSIONSVIEMODEL_H +#define PROFESSIONSVIEMODEL_H + +#include + +#include "../db/database.h" + +class ProfessionsViewModel : public QStandardItemModel { +private: + Q_OBJECT + +public: + ProfessionsViewModel(QObject *parent); + + void invalidateData(); +}; + +#endif // PROFESSIONSVIEMODEL_H diff --git a/iFacility/viewmodels/userprofessionviewmodel.cpp b/iFacility/viewmodels/userprofessionviewmodel.cpp index 6ac951d..8134856 100644 --- a/iFacility/viewmodels/userprofessionviewmodel.cpp +++ b/iFacility/viewmodels/userprofessionviewmodel.cpp @@ -5,7 +5,7 @@ UserProfessionViewModel::UserProfessionViewModel(QObject *parent) : QAbstractTab } int UserProfessionViewModel::rowCount(const QModelIndex &/*parent*/) const { - return mProfList.length(); + return mUser != nullptr? mUser->getProfessions().length() : 0; } int UserProfessionViewModel::columnCount(const QModelIndex &/*parent*/) const { @@ -16,41 +16,53 @@ QVariant UserProfessionViewModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { switch (section) { - case 0: - return QString("Profession"); - case 1: - return QString("Date of acquirement"); - case 2: - return QString("Rank"); + case 0: + return QString("Profession"); + case 1: + return QString("Date of acquirement"); + case 2: + return QString("Rank"); } } return QVariant(); } QVariant UserProfessionViewModel::data(const QModelIndex &index, int role) const { + auto profs = mUser->getProfessions(); + auto uProf = profs[index.row()]; + if (role == Qt::DisplayRole) { - auto item = mProfList[index.row()]; - auto prof = Database::instance()->getProfession(item.getProfession()); + auto prof = Database::instance()->getProfession(uProf.getProfession()); int col = index.column(); switch (col) { - case 0: - return prof == nullptr? "ERROR:UNKNOWN" : prof->title(); - case 1: - return item.getAcquiredDate(); - case 2: - return item.getRank(); + case 0: + return prof == nullptr? "#ERROR!" : prof->title(); + case 1: + return uProf.getAcquiredDate().toString(Qt::DateFormat::SystemLocaleShortDate); + case 2: + return uProf.getRank(); } return "UNKNOWN FIELD"; } + else if (role == Qt::FontRole) { + if (uProf.getProfession() == mUser->getCurrentProfession()) { + QFont f; + f.setBold(true); + return f; + } + } return QVariant(); } -void UserProfessionViewModel::setProfessionsList(const ProfessionsList &profList) { +void UserProfessionViewModel::setUser(User *user) { + mUser = user; + invalidateData(); +} + +void UserProfessionViewModel::invalidateData() { beginResetModel(); - mProfList.clear(); - mProfList += profList; endResetModel(); } diff --git a/iFacility/viewmodels/userprofessionviewmodel.h b/iFacility/viewmodels/userprofessionviewmodel.h index 355beab..110b2eb 100644 --- a/iFacility/viewmodels/userprofessionviewmodel.h +++ b/iFacility/viewmodels/userprofessionviewmodel.h @@ -2,6 +2,7 @@ #define USERPROFESSIONVIEWMODEL_H #include +#include #include "../objects/user.h" #include "../db/database.h" @@ -10,16 +11,18 @@ class UserProfessionViewModel : public QAbstractTableModel { private: Q_OBJECT - ProfessionsList mProfList; + User *mUser = nullptr; public: UserProfessionViewModel(QObject *parent); + int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - void setProfessionsList(const ProfessionsList &profList); + void setUser(User *user); + void invalidateData(); }; #endif // USERPROFESSIONVIEWMODEL_H diff --git a/iFacility/viewmodels/workersviewmodel.cpp b/iFacility/viewmodels/workersviewmodel.cpp new file mode 100644 index 0000000..35d297f --- /dev/null +++ b/iFacility/viewmodels/workersviewmodel.cpp @@ -0,0 +1,103 @@ +#include "workersviewmodel.h" + +WorkersViewModel::WorkersViewModel(QObject *parent) : QAbstractTableModel(parent) { + +} + +int WorkersViewModel::rowCount(const QModelIndex &/*parent*/) const { + return mUserData.length(); +} + +int WorkersViewModel::columnCount(const QModelIndex &/*parent*/) const { + return 7; +} + +QVariant WorkersViewModel::headerData(int section, Qt::Orientation orientation, int role) const { + if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { + switch (section) { + case 0: + return QString("UID"); + case 1: + return QString("Login"); + case 2: + return QString("Full name"); + case 3: + return QString("First profession"); + case 4: + return QString("Second profession"); + case 5: + return QString("Third profession"); + case 6: + return QString("Fourth profession"); + } + } + return QVariant(); +} + +QString WorkersViewModel::getProfessionAt(const User &user, int pIdx) const { + auto profs = user.getProfessions(); + QString out = ""; + if (profs.size() >= pIdx + 1) { + auto p = Database::instance()->getProfession(profs[pIdx].getProfession()); + out = tr("%1 (%2 rank)").arg(p->title()).arg(profs[pIdx].getRank()); + } + return out; +} + +bool WorkersViewModel::shouldBeBold(const QModelIndex &index) const { + int col = index.column(); + if (col < 3) { + return false; + } + auto usr = mUserData[index.row()]; + if (!getProfessionAt(usr, col-3).isEmpty()) { + if (usr.getProfessions()[col-3].getProfession() == usr.getCurrentProfession()) { + return true; + } + } + return false; +} + +QVariant WorkersViewModel::data(const QModelIndex &index, int role) const { + if (role == Qt::DisplayRole) { + auto usr = mUserData[index.row()]; + auto profs = usr.getProfessions(); + + int col = index.column(); + switch (col) { + case 0: + return usr.uID(); + case 1: + return usr.getLogin(); + case 2: + return usr.getFullName(); + case 3: + return getProfessionAt(usr, 0); + case 4: + return getProfessionAt(usr, 1); + case 5: + return getProfessionAt(usr, 2); + case 6: + return getProfessionAt(usr, 3); + } + + return "UNKNOWN FIELD"; + } + else if (role == Qt::FontRole) { + if (shouldBeBold(index)) { + QFont f; + f.setBold(true); + return f; + } + } + return QVariant(); +} + +void WorkersViewModel::invalidateData() { + beginResetModel(); + mUserData.clear(); + foreach (auto u, Database::instance()->getUsersByType(UserType::WORKER)) { + mUserData += *u; + } + endResetModel(); +} diff --git a/iFacility/viewmodels/workersviewmodel.h b/iFacility/viewmodels/workersviewmodel.h new file mode 100644 index 0000000..1844ee7 --- /dev/null +++ b/iFacility/viewmodels/workersviewmodel.h @@ -0,0 +1,33 @@ +#ifndef WORKERSVIEWMODEL_H +#define WORKERSVIEWMODEL_H + +#include +#include +#include +#include +#include + +#include "../objects/user.h" +#include "../db/database.h" + +class WorkersViewModel : public QAbstractTableModel { +private: + Q_OBJECT + + QVector mUserData; + + QString getProfessionAt(const User &user, int pIdx) const; + bool shouldBeBold(const QModelIndex &index) const; + +public: + WorkersViewModel(QObject *parent); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + + void invalidateData(); +}; + +#endif // WORKERSVIEWMODEL_H