1 /*
2 * Copyright 2013-2018 Christian Dávid <christian-david@web.de>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of
7 * the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #ifndef ONLINEJOBADMINISTRATION_H
19 #define ONLINEJOBADMINISTRATION_H
20
21 // ----------------------------------------------------------------------------
22 // QT Includes
23
24 #include <QMap>
25
26 // ----------------------------------------------------------------------------
27 // KDE Includes
28
29 // ----------------------------------------------------------------------------
30 // Project Includes
31
32 #include "onlinejob.h"
33 #include "onlinetasks/interfaces/tasks/onlinetask.h"
34 #include "onlinetasks/interfaces/tasks/ionlinetasksettings.h"
35 #include "onlinetasks/interfaces/tasks/credittransfer.h"
36 #include "onlinetasks/interfaces/converter/onlinetaskconverter.h"
37
38 class onlineTask;
39 class IonlineJobEdit;
40
41 namespace KMyMoneyPlugin
42 {
43 class OnlinePluginExtended;
44 }
45
46 /**
47 * @brief Connection between KMyMoney and the plugins
48 *
49 * It's main task is the communication with plugins
50 * and caching their information during run-time. During
51 * sending this class selects the correct plugin for each
52 * onlineJob.
53 *
54 * This class keeps an overview which account can handle which job and
55 * offers methods to access these information.
56 *
57 * onlineJobAdministration is created with singleton pattern. Get the
58 * instance with @ref onlineJobAdministration::instance() .
59 */
60 class KMM_MYMONEY_EXPORT onlineJobAdministration : public QObject
61 {
62 Q_OBJECT
63 KMM_MYMONEY_UNIT_TESTABLE
64
65 Q_PROPERTY(bool canSendAnyTask READ canSendAnyTask NOTIFY canSendAnyTaskChanged STORED false);
66 Q_PROPERTY(bool canSendCreditTransfer READ canSendCreditTransfer NOTIFY canSendCreditTransferChanged STORED false);
67
68 protected:
69 explicit onlineJobAdministration(QObject *parent = 0);
70
71 public:
72 ~onlineJobAdministration();
73
74 struct onlineJobEditOffer {
75 QString fileName;
76 QString pluginKeyword;
77 QString name;
78 };
79 using onlineJobEditOffers = QVector<onlineJobEditOffer>;
80
81 /**
82 * @brief List all available onlineTasks
83 */
84 QStringList availableOnlineTasks();
85
86 static onlineJobAdministration* instance();
87
88 /** @brief clear the internal caches for shutdown */
89 void clearCaches();
90
91 /** @brief Use onlineTask::name() to create a corresponding onlineJob */
92 onlineJob createOnlineJob(const QString& name, const QString& id = QString()) const;
93
94 /**
95 * @brief Return list of IonlineJobEdits
96 *
97 * Method is temporary!
98 *
99 * @return I stay owner of all pointers.
100 */
101 onlineJobEditOffers onlineJobEdits();
102 QString onlineJobEditName(onlineJobEditOffer);
103
104 bool isJobSupported(const QString& accountId, const QString& name) const;
105 bool isJobSupported(const QString& accountId, const QStringList& names) const;
106 bool isAnyJobSupported(const QString& accountId) const;
107
108 onlineTaskConverter::convertType canConvert(const QString& originalTaskIid, const QString& convertTaskIid) const;
109 onlineTaskConverter::convertType canConvert(const QString& originalTaskIid, const QStringList& convertTaskIids) const;
110
111 #if 0
112 template<class T>
113 onlineJobTyped<T> convert(const onlineJob& original, const QString& convertTaskIid, onlineTaskConverter::convertType& convertType, QString& userInformation, const QString& onlineJobId) const;
114 template<class T>
115 onlineJobTyped<T> convert(const onlineJob& original, const QString& convertTaskIid, onlineTaskConverter::convertType& convertType, QString& userInformation) const;
116 #endif
117
118 /**
119 * @brief Convert an onlineTask to another type
120 *
121 * @param original onlineJob to convert
122 * @param convertTaskIid onlineTask iid you want to convert into
123 * @param convertType OUT result of conversion. Note: this depends on original
124 * @param userInformation OUT A translated html-string with information about the changes which were done
125 * @param onlineJobId The id of the new onlineJob, if none is given original.id() is used
126 */
127 onlineJob convert(const onlineJob& original, const QString& convertTaskIid, onlineTaskConverter::convertType& convertType, QString& userInformation, const QString& onlineJobId) const;
128
129 /**
130 * @copydoc convert()
131 */
132 onlineJob convert(const onlineJob& original, const QString& convertTaskIid, onlineTaskConverter::convertType& convertType, QString& userInformation) const;
133
134 /**
135 * @brief Converts a onlineTask to best fitting type of a set of onlineTasks
136 *
137 * Will look for best conversion possible from original to any of convertTaskIids.
138 *
139 * @param original onlineJob to convert
140 * @param convertTaskIids onlineTask-iids you want to convert into.
141 * @param convertType OUT result of conversion. Note: this depends on original
142 * @param userInformation OUT A translated html-string with information about the changes which were done
143 * @param onlineJobId The id of the new onlineJob, if none is given original.id() is used
144 */
145 onlineJob convertBest(const onlineJob& original, const QStringList& convertTaskIids, onlineTaskConverter::convertType& convertType, QString& userInformation, const QString& onlineJobId) const;
146
147 /**
148 * @brief Convenient for convertBest() which crates an onlineJob with the same id as original.
149 */
150 onlineJob convertBest(const onlineJob& original, const QStringList& convertTaskIids, onlineTaskConverter::convertType& convertType, QString& userInformation) const;
151
152 /**
153 * @brief Request onlineTask::settings from plugin
154 *
155 * @return QSharedPointer to settings from plugin, can be a nullptr
156 */
157 template<class T>
158 QSharedPointer<T> taskSettings(const QString& taskId, const QString& accountId) const;
159
160 /**
161 * @brief Request onlineTask::settings from plugin
162 *
163 * @see onlineTask::settings
164 *
165 * @param taskId onlineTask::name()
166 * @param accountId MyMoneyAccount.id()
167 * @return QSharedPointer to settings. QSharedPointer::isNull() is true if an error occurs
168 * (e.g. plugin does not support the task).
169 */
170 QSharedPointer<IonlineTaskSettings> taskSettings(const QString& taskId, const QString& accountId) const;
171
172 /**
173 * @brief Check if the onlineTask system can do anything
174 *
175 * This is true if at least one plugin can process one of the available onlineTasks for at least one available account.
176 */
177 bool canSendAnyTask();
178
179 /**
180 * @brief Are there plugins and accounts to send a credit transfers?
181 *
182 * Like @r canSendAnyTask() but restricts the onlineTasks to credit transfers. This is useful
183 * to disable the create credit transfer buttons.
184 */
185 bool canSendCreditTransfer();
186
187 /**
188 * @brief Are all preconditions set to edit the given job?
189 */
190 bool canEditOnlineJob(const onlineJob& job);
191
192 /**
193 * @brief See if a online task has a specified base
194 *
195 * This is usable if you want to see if e.g. taskIid is
196 * of type creditTransfer
197 */
198 template<class baseTask>
199 bool isInherited(const QString& taskIid) const;
200
201 /**
202 * @brief makes plugins loaded in KMyMoneyApp available here
203 * @param plugins
204 */
205 void setOnlinePlugins(QMap<QString, KMyMoneyPlugin::OnlinePluginExtended*>& plugins);
206
207 /**
208 * @brief updates online actions and should be called after plugin enable or disable
209 */
210 void updateActions();
211
212 /**
213 * @brief Creates an onlineTask by its iid and xml data
214 * @return pointer to task, caller gains ownership. Can be 0.
215 */
216 onlineTask* createOnlineTaskByXml(const QString& iid, const QDomElement& element) const;
217
218 Q_SIGNALS:
219 /**
220 * @brief Emitted if canSendAnyTask() changed
221 *
222 * At the moment it this signal can be sent even if the status did not change.
223 */
224 void canSendAnyTaskChanged(bool);
225
226 /**
227 * @brief Emitted if canSendCreditTransfer changed
228 *
229 * At the moment it this signal can be sent even if the status did not change.
230 */
231 void canSendCreditTransferChanged(bool);
232
233 public Q_SLOTS:
234 /**
235 * @brief Slot for plugins to make an onlineTask available.
236 * @param task the task to register, I take ownership
237 */
238 void registerOnlineTask(onlineTask *const task);
239
240 /**
241 * @brief Slot for plugins to make an onlineTaskConverter available.
242 * @param converter the converter to register, I take ownership
243 */
244 void registerOnlineTaskConverter(onlineTaskConverter *const converter);
245
246 /**
247 * @brief Check if the properties about available and sendable online tasks are still valid
248 */
249 void updateOnlineTaskProperties();
250
251 private:
252 /**
253 * Register all available online tasks
254 */
255 void registerAllOnlineTasks();
256
257 /**
258 * @brief Find onlinePlugin which is responsible for accountId
259 * @param accountId
260 * @return Pointer to onlinePluginExtended, do not delete.
261 */
262 KMyMoneyPlugin::OnlinePluginExtended* getOnlinePlugin(const QString& accountId) const;
263
264 /**
265 * @brief Creates an onlineTask by iid
266 * @return pointer to task, caller gains ownership. Can be 0.
267 */
268 onlineTask* createOnlineTask(const QString& iid) const;
269
270 // Must be able to call createOnlineTaskByXml
271 friend class onlineJob;
272
273 // Must be able to call createOnlineTask
274 template<class T>
275 friend class onlineJobTyped;
276
277 /**
278 * @brief Get root instance of an onlineTask
279 *
280 * Returns a pointer from m_onlineTasks or tries to load/create
281 * a approiate root element.
282 *
283 * Only createOnlineTask and createOnlineTaskByXml use it.
284 *
285 * @return A pointer, you do *not* gain ownership! Can be 0 if something went wrong.
286 *
287 * @internal Made to be forward compatible when onlineTask are loaded as plugins.
288 */
289 inline onlineTask* rootOnlineTask(const QString& name) const;
290
291 /**
292 * The key is the onlinePlugin's name
293 */
294 QMap<QString, KMyMoneyPlugin::OnlinePluginExtended*>* m_onlinePlugins;
295
296 /**
297 * The key is the name of the task
298 */
299 QMap<QString, onlineTask*> m_onlineTasks;
300
301 /**
302 * Key is the task the converter converts to
303 */
304 QMultiMap<QString, onlineTaskConverter*> m_onlineTaskConverter;
305
306 /**
307 * Instances of editors
308 */
309 QList<IonlineJobEdit*> m_onlineTaskEditors;
310
311 bool m_inRegistration;
312 };
313
314 template<class T>
taskSettings(const QString & taskName,const QString & accountId)315 QSharedPointer<T> onlineJobAdministration::taskSettings(const QString& taskName, const QString& accountId) const
316 {
317 IonlineTaskSettings::ptr settings = taskSettings(taskName, accountId);
318 if (!settings.isNull()) {
319 QSharedPointer<T> settingsFinal = settings.dynamicCast<T>();
320 if (Q_LIKELY(!settingsFinal.isNull())) // This can only happen if the onlinePlugin has a bug.
321 return settingsFinal;
322 }
323 return QSharedPointer<T>();
324 }
325
326 template< class baseTask >
isInherited(const QString & taskIid)327 bool onlineJobAdministration::isInherited(const QString& taskIid) const
328 {
329 return (dynamic_cast<baseTask*>(rootOnlineTask(taskIid)) != 0);
330 }
331
332 #if 0
333 template<class T>
334 onlineJobTyped<T> onlineJobAdministration::convert(const onlineJob& original, const QString& convertTaskIid, onlineTaskConverter::convertType& convertType, QString& userInformation, const QString& onlineJobId) const
335 {
336 onlineJob job = convert(original, convertTaskIid, convertType, userInformation, onlineJobId);
337 return onlineJobTyped<T>(job);
338 }
339
340 template<class T>
341 onlineJobTyped< T > onlineJobAdministration::convert(const onlineJob& original, const QString& convertTaskIid, onlineTaskConverter::convertType& convertType, QString& userInformation) const
342 {
343 return convert<T>(original, convertTaskIid, convertType, userInformation, original.id());
344 }
345 #endif
346
347 #endif // ONLINEJOBADMINISTRATION_H
348