File indexing completed on 2024-05-26 05:10:42
0001 /*************************************************************************** 0002 * SPDX-FileCopyrightText: 2022 S. MANKOWSKI stephane@mankowski.fr 0003 * SPDX-FileCopyrightText: 2022 G. DE BURE support@mankowski.fr 0004 * SPDX-License-Identifier: GPL-3.0-or-later 0005 ***************************************************************************/ 0006 /** @file 0007 * A skrooge plugin to payee transactions 0008 * 0009 * @author Stephane MANKOWSKI 0010 */ 0011 #include "skgpayeeplugin.h" 0012 0013 #include <kaboutdata.h> 0014 #include <kactioncollection.h> 0015 #include <kpluginfactory.h> 0016 #include <kstandardaction.h> 0017 0018 #include "skgdocumentbank.h" 0019 #include "skgpayee_settings.h" 0020 #include "skgpayeepluginwidget.h" 0021 #include "skgtraces.h" 0022 #include "skgtransactionmng.h" 0023 0024 /** 0025 * This plugin factory. 0026 */ 0027 K_PLUGIN_CLASS_WITH_JSON(SKGPayeePlugin, "metadata.json") 0028 0029 SKGPayeePlugin::SKGPayeePlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/) : SKGInterfacePlugin(iParent), m_currentBankDocument(nullptr) 0030 { 0031 Q_UNUSED(iWidget) 0032 SKGTRACEINFUNC(10) 0033 } 0034 0035 SKGPayeePlugin::~SKGPayeePlugin() 0036 { 0037 SKGTRACEINFUNC(10) 0038 m_currentBankDocument = nullptr; 0039 } 0040 0041 bool SKGPayeePlugin::setupActions(SKGDocument* iDocument) 0042 { 0043 SKGTRACEINFUNC(10) 0044 0045 if (qobject_cast<SKGDocumentBank*>(iDocument) == nullptr) { 0046 return false; 0047 } 0048 0049 m_currentBankDocument = iDocument; 0050 0051 setComponentName(QStringLiteral("skrooge_payee"), title()); 0052 setXMLFile(QStringLiteral("skrooge_payee.rc")); 0053 0054 // Actions 0055 QStringList overlaydelete; 0056 overlaydelete.push_back(QStringLiteral("edit-delete")); 0057 0058 auto deleteUnusedPayeesAction = new QAction(SKGServices::fromTheme(icon(), overlaydelete), i18nc("Verb", "Delete unused payees"), this); 0059 connect(deleteUnusedPayeesAction, &QAction::triggered, this, &SKGPayeePlugin::deleteUnusedPayees); 0060 registerGlobalAction(QStringLiteral("clean_delete_unused_payees"), deleteUnusedPayeesAction); 0061 0062 // ------------ 0063 auto actTmp = new QAction(SKGServices::fromTheme(icon()), i18nc("Verb", "Open similar payees…"), this); 0064 actTmp->setData(QString("skg://skrooge_payee_plugin/?title_icon=" % icon() % "&title=" % SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Similar payees")) % 0065 "&whereClause=" % SKGServices::encodeForUrl(QStringLiteral("EXISTS (SELECT 1 FROM payee p2 WHERE p2.id<>v_payee_display.id AND upper(p2.t_name)=upper(v_payee_display.t_name) AND p2.t_name<>v_payee_display.t_name)")))); 0066 connect(actTmp, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() { 0067 SKGMainPanel::getMainPanel()->SKGMainPanel::openPage(); 0068 }); 0069 registerGlobalAction(QStringLiteral("view_open_similar_payees"), actTmp); 0070 0071 return true; 0072 } 0073 0074 SKGTabPage* SKGPayeePlugin::getWidget() 0075 { 0076 SKGTRACEINFUNC(10) 0077 return new SKGPayeePluginWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument); 0078 } 0079 0080 KConfigSkeleton* SKGPayeePlugin::getPreferenceSkeleton() 0081 { 0082 return skgpayee_settings::self(); 0083 } 0084 0085 QString SKGPayeePlugin::title() const 0086 { 0087 return i18nc("Noun, something that is used to track items", "Payees"); 0088 } 0089 0090 QString SKGPayeePlugin::icon() const 0091 { 0092 return QStringLiteral("user-group-properties"); 0093 } 0094 0095 QString SKGPayeePlugin::toolTip() const 0096 { 0097 return i18nc("A tool tip", "Payees management"); 0098 } 0099 0100 int SKGPayeePlugin::getOrder() const 0101 { 0102 return 28; 0103 } 0104 0105 QStringList SKGPayeePlugin::tips() const 0106 { 0107 QStringList output; 0108 output.push_back(i18nc("Description of a tips", "<p>… <a href=\"skg://skrooge_payee_plugin\">payees</a> can be merged by drag & drop.</p>")); 0109 return output; 0110 } 0111 0112 bool SKGPayeePlugin::isInPagesChooser() const 0113 { 0114 return true; 0115 } 0116 0117 SKGAdviceList SKGPayeePlugin::advice(const QStringList& iIgnoredAdvice) 0118 { 0119 SKGTRACEINFUNC(10) 0120 SKGAdviceList output; 0121 // Check unused payee 0122 if (!iIgnoredAdvice.contains(QStringLiteral("skgpayeeplugin_unused"))) { 0123 bool exist = false; 0124 m_currentBankDocument->existObjects(QStringLiteral("payee LEFT JOIN operation ON operation.r_payee_id=payee.id"), QStringLiteral("operation.id IS NULL"), exist); 0125 if (exist) { 0126 SKGAdvice ad; 0127 ad.setUUID(QStringLiteral("skgpayeeplugin_unused")); 0128 ad.setPriority(5); 0129 ad.setShortMessage(i18nc("Advice on making the best (short)", "Many unused payees")); 0130 ad.setLongMessage(i18nc("Advice on making the best (long)", "You can improve performances by removing payees for which no transaction is registered.")); 0131 SKGAdvice::SKGAdviceActionList autoCorrections; 0132 { 0133 SKGAdvice::SKGAdviceAction a; 0134 a.Title = QStringLiteral("skg://clean_delete_unused_payees"); 0135 a.IsRecommended = true; 0136 autoCorrections.push_back(a); 0137 } 0138 ad.setAutoCorrections(autoCorrections); 0139 output.push_back(ad); 0140 } 0141 } 0142 0143 // Check payee with different case 0144 if (!iIgnoredAdvice.contains(QStringLiteral("skgpayeeplugin_case"))) { 0145 bool exist = false; 0146 m_currentBankDocument->existObjects(QStringLiteral("payee"), QStringLiteral("EXISTS (SELECT 1 FROM payee p2 WHERE p2.id>payee.id AND p2.t_name=payee.t_name COLLATE NOCASE AND p2.t_name<>payee.t_name)"), exist); 0147 if (exist) { 0148 SKGAdvice ad; 0149 ad.setUUID(QStringLiteral("skgpayeeplugin_case")); 0150 ad.setPriority(3); 0151 ad.setShortMessage(i18nc("Advice on making the best (short)", "Some payees seem to be identical")); 0152 ad.setLongMessage(i18nc("Advice on making the best (long)", "Some payee seem to be identical but with different syntax. They could be merged.")); 0153 QStringList autoCorrections; 0154 autoCorrections.push_back(QStringLiteral("skg://view_open_similar_payees")); 0155 ad.setAutoCorrections(autoCorrections); 0156 output.push_back(ad); 0157 } 0158 } 0159 return output; 0160 } 0161 0162 void SKGPayeePlugin::deleteUnusedPayees() const 0163 { 0164 SKGError err; 0165 _SKGTRACEINFUNCRC(10, err) 0166 if (m_currentBankDocument != nullptr) { 0167 SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Delete unused payees"), err) 0168 0169 // Modification of payee object 0170 QString sql = QStringLiteral("DELETE FROM payee WHERE id IN (SELECT payee.id FROM payee LEFT JOIN operation ON operation.r_payee_id=payee.id WHERE operation.id IS NULL)"); 0171 err = m_currentBankDocument->executeSqliteOrder(sql); 0172 } 0173 0174 // status bar 0175 IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Unused payees deleted"))) 0176 else { 0177 err.addError(ERR_FAIL, i18nc("Error message", "Unused payees deletion failed")); 0178 } 0179 0180 // Display error 0181 SKGMainPanel::displayErrorMessage(err); 0182 } 0183 0184 #include <skgpayeeplugin.moc>