1 /***************************************************************************
2 * SPDX-FileCopyrightText: 2021 S. MANKOWSKI stephane@mankowski.fr
3 * SPDX-FileCopyrightText: 2021 G. DE BURE support@mankowski.fr
4 * SPDX-License-Identifier: GPL-3.0-or-later
5 ***************************************************************************/
6 /** @file
7 * A skrooge plugin to search and process operations.
8 *
9 * @author Stephane MANKOWSKI
10 */
11 #include "skgsearchpluginwidget.h"
12
13 #include <qdir.h>
14 #include <qdom.h>
15 #include <qevent.h>
16
17 #include "skgbankincludes.h"
18 #include "skgcategoryobject.h"
19 #include "skgdocument.h"
20 #include "skgmainpanel.h"
21 #include "skgobjectmodel.h"
22 #include "skgruleobject.h"
23 #include "skgservices.h"
24 #include "skgtraces.h"
25
SKGSearchPluginWidget(QWidget * iParent,SKGDocument * iDocument)26 SKGSearchPluginWidget::SKGSearchPluginWidget(QWidget* iParent, SKGDocument* iDocument)
27 : SKGTabPage(iParent, iDocument)
28 {
29 SKGTRACEINFUNC(1)
30 if (iDocument == nullptr) {
31 return;
32 }
33
34 ui.setupUi(this);
35 auto msg = i18nc("Message template", "Message to display when alarm is triggered (%1 is the total amount, %2 is the alarm amount, %3 the difference)", "%1", "%2", "%3");
36 ui.kAlarmMessage->setToolTip(msg);
37 ui.kAlarmMessage->setStatusTip(msg);
38
39 ui.kView->getShowWidget()->addItem(QStringLiteral("search"), i18nc("Noun, a search", "Search"), QStringLiteral("edit-find"), QStringLiteral("t_action_type='S'"), QLatin1String(""), QLatin1String(""), QLatin1String(""), QLatin1String(""), Qt::META + Qt::Key_S);
40 ui.kView->getShowWidget()->addItem(QStringLiteral("update"), i18nc("Noun, a modification", "Update"), QStringLiteral("view-refresh"), QStringLiteral("t_action_type='U'"), QLatin1String(""), QLatin1String(""), QLatin1String(""), QLatin1String(""), Qt::META + Qt::Key_U);
41 ui.kView->getShowWidget()->addItem(QStringLiteral("alarm"), i18nc("Noun, an alarm", "Alarm"), QStringLiteral("dialog-warning"), QStringLiteral("t_action_type='A'"), QLatin1String(""), QLatin1String(""), QLatin1String(""), QLatin1String(""), Qt::META + Qt::Key_A);
42 ui.kView->getShowWidget()->addItem(QStringLiteral("template"), i18nc("Noun, a modification by applying a template", "Template"), QStringLiteral("edit-guides"), QStringLiteral("t_action_type='T'"), QLatin1String(""), QLatin1String(""), QLatin1String(""), QLatin1String(""), Qt::META + Qt::Key_T);
43 ui.kView->getShowWidget()->addSeparator();
44 ui.kView->getShowWidget()->addItem(QStringLiteral("highlighted"), i18nc("Adjective, an highlighted item", "Highlighted"), QStringLiteral("bookmarks"), QStringLiteral("t_bookmarked='Y'"), QLatin1String(""), QLatin1String(""), QLatin1String(""), QLatin1String(""), Qt::META + Qt::Key_H);
45 ui.kView->getShowWidget()->setDefaultState(QStringLiteral("search;update;alarm;template;highlighted"));
46
47 // Add Standard KDE Icons to buttons
48 ui.kUpdate->setIcon(SKGServices::fromTheme(QStringLiteral("dialog-ok")));
49 ui.kAdd->setIcon(SKGServices::fromTheme(QStringLiteral("list-add")));
50 ui.kSearch->setIcon(SKGServices::fromTheme(QStringLiteral("edit-find")));
51 QStringList overlayopen;
52 overlayopen.push_back(QStringLiteral("quickopen"));
53 ui.kOpenReport->setIcon(SKGServices::fromTheme(QStringLiteral("view-statistics"), overlayopen));
54
55 ui.kTopBtn->setIcon(SKGServices::fromTheme(QStringLiteral("arrow-up-double")));
56 ui.kUpBtn->setIcon(SKGServices::fromTheme(QStringLiteral("arrow-up")));
57 ui.kDownBtn->setIcon(SKGServices::fromTheme(QStringLiteral("arrow-down")));
58 ui.kBottomBtn->setIcon(SKGServices::fromTheme(QStringLiteral("arrow-down-double")));
59
60 {
61 SKGWidgetSelector::SKGListQWidget list;
62 list.push_back(ui.kQueryGrp);
63 list.push_back(ui.kBtnFrm);
64 ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("edit-find")), i18n("Search"), i18n("Display the edit panel for searches"), list);
65 }
66 {
67 SKGWidgetSelector::SKGListQWidget list;
68 list.push_back(ui.kQueryGrp);
69 list.push_back(ui.kBtnFrm);
70 list.push_back(ui.kActionGrp);
71 ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("view-refresh")), i18n("Update"), i18n("Display the edit panel for updates"), list);
72 }
73 {
74 SKGWidgetSelector::SKGListQWidget list;
75 list.push_back(ui.kQueryGrp);
76 list.push_back(ui.kBtnFrm);
77 list.push_back(ui.kAlarmFrm);
78 ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("dialog-warning")), i18n("Alarm"), i18n("Display the edit panel for alarm"), list);
79 }
80 {
81 SKGWidgetSelector::SKGListQWidget list;
82 list.push_back(ui.kQueryGrp);
83 list.push_back(ui.kBtnFrm);
84 list.push_back(ui.kTemplateFrm);
85 ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("edit-guides")), i18n("Template"), i18n("Display the edit panel for updates by templates"), list);
86 }
87
88 QStringList attributeForQuery;
89 attributeForQuery.reserve(40);
90 attributeForQuery << QStringLiteral("d_DATEOP") << QStringLiteral("t_number") << QStringLiteral("t_mode") << QStringLiteral("t_PAYEE") << QStringLiteral("t_comment") << QStringLiteral("t_REALCOMMENT") << QStringLiteral("t_REALCATEGORY") << QStringLiteral("t_status") << QStringLiteral("t_bookmarked") << QStringLiteral("t_imported") << QStringLiteral("t_TRANSFER") << QStringLiteral("t_UNIT") << QStringLiteral("t_ACCOUNT") << QStringLiteral("t_BANK") << QStringLiteral("t_TOACCOUNT") << QStringLiteral("f_REALCURRENTAMOUNT") << QStringLiteral("t_REALREFUND") << QStringLiteral("f_BALANCE") << QStringLiteral("i_NBSUBOPERATIONS");
91 QStringList attributeForUpdate;
92 attributeForUpdate.reserve(40);
93 attributeForUpdate << QStringLiteral("d_DATEOP") << QStringLiteral("t_number") << QStringLiteral("t_mode") << QStringLiteral("t_PAYEE") << QStringLiteral("t_comment") << QStringLiteral("t_status") << QStringLiteral("t_bookmarked") << QStringLiteral("t_imported") << QStringLiteral("t_REALCOMMENT") << QStringLiteral("t_REALCATEGORY") << QStringLiteral("t_ACCOUNT") << QStringLiteral("t_REALREFUND") << QStringLiteral("t_UNIT");
94 // WARNING: trigger must be modified if this list is modifier
95
96 // Adding properties
97 QStringList properties;
98 iDocument->getDistinctValues(QStringLiteral("parameters"), QStringLiteral("t_name"), QStringLiteral("(t_uuid_parent like '%-operation' OR t_uuid_parent like '%-suboperation') AND t_name NOT LIKE 'SKG_%'"), properties);
99 int nb = properties.count();
100 for (int i = 0; i < nb; ++i) {
101 attributeForQuery.push_back("p_" % properties.at(i));
102 attributeForUpdate.push_back("p_" % properties.at(i));
103 }
104
105 ui.kQueryCreator->setParameters(iDocument, QStringLiteral("v_suboperation_consolidated"), attributeForQuery);
106 ui.kActionCreator->setParameters(iDocument, QStringLiteral("v_suboperation_consolidated"), attributeForUpdate, true);
107
108 // Bind operation view
109 ui.kView->setModel(new SKGObjectModel(qobject_cast<SKGDocumentBank*>(getDocument()), QStringLiteral("v_rule_display"), QStringLiteral("1=1 ORDER BY f_sortorder"), this, QLatin1String(""), false));
110 ui.kView->getView()->sortByColumn(0, Qt::AscendingOrder);
111
112 // Add registered global action in contextual menu
113 if (SKGMainPanel::getMainPanel() != nullptr) {
114 auto menu = new QMenu(this);
115 menu->setIcon(SKGServices::fromTheme(QStringLiteral("system-run")));
116 menu->addAction(SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("execute_all")));
117 menu->addAction(SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("execute_imported")));
118 menu->addAction(SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("execute_not_validated")));
119 menu->addAction(SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("execute_notchecked")));
120
121 ui.kApply->setIcon(menu->icon());
122 ui.kApply->setMenu(menu);
123 ui.kApply->setPopupMode(QToolButton::InstantPopup);
124 }
125
126 ui.kWidgetSelector->setSelectedMode(0);
127
128 connect(ui.kView->getView(), &SKGTreeView::clickEmptyArea, this, &SKGSearchPluginWidget::cleanEditor);
129 connect(ui.kView->getView(), &SKGTreeView::doubleClicked, SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("open")).data(), &QAction::trigger);
130 connect(ui.kView->getView(), &SKGTreeView::selectionChangedDelayed, this, [ = ] {this->onSelectionChanged();});
131 connect(ui.kQueryCreator, &SKGQueryCreator::search, this, &SKGSearchPluginWidget::onOpen);
132
133 connect(ui.kAdd, &QPushButton::clicked, this, &SKGSearchPluginWidget::onAddRule);
134 connect(ui.kUpdate, &QPushButton::clicked, this, &SKGSearchPluginWidget::onModifyRule);
135 connect(ui.kTopBtn, &QToolButton::clicked, this, &SKGSearchPluginWidget::onTop);
136 connect(ui.kUpBtn, &QToolButton::clicked, this, &SKGSearchPluginWidget::onUp);
137 connect(ui.kDownBtn, &QToolButton::clicked, this, &SKGSearchPluginWidget::onDown);
138 connect(ui.kBottomBtn, &QToolButton::clicked, this, &SKGSearchPluginWidget::onBottom);
139 connect(ui.kOpenReport, &QPushButton::clicked, this, &SKGSearchPluginWidget::onOpen);
140 connect(ui.kSearch, &QPushButton::clicked, this, &SKGSearchPluginWidget::onOpen);
141
142 // Refresh
143 connect(getDocument(), &SKGDocument::tableModified, this, &SKGSearchPluginWidget::dataModified, Qt::QueuedConnection);
144 dataModified(QLatin1String(""), 0);
145
146 onSelectionChanged();
147
148 // Set Event filters to catch CTRL+ENTER or SHIFT+ENTER
149 this->installEventFilter(this);
150 }
151
~SKGSearchPluginWidget()152 SKGSearchPluginWidget::~SKGSearchPluginWidget()
153 {
154 SKGTRACEINFUNC(1)
155 }
156
eventFilter(QObject * iObject,QEvent * iEvent)157 bool SKGSearchPluginWidget::eventFilter(QObject* iObject, QEvent* iEvent)
158 {
159 if ((iEvent != nullptr) && iEvent->type() == QEvent::KeyPress) {
160 auto* keyEvent = dynamic_cast<QKeyEvent*>(iEvent);
161 if (keyEvent && (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) && iObject == this) {
162 if ((QApplication::keyboardModifiers() & Qt::ControlModifier) != 0u && ui.kAdd->isEnabled()) {
163 ui.kAdd->click();
164 } else if ((QApplication::keyboardModifiers() &Qt::ShiftModifier) != 0u && ui.kUpdate->isEnabled()) {
165 ui.kUpdate->click();
166 }
167 }
168 }
169
170 return SKGTabPage::eventFilter(iObject, iEvent);
171 }
172
getState()173 QString SKGSearchPluginWidget::getState()
174 {
175 SKGTRACEINFUNC(10)
176 QDomDocument doc(QStringLiteral("SKGML"));
177 QDomElement root = doc.createElement(QStringLiteral("parameters"));
178 doc.appendChild(root);
179 root.setAttribute(QStringLiteral("currentPage"), SKGServices::intToString(ui.kWidgetSelector->getSelectedMode()));
180 root.setAttribute(QStringLiteral("view"), ui.kView->getState());
181 return doc.toString();
182 }
183
setState(const QString & iState)184 void SKGSearchPluginWidget::setState(const QString& iState)
185 {
186 SKGTRACEINFUNC(10)
187 QDomDocument doc(QStringLiteral("SKGML"));
188 doc.setContent(iState);
189 QDomElement root = doc.documentElement();
190
191 QString currentPage = root.attribute(QStringLiteral("currentPage"));
192 QString xmlsearchcondition = root.attribute(QStringLiteral("xmlsearchcondition"));
193
194 if (currentPage.isEmpty()) {
195 currentPage = '0';
196 }
197
198 ui.kWidgetSelector->setSelectedMode(SKGServices::stringToInt(currentPage));
199 ui.kQueryCreator->setXMLCondition(xmlsearchcondition);
200 ui.kView->setState(root.attribute(QStringLiteral("view")));
201 }
202
getDefaultStateAttribute()203 QString SKGSearchPluginWidget::getDefaultStateAttribute()
204 {
205 return QStringLiteral("SKGSEARCH_DEFAULT_PARAMETERS");
206 }
207
mainWidget()208 QWidget* SKGSearchPluginWidget::mainWidget()
209 {
210 return ui.kView->getView();
211 }
212
getSelectedObjects()213 SKGObjectBase::SKGListSKGObjectBase SKGSearchPluginWidget::getSelectedObjects()
214 {
215 SKGObjectBase::SKGListSKGObjectBase list = ui.kView->getView()->getSelectedObjects();
216
217 // Sort selection by f_sortorder. It is mandatory for reorder functions
218 std::stable_sort(list.begin(), list.end());
219
220 return list;
221 }
222
getNbSelectedObjects()223 int SKGSearchPluginWidget::getNbSelectedObjects()
224 {
225 return ui.kView->getView()->getNbSelectedObjects();
226 }
227
dataModified(const QString & iTableName,int iIdTransaction)228 void SKGSearchPluginWidget::dataModified(const QString& iTableName, int iIdTransaction)
229 {
230 SKGTRACEINFUNC(1)
231 Q_UNUSED(iIdTransaction)
232
233 // Refresh account list
234 if (iTableName == QStringLiteral("unit") || iTableName.isEmpty()) {
235 ui.kAlarmUnit->setText(qobject_cast<SKGDocumentBank*>(getDocument())->getPrimaryUnit().Symbol);
236 }
237
238 if (iTableName == QStringLiteral("operation") || iTableName.isEmpty()) {
239 // Fill combo boxes
240 SKGStringListList result;
241 getDocument()->executeSelectSqliteOrder(QStringLiteral("SELECT id, t_displayname FROM v_operation_displayname WHERE t_template='Y' ORDER BY t_displayname"), result);
242 int nb2 = result.count();
243 for (int i = 1; i < nb2; ++i) { // Ignore header
244 const QStringList& r = result.at(i);
245 ui.kTemplate->addItem(r.at(1), r.at(0));
246 }
247 }
248 }
249
onAddRule()250 void SKGSearchPluginWidget::onAddRule()
251 {
252 SKGError err;
253 SKGTRACEINFUNCRC(1, err) {
254 SKGRuleObject rule;
255 {
256 SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Search and process creation"), err)
257 rule = SKGRuleObject(getDocument());
258 IFOKDO(err, rule.setXMLSearchDefinition(ui.kQueryCreator->getXMLCondition()))
259 IFOKDO(err, rule.setOrder(-1))
260
261 QString xml = getXMLActionDefinition();
262 IFOKDO(err, rule.setActionType(xml.isEmpty() ? SKGRuleObject::SEARCH : SKGRuleObject::ActionType(ui.kWidgetSelector->getSelectedMode())))
263 IFOKDO(err, rule.setXMLActionDefinition(xml))
264 IFOKDO(err, rule.save())
265
266 // Send message
267 IFOKDO(err, rule.getDocument()->sendMessage(i18nc("An information to the user", "The search rule '%1' have been added", rule.getDisplayName()), SKGDocument::Hidden))
268 }
269
270 // status bar
271 IFOK(err) {
272 err = SKGError(0, i18nc("Successful message after an user action", "Search and process created"));
273 ui.kView->getView()->selectObject(rule.getUniqueID());
274 } else {
275 err.addError(ERR_FAIL, i18nc("Error message", "Search and process creation failed"));
276 }
277 }
278
279 // Display error
280 SKGMainPanel::displayErrorMessage(err, true);
281 }
282
onOpen()283 void SKGSearchPluginWidget::onOpen()
284 {
285 SKGError err;
286 SKGTRACEINFUNCRC(1, err)
287 SKGRuleObject rule;
288 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
289 rule = SKGRuleObject(getDocument());
290 IFOKDO(err, rule.setXMLSearchDefinition(ui.kQueryCreator->getXMLCondition()))
291 IFOKDO(err, rule.setOrder(-1))
292
293 QString xml = getXMLActionDefinition();
294 IFOKDO(err, rule.setActionType(xml.isEmpty() ? SKGRuleObject::SEARCH : SKGRuleObject::ActionType(ui.kWidgetSelector->getSelectedMode())))
295 IFOKDO(err, rule.setXMLActionDefinition(xml))
296 IFOK(err) open(rule, (sender() == ui.kOpenReport ? SKGSearchPluginWidget::REPORT : SKGSearchPluginWidget::TABLE));
297 QApplication::restoreOverrideCursor();
298
299 // Display error
300 SKGMainPanel::displayErrorMessage(err);
301 }
302
onModifyRule()303 void SKGSearchPluginWidget::onModifyRule()
304 {
305 SKGError err;
306 SKGTRACEINFUNCRC(1, err) {
307 SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Search and process update"), err)
308 SKGObjectBase::SKGListSKGObjectBase rules = getSelectedObjects();
309 if (rules.count() == 1) {
310 SKGRuleObject rule(rules.at(0));
311 IFOKDO(err, rule.setXMLSearchDefinition(ui.kQueryCreator->getXMLCondition()))
312 QString xml = getXMLActionDefinition();
313 IFOKDO(err, rule.setActionType(xml.isEmpty() ? SKGRuleObject::SEARCH : SKGRuleObject::ActionType(ui.kWidgetSelector->getSelectedMode())))
314 IFOKDO(err, rule.setXMLActionDefinition(xml))
315 IFOKDO(err, rule.save())
316
317 // Send message
318 IFOKDO(err, rule.getDocument()->sendMessage(i18nc("An information to the user", "The search rule '%1' have been updated", rule.getDisplayName()), SKGDocument::Hidden))
319 }
320 }
321
322 // status bar
323 IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Search and process updated")))
324 else {
325 err.addError(ERR_FAIL, i18nc("Error message", "Search and process update failed"));
326 }
327
328 // Display error
329 SKGMainPanel::displayErrorMessage(err, true);
330
331 // Set focus on table
332 ui.kView->getView()->setFocus();
333 }
334
onSelectionChanged()335 void SKGSearchPluginWidget::onSelectionChanged()
336 {
337 SKGObjectBase::SKGListSKGObjectBase selection = getSelectedObjects();
338 int nbSel = selection.count();
339
340 ui.kTopBtn->setEnabled(nbSel > 0);
341 ui.kUpBtn->setEnabled(nbSel > 0);
342 ui.kDownBtn->setEnabled(nbSel > 0);
343 ui.kBottomBtn->setEnabled(nbSel > 0);
344 ui.kUpdate->setEnabled(nbSel == 1);
345 ui.kApply->setEnabled(nbSel > 0);
346
347 if (nbSel > 0) {
348 SKGRuleObject rule(selection.at(0));
349 ui.kQueryCreator->setXMLCondition(rule.getXMLSearchDefinition());
350
351 int index = qMax(0, static_cast<int>(rule.getActionType()));
352 if (ui.kWidgetSelector->getSelectedMode() != -1) {
353 ui.kWidgetSelector->setSelectedMode(index);
354 }
355 if (index == 1) {
356 // Set update mode
357 ui.kActionCreator->setXMLCondition(rule.getXMLActionDefinition());
358 } else if (index == 2) {
359 // Set alarm mode
360 QDomDocument doc(QStringLiteral("SKGML"));
361 doc.setContent(rule.getXMLActionDefinition());
362
363 QDomElement element = doc.documentElement();
364 QDomElement elementLine = element.firstChild().toElement();
365 QDomElement elementElement = elementLine.firstChild().toElement();
366 ui.kAlarmAmount->setValue(SKGServices::stringToDouble(elementElement.attribute(QStringLiteral("value"))));
367 ui.kAlarmMessage->setText(elementElement.attribute(QStringLiteral("value2")));
368 } else if (index == 3) {
369 // Set template mode
370 QDomDocument doc(QStringLiteral("SKGML"));
371 doc.setContent(rule.getXMLActionDefinition());
372
373 QDomElement element = doc.documentElement();
374 QDomElement elementLine = element.firstChild().toElement();
375 QDomElement elementElement = elementLine.firstChild().toElement();
376 ui.kTemplate->setCurrentIndex(ui.kTemplate->findData(elementElement.attribute(QStringLiteral("value"))));
377 }
378 }
379
380 onEditorModified();
381
382 Q_EMIT selectionChanged();
383 }
384
onTop()385 void SKGSearchPluginWidget::onTop()
386 {
387 SKGError err;
388 SKGTRACEINFUNCRC(1, err)
389
390 // Get rules
391 SKGObjectBase::SKGListSKGObjectBase rules = getSelectedObjects();
392 int nb = rules.count();
393 {
394 SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Search update"), err, nb)
395 for (int i = nb - 1; !err && i >= 0; --i) {
396 SKGRuleObject rule(rules.at(i));
397
398 double order = 1;
399 SKGStringListList result;
400 err = getDocument()->executeSelectSqliteOrder(QStringLiteral("SELECT min(f_sortorder) from rule"), result);
401 if (!err && result.count() == 2) {
402 order = SKGServices::stringToDouble(result.at(1).at(0)) - 1;
403 }
404
405 IFOKDO(err, rule.setOrder(order))
406 IFOKDO(err, rule.save())
407
408 // Send message
409 IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The search '%1' has been updated", rule.getDisplayName()), SKGDocument::Hidden))
410
411 IFOKDO(err, getDocument()->stepForward(i + 1))
412 }
413 }
414
415 // status bar
416 IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Search updated")))
417 else {
418 err.addError(ERR_FAIL, i18nc("Error message", "Search update failed"));
419 }
420
421 // Display error
422 SKGMainPanel::displayErrorMessage(err);
423 }
424
onUp()425 void SKGSearchPluginWidget::onUp()
426 {
427 SKGError err;
428 SKGTRACEINFUNCRC(1, err)
429
430 // Get rules
431 SKGObjectBase::SKGListSKGObjectBase rules = getSelectedObjects();
432 int nb = rules.count();
433 {
434 SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Search update"), err, nb)
435 for (int i = 0; !err && i < nb; ++i) {
436 SKGRuleObject rule(rules.at(i));
437
438 double order = rule.getOrder();
439 SKGStringListList result;
440 err = getDocument()->executeSelectSqliteOrder("SELECT f_sortorder from rule where f_sortorder<" % SKGServices::doubleToString(order) % " ORDER BY f_sortorder DESC", result);
441 IFOK(err) {
442 if (result.count() == 2) {
443 order = SKGServices::stringToDouble(result.at(1).at(0)) - 1;
444 } else if (result.count() >= 2) {
445 order = (SKGServices::stringToDouble(result.at(1).at(0)) + SKGServices::stringToDouble(result.at(2).at(0))) / 2;
446 }
447 }
448
449 IFOKDO(err, rule.setOrder(order))
450 IFOKDO(err, rule.save())
451
452 // Send message
453 IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The search '%1' has been updated", rule.getDisplayName()), SKGDocument::Hidden))
454
455 IFOKDO(err, getDocument()->stepForward(i + 1))
456 }
457 }
458
459 // status bar
460 IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Search updated")))
461 else {
462 err.addError(ERR_FAIL, i18nc("Error message", "Search update failed"));
463 }
464
465 // Display error
466 SKGMainPanel::displayErrorMessage(err);
467 }
468
onDown()469 void SKGSearchPluginWidget::onDown()
470 {
471 SKGError err;
472 SKGTRACEINFUNCRC(1, err)
473
474 // Get rules
475 SKGObjectBase::SKGListSKGObjectBase rules = getSelectedObjects();
476 int nb = rules.count();
477 {
478 SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Search update"), err, nb)
479 for (int i = nb - 1; !err && i >= 0; --i) {
480 SKGRuleObject rule(rules.at(i));
481
482 double order = rule.getOrder();
483 SKGStringListList result;
484 err = getDocument()->executeSelectSqliteOrder("SELECT f_sortorder from rule where f_sortorder>" % SKGServices::doubleToString(order) % " ORDER BY f_sortorder ASC", result);
485 IFOK(err) {
486 if (result.count() == 2) {
487 order = SKGServices::stringToDouble(result.at(1).at(0)) + 1;
488 } else if (result.count() >= 2) {
489 order = (SKGServices::stringToDouble(result.at(1).at(0)) + SKGServices::stringToDouble(result.at(2).at(0))) / 2;
490 }
491 }
492
493 IFOKDO(err, rule.setOrder(order))
494 IFOKDO(err, rule.save())
495
496 // Send message
497 IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The search '%1' has been updated", rule.getDisplayName()), SKGDocument::Hidden))
498
499 IFOKDO(err, getDocument()->stepForward(i + 1))
500 }
501 }
502
503 // status bar
504 IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Search updated")))
505 else {
506 err.addError(ERR_FAIL, i18nc("Error message", "Search update failed"));
507 }
508
509 // Display error
510 SKGMainPanel::displayErrorMessage(err);
511 }
512
onBottom()513 void SKGSearchPluginWidget::onBottom()
514 {
515 SKGError err;
516 SKGTRACEINFUNCRC(1, err)
517
518 // Get rules
519 SKGObjectBase::SKGListSKGObjectBase rules = getSelectedObjects();
520 int nb = rules.count();
521 {
522 SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Search update"), err, nb)
523 for (int i = 0; !err && i < nb; ++i) {
524 SKGRuleObject rule(rules.at(i));
525
526 double order = 1;
527 SKGStringListList result;
528 err = getDocument()->executeSelectSqliteOrder(QStringLiteral("SELECT max(f_sortorder) from rule"), result);
529 if (!err && result.count() == 2) {
530 order = SKGServices::stringToDouble(result.at(1).at(0)) + 1;
531 }
532
533 IFOKDO(err, rule.setOrder(order))
534 IFOKDO(err, rule.save())
535
536 // Send message
537 IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The search '%1' has been updated", rule.getDisplayName()), SKGDocument::Hidden))
538
539 IFOKDO(err, getDocument()->stepForward(i + 1))
540 }
541 }
542
543 // status bar
544 IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Search updated")))
545 else {
546 err.addError(ERR_FAIL, i18nc("Error message", "Search update failed"));
547 }
548
549 // Display error
550 SKGMainPanel::displayErrorMessage(err);
551 }
552
open(const SKGRuleObject & iRule,OpenMode iMode)553 void SKGSearchPluginWidget::open(const SKGRuleObject& iRule, OpenMode iMode)
554 {
555 _SKGTRACEINFUNC(10)
556
557 // Build where clause and title
558 QString wc = "i_SUBOPID in (SELECT i_SUBOPID FROM v_operation_prop WHERE " % iRule.getSelectSqlOrder() % ')';
559 QString title = i18nc("Noun, a list of items", "Sub operations corresponding to rule '%1'", iRule.getSearchDescription());
560
561 // Call operation plugin
562 QDomDocument doc(QStringLiteral("SKGML"));
563 doc.setContent(SKGMainPanel::getMainPanel()->getDocument()->getParameter(iMode == TABLE ? QStringLiteral("SKGOPERATION_CONSOLIDATED_DEFAULT_PARAMETERS") : QStringLiteral("SKGREPORT_DEFAULT_PARAMETERS")));
564 QDomElement root = doc.documentElement();
565 if (root.isNull()) {
566 root = doc.createElement(QStringLiteral("parameters"));
567 doc.appendChild(root);
568 }
569
570 root.setAttribute(QStringLiteral("operationWhereClause"), wc);
571 root.setAttribute(QStringLiteral("title"), title);
572 root.setAttribute(QStringLiteral("title_icon"), QStringLiteral("edit-find"));
573
574 if (iMode == TABLE) {
575 root.setAttribute(QStringLiteral("operationTable"), QStringLiteral("v_suboperation_consolidated"));
576 root.setAttribute(QStringLiteral("currentPage"), QStringLiteral("-1"));
577 SKGMainPanel::getMainPanel()->openPage(SKGMainPanel::getMainPanel()->getPluginByName(QStringLiteral("Skrooge operation plugin")), -1, doc.toString(), i18nc("Noun, a list of items", "Sub operations"));
578 } else {
579 root.setAttribute(QStringLiteral("period"), QStringLiteral("0"));
580 SKGMainPanel::getMainPanel()->openPage(SKGMainPanel::getMainPanel()->getPluginByName(QStringLiteral("Skrooge report plugin")), -1, doc.toString());
581 }
582 }
583
onEditorModified()584 void SKGSearchPluginWidget::onEditorModified()
585 {
586 SKGObjectBase::SKGListSKGObjectBase selection = getSelectedObjects();
587 int nbSelect = selection.count();
588 ui.kUpdate->setEnabled(nbSelect == 1);
589 ui.kQueryInfo->setText(QLatin1String(""));
590
591 if (nbSelect == 1) {
592 SKGRuleObject rule(selection.at(0));
593
594 // Build where clause and title
595 QString wc = rule.getSelectSqlOrder();
596
597 SKGStringListList result;
598 int vAll = 0;
599 getDocument()->executeSelectSqliteOrder("SELECT count(distinct(id)) from v_operation_prop WHERE " % wc, result);
600 if (result.count() == 2) {
601 vAll = SKGServices::stringToInt(result.at(1).at(0));
602 }
603
604 int vNotChecked = 0;
605 getDocument()->executeSelectSqliteOrder("SELECT count(distinct(id)) from v_operation_prop WHERE t_status!='Y' AND " % wc, result);
606 if (result.count() == 2) {
607 vNotChecked = SKGServices::stringToInt(result.at(1).at(0));
608 }
609
610 int vImported = 0;
611 getDocument()->executeSelectSqliteOrder("SELECT count(distinct(id)) from v_operation_prop WHERE t_imported!='N' AND " % wc, result);
612 if (result.count() == 2) {
613 vImported = SKGServices::stringToInt(result.at(1).at(0));
614 }
615
616 int vNotValidatedl = 0;
617 getDocument()->executeSelectSqliteOrder("SELECT count(distinct(id)) from v_operation_prop WHERE t_imported='P' AND " % wc, result);
618 if (result.count() == 2) {
619 vNotValidatedl = SKGServices::stringToInt(result.at(1).at(0));
620 }
621
622 ui.kQueryInfo->setText(i18np("%1 operation found (%2 imported, %3 not yet validated, %4 not checked).", "%1 operations found (%2 imported, %3 not yet validated, %4 not checked).", vAll, vImported, vNotValidatedl, vNotChecked));
623 }
624 }
625
cleanEditor()626 void SKGSearchPluginWidget::cleanEditor()
627 {
628 if (getNbSelectedObjects() == 0) {
629 ui.kQueryCreator->clearContents();
630 ui.kActionCreator->clearContents();
631 }
632 }
633
getXMLActionDefinition()634 QString SKGSearchPluginWidget::getXMLActionDefinition()
635 {
636 QString output;
637 if (ui.kWidgetSelector->getSelectedMode() == 1) {
638 // Mode update
639 output = ui.kActionCreator->getXMLCondition();
640 } else if (ui.kWidgetSelector->getSelectedMode() == 2) {
641 // Mode alarm
642 QDomDocument doc(QStringLiteral("SKGML"));
643 QDomElement element = doc.createElement(QStringLiteral("element"));
644 doc.appendChild(element);
645
646 QDomElement elementLine = doc.createElement(QStringLiteral("element"));
647 element.appendChild(elementLine);
648
649 QDomElement elementElement = doc.createElement(QStringLiteral("element"));
650 elementLine.appendChild(elementElement);
651
652 elementElement.setAttribute(QStringLiteral("attribute"), QStringLiteral("f_REALCURRENTAMOUNT"));
653 elementElement.setAttribute(QStringLiteral("operator"), QStringLiteral("ABS(TOTAL(#ATT#))#OP##V1#,ABS(TOTAL(#ATT#)), #V1#, '#V2S#'"));
654 elementElement.setAttribute(QStringLiteral("operator2"), QStringLiteral(">="));
655 elementElement.setAttribute(QStringLiteral("value"), SKGServices::doubleToString(ui.kAlarmAmount->value()));
656 elementElement.setAttribute(QStringLiteral("value2"), ui.kAlarmMessage->text());
657
658 output = doc.toString();
659 } else if (ui.kWidgetSelector->getSelectedMode() == 3) {
660 // Mode template
661 QDomDocument doc(QStringLiteral("SKGML"));
662 QDomElement element = doc.createElement(QStringLiteral("element"));
663 doc.appendChild(element);
664
665 QDomElement elementLine = doc.createElement(QStringLiteral("element"));
666 element.appendChild(elementLine);
667
668 QDomElement elementElement = doc.createElement(QStringLiteral("element"));
669 elementLine.appendChild(elementElement);
670
671 elementElement.setAttribute(QStringLiteral("attribute"), QStringLiteral("id"));
672 elementElement.setAttribute(QStringLiteral("operator"), QStringLiteral("APPLYTEMPLATE(#V1#)"));
673 elementElement.setAttribute(QStringLiteral("value"), ui.kTemplate->itemData(ui.kTemplate->currentIndex()).toString());
674 elementElement.setAttribute(QStringLiteral("value2"), ui.kTemplate->currentText());
675
676 output = doc.toString();
677 }
678 return output;
679 }
680
isEditor()681 bool SKGSearchPluginWidget::isEditor()
682 {
683 return true;
684 }
685
activateEditor()686 void SKGSearchPluginWidget::activateEditor()
687 {
688 if (ui.kWidgetSelector->getSelectedMode() == -1) {
689 ui.kWidgetSelector->setSelectedMode(0);
690 }
691 }
692
693
694
695
696