package info.bukova.isspst.services.invoicing;

import info.bukova.isspst.data.Invoicing;
import info.bukova.isspst.data.InvoicingItem;
import info.bukova.isspst.data.Workgroup;
import info.bukova.isspst.services.AbstractOwnedService;
import info.bukova.isspst.services.LazyLoader;

import java.math.BigDecimal;
import java.util.List;

import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;

public class InvoicingServiceImpl extends AbstractOwnedService<Invoicing> implements
		InvoicingService {

	@Override
	@Transactional
	public BigDecimal totalInvoicedForWorkgroup(Workgroup workgroup) {
		Query q = dao.getQuery("select sum(inv.totalInvoiced) "
				+ "from Invoicing inv join inv.requirement rq join rq.workgroup w "
				+ "where w = :workgroup ");
		q.setParameter("workgroup", workgroup);
		return (BigDecimal) q.uniqueResult();
	}

	@Override
	@Transactional
	@LazyLoader("form")
	public void loadReqItems(Invoicing invoicing) {
		Invoicing inv = getById(invoicing.getId());
		Hibernate.initialize(inv.getRequirement().getItems());
		invoicing.getRequirement().setItems(inv.getRequirement().getItems());
	}

	@Override
	@Transactional
	@LazyLoader({"form", "grid"})
	public void loadItems(Invoicing invoicing) {
		Invoicing inv = getById(invoicing.getId());
		Hibernate.initialize(inv.getItems());
		invoicing.setItems(inv.getItems());
	}

	@Override
	public void calculate(Invoicing invoicing) {
		BigDecimal total = BigDecimal.ZERO;
		
		for (InvoicingItem item : invoicing.getItems()) {
			total = total.add(item.getAmount());
		}
		
		invoicing.setTotalInvoiced(total);
	}

	@SuppressWarnings("unchecked")
	@Override
	@Transactional
	@PreAuthorize("hasPermission(this, 'PERM_READ')")
	public List<Invoicing> getAll() {
		Query q = dao.getQuery("select inv from Invoicing as inv join fetch inv.requirement rq join fetch rq.ownedBy order by rq.numser");
		return q.list();
	}
	
	@Transactional
	@LazyLoader("form")
	public void loadOwnedBy(Invoicing invoice) {
		Invoicing inv = getById(invoice.getId());
		Hibernate.initialize(inv.getRequirement().getOwnedBy());
		invoice.getRequirement().setOwnedBy(inv.getRequirement().getOwnedBy());
	}

	@SuppressWarnings("unchecked")
	@Override
	@Transactional
	@PreAuthorize("hasPermission(this, 'PERM_READ')")
	public List<Invoicing> getPendingList()
	{
		Query q = dao.getQuery("select inv from Invoicing as inv join fetch inv.requirement rq join fetch rq.ownedBy where (inv.completed Is Null or inv.completed = false) order by rq.numser");
		return q.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	@Transactional
	@PreAuthorize("hasPermission(this, 'PERM_READ')")
	public List<Invoicing> getArchiveList()
	{
		Query q = dao.getQuery("select inv from Invoicing as inv join fetch inv.requirement rq join fetch rq.ownedBy where inv.completed = true order by rq.numser");
		return q.list();
	}
}
