import datetime
from sqlalchemy.sql.expression import func

from pyramid.view import view_config

from brewman.models import DBSession
from brewman.models.master import Product, CostCenter

from brewman.models.voucher import Voucher, Journal, Inventory
from brewman.views.services.session import session_period_finish


@view_config(request_method='GET', route_name='closing_stock', renderer='brewman:templates/angular_base.mako',
             permission='Closing Stock')
@view_config(request_method='GET', route_name='closing_stock_date', renderer='brewman:templates/angular_base.mako',
             permission='Closing Stock')
def html(request):
    return {}


@view_config(request_method='GET', route_name='api_closing_stock', renderer='json', permission='Closing Stock')
def report_blank(request):
    return {'Date': session_period_finish(request), 'Body': []}


@view_config(request_method='GET', route_name='api_closing_stock_date', renderer='json', permission='Closing Stock')
def report_data(request):
    date = request.matchdict.get('date', None)
    return {'Date': date, 'Body': build_report(date)}


def build_report(date):
    date = datetime.datetime.strptime(date, '%d-%b-%Y')
    amount_sum = func.sum(Journal.debit * Inventory.quantity * Inventory.rate * (1 + Inventory.tax)).label('Amount')
    quantity_sum = func.sum(Journal.debit * Inventory.quantity).label('Quantity')
    query = DBSession.query(Product, quantity_sum, amount_sum) \
        .join(Product.inventories).join(Inventory.voucher).join(Voucher.journals) \
        .filter(Voucher.date <= date) \
        .filter(Journal.cost_center_id == CostCenter.cost_center_purchase()) \
        .group_by(Product) \
        .order_by(amount_sum.desc()).all()

    body = []
    for product, quantity, amount in query:
        if quantity != 0 and amount != 0:
            body.append({'Product': product.full_name, 'Group': product.product_group.name,
                         'Quantity': quantity, 'Amount': amount})
    return body


def get_opening_stock(startDate):
    opening_stock = DBSession.query(func.sum(Inventory.quantity * Inventory.rate * (1 + Inventory.tax) * Journal.debit)) \
        .join(Journal.voucher).join(Journal.ledger).join(Voucher.inventories) \
        .filter(Voucher.date < startDate) \
        .filter(Journal.cost_center_id == CostCenter.cost_center_purchase()) \
        .scalar()
    return 0 if opening_stock is None else opening_stock


def get_closing_stock(finishDate):
    closing_stock = DBSession.query(func.sum(Inventory.quantity * Inventory.rate * (1 + Inventory.tax) * Journal.debit)) \
        .join(Journal.voucher).join(Journal.ledger).join(Voucher.inventories) \
        .filter(Voucher.date <= finishDate) \
        .filter(Journal.cost_center_id == CostCenter.cost_center_purchase()) \
        .scalar()
    return 0 if closing_stock is None else closing_stock
