File indexing completed on 2024-05-12 05:06:47

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