# -*- coding: utf-8 -*-
from openerp import models, fields, tools, api
from datetime import datetime
from pytz import timezone
import openerp.addons.decimal_precision as dp

DATE_FORMAT = '%Y-%m-%d'

class eiru_account_statement_cancel(models.Model):
    _inherit = 'account.bank.statement'

    @api.model
    def eiru_get_bank_statement_cancel(self, id):
        return [{
            'id': statement.id,
            'name': statement.name,
            'state': statement.state,
            'date': statement.date,
            'currencystatement': {
                'id': statement.currency.id,
                'symbol': statement.currency.symbol,
                'rate': statement.currency.rate,
                'thousandsSeparator': statement.currency.thousands_separator,
                'decimalSeparator': statement.currency.decimal_separator,
                'decimalPlaces': statement.currency.decimal_places,
                'position': statement.currency.position,
            },
            'user': {
                'id': statement.user_id.id,
                'name': statement.user_id.name
            },
            'statementTransfer': [{
                'id': transfer.id,
                'name': transfer.name,
                'amount': transfer.amount,
                'ref': transfer.ref,
                'date': transfer.date,
                'outputStatement':{
                    'id': transfer.output_statement.id,
                    'name': transfer.output_statement.name,
                    'state': transfer.output_statement.state,
                    'statementUser': "%s/%s" % ((transfer.output_statement.name), (transfer.output_statement.user_id.name))
                },
                'inputStatement':{
                    'id': transfer.input_statement.id,
                    'name': transfer.input_statement.name,
                    'state': transfer.input_statement.state,
                    'statementUser': "%s/%s" % ((transfer.input_statement.name), (transfer.input_statement.user_id.name))
                },
                'outputLineId': transfer.output_line.id,
                'inputLineId': transfer.input_line.id,
                'type': 'in' if (transfer.input_statement.id == statement.id) else 'out'
            } for transfer in self.env['cash.box.transfer'].search(['|', ('output_statement.id','=',statement.id), ('input_statement.id','=',statement.id)])],
            'statementConfirm': [{
                'id': casBox.id,
                'name': casBox.name,
                'amountStatement': casBox.amount_statement,
                'amountReal': casBox.amount_real,
                'amountDifference': casBox.amount_difference,
                'amountNextOpen': casBox.amount_next_open,
                'type': 'open' if (casBox.statement_open.id == statement.id) else 'confirm',
                'statementConfirm':{
                    'id': casBox.statement_id.id if (casBox.statement_id) else '',
                    'name': casBox.statement_id.name if (casBox.statement_id) else '',
                    'state': casBox.statement_id.state if (casBox.statement_id) else '',
                    'statementUser': "%s/%s" % ((casBox.statement_id.name), (casBox.statement_id.user_id.name)) if (casBox.statement_id) else ''
                },
                'statementOpen':{
                    'id': casBox.statement_open.id if (casBox.statement_open) else '',
                    'name': casBox.statement_open.name if (casBox.statement_open) else '',
                    'state': casBox.statement_open.state if (casBox.statement_open) else '',
                    'statementUser': "%s/%s" % ((casBox.statement_open.name), (casBox.statement_open.user_id.name)) if (casBox.statement_open) else ''
                },
                'lineDifference': [{
                    'id':  lineDifference.id,
                    'date': lineDifference.date,
                    'name': lineDifference.name ,
                    'amount': lineDifference.amount,
                    'state': lineDifference.statement_id.state,
                    'type': 'balance'
                } for lineDifference in self.env['account.bank.statement.line'].browse(casBox.line_difference.id)],
                'lineNextOpen': [{
                    'id': lineNextOpen.id,
                    'date': lineNextOpen.date,
                    'name': lineNextOpen.name ,
                    'amount': lineNextOpen.amount,
                    'state': casBox.statement_open.state if (casBox.statement_open) else '',
                    'type': 'reserve'
                } for lineNextOpen in self.env['account.bank.statement.line'].browse(casBox.line_next_open.id)]
            } for casBox in self.env['cashbox.statement.confirm'].search([('statement_id.id','=',statement.id)])],
        } for statement in self.env['account.bank.statement'].search([('id','=',id)])]


    '''
          ____ _____  _  _____ _____ __  __ _____ _   _ _____    ____    _    _   _  ____ _____ _
         / ___|_   _|/ \|_   _| ____|  \/  | ____| \ | |_   _|  / ___|  / \  | \ | |/ ___| ____| |
         \___ \ | | / _ \ | | |  _| | |\/| |  _| |  \| | | |   | |     / _ \ |  \| | |   |  _| | |
          ___) || |/ ___ \| | | |___| |  | | |___| |\  | | |   | |___ / ___ \| |\  | |___| |___| |___
         |____/ |_/_/   \_\_| |_____|_|  |_|_____|_| \_| |_|    \____/_/   \_\_| \_|\____|_____|_____|
    '''
    '''
        Get Statement
    '''
    def _eiru_get_account_bank_statement(self, id):
        return self.env['account.bank.statement'].browse(id)

    '''
        Get Statement Line
    '''
    def _eiru_get_account_bank_statement_line(self, id):
        return self.env['account.bank.statement.line'].browse(id)

    '''
        Get CashBox statement Confirm
    '''
    def _eiru_account_get_cashbox_confirm(self, statementId):
        return self.env['cashbox.statement.confirm'].search([('statement_id', '=', statementId)])

    '''
        statement Cancel
    '''
    @api.model
    def eiru_statement_cancel(self, values):
        ### date server
        dateServer = self.get_server_datetime()
        ###  Statement
        statement = self._eiru_get_account_bank_statement(values['statementId'])
        if (not statement):
            return {
                'state': False,
                'messege': "Error en obtener el registro de caja ref(account.bank.statement)."
            }

        ### user
        users = self.env.user
        if (not users):
            return {
                'state': False,
                'messege':"Error en obtener el usuario. ref(res.users) "
            }

        # Creatre Line cancel
        line_ids = []
        for line in statement.line_ids:
            line_ids.append([0, False, {
                'statement_line': line.id,
                'date': line.date,
                'name': line.name,
                'ref': line.ref,
                'partner_id': line.partner_id.id,
                'amount': line.amount,
                'currency_id': line.currency_id.id
            }])

        # create cancel
        cancel = {
            'name': "Cancelación de caja "+str(statement.name),
            'ref': values['messege'],
            'date': dateServer,
            'message': values['messege'],
            'statement_id': statement.id,
            'journal_id': statement.journal_id.id,
            'user_statement': statement.user_id.id,
            'user_cancel': users.id,
            'line_ids': line_ids
        }
        statementCancel = self.env['cashbox.statement.cancel'].create(cancel)
        if (not statementCancel):
            return {
                'state': False,
                'messege': 'Error en el registro de cancelación de caja. ref(cashbox.statement.cancel /cashbox.statement.cancel.line).'
            }

        '''
            Confirm
        '''
        statementOpen = []
        stateOpen   = []
        lineDifference = []
        lineNextOpen = []
        lineOpen = []

        cashBoxConfirm = self._eiru_account_get_cashbox_confirm(statement.id)
        if (cashBoxConfirm):
            statementOpen = self._eiru_get_account_bank_statement(cashBoxConfirm.statement_open.id)
            if (statementOpen and statementOpen.state =='confirm' and cashBoxConfirm.statement_open.id != cashBoxConfirm.statement_id.id ):
                return {
                    'state': False,
                    'messege': "No se puede reabrir esta caja porque  tiene relación a una caja que ya esta cerrada."
                }

            stateOpen = statementOpen.state
            # Line Diferencia
            lineDifference = self._eiru_get_account_bank_statement_line(cashBoxConfirm.line_difference.id)
            # line Next Open
            lineNextOpen = self._eiru_get_account_bank_statement_line(cashBoxConfirm.line_next_open.id)
            # Line Open
            lineOpen = self._eiru_get_account_bank_statement_line(cashBoxConfirm.line_open.id)

        '''
            Cancel statement
        '''
        cancel = self.eiru_button_cancel(statement)
        if (not cancel):
            return {
                'state': False,
                'messege': "Error al cancelar la caja"
            }

        if (lineDifference):
            self._write_statement_line_transfer(lineDifference)
            self._unlink_statement_line_transfer(lineDifference)

        if (lineNextOpen):
            self._write_statement_line_transfer(lineNextOpen)
            self._unlink_statement_line_transfer(lineNextOpen)


        if (lineOpen):
            statementOpenCancel = self.eiru_button_cancel(statementOpen)
            if (not statementOpenCancel):
                return {
                    'state': False,
                    'messege': "Error al cancelar la caja"
                }

            self._write_statement_line_transfer(lineOpen)
            self._unlink_statement_line_transfer(lineOpen)

            if (stateOpen == 'open'):
                statementOpen.button_open()

        '''
            Update Confirm
        '''
        confirm = {
            'state_avaliable': True,
            'statement_open': '',
            'amount_real': 0.0,
            'amount_difference': 0.0,
            'amount_next_open': 0.0

        }
        confirmCasBox = self._writer_cashbox_statement_confirm(cashBoxConfirm,confirm)
        if (not confirmCasBox):
            return {
                'state': False,
                'messege': 'Error en actualizar cierre de caja ref(cashbox.statement.confirm)'
            }

        open = statement.button_open()
        if (not open):
            return {
                'state': False,
                'messege': 'Error en reabrir la caja  ref('+statement+')'
            }

        return {
            'state': True,
            'messege': 'Caja reabierta'
        }

    '''
        Cancelar Caja
    '''
    def eiru_button_cancel(self,statement):
        return super(eiru_account_statement_cancel, statement.with_context(cancel_from_statement=True)).button_cancel()


'''
    Histórico de Cajas Canceladas.
'''
class cashbox_statement_cancel(models.Model):
    _name = "cashbox.statement.cancel"

    ### fields Basic
    name = fields.Char('name')
    ref = fields.Char('Ref')
    date = fields.Date()
    message = fields.Text('Message Cancel')
    active = fields.Boolean('Active', default=True)
    message_deleted = fields.Text('Message Deleted')
    ### statement, journal, users
    statement_id = fields.Many2one('account.bank.statement', 'Bank Statement Cancel')
    journal_id = fields.Many2one('account.journal', 'Journal')
    user_statement = fields.Many2one('res.users', 'User Statement')
    user_cancel = fields.Many2one('res.users', 'Usaer Cancel')
    line_ids    = fields.One2many('cashbox.statement.cancel.line', 'cancel_id', 'Cancel Lines')

class cashbox_statement_cancel_line(models.Model):
    _name = "cashbox.statement.cancel.line"

    ### cashbox.statement.cancel
    cancel_id = fields.Many2one('cashbox.statement.cancel', 'Statement Cancel')
    statement_line = fields.Many2one('account.bank.statement.line', 'statement Line')
    date = fields.Date()
    name = fields.Char('name')
    ref = fields.Char('Ref')
    partner_id = fields.Many2one('res.partner', 'partner')
    amount = fields.Float('Amount Line', digits_compute=dp.get_precision('Account'))
    currency_id = fields.Many2one('res.currency', string="Currency", help="Moneda de la operación")