diff --git a/src/main/java/de/deadlocker8/budgetmaster/accounts/Account.java b/src/main/java/de/deadlocker8/budgetmaster/accounts/Account.java
index 92f09e6af64bb9a487734d7d8b59cd457a11dbc5..c1647ca760e5ee6508f5e78197ac61b6cb5cef47 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/accounts/Account.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/accounts/Account.java
@@ -29,8 +29,13 @@ public class Account
 
 	private Boolean isSelected = false;
 	private Boolean isDefault = false;
+
+	@Deprecated
 	private Boolean isReadOnly = false;
 
+	@Expose
+	private AccountState accountState;
+
 	@ManyToOne
 	@Expose
 	private Image icon;
@@ -44,7 +49,7 @@ public class Account
 		this.type = type;
 		this.isSelected = false;
 		this.isDefault = false;
-		this.isReadOnly = false;
+		this.accountState = AccountState.FULL_ACCESS;
 		this.icon = icon;
 	}
 
@@ -107,16 +112,28 @@ public class Account
 		isDefault = aDefault;
 	}
 
+	@Deprecated
 	public Boolean isReadOnly()
 	{
 		return isReadOnly;
 	}
 
+	@Deprecated
 	public void setReadOnly(Boolean readOnly)
 	{
 		isReadOnly = readOnly;
 	}
 
+	public AccountState getAccountState()
+	{
+		return accountState;
+	}
+
+	public void setAccountState(AccountState accountState)
+	{
+		this.accountState = accountState;
+	}
+
 	public AccountType getType()
 	{
 		return type;
@@ -146,7 +163,7 @@ public class Account
 				", referringTransactions=" + referringTransactions +
 				", isSelected=" + isSelected +
 				", isDefault=" + isDefault +
-				", isReadOnly=" + isReadOnly +
+				", accountState=" + accountState +
 				", type=" + type +
 				", icon=" + icon +
 				'}';
@@ -158,18 +175,17 @@ public class Account
 		if(this == o) return true;
 		if(o == null || getClass() != o.getClass()) return false;
 		Account account = (Account) o;
-		return isSelected == account.isSelected &&
-				isDefault == account.isDefault &&
-				isReadOnly == account.isReadOnly &&
-				Objects.equals(ID, account.ID) &&
+		return Objects.equals(ID, account.ID) &&
 				Objects.equals(name, account.name) &&
-				type == account.type &&
-				Objects.equals(icon, account.icon);
+				Objects.equals(isSelected, account.isSelected) &&
+				Objects.equals(isDefault, account.isDefault) &&
+				accountState == account.accountState &&
+				Objects.equals(icon, account.icon) && type == account.type;
 	}
 
 	@Override
 	public int hashCode()
 	{
-		return Objects.hash(ID, name, isSelected, isDefault, isReadOnly, type, icon);
+		return Objects.hash(ID, name, isSelected, isDefault, accountState, icon, type);
 	}
 }
\ No newline at end of file
diff --git a/src/main/java/de/deadlocker8/budgetmaster/accounts/AccountController.java b/src/main/java/de/deadlocker8/budgetmaster/accounts/AccountController.java
index 38b3e8dd1fdcdfc34847f8b14183dccd2f86ec07..4cb602a66050bea90bb1b72afa29dd620153daf9 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/accounts/AccountController.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/accounts/AccountController.java
@@ -133,6 +133,7 @@ public class AccountController extends BaseController
 		model.addAttribute("account", emptyAccount);
 		model.addAttribute("settings", settingsService.getSettings());
 		model.addAttribute("availableImages", imageService.getRepository().findAll());
+		model.addAttribute("availableAccountStates", AccountState.values());
 		return "accounts/newAccount";
 	}
 
@@ -148,6 +149,7 @@ public class AccountController extends BaseController
 		model.addAttribute("account", accountOptional.get());
 		model.addAttribute("settings", settingsService.getSettings());
 		model.addAttribute("availableImages", imageService.getRepository().findAll());
+		model.addAttribute("availableAccountStates", AccountState.values());
 		return "accounts/newAccount";
 	}
 
@@ -172,6 +174,7 @@ public class AccountController extends BaseController
 			model.addAttribute("account", account);
 			model.addAttribute("settings", settingsService.getSettings());
 			model.addAttribute("availableImages", imageService.getRepository().findAll());
+			model.addAttribute("availableAccountStates", AccountState.values());
 			return "accounts/newAccount";
 		}
 		else
diff --git a/src/main/java/de/deadlocker8/budgetmaster/accounts/AccountService.java b/src/main/java/de/deadlocker8/budgetmaster/accounts/AccountService.java
index a2c710af86432b813eef3b5238bede4831b9351b..cd7624f8a1bc0d64deac0560ed646df01631a7c7 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/accounts/AccountService.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/accounts/AccountService.java
@@ -11,6 +11,7 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
@@ -105,15 +106,7 @@ public class AccountService implements Resetable
 			LOGGER.debug("Created default account");
 		}
 
-		// handle null values for new field "isReadOnly"
-		for(Account account : accountRepository.findAll())
-		{
-			if(account.isReadOnly() == null)
-			{
-				account.setReadOnly(false);
-			}
-			accountRepository.save(account);
-		}
+		updateMissingAttributes();
 
 		Account defaultAccount = accountRepository.findByIsDefault(true);
 		if(defaultAccount == null)
@@ -124,6 +117,27 @@ public class AccountService implements Resetable
 		setAsDefaultAccount(accountRepository.findByIsDefault(true).getID());
 	}
 
+	private void updateMissingAttributes()
+	{
+		// handle null values for new field "accountState"
+		for(Account account : accountRepository.findAll())
+		{
+			if(account.getAccountState() == null)
+			{
+				if(account.isReadOnly() == null || !account.isReadOnly())
+				{
+					account.setAccountState(AccountState.FULL_ACCESS);
+				}
+				else
+				{
+					account.setAccountState(AccountState.READ_ONLY);
+				}
+				LOGGER.debug(MessageFormat.format("Updated account {0}: Set missing attribute \"accountState\" to {1}", account.getName(), account.getAccountState()));
+			}
+			accountRepository.save(account);
+		}
+	}
+
 	private void deselectAllAccounts()
 	{
 		List<Account> accounts = accountRepository.findAll();
@@ -165,7 +179,7 @@ public class AccountService implements Resetable
 		}
 
 		Account accountToSelect = accountToSelectOptional.get();
-		if(accountToSelect.isReadOnly())
+		if(accountToSelect.getAccountState() != AccountState.FULL_ACCESS)
 		{
 			return;
 		}
diff --git a/src/main/java/de/deadlocker8/budgetmaster/accounts/AccountState.java b/src/main/java/de/deadlocker8/budgetmaster/accounts/AccountState.java
new file mode 100644
index 0000000000000000000000000000000000000000..217345583de1dd06093a6d584b342a410bb8f7ea
--- /dev/null
+++ b/src/main/java/de/deadlocker8/budgetmaster/accounts/AccountState.java
@@ -0,0 +1,8 @@
+package de.deadlocker8.budgetmaster.accounts;
+
+public enum AccountState
+{
+	FULL_ACCESS,
+	READ_ONLY,
+	HIDDEN
+}
diff --git a/src/main/java/de/deadlocker8/budgetmaster/templates/TemplateService.java b/src/main/java/de/deadlocker8/budgetmaster/templates/TemplateService.java
index 3c41b17d95231fe534fece7d4fdcb058c86ba5ba..7850ed482dfbd86a32b2e46c407dd7d21d24eae6 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/templates/TemplateService.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/templates/TemplateService.java
@@ -4,6 +4,7 @@ import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import de.deadlocker8.budgetmaster.accounts.Account;
 import de.deadlocker8.budgetmaster.accounts.AccountService;
+import de.deadlocker8.budgetmaster.accounts.AccountState;
 import de.deadlocker8.budgetmaster.categories.CategoryService;
 import de.deadlocker8.budgetmaster.categories.CategoryType;
 import de.deadlocker8.budgetmaster.services.Resetable;
@@ -86,7 +87,7 @@ public class TemplateService implements Resetable
 		}
 
 		final Account account = template.getAccount();
-		if(account != null && account.isReadOnly())
+		if(account != null && account.getAccountState() != AccountState.FULL_ACCESS)
 		{
 			template.setAccount(accountService.getRepository().findByIsDefault(true));
 		}
diff --git a/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionController.java b/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionController.java
index 6b0875f95cb9a16f95dc0531ce9ded02899d9938..f406b675b97e1e9becc901a8d5c408d309496610 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionController.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionController.java
@@ -2,6 +2,7 @@ package de.deadlocker8.budgetmaster.transactions;
 
 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.CategoryService;
 import de.deadlocker8.budgetmaster.categories.CategoryType;
@@ -249,7 +250,7 @@ public class TransactionController extends BaseController
 
 		Transaction transaction = transactionOptional.get();
 
-		if(transaction.getAccount().isReadOnly())
+		if(transaction.getAccount().getAccountState() != AccountState.FULL_ACCESS)
 		{
 			return "redirect:/transactions";
 		}
diff --git a/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionService.java b/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionService.java
index 52d401fbc59d930f7f8dcd52935e2c31d27660ff..6724a46891378f08783e0e6f1b43dae7bc2297b1 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionService.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionService.java
@@ -3,6 +3,7 @@ package de.deadlocker8.budgetmaster.transactions;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import de.deadlocker8.budgetmaster.accounts.Account;
+import de.deadlocker8.budgetmaster.accounts.AccountState;
 import de.deadlocker8.budgetmaster.accounts.AccountType;
 import de.deadlocker8.budgetmaster.categories.CategoryService;
 import de.deadlocker8.budgetmaster.categories.CategoryType;
@@ -193,7 +194,7 @@ public class TransactionService implements Resetable
 					return false;
 				}
 
-				return !transaction.getAccount().isReadOnly();
+				return transaction.getAccount().getAccountState() == AccountState.FULL_ACCESS;
 			}
 		}
 		return false;
diff --git a/src/main/resources/templates/accounts/accounts.ftl b/src/main/resources/templates/accounts/accounts.ftl
index 0f7d695ab17128bf940742915fe997ff4b9e64de..930563cb484a6b7c4ea4b1b65b697a689a133b56 100644
--- a/src/main/resources/templates/accounts/accounts.ftl
+++ b/src/main/resources/templates/accounts/accounts.ftl
@@ -27,7 +27,7 @@
                             <#if (account.getType().name() == "CUSTOM")>
                                 <tr class="account-overview-row">
                                     <td>
-                                        <#if account.isReadOnly()>
+                                        <#if account.getAccountState().name() == "READ_ONLY">
                                             <#assign toolTipText = locale.getString("account.tooltip.readonly.activate")/>
                                             <#assign lockIcon = '<i class="fas fa-lock"></i>'/>
                                             <div class="placeholder-icon"></div>
diff --git a/src/main/resources/templates/accounts/newAccount.ftl b/src/main/resources/templates/accounts/newAccount.ftl
index 6e2eb0c3b03f6cf1fbcc59698c66e276e8336d5a..15503f670e13e6c183bea0e2f86537fcf3355ad2 100644
--- a/src/main/resources/templates/accounts/newAccount.ftl
+++ b/src/main/resources/templates/accounts/newAccount.ftl
@@ -34,7 +34,6 @@
                         <input type="hidden" name="ID" value="<#if account.getID()??>${account.getID()?c}</#if>">
                         <input type="hidden" name="isSelected" value="<#if account.isSelected()??>${account.isSelected()?c}</#if>">
                         <input type="hidden" name="isDefault" value="<#if account.isDefault()??>${account.isDefault()?c}</#if>">
-                        <input type="hidden" name="isReadOnly" value="<#if account.isReadOnly()??>${account.isReadOnly()?c}</#if>">
 
                         <#-- name -->
                         <div class="row">
@@ -63,6 +62,17 @@
                             </div>
                         </div>
 
+                        <#-- state -->
+                        <div class="row">
+                            <div class="input-field col s12 m12 l8 offset-l2">
+                                <select name="accountState">
+                                    <#list availableAccountStates as state>
+                                        <option value="${state}">${state}</option>
+                                    </#list>
+                                </select>
+                            </div>
+                        </div>
+
                         <br>
 
                         <#-- buttons -->
diff --git a/src/main/resources/templates/transactions/transactionsMacros.ftl b/src/main/resources/templates/transactions/transactionsMacros.ftl
index 4cd4bd44905755089c557931b2355d3b92a7f59a..24c9c5f5bafe1a19cf5432f8cf9c2e0d83af932a 100644
--- a/src/main/resources/templates/transactions/transactionsMacros.ftl
+++ b/src/main/resources/templates/transactions/transactionsMacros.ftl
@@ -61,7 +61,7 @@
 </#macro>
 
 <#macro transactionAccountIcon transaction>
-    <#if helpers.getCurrentAccount().getType() == "ALL" && transaction.getAccount()??>
+    <#if helpers.getCurrentAccount().getType().name() == "ALL" && transaction.getAccount()??>
         <#import "../helpers/customSelectMacros.ftl" as customSelectMacros>
         <div class="col s2 l1 xl1 tooltipped no-padding" data-position="bottom" data-tooltip="${transaction.getAccount().getName()}">
             <div class="hide-on-med-and-down">