From e2ff28f8831356f6a0a9f383f2425302ca8c1179 Mon Sep 17 00:00:00 2001 From: Azmi TOUIL <42934070+AzmiTouil@users.noreply.github.com> Date: Fri, 6 Sep 2024 10:27:25 +0200 Subject: [PATCH 01/16] feat: Manage Wallet from rewards management page - MEED-7380 - Meeds-io#154 (#553) This PR will allow admin to Manage Wallet from rewards management page. --- .../locale/addon/Wallet_en.properties | 7 + .../wallet-reward/components/RewardApp.vue | 402 ++---------------- .../components/reward/BudgetConfiguration.vue | 43 ++ .../components/reward/CurrentBalance.vue | 135 ++++++ .../components/reward/RewardManagement.vue | 37 ++ .../vue-app/wallet-reward/initComponents.js | 6 + 6 files changed, 256 insertions(+), 374 deletions(-) create mode 100644 wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/BudgetConfiguration.vue create mode 100644 wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/CurrentBalance.vue create mode 100644 wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardManagement.vue diff --git a/wallet-services/src/main/resources/locale/addon/Wallet_en.properties b/wallet-services/src/main/resources/locale/addon/Wallet_en.properties index 1f4532e04..33fd07988 100644 --- a/wallet-services/src/main/resources/locale/addon/Wallet_en.properties +++ b/wallet-services/src/main/resources/locale/addon/Wallet_en.properties @@ -494,6 +494,13 @@ wallet.administration.initialFundsMessagePlaceholder=Enter a default message to wallet.administration.apply=Apply wallet.administration.cancel=Cancel wallet.administration.reset=Reset +wallet.administration.fundWallet=Fund Wallet +wallet.administration.manageWallet=Manage wallet +wallet.administration.budgetConfiguration=Budget Configuration +wallet.administration.budgetConfiguration.setUp=Setup the Rewarding Budget +wallet.administration.budgetConfiguration.setBudget=Set Budget +wallet.administration.rewardManagement=Reward Management +wallet.administration.rewardManagement.noContributionsYet=No contributions to reward yet wallet.overview.rewards.title=Wallet History wallet.overview.points=Points diff --git a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/RewardApp.vue b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/RewardApp.vue index 1809918ea..bda65a548 100644 --- a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/RewardApp.vue +++ b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/RewardApp.vue @@ -1,382 +1,36 @@ - - diff --git a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/BudgetConfiguration.vue b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/BudgetConfiguration.vue new file mode 100644 index 000000000..dd54d856e --- /dev/null +++ b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/BudgetConfiguration.vue @@ -0,0 +1,43 @@ + + \ No newline at end of file diff --git a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/CurrentBalance.vue b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/CurrentBalance.vue new file mode 100644 index 000000000..90acb3f2b --- /dev/null +++ b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/CurrentBalance.vue @@ -0,0 +1,135 @@ + + + \ No newline at end of file diff --git a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardManagement.vue b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardManagement.vue new file mode 100644 index 000000000..3861414e5 --- /dev/null +++ b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardManagement.vue @@ -0,0 +1,37 @@ + + \ No newline at end of file diff --git a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/initComponents.js b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/initComponents.js index d203667e5..50b9e23d4 100644 --- a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/initComponents.js +++ b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/initComponents.js @@ -1,4 +1,7 @@ import RewardApp from './components/RewardApp.vue'; +import RewardManagement from './components/reward/RewardManagement.vue'; +import CurrentBalance from './components/reward/CurrentBalance.vue'; +import BudgetConfiguration from './components/reward/BudgetConfiguration.vue'; import RewardDetailModal from './components/reward/modal/RewardDetailModal.vue'; import TimeZoneSelectBox from './components/reward/TimeZoneSelectBox.vue'; import ConfigurationTab from './components/reward/ConfigurationTab.vue'; @@ -8,6 +11,9 @@ import TeamsListTab from './components/reward/TeamsListTab.vue'; const components = { 'wallet-reward-app': RewardApp, + 'wallet-reward-management': RewardManagement, + 'wallet-current-balance': CurrentBalance, + 'wallet-budget-configuration': BudgetConfiguration, 'wallet-reward-reward-detail-modal': RewardDetailModal, 'wallet-reward-timezone-selectbox': TimeZoneSelectBox, 'wallet-reward-configuration-tab': ConfigurationTab, From bc43fd898b8dfb726b977488362438ec36ac97dc Mon Sep 17 00:00:00 2001 From: Azmi TOUIL <42934070+AzmiTouil@users.noreply.github.com> Date: Wed, 11 Sep 2024 16:09:12 +0200 Subject: [PATCH 02/16] feat: Suggest to create a rewarding budget - MEED-7379 - Meeds-io/MIPs#154 (#554) Ability for rewarding admin to create/update reward budget --- pom.xml | 11 +- .../wallet/model/reward/RewardPeriod.java | 2 +- .../wallet/model/reward/RewardSettings.java | 23 +- .../model/reward/WalletPluginReward.java | 3 - .../wallet/model/reward/WalletReward.java | 8 - .../reward/rest/RewardSettingsREST.java | 2 +- .../reward/service/RewardReportService.java | 2 + .../reward/service/RewardSettingsService.java | 33 +- wallet-reward-services/pom.xml | 30 +- .../entity/WalletRewardPluginEntity.java | 23 - .../RewardSuccessNotificationPlugin.java | 17 +- .../service/WalletRewardReportService.java | 303 ++---- .../service/WalletRewardSettingsService.java | 85 +- .../storage/WalletRewardReportStorage.java | 7 +- .../portal/wallet-reward-configuration.xml | 14 - .../wallet/reward/BaseRewardTest.java | 64 ++ .../wallet/reward/BaseWalletRewardTest.java | 30 - .../reward/job/WalletRewardJobTest.java | 40 +- .../RewardSuccessNotificationPluginTest.java | 62 +- .../RewardSuccessTemplateBuilderTest.java | 60 +- .../RewardSuccessTemplateProviderTest.java | 46 +- .../WalletRewardReportServiceTest.java | 937 ++---------------- .../WalletRewardSettingsServiceTest.java | 172 +--- .../conf/test-wallet-reward-configuration.xml | 134 --- .../src/main/resources/jpa-entities.idx | 6 + .../locale/addon/Wallet_en.properties | 31 + wallet-webapps/pom.xml | 6 + .../io/meeds/wallet/WalletApplication.java | 43 + .../vue-app/wallet-common/js/RewardService.js | 3 +- .../wallet-reward/components/RewardApp.vue | 59 +- .../components/reward/BudgetConfiguration.vue | 185 +++- .../reward/BudgetConfigurationDrawer.vue | 236 +++++ .../components/reward/ConfigurationTab.vue | 243 ----- .../components/reward/CurrentBalance.vue | 9 +- .../reward/DistributionForecast.vue | 114 +++ .../components/reward/SendRewardsTab.vue | 520 ---------- .../components/reward/TeamForm.vue | 551 ---------- .../components/reward/TeamsListTab.vue | 341 ------- .../components/reward/TimeZoneSelectBox.vue | 32 +- .../reward/modal/RewardDetailModal.vue | 110 -- .../vue-app/wallet-reward/initComponents.js | 14 +- 41 files changed, 1147 insertions(+), 3464 deletions(-) create mode 100644 wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/BaseRewardTest.java create mode 100644 wallet-services/src/main/resources/jpa-entities.idx create mode 100644 wallet-webapps/src/main/java/io/meeds/wallet/WalletApplication.java create mode 100644 wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/BudgetConfigurationDrawer.vue delete mode 100644 wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/ConfigurationTab.vue create mode 100644 wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/DistributionForecast.vue delete mode 100644 wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/SendRewardsTab.vue delete mode 100644 wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/TeamForm.vue delete mode 100644 wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/TeamsListTab.vue delete mode 100644 wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/modal/RewardDetailModal.vue diff --git a/pom.xml b/pom.xml index db35025f5..ea471ce6c 100644 --- a/pom.xml +++ b/pom.xml @@ -50,7 +50,8 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 1.3.0 7.0.x-meed-SNAPSHOT 7.0.x-meed-SNAPSHOT - + 7.0.x-meed-SNAPSHOT + meeds-io @@ -71,7 +72,13 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. pom import - + + io.meeds.gamification + gamification + ${addon.meeds.gamification.version} + pom + import + io.meeds.analytics analytics-parent diff --git a/wallet-api/src/main/java/org/exoplatform/wallet/model/reward/RewardPeriod.java b/wallet-api/src/main/java/org/exoplatform/wallet/model/reward/RewardPeriod.java index 9f91400cf..f5bf8bf5e 100644 --- a/wallet-api/src/main/java/org/exoplatform/wallet/model/reward/RewardPeriod.java +++ b/wallet-api/src/main/java/org/exoplatform/wallet/model/reward/RewardPeriod.java @@ -62,7 +62,7 @@ public static RewardPeriod getCurrentPeriod(RewardSettings rewardSettings) { public static RewardPeriod getPeriodOfTime(RewardSettings rewardSettings, LocalDate date) { ZoneId zoneId = rewardSettings == null ? ZoneId.systemDefault() : rewardSettings.zoneId(); - RewardPeriodType rewardPeriodType = null; + RewardPeriodType rewardPeriodType; if (rewardSettings == null || rewardSettings.getPeriodType() == null) { rewardPeriodType = RewardPeriodType.DEFAULT; } else { diff --git a/wallet-api/src/main/java/org/exoplatform/wallet/model/reward/RewardSettings.java b/wallet-api/src/main/java/org/exoplatform/wallet/model/reward/RewardSettings.java index 94afb6ca5..9ca4aa111 100644 --- a/wallet-api/src/main/java/org/exoplatform/wallet/model/reward/RewardSettings.java +++ b/wallet-api/src/main/java/org/exoplatform/wallet/model/reward/RewardSettings.java @@ -18,8 +18,6 @@ import java.io.Serializable; import java.time.ZoneId; -import java.util.HashSet; -import java.util.Set; import lombok.AllArgsConstructor; import lombok.Data; @@ -29,13 +27,20 @@ @NoArgsConstructor @AllArgsConstructor public class RewardSettings implements Serializable, Cloneable { - private static final long serialVersionUID = -8650247964730374760L; - private RewardPeriodType periodType = RewardPeriodType.DEFAULT; + private static final long serialVersionUID = -8650247964730374760L; - private String timeZone = ZoneId.systemDefault().getId(); + private RewardPeriodType periodType = RewardPeriodType.DEFAULT; - private Set pluginSettings; + private String timeZone = ZoneId.systemDefault().getId(); + + private RewardBudgetType budgetType = RewardBudgetType.DEFAULT;; + + private double threshold; + + private double amount; + + private boolean storedSetting; public ZoneId zoneId() { return ZoneId.of(timeZone); @@ -46,11 +51,7 @@ public RewardSettings clone() { // NOSONAR try { return (RewardSettings) super.clone(); } catch (CloneNotSupportedException e) { - @SuppressWarnings("unchecked") - Set clonedPluginSettings = - pluginSettings == null ? null - : (Set) new HashSet<>(pluginSettings).clone(); - return new RewardSettings(periodType, timeZone, clonedPluginSettings); + return new RewardSettings(periodType, timeZone, budgetType, threshold, amount, storedSetting); } } } diff --git a/wallet-api/src/main/java/org/exoplatform/wallet/model/reward/WalletPluginReward.java b/wallet-api/src/main/java/org/exoplatform/wallet/model/reward/WalletPluginReward.java index c6e9dd977..8b402b750 100644 --- a/wallet-api/src/main/java/org/exoplatform/wallet/model/reward/WalletPluginReward.java +++ b/wallet-api/src/main/java/org/exoplatform/wallet/model/reward/WalletPluginReward.java @@ -31,9 +31,6 @@ public class WalletPluginReward implements Serializable { private long identityId; - @Exclude - private boolean poolsUsed; - @Exclude private double points; diff --git a/wallet-api/src/main/java/org/exoplatform/wallet/model/reward/WalletReward.java b/wallet-api/src/main/java/org/exoplatform/wallet/model/reward/WalletReward.java index 71ea0baf0..31c5ff541 100644 --- a/wallet-api/src/main/java/org/exoplatform/wallet/model/reward/WalletReward.java +++ b/wallet-api/src/main/java/org/exoplatform/wallet/model/reward/WalletReward.java @@ -107,12 +107,4 @@ public double getTokensToSend() { return rewards.stream().mapToDouble(WalletPluginReward::getAmount).sum(); } } - - public double getPoolTokensToSend() { - if (rewards == null || rewards.isEmpty()) { - return 0; - } else { - return rewards.stream().filter(WalletPluginReward::isPoolsUsed).mapToDouble(WalletPluginReward::getAmount).sum(); - } - } } diff --git a/wallet-api/src/main/java/org/exoplatform/wallet/reward/rest/RewardSettingsREST.java b/wallet-api/src/main/java/org/exoplatform/wallet/reward/rest/RewardSettingsREST.java index 94c41c1ff..c0ee598cc 100644 --- a/wallet-api/src/main/java/org/exoplatform/wallet/reward/rest/RewardSettingsREST.java +++ b/wallet-api/src/main/java/org/exoplatform/wallet/reward/rest/RewardSettingsREST.java @@ -77,7 +77,7 @@ public RewardSettingsREST(RewardSettingsService rewardSettingsService) { public Response getSettings() { try { RewardSettings settings = rewardSettingsService.getSettings(); - return Response.ok(settings == null ? new RewardSettings() : settings).build(); + return Response.ok(settings).build(); } catch (Exception e) { LOG.error("Error getting reward settings", e); return Response.serverError().build(); diff --git a/wallet-api/src/main/java/org/exoplatform/wallet/reward/service/RewardReportService.java b/wallet-api/src/main/java/org/exoplatform/wallet/reward/service/RewardReportService.java index 4bb6fbbeb..d2eb21eb1 100644 --- a/wallet-api/src/main/java/org/exoplatform/wallet/reward/service/RewardReportService.java +++ b/wallet-api/src/main/java/org/exoplatform/wallet/reward/service/RewardReportService.java @@ -20,12 +20,14 @@ import java.util.List; import java.util.Set; +import org.springframework.stereotype.Service; import org.exoplatform.social.core.identity.model.Identity; import org.exoplatform.wallet.model.reward.*; /** * A storage service to save/load reward settings */ +@Service public interface RewardReportService { /** diff --git a/wallet-api/src/main/java/org/exoplatform/wallet/reward/service/RewardSettingsService.java b/wallet-api/src/main/java/org/exoplatform/wallet/reward/service/RewardSettingsService.java index 977e8525d..c2591c307 100644 --- a/wallet-api/src/main/java/org/exoplatform/wallet/reward/service/RewardSettingsService.java +++ b/wallet-api/src/main/java/org/exoplatform/wallet/reward/service/RewardSettingsService.java @@ -16,51 +16,26 @@ */ package org.exoplatform.wallet.reward.service; -import java.util.Collection; +import org.springframework.stereotype.Service; import org.exoplatform.wallet.model.reward.RewardSettings; -import org.exoplatform.wallet.reward.api.RewardPlugin; /** * A storage service to save/load reward transactions */ +@Service public interface RewardSettingsService { /** * @return the reward settings */ - public RewardSettings getSettings(); + RewardSettings getSettings(); /** * Save reward settings * * @param rewardSettingsToStore reward settings object */ - public void saveSettings(RewardSettings rewardSettingsToStore); - - /** - * @return configured reward settings plugins - */ - public Collection getRewardPlugins(); - - /** - * @param pluginId reward plugin id - * @return configured reward plugin identified by an id - */ - public RewardPlugin getRewardPlugin(String pluginId); - - /** - * Registers a reward plugin - * - * @param rewardPlugin reward component plugin - */ - public void registerPlugin(RewardPlugin rewardPlugin); - - /** - * Removes a previously registered reward plugin - * - * @param pluginId - */ - void unregisterPlugin(String pluginId); + void saveSettings(RewardSettings rewardSettingsToStore); } diff --git a/wallet-reward-services/pom.xml b/wallet-reward-services/pom.xml index ffbdfb230..703c89b95 100644 --- a/wallet-reward-services/pom.xml +++ b/wallet-reward-services/pom.xml @@ -25,7 +25,7 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. wallet-reward-services Meeds:: Add-on:: Wallet - Reward Services - 0.82 + 0.18 @@ -53,11 +53,39 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. analytics-api provided + + io.meeds.gamification + gamification-services + provided + + + io.meeds.social + social-component-service + test-jar + test + io.meeds.social social-component-notification + test-jar + test + + + org.springframework.boot + spring-boot-starter-test + test + + + com.vaadin.external.google + android-json + + + + + io.meeds.gamification + gamification-services test test-jar diff --git a/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/entity/WalletRewardPluginEntity.java b/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/entity/WalletRewardPluginEntity.java index 8040f350b..87ffb40ae 100644 --- a/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/entity/WalletRewardPluginEntity.java +++ b/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/entity/WalletRewardPluginEntity.java @@ -27,7 +27,6 @@ @Table(name = "ADDONS_WALLET_REWARD_PLUGIN") @NamedQueries({ @NamedQuery(name = "RewardPlugin.getRewardPluginsByRewardId", query = "SELECT rp FROM RewardPlugin rp WHERE rp.reward.id = :rewardId"), - @NamedQuery(name = "RewardPlugin.getRewardPluginsByRewardIdAndPluginId", query = "SELECT rp FROM RewardPlugin rp WHERE rp.reward.id = :rewardId AND rp.pluginId = :pluginId"), }) public class WalletRewardPluginEntity implements Serializable { @@ -39,12 +38,6 @@ public class WalletRewardPluginEntity implements Serializable { @Column(name = "REWARD_PLUGIN_ID") private Long id; - @Column(name = "PLUGIN_ID") - private String pluginId; - - @Column(name = "POOL_USED") - private boolean poolUsed; - @Column(name = "POINTS") private double points; @@ -63,22 +56,6 @@ public void setId(Long id) { this.id = id; } - public String getPluginId() { - return pluginId; - } - - public void setPluginId(String pluginId) { - this.pluginId = pluginId; - } - - public boolean isPoolUsed() { - return poolUsed; - } - - public void setPoolUsed(boolean poolUsed) { - this.poolUsed = poolUsed; - } - public double getPoints() { return points; } diff --git a/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/notification/RewardSuccessNotificationPlugin.java b/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/notification/RewardSuccessNotificationPlugin.java index 140ba7310..1bcafbc66 100644 --- a/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/notification/RewardSuccessNotificationPlugin.java +++ b/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/notification/RewardSuccessNotificationPlugin.java @@ -31,8 +31,17 @@ import org.exoplatform.wallet.model.ContractDetail; import org.exoplatform.wallet.model.reward.RewardPeriod; import org.exoplatform.wallet.model.reward.RewardReport; +import org.exoplatform.wallet.model.settings.GlobalSettings; +import org.exoplatform.wallet.service.WalletService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +@Component public class RewardSuccessNotificationPlugin extends BaseNotificationPlugin { + + @Autowired + protected WalletService walletService; + private static final Log LOG = ExoLogger.getLogger(RewardSuccessNotificationPlugin.class); public RewardSuccessNotificationPlugin(InitParams initParams) { @@ -60,11 +69,15 @@ protected NotificationInfo makeNotification(NotificationContext ctx) { LOG.error("Error making notification of reward report " + rewardReport, e); return null; } - if (recipients == null || recipients.isEmpty()) { + if (recipients.isEmpty()) { return null; } - ContractDetail contractDetail = getContractDetail(); + GlobalSettings globalSettings = walletService.getSettings(); + if (globalSettings == null || globalSettings.getContractDetail() == null) { + return null; + } + ContractDetail contractDetail = globalSettings.getContractDetail(); RewardPeriod period = rewardReport.getPeriod(); return NotificationInfo.instance() diff --git a/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/service/WalletRewardReportService.java b/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/service/WalletRewardReportService.java index aff317b80..0f0cf1f92 100644 --- a/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/service/WalletRewardReportService.java +++ b/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/service/WalletRewardReportService.java @@ -18,7 +18,6 @@ import static org.exoplatform.wallet.utils.RewardUtils.REWARD_TRANSACTION_LABEL_KEY; import static org.exoplatform.wallet.utils.RewardUtils.REWARD_TRANSACTION_NO_POOL_MESSAGE_KEY; -import static org.exoplatform.wallet.utils.RewardUtils.REWARD_TRANSACTION_WITH_POOL_MESSAGE_KEY; import static org.exoplatform.wallet.utils.RewardUtils.TRANSACTION_STATUS_PENDING; import static org.exoplatform.wallet.utils.RewardUtils.TRANSACTION_STATUS_SUCCESS; import static org.exoplatform.wallet.utils.RewardUtils.formatTime; @@ -33,20 +32,11 @@ import java.math.BigInteger; import java.time.LocalDate; import java.time.ZoneId; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Set; -import java.util.function.Function; import java.util.stream.Collectors; +import io.meeds.gamification.service.RealizationService; import org.apache.commons.lang3.StringUtils; import org.exoplatform.commons.utils.CommonsUtils; @@ -59,7 +49,6 @@ import org.exoplatform.wallet.model.reward.RewardBudgetType; import org.exoplatform.wallet.model.reward.RewardPeriod; import org.exoplatform.wallet.model.reward.RewardPeriodType; -import org.exoplatform.wallet.model.reward.RewardPluginSettings; import org.exoplatform.wallet.model.reward.RewardReport; import org.exoplatform.wallet.model.reward.RewardSettings; import org.exoplatform.wallet.model.reward.RewardStatus; @@ -68,45 +57,47 @@ import org.exoplatform.wallet.model.reward.WalletPluginReward; import org.exoplatform.wallet.model.reward.WalletReward; import org.exoplatform.wallet.model.transaction.TransactionDetail; -import org.exoplatform.wallet.reward.api.RewardPlugin; import org.exoplatform.wallet.reward.storage.WalletRewardReportStorage; import org.exoplatform.wallet.service.WalletAccountService; import org.exoplatform.wallet.service.WalletTokenAdminService; import lombok.Setter; +import org.springframework.stereotype.Service; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; /** * A service to manage reward reports */ +@Service +@Primary public class WalletRewardReportService implements RewardReportService { private static final Log LOG = ExoLogger.getLogger(WalletRewardReportService.class); private static final String EMPTY_SETTINGS = "Error computing rewards using empty settings"; - private final WalletAccountService walletAccountService; + @Autowired + private WalletAccountService walletAccountService; + @Autowired private WalletTokenAdminService walletTokenAdminService; - private final RewardSettingsService rewardSettingsService; + @Autowired + private RewardSettingsService rewardSettingsService; - private final RewardTeamService rewardTeamService; + @Autowired + private RewardTeamService rewardTeamService; - private final WalletRewardReportStorage rewardReportStorage; + @Autowired + private WalletRewardReportStorage rewardReportStorage; + + @Autowired + private RealizationService realizationService; @Setter private boolean rewardSendingInProgress; - public WalletRewardReportService(WalletAccountService walletAccountService, - RewardSettingsService rewardSettingsService, - RewardTeamService rewardTeamService, - WalletRewardReportStorage rewardReportStorage) { - this.walletAccountService = walletAccountService; - this.rewardSettingsService = rewardSettingsService; - this.rewardTeamService = rewardTeamService; - this.rewardReportStorage = rewardReportStorage; - } - @Override public void sendRewards(LocalDate date, String username) throws Exception { // NOSONAR if (!isUserRewardingAdmin(username)) { @@ -117,7 +108,7 @@ public void sendRewards(LocalDate date, String username) throws Exception { // N throw new IllegalStateException("Can't send rewards for current period"); } - if (rewardReport == null || rewardReport.getRewards() == null || rewardReport.getRewards().isEmpty()) { + if (rewardReport.getRewards() == null || rewardReport.getRewards().isEmpty()) { return; } @@ -226,7 +217,10 @@ public RewardReport computeRewards(LocalDate date) { @Override public RewardReport computeRewardsByUser(LocalDate date, long userIdentityId) { RewardReport rewardReport = computeRewards(date); - Set rewards = rewardReport.getRewards().stream().filter(reward -> reward.getIdentityId() == userIdentityId).collect(Collectors.toSet()); + Set rewards = rewardReport.getRewards() + .stream() + .filter(reward -> reward.getIdentityId() == userIdentityId) + .collect(Collectors.toSet()); rewardReport.setRewards(rewards); return rewardReport; } @@ -236,7 +230,7 @@ public RewardReport getRewardReportByPeriodId(long periodId) { RewardSettings rewardSettings = rewardSettingsService.getSettings(); return rewardReportStorage.getRewardReportByPeriodId(periodId, rewardSettings.zoneId()); } - + @Override public RewardReport getRewardReport(LocalDate date) { RewardSettings rewardSettings = rewardSettingsService.getSettings(); @@ -247,9 +241,7 @@ public RewardReport getRewardReport(LocalDate date) { throw new IllegalStateException("Error computing rewards using empty period type"); } - return rewardReportStorage.getRewardReport(rewardSettings.getPeriodType(), - date, - rewardSettings.zoneId()); + return rewardReportStorage.getRewardReport(rewardSettings.getPeriodType(), date, rewardSettings.zoneId()); } @Override @@ -320,28 +312,18 @@ private RewardPeriod getRewardPeriod(LocalDate date) { private void computeRewardDetails(RewardReport rewardReport, Set wallets) { // Get te list of enabled reward plugins - Map rewardPlugins = getEnabledRewardPlugins(); RewardPeriod period = rewardReport.getPeriod(); Set walletRewards = retrieveWalletRewards(rewardReport, wallets); Set enabledRewards = walletRewards.stream().filter(WalletReward::isEnabled).collect(Collectors.toSet()); - Set enabledTeamRewards = enabledRewards.stream() - .filter(wr -> wr.getTeam() == null || !wr.getTeam().isDisabled()) - .collect(Collectors.toSet()); // Compute rewards per plugin Set walletRewardsByPlugin = new HashSet<>(); - for (Map.Entry pluginEntry : rewardPlugins.entrySet()) { - RewardPlugin plugin = pluginEntry.getKey(); - RewardPluginSettings pluginSettings = pluginEntry.getValue(); + RewardSettings rewardSettings = rewardSettingsService.getSettings(); - Set identityIds = walletRewards.stream().map(WalletReward::getIdentityId).collect(Collectors.toSet()); - Map earnedPoints = plugin.getEarnedPoints(identityIds, - period.getStartDateInSeconds(), - period.getEndDateInSeconds()); + Set identityIds = walletRewards.stream().map(WalletReward::getIdentityId).collect(Collectors.toSet()); + Map earnedPoints = getEarnedPoints(identityIds, period.getStartDateInSeconds(), period.getEndDateInSeconds()); - Set validWalletRewards = pluginSettings.isUsePools() ? enabledTeamRewards : enabledRewards; - computeReward(pluginSettings, earnedPoints, validWalletRewards, walletRewardsByPlugin); - } + computeReward(rewardSettings, earnedPoints, enabledRewards, walletRewardsByPlugin); // Assign rewards objects for each wallet,a wallet can have multiple rewards // one per plugin @@ -354,6 +336,24 @@ private void computeRewardDetails(RewardReport rewardReport, Set wallets } } + private Map getEarnedPoints(Set identityIds, long startDateInSeconds, long endDateInSeconds) { + HashMap earnedPoints = new HashMap<>(); + if (identityIds == null || identityIds.isEmpty()) { + return earnedPoints; + } + Date startDate = new Date(startDateInSeconds * 1000); + Date endDate = new Date(endDateInSeconds * 1000); + Map points = new HashMap<>(); + try { + points = realizationService.getScoresByIdentityIdsAndBetweenDates(identityIds.stream().map(Object::toString).toList(), + startDate, + endDate); + } catch (Exception e) { + LOG.warn("Error getting points for user with ids {}", identityIds, e); + } + return points.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().doubleValue())); + } + private Set retrieveWalletRewards(RewardReport rewardReport, Set wallets) { Set walletRewards = rewardReport.getRewards(); if (walletRewards == null) { @@ -367,15 +367,11 @@ private Set retrieveWalletRewards(RewardReport rewardReport, Set wallet != null && wr.getWallet() != null && wr.getIdentityId() == wallet.getTechnicalId()) .toList(); - WalletReward walletReward = walletRewardList.stream().filter(r -> r.getTransaction() != null).sorted((r2, r1) -> { - if (r1.getTokensSent() > r2.getTokensSent()) { - return 1; - } else if (r2.getTokensSent() > r1.getTokensSent()) { - return -1; - } else { - return 0; - } - }).findFirst().orElseGet(() -> walletRewardList.isEmpty() ? null : walletRewardList.get(0)); + WalletReward walletReward = + walletRewardList.stream() + .filter(r -> r.getTransaction() != null) + .min((r2, r1) -> Double.compare(r1.getTokensSent(), r2.getTokensSent())) + .orElseGet(() -> walletRewardList.isEmpty() ? null : walletRewardList.getFirst()); if (walletReward == null) { walletReward = new WalletReward(); walletRewards.add(walletReward); @@ -390,101 +386,62 @@ private Set retrieveWalletRewards(RewardReport rewardReport, Set getEnabledRewardPlugins() { - RewardSettings rewardSettings = rewardSettingsService.getSettings(); - final Set pluginSettings = rewardSettings.getPluginSettings() - .stream() - .filter(RewardPluginSettings::isEnabled) - .collect(Collectors.toSet()); - Collection rewardPlugins = rewardSettingsService.getRewardPlugins(); - return rewardPlugins.stream() - .filter(RewardPlugin::isEnabled) - .filter(rewardPlugin -> getPluginSetting(pluginSettings, rewardPlugin.getPluginId()) != null) - .collect(Collectors.toMap(Function.identity(), - rewardPlugin -> getPluginSetting(pluginSettings, rewardPlugin.getPluginId()))); - } - - private RewardPluginSettings getPluginSetting(Set pluginSettings, String pluginId) { - for (RewardPluginSettings rewardPluginSettings : pluginSettings) { - if (StringUtils.equals(pluginId, rewardPluginSettings.getPluginId())) { - return rewardPluginSettings; - } - } - return null; - } - - private void computeReward(RewardPluginSettings rewardPluginSettings, + private void computeReward(RewardSettings rewardSettings, Map earnedPoints, Set enabledRewards, Set rewardMemberDetails) { - RewardBudgetType budgetType = rewardPluginSettings.getBudgetType(); + RewardBudgetType budgetType = rewardSettings.getBudgetType(); if (budgetType == null) { - LOG.warn("Budget type of reward plugin {} is empty, thus no computing is possible", rewardPluginSettings.getPluginId()); + LOG.warn("Budget type of reward is empty, thus no computing is possible"); return; } - String pluginId = rewardPluginSettings.getPluginId(); - double configuredPluginAmount = rewardPluginSettings.getAmount(); + double configuredPluginAmount = rewardSettings.getAmount(); if (configuredPluginAmount < 0) { - throw new IllegalStateException("Plugin " + pluginId + " has a configured negative reward amount (" + configuredPluginAmount - + ")"); + throw new IllegalStateException("reward amount has a configured negative (" + configuredPluginAmount + ")"); } Set validIdentityIdsToUse = enabledRewards.stream().map(WalletReward::getIdentityId).collect(Collectors.toSet()); - // Filter non elligible users switch threshold - filterElligibleMembers(earnedPoints.entrySet(), validIdentityIdsToUse, rewardPluginSettings, rewardMemberDetails); + // Filter non-eligible users switch threshold + filterEligibleMembers(earnedPoints.entrySet(), validIdentityIdsToUse, rewardSettings, rewardMemberDetails); - double amountPerPoint = 0; - double totalFixedBudget = 0; + double amountPerPoint; + double totalFixedBudget; switch (budgetType) { case FIXED_PER_POINT: amountPerPoint = configuredPluginAmount; - addRewardsSwitchPointAmount(rewardMemberDetails, earnedPoints.entrySet(), pluginId, amountPerPoint); + addRewardsSwitchPointAmount(rewardMemberDetails, earnedPoints.entrySet(), amountPerPoint); break; case FIXED: totalFixedBudget = configuredPluginAmount; - addTeamMembersReward(rewardPluginSettings, earnedPoints, totalFixedBudget, rewardMemberDetails); + addTeamMembersReward(earnedPoints, totalFixedBudget, rewardMemberDetails); break; case FIXED_PER_MEMBER: - double budgetPerMember = configuredPluginAmount; - int totalElligibleMembersCount = earnedPoints.size(); - totalFixedBudget = budgetPerMember * totalElligibleMembersCount; - addTeamMembersReward(rewardPluginSettings, earnedPoints, totalFixedBudget, rewardMemberDetails); + int totalEligibleMembersCount = earnedPoints.size(); + totalFixedBudget = configuredPluginAmount * totalEligibleMembersCount; + addTeamMembersReward(earnedPoints, totalFixedBudget, rewardMemberDetails); break; default: - throw new IllegalStateException("Budget type is not recognized in plugin settings: " + pluginId + ", budget type = " - + budgetType); + throw new IllegalStateException("Budget type is not recognized, budget type = " + budgetType); } } - private void addTeamMembersReward(RewardPluginSettings rewardPluginSettings, - Map earnedPoints, + private void addTeamMembersReward(Map earnedPoints, double totalFixedBudget, Set rewardMemberDetails) { if (totalFixedBudget <= 0) { return; } double amountPerPoint; - if (rewardPluginSettings.isUsePools()) { - List teams = rewardTeamService.getTeams(); - Set identityIds = filterEligibleMembersAndTeams(teams, earnedPoints); - buildNoPoolUsers(earnedPoints, teams, identityIds); - computeTeamsMembersBudget(rewardPluginSettings.getPluginId(), teams, totalFixedBudget, rewardMemberDetails, earnedPoints); - } else { - double totalPoints = earnedPoints.entrySet().stream().collect(Collectors.summingDouble(Entry::getValue)); - if (totalPoints <= 0 || totalFixedBudget <= 0) { - return; - } - amountPerPoint = totalFixedBudget / totalPoints; - addRewardsSwitchPointAmount(rewardMemberDetails, - earnedPoints.entrySet(), - rewardPluginSettings.getPluginId(), - amountPerPoint); + double totalPoints = earnedPoints.values().stream().mapToDouble(v -> v).sum(); + if (totalPoints <= 0) { + return; } + amountPerPoint = totalFixedBudget / totalPoints; + addRewardsSwitchPointAmount(rewardMemberDetails, earnedPoints.entrySet(), amountPerPoint); } private void addRewardsSwitchPointAmount(Set rewardMemberDetails, Set> identitiesPointsEntries, - String pluginId, double amountPerPoint) { for (Entry identitiyPointsEntry : identitiesPointsEntries) { Long identityId = identitiyPointsEntry.getKey(); @@ -493,20 +450,17 @@ private void addRewardsSwitchPointAmount(Set rewardMemberDet WalletPluginReward rewardMemberDetail = new WalletPluginReward(); rewardMemberDetail.setIdentityId(identityId); - rewardMemberDetail.setPluginId(pluginId); rewardMemberDetail.setPoints(points); rewardMemberDetail.setAmount(amount); - rewardMemberDetail.setPoolsUsed(false); rewardMemberDetails.add(rewardMemberDetail); } } - private void filterElligibleMembers(Set> identitiesPointsEntries, - Set validIdentityIdsToUse, - RewardPluginSettings rewardPluginSettings, - Set rewardMemberDetails) { - String pluginId = rewardPluginSettings.getPluginId(); - double threshold = rewardPluginSettings.getThreshold(); + private void filterEligibleMembers(Set> identitiesPointsEntries, + Set validIdentityIdsToUse, + RewardSettings rewardSettings, + Set rewardMemberDetails) { + double threshold = rewardSettings.getThreshold(); Iterator> identitiesPointsIterator = identitiesPointsEntries.iterator(); while (identitiesPointsIterator.hasNext()) { @@ -515,8 +469,7 @@ private void filterElligibleMembers(Set> identitiesPointsEnt Double points = entry.getValue(); points = points == null ? 0 : points; if (points < 0) { - throw new IllegalStateException("Plugin with id " + pluginId + " has assigned a negative points (" + points - + ") to user with id " + identityId); + throw new IllegalStateException("Negative points has assigned (" + points + ") to user with id " + identityId); } if (points < threshold || points == 0 || !validIdentityIdsToUse.contains(identityId)) { @@ -528,68 +481,14 @@ private void filterElligibleMembers(Set> identitiesPointsEnt // Add member with earned points for information on UI WalletPluginReward rewardMemberDetail = new WalletPluginReward(); rewardMemberDetail.setIdentityId(identityId); - rewardMemberDetail.setPluginId(pluginId); rewardMemberDetail.setPoints(points); rewardMemberDetail.setAmount(0); - rewardMemberDetail.setPoolsUsed(rewardPluginSettings.isUsePools()); rewardMemberDetails.add(rewardMemberDetail); } } } } - private void computeTeamsMembersBudget(String pluginId, - List teams, - double totalTeamsBudget, - Set rewardMemberDetails, - Map earnedPoints) { - double totalFixedTeamsBudget = 0; - double computedRecipientsCount = 0; - List computedBudgetTeams = new ArrayList<>(); - Map totalPointsPerTeam = new HashMap<>(); - - // Compute teams budget with fixed amount - for (RewardTeam rewardTeam : teams) { - RewardBudgetType teamBudgetType = rewardTeam.getRewardType(); - if (rewardTeam.getMembers() == null || rewardTeam.getMembers().isEmpty()) { - continue; - } - double totalTeamPoints = rewardTeam.getMembers() - .stream() - .collect(Collectors.summingDouble(member -> earnedPoints.get(member.getIdentityId()))); - if (teamBudgetType == RewardBudgetType.COMPUTED) { - computedRecipientsCount += rewardTeam.getMembers().size(); - computedBudgetTeams.add(rewardTeam); - totalPointsPerTeam.put(rewardTeam.getId(), totalTeamPoints); - } else if (teamBudgetType == RewardBudgetType.FIXED_PER_MEMBER) { - double totalTeamBudget = rewardTeam.getBudget() * rewardTeam.getMembers().size(); - addTeamRewardRepartition(rewardTeam, totalTeamBudget, totalTeamPoints, pluginId, earnedPoints, rewardMemberDetails); - totalFixedTeamsBudget += totalTeamBudget; - } else if (teamBudgetType == RewardBudgetType.FIXED) { - double totalTeamBudget = rewardTeam.getBudget(); - addTeamRewardRepartition(rewardTeam, totalTeamBudget, totalTeamPoints, pluginId, earnedPoints, rewardMemberDetails); - totalFixedTeamsBudget += rewardTeam.getBudget(); - } - } - - if (totalFixedTeamsBudget >= totalTeamsBudget) { - throw new IllegalStateException("Total fixed teams budget is higher than fixed budget for all users"); - } - - // Compute teams budget with computed amount - if (computedRecipientsCount > 0 && !computedBudgetTeams.isEmpty()) { - double remaingBudgetForComputedTeams = totalTeamsBudget - totalFixedTeamsBudget; - double budgetPerTeamMember = remaingBudgetForComputedTeams / computedRecipientsCount; - computedBudgetTeams.forEach(rewardTeam -> { - if (rewardTeam.getMembers() != null && !rewardTeam.getMembers().isEmpty()) { - double totalTeamBudget = budgetPerTeamMember * rewardTeam.getMembers().size(); - Double totalTeamPoints = totalPointsPerTeam.get(rewardTeam.getId()); - addTeamRewardRepartition(rewardTeam, totalTeamBudget, totalTeamPoints, pluginId, earnedPoints, rewardMemberDetails); - } - }); - } - } - private void buildNoPoolUsers(Map earnedPoints, List teams, Set identityIds) { // Build "No pool" users ArrayList noPoolsIdentityIds = new ArrayList<>(earnedPoints.keySet()); @@ -648,7 +547,8 @@ private String getTransactionLabel(WalletReward walletReward, ContractDetail con .replace("{1}", formatNumber(walletReward.getTokensToSend(), locale.getLanguage())) .replace("{2}", contractDetail.getSymbol()) .replace("{3}", formatTime(periodOfTime.getStartDateInSeconds(), rewardSettings.zoneId(), locale.getLanguage())) - .replace("{4}", formatTime(periodOfTime.getEndDateInSeconds() - 1, rewardSettings.zoneId(), locale.getLanguage())); + .replace("{4}", + formatTime(periodOfTime.getEndDateInSeconds() - 1, rewardSettings.zoneId(), locale.getLanguage())); } private String getTransactionMessage(WalletReward walletReward, ContractDetail contractDetail, RewardPeriod periodOfTime) { @@ -659,32 +559,18 @@ private String getTransactionMessage(WalletReward walletReward, ContractDetail c ZoneId zoneId = rewardSettings.zoneId(); for (WalletPluginReward walletPluginReward : walletRewardsByPlugin) {// NOSONAR - String transactionMessagePart = null; - if (walletPluginReward.isPoolsUsed() && StringUtils.isNotBlank(walletReward.getPoolName())) { - String label = getResourceBundleKey(locale, REWARD_TRANSACTION_WITH_POOL_MESSAGE_KEY); - if (StringUtils.isBlank(label)) { - continue; - } - transactionMessagePart = label.replace("{0}", formatNumber(walletPluginReward.getAmount(), locale.getLanguage())) - .replace("{1}", contractDetail.getSymbol()) - .replace("{2}", formatNumber(walletPluginReward.getPoints(), locale.getLanguage())) - .replace("{3}", walletPluginReward.getPluginId()) - .replace("{4}", walletReward.getPoolName()) - .replace("{5}", formatTime(periodOfTime.getStartDateInSeconds(), zoneId, locale.getLanguage())) - .replace("{6}", formatTime(periodOfTime.getEndDateInSeconds() - 1, zoneId, locale.getLanguage())); - - } else { - String label = getResourceBundleKey(locale, REWARD_TRANSACTION_NO_POOL_MESSAGE_KEY); - if (StringUtils.isBlank(label)) { - continue; - } - transactionMessagePart = label.replace("{0}", formatNumber(walletPluginReward.getAmount(), locale.getLanguage())) - .replace("{1}", contractDetail.getSymbol()) - .replace("{2}", formatNumber(walletPluginReward.getPoints(), locale.getLanguage())) - .replace("{3}", walletPluginReward.getPluginId()) - .replace("{4}", formatTime(periodOfTime.getStartDateInSeconds(), zoneId, locale.getLanguage())) - .replace("{5}", formatTime(periodOfTime.getEndDateInSeconds() - 1, zoneId, locale.getLanguage())); + String transactionMessagePart; + String label = getResourceBundleKey(locale, REWARD_TRANSACTION_NO_POOL_MESSAGE_KEY); + if (StringUtils.isBlank(label)) { + continue; } + transactionMessagePart = + label.replace("{0}", formatNumber(walletPluginReward.getAmount(), locale.getLanguage())) + .replace("{1}", contractDetail.getSymbol()) + .replace("{2}", formatNumber(walletPluginReward.getPoints(), locale.getLanguage())) + .replace("{4}", formatTime(periodOfTime.getStartDateInSeconds(), zoneId, locale.getLanguage())) + .replace("{5}", + formatTime(periodOfTime.getEndDateInSeconds() - 1, zoneId, locale.getLanguage())); transactionMessage.append(transactionMessagePart); transactionMessage.append("\r\n"); @@ -695,7 +581,6 @@ private String getTransactionMessage(WalletReward walletReward, ContractDetail c private void addTeamRewardRepartition(RewardTeam rewardTeam, double totalTeamBudget, double totalTeamPoints, - String pluginId, Map earnedPoints, Set rewardMemberDetails) { if (rewardTeam.getMembers() == null || rewardTeam.getMembers().isEmpty() || totalTeamBudget <= 0 || totalTeamPoints <= 0) { @@ -709,10 +594,8 @@ private void addTeamRewardRepartition(RewardTeam rewardTeam, WalletPluginReward rewardMemberDetail = new WalletPluginReward(); rewardMemberDetail.setIdentityId(identityId); - rewardMemberDetail.setPluginId(pluginId); rewardMemberDetail.setPoints(points); rewardMemberDetail.setAmount(points * amountPerPoint); - rewardMemberDetail.setPoolsUsed(true); rewardMemberDetails.add(rewardMemberDetail); }); } diff --git a/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/service/WalletRewardSettingsService.java b/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/service/WalletRewardSettingsService.java index 1f449ff6e..f991e6e77 100644 --- a/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/service/WalletRewardSettingsService.java +++ b/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/service/WalletRewardSettingsService.java @@ -22,27 +22,25 @@ import java.util.*; -import org.apache.commons.lang3.StringUtils; - import org.exoplatform.commons.api.settings.SettingService; import org.exoplatform.commons.api.settings.SettingValue; import org.exoplatform.wallet.model.reward.*; -import org.exoplatform.wallet.reward.api.RewardPlugin; +import org.springframework.stereotype.Service; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; /** * A storage service to save/load reward transactions */ +@Service +@Primary public class WalletRewardSettingsService implements RewardSettingsService { + @Autowired private SettingService settingService; private RewardSettings configuredRewardSettings; - private Map rewardPlugins = new HashMap<>(); - - public WalletRewardSettingsService(SettingService settingService) { - this.settingService = settingService; - } @Override public RewardSettings getSettings() { // NOSONAR @@ -57,42 +55,13 @@ public RewardSettings getSettings() { // NOSONAR String settingsValueString = settingsValue == null || settingsValue.getValue() == null ? null : settingsValue.getValue().toString(); - RewardSettings rewardSettings = null; + RewardSettings rewardSettings; if (settingsValueString == null) { rewardSettings = new RewardSettings(); + rewardSettings.setStoredSetting(false); } else { rewardSettings = fromJsonString(settingsValueString, RewardSettings.class); - } - - Set pluginSettings = rewardSettings.getPluginSettings(); - if (pluginSettings == null) { - pluginSettings = new HashSet<>(); - rewardSettings.setPluginSettings(pluginSettings); - } - - // Add configured plugin settings if not already stored - Set configuredPluginIds = rewardPlugins.keySet(); - if (!configuredPluginIds.isEmpty()) { - for (String configuredPluginId : configuredPluginIds) { - if (pluginSettings.stream().noneMatch(plugin -> StringUtils.equals(plugin.getPluginId(), configuredPluginId))) { - RewardPluginSettings emptyRewardSettings = new RewardPluginSettings(); - emptyRewardSettings.setPluginId(configuredPluginId); - pluginSettings.add(emptyRewardSettings); - } - } - } - - // Check enabled plugins - for (RewardPluginSettings rewardPluginSettings : pluginSettings) { - if (rewardPluginSettings != null) { - String pluginId = rewardPluginSettings.getPluginId(); - RewardPlugin rewardPlugin = getRewardPlugin(pluginId); - boolean enabled = false; - if (rewardPlugin != null) { - enabled = rewardPlugin.isEnabled(); - } - rewardPluginSettings.setEnabled(enabled); - } + Objects.requireNonNull(rewardSettings).setStoredSetting(true); } // Cache reward settings @@ -106,46 +75,10 @@ public void saveSettings(RewardSettings rewardSettingsToStore) { throw new IllegalArgumentException("Empty settings to save"); } - // Check using pool only if not budget is of type 'points reward' - Set pluginSettings = rewardSettingsToStore.getPluginSettings(); - if (pluginSettings != null && !pluginSettings.isEmpty()) { - for (RewardPluginSettings rewardPluginSettings : pluginSettings) { - if (rewardPluginSettings.getBudgetType() == RewardBudgetType.FIXED_PER_POINT) { - rewardPluginSettings.setUsePools(false); - } - } - } String settingsString = toJsonString(rewardSettingsToStore); settingService.set(REWARD_CONTEXT, REWARD_SCOPE, REWARD_SETTINGS_KEY_NAME, SettingValue.create(settingsString)); // Purge cached settings this.configuredRewardSettings = null; } - - @Override - public void registerPlugin(RewardPlugin rewardPlugin) { - rewardPlugins.put(rewardPlugin.getPluginId(), rewardPlugin); - - // Purge cached settings - this.configuredRewardSettings = null; - } - - @Override - public void unregisterPlugin(String pluginId) { - rewardPlugins.remove(pluginId); - - // Purge cached settings - this.configuredRewardSettings = null; - } - - @Override - public Collection getRewardPlugins() { - return rewardPlugins.values(); - } - - @Override - public RewardPlugin getRewardPlugin(String pluginId) { - return rewardPlugins.get(pluginId); - } - } diff --git a/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/storage/WalletRewardReportStorage.java b/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/storage/WalletRewardReportStorage.java index ed9aa3890..fdd1e20e6 100644 --- a/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/storage/WalletRewardReportStorage.java +++ b/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/storage/WalletRewardReportStorage.java @@ -250,15 +250,12 @@ public void saveRewardReport(RewardReport rewardReport) { // NOSONAR for (WalletPluginReward rewardPlugin : rewardPlugins) { WalletRewardPluginEntity rewardPluginEntity = - rewardPluginDAO.getRewardPluginsByRewardIdAndPluginId(rewardEntity.getId(), - rewardPlugin.getPluginId()); + rewardPluginDAO.getRewardPluginsByRewardId(rewardEntity.getId()).getFirst(); if (rewardPluginEntity == null) { rewardPluginEntity = new WalletRewardPluginEntity(); } rewardPluginEntity.setAmount(rewardPlugin.getAmount()); rewardPluginEntity.setPoints(rewardPlugin.getPoints()); - rewardPluginEntity.setPluginId(rewardPlugin.getPluginId()); - rewardPluginEntity.setPoolUsed(rewardPlugin.isPoolsUsed()); rewardPluginEntity.setReward(rewardEntity); if (rewardPluginEntity.getId() == null) { @@ -343,8 +340,6 @@ private WalletReward toDTO(WalletRewardEntity rewardEntity, ZoneId zoneId) { private WalletPluginReward toDTO(WalletRewardPluginEntity rewardPluginEntity) { WalletPluginReward pluginReward = new WalletPluginReward(); pluginReward.setIdentityId(rewardPluginEntity.getReward().getIdentityId()); - pluginReward.setPluginId(rewardPluginEntity.getPluginId()); - pluginReward.setPoolsUsed(rewardPluginEntity.isPoolUsed()); pluginReward.setPoints(rewardPluginEntity.getPoints()); pluginReward.setAmount(rewardPluginEntity.getAmount()); return pluginReward; diff --git a/wallet-reward-services/src/main/resources/conf/portal/wallet-reward-configuration.xml b/wallet-reward-services/src/main/resources/conf/portal/wallet-reward-configuration.xml index 8f2774dbd..f720ae118 100644 --- a/wallet-reward-services/src/main/resources/conf/portal/wallet-reward-configuration.xml +++ b/wallet-reward-services/src/main/resources/conf/portal/wallet-reward-configuration.xml @@ -54,20 +54,6 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. org.exoplatform.wallet.reward.service.RewardSettingsService org.exoplatform.wallet.reward.service.WalletRewardSettingsService - - - gamification - registerPlugin - org.exoplatform.wallet.reward.plugin.GamificationRewardPlugin - Gamification points reward plugin - - - kudos - registerPlugin - org.exoplatform.wallet.reward.plugin.KudosRewardPlugin - Kudos reward plugin - - diff --git a/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/BaseRewardTest.java b/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/BaseRewardTest.java new file mode 100644 index 000000000..89774b2a9 --- /dev/null +++ b/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/BaseRewardTest.java @@ -0,0 +1,64 @@ +/** + * This file is part of the Meeds project (https://meeds.io/). + * + * Copyright (C) 2020 - 2024 Meeds Association contact@meeds.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.wallet.reward; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import org.exoplatform.component.test.ConfigurationUnit; +import org.exoplatform.component.test.ConfiguredBy; +import org.exoplatform.component.test.ContainerScope; + +import io.meeds.kernel.test.AbstractSpringTest; +import io.meeds.kernel.test.KernelExtension; +import io.meeds.spring.AvailableIntegration; + +@ExtendWith({ SpringExtension.class, KernelExtension.class }) +@SpringBootApplication(scanBasePackages = { + BaseRewardTest.MODULE_NAME, + AvailableIntegration.KERNEL_TEST_MODULE, + AvailableIntegration.LIQUIBASE_MODULE, + AvailableIntegration.JPA_MODULE, + AvailableIntegration.WEB_MODULE, +}) +@TestPropertySource(properties = { + "spring.liquibase.change-log=" + BaseRewardTest.CHANGELOG_PATH, +}) +@ConfiguredBy({ + @ConfigurationUnit(scope = ContainerScope.ROOT, path = "conf/configuration.xml"), + @ConfigurationUnit(scope = ContainerScope.PORTAL, path = "conf/portal/configuration.xml"), + @ConfigurationUnit(scope = ContainerScope.PORTAL, path = "conf/test-wallet-reward-configuration.xml"), +}) +public abstract class BaseRewardTest extends AbstractSpringTest { + + public static final String MODULE_NAME = "io.meeds.kudos"; + + public static final String CHANGELOG_PATH = "classpath:db/changelog/reward-rdbms.db.changelog-master.xml"; + + @BeforeEach + public void setUp() { + getContainer(); + begin(); + } + +} diff --git a/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/BaseWalletRewardTest.java b/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/BaseWalletRewardTest.java index bedf9cbc3..37279f921 100644 --- a/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/BaseWalletRewardTest.java +++ b/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/BaseWalletRewardTest.java @@ -109,25 +109,6 @@ public abstract class BaseWalletRewardTest extends AbstractKernelTest { protected static final String PROVIDER = WalletProvider.INTERNAL_WALLET.name(); - protected static final RewardPlugin CUSTOM_REWARD_PLUGIN = new RewardPlugin() { - @Override - public String getName() { - return CUSTOM_PLUGIN_NAME; - } - - @Override - public String getPluginId() { - return CUSTOM_PLUGIN_ID; - } - - @Override - public Map getEarnedPoints(Set identityIds, - long startDateInSeconds, - long endDateInSeconds) { - return WalletRewardSettingsServiceTest.getEarnedPoints(identityIds); - } - }; - protected PortalContainer container; private static RewardSettings defaultSettings = null; @@ -313,17 +294,6 @@ protected String generateTransactionHash() { return hashStringBuffer.toString(); } - protected RewardSettings cloneSettings(RewardSettings defaultSettings) { - RewardSettings newSettings = defaultSettings.clone(); - HashSet defaultPluginSettings = new HashSet<>(newSettings.getPluginSettings()); - Set pluginSettings = new HashSet<>(); - for (RewardPluginSettings rewardPluginSetting : defaultPluginSettings) { - pluginSettings.add(rewardPluginSetting.clone()); - } - newSettings.setPluginSettings(pluginSettings); - return newSettings; - } - private void registerResourceBundleService() { ResourceBundleService resourceBundleService = Mockito.mock(ResourceBundleService.class); MapResourceBundle resourceBundle = new MapResourceBundle(Locale.getDefault()); diff --git a/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/job/WalletRewardJobTest.java b/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/job/WalletRewardJobTest.java index df88ff133..a9ef5fffa 100644 --- a/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/job/WalletRewardJobTest.java +++ b/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/job/WalletRewardJobTest.java @@ -59,23 +59,6 @@ public class WalletRewardJobTest extends BaseWalletRewardTest { - @Test - public void testGetRewardPlugins() { - WalletRewardSettingsService rewardSettingsService = getService(WalletRewardSettingsService.class); - Collection rewardPlugins = rewardSettingsService.getRewardPlugins(); - assertEquals(2, rewardPlugins.size()); - - RewardPeriod period = RewardPeriodType.WEEK.getPeriodOfTime(LocalDate.now(), ZoneId.systemDefault()); - for (RewardPlugin rewardPlugin : rewardPlugins) { - try { - rewardPlugin.getEarnedPoints(Collections.singleton(1l), period.getStartDateInSeconds(), period.getEndDateInSeconds()); - // Submodules aren't loaded yet - } catch (Exception e) { - // Expected - } - } - } - @Test public void testSendRewards() throws Exception { WalletRewardSettingsService rewardSettingsService = getService(WalletRewardSettingsService.class); @@ -89,23 +72,16 @@ public void testSendRewards() throws Exception { LocalDate date = YearMonth.of(2019, 07).atEndOfMonth(); RewardSettings defaultSettings = rewardSettingsService.getSettings(); - rewardSettingsService.registerPlugin(CUSTOM_REWARD_PLUGIN); try { // Build new settings - RewardSettings newSettings = cloneSettings(rewardSettingsService.getSettings()); - Set newPluginSettings = newSettings.getPluginSettings(); + RewardSettings newSettings = defaultSettings.clone(); newSettings.setPeriodType(RewardPeriodType.MONTH); - RewardPluginSettings customPluginSetting = newPluginSettings.stream() - .filter(plugin -> CUSTOM_PLUGIN_ID.equals(plugin.getPluginId())) - .findFirst() - .orElse(null); + double sumOfTokensToSend = 5490d; - customPluginSetting.setUsePools(true); // NOSONAR - customPluginSetting.setBudgetType(RewardBudgetType.FIXED); - customPluginSetting.setAmount(sumOfTokensToSend); - customPluginSetting.setThreshold(0); - customPluginSetting.setEnabled(true); + newSettings.setBudgetType(RewardBudgetType.FIXED); + newSettings.setAmount(sumOfTokensToSend); + newSettings.setThreshold(0); rewardSettingsService.saveSettings(newSettings); WalletStorage walletStorage = getService(WalletStorage.class); @@ -199,7 +175,6 @@ public void testSendRewards() throws Exception { assertNotNull(rewardPeriodsInProgress); assertEquals(0, rewardPeriodsInProgress.size()); } finally { - rewardSettingsService.unregisterPlugin(CUSTOM_PLUGIN_ID); rewardSettingsService.saveSettings(defaultSettings); } } @@ -234,10 +209,7 @@ public TransactionDetail answer(InvocationOnMock invocation) throws Throwable { }); } - private RewardTeam createTeamWithMembers(int startInclusive, - int endInclusive, - RewardBudgetType budgetType, - boolean disabled) { + private RewardTeam createTeamWithMembers(int startInclusive, int endInclusive, RewardBudgetType budgetType, boolean disabled) { WalletRewardTeamService rewardTeamService = getService(WalletRewardTeamService.class); long[] memberIds = LongStream.rangeClosed(startInclusive, endInclusive).toArray(); RewardTeam rewardTeam = newRewardTeam(memberIds); diff --git a/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/notification/RewardSuccessNotificationPluginTest.java b/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/notification/RewardSuccessNotificationPluginTest.java index 2d76c08b4..306f9749a 100644 --- a/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/notification/RewardSuccessNotificationPluginTest.java +++ b/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/notification/RewardSuccessNotificationPluginTest.java @@ -1,18 +1,20 @@ /* * This file is part of the Meeds project (https://meeds.io/). - * Copyright (C) 2020 Meeds Association - * contact@meeds.io + * + * Copyright (C) 2020 - 2024 Meeds Lab contact@meedslab.com + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. + * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.exoplatform.wallet.reward.notification; @@ -22,38 +24,53 @@ import static org.exoplatform.wallet.utils.RewardUtils.REWARD_SUCCESS_COUNT; import static org.exoplatform.wallet.utils.RewardUtils.REWARD_TRANSACTION_COUNT; import static org.exoplatform.wallet.utils.RewardUtils.REWARD_VALID_MEMBERS_COUNT; -import static org.exoplatform.wallet.utils.RewardUtils.getRewardSettings; import static org.exoplatform.wallet.utils.WalletUtils.AMOUNT; +import static org.mockito.Mockito.when; import java.util.HashSet; import java.util.Set; -import org.junit.Test; +import org.exoplatform.wallet.model.reward.RewardSettings; +import org.exoplatform.wallet.model.settings.GlobalSettings; +import org.exoplatform.wallet.reward.BaseRewardTest; +import org.exoplatform.wallet.service.WalletService; +import org.junit.jupiter.api.Test; import org.exoplatform.commons.api.notification.NotificationContext; import org.exoplatform.commons.api.notification.model.NotificationInfo; -import org.exoplatform.commons.api.notification.plugin.config.PluginConfig; import org.exoplatform.commons.notification.impl.NotificationContextImpl; import org.exoplatform.container.xml.InitParams; -import org.exoplatform.container.xml.ObjectParam; import org.exoplatform.wallet.model.reward.RewardPeriod; import org.exoplatform.wallet.model.reward.RewardReport; import org.exoplatform.wallet.model.reward.WalletReward; import org.exoplatform.wallet.model.transaction.TransactionDetail; -import org.exoplatform.wallet.reward.BaseWalletRewardTest; +import org.mockito.Mock; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; -public class RewardSuccessNotificationPluginTest extends BaseWalletRewardTest { +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@SpringJUnitConfig(BaseRewardTest.class) +public class RewardSuccessNotificationPluginTest extends BaseRewardTest { + + @Mock + private InitParams initParams; + + @Mock + private WalletService walletService; - /** - * Check that provider returns templates correctly - */ @Test public void testMakeMessage() { - RewardSuccessNotificationPlugin plugin = new RewardSuccessNotificationPlugin(getParams()); + GlobalSettings globalSettings = new GlobalSettings(); + when(walletService.getSettings()).thenReturn(globalSettings); + RewardSuccessNotificationPlugin plugin = new RewardSuccessNotificationPlugin(initParams); + plugin.walletService = walletService; NotificationContext ctx = NotificationContextImpl.cloneInstance(); RewardReport rewardReport = new RewardReport(); - RewardPeriod rewardPeriod = RewardPeriod.getCurrentPeriod(getRewardSettings()); + RewardSettings rewardSettings = new RewardSettings(); + RewardPeriod rewardPeriod = RewardPeriod.getCurrentPeriod(rewardSettings); rewardReport.setPeriod(rewardPeriod); Set rewards = new HashSet<>(); @@ -83,19 +100,4 @@ public void testMakeMessage() { notification.getValueOwnerParameter(REWARD_VALID_MEMBERS_COUNT)); assertEquals(String.valueOf(rewardReport.getTokensSent()), notification.getValueOwnerParameter(AMOUNT)); } - - private InitParams getParams() { - InitParams initParams = new InitParams(); - ObjectParam objectParam = new ObjectParam(); - objectParam.setName("plugin-config"); - objectParam.setType(PluginConfig.class.getName()); - objectParam.addProperty("pluginId", "RewardSuccessNotificationPlugin"); - objectParam.addProperty("resourceBundleKey", "UINotification.label.RewardSuccessNotificationPlugin"); - objectParam.addProperty("order", "1"); - objectParam.addProperty("groupId", "wallet"); - objectParam.addProperty("bundlePath", "locale.notification.WalletNotification"); - initParams.addParam(objectParam); - return initParams; - } - } diff --git a/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/notification/RewardSuccessTemplateBuilderTest.java b/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/notification/RewardSuccessTemplateBuilderTest.java index df7254b5b..6e281a05d 100644 --- a/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/notification/RewardSuccessTemplateBuilderTest.java +++ b/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/notification/RewardSuccessTemplateBuilderTest.java @@ -1,28 +1,35 @@ /* * This file is part of the Meeds project (https://meeds.io/). - * Copyright (C) 2020 Meeds Association - * contact@meeds.io + * + * Copyright (C) 2020 - 2024 Meeds Lab contact@meedslab.com + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. + * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.exoplatform.wallet.reward.notification; import static org.exoplatform.wallet.utils.RewardUtils.REWARD_REPORT_NOTIFICATION_PARAM; -import static org.exoplatform.wallet.utils.RewardUtils.getRewardSettings; import java.util.HashSet; import java.util.Set; -import org.junit.Test; +import org.exoplatform.container.PortalContainer; +import org.exoplatform.wallet.model.reward.RewardSettings; +import org.exoplatform.wallet.model.settings.GlobalSettings; +import org.exoplatform.wallet.reward.BaseRewardTest; +import org.exoplatform.wallet.reward.service.RewardSettingsService; +import org.exoplatform.wallet.service.WalletService; +import org.junit.jupiter.api.Test; import org.exoplatform.commons.api.notification.NotificationContext; import org.exoplatform.commons.api.notification.channel.ChannelManager; @@ -32,7 +39,6 @@ import org.exoplatform.commons.api.notification.service.setting.PluginContainer; import org.exoplatform.commons.api.notification.service.setting.PluginSettingService; import org.exoplatform.commons.notification.impl.NotificationContextImpl; -import org.exoplatform.commons.utils.CommonsUtils; import org.exoplatform.container.xml.InitParams; import org.exoplatform.container.xml.ObjectParameter; import org.exoplatform.container.xml.ValueParam; @@ -40,29 +46,41 @@ import org.exoplatform.wallet.model.reward.RewardReport; import org.exoplatform.wallet.model.reward.WalletReward; import org.exoplatform.wallet.model.transaction.TransactionDetail; -import org.exoplatform.wallet.reward.BaseWalletRewardTest; -import org.exoplatform.wallet.reward.service.WalletRewardSettingsService; -public class RewardSuccessTemplateBuilderTest extends BaseWalletRewardTest { +import org.mockito.Mock; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.Mockito.when; + +@SpringJUnitConfig(BaseRewardTest.class) +public class RewardSuccessTemplateBuilderTest extends BaseRewardTest { + + @Mock + private WalletService walletService; + + @Mock + private RewardSettingsService rewardSettingsService; - /** - * Check that provider returns templates correctly - */ @Test public void testBuildMessage() { + PortalContainer container = PortalContainer.getInstance(); + GlobalSettings globalSettings = new GlobalSettings(); + when(walletService.getSettings()).thenReturn(globalSettings); + when(rewardSettingsService.getSettings()).thenReturn(new RewardSettings()); InitParams params = getParams(); RewardSuccessNotificationPlugin plugin = new RewardSuccessNotificationPlugin(params); + plugin.walletService = walletService; - RewardSuccessTemplateProvider templateProvider = - new RewardSuccessTemplateProvider(container, - getService(WalletRewardSettingsService.class), - params); + RewardSuccessTemplateProvider templateProvider = new RewardSuccessTemplateProvider(container, rewardSettingsService, params); templateProvider.setMailTemplatePath("jar:/template/RewardSuccessReward.gtmpl"); NotificationContext ctx = NotificationContextImpl.cloneInstance(); RewardReport rewardReport = new RewardReport(); - RewardPeriod rewardPeriod = RewardPeriod.getCurrentPeriod(getRewardSettings()); + RewardSettings rewardSettings = new RewardSettings(); + RewardPeriod rewardPeriod = RewardPeriod.getCurrentPeriod(rewardSettings); rewardReport.setPeriod(rewardPeriod); Set rewards = new HashSet<>(); @@ -79,9 +97,9 @@ public void testBuildMessage() { ctx.setNotificationInfo(notification); notification.to(notification.getSendToUserIds().get(0)); - CommonsUtils.getService(PluginSettingService.class).registerPluginConfig(getPluginConfig()); - CommonsUtils.getService(PluginContainer.class).addPlugin(plugin); - CommonsUtils.getService(ChannelManager.class).registerOverrideTemplateProvider(templateProvider); + container.getComponentInstanceOfType(PluginSettingService.class).registerPluginConfig(getPluginConfig()); + container.getComponentInstanceOfType(PluginContainer.class).addPlugin(plugin); + container.getComponentInstanceOfType(ChannelManager.class).registerOverrideTemplateProvider(templateProvider); MessageInfo message = templateProvider.getBuilder().buildMessage(ctx); assertNotNull(message); diff --git a/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/notification/RewardSuccessTemplateProviderTest.java b/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/notification/RewardSuccessTemplateProviderTest.java index c11a4f3cd..d2ff289ad 100644 --- a/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/notification/RewardSuccessTemplateProviderTest.java +++ b/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/notification/RewardSuccessTemplateProviderTest.java @@ -1,40 +1,54 @@ /* * This file is part of the Meeds project (https://meeds.io/). - * Copyright (C) 2020 Meeds Association - * contact@meeds.io + * + * Copyright (C) 2020 - 2024 Meeds Lab contact@meedslab.com + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. + * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.exoplatform.wallet.reward.notification; import java.util.Map; -import org.junit.Test; +import org.exoplatform.container.PortalContainer; +import org.exoplatform.wallet.model.reward.RewardSettings; +import org.exoplatform.wallet.reward.BaseRewardTest; +import org.exoplatform.wallet.reward.service.RewardSettingsService; +import org.junit.jupiter.api.Test; import org.exoplatform.commons.api.notification.model.PluginKey; import org.exoplatform.container.xml.InitParams; import org.exoplatform.container.xml.ValueParam; -import org.exoplatform.wallet.reward.BaseWalletRewardTest; -import org.exoplatform.wallet.reward.service.WalletRewardSettingsService; -public class RewardSuccessTemplateProviderTest extends BaseWalletRewardTest { +import org.mockito.Mock; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.Mockito.when; + +@SpringJUnitConfig(BaseRewardTest.class) +public class RewardSuccessTemplateProviderTest extends BaseRewardTest { + + @Mock + private RewardSettingsService rewardSettingsService; - /** - * Check that provider returns templates correctly - */ @Test public void testGetTemplate() { + PortalContainer container = PortalContainer.getInstance(); + when(rewardSettingsService.getSettings()).thenReturn(new RewardSettings()); RewardSuccessTemplateProvider provider = new RewardSuccessTemplateProvider(container, - getService(WalletRewardSettingsService.class), + rewardSettingsService, getParams("MAIL_CHANNEL")); Map templateFilePathConfigs = provider.getTemplateFilePathConfigs(); assertNotNull(templateFilePathConfigs); @@ -42,18 +56,14 @@ public void testGetTemplate() { String template = templateFilePathConfigs.values().iterator().next(); assertEquals(provider.getMailTemplatePath(), template); - provider = new RewardSuccessTemplateProvider(container, - getService(WalletRewardSettingsService.class), - getParams("MAIL_CHANNEL")); + provider = new RewardSuccessTemplateProvider(container, rewardSettingsService, getParams("MAIL_CHANNEL")); templateFilePathConfigs = provider.getTemplateFilePathConfigs(); assertNotNull(templateFilePathConfigs); assertEquals(1, templateFilePathConfigs.size()); template = templateFilePathConfigs.values().iterator().next(); assertEquals(provider.getMailTemplatePath(), template); - provider = new RewardSuccessTemplateProvider(container, - getService(WalletRewardSettingsService.class), - getParams("PUSH_CHANNEL")); + provider = new RewardSuccessTemplateProvider(container, rewardSettingsService, getParams("PUSH_CHANNEL")); templateFilePathConfigs = provider.getTemplateFilePathConfigs(); assertNotNull(templateFilePathConfigs); assertEquals(1, templateFilePathConfigs.size()); diff --git a/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/service/WalletRewardReportServiceTest.java b/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/service/WalletRewardReportServiceTest.java index 048773d5c..8f9e735be 100644 --- a/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/service/WalletRewardReportServiceTest.java +++ b/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/service/WalletRewardReportServiceTest.java @@ -1,926 +1,107 @@ /* * This file is part of the Meeds project (https://meeds.io/). - * Copyright (C) 2020 Meeds Association - * contact@meeds.io + * + * Copyright (C) 2020 - 2024 Meeds Lab contact@meedslab.com + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. + * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.exoplatform.wallet.reward.service; -import java.math.BigInteger; import java.time.LocalDate; import java.time.YearMonth; -import java.time.ZoneId; -import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; -import java.util.List; import java.util.Set; -import java.util.stream.LongStream; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.IntStream; -import org.junit.Test; -import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; +import io.meeds.gamification.service.RealizationService; +import org.exoplatform.wallet.model.WalletState; +import org.junit.jupiter.api.Test; -import org.exoplatform.container.component.RequestLifeCycle; import org.exoplatform.wallet.model.Wallet; -import org.exoplatform.wallet.model.reward.RewardBudgetType; -import org.exoplatform.wallet.model.reward.RewardPeriod; -import org.exoplatform.wallet.model.reward.RewardPeriodType; -import org.exoplatform.wallet.model.reward.RewardPluginSettings; import org.exoplatform.wallet.model.reward.RewardReport; import org.exoplatform.wallet.model.reward.RewardSettings; -import org.exoplatform.wallet.model.reward.RewardStatus; -import org.exoplatform.wallet.model.reward.RewardTeam; -import org.exoplatform.wallet.model.reward.WalletPluginReward; -import org.exoplatform.wallet.model.reward.WalletReward; -import org.exoplatform.wallet.model.transaction.TransactionDetail; -import org.exoplatform.wallet.reward.BaseWalletRewardTest; -import org.exoplatform.wallet.reward.dao.RewardDAO; -import org.exoplatform.wallet.reward.dao.RewardPeriodDAO; -import org.exoplatform.wallet.reward.entity.WalletRewardEntity; -import org.exoplatform.wallet.reward.entity.WalletRewardPeriodEntity; import org.exoplatform.wallet.reward.storage.WalletRewardReportStorage; import org.exoplatform.wallet.service.WalletAccountService; import org.exoplatform.wallet.service.WalletTokenAdminService; -import org.exoplatform.wallet.service.WalletTransactionService; -import org.exoplatform.wallet.utils.RewardUtils; -import org.exoplatform.wallet.utils.WalletUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; -import static org.exoplatform.wallet.utils.RewardUtils.timeToSecondsAtDayStart; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.Mockito.when; -public class WalletRewardReportServiceTest extends BaseWalletRewardTest { // NOSONAR +@SpringBootTest(classes = { WalletRewardReportService.class }) +public class WalletRewardReportServiceTest { // NOSONAR - /** - * Check that service is instantiated - */ - @Test - public void testServiceInstantiated() { - WalletRewardReportService walletRewardService = getService(WalletRewardReportService.class); - assertNotNull(walletRewardService); - } - - @Test - public void testComputeRewards() { - WalletRewardReportService walletRewardService = getService(WalletRewardReportService.class); - LocalDate date = YearMonth.of(2019, 03).atEndOfMonth(); - RewardReport rewardReport = walletRewardService.computeRewards(date); - assertNotNull(rewardReport); - assertNotNull(rewardReport.getRewards()); - assertEquals(0, rewardReport.getRewards().size()); - - WalletAccountService accountService = getService(WalletAccountService.class); - int enabledWalletsCount = 60; - for (int i = 0; i < enabledWalletsCount; i++) { - Wallet wallet = newWallet(i + 1l); - wallet = accountService.saveWallet(wallet, true); - updateWalletBlockchainState(wallet); - accountService.saveWalletBlockchainState(wallet, WalletUtils.getContractAddress()); - entitiesToClean.add(wallet); - } - - rewardReport = walletRewardService.computeRewards(date); - assertNotNull(rewardReport); - // Even if settings are null, the returned rewards shouldn't be empty - assertEquals(enabledWalletsCount, rewardReport.getRewards().size()); - - WalletRewardSettingsService rewardSettingsService = getService(WalletRewardSettingsService.class); - RewardSettings defaultSettings = rewardSettingsService.getSettings(); - rewardSettingsService.registerPlugin(CUSTOM_REWARD_PLUGIN); - try { - // Build new settings - RewardSettings newSettings = cloneSettings(rewardSettingsService.getSettings()); - - Set newPluginSettings = newSettings.getPluginSettings(); - long amount = 3l; - - newSettings.setPeriodType(RewardPeriodType.MONTH); - - RewardPluginSettings customPluginSetting = newPluginSettings.stream() - .filter(plugin -> CUSTOM_PLUGIN_ID.equals(plugin.getPluginId())) - .findFirst() - .orElse(null); - - assertNotNull(customPluginSetting); + @MockBean + private WalletAccountService walletAccountService; - customPluginSetting.setAmount(amount); // NOSONAR - customPluginSetting.setBudgetType(RewardBudgetType.FIXED_PER_POINT); - customPluginSetting.setThreshold(0); - customPluginSetting.setEnabled(true); - customPluginSetting.setUsePools(false); - rewardSettingsService.saveSettings(newSettings); + @MockBean + private WalletTokenAdminService walletTokenAdminService; - // Check computed amount for plugin per wallet when no teams and with - // fixed - // budget per point - double sumOfTokensToSend = checkComputedRewards(walletRewardService, - date, - enabledWalletsCount, - amount); + @MockBean + private RewardSettingsService rewardSettingsService; - customPluginSetting.setBudgetType(RewardBudgetType.FIXED); - customPluginSetting.setAmount(sumOfTokensToSend); - rewardSettingsService.saveSettings(newSettings); + @MockBean + private RewardTeamService rewardTeamService; - // Check computed amount for plugin per wallet when no teams and with - // fixed total budget for reward plugin - checkComputedRewards(walletRewardService, - date, - enabledWalletsCount, - amount); + @MockBean + private WalletRewardReportStorage rewardReportStorage; - customPluginSetting.setBudgetType(RewardBudgetType.FIXED_PER_MEMBER); - customPluginSetting.setAmount(sumOfTokensToSend / enabledWalletsCount); - rewardSettingsService.saveSettings(newSettings); + @MockBean + private RealizationService realizationService; - // Check computed amount for plugin per wallet when no teams and with - // fixed budget per member - checkComputedRewards(walletRewardService, - date, - enabledWalletsCount, - amount); - - customPluginSetting.setThreshold(31); - customPluginSetting.setAmount(amount); // NOSONAR - customPluginSetting.setBudgetType(RewardBudgetType.FIXED_PER_POINT); - rewardSettingsService.saveSettings(newSettings); - - // Check computed amount for plugin per wallet when no teams and with - // fixed budget per point and with Threshold - checkComputedRewards(walletRewardService, - date, - 30, - amount); - - customPluginSetting.setThreshold(0); - rewardSettingsService.saveSettings(newSettings); - - RewardTeam rewardTeam1 = createTeamWithMembers(1, 10, RewardBudgetType.COMPUTED, true); - RewardTeam rewardTeam2 = createTeamWithMembers(11, 20, RewardBudgetType.FIXED, true); - RewardTeam rewardTeam3 = createTeamWithMembers(21, 30, RewardBudgetType.FIXED_PER_MEMBER, true); - RewardTeam rewardTeam4 = createTeamWithMembers(31, 40, RewardBudgetType.FIXED_PER_MEMBER, true); - RewardTeam rewardTeam5 = createTeamWithMembers(41, 50, RewardBudgetType.COMPUTED, true); - RewardTeam rewardTeam6 = createTeamWithMembers(51, 60, RewardBudgetType.COMPUTED, true); - - List teams = new ArrayList<>(); - teams.add(rewardTeam1); - teams.add(rewardTeam2); - teams.add(rewardTeam3); - teams.add(rewardTeam4); - teams.add(rewardTeam5); - teams.add(rewardTeam6); - - // Check computed amount for plugin per wallet with teams (each having 10 - // members), with fixed budget per point and with plugin not using teams - checkComputedRewards(walletRewardService, - date, - enabledWalletsCount, - amount); - - customPluginSetting.setUsePools(true); - customPluginSetting.setBudgetType(RewardBudgetType.FIXED); - customPluginSetting.setAmount(sumOfTokensToSend); - rewardSettingsService.saveSettings(newSettings); - - // Check computed amount for plugin per wallet with teams (each having 10 - // members), with fixed total budget and with plugin using teams that are - // disabled - checkComputedRewards(walletRewardService, - date, - 0, - 0); - - // Check computed amount for plugin per wallet with teams (each having 10 - // members), with fixed total budget and with plugin using teams that are - // enabled - WalletRewardTeamService rewardTeamService = getService(WalletRewardTeamService.class); - teams.forEach(team -> { - team.setDisabled(false); - rewardTeamService.saveTeam(team); - }); - - rewardReport = walletRewardService.computeRewards(date); - - // check total budget to send - double tokensToSend = rewardReport.getRewards().stream().mapToDouble(WalletReward::getTokensToSend).sum(); - assertEquals(sumOfTokensToSend, tokensToSend, 0); - - // Check budget of team having a defined budget as 'fixed' - double tokensSentToTeam2 = rewardReport.getRewards() - .stream() - .filter(walletReward -> walletReward.getTeam() != null - && rewardTeam2.getId().equals(walletReward.getTeam().getId())) - .mapToDouble(WalletReward::getTokensToSend) - .sum(); - assertEquals(rewardTeam2.getBudget(), tokensSentToTeam2, 0); - - // Check budget of teams (team3 and team4) having a defined budget as - // 'fixed per member' - double tokensSentToTeam3 = rewardReport.getRewards() - .stream() - .filter(walletReward -> walletReward.getTeam() != null - && rewardTeam3.getId().equals(walletReward.getTeam().getId())) - .mapToDouble(WalletReward::getTokensToSend) - .sum(); - assertEquals(rewardTeam3.getBudget() * rewardTeam3.getMembers().size(), tokensSentToTeam3, 0); - - double tokensSentToTeam4 = rewardReport.getRewards() - .stream() - .filter(walletReward -> walletReward.getTeam() != null - && rewardTeam4.getId().equals(walletReward.getTeam().getId())) - .mapToDouble(WalletReward::getTokensToSend) - .sum(); - assertEquals(rewardTeam4.getBudget() * rewardTeam4.getMembers().size(), tokensSentToTeam4, 0); - - // Check budget of other teams (team1, team5 and team2) having a defined - // budget as 'computed' - double tokensSentToOtherTeams = sumOfTokensToSend - tokensSentToTeam2 - tokensSentToTeam3 - tokensSentToTeam4; - double tokensSentToOtherTeam = tokensSentToOtherTeams / 3d; - - double tokensSentToTeam1 = rewardReport.getRewards() - .stream() - .filter(walletReward -> walletReward.getTeam() != null - && rewardTeam1.getId().equals(walletReward.getTeam().getId())) - .mapToDouble(WalletReward::getTokensToSend) - .sum(); - assertEquals(tokensSentToOtherTeam, tokensSentToTeam1, 0); - - double tokensSentToTeam5 = rewardReport.getRewards() - .stream() - .filter(walletReward -> walletReward.getTeam() != null - && rewardTeam5.getId().equals(walletReward.getTeam().getId())) - .mapToDouble(WalletReward::getTokensToSend) - .sum(); - assertEquals(tokensSentToOtherTeam, tokensSentToTeam5, 0); - - double tokensSentToTeam6 = rewardReport.getRewards() - .stream() - .filter(walletReward -> walletReward.getTeam() != null - && rewardTeam6.getId().equals(walletReward.getTeam().getId())) - .mapToDouble(WalletReward::getTokensToSend) - .sum(); - assertEquals(tokensSentToOtherTeam, tokensSentToTeam6, 0); - } finally { - rewardSettingsService.unregisterPlugin(CUSTOM_PLUGIN_ID); - rewardSettingsService.saveSettings(defaultSettings); - } - } + @Autowired + private RewardReportService rewardReportService; @Test - public void testComputeRewardWithDuplication() { - WalletTransactionService walletTransactionService = getService(WalletTransactionService.class); - WalletRewardReportService walletRewardService = getService(WalletRewardReportService.class); - LocalDate date = YearMonth.of(2019, 03).atEndOfMonth(); - RewardReport rewardReport = walletRewardService.computeRewards(date); + public void testComputeRewards() { + LocalDate date = YearMonth.of(2019, 3).atEndOfMonth(); + RewardSettings rewardSettings = new RewardSettings(); + when(rewardSettingsService.getSettings()).thenReturn(rewardSettings); + RewardReport rewardReport = rewardReportService.computeRewards(date); assertNotNull(rewardReport); assertNotNull(rewardReport.getRewards()); assertEquals(0, rewardReport.getRewards().size()); - WalletAccountService accountService = getService(WalletAccountService.class); - int enabledWalletsCount = 60; - for (int i = 0; i < enabledWalletsCount; i++) { - Wallet wallet = newWallet(i + 1l); - wallet = accountService.saveWallet(wallet, true); - updateWalletBlockchainState(wallet); - accountService.saveWalletBlockchainState(wallet, WalletUtils.getContractAddress()); - entitiesToClean.add(wallet); - } - - rewardReport = walletRewardService.computeRewards(date); - assertNotNull(rewardReport); - assertEquals(enabledWalletsCount, rewardReport.getRewards().size()); - - WalletRewardSettingsService rewardSettingsService = getService(WalletRewardSettingsService.class); - RewardSettings defaultSettings = rewardSettingsService.getSettings(); - rewardSettingsService.registerPlugin(CUSTOM_REWARD_PLUGIN); - try { - // Build new settings - RewardSettings newSettings = cloneSettings(rewardSettingsService.getSettings()); - - Set newPluginSettings = newSettings.getPluginSettings(); - long amount = 3l; - - newSettings.setPeriodType(RewardPeriodType.MONTH); - - RewardPluginSettings customPluginSetting = newPluginSettings.stream() - .filter(plugin -> CUSTOM_PLUGIN_ID.equals(plugin.getPluginId())) - .findFirst() - .orElse(null); - - assertNotNull(customPluginSetting); - - customPluginSetting.setAmount(amount); // NOSONAR - customPluginSetting.setBudgetType(RewardBudgetType.FIXED_PER_POINT); - customPluginSetting.setThreshold(0); - customPluginSetting.setEnabled(true); - customPluginSetting.setUsePools(false); - rewardSettingsService.saveSettings(newSettings); - - // Check computed amount for plugin per wallet when no teams and with - // fixed budget per point - double sumOfTokensToSend = checkComputedRewards(walletRewardService, - date, - enabledWalletsCount, - amount); - customPluginSetting.setBudgetType(RewardBudgetType.FIXED); - customPluginSetting.setAmount(sumOfTokensToSend); - rewardSettingsService.saveSettings(newSettings); - - rewardReport = walletRewardService.computeRewards(date); - - // check total budget to send - double tokensToSend = rewardReport.getRewards().stream().mapToDouble(WalletReward::getTokensToSend).sum(); - assertEquals(sumOfTokensToSend, tokensToSend, 0); - - Set rewards = rewardReport.getRewards(); - RewardPeriod period = rewardReport.getPeriod(); - RewardPeriodDAO rewardPeriodDAO = getService(RewardPeriodDAO.class); - WalletRewardPeriodEntity rewardPeriodEntity = rewardPeriodDAO.findRewardPeriodByTypeAndTime(period.getRewardPeriodType(), - period.getPeriodMedianDateInSeconds()); - if (rewardPeriodEntity == null) { - rewardPeriodEntity = new WalletRewardPeriodEntity(); - rewardPeriodEntity.setPeriodType(period.getRewardPeriodType()); - rewardPeriodEntity.setStatus(RewardStatus.PENDING); - rewardPeriodEntity.setStartTime(period.getStartDateInSeconds()); - rewardPeriodEntity.setEndTime(period.getEndDateInSeconds()); - rewardPeriodEntity.setTimeZone(period.getTimeZone()); - rewardPeriodEntity = rewardPeriodDAO.create(rewardPeriodEntity); - } - // Create entity with empty transaction information - for (WalletReward walletReward : rewards) { - WalletRewardEntity rewardEntity = new WalletRewardEntity(); - rewardEntity.setEnabled(true); - rewardEntity.setIdentityId(walletReward.getIdentityId()); - rewardEntity.setTokensToSend(walletReward.getTokensToSend()); - rewardEntity.setPeriod(rewardPeriodEntity); - rewardEntity = getService(RewardDAO.class).create(rewardEntity); - } - restartTransaction(); - - rewardReport = walletRewardService.computeRewards(date); - assertEquals(0, rewardReport.getTokensSent(), 0); - assertFalse(rewardReport.isCompletelyProceeded()); - - // Create duplicated entity with sent transaction information - // for the same identity and period - for (WalletReward walletReward : rewards) { - WalletRewardEntity rewardEntity = new WalletRewardEntity(); - rewardEntity.setEnabled(true); - rewardEntity.setIdentityId(walletReward.getIdentityId()); - rewardEntity.setTokensToSend(walletReward.getTokensToSend()); - rewardEntity.setPeriod(rewardPeriodEntity); - rewardEntity.setTokensSent(tokensToSend); - TransactionDetail transactionDetail = createWalltRewardTransaction(walletTransactionService, walletReward); - rewardEntity.setTransactionHash(transactionDetail.getHash()); - rewardEntity = getService(RewardDAO.class).create(rewardEntity); - } - restartTransaction(); - - rewardReport = walletRewardService.computeRewards(date); - assertEquals(rewardReport.getTokensToSend(), rewardReport.getTokensSent(), 0); - assertTrue(rewardReport.isCompletelyProceeded()); - } finally { - rewardSettingsService.unregisterPlugin(CUSTOM_PLUGIN_ID); - rewardSettingsService.saveSettings(defaultSettings); - } - } - - @Test - public void testComputeRewardsByUser() { - - WalletAccountService accountService = getService(WalletAccountService.class); - Wallet userWallet = newWallet(1l); - userWallet = accountService.saveWallet(userWallet, true); - updateWalletBlockchainState(userWallet); - accountService.saveWalletBlockchainState(userWallet, WalletUtils.getContractAddress()); - entitiesToClean.add(userWallet); - - int enabledWalletsCount = 6; - for (int i = 1; i < enabledWalletsCount; i++) { - Wallet wallet = newWallet(i + 1l); - wallet = accountService.saveWallet(wallet, true); - updateWalletBlockchainState(wallet); - accountService.saveWalletBlockchainState(wallet, WalletUtils.getContractAddress()); - entitiesToClean.add(wallet); - } - - WalletRewardReportService walletRewardService = getService(WalletRewardReportService.class); - LocalDate date = YearMonth.of(2022, 12).atEndOfMonth(); - RewardReport rewardReport = walletRewardService.computeRewardsByUser(date, userWallet.getTechnicalId()); - assertNotNull(rewardReport); - assertNotNull(rewardReport.getRewards()); - assertEquals(1, rewardReport.getRewards().size()); - } - - @Test - public void testComputeRewardsWithTimeZoneChange() throws Exception { - WalletTransactionService walletTransactionService = getService(WalletTransactionService.class); - WalletRewardReportStorage rewardReportStorage = getService(WalletRewardReportStorage.class); - WalletAccountService walletAccountService = getService(WalletAccountService.class); - WalletRewardSettingsService rewardSettingsService = getService(WalletRewardSettingsService.class); - RewardTeamService rewardTeamService = getService(RewardTeamService.class); - - WalletRewardReportService walletRewardService = new WalletRewardReportService(walletAccountService, - rewardSettingsService, - rewardTeamService, - rewardReportStorage); - - WalletTokenAdminService tokenAdminService = Mockito.mock(WalletTokenAdminService.class); - resetTokenAdminService(walletTransactionService, tokenAdminService, false, true); - - WalletAccountService accountService = getService(WalletAccountService.class); - int enabledWalletsCount = 60; - for (int i = 0; i < enabledWalletsCount; i++) { - Wallet wallet = newWallet(i + 1l); - wallet = accountService.saveWallet(wallet, true); - updateWalletBlockchainState(wallet); - accountService.saveWalletBlockchainState(wallet, WalletUtils.getContractAddress()); - entitiesToClean.add(wallet); - } - - LocalDate previousMonthDate = LocalDate.of(2022, 03, 01); - LocalDate currentMonthDate = LocalDate.of(2022, 04, 01); - - RewardSettings defaultSettings = rewardSettingsService.getSettings(); - rewardSettingsService.registerPlugin(CUSTOM_REWARD_PLUGIN); - try { - RewardReport rewardReport = walletRewardService.computeRewards(previousMonthDate); - assertEquals(0d, rewardReport.getRemainingTokensToSend(), 0); - assertEquals(0d, rewardReport.getTokensSent(), 0); - - // Build new settings - RewardSettings newSettings = cloneSettings(rewardSettingsService.getSettings()); - newSettings.setTimeZone("GMT"); - Set newPluginSettings = newSettings.getPluginSettings(); - - newSettings.setPeriodType(RewardPeriodType.MONTH); - RewardPluginSettings customPluginSetting = newPluginSettings.stream() - .filter(plugin -> CUSTOM_PLUGIN_ID.equals(plugin.getPluginId())) - .findFirst() - .orElse(null); - double sumOfTokensToSend = 5490d; - customPluginSetting.setUsePools(false); // NOSONAR - customPluginSetting.setBudgetType(RewardBudgetType.FIXED); - customPluginSetting.setAmount(sumOfTokensToSend); - customPluginSetting.setThreshold(0); - customPluginSetting.setEnabled(true); - rewardSettingsService.saveSettings(newSettings); - - rewardReport = walletRewardService.computeRewards(previousMonthDate); - assertNotNull(rewardReport); - assertNotNull(rewardReport.getRewards()); - assertEquals(enabledWalletsCount, rewardReport.getRewards().size()); - assertEquals(0d, rewardReport.getTokensSent(), 0); - assertEquals(sumOfTokensToSend, rewardReport.getRemainingTokensToSend(), 0); - - // Admin having only 10 tokens - int contractDecimals = WalletUtils.getContractDetail().getDecimals(); - Mockito.when(tokenAdminService.getTokenBalanceOf("adminAddress")) - .thenReturn(BigInteger.valueOf((long) sumOfTokensToSend).pow(contractDecimals)); - - walletRewardService.sendRewards(previousMonthDate, "root"); - - rewardReport = walletRewardService.computeRewards(previousMonthDate); - assertEquals(sumOfTokensToSend, rewardReport.getTokensSent(), 0); - assertEquals(0d, rewardReport.getRemainingTokensToSend(), 0); - - rewardReport = walletRewardService.computeRewards(currentMonthDate); - assertNotNull(rewardReport); - assertNotNull(rewardReport.getRewards()); - assertEquals(enabledWalletsCount, rewardReport.getRewards().size()); - assertEquals(0d, rewardReport.getTokensSent(), 0); - assertEquals(sumOfTokensToSend, rewardReport.getRemainingTokensToSend(), 0); - - newSettings.setTimeZone("Europe/Paris"); - rewardSettingsService.saveSettings(newSettings); - - rewardReport = walletRewardService.computeRewards(currentMonthDate); - assertNotNull(rewardReport); - assertNotNull(rewardReport.getRewards()); - assertEquals(enabledWalletsCount, rewardReport.getRewards().size()); - assertEquals(0d, rewardReport.getTokensSent(), 0); - assertEquals(sumOfTokensToSend, rewardReport.getRemainingTokensToSend(), 0); - } finally { - rewardSettingsService.unregisterPlugin(CUSTOM_PLUGIN_ID); - rewardSettingsService.saveSettings(defaultSettings); - } - } - - @Test - public void testSendRewards() throws Exception { - WalletAccountService walletAccountService = getService(WalletAccountService.class); - WalletRewardSettingsService rewardSettingsService = getService(WalletRewardSettingsService.class); - RewardTeamService rewardTeamService = getService(RewardTeamService.class); - WalletTransactionService walletTransactionService = getService(WalletTransactionService.class); - WalletRewardReportStorage rewardReportStorage = getService(WalletRewardReportStorage.class); - - WalletRewardReportService walletRewardService = new WalletRewardReportService(walletAccountService, - rewardSettingsService, - rewardTeamService, - rewardReportStorage); - WalletTokenAdminService tokenAdminService = Mockito.mock(WalletTokenAdminService.class); - resetTokenAdminService(walletTransactionService, tokenAdminService, false, true); - - int contractDecimals = WalletUtils.getContractDetail().getDecimals(); - LocalDate date = YearMonth.of(2019, 04).atEndOfMonth(); - - RewardSettings defaultSettings = rewardSettingsService.getSettings(); - rewardSettingsService.registerPlugin(CUSTOM_REWARD_PLUGIN); - try { - // Build new settings - RewardSettings newSettings = cloneSettings(rewardSettingsService.getSettings()); - Set newPluginSettings = newSettings.getPluginSettings(); - - newSettings.setPeriodType(RewardPeriodType.MONTH); - RewardPluginSettings customPluginSetting = newPluginSettings.stream() - .filter(plugin -> CUSTOM_PLUGIN_ID.equals(plugin.getPluginId())) - .findFirst() - .orElse(null); - double sumOfTokensToSend = 5490d; - customPluginSetting.setUsePools(true); // NOSONAR - customPluginSetting.setBudgetType(RewardBudgetType.FIXED); - customPluginSetting.setAmount(sumOfTokensToSend); - customPluginSetting.setThreshold(0); - customPluginSetting.setEnabled(true); - rewardSettingsService.saveSettings(newSettings); - - WalletAccountService accountService = getService(WalletAccountService.class); - int enabledWalletsCount = 60; - for (int i = 0; i < enabledWalletsCount; i++) { - Wallet wallet = newWallet(i + 1l); - wallet = accountService.saveWallet(wallet, true); - updateWalletBlockchainState(wallet); - accountService.saveWalletBlockchainState(wallet, WalletUtils.getContractAddress()); - entitiesToClean.add(wallet); - } - - // Build teams - List teams = new ArrayList<>(); - RewardTeam rewardTeam1 = createTeamWithMembers(1, 10, RewardBudgetType.COMPUTED, false); - teams.add(rewardTeam1); - RewardTeam rewardTeam2 = createTeamWithMembers(11, 20, RewardBudgetType.FIXED, false); - teams.add(rewardTeam2); - RewardTeam rewardTeam3 = createTeamWithMembers(21, 30, RewardBudgetType.FIXED_PER_MEMBER, false); - teams.add(rewardTeam3); - RewardTeam rewardTeam4 = createTeamWithMembers(31, 40, RewardBudgetType.FIXED_PER_MEMBER, false); - teams.add(rewardTeam4); - RewardTeam rewardTeam5 = createTeamWithMembers(41, 50, RewardBudgetType.COMPUTED, false); - teams.add(rewardTeam5); - RewardTeam rewardTeam6 = createTeamWithMembers(51, 60, RewardBudgetType.COMPUTED, false); - teams.add(rewardTeam6); - - // Admin having only 10 tokens - Mockito.when(tokenAdminService.getTokenBalanceOf("adminAddress")) - .thenReturn(BigInteger.valueOf(10l).pow(contractDecimals)); - try { - walletRewardService.sendRewards(date, "root"); - fail("Shouldn't send funds when admin not having enough funds"); - } catch (Exception e) { - // Expected - } - Mockito.verify(tokenAdminService, Mockito.times(0)).reward(Mockito.any(), Mockito.any()); - - // Admin having enough funds - Mockito.when(tokenAdminService.getTokenBalanceOf("adminAddress")) - .thenReturn(BigInteger.valueOf((long) sumOfTokensToSend + 1).pow(contractDecimals)); - walletRewardService.sendRewards(date, "root"); - Mockito.verify(tokenAdminService, Mockito.times(60)).reward(Mockito.any(), Mockito.any()); - - // Send reward for the second time for the same period - resetTokenAdminService(walletTransactionService, tokenAdminService, false, true); - Mockito.when(tokenAdminService.getTokenBalanceOf("adminAddress")) - .thenReturn(BigInteger.valueOf((long) sumOfTokensToSend + 1).pow(contractDecimals)); - try { - walletRewardService.sendRewards(date, "root"); - } catch (Exception e) { - // Expected, no rewards to send - } - Mockito.verify(tokenAdminService, Mockito.times(0)).reward(Mockito.any(), Mockito.any()); - } finally { - rewardSettingsService.unregisterPlugin(CUSTOM_PLUGIN_ID); - rewardSettingsService.saveSettings(defaultSettings); - } - } - - @Test - public void testSaveRewardReport() { - RewardReport rewardReport = new RewardReport(); - LocalDate date = LocalDate.now(); - - WalletAccountService accountService = getService(WalletAccountService.class); - - WalletRewardSettingsService rewardSettingsService = getService(WalletRewardSettingsService.class); - RewardSettings defaultSettings = rewardSettingsService.getSettings(); - - RewardPeriod period = defaultSettings.getPeriodType().getPeriodOfTime(date, ZoneId.systemDefault()); - rewardReport.setPeriod(period); - Set rewards = new HashSet<>(); - for (int i = 0; i < 20; i++) { - Wallet wallet = newWallet(i + 1l); - wallet = accountService.saveWallet(wallet, true); - updateWalletBlockchainState(wallet); - accountService.saveWalletBlockchainState(wallet, WalletUtils.getContractAddress()); - entitiesToClean.add(wallet); - - WalletReward walletReward = new WalletReward(); - walletReward.setWallet(wallet); - walletReward.setPeriod(period); - Set pluginRewards = new HashSet<>(); - for (int j = 0; j < 10; j++) { - WalletPluginReward pluginReward = new WalletPluginReward(); - pluginReward.setAmount(5); - pluginReward.setIdentityId(wallet.getTechnicalId()); - pluginReward.setPluginId("plugin" + j); - pluginReward.setPoints(5); - pluginReward.setPoolsUsed(false); - pluginRewards.add(pluginReward); - } - walletReward.setRewards(pluginRewards); - rewards.add(walletReward); - } - rewardReport.setRewards(rewards); - - RewardReportService rewardReportService = getService(RewardReportService.class); - rewardReportService.saveRewardReport(rewardReport); - - RequestLifeCycle.end(); - RequestLifeCycle.begin(container); - - RewardReport savedRewardReport = rewardReportService.getRewardReport(date); - assertEquals(rewardReport, savedRewardReport); - - RewardPeriod rewardPeriod = rewardReportService.getRewardPeriod(period.getRewardPeriodType(), period.getPeriodMedianDate()); - assertNotNull(rewardPeriod); - assertTrue(rewardPeriod.getId() > 0); - - RewardReport report = rewardReportService.getRewardReportByPeriodId(rewardPeriod.getId()); - assertNotNull(report); - assertNotNull(report.getPeriod()); - assertEquals(rewardPeriod.getId(), report.getPeriod().getId()); - } - - @Test - public void testFindRewardReportPeriods() { - RewardReport rewardReport = new RewardReport(); - LocalDate date = LocalDate.now(); - - WalletAccountService accountService = getService(WalletAccountService.class); - - WalletRewardSettingsService rewardSettingsService = getService(WalletRewardSettingsService.class); - RewardSettings defaultSettings = rewardSettingsService.getSettings(); - - RewardPeriod period = defaultSettings.getPeriodType().getPeriodOfTime(date, ZoneId.systemDefault()); - rewardReport.setPeriod(period); - Set rewards = new HashSet<>(); - for (int i = 0; i < 20; i++) { - Wallet wallet = newWallet(i + 1l); - wallet = accountService.saveWallet(wallet, true); - updateWalletBlockchainState(wallet); - accountService.saveWalletBlockchainState(wallet, WalletUtils.getContractAddress()); - entitiesToClean.add(wallet); - - WalletReward walletReward = new WalletReward(); - walletReward.setWallet(wallet); - walletReward.setPeriod(period); - Set pluginRewards = new HashSet<>(); - for (int j = 0; j < 10; j++) { - WalletPluginReward pluginReward = new WalletPluginReward(); - pluginReward.setAmount(5); - pluginReward.setIdentityId(wallet.getTechnicalId()); - pluginReward.setPluginId("plugin" + j); - pluginReward.setPoints(5); - pluginReward.setPoolsUsed(false); - pluginRewards.add(pluginReward); - } - walletReward.setRewards(pluginRewards); - rewards.add(walletReward); - } - rewardReport.setRewards(rewards); - - RewardReportService rewardReportService = getService(RewardReportService.class); - rewardReportService.saveRewardReport(rewardReport); - - restartTransaction(); - - List rewardReportPeriods = rewardReportService.findRewardReportPeriods(0, 1); - assertNotNull(rewardReportPeriods); - assertEquals(1, rewardReportPeriods.size()); - - long from = timeToSecondsAtDayStart(LocalDate.now(), ZoneId.systemDefault()); - long to = timeToSecondsAtDayStart(LocalDate.now().plusMonths(1), ZoneId.systemDefault()); - rewardReportPeriods = rewardReportService.findRewardPeriodsBetween(from, to, 0, 10); - assertNotNull(rewardReportPeriods); - assertEquals(1, rewardReportPeriods.size()); - } - - @Test - public void testListRewards() throws Exception { - WalletAccountService walletAccountService = getService(WalletAccountService.class); - WalletRewardSettingsService rewardSettingsService = getService(WalletRewardSettingsService.class); - RewardTeamService rewardTeamService = getService(RewardTeamService.class); - WalletTransactionService walletTransactionService = getService(WalletTransactionService.class); - WalletRewardReportStorage rewardReportStorage = getService(WalletRewardReportStorage.class); - - WalletRewardReportService walletRewardService = new WalletRewardReportService(walletAccountService, - rewardSettingsService, - rewardTeamService, - rewardReportStorage); - - WalletTokenAdminService tokenAdminService = Mockito.mock(WalletTokenAdminService.class); - resetTokenAdminService(walletTransactionService, tokenAdminService, false, true); - - int contractDecimals = WalletUtils.getContractDetail().getDecimals(); - LocalDate date = YearMonth.of(2019, 05).atEndOfMonth(); - - RewardSettings defaultSettings = rewardSettingsService.getSettings(); - rewardSettingsService.registerPlugin(CUSTOM_REWARD_PLUGIN); - try { - // Build new settings - RewardSettings newSettings = cloneSettings(rewardSettingsService.getSettings()); - Set newPluginSettings = newSettings.getPluginSettings(); - - newSettings.setPeriodType(RewardPeriodType.MONTH); - RewardPluginSettings customPluginSetting = newPluginSettings.stream() - .filter(plugin -> CUSTOM_PLUGIN_ID.equals(plugin.getPluginId())) - .findFirst() - .orElse(null); - double sumOfTokensToSend = 5490d; - customPluginSetting.setUsePools(true); // NOSONAR - customPluginSetting.setBudgetType(RewardBudgetType.FIXED); - customPluginSetting.setAmount(sumOfTokensToSend); - customPluginSetting.setThreshold(0); - customPluginSetting.setEnabled(true); - rewardSettingsService.saveSettings(newSettings); - - WalletAccountService accountService = getService(WalletAccountService.class); - int enabledWalletsCount = 60; - for (int i = 0; i < enabledWalletsCount; i++) { - Wallet wallet = newWallet(i + 1l); - wallet = accountService.saveWallet(wallet, true); - updateWalletBlockchainState(wallet); - accountService.saveWalletBlockchainState(wallet, WalletUtils.getContractAddress()); - entitiesToClean.add(wallet); - } - - // Build teams - List teams = new ArrayList<>(); - RewardTeam rewardTeam1 = createTeamWithMembers(1, 10, RewardBudgetType.COMPUTED, false); - teams.add(rewardTeam1); - RewardTeam rewardTeam2 = createTeamWithMembers(11, 20, RewardBudgetType.FIXED, false); - teams.add(rewardTeam2); - RewardTeam rewardTeam3 = createTeamWithMembers(21, 30, RewardBudgetType.FIXED_PER_MEMBER, false); - teams.add(rewardTeam3); - RewardTeam rewardTeam4 = createTeamWithMembers(31, 40, RewardBudgetType.FIXED_PER_MEMBER, false); - teams.add(rewardTeam4); - RewardTeam rewardTeam5 = createTeamWithMembers(41, 50, RewardBudgetType.COMPUTED, false); - teams.add(rewardTeam5); - RewardTeam rewardTeam6 = createTeamWithMembers(51, 60, RewardBudgetType.COMPUTED, false); - teams.add(rewardTeam6); - - List walletRewards = walletRewardService.listRewards("root3", 10); - assertNotNull(walletRewards); - assertEquals(0, walletRewards.size()); - - // Admin having enough funds - Mockito.when(tokenAdminService.getTokenBalanceOf("adminAddress")) - .thenReturn(BigInteger.valueOf((long) sumOfTokensToSend + 1).pow(contractDecimals)); - walletRewardService.sendRewards(date, "root"); - Mockito.verify(tokenAdminService, Mockito.times(60)).reward(Mockito.any(), Mockito.any()); - - walletRewards = walletRewardService.listRewards("root3", 10); - assertNotNull(walletRewards); - assertEquals(1, walletRewards.size()); - - WalletReward walletReward = walletRewards.get(0); - assertNotNull(walletReward); - assertNotNull(walletReward.getPeriod()); - assertNotNull(walletReward.getTransaction()); - assertEquals(RewardUtils.TRANSACTION_STATUS_SUCCESS, walletReward.getStatus()); - assertNotNull(walletReward.getWallet()); - assertEquals(3, walletReward.getIdentityId()); - assertEquals(3, walletReward.getWallet().getTechnicalId()); - assertNotNull(walletReward.getTeam()); - assertNotNull(walletReward.getTeams()); - assertEquals(1, walletReward.getTeams().size()); - - assertNotNull(walletReward.getRewards()); - assertEquals(1, walletReward.getRewards().size()); - WalletPluginReward pluginReward = walletReward.getRewards().iterator().next(); - assertNotNull(pluginReward); - assertEquals(CUSTOM_PLUGIN_ID, pluginReward.getPluginId()); - assertEquals(3, pluginReward.getPoints(), 0); - assertEquals(3, pluginReward.getIdentityId()); - assertEquals(58, pluginReward.getAmount(), 0.1); - } finally { - rewardSettingsService.unregisterPlugin(CUSTOM_PLUGIN_ID); - rewardSettingsService.saveSettings(defaultSettings); - } - } - - private void resetTokenAdminService(WalletTransactionService walletTransactionService, - WalletTokenAdminService tokenAdminService, - boolean pendingTransactions, - boolean successTransactions) throws Exception { // NOSONAR - if (container.getComponentInstanceOfType(WalletTokenAdminService.class) != null) { - container.unregisterComponent(WalletTokenAdminService.class); - } - container.registerComponentInstance(WalletTokenAdminService.class, tokenAdminService); - Mockito.reset(tokenAdminService); - Mockito.when(tokenAdminService.getAdminWalletAddress()).thenReturn("adminAddress"); - Mockito.when(tokenAdminService.reward(Mockito.any(), Mockito.any())).thenAnswer(new Answer() { - @Override - public TransactionDetail answer(InvocationOnMock invocation) throws Throwable { - TransactionDetail transactionDetail = invocation.getArgument(0, TransactionDetail.class); - saveRewardTransaction(walletTransactionService, pendingTransactions, successTransactions, transactionDetail); - return transactionDetail; - } - + int enabledWalletsCount = 59; + Set wallets = Collections.newSetFromMap(new ConcurrentHashMap<>()); + IntStream.range(0, enabledWalletsCount).parallel().forEach(i -> { + Wallet wallet = newWallet(i + 1L); + wallets.add(wallet); }); - } + when(walletAccountService.listWallets()).thenReturn(wallets); - private RewardTeam createTeamWithMembers(int startInclusive, - int endInclusive, - RewardBudgetType budgetType, - boolean disabled) { - WalletRewardTeamService rewardTeamService = getService(WalletRewardTeamService.class); - long[] memberIds = LongStream.rangeClosed(startInclusive, endInclusive).toArray(); - RewardTeam rewardTeam = newRewardTeam(memberIds); - rewardTeam.setName("Name" + startInclusive); - rewardTeam.setDisabled(disabled); - rewardTeam.setRewardType(budgetType); - double totalBudget = (double) LongStream.rangeClosed(startInclusive, endInclusive).sum() * 3d; - if (budgetType == RewardBudgetType.COMPUTED || budgetType == RewardBudgetType.FIXED) { - rewardTeam.setBudget(totalBudget); - } else { - rewardTeam.setBudget(totalBudget / memberIds.length); - } - rewardTeam = rewardTeamService.saveTeam(rewardTeam); - entitiesToClean.add(rewardTeam); - return rewardTeam; - } - - private double checkComputedRewards(WalletRewardReportService walletRewardService, - LocalDate date, - int enabledWalletsCount, - long amount) { - double sumOfTokensToSend = 0; - RewardReport rewardReport = walletRewardService.computeRewards(date); + rewardReport = rewardReportService.computeRewards(date); assertNotNull(rewardReport); - Set rewards = rewardReport.getRewards(); - assertNotNull(rewards); - - assertEquals(enabledWalletsCount, rewardReport.getValidRewardCount()); - for (WalletReward walletReward : rewardReport.getValidRewards()) { - assertNotNull(walletReward); - assertNotNull(walletReward.getWallet()); - assertNotNull(walletReward.getRewards()); - assertEquals(1, walletReward.getRewards().size()); - assertEquals(0, walletReward.getTokensSent(), 0); - long tokensToSend = walletReward.getIdentityId() * amount; - sumOfTokensToSend += tokensToSend; - assertEquals("Wallet '" + walletReward + "' has an unexpected reward amount", - tokensToSend, - walletReward.getTokensToSend(), - 0); - } - return sumOfTokensToSend; - } - - private TransactionDetail createWalltRewardTransaction(WalletTransactionService walletTransactionService, - WalletReward walletReward) { - TransactionDetail transactionDetail = new TransactionDetail(); - transactionDetail.setFrom("adminWalletAddress"); - transactionDetail.setTo(walletReward.getWallet().getAddress()); - transactionDetail.setContractAmount(walletReward.getTokensToSend()); - transactionDetail.setValue(walletReward.getTokensToSend()); - saveRewardTransaction(walletTransactionService, false, true, transactionDetail); - return transactionDetail; + // Even if settings are null, the returned rewards shouldn't be empty + assertEquals(enabledWalletsCount, rewardReport.getRewards().size()); } - private void saveRewardTransaction(WalletTransactionService walletTransactionService, - boolean pendingTransactions, - boolean successTransactions, - TransactionDetail transactionDetail) { - transactionDetail.setHash(generateTransactionHash()); - transactionDetail.setPending(pendingTransactions); - transactionDetail.setSucceeded(successTransactions); - transactionDetail.setContractMethodName("reward"); - RequestLifeCycle.begin(container); - try { - walletTransactionService.saveTransactionDetail(transactionDetail, false); - } finally { - RequestLifeCycle.end(); - } - entitiesToClean.add(transactionDetail); + protected Wallet newWallet(long identityId) { + Wallet wallet = new Wallet(); + wallet.setTechnicalId(identityId); + wallet.setAddress("walletAddress" + identityId); + wallet.setPassPhrase("passphrase"); + wallet.setEnabled(true); + wallet.setIsInitialized(true); + wallet.setEtherBalance(0d); + wallet.setTokenBalance(0d); + wallet.setInitializationState(WalletState.INITIALIZED.name()); + return wallet; } - } diff --git a/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/service/WalletRewardSettingsServiceTest.java b/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/service/WalletRewardSettingsServiceTest.java index 702023be5..0fd8b953f 100644 --- a/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/service/WalletRewardSettingsServiceTest.java +++ b/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/service/WalletRewardSettingsServiceTest.java @@ -1,174 +1,104 @@ /* * This file is part of the Meeds project (https://meeds.io/). - * Copyright (C) 2020 Meeds Association - * contact@meeds.io + * + * Copyright (C) 2020 - 2024 Meeds Lab contact@meedslab.com + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. + * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.exoplatform.wallet.reward.service; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.junit.Test; +import com.google.javascript.jscomp.jarjar.com.google.common.base.Objects; +import org.exoplatform.commons.api.settings.SettingService; +import org.exoplatform.commons.api.settings.SettingValue; +import org.junit.jupiter.api.Test; import org.exoplatform.wallet.model.reward.RewardBudgetType; import org.exoplatform.wallet.model.reward.RewardPeriodType; -import org.exoplatform.wallet.model.reward.RewardPluginSettings; import org.exoplatform.wallet.model.reward.RewardSettings; -import org.exoplatform.wallet.reward.BaseWalletRewardTest; -import org.exoplatform.wallet.reward.api.RewardPlugin; - -public class WalletRewardSettingsServiceTest extends BaseWalletRewardTest { - - /** - * Check that service is instantiated - */ - @Test - public void testServiceInstantiated() { - WalletRewardSettingsService rewardSettingsService = getService(WalletRewardSettingsService.class); - assertNotNull(rewardSettingsService); - } - - @Test - public void tetGetRewardPlugins() { - WalletRewardSettingsService rewardSettingsService = getService(WalletRewardSettingsService.class); - - Collection rewardPlugins = rewardSettingsService.getRewardPlugins(); - assertNotNull("List of rewards plugins shouldn't be null", rewardPlugins); - assertEquals("Unexpected reward plugins count", 2, rewardPlugins.size()); - } - - @Test - public void tetGetRewardPlugin() { - WalletRewardSettingsService rewardSettingsService = getService(WalletRewardSettingsService.class); - - String pluginId = "kudos"; - RewardPlugin kudosRewardPlugin = rewardSettingsService.getRewardPlugin(pluginId); - assertNotNull("Rewards plugin 'kudos' shouldn't be null", kudosRewardPlugin); - assertEquals("Unexpected reward plugin name", pluginId, kudosRewardPlugin.getName()); - assertEquals("Unexpected reward plugin id", pluginId, kudosRewardPlugin.getPluginId()); - Map earnedPoints = kudosRewardPlugin.getEarnedPoints(Collections.emptySet(), 0, Long.MAX_VALUE); - assertEquals("Unexpected reward plugin earned points", - new HashMap<>(), - earnedPoints); - } +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; - @Test - public void testRegisterPlugin() { - WalletRewardSettingsService rewardSettingsService = getService(WalletRewardSettingsService.class); +import static org.exoplatform.wallet.utils.WalletUtils.toJsonString; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Mockito.*; - rewardSettingsService.registerPlugin(CUSTOM_REWARD_PLUGIN); - try { - RewardPlugin registeredRewardPlugin = rewardSettingsService.getRewardPlugin(CUSTOM_PLUGIN_ID); +@SpringBootTest(classes = { WalletRewardSettingsService.class }) +public class WalletRewardSettingsServiceTest { - assertNotNull("Rewards plugin 'kudos' shouldn't be null", registeredRewardPlugin); - assertEquals("Returned rewards plugin isn't the same as the registered one", CUSTOM_REWARD_PLUGIN, registeredRewardPlugin); - assertEquals("Unexpected reward plugin name", CUSTOM_PLUGIN_NAME, CUSTOM_REWARD_PLUGIN.getName()); - assertEquals("Unexpected reward plugin id", CUSTOM_PLUGIN_ID, CUSTOM_REWARD_PLUGIN.getPluginId()); - assertTrue("Reward plugin should be enabled by default", CUSTOM_REWARD_PLUGIN.isEnabled()); + @MockBean + private SettingService settingService; - Set identityIds = new HashSet<>(Arrays.asList(1l, 2l, 3l, 4l, 5l)); - Map expectedRewards = getEarnedPoints(identityIds); - Map earnedPoints = CUSTOM_REWARD_PLUGIN.getEarnedPoints(identityIds, 0, Long.MAX_VALUE); - assertEquals("Unexpected reward plugin earned points", - expectedRewards, - earnedPoints); - } finally { - rewardSettingsService.unregisterPlugin(CUSTOM_PLUGIN_ID); - } - } + @Autowired + private RewardSettingsService rewardSettingsService; @Test public void testGetSettings() { - WalletRewardSettingsService rewardSettingsService = getService(WalletRewardSettingsService.class); RewardSettings defaultSettings = rewardSettingsService.getSettings(); + verify(settingService, times(1)).get(any(), any(), any()); assertNotNull(defaultSettings); - assertEquals("Wrong default reward period type", RewardPeriodType.DEFAULT, defaultSettings.getPeriodType()); - - Set pluginSettings = defaultSettings.getPluginSettings(); - assertNotNull("List of rewards plugin settings shouldn't be null", pluginSettings); - assertEquals("Unexpected reward plugin settings count", 2, pluginSettings.size()); + assertEquals(RewardPeriodType.DEFAULT, defaultSettings.getPeriodType()); - RewardPluginSettings rewardPluginSettings = pluginSettings.iterator().next(); - assertNotNull(rewardPluginSettings); - assertEquals(0, rewardPluginSettings.getAmount(), 0); - assertEquals(RewardBudgetType.DEFAULT, rewardPluginSettings.getBudgetType()); - assertEquals(0, rewardPluginSettings.getThreshold(), 0); - assertFalse(rewardPluginSettings.isEnabled()); + assertEquals(0, defaultSettings.getAmount(), 0); + assertEquals(RewardBudgetType.DEFAULT, defaultSettings.getBudgetType()); + assertEquals(0, defaultSettings.getThreshold(), 0); } @Test public void testSaveSettings() { - WalletRewardSettingsService rewardSettingsService = getService(WalletRewardSettingsService.class); - RewardSettings defaultSettings = rewardSettingsService.getSettings(); - RewardSettings newSettings = cloneSettings(defaultSettings); - - Set newPluginSettings = newSettings.getPluginSettings(); - long amount = 1l; - boolean enabled = true; - boolean usePools = true; - long threshold = 2l; + RewardSettings newSettings = defaultSettings.clone(); + long amount = 1L; + long threshold = 2L; RewardBudgetType budgetType = RewardBudgetType.FIXED_PER_POINT; RewardPeriodType periodType = RewardPeriodType.SEMESTER; newSettings.setPeriodType(periodType); - for (RewardPluginSettings pluginSetting : newPluginSettings) { - pluginSetting.setAmount(amount); - pluginSetting.setBudgetType(budgetType); - pluginSetting.setEnabled(enabled); - pluginSetting.setThreshold(threshold); - pluginSetting.setUsePools(usePools); - } + newSettings.setAmount(amount); + newSettings.setBudgetType(budgetType); + newSettings.setThreshold(threshold); + rewardSettingsService.saveSettings(newSettings); + RewardSettings finalNewSettings = newSettings; + verify(settingService, times(1)).set(any(), + any(), + any(), + argThat(value -> Objects.equal(value.getValue(), toJsonString(finalNewSettings)))); try { + SettingValue value = SettingValue.create(toJsonString(finalNewSettings)); + when(settingService.get(any(), any(), any())).thenReturn(value); newSettings = rewardSettingsService.getSettings(); assertNotNull(newSettings); assertEquals(periodType, newSettings.getPeriodType()); - newPluginSettings = newSettings.getPluginSettings(); - for (RewardPluginSettings pluginSetting : newPluginSettings) { - assertEquals(amount, pluginSetting.getAmount(), 0); - assertEquals(threshold, pluginSetting.getThreshold(), 0); - assertFalse("Enablement should be retrieved always from registered plugin and not from storage", - pluginSetting.isEnabled()); - assertEquals(budgetType, pluginSetting.getBudgetType()); - assertFalse("Pools can't be used when budget type equals to 'FIXED_PER_POINT'", pluginSetting.isUsePools()); - } + assertEquals(amount, newSettings.getAmount(), 0); + assertEquals(threshold, newSettings.getThreshold(), 0); + assertEquals(budgetType, newSettings.getBudgetType()); budgetType = RewardBudgetType.FIXED; - for (RewardPluginSettings pluginSetting : newPluginSettings) { - pluginSetting.setBudgetType(budgetType); - pluginSetting.setUsePools(usePools); - } + newSettings.setBudgetType(budgetType); rewardSettingsService.saveSettings(newSettings); - + value = SettingValue.create(toJsonString(newSettings)); + when(settingService.get(any(), any(), any())).thenReturn(value); newSettings = rewardSettingsService.getSettings(); - - newPluginSettings = newSettings.getPluginSettings(); - for (RewardPluginSettings pluginSetting : newPluginSettings) { - assertEquals(budgetType, pluginSetting.getBudgetType()); - assertTrue("Pools should be saved using new value 'true' when budget type is set to 'FIXED'", pluginSetting.isUsePools()); - } + assertEquals(budgetType, newSettings.getBudgetType()); } finally { rewardSettingsService.saveSettings(defaultSettings); } } - } diff --git a/wallet-reward-services/src/test/resources/conf/test-wallet-reward-configuration.xml b/wallet-reward-services/src/test/resources/conf/test-wallet-reward-configuration.xml index a510d4283..f4a966a7e 100644 --- a/wallet-reward-services/src/test/resources/conf/test-wallet-reward-configuration.xml +++ b/wallet-reward-services/src/test/resources/conf/test-wallet-reward-configuration.xml @@ -3,138 +3,4 @@ for more details. You should have received a copy of the GNU Lesser General Public License along with this software; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF site: http://www.fsf.org. --> - - org.exoplatform.social.core.space.spi.SpaceService - org.exoplatform.wallet.reward.test.mock.SpaceServiceMock - - - - org.exoplatform.social.core.manager.IdentityManager - org.exoplatform.wallet.reward.test.mock.IdentityManagerMock - - - - org.exoplatform.wallet.reward.dao.RewardTeamDAO - - - - org.exoplatform.wallet.reward.dao.RewardPluginDAO - - - - org.exoplatform.wallet.reward.dao.RewardDAO - - - - org.exoplatform.wallet.reward.dao.RewardPeriodDAO - - - - org.exoplatform.wallet.reward.dao.RewardTeamDAO - - - - org.exoplatform.wallet.reward.storage.WalletRewardTeamStorage - - - - org.exoplatform.wallet.reward.storage.WalletRewardReportStorage - - - - org.exoplatform.wallet.reward.service.RewardTeamService - org.exoplatform.wallet.reward.service.WalletRewardTeamService - - - - org.exoplatform.wallet.reward.service.RewardSettingsService - org.exoplatform.wallet.reward.service.WalletRewardSettingsService - - - gamification - registerPlugin - org.exoplatform.wallet.reward.plugin.GamificationRewardPlugin - Gamification points reward plugin - - - kudos - registerPlugin - org.exoplatform.wallet.reward.plugin.KudosRewardPlugin - Kudos reward plugin - - - - - - org.exoplatform.wallet.reward.service.RewardReportService - org.exoplatform.wallet.reward.service.WalletRewardReportService - - - - org.exoplatform.wallet.reward.rest.RewardTeamREST - - - - org.exoplatform.wallet.reward.rest.RewardSettingsREST - - - - org.exoplatform.wallet.reward.rest.RewardReportREST - - - - org.exoplatform.commons.api.persistence.DataInitializer - - WalletRDBMSChangeLogsPlugin - addChangeLogsPlugin - org.exoplatform.commons.persistence.impl.ChangeLogsPlugin - - - changelogs - Change logs of Wallet RDBMS - db/changelog/reward-rdbms.db.changelog-master.xml - - - - - - - org.exoplatform.services.scheduler.JobSchedulerService - - AddCronJob - addCronJob - org.exoplatform.services.scheduler.CronJob - Add a job to verify if rewards sent having pending transactions are completely successfully sent - - - cronjob.info - Configuration for rewards transactions status verifier - - - - - - - - - - - org.exoplatform.services.listener.ListenerService - - exo.wallet.reward.report.success - addListener - org.exoplatform.wallet.reward.listener.RewardSucceedAnalyticsListener - - - exo.wallet.reward.report.success - addListener - org.exoplatform.wallet.reward.listener.RewardSucceedNotificationListener - - - exo.wallet.transaction.replaced - addListener - org.exoplatform.wallet.reward.listener.RewardSucceedNotificationListener - - - diff --git a/wallet-services/src/main/resources/jpa-entities.idx b/wallet-services/src/main/resources/jpa-entities.idx new file mode 100644 index 000000000..a0c675667 --- /dev/null +++ b/wallet-services/src/main/resources/jpa-entities.idx @@ -0,0 +1,6 @@ +org.exoplatform.wallet.entity.AddressLabelEntity +org.exoplatform.wallet.entity.TransactionEntity +org.exoplatform.wallet.entity.WalletBackupEntity +org.exoplatform.wallet.entity.WalletBlockchainStateEntity +org.exoplatform.wallet.entity.WalletEntity +org.exoplatform.wallet.entity.WalletPrivateKeyEntity diff --git a/wallet-services/src/main/resources/locale/addon/Wallet_en.properties b/wallet-services/src/main/resources/locale/addon/Wallet_en.properties index 33fd07988..08496f80c 100644 --- a/wallet-services/src/main/resources/locale/addon/Wallet_en.properties +++ b/wallet-services/src/main/resources/locale/addon/Wallet_en.properties @@ -498,7 +498,38 @@ wallet.administration.fundWallet=Fund Wallet wallet.administration.manageWallet=Manage wallet wallet.administration.budgetConfiguration=Budget Configuration wallet.administration.budgetConfiguration.setUp=Setup the Rewarding Budget +wallet.administration.budgetConfiguration.points=Points wallet.administration.budgetConfiguration.setBudget=Set Budget +wallet.administration.budgetConfiguration.editConfiguration=Edit Configuration +wallet.administration.budgetConfiguration.periodType.title=Rewards are sent +wallet.administration.budgetConfiguration.timeZone.title=If contributions are done +wallet.administration.budgetConfiguration.threshold.title=For contributors with a minimum of +wallet.administration.budgetConfiguration.budgetFixed.title=Budget is fixed +wallet.administration.budgetConfiguration.budgetPerContributor.title=Budget is per Contributor + +wallet.administration.budgetConfigurationDrawer.title=Set Global Budget +wallet.administration.budgetConfigurationDrawer.periodType=Rewarding Periodicity +wallet.administration.budgetConfigurationDrawer.periodType.title=Rewarding will be done +wallet.administration.budgetConfigurationDrawer.timeZone=Contributions Listing Timezone +wallet.administration.budgetConfigurationDrawer.timeZone.title=Following timezone will be applied +wallet.administration.budgetConfigurationDrawer.threshold.title=Minimum threshold to reward users +wallet.administration.budgetConfigurationDrawer.amount.title=Budget +wallet.administration.budgetConfigurationDrawer.budgetFixed=Fixed +wallet.administration.budgetConfigurationDrawer.budgetPerContributor=Per Contributor +wallet.administration.budgetConfigurationDrawer.invalidThreshold=Please choose a threshold value less than {0} points. +wallet.administration.budgetConfigurationDrawer.invalidAmount=Please choose an amount value less than {0} Meeds. + +wallet.administration.distributionForecast=Distribution Forecast +wallet.administration.distributionForecast.subtile=Based on current contributions +wallet.administration.distributionForecast.participants=Participants +wallet.administration.distributionForecast.eligibleContributors=Eligible Contributors +wallet.administration.distributionForecast.acceptedContributions=Accepted Contributions +wallet.administration.distributionForecast.budget=Budget + +wallet.administration.periodType.label.week=Weekly +wallet.administration.periodType.label.month=Monthly +wallet.administration.periodType.label.quarter=Quarterly + wallet.administration.rewardManagement=Reward Management wallet.administration.rewardManagement.noContributionsYet=No contributions to reward yet diff --git a/wallet-webapps/pom.xml b/wallet-webapps/pom.xml index cb5840f84..f07e425b7 100644 --- a/wallet-webapps/pom.xml +++ b/wallet-webapps/pom.xml @@ -26,6 +26,12 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. war Meeds:: Add-on:: Wallet - Application + + io.meeds.social + social-component-service + provided + + io.meeds.platform-ui platform-ui-skin diff --git a/wallet-webapps/src/main/java/io/meeds/wallet/WalletApplication.java b/wallet-webapps/src/main/java/io/meeds/wallet/WalletApplication.java new file mode 100644 index 000000000..32a7049bc --- /dev/null +++ b/wallet-webapps/src/main/java/io/meeds/wallet/WalletApplication.java @@ -0,0 +1,43 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * + * Copyright (C) 2020 - 2024 Meeds Association contact@meeds.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ +package io.meeds.wallet; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; +import org.springframework.context.annotation.PropertySource; + +import io.meeds.spring.AvailableIntegration; +import io.meeds.spring.kernel.PortalApplicationContextInitializer; + +@SpringBootApplication(scanBasePackages = { + WalletApplication.MODULE_NAME, + AvailableIntegration.KERNEL_MODULE, + AvailableIntegration.JPA_MODULE, + AvailableIntegration.WEB_MODULE, +}, +exclude = { + LiquibaseAutoConfiguration.class, +}) +@PropertySource("classpath:application.properties") +@PropertySource("classpath:application-common.properties") +public class WalletApplication extends PortalApplicationContextInitializer { + + public static final String MODULE_NAME = "io.meeds.wallet"; + +} diff --git a/wallet-webapps/src/main/webapp/vue-app/wallet-common/js/RewardService.js b/wallet-webapps/src/main/webapp/vue-app/wallet-common/js/RewardService.js index 2f4a01763..cb28c2070 100644 --- a/wallet-webapps/src/main/webapp/vue-app/wallet-common/js/RewardService.js +++ b/wallet-webapps/src/main/webapp/vue-app/wallet-common/js/RewardService.js @@ -20,8 +20,7 @@ export function getRewardSettings() { method: 'GET', credentials: 'include', }) - .then((resp) => resp && resp.ok && resp.json()) - .then((settings) => (window.walletRewardSettings = settings)); + .then((resp) => resp && resp.ok && resp.json()); } export function saveRewardSettings(settings) { diff --git a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/RewardApp.vue b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/RewardApp.vue index bda65a548..ef9b12297 100644 --- a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/RewardApp.vue +++ b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/RewardApp.vue @@ -29,8 +29,65 @@ flat> - + + + + diff --git a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/BudgetConfiguration.vue b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/BudgetConfiguration.vue index dd54d856e..010062293 100644 --- a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/BudgetConfiguration.vue +++ b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/BudgetConfiguration.vue @@ -20,24 +20,181 @@ --> \ No newline at end of file + + + \ No newline at end of file diff --git a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/BudgetConfigurationDrawer.vue b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/BudgetConfigurationDrawer.vue new file mode 100644 index 000000000..a301b28c3 --- /dev/null +++ b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/BudgetConfigurationDrawer.vue @@ -0,0 +1,236 @@ + + + + \ No newline at end of file diff --git a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/ConfigurationTab.vue b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/ConfigurationTab.vue deleted file mode 100644 index 35ffafed0..000000000 --- a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/ConfigurationTab.vue +++ /dev/null @@ -1,243 +0,0 @@ - - - - diff --git a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/CurrentBalance.vue b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/CurrentBalance.vue index 90acb3f2b..f7fb13f4a 100644 --- a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/CurrentBalance.vue +++ b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/CurrentBalance.vue @@ -24,7 +24,7 @@ class="border-radius border-color ma-5" flat>
- + {{ $t('exoplatform.wallet.label.currentBalance') }} @@ -39,7 +39,6 @@ fas fa-credit-card @@ -59,17 +58,17 @@ @@ -50,9 +63,17 @@ export default { data: () => ({ rewardSettings: {}, loading: false, - rewardReport: null, + loadingRewards: false, + rewardReports: [], + selectedRewardReport: null, + showRewardDetails: false, + rewardsPage: 0, + rewardsPageSize: 12, }), computed: { + rewardReport() { + return this.rewardReports[0]; + }, rewardPeriod() { return this.rewardReport?.period; }, @@ -80,14 +101,33 @@ export default { if (period) { this.period = period; } - this.loading = true; - return this.$rewardService.computeRewards(this.selectedDate) - .then(rewardReport => { - this.rewardReport = rewardReport; + this.loadingRewards = true; + + return this.$rewardService.computeRewards(this.rewardsPage, this.rewardsPageSize) + .then(rewardReports => { + this.rewardReports.push(...rewardReports); return this.$nextTick(); - }) - .finally(() => this.loading = false); + }).finally(() => this.loadingRewards = false); + }, + deleteRewardSettings() { + return this.$rewardService.deleteRewardSettings() + .then(() => { + this.rewardReports = []; + return this.refreshRewardSettings(); + }); + }, + openDetails(rewardReport) { + this.showRewardDetails = true; + this.selectedRewardReport = rewardReport; + }, + loadMore() { + this.rewardsPage += 1; + this.refreshRewards(); }, + settingUpdated() { + this.rewardReports = []; + this.refreshRewardSettings(); + } }, }; diff --git a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/BudgetConfiguration.vue b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/BudgetConfiguration.vue index 010062293..7966bcad3 100644 --- a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/BudgetConfiguration.vue +++ b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/BudgetConfiguration.vue @@ -39,7 +39,6 @@
@@ -50,6 +49,25 @@ {{ $t('wallet.administration.budgetConfiguration.editConfiguration') }} + + + + {{ $t('wallet.administration.budgetConfiguration.editConfiguration') }} + +
+ \ No newline at end of file diff --git a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardCardMaskContent.vue b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardCardMaskContent.vue new file mode 100644 index 000000000..943fb5273 --- /dev/null +++ b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardCardMaskContent.vue @@ -0,0 +1,45 @@ + + + \ No newline at end of file diff --git a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardDetails.vue b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardDetails.vue new file mode 100644 index 000000000..be77f2fed --- /dev/null +++ b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardDetails.vue @@ -0,0 +1,210 @@ + + + + \ No newline at end of file diff --git a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardDetailsItem.vue b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardDetailsItem.vue new file mode 100644 index 000000000..f35c04301 --- /dev/null +++ b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardDetailsItem.vue @@ -0,0 +1,263 @@ + + + + \ No newline at end of file diff --git a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardManagement.vue b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardManagement.vue index 3861414e5..366a8123c 100644 --- a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardManagement.vue +++ b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardManagement.vue @@ -20,18 +20,66 @@ --> \ No newline at end of file + + + \ No newline at end of file diff --git a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/initComponents.js b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/initComponents.js index eace79ade..cfd247f5b 100644 --- a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/initComponents.js +++ b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/initComponents.js @@ -1,19 +1,27 @@ import RewardApp from './components/RewardApp.vue'; import RewardManagement from './components/reward/RewardManagement.vue'; +import RewardCard from './components/reward/RewardCard.vue'; +import RewardDetails from './components/reward/RewardDetails.vue'; +import RewardDetailsItem from './components/reward/RewardDetailsItem.vue'; import CurrentBalance from './components/reward/CurrentBalance.vue'; import BudgetConfiguration from './components/reward/BudgetConfiguration.vue'; import BudgetConfigurationDrawer from './components/reward/BudgetConfigurationDrawer.vue'; import DistributionForecast from './components/reward/DistributionForecast.vue'; import TimeZoneSelectBox from './components/reward/TimeZoneSelectBox.vue'; +import RewardCardMaskContent from './components/reward/RewardCardMaskContent.vue'; const components = { 'wallet-reward-app': RewardApp, 'wallet-reward-management': RewardManagement, + 'wallet-reward-card': RewardCard, + 'wallet-reward-details': RewardDetails, + 'wallet-reward-details-item': RewardDetailsItem, 'wallet-current-balance': CurrentBalance, 'wallet-budget-configuration': BudgetConfiguration, 'wallet-budget-configuration-drawer': BudgetConfigurationDrawer, 'wallet-budget-distribution-forecast': DistributionForecast, 'wallet-reward-timezone-selectbox': TimeZoneSelectBox, + 'wallet-reward-card-mask-content': RewardCardMaskContent, }; for (const key in components) { From dd1588c5df0454dac690004bf4ace570dd29812a Mon Sep 17 00:00:00 2001 From: Azmi TOUIL <42934070+AzmiTouil@users.noreply.github.com> Date: Mon, 30 Sep 2024 10:24:24 +0200 Subject: [PATCH 04/16] feat: Display Detail of a rewarding for different cases - MEED-7479 - Meeds-io/MIPs#154 (#566) --- .../wallet/reward/rest/RewardReportREST.java | 17 ++--- .../service/WalletRewardReportService.java | 13 ++-- .../locale/addon/Wallet_en.properties | 4 ++ .../components/reward/BudgetConfiguration.vue | 2 +- .../components/reward/RewardDetails.vue | 69 ++++++++++++++----- .../components/reward/RewardDetailsItem.vue | 37 ++++++---- 6 files changed, 97 insertions(+), 45 deletions(-) diff --git a/wallet-api/src/main/java/io/meeds/wallet/reward/rest/RewardReportREST.java b/wallet-api/src/main/java/io/meeds/wallet/reward/rest/RewardReportREST.java index b281430b2..6672b32aa 100644 --- a/wallet-api/src/main/java/io/meeds/wallet/reward/rest/RewardReportREST.java +++ b/wallet-api/src/main/java/io/meeds/wallet/reward/rest/RewardReportREST.java @@ -100,14 +100,15 @@ public List computeRewards(@Parameter(description = "Page") @Parameter(description = "Page size") @RequestParam(value = "size", defaultValue = "12", required = false) int size) { - - int numberOfPeriods = (page + 1) * size; - List periods = generatePreviousPeriods(numberOfPeriods); - - List rewardReports = periods.stream() - .skip((long) page * size) - .limit(size) - .map(rewardPeriod -> rewardReportService.computeRewards(rewardPeriod.getPeriodMedianDate())) + int skip = page * size; + List periods = generatePreviousPeriods(skip + size).subList(skip, skip + size); + List rewardReports = periods.parallelStream() + .map(period -> { + RewardReport rewardReport = + rewardReportService.computeRewards(period.getPeriodMedianDate()); + rewardReport.setPeriod(new RewardPeriodWithFullDate(rewardReport.getPeriod())); + return rewardReport; + }) .toList(); rewardReports.forEach(rewardReport -> rewardReport.setPeriod(new RewardPeriodWithFullDate(rewardReport.getPeriod()))); return rewardReports; diff --git a/wallet-reward-services/src/main/java/io/meeds/wallet/reward/service/WalletRewardReportService.java b/wallet-reward-services/src/main/java/io/meeds/wallet/reward/service/WalletRewardReportService.java index c1ad85948..ea8771703 100644 --- a/wallet-reward-services/src/main/java/io/meeds/wallet/reward/service/WalletRewardReportService.java +++ b/wallet-reward-services/src/main/java/io/meeds/wallet/reward/service/WalletRewardReportService.java @@ -41,8 +41,10 @@ import io.meeds.gamification.constant.IdentityType; import io.meeds.gamification.model.filter.RealizationFilter; import io.meeds.gamification.service.RealizationService; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; +import org.exoplatform.commons.api.persistence.ExoTransactional; import org.exoplatform.commons.utils.CommonsUtils; import org.exoplatform.services.log.ExoLogger; import org.exoplatform.services.log.Log; @@ -63,7 +65,6 @@ import io.meeds.wallet.wallet.service.WalletTokenAdminService; import lombok.Setter; -import org.springframework.cache.annotation.Cacheable; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; @@ -195,6 +196,7 @@ public boolean isRewardSendingInProgress() { } @Override + @ExoTransactional public RewardReport computeRewards(LocalDate date) { if (date == null) { throw new IllegalArgumentException("date is mandatory"); @@ -228,11 +230,10 @@ public RewardReport computeRewards(LocalDate date) { List participants = realizationService.getParticipantsBetweenDates(start, end); // Only user wallets benefits from rewards - Set wallets = walletAccountService.listWalletsByIdentityIds(participants) - .stream() - .filter(wallet -> WalletType.isUser(wallet.getType())) - .collect(Collectors.toSet()); - computeRewardDetails(rewardReport, wallets); + if (CollectionUtils.isNotEmpty(participants)) { + Set wallets = walletAccountService.listWalletsByIdentityIds(participants); + computeRewardDetails(rewardReport, wallets); + } return rewardReport; } diff --git a/wallet-services/src/main/resources/locale/addon/Wallet_en.properties b/wallet-services/src/main/resources/locale/addon/Wallet_en.properties index b41688148..133f03fa3 100644 --- a/wallet-services/src/main/resources/locale/addon/Wallet_en.properties +++ b/wallet-services/src/main/resources/locale/addon/Wallet_en.properties @@ -558,6 +558,10 @@ wallet.administration.rewardDetails.label.rewards=Rewards wallet.administration.rewardDetails.label.actions=Actions wallet.administration.rewardDetails.label.openTransaction=Open Transaction wallet.administration.rewardDetails.label.seeHistory=See History +wallet.administration.rewardDetails.label.latestRewardsSent=Latest Rewards Sent on: +wallet.administration.rewardDetails.label.rewardsToSend={0} MEED for {1} points +wallet.administration.rewardDetails.label.reward=Reward +wallet.administration.rewardDetails.label.notSentYet=Not sent yet wallet.overview.rewards.title=Wallet History wallet.overview.points=Points diff --git a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/BudgetConfiguration.vue b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/BudgetConfiguration.vue index 7966bcad3..081dbaaf7 100644 --- a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/BudgetConfiguration.vue +++ b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/BudgetConfiguration.vue @@ -65,7 +65,7 @@
- {{ $t('wallet.administration.budgetConfiguration.editConfiguration') }} + {{ $t('wallet.administration.budgetConfiguration.deleteConfiguration') }} diff --git a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardDetails.vue b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardDetails.vue index be77f2fed..71792c095 100644 --- a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardDetails.vue +++ b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardDetails.vue @@ -41,23 +41,28 @@ {{ $t('wallet.administration.rewardDetails.sendingProgress') }}... - - - {{ $t('wallet.administration.rewardCard.status.inPeriod') }} - + +
+ {{ $t('wallet.administration.rewardDetails.label.latestRewardsSent') }} {{ sendDate }} +
- - - fas fa-external-link-alt - - {{ $t('wallet.administration.rewardDetails.label.openTransaction') }} - + + + {{ $t('wallet.administration.rewardDetails.label.notSentYet') }} + Date: Tue, 1 Oct 2024 14:39:33 +0200 Subject: [PATCH 05/16] feat: Detail of a rewarding period when reward sent + UEM - MEED-7478 - Meeds-io/MIPs#154 (#568) --- .../components/reward/RewardDetails.vue | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardDetails.vue b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardDetails.vue index 71792c095..59be92724 100644 --- a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardDetails.vue +++ b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardDetails.vue @@ -42,7 +42,7 @@ {{ $t('wallet.administration.rewardDetails.sendingProgress') }}... -
- {{ $t('wallet.administration.rewardDetails.label.latestRewardsSent') }} {{ sendDate }} -
+ +
From bace2f88b29394fc775977c48fb5eb4f971ed395 Mon Sep 17 00:00:00 2001 From: Azmi TOUIL <42934070+AzmiTouil@users.noreply.github.com> Date: Wed, 2 Oct 2024 13:24:10 +0200 Subject: [PATCH 07/16] feat: Manage Error when rewards not sent - MEED-7389 - Meeds-io/MIPs#154 (#570) --- .../locale/addon/Wallet_en.properties | 1 + .../components/reward/RewardDetails.vue | 21 ++++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/wallet-services/src/main/resources/locale/addon/Wallet_en.properties b/wallet-services/src/main/resources/locale/addon/Wallet_en.properties index 133f03fa3..d0ac10358 100644 --- a/wallet-services/src/main/resources/locale/addon/Wallet_en.properties +++ b/wallet-services/src/main/resources/locale/addon/Wallet_en.properties @@ -551,6 +551,7 @@ wallet.administration.rewardDetails.transactionInProgress=Transaction in progres wallet.administration.rewardDetails.transactionError=Transaction error wallet.administration.rewardDetails.searchLabel=search in names, wallet address wallet.administration.rewardDetails.sendingProgress=Sending in progress +wallet.administration.rewardDetails.sendingError=Rewards not sent. Try again wallet.administration.rewardDetails.label.name=Name wallet.administration.rewardDetails.label.status=Status wallet.administration.rewardDetails.label.points=Points diff --git a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardDetails.vue b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardDetails.vue index 59be92724..e42945358 100644 --- a/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardDetails.vue +++ b/wallet-webapps/src/main/webapp/vue-app/wallet-reward/components/reward/RewardDetails.vue @@ -42,7 +42,16 @@ {{ $t('wallet.administration.rewardDetails.sendingProgress') }}...