File indexing completed on 2024-05-12 16:42:43

0001 /*
0002     SPDX-FileCopyrightText: 2013-2018 Christian Dávid <christian-david@web.de>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #ifndef ONLINEJOBADMINISTRATION_H
0007 #define ONLINEJOBADMINISTRATION_H
0008 
0009 // ----------------------------------------------------------------------------
0010 // QT Includes
0011 
0012 #include <QMap>
0013 
0014 // ----------------------------------------------------------------------------
0015 // KDE Includes
0016 
0017 // ----------------------------------------------------------------------------
0018 // Project Includes
0019 
0020 #include "onlinejob.h"
0021 #include "onlinetasks/interfaces/tasks/onlinetask.h"
0022 #include "onlinetasks/interfaces/tasks/ionlinetasksettings.h"
0023 #include "onlinetasks/interfaces/tasks/credittransfer.h"
0024 #include "onlinetasks/interfaces/converter/onlinetaskconverter.h"
0025 
0026 class onlineTask;
0027 class IonlineJobEdit;
0028 
0029 namespace KMyMoneyPlugin
0030 {
0031 class OnlinePluginExtended;
0032 }
0033 
0034 /**
0035  * @brief Connection between KMyMoney and the plugins
0036  *
0037  * It's main task is the communication with plugins
0038  * and caching their information during run-time. During
0039  * sending this class selects the correct plugin for each
0040  * onlineJob.
0041  *
0042  * This class keeps an overview which account can handle which job and
0043  * offers methods to access these information.
0044  *
0045  * onlineJobAdministration is created with singleton pattern. Get the
0046  * instance with @ref onlineJobAdministration::instance() .
0047  */
0048 class KMM_MYMONEY_EXPORT onlineJobAdministration : public QObject
0049 {
0050     Q_OBJECT
0051     KMM_MYMONEY_UNIT_TESTABLE
0052 
0053     Q_PROPERTY(bool canSendAnyTask READ canSendAnyTask NOTIFY canSendAnyTaskChanged STORED false);
0054     Q_PROPERTY(bool canSendCreditTransfer READ canSendCreditTransfer NOTIFY canSendCreditTransferChanged STORED false);
0055 
0056 protected:
0057     explicit onlineJobAdministration(QObject *parent = 0);
0058 
0059 public:
0060     ~onlineJobAdministration();
0061 
0062     struct onlineJobEditOffer {
0063         QString fileName;
0064         QString pluginKeyword;
0065         QString name;
0066     };
0067     using onlineJobEditOffers = QVector<onlineJobEditOffer>;
0068 
0069     /**
0070      * @brief List all available onlineTasks
0071      */
0072     QStringList availableOnlineTasks();
0073 
0074     static onlineJobAdministration* instance();
0075 
0076     /** @brief clear the internal caches for shutdown */
0077     void clearCaches();
0078 
0079     /** @brief Use onlineTask::name() to create a corresponding onlineJob */
0080     onlineJob createOnlineJob(const QString& name, const QString& id = QString()) const;
0081 
0082     /**
0083      * @brief Return list of IonlineJobEdits
0084      *
0085      * Method is temporary!
0086      *
0087      * @return I stay owner of all pointers.
0088      */
0089     onlineJobEditOffers onlineJobEdits();
0090     QString onlineJobEditName(onlineJobEditOffer);
0091 
0092     bool isJobSupported(const QString& accountId, const QString& name) const;
0093     bool isJobSupported(const QString& accountId, const QStringList& names) const;
0094     bool isAnyJobSupported(const QString& accountId) const;
0095 
0096     onlineTaskConverter::convertType canConvert(const QString& originalTaskIid, const QString& convertTaskIid) const;
0097     onlineTaskConverter::convertType canConvert(const QString& originalTaskIid, const QStringList& convertTaskIids) const;
0098 
0099 #if 0
0100     template<class T>
0101     onlineJobTyped<T> convert(const onlineJob& original, const QString& convertTaskIid, onlineTaskConverter::convertType& convertType, QString& userInformation, const QString& onlineJobId) const;
0102     template<class T>
0103     onlineJobTyped<T> convert(const onlineJob& original, const QString& convertTaskIid, onlineTaskConverter::convertType& convertType, QString& userInformation) const;
0104 #endif
0105 
0106     /**
0107      * @brief Convert an onlineTask to another type
0108      *
0109      * @param original onlineJob to convert
0110      * @param convertTaskIid onlineTask iid you want to convert into
0111      * @param convertType OUT result of conversion. Note: this depends on original
0112      * @param userInformation OUT A translated html-string with information about the changes which were done
0113      * @param onlineJobId The id of the new onlineJob, if none is given original.id() is used
0114      */
0115     onlineJob convert(const onlineJob& original, const QString& convertTaskIid, onlineTaskConverter::convertType& convertType, QString& userInformation, const QString& onlineJobId) const;
0116 
0117     /**
0118      * @copydoc convert()
0119      */
0120     onlineJob convert(const onlineJob& original, const QString& convertTaskIid, onlineTaskConverter::convertType& convertType, QString& userInformation) const;
0121 
0122     /**
0123      * @brief Converts a onlineTask to best fitting type of a set of onlineTasks
0124      *
0125      * Will look for best conversion possible from original to any of convertTaskIids.
0126      *
0127      * @param original onlineJob to convert
0128      * @param convertTaskIids onlineTask-iids you want to convert into.
0129      * @param convertType OUT result of conversion. Note: this depends on original
0130      * @param userInformation OUT A translated html-string with information about the changes which were done
0131      * @param onlineJobId The id of the new onlineJob, if none is given original.id() is used
0132      */
0133     onlineJob convertBest(const onlineJob& original, const QStringList& convertTaskIids, onlineTaskConverter::convertType& convertType, QString& userInformation, const QString& onlineJobId) const;
0134 
0135     /**
0136      * @brief Convenient for convertBest() which crates an onlineJob with the same id as original.
0137      */
0138     onlineJob convertBest(const onlineJob& original, const QStringList& convertTaskIids, onlineTaskConverter::convertType& convertType, QString& userInformation) const;
0139 
0140     /**
0141      * @brief Request onlineTask::settings from plugin
0142      *
0143      * @return QSharedPointer to settings from plugin, can be a nullptr
0144      */
0145     template<class T>
0146     QSharedPointer<T> taskSettings(const QString& taskId, const QString& accountId) const;
0147 
0148     /**
0149      * @brief Request onlineTask::settings from plugin
0150      *
0151      * @see onlineTask::settings
0152      *
0153      * @param taskId onlineTask::name()
0154      * @param accountId MyMoneyAccount.id()
0155      * @return QSharedPointer to settings. QSharedPointer::isNull() is true if an error occurs
0156      * (e.g. plugin does not support the task).
0157      */
0158     QSharedPointer<IonlineTaskSettings> taskSettings(const QString& taskId, const QString& accountId) const;
0159 
0160     /**
0161      * @brief Check if the onlineTask system can do anything
0162      *
0163      * This is true if at least one plugin can process one of the available onlineTasks for at least one available account.
0164      */
0165     bool canSendAnyTask();
0166 
0167     /**
0168      * @brief Are there plugins and accounts to send a credit transfers?
0169      *
0170      * Like @r canSendAnyTask() but restricts the onlineTasks to credit transfers. This is useful
0171      * to disable the create credit transfer buttons.
0172      */
0173     bool canSendCreditTransfer();
0174 
0175     /**
0176      * @brief Are all preconditions set to edit the given job?
0177      */
0178     bool canEditOnlineJob(const onlineJob& job);
0179 
0180     /**
0181      * @brief See if a online task has a specified base
0182      *
0183      * This is usable if you want to see if e.g. taskIid is
0184      * of type creditTransfer
0185      */
0186     template<class baseTask>
0187     bool isInherited(const QString& taskIid) const;
0188 
0189     /**
0190      * @brief makes plugins loaded in KMyMoneyApp available here
0191      * @param plugins
0192      */
0193     void setOnlinePlugins(QMap<QString, KMyMoneyPlugin::OnlinePluginExtended*>& plugins);
0194 
0195     /**
0196      * @brief updates online actions and should be called after plugin enable or disable
0197      */
0198     void updateActions();
0199 
0200     /**
0201      * @brief Creates an onlineTask by its iid and xml data
0202      * @return pointer to task, caller gains ownership. Can be 0.
0203      */
0204     onlineTask* createOnlineTaskByXml(const QString& iid, const QDomElement& element) const;
0205 
0206 Q_SIGNALS:
0207     /**
0208      * @brief Emitted if canSendAnyTask() changed
0209      *
0210      * At the moment it this signal can be sent even if the status did not change.
0211      */
0212     void canSendAnyTaskChanged(bool);
0213 
0214     /**
0215      * @brief Emitted if canSendCreditTransfer changed
0216      *
0217      * At the moment it this signal can be sent even if the status did not change.
0218      */
0219     void canSendCreditTransferChanged(bool);
0220 
0221 public Q_SLOTS:
0222     /**
0223      * @brief Slot for plugins to make an onlineTask available.
0224      * @param task the task to register, I take ownership
0225      */
0226     void registerOnlineTask(onlineTask *const task);
0227 
0228     /**
0229      * @brief Slot for plugins to make an onlineTaskConverter available.
0230      * @param converter the converter to register, I take ownership
0231      */
0232     void registerOnlineTaskConverter(onlineTaskConverter *const converter);
0233 
0234     /**
0235      * @brief Check if the properties about available and sendable online tasks are still valid
0236      */
0237     void updateOnlineTaskProperties();
0238 
0239 private:
0240     /**
0241      * Register all available online tasks
0242      */
0243     void registerAllOnlineTasks();
0244 
0245     /**
0246      * @brief Find onlinePlugin which is responsible for accountId
0247      * @param accountId
0248      * @return Pointer to onlinePluginExtended, do not delete.
0249      */
0250     KMyMoneyPlugin::OnlinePluginExtended* getOnlinePlugin(const QString& accountId) const;
0251 
0252     /**
0253      * @brief Creates an onlineTask by iid
0254      * @return pointer to task, caller gains ownership. Can be 0.
0255      */
0256     onlineTask* createOnlineTask(const QString& iid) const;
0257 
0258     // Must be able to call createOnlineTaskByXml
0259     friend class onlineJob;
0260 
0261     // Must be able to call createOnlineTask
0262     template<class T>
0263     friend class onlineJobTyped;
0264 
0265     /**
0266      * @brief Get root instance of an onlineTask
0267      *
0268      * Returns a pointer from m_onlineTasks or tries to load/create
0269      * a approiate root element.
0270      *
0271      * Only createOnlineTask and createOnlineTaskByXml use it.
0272      *
0273      * @return A pointer, you do *not* gain ownership! Can be 0 if something went wrong.
0274      *
0275      * @internal Made to be forward compatible when onlineTask are loaded as plugins.
0276      */
0277     inline onlineTask* rootOnlineTask(const QString& name) const;
0278 
0279     /**
0280      * The key is the onlinePlugin's name
0281      */
0282     QMap<QString, KMyMoneyPlugin::OnlinePluginExtended*>* m_onlinePlugins;
0283 
0284     /**
0285      * The key is the name of the task
0286      */
0287     QMap<QString, onlineTask*> m_onlineTasks;
0288 
0289     /**
0290      * Key is the task the converter converts to
0291      */
0292     QMultiMap<QString, onlineTaskConverter*> m_onlineTaskConverter;
0293 
0294     /**
0295      * Instances of editors
0296      */
0297     QList<IonlineJobEdit*> m_onlineTaskEditors;
0298 
0299     bool m_inRegistration;
0300 };
0301 
0302 template<class T>
0303 QSharedPointer<T> onlineJobAdministration::taskSettings(const QString& taskName, const QString& accountId) const
0304 {
0305     IonlineTaskSettings::ptr settings = taskSettings(taskName, accountId);
0306     if (!settings.isNull()) {
0307         QSharedPointer<T> settingsFinal = settings.dynamicCast<T>();
0308         if (Q_LIKELY(!settingsFinal.isNull()))     // This can only happen if the onlinePlugin has a bug.
0309             return settingsFinal;
0310     }
0311     return QSharedPointer<T>();
0312 }
0313 
0314 template< class baseTask >
0315 bool onlineJobAdministration::isInherited(const QString& taskIid) const
0316 {
0317     return (dynamic_cast<baseTask*>(rootOnlineTask(taskIid)) != 0);
0318 }
0319 
0320 #if 0
0321 template<class T>
0322 onlineJobTyped<T> onlineJobAdministration::convert(const onlineJob& original, const QString& convertTaskIid, onlineTaskConverter::convertType& convertType, QString& userInformation, const QString& onlineJobId) const
0323 {
0324     onlineJob job = convert(original, convertTaskIid, convertType, userInformation, onlineJobId);
0325     return onlineJobTyped<T>(job);
0326 }
0327 
0328 template<class T>
0329 onlineJobTyped< T > onlineJobAdministration::convert(const onlineJob& original, const QString& convertTaskIid, onlineTaskConverter::convertType& convertType, QString& userInformation) const
0330 {
0331     return convert<T>(original, convertTaskIid, convertType, userInformation, original.id());
0332 }
0333 #endif
0334 
0335 #endif // ONLINEJOBADMINISTRATION_H