@Entity
@Table(name = "events")
public class Event {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;

	@Version
	private Long version;

	// TODO: Actually associate this with a user, not just an id that we have to reference...see Payment Model.
	//@ManyToOne(targetEntity=User.class)
	//@JoinColumn(name = "owner")
	//private User owner;
	@Column(name = "owner")
	private Long owner;
	
	@Column(name = "name")
	private String name;

	@Column(name = "amount")
	private BigDecimal amount;
	
	@Column(name = "completed")
	private Boolean completed;
	
	@Column(name = "hidden")
	private Boolean hidden;

	@Column(name = "created")
	@Temporal(TemporalType.TIMESTAMP)
	private java.util.Date created;

	public Long getId() {
		return id;
	}

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

	public Long getVersion() {
		return version;
	}

	public void setVersion(Long version) {
		this.version = version;
	}

	public Long getOwner() {
		return owner;
	}

	public void setOwner(Long owner) {
		this.owner = owner;
	}

	public String getName() {
		return name;
	}

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

	public BigDecimal getAmount() {
		return amount;
	}

	public void setAmount(BigDecimal amount) {
		this.amount = amount;
	}
	
	public Boolean getCompleted() {
		return completed;
	}
	
	public void setCompleted(Boolean completed) {
		this.completed = completed;
	}
	
	public Boolean getHidden() {
		return hidden;
	}

	public void setHidden(Boolean hidden) {
		this.hidden = hidden;
	}

	public java.util.Date getCreated() {
		return created;
	}

	public void setCreated(java.util.Date created) {
		this.created = created;
	}
	
	public void populateEvent(Long owner, String name, BigDecimal amount,
	java.util.Date created, Boolean hidden) {
		this.owner = owner;
		this.name = name;
		this.amount = amount;
		this.created = created;
		this.completed = false;
		this.hidden = hidden;
	}
} @Entity
@Table(name = "users")
public class User implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * 
	 */
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;

	@Version
	private Long version;

	@Column(name = "username")
	private String username;

	@Column(name = "password")
	private String password;

	@Column(name = "email")
	private String email;

	@Column(name = "answer")
	private String answer;

	@Column(name = "firstname")
	private String firstname;

	@Column(name = "lastname")
	private String lastname;

	@Column(name = "privacyEnabled")
	private Boolean privacyEnabled;

	@Column(name = "enabled")
	private Boolean enabled;

	@Column(name = "accountNonExpired")
	private Boolean accountNonExpired;

	@Column(name = "credentialsNonExpired")
	private Boolean credentialsNonExpired;

	@Column(name = "accountNonLocked")
	private Boolean accountNonLocked;

	@Column(name = "credit_card")
	private Long creditCard;

	@Column(name = "balance")
	private BigDecimal balance;

	@OneToMany(mappedBy = "user")
	private Set<Role> roles;

	public Long getId() {
		return id;
	}

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

	public Long getVersion() {
		return version;
	}

	public void setVersion(Long version) {
		this.version = version;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getFirstname() {
		return firstname;
	}

	public void setFirstname(String firstname) {
		this.firstname = firstname;
	}

	public String getLastname() {
		return lastname;
	}

	public void setLastname(String lastname) {
		this.lastname = lastname;
	}

	public void setCreditCard(long creditCard) {
		this.creditCard = creditCard;
	}

	public Long getCreditCard() {
		return creditCard;
	}

	public void setCreditCard(Long creditCard) {
		this.creditCard = creditCard;
	}

	public BigDecimal getBalance() {
		return balance;
	}

	public void setBalance(BigDecimal balance) {
		this.balance = balance;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getAnswer() {
		return answer;
	}

	public void setAnswer(String answer) {
		this.answer = answer;
	}

	public boolean isAccountNonLocked() {
		return true;
	}

	public void setAccountNonLocked(Boolean accountNonLocked) {
		this.accountNonLocked = accountNonLocked;
	}

	public Set<Role> getRoles() {
		return roles;
	}

	public void setRoles(Set<Role> roles) {
		this.roles = roles;
	}

	public void addAccountInfo(String username, String password, String answer,
			String email, String firstname, String lastname) {
		this.setUsername(username);
		this.setPassword(password);
		this.setAnswer(answer);
		this.setEmail(email);
		this.setFirstname(firstname);
		this.setLastname(lastname);
		this.setAccountNonLocked(true);
		this.roles = new HashSet<Role>();
		// create a new user with basic user privileges
		roles.add(new Role("USER", this));
		this.setRoles(roles);
		this.setPrivacyEnabled(false);
		this.balance = new BigDecimal(0.0);
	}

	public boolean isAccountNonExpired() {
		// TODO Auto-generated method stub
		return true;
	}

	public boolean isCredentialsNonExpired() {
		// TODO Auto-generated method stub
		return true;
	}

	public boolean isEnabled() {
		// TODO Auto-generated method stub
		return true;
	}

	public Boolean getPrivacyEnabled() {
		return privacyEnabled;
	}

	public void setPrivacyEnabled(Boolean privacyEnabled) {
		this.privacyEnabled = privacyEnabled;
	}

	public Boolean getEnabled() {
		return enabled;
	}

	public void setEnabled(Boolean enabled) {
		this.enabled = enabled;
	}

	public Boolean getAccountNonExpired() {
		return accountNonExpired;
	}

	public void setAccountNonExpired(Boolean accountNonExpired) {
		this.accountNonExpired = accountNonExpired;
	}

	public Boolean getCredentialsNonExpired() {
		return credentialsNonExpired;
	}

	public void setCredentialsNonExpired(Boolean credentialsNonExpired) {
		this.credentialsNonExpired = credentialsNonExpired;
	}

	public static long getSerialversionuid() {
		return serialVersionUID;
	}

	public Boolean getAccountNonLocked() {
		return accountNonLocked;
	}
} @Entity
@Table(name = "eventMemberships")
public class EventMembership {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;

	@Version
	private Long version;

	@Column(name = "eventId")
	private Long eventId;

	@Column(name = "user")
	private Long user;

	@Column(name = "amount")
	private BigDecimal amount;

	@Column(name = "created")
	private java.util.Date created;

	public Long getId() {
		return id;
	}

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

	public Long getVersion() {
		return version;
	}

	public void setVersion(Long version) {
		this.version = version;
	}

	public Long getEventId() {
		return eventId;
	}

	public void setEventId(Long eventId) {
		this.eventId = eventId;
	}

	public Long getUser() {
		return user;
	}

	public void setUser(Long user) {
		this.user = user;
	}

	public BigDecimal getAmount() {
		return amount;
	}

	public void setAmount(BigDecimal amount) {
		this.amount = amount;
	}

	public java.util.Date getCreated() {
		return created;
	}

	public void setCreated(java.util.Date created) {
		this.created = created;
	}

	public void populateEventMembership(Long eventId, Long user,
			BigDecimal amount, java.util.Date created) {
		this.eventId = eventId;
		this.user = user;
		this.amount = amount;
		this.created = created;
	}
} @Entity
@Table(name = "payments")
public class Payment {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;

	@Version
	private Long version;

	@ManyToOne(targetEntity=Event.class)
	@JoinColumn(name = "event")
	private Event event;

	@Column(name = "amount")
	private BigDecimal amount;

	@Column(name = "timestamp")
	@Temporal(TemporalType.TIMESTAMP)
	private Date timestamp;

	@ManyToOne(targetEntity=User.class)
	@JoinColumn(name = "sender")
	private User sender;

	@ManyToOne(targetEntity=User.class)
	@JoinColumn(name = "receiver")
	private User receiver;

	public Long getId() {
		return id;
	}

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

	public Long getVersion() {
		return version;
	}

	public void setVersion(Long version) {
		this.version = version;
	}

	public Event getEvent() {
		return event;
	}

	public void setEvent(Event event) {
		this.event = event;
	}

	public BigDecimal getAmount() {
		return amount;
	}

	public void setAmount(BigDecimal amount) {
		this.amount = amount;
	}

	public java.util.Date getTimestamp() {
		return timestamp;
	}

	public void setTimestamp(java.util.Date timestamp) {
		this.timestamp = timestamp;
	}

	public User getSender() {
		return sender;
	}

	public void setSender(User sender) {
		this.sender = sender;
	}

	public User getReceiver() {
		return receiver;
	}

	public void setReceiver(User receiver) {
		this.receiver = receiver;
	}

	public void populatePayment(Event event, BigDecimal amount, User sender, User receiver) {
		this.event = event;
		this.amount = amount;
		this.sender = sender;
		this.receiver = receiver;
	}
} @Repository
@Qualifier(value = "eventMembershipRepository")
public interface EventMembershipRepository extends
		CrudRepository<EventMembership, Long> {

	@Query("delete EventMembership where eventId = ?1 and user = ?2")
	@Modifying
	@Transactional
	public void deleteEventByIdAndUser(Long event, Long user);
	
	@Query("select e from EventMembership e where e.user = ?1")
	public List<EventMembership> findEventMembershipByUserId(Long userId);

	@Query("select e from EventMembership e where e.eventId = ?1")
	public List<EventMembership> findEventMembershipsByEventId(Long eventId);
	
	@Query("select e from EventMembership e where e.eventId = ?1 and e.user = ?2")
	public EventMembership findEventMembershipByEventIdAndUserId(Long eventId, Long userId);

	@Query("select count(e) > 0 from EventMembership e where e.eventId = ?1 and e.user = ?2")
	public boolean isUserMember(Long eventId, Long userId);
	
	@Modifying
	@Transactional
	@Query("Update EventMembership e set e.amount = e.amount - ?3 where e.eventId = ?1 and e.user = ?2")
	public void makePayment(Long eventId, Long userId, BigDecimal amount);
} @Repository
@Qualifier(value = "eventRepository")
public interface EventRepository extends CrudRepository<Event, Long> {

	@Query("select e from Event e where e.owner = ?1")
	public List<Event> findEventsByOwner(long id);
	
	@Query("select e from Event e where e.id = ?1")
	public Event getEventById(long id);

	@Query("delete from Event where id = ?1")
	@Modifying
	public void deleteEventById(Long id);

	@Query("select owner from Event e where e.id = ?1")
	public Long getEventOwnerIdByEventId(Long eventId);
	
	@Modifying
	@Query("update Event e set e.owner = ?1, e.name = ?2, e.amount = ?3, e.hidden = ?4 where e.id = ?5")
	public void updateEventById(Long owner, String name, BigDecimal amount, Boolean hidden, Long id);

	@Query
	public List<Event> findByHiddenFalse();
	
	@Query
	public List<Event> findByHiddenTrue();
} @Repository
@Qualifier(value = "paymentRepository")
public interface PaymentRepository extends CrudRepository<Payment, Long> {

	@Query("select p from Payment p where p.sender = ?1")
	public List<Payment> findPaymentsBySender(User sender);

	@Query("select p from Payment p where p.receiver = ?1")
	public List<Payment> findPaymentsByReceiver(User receiver);
	
	@Query("select p from Payment p where p.event = ?1")
	public List<Payment> findPaymentsByEvent(Event event);
} @Repository
@Qualifier(value = "accountRepository")
public interface UserRepository extends CrudRepository<User, Long> {

	@Query("select u from User u where u.id = ?1")
	public User findById(Long id);

	@Query("select username from User u where u.username = ?1")
	public String findByUsername(String username);

	@Query("select username from User u where u.username = ?1 and u.password = ?2")
	public String findByUsernameAndPassword(String username, String password);

	@Query("select username from User u where u.id = ?1 and u.password = ?2")
	public String findUserByIdAndPassword(long id, String password);

	@Modifying
	@Query("update User u set u.password = ?2 where u.username = ?1")
	public void updatePasswordByUsername(String username, String password);

	@Modifying
	@Query("update User u set u.password = ?1 where u.id = ?2")
	public void updatePasswordById(String password, long id);

	// TODO leave as-is or grab the specific settings stuff...prob just
	// send/receive the entire user model from client
	@Query("select u from User u where u.username=?1")
	public void findSettingsByUsername(String username);

	// TODO: add the right settings to be persisted, or just persist the entire
	// user object or something else lazy
	@Modifying
	@Query("update User u set u.firstname = ?2, u.lastname = ?3, u.email = ?4 where u.username = ?1")
	public void updateUserProfile(String username, String firstname, String lastname, String email);

	@Query("select u from User u where u.username = ?1")
	public User getUserModelByUsername(String username);

	@Query("select accountNonLocked from User u where u.username = ?1 and u.accountNonLocked = false")
	public boolean getAccountNonLockedByUsername(String username);

	@Query("select u from User u where u.privacyEnabled = false")
	public List<User> getUsersByPrivacyDisabled();

	@Query("select answer from User u where u.username = ?1")
	public String getAnswerByUsername(String username);

	@Modifying
	@Transactional
	@Query("update User u set u.balance = ?2 where u.id = ?1")
	public void updateBalance(Long id, BigDecimal amount);

	@Modifying
	@Transactional
	@Query("update User u set u.answer = ?1 where u.id = ?2")
	public void updateAnswerById(String answer, long id);
} @Component
public class SecurityUtils {

	public NvUserDetails getSecurityContext() {
		return (NvUserDetails) SecurityContextHolder.getContext()
				.getAuthentication().getPrincipal();
	}

	public long getCurrentUserId() {
		return getSecurityContext().getUser().getId();
	}
} public interface EventService {

	public Long addEvent(String name, BigDecimal amount);

	public void updateEvent(Long owner, String name, BigDecimal amount, Boolean ispublic, Long id);

	public void addEventMembership(Long event, Long user, BigDecimal amount);

	public void deleteEvent(Long id);

	public void deleteEventMembership(Long eventId, Long userId);
	
	public boolean isUserMember(Long eventId, Long userId);

	public List<Event> getEventsByOwner(Long owner);
	
	public List<Event> getPublicEvents();

	public List<EventMembership> getEventsByMembership(Long userId);
	
	public List<EventMembership> getMembershipsByEvent(Long eventId);
	
	public List<User> getUsersbyEventMembership(Long eventId);
	
	public Event getEventById(Long id);
	
} public interface PaymentService {

	public boolean makePayment(Event event, BigDecimal amount);

	public List<Payment> getSentPayments(User user);

	public List<Payment> getReceivedPayments(User user);
	
	public BigDecimal getTotalPayments(Event event);
} public interface UserService extends UserDetailsService {

	public UserDetails loadUserByUsername(String username);
	
	public User loadUserById(Long id);
	
	public User loadUser(String username);

	public void addRegularUser(String username, String password, String email,
			String answer, String firstname, String lastname);

	public boolean isAnswerValid(String username, String answer);

	public boolean validateCredentials(String username, String password);

	public void logout();

	public boolean validateCurrentPassword(String password);

	public void updatePasswordById(String password);
	
	public void updateAnswerById(String answer);
	
	public void updatePasswordByUsername(String username, String password);
	
	public void updateUser(String username, String firstname, String lastname, String email);

	public boolean doesUserExist(String username);

	public List<User> getPublicUsers();

	public void credit(Long id, BigDecimal amount);

	public boolean debit(Long id, BigDecimal amount);
}
import java.math.BigDecimal;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import com.nvisium.androidnv.api.model.Event;
import com.nvisium.androidnv.api.model.User;
import com.nvisium.androidnv.api.model.EventMembership;
import com.nvisium.androidnv.api.model.Payment;
import com.nvisium.androidnv.api.repository.EventMembershipRepository;
import com.nvisium.androidnv.api.repository.EventRepository;
import com.nvisium.androidnv.api.repository.PaymentRepository;
import com.nvisium.androidnv.api.repository.UserRepository;
import com.nvisium.androidnv.api.security.SecurityUtils;
import com.nvisium.androidnv.api.service.EventService;
import com.nvisium.androidnv.api.service.PaymentService;
import com.nvisium.androidnv.api.service.UserService;
package com.nvisium.androidnv.api.service.impl;




@Service
@Qualifier(value = "paymentService")
public class PaymentServiceImpl implements PaymentService {