from brewman.models.master import CostCenter
from brewman.models.validation_exception import ValidationError

__author__ = 'tanshu'

def validate(voucher):
    journals_valid(voucher)
    if voucher.type in [2, 3, 6]:
        inventory_valid(voucher)
        if voucher.id is None and voucher.type == 3:
            # Issue
            issue_new(voucher)
        if voucher.id is None and voucher.type == 6:
            # Purchase Return
            purchase_return_new(voucher)
        if voucher.id is not None and voucher.type == 3:
            # Issue
            issue_update(voucher)
        if voucher.id is not None and voucher.type == 6:
            # Purchase Return
            purchase_return_update(voucher)


def check_batch_insert(voucher):
    if voucher.type == 9:
        raise ValidationError("Verification Vouchers have been disabled")
    if voucher.type == 6:
        # Purchase Return
        for item in voucher.inventories:
            batch = item.batch
            if batch.quantity_remaining < item.quantity:
                raise ValidationError(
                    "Quantity of {0} ({1}) cannot be more than {2}".format(item.product.name, item.product.units,
                        batch.quantity_remaining))
    if voucher.type == 3:
        # Issue
        purchase = None
        for item in voucher.journals:
            if item.cost_center_id == CostCenter.cost_center_purchase():
                purchase = item
        if purchase == None:
            return
        if purchase.debit == 1:
            return
        for item in voucher.inventories:
            batch = item.batch
            if batch.quantity_remaining < item.quantity:
                raise ValidationError(
                    "Quantity of {0} ({1}) cannot be more than {2}".format(item.product.name, item.product.units,
                        batch.quantity_remaining))
    if voucher.type == 2:
        # Purchase
        pass


def issue_new(voucher):
    consuming = filter(lambda x: x.cost_center_id == CostCenter.cost_center_purchase(), voucher.journals)
    if not len(consuming):
        consuming = False
    elif consuming[0].debit == 1:
        consuming == False
    else:
        consuming == True

    if not consuming:
        return

    for item in voucher.inventories:
        batch = item.batch
        if batch.quantity_remaining < item.quantity:
            raise ValidationError(
                "Quantity of {0} ({1}) cannot be more than {2}".format(item.product.name, item.product.units,
                    batch.quantity_remaining))


def issue_update(voucher):
    consuming = filter(lambda x: x.cost_center_id == CostCenter.cost_center_purchase(), voucher.journals)
    if not len(consuming):
        consuming = False
    elif consuming[0].debit == 1:
        consuming == False
    else:
        consuming == True

    if not consuming:
        return

    for item in voucher.inventories:
        batch = item.batch
        if batch.quantity_remaining < item.quantity:
            raise ValidationError(
                "Quantity of {0} ({1}) cannot be more than {2}".format(item.product.name, item.product.units,
                    batch.quantity_remaining))


def purchase_return_new(voucher):
    for item in voucher.inventories:
        batch = item.batch
        if batch.quantity_remaining < item.quantity:
            raise ValidationError(
                "Quantity of {0} ({1}) cannot be more than {2}".format(item.product.name, item.product.units,
                    batch.quantity_remaining))


def purchase_return_update(voucher):
    for item in voucher.inventories:
        batch = item.batch
        if batch.quantity_remaining < item.quantity:
            raise ValidationError(
                "Quantity of {0} ({1}) cannot be more than {2}".format(item.product.name, item.product.units,
                    batch.quantity_remaining))


def inventory_valid(voucher):
    if voucher.type in [2, 6, 3]:
        if not len(voucher.inventories):
            raise ValidationError("Not enough inventories")
        is_distinct_inventory(voucher.inventories)


def is_distinct_inventory(inventories):
    found = set()
    for item in inventories:
        itemHash = hash(item.product_id)
        if itemHash in found:
            raise ValidationError("Duplicate inventories")
        else:
            found.add(itemHash)


def batch_valid(voucher):
    pass


def is_date_allowed(voucher):
    pass


def journals_valid(voucher):
    if len(voucher.journals) < 2:
        raise ValidationError("Not enough journals")
    signedAmount = 0
    for item in voucher.journals:
        signedAmount += item.signed_amount
    if not signedAmount == 0:
        raise ValidationError("Journal amounts do no match")
    is_distinct_journal(voucher.journals)


def is_distinct_journal(journals):
    found = set()
    for item in journals:
        itemHash = hash(item.ledger_id) ^ hash(item.cost_center_id)
        if itemHash in found:
            raise ValidationError("Duplicate journals")
        else:
            found.add(itemHash)

