FoodWave.java 5.82 KB
/*
 * Copyright Codecrew Ry
 * 
 * All rights reserved.
 * 
 * This license applies to any software containing a notice placed by the 
 * copyright holder. Such software is herein referred to as the Software. 
 * This license covers modification, distribution and use of the Software. 
 * 
 * Any distribution and use in source and binary forms, with or without 
 * modification is not permitted without explicit written permission from the 
 * copyright owner. 
 * 
 * A non-exclusive royalty-free right is granted to the copyright owner of the 
 * Software to use, modify and distribute all modifications to the Software in 
 * future versions of the Software. 
 * 
 */
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package fi.codecrew.moya.model;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

/**
 * 
 */
@Entity
@Table(name = "food_waves")
public class FoodWave extends GenericEntity {

	private static final long serialVersionUID = 9221716203467295049L;

	@Column(name = "wave_name", nullable = false)
	private String name;

	@Lob
	@Column(name = "wave_description")
	private String description;

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

	@Column(name = "max_foods")
	private Integer maximumFoods;

	@Column(name = "wave_closed", nullable = false, columnDefinition = "boolean default false")
	private boolean closed = false;

	@OneToMany(mappedBy = "foodWave")
	private List<AccountEvent> accountEvents;

	@OneToMany(mappedBy = "foodwave")
	private List<BillLine> billLines;

	@ManyToOne
	@JoinColumn(name = "template_id", referencedColumnName = "id", nullable = false)
	private FoodWaveTemplate template;

	public FoodWave() {
		super();
	}

	public FoodWave(String waveName, boolean waveClosed) {
		super();
		this.name = waveName;
		this.closed = waveClosed;
	}

	public String getName() {
		return name;
	}

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

	public String getDescription() {
		return description;
	}

	public void setDescription(String waveDescription) {
		this.description = waveDescription;
	}

	public Date getTime() {
		return time;
	}

	public void setTime(Date waveTime) {
		this.time = waveTime;
	}

	public boolean getClosed() {
		return closed;
	}

	public boolean isClosed() {
		return closed;
	}

	public void setClosed(boolean waveClosed) {
		this.closed = waveClosed;
	}

	public void toggleClosed() {
		this.closed = !isClosed();
	}

	public List<AccountEvent> getAccountEvents() {
		return accountEvents;
	}

	public void setAccountEvents(List<AccountEvent> accountEventList) {
		this.accountEvents = accountEventList;
	}

	public void setTemplate(FoodWaveTemplate template) {
		this.template = template;
	}

	public FoodWaveTemplate getTemplate() {
		return template;
	}

	public boolean isFull() {
		if (getMaximumFoods() <= 0) {
			return false;
		}

		if (getReservedCount() >= getMaximumFoods()) {
			return true;
		}

		return false;
	}

	/**
	 * Check if foodwave is orderable
	 * 
	 * That means that it's not closed, full and it's in future
	 * 
	 * @return
	 */
	public boolean isOrderable() {

		if (isClosed()) {
			return false;
		}

		if (getTime().before(new Date())) {
			return false;
		}

		if (isFull()) {
			return false;
		}

		return true;
	}

	public List<Product> getOrderedProducts() {
		List<Product> retlist = new ArrayList<Product>();

		if (getAccountEvents() != null) {

			for (AccountEvent ae : getAccountEvents()) {

				if (!retlist.contains(ae.getProduct())) {
					retlist.add(ae.getProduct());
				}
			}
		}

		return retlist;
	}

	public List<BillLine> getBillLines() {
		return billLines;
	}

	public Integer getMaximumFoods() {

		if (maximumFoods == null) {
			return 0;
		}

		return maximumFoods;
	}

	public void setBillLines(List<BillLine> billLines) {
		this.billLines = billLines;
	}

	public Integer getReservedCount() {
		Integer retval = 0;

		retval += getOrderedCount();
		retval += getUnpaidCount();

		return retval;
	}

	public void setMaximumFoods(Integer maximumFoods) {
		this.maximumFoods = maximumFoods;
	}

	public Integer getUnpaidCount() {
		Integer ret = 0;
		for (BillLine line : getBillLines()) {
			if (!line.getBill().isPaid() && !line.getBill().isExpired()) {
				ret += line.getQuantity().intValue();
			}
		}
		return ret;
	}

	public Integer getOrderedCount() {
		Integer ret = 0;

		if (getAccountEvents() != null) {
			for (AccountEvent ae : getAccountEvents()) {
				ret += ae.getQuantity().intValue();
			}
		}

		return ret;
	}

	public Integer getDeliveredCount() {
		Integer delCount = new Integer(0);

		if (getAccountEvents() != null && getReservedCount() != 0) {
			for (AccountEvent ae : getAccountEvents()) {
				if (ae.isEventDelivered()) {
					delCount++;
				}
			}
		}

		return delCount;
	}

	public boolean isDelivered() {
		if (getAccountEvents() != null && getReservedCount() != 0) {
			for (AccountEvent ae : getAccountEvents()) {
				if (!ae.isEventDelivered()) {
					return false;
				}
			}
		}
		return true;
	}
	
	@Transient
	public Date getLastPaymentTime() {
		return new Date(getTime().getTime() + (getTemplate().getWaitPaymentsMinutes().longValue() * 60l * 1000l));
	}

	public boolean isPaymentOver() {

		// add this magical "wait payments this amount of minutes" to foodwave
		Date endDate = new Date(getTime().getTime() + (getTemplate().getWaitPaymentsMinutes().longValue() * 60l * 1000l));

		if (isClosed() || endDate.before(new Date())) {
			return true;
		}

		return false;
	}

}