diff --git a/src/blackcore/webdataservices.cpp b/src/blackcore/webdataservices.cpp index be248bd17..62d03f345 100644 --- a/src/blackcore/webdataservices.cpp +++ b/src/blackcore/webdataservices.cpp @@ -539,6 +539,23 @@ namespace BlackCore return 0; } + CStatusMessageList CWebDataServices::validateForPublishing(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels) const + { + CStatusMessageList msgs(models.validateForPublishing(validModels, invalidModels)); + + // check against existing distributors + const CDistributorList distributors(this->getDistributors()); + if (!distributors.isEmpty()) + { + // only further check the valid ones + CAircraftModelList newValidModels; + CStatusMessageList msgsDistributos(validModels.validateDistributors(distributors, newValidModels, invalidModels)); + validModels = newValidModels; + msgs.push_back(msgsDistributos); + } + return msgs; + } + CAirlineIcaoCodeList CWebDataServices::getAirlineIcaoCodesForDesignator(const QString &designator) const { if (m_icaoDataReader) { return m_icaoDataReader->getAirlineIcaoCodesForDesignator(designator); } diff --git a/src/blackcore/webdataservices.h b/src/blackcore/webdataservices.h index dc7669d04..a82dda3ef 100644 --- a/src/blackcore/webdataservices.h +++ b/src/blackcore/webdataservices.h @@ -294,6 +294,10 @@ namespace BlackCore //! \threadsafe int getMetarsCount() const; + //! Validate for publishing + //! \remark More detailed check than BlackMisc::Simulation::CAircraftModelList::validateForPublishing + BlackMisc::CStatusMessageList validateForPublishing(const BlackMisc::Simulation::CAircraftModelList &models, BlackMisc::Simulation::CAircraftModelList &validModels, BlackMisc::Simulation::CAircraftModelList &invalidModels) const; + //! Publish models to database BlackMisc::CStatusMessageList asyncPublishModels(const BlackMisc::Simulation::CAircraftModelList &models) const; diff --git a/src/blackgui/components/dbstashcomponent.cpp b/src/blackgui/components/dbstashcomponent.cpp index 6fb60b35f..bc6996d54 100644 --- a/src/blackgui/components/dbstashcomponent.cpp +++ b/src/blackgui/components/dbstashcomponent.cpp @@ -90,7 +90,7 @@ namespace BlackGui { if (!allowReplace && ui->tvp_StashAircraftModels->container().containsModelStringOrDbKey(model)) { - const QString msg("Model \"%1\" already stashed"); + const QString msg("Model '%1' already stashed"); return CStatusMessage(validationCategories(), CStatusMessage::SeverityError, msg.arg(model.getModelString())); } return CStatusMessage(); @@ -316,10 +316,10 @@ namespace BlackGui CStatusMessageList CDbStashComponent::validate(CAircraftModelList &validModels, CAircraftModelList &invalidModels) const { if (ui->tvp_StashAircraftModels->isEmpty()) {return CStatusMessageList(); } + Q_ASSERT_X(sGui->getWebDataServices(), Q_FUNC_INFO, "No web services"); const CAircraftModelList models(getSelectedOrAllModels()); if (models.isEmpty()) { return CStatusMessageList(); } - - const CStatusMessageList msgs(models.validateForPublishing(validModels, invalidModels)); + const CStatusMessageList msgs(sGui->getWebDataServices()->validateForPublishing(models, validModels, invalidModels)); // OK? if (msgs.isEmpty()) @@ -346,16 +346,14 @@ namespace BlackGui else { // delete highlighting because no errors - ui->tvp_StashAircraftModels->setHighlightModelStrings(QStringList()); - + ui->tvp_StashAircraftModels->clearHighlighting(); if (displayInfo) { - QString no = QString::number(this->getStashedModelsCount()); + const QString no = QString::number(this->getStashedModelsCount()); CStatusMessage msg(validationCategories(), CStatusMessage::SeverityInfo, "Validation passed for " + no + " models"); this->showMessage(msg); } } - return !validModels.isEmpty(); // at least some valid objects } diff --git a/src/blackmisc/simulation/aircraftmodel.cpp b/src/blackmisc/simulation/aircraftmodel.cpp index 95e1f157a..1a6028c0b 100644 --- a/src/blackmisc/simulation/aircraftmodel.cpp +++ b/src/blackmisc/simulation/aircraftmodel.cpp @@ -340,7 +340,7 @@ namespace BlackMisc if (distributors.isEmpty()) { return false; } bool found = false; const int noDistributorOrder = distributors.size(); - if (this->hasDistributor()) + if (this->hasDbDistributor()) { const CDistributor d = distributors.findByKeyOrAlias(this->m_distributor.getDbKey()); if (d.hasValidDbKey()) @@ -360,22 +360,27 @@ namespace BlackMisc return found; } - bool CAircraftModel::hasDistributor() const + bool CAircraftModel::hasDbDistributor() const { - return this->m_distributor.hasValidDbKey(); + return this->m_distributor.isLoadedFromDb(); } - bool CAircraftModel::matchesDistributor(const CDistributor &distributor) const + bool CAircraftModel::hasDistributor() const { - if (!distributor.hasValidDbKey()) { return false; } - if (!this->hasDistributor()) { return false; } + return this->m_distributor.hasValidDbKey(); // key is valid, but not guaranteed from DB + } + + bool CAircraftModel::matchesDbDistributor(const CDistributor &distributor) const + { + if (!distributor.isLoadedFromDb()) { return false; } + if (!this->hasDbDistributor()) { return false; } return this->m_distributor.getDbKey() == distributor.getDbKey(); } - bool CAircraftModel::matchesAnyDistributor(const CDistributorList &distributors) const + bool CAircraftModel::matchesAnyDbDistributor(const CDistributorList &distributors) const { if (distributors.isEmpty()) { return false; } - if (!this->hasDistributor()) { return false; } + if (!this->hasDbDistributor()) { return false; } return distributors.matchesAnyKeyOrAlias(this->m_distributor.getDbKey()); } diff --git a/src/blackmisc/simulation/aircraftmodel.h b/src/blackmisc/simulation/aircraftmodel.h index da82616c3..60336d5c1 100644 --- a/src/blackmisc/simulation/aircraftmodel.h +++ b/src/blackmisc/simulation/aircraftmodel.h @@ -222,14 +222,17 @@ namespace BlackMisc //! Update distributor`s order attribute bool setDistributorOrder(const CDistributorList &distributors); - //! Distributor + //! Distributor loaded from DB + bool hasDbDistributor() const; + + //! Distributor, but not necessarily loaded from DB bool hasDistributor() const; //! By distributor - bool matchesDistributor(const CDistributor &distributor) const; + bool matchesDbDistributor(const CDistributor &distributor) const; //! By distributor - bool matchesAnyDistributor(const CDistributorList &distributors) const; + bool matchesAnyDbDistributor(const CDistributorList &distributors) const; //! Name const QString &getName() const { return this->m_name; } diff --git a/src/blackmisc/simulation/aircraftmodellist.cpp b/src/blackmisc/simulation/aircraftmodellist.cpp index 3bff7a014..094612373 100644 --- a/src/blackmisc/simulation/aircraftmodellist.cpp +++ b/src/blackmisc/simulation/aircraftmodellist.cpp @@ -243,7 +243,7 @@ namespace BlackMisc if (distributors.isEmpty()) { return CAircraftModelList(); } return this->findBy([ = ](const CAircraftModel & model) { - return model.matchesAnyDistributor(distributors); + return model.matchesAnyDbDistributor(distributors); }); } @@ -565,6 +565,37 @@ namespace BlackMisc return msgs; } + CStatusMessageList CAircraftModelList::validateDistributors(const CDistributorList &distributors, CAircraftModelList &validModels, CAircraftModelList &invalidModels) const + { + CStatusMessageList msgs; + CDistributorList distributorsFromDb(distributors); + distributorsFromDb.removeIfNotLoadedFromDb(); + + // Any DB distributors? + if (distributorsFromDb.isEmpty()) + { + const CStatusMessage msg = CStatusMessage(this).validationError("No DB distributors for validation"); + msgs.push_back(msg); + invalidModels.push_back(*this); + return msgs; + } + + for (const CAircraftModel &model : *this) + { + if (model.hasDbDistributor() || model.matchesAnyDbDistributor(distributorsFromDb)) + { + validModels.push_back(model); + } + else + { + const CStatusMessage msg = CStatusMessage(this).validationError("No valid distributor for '%1', was '%2'") << model.getModelString() << model.getDistributor().getDbKey(); + msgs.push_back(msg); + invalidModels.push_back(model); + } + } + return msgs; + } + QJsonArray CAircraftModelList::toDatabaseJson() const { QJsonArray array; diff --git a/src/blackmisc/simulation/aircraftmodellist.h b/src/blackmisc/simulation/aircraftmodellist.h index c59103cd8..305575cbe 100644 --- a/src/blackmisc/simulation/aircraftmodellist.h +++ b/src/blackmisc/simulation/aircraftmodellist.h @@ -204,6 +204,9 @@ namespace BlackMisc //! Validate for publishing CStatusMessageList validateForPublishing(CAircraftModelList &validModels, CAircraftModelList &invalidModels) const; + //! Validate distributors + CStatusMessageList validateDistributors(const BlackMisc::Simulation::CDistributorList &distributors, CAircraftModelList &validModels, CAircraftModelList &invalidModels) const; + //! To database JSON QJsonArray toDatabaseJson() const; diff --git a/src/blackmisc/simulation/distributorlist.cpp b/src/blackmisc/simulation/distributorlist.cpp index 50a99cf8e..1611cf99e 100644 --- a/src/blackmisc/simulation/distributorlist.cpp +++ b/src/blackmisc/simulation/distributorlist.cpp @@ -36,7 +36,7 @@ namespace BlackMisc CDistributor CDistributorList::findByModelData(const CAircraftModel &model) const { - // some stuipd hardcoded resolutions + // some stuipd hardcoded resolutions for distributors if (model.getDistributor().hasValidDbKey()) { return model.getDistributor(); } if (model.getModelString().startsWith("WOA", Qt::CaseInsensitive)) { return this->findByKeyOrAlias("WOAI"); } if (model.getDescription().contains("WOA", Qt::CaseInsensitive)) { return this->findByKeyOrAlias("WOAI"); } @@ -114,5 +114,15 @@ namespace BlackMisc } return distributors; } + + bool CDistributorList::isCompletelyFromDb() const + { + return !this->contains(&CDistributor::isLoadedFromDb, false); + } + + int CDistributorList::removeIfNotLoadedFromDb() + { + return this->removeIf(&CDistributor::isLoadedFromDb, false); + } } // namespace } // namespace diff --git a/src/blackmisc/simulation/distributorlist.h b/src/blackmisc/simulation/distributorlist.h index c7110b063..507394aa5 100644 --- a/src/blackmisc/simulation/distributorlist.h +++ b/src/blackmisc/simulation/distributorlist.h @@ -67,6 +67,12 @@ namespace BlackMisc //! Find for given simulator CDistributorList matchesSimulator(const CSimulatorInfo &simulator) const; + + //! All data from DB? + bool isCompletelyFromDb() const; + + //! Remove distributors not from DB + int removeIfNotLoadedFromDb(); }; } //namespace } // namespace