package com.github.cstroe.spendhawk.entity;

import com.github.cstroe.spendhawk.util.HibernateUtil;
import org.hibernate.criterion.Restrictions;

import java.util.Collection;
import java.util.Optional;

/**
 * A user has:
 * <ul>
 *     <li>A unique database id.</li>
 *     <li>A user name.  Used for identification in the system.</li>
 *     <li>Many accounts.</li>
 *     <li>Many expense categories.</li>
 * </ul>
 */
public class User {

    public static final String DEFAULT_INCOME_ACCOUNT_NAME = "Income";
    public static final String DEFAULT_EXPENSE_ACCOUNT_NAME = "Expenses";
    public static final String DEFAULT_ASSET_ACCOUNT_NAME = "Assets";

    private Long id;
    private String name;
    private Collection<Account> accounts;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Collection<Account> getAccounts() {
        return accounts;
    }

    public void setAccounts(Collection<Account> accounts) {
        this.accounts = accounts;
    }

    public Optional<Account> getAccountByName(String name) {
        return this.accounts.stream()
            .filter(a -> a.getName().equals(name))
            .findFirst();
    }

    public Optional<Account> getDefaultExpenseAccount() {
        return getAccountByName(DEFAULT_EXPENSE_ACCOUNT_NAME);
    }

    public Optional<Account> getDefaultIncomeAccount() {
        return getAccountByName(DEFAULT_INCOME_ACCOUNT_NAME);
    }

    public Optional<Account> getDefaultAssetAccount() {
        return getAccountByName(DEFAULT_ASSET_ACCOUNT_NAME);
    }

    public static Optional<User> findById(Long id) {
        return Optional.ofNullable((User) HibernateUtil.getSessionFactory().getCurrentSession()
                .createCriteria(User.class)
                .add(Restrictions.eq("id", id))
                .uniqueResult());
    }

}

@@ -1240,16 +1240,187 @@
   return
+ getAccountByName(name, false);%0A    %7D%0A%0A    private Optional%3CAccount%3E getAccountByName(String name, boolean createIfNotExists) %7B%0A        Optional%3CAccount%3E accountOptional =
  this.ac
@@ -1516,43 +1516,360 @@
 ();%0A
+%0A
     
-%7D%0A%0A    public Optional%3CAccount%3E
+    if(createIfNotExists && !accountOptional.isPresent()) %7B%0A            Account newAccount = new Account();%0A            newAccount.setName(name);%0A            newAccount.setUser(this);%0A            newAccount.save();%0A            return Optional.of(newAccount);%0A        %7D else %7B%0A            return accountOptional;%0A        %7D%0A    %7D%0A%0A    public Account
  get
@@ -1946,32 +1946,44 @@
 NSE_ACCOUNT_NAME
+, true).get(
 );%0A    %7D%0A%0A    pu
@@ -1987,33 +1987,23 @@
  public 
-Optional%3C
 Account
-%3E
  getDefa
@@ -2074,32 +2074,44 @@
 OME_ACCOUNT_NAME
+, true).get(
 );%0A    %7D%0A%0A    pu
@@ -2115,33 +2115,23 @@
  public 
-Optional%3C
 Account
-%3E
  getDefa
@@ -2208,16 +2208,28 @@
 UNT_NAME
+, true).get(
 );%0A    %7D

Create the default accounts if they don't already exist.