import datetime
from sqlalchemy.orm.util import aliased
from sqlalchemy.sql.expression import and_
import uuid

from pyramid.view import view_config

from brewman.models import DBSession
from brewman.models.validation_exception import TryCatchFunction

from brewman.models.voucher import Voucher, Journal, VoucherType


@view_config(route_name='api_issues_grid', request_param='Source', renderer='json', permission='Issue')
@TryCatchFunction
def grid_date(request):
    date = datetime.datetime.strptime(request.matchdict['date'], '%d-%b-%Y')
    return get_grid(date, uuid.UUID(request.GET['Source']), uuid.UUID(request.GET['Destination']))


@view_config(route_name='api_issues_grid', renderer='json', permission='Issue')
@TryCatchFunction
def grid_voucher(request):
    voucher = Voucher.by_id(uuid.UUID(request.matchdict['date']))
    source = [j.cost_center_id for j in voucher.journals if j.debit == -1]
    source = source[0]
    destination = [j.cost_center_id for j in voucher.journals if j.debit == 1]
    destination = destination[0]
    return get_grid(voucher.date, source, destination)


def get_grid(date, source, destination):
    list = []

    source_journal = aliased(Journal)
    destination_journal = aliased(Journal)
    source_or = (and_(source_journal.cost_center_id == source, source_journal.debit == -1))
    destination_or = (and_(destination_journal.cost_center_id == destination, destination_journal.debit == 1))
    query = DBSession.query(Voucher, source_journal.amount)\
    .join(source_journal, Voucher.journals)\
    .join(destination_journal, Voucher.journals)\
    .filter(Voucher.date == date)\
    .filter(Voucher.type == VoucherType.by_name('Issue').id)\
    .filter(and_(source_or, destination_or))\
    .order_by(Voucher.creation_date)\
    .all()

    for voucher, amount in query:
        list.append(
            {'VoucherID': str(voucher.id), 'Amount': amount})
    return list
