diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/settings/SettingsController.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/settings/SettingsController.java index 2b0e367e99f2eb1d5e26c2b0764fcf0f21a79f6d..1bcce0999fc94502f8e92ed744ae29e278b1eb34 100644 --- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/settings/SettingsController.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/settings/SettingsController.java @@ -13,6 +13,7 @@ import de.deadlocker8.budgetmaster.hints.HintService; import de.deadlocker8.budgetmaster.services.ImportResultItem; import de.deadlocker8.budgetmaster.services.ImportService; import de.deadlocker8.budgetmaster.settings.containers.*; +import de.deadlocker8.budgetmaster.settings.demo.DemoDateCreator; import de.deadlocker8.budgetmaster.transactions.keywords.TransactionNameKeyword; import de.deadlocker8.budgetmaster.transactions.keywords.TransactionNameKeywordRepository; import de.deadlocker8.budgetmaster.transactions.keywords.TransactionNameKeywordService; @@ -100,11 +101,12 @@ public class SettingsController extends BaseController private final BackupService backupService; private final HintService hintService; private final TransactionNameKeywordService keywordService; + private final DemoDateCreator demoDateCreator; private final List<Integer> SEARCH_RESULTS_PER_PAGE_OPTIONS = Arrays.asList(10, 20, 25, 30, 50, 100); @Autowired - public SettingsController(SettingsService settingsService, DatabaseService databaseService, CategoryService categoryService, ImportService importService, BudgetMasterUpdateService budgetMasterUpdateService, BackupService backupService, HintService hintService, TransactionNameKeywordService keywordService) + public SettingsController(SettingsService settingsService, DatabaseService databaseService, CategoryService categoryService, ImportService importService, BudgetMasterUpdateService budgetMasterUpdateService, BackupService backupService, HintService hintService, TransactionNameKeywordService keywordService, DemoDateCreator demoDateCreator) { this.settingsService = settingsService; this.databaseService = databaseService; @@ -114,6 +116,7 @@ public class SettingsController extends BaseController this.backupService = backupService; this.hintService = hintService; this.keywordService = keywordService; + this.demoDateCreator = demoDateCreator; } @GetMapping @@ -472,6 +475,16 @@ public class SettingsController extends BaseController return data.toString(); } + + @GetMapping("/database/createDemoData") + public String createDemoData(Model model) + { + demoDateCreator.createDemoData(); + + prepareBasicModel(model, settingsService.getSettings()); + return ReturnValues.ALL_ENTITIES; + } + private void prepareBasicModel(Model model, Settings settings) { model.addAttribute(ModelAttributes.SETTINGS, settings); diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/settings/demo/DemoDateCreator.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/settings/demo/DemoDateCreator.java new file mode 100644 index 0000000000000000000000000000000000000000..d0f82fb4be26cc1e595fbbc462898f07135cf6d0 --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/settings/demo/DemoDateCreator.java @@ -0,0 +1,202 @@ +package de.deadlocker8.budgetmaster.settings.demo; + +import de.deadlocker8.budgetmaster.accounts.Account; +import de.deadlocker8.budgetmaster.accounts.AccountService; +import de.deadlocker8.budgetmaster.accounts.AccountState; +import de.deadlocker8.budgetmaster.accounts.AccountType; +import de.deadlocker8.budgetmaster.categories.Category; +import de.deadlocker8.budgetmaster.categories.CategoryService; +import de.deadlocker8.budgetmaster.categories.CategoryType; +import de.deadlocker8.budgetmaster.icon.Icon; +import de.deadlocker8.budgetmaster.icon.IconService; +import de.deadlocker8.budgetmaster.transactions.Transaction; +import de.deadlocker8.budgetmaster.transactions.TransactionService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.text.MessageFormat; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import static java.time.temporal.TemporalAdjusters.firstDayOfMonth; +import static java.time.temporal.TemporalAdjusters.lastDayOfMonth; + +@Component +public class DemoDateCreator +{ + private static final Logger LOGGER = LoggerFactory.getLogger(DemoDateCreator.class); + + private final CategoryService categoryService; + private final IconService iconService; + private final AccountService accountService; + private final TransactionService transactionService; + + private final Random random; + + private Category categorySalary; + + @Autowired + public DemoDateCreator(CategoryService categoryService, IconService iconService, AccountService accountService, TransactionService transactionService) + { + this.categoryService = categoryService; + this.iconService = iconService; + this.accountService = accountService; + this.transactionService = transactionService; + + this.random = new Random(); + } + + public void createDemoData() + { + LOGGER.debug("Creating demo data..."); + + LOGGER.debug("Creating demo accounts..."); + createDemoAccounts(); + + LOGGER.debug("Creating demo categories..."); + createDemoCategories(); + + LOGGER.debug("Creating demo transactions..."); + createMultipleDemoTransaction(); + + LOGGER.debug("Demo data created"); + } + + private void createDemoAccounts() + { + final Icon icon = iconService.createIconReference(null, null, null); + iconService.getRepository().save(icon); + final Account oldAccount = new Account("Old account", AccountType.CUSTOM, icon); + oldAccount.setAccountState(AccountState.HIDDEN); + accountService.getRepository().save(oldAccount); + + final Icon icon2 = iconService.createIconReference(null, null, null); + iconService.getRepository().save(icon2); + final Account readOnlyAccount = new Account("Read-only account", AccountType.CUSTOM, icon2); + readOnlyAccount.setAccountState(AccountState.READ_ONLY); + accountService.getRepository().save(readOnlyAccount); + + final Icon icon3 = iconService.createIconReference(null, "fas fa-piggy-bank", null); + iconService.getRepository().save(icon3); + final Account savingsBankAccount = new Account("Savings Bank", AccountType.CUSTOM, icon3); + accountService.getRepository().save(savingsBankAccount); + } + + private void createDemoCategories() + { + final Icon icon = iconService.createIconReference(null, "fas fa-car", null); + iconService.getRepository().save(icon); + categoryService.save(new Category("Car", "#007afa", CategoryType.CUSTOM, icon)); + + final Icon icon2 = iconService.createIconReference(null, "fas fa-money-bill-alt", null); + iconService.getRepository().save(icon2); + categoryService.save(new Category("Cash", "#888888", CategoryType.CUSTOM, icon2)); + + final Icon icon3 = iconService.createIconReference(null, null, null); + iconService.getRepository().save(icon3); + categoryService.save(new Category("Electricity/Gas", "#888888", CategoryType.CUSTOM, icon3)); + + final Icon icon4 = iconService.createIconReference(null, null, null); + iconService.getRepository().save(icon4); + categoryService.save(new Category("Electronics", "#ff9500", CategoryType.CUSTOM, icon4)); + + final Icon icon5 = iconService.createIconReference(null, null, null); + iconService.getRepository().save(icon5); + categoryService.save(new Category("Misc", "#333333", CategoryType.CUSTOM, icon5)); + + final Icon icon6 = iconService.createIconReference(null, "fas fa-mobile-alt", null); + iconService.getRepository().save(icon6); + categoryService.save(new Category("Mobile Phone/Internet", "#5ac8fa", CategoryType.CUSTOM, icon6)); + + final Icon icon7 = iconService.createIconReference(null, "fas fa-home", null); + iconService.getRepository().save(icon7); + categoryService.save(new Category("Rent", "#9b59b6", CategoryType.CUSTOM, icon7)); + + final Icon icon8 = iconService.createIconReference(null, "fas fa-coins", null); + iconService.getRepository().save(icon8); + categorySalary = categoryService.save(new Category("Salary", "#4cd964", CategoryType.CUSTOM, icon8)); + } + + private void createMultipleDemoTransaction() + { + final LocalDate now = LocalDate.now(); + + for(int k = 0; k < 3; k++) + { + final LocalDate date = now.minusMonths(k); + + for(int i = 0; i < 20; i++) + { + createSingleDemoTransaction(date); + } + + final Transaction transaction = new Transaction(); + transaction.setName("Salary"); + transaction.setAmount(getRandomNumber(2000 * 100, 4000 * 100)); + transaction.setIsExpenditure(false); + transaction.setCategory(categorySalary); + transaction.setDate(date.withDayOfMonth(1)); + transaction.setDescription(""); + transaction.setTags(new ArrayList<>()); + transaction.setAccount(accountService.getAllActivatedAccountsAsc().get(1)); + transaction.setTransferAccount(null); + transaction.setRepeatingOption(null); + + transactionService.getRepository().save(transaction); + } + } + + private void createSingleDemoTransaction(LocalDate date) + { + final Transaction transaction = new Transaction(); + transaction.setName(getRandomTransactionName()); + transaction.setAmount(-getRandomNumber(100, 250 * 100)); + transaction.setIsExpenditure(true); + transaction.setCategory(getRandomCategory()); + transaction.setDate(getRandomDateInMonth(date)); + transaction.setDescription(getRandomTransactionDescription()); + transaction.setTags(new ArrayList<>()); + transaction.setAccount(accountService.getAllActivatedAccountsAsc().get(1)); + transaction.setTransferAccount(null); + transaction.setRepeatingOption(null); + + LOGGER.debug(MessageFormat.format("Creating demo transaction: {0}", transaction)); + + transactionService.getRepository().save(transaction); + } + + private String getRandomTransactionName() + { + final List<String> names = List.of("Electricity", "Internet and Phone", "Pizza", "Pizza", "Bread", "Fuel", "Fuel", "Rent", "Train Ticket", "Train Ticket", "Train Ticket", "Train Ticket", "Train Ticket", "Coffee", "Coffee", "Coffee", "Coffee", "Groceries"); + return names.get(getRandomNumber(0, names.size())); + } + + private String getRandomTransactionDescription() + { + final List<String> names = List.of("Lorem Ipsum", "dolor sit amet", "the best in town", "", "", "", ""); + return names.get(getRandomNumber(0, names.size())); + } + + private Category getRandomCategory() + { + final List<Category> categories = categoryService.getAllCustomCategories(); + return categories.get(getRandomNumber(0, categories.size())); + } + + private int getRandomNumber(int min, int max) + { + return random.nextInt(min, max); + } + + private LocalDate getRandomDateInMonth(LocalDate date) + { + final LocalDate firstDayInMonth = date.with(firstDayOfMonth()); + final int maxDayNumber = date.with(lastDayOfMonth()).getDayOfMonth(); + + return firstDayInMonth.withDayOfMonth(getRandomNumber(1, maxDayNumber)); + } +} diff --git a/BudgetMasterServer/src/main/resources/languages/base_de.properties b/BudgetMasterServer/src/main/resources/languages/base_de.properties index 319edb0d8aa0e10c26285ef9c6cd74a0b37c9535..e6eb1a1a00a25243127928d6c9fc1de89c516d96 100644 --- a/BudgetMasterServer/src/main/resources/languages/base_de.properties +++ b/BudgetMasterServer/src/main/resources/languages/base_de.properties @@ -339,6 +339,8 @@ settings.database.import=Importieren settings.database.export=Exportieren settings.database.delete=Löschen settings.database.delete.verification=Bestätigungscodes +settings.database.createDemoData=Demodaten erzeugen + settings.search.itemsPerPage=Anzahl der Suchergebnisse pro Seite diff --git a/BudgetMasterServer/src/main/resources/languages/base_en.properties b/BudgetMasterServer/src/main/resources/languages/base_en.properties index 752c0c9a07355d5b13b694183d1f01233e4e96b0..8181ffd6aed50243a29dff527555d1b86405becc 100644 --- a/BudgetMasterServer/src/main/resources/languages/base_en.properties +++ b/BudgetMasterServer/src/main/resources/languages/base_en.properties @@ -340,6 +340,7 @@ settings.database.import=Import settings.database.export=Export settings.database.delete=Delete settings.database.delete.verification=Verification Code +settings.database.createDemoData=Create Demo Data settings.search.itemsPerPage=Number of search results per page diff --git a/BudgetMasterServer/src/main/resources/templates/settings/settings.ftl b/BudgetMasterServer/src/main/resources/templates/settings/settings.ftl index 0d0edbe200f37eaacdf82732c1db8b4322268d85..d58770692479973b2f546a60ee509a8174e1eddc 100644 --- a/BudgetMasterServer/src/main/resources/templates/settings/settings.ftl +++ b/BudgetMasterServer/src/main/resources/templates/settings/settings.ftl @@ -66,6 +66,14 @@ <@settingsMacros.settingsCollapsibleItem "" "fas fa-database" locale.getString("menu.settings.database") true> <@settingsMacros.databaseNormal/> <@settingsMacros.databaseSmall/> + <div class="row no-margin-bottom"> + <#if programArgs.isDebug()> + <br> + <div class="col s12 center-align"> + <@header.buttonLink url='/settings/database/createDemoData' icon='auto_fix_normal' localizationKey='settings.database.createDemoData' color='background-orange-dark'/> + </div> + </#if> + </div> </@settingsMacros.settingsCollapsibleItem> </ul> </div>