import datetime
import uuid
from pyramid.response import Response
from pyramid.security import authenticated_userid
from pyramid.view import view_defaults, view_config
import transaction
from brewman import groupfinder
from brewman.models.auth import User
from brewman.models.validation_exception import ValidationError, TryCatchFunction
from brewman.models.voucher import Voucher
from brewman.views import get_lock_info
from brewman.views.services.session import session_current_date_set
from . import voucher_info, issue_update_voucher, purchase_update_voucher, journal_update_voucher
from brewman.views.services.voucher.purchase_return import purchase_return_update_voucher
from brewman.views.services.voucher.salary_deduction import salary_deduction_update_voucher

__author__ = 'tanshu'


@view_defaults(request_method='POST', route_name='api_voucher_id', renderer='json')
class update_voucher(object):
    def __init__(self, request):
        self.request = request
        self.user = User.by_id(uuid.UUID(authenticated_userid(request)))
        self.voucher = Voucher.by_id(uuid.UUID(request.matchdict.get('id', None)))
        self.json = request.json_body
        self.start, self.finish = get_lock_info()
        self.voucher_date = datetime.datetime.strptime(self.json['Date'], '%d-%b-%Y')


        permissions = groupfinder(self.user.id, self.request)
        if self.voucher.posted and not 'Edit Posted Vouchers' in permissions:
            response = Response("You are not allowed to edit posted vouchers")
            response.status_int = 403
            self.error = response
        elif self.voucher.user_id != self.user.id and "Edit Other User's Vouchers" not in permissions:
            response = Response("You are not allowed to edit other user's vouchers")
            response.status_int = 403
            self.error = response
        elif self.start is not None and (self.start > self.voucher_date or self.start > self.voucher.date):
            response = Response("Vouchers before {0} have been locked.".format(self.start.strftime('%d-%b-%Y')))
            response.status_int = 403
            self.error = response
        elif self.finish is not None and (self.finish < self.voucher_date or self.finish < self.voucher.date):
            response = Response("Vouchers after {0} have been locked.".format(self.finish.strftime('%d-%b-%Y')))
            response.status_int = 403
            self.error = response
        else:
            self.error = None


    @view_config(request_param='type=Journal', permission='Journal')
    def journal(self):
        return self.update()


    @view_config(request_param='type=Payment', permission='Payment')
    def payment(self):
        return self.update()


    @view_config(request_param='type=Receipt', permission='Receipt')
    def receipt(self):
        return self.update()


    @view_config(request_param='type=Purchase', permission='Purchase')
    def purchase(self):
        return self.update()


    @view_config(request_param='type=Purchase Return', permission='Purchase Return')
    def purchase_return(self):
        return self.update()


    @view_config(request_param='type=Issue', permission='Issue')
    def issue(self):
        return self.update()

    @view_config(request_param='type=Salary Deduction', permission='Salary Deduction')
    def salary_deduction(self):
        return self.update()

    @TryCatchFunction
    def update(self):
        if self.error is not None:
            return self.error
        if self.json['Type'] in ['Journal', 'Payment', 'Receipt']:
            voucher = journal_update_voucher(self.voucher, self.json, self.user)
        elif self.json['Type'] in ['Purchase']:
            voucher = purchase_update_voucher(self.voucher, self.json, self.user)
        elif self.json['Type'] in ['Purchase Return']:
            voucher = purchase_return_update_voucher(self.voucher, self.json, self.user)
        elif self.json['Type'] in ['Issue']:
            voucher = issue_update_voucher(self.voucher, self.json, self.user)
        elif self.json['Type'] in ['Salary Deduction']:
            voucher = salary_deduction_update_voucher(self.voucher, self.json, self.user)
        transaction.commit()
        session_current_date_set(self.request, self.json['Date'])
        return voucher_info(Voucher.by_id(voucher.id))
