# -*- coding: utf-8 -*-

from datetime import datetime

from odoo import api, fields, models, _

from odoo.exceptions import UserError

from logging import getLogger
_logger = getLogger(__name__)

ls_estatus_conciliacion = [('borrador', 'Borrador'),
                           ('conciliado', 'Conciliado'),
                           ('devuelto', 'Devuelto')]

ls_estatus_cobros = [('activo', 'Activo'),
                     ('cerrado', 'Cerrado')]

ls_estatus_cobranza = [('activo', 'Activo'),
                       ('cerrado', 'Cerrado')]

ls_estatus_accion_cobros = [('activo', 'Activo'),
                            ('vencido', 'Vencido'),
                            ('cerrado', 'Cerrado')]


class SgtConciliacionPagos(models.Model):
    _name = 'sgt_conciliacion_pagos'
    _rec_name = 'numero_conciliacion'

    estatus = fields.Selection(ls_estatus_conciliacion, string='Estatus de Conciliación', default='borrador')
    numero_conciliacion = fields.Char(string='N° de Conciliación')
    partner_id = fields.Many2one('res.partner', 'Aportante')
    pagos_id = fields.Many2one('sgt_pagos', string='Pago Efectuado')
    movimiento_id = fields.Many2one(related='pagos_id.movimiento_id')
    observacion = fields.Text(string='Observación')

    @api.multi
    def pago_conciliado(self):
        if self.observacion:
            if self.pagos_id.movimiento_id.concepto_movimiento_id.codigo == '100':
                self.pagos_id.movimiento_id.pagado = True
                self.env['sgt_pagos'].search([('id', '=', self.pagos_id.id)]).write({'estatus': 'conciliado'})
                self.env['sgt_movimientos'].search([('declaracion_id', '=', self.pagos_id.movimiento_id.declaracion_id.id), ('tipo_movimiento', '=', 'credito'), ('estatus', '!=', 'pagado')]).write({'estatus': 'pagado'})
                self.estatus = 'conciliado'
            elif self.pagos_id.movimiento_id.concepto_movimiento_id.codigo == '200':
                self.pagos_id.movimiento_id.pagado = True
                self.env['sgt_pagos'].search([('id', '=', self.pagos_id.id)]).write({'estatus': 'conciliado'})
                self.env['sgt_movimientos'].search([('movimiento_id', '=', self.pagos_id.movimiento_id.id), ('tipo_movimiento', '=', 'credito'), ('estatus', '!=', 'pagado')]).write({'estatus': 'pagado'})
                self.estatus = 'conciliado'
            elif self.pagos_id.movimiento_id.concepto_movimiento_id.codigo == '300':
                self.pagos_id.movimiento_id.pagado = True
                self.env['sgt_pagos'].search([('id', '=', self.pagos_id.id)]).write({'estatus': 'conciliado'})
                self.env['sgt_movimientos'].search([('movimiento_id', '=', self.pagos_id.movimiento_id.id), ('tipo_movimiento', '=', 'credito'), ('estatus', '!=', 'pagado')]).write({'estatus': 'pagado'})
                self.estatus = 'conciliado'
            elif self.pagos_id.movimiento_id.concepto_movimiento_id.codigo == '310':
                self.pagos_id.movimiento_id.pagado = True
                self.env['sgt_pagos'].search([('id', '=', self.pagos_id.id)]).write({'estatus': 'conciliado'})
                self.env['sgt_movimientos'].search([('pago_id', '=', self.pagos_id.id), ('tipo_movimiento', '=', 'credito'), ('estatus', '!=', 'pagado')]).write({'estatus': 'pagado'})
                self.estatus = 'conciliado'
        else:
            raise UserError(_('El Campo de Observación se encuentra Vacío.'))

    @api.multi
    def devolver_pago(self):
        if self.observacion and self.partner_id.email:
            template = self.env.ref('kyb_sgt_cobranzas.mail_template_devolucion_pago_sgt')
            if template:
                template.with_context(dbname=self._cr.dbname).send_mail(self.id, force_send=True)
                self.pagos_id.estatus = 'Cancelado'
                self.estatus = 'devuelto'
            else:
                raise UserError(_('Template no definido.'))
        else:
            raise UserError(_('El Campo de observaciones se encuentra Vacío.'))

    @api.model
    def create(self, values):
        values.update({'numero_conciliacion': self.env['ir.sequence'].next_by_code('sgt_conciliacion_pagos')})
        return super(SgtConciliacionPagos, self).create(values)


class SgtCobrosAcciones(models.Model):
    _name = 'sgt_cobros_acciones'
    _rec_name = 'codigo'
    _inherit = ['mail.thread', 'ir.needaction_mixin']

    partner_id = fields.Many2one('res.partner', string='Contribuyente')
    cuenta_id = fields.Many2one('sgt_cuentas', string='Cuenta')
    codigo = fields.Char(string='Código', size=20, help='Código del Cobro')
    comentarios = fields.Text(string='Comentarios', help='Comentarios de la Acción')
    fecha_promesa_pago = fields.Date(string='Fecha de Promesa de Pago', help='Fecha de Promesa de Pago ')
    monto_prometido = fields.Float(string='Monto Prometido', help='Monto que el cliente se comprometió a pagar en la fecha prometida', digits=(12, 2))
    in_wizard = fields.Boolean(default=False)
    state = fields.Selection(ls_estatus_accion_cobros, string='Estatus', default='activo')
    vencido = fields.Boolean(default=False)
    saldo_inicial = fields.Float('Saldo Deudor Inicial', readonly=True, help='Saldo del Deudor del Cliente a la Fecha de esta Acción de Cobro', digits=(12, 2))
    fecha_vencimiento = fields.Datetime('Fecha de Vencimiento', readonly=True, help='Fecha de vencimiento de la promesa de pago')
    saldo_deudor_vencimiento = fields.Float('Saldo Deudor a la Fecha de Vencimiento', readonly=True, digits=(12, 2))
    fecha_cerrado = fields.Datetime('Fecha de Cierre', readonly=True)
    saldo_deudor_cerrado = fields.Float('Saldo Deudor', readonly=True, digits=(12, 2))
    saldo_favor_cerrado = fields.Float('Saldo a favor', readonly=True, digits=(12, 2))
    saldo_deudor_cuenta = fields.Float(string='Saldo Deudor', compute='establecer_saldo', store=True, digits=(12, 2))

    @api.onchange('partner_id')
    def _onchange_limpiar_partner_id(self):
        self.cuenta_id = ''

    def _cron_validar_fecha(self):
        acciones_vencidas = self.env['sgt_cobros_acciones'].search([('fecha_promesa_pago', '<=', datetime.now()), ('state', '=', 'activo')])
        for ids in acciones_vencidas:
            ids.write({'vencido': True})
            ids.write({'state': 'vencido'})
            ids.write({'fecha_vencimiento': datetime.now()})
            ids.write({'saldo_deudor_vencimiento': ids.cuenta_id.saldo_deudor})

    @api.model
    def create(self, values):
        contribuyente = self.env['sgt_cuentas'].browse(values['cuenta_id'])
        values.update({'saldo_inicial': contribuyente.saldo_deudor})
        values.update({'codigo': self.env['ir.sequence'].next_by_code('sgt_cobros_acciones')})
        return super(SgtCobrosAcciones, self).create(values)

    @api.multi
    @api.depends('cuenta_id')
    def establecer_saldo(self):
        for accion in self:
            accion.saldo_deudor_cuenta = accion.cuenta_id.saldo_deudor

    @api.multi
    def accion_cerrada(self):
        if (self.state == 'activo' or self.state == 'vencido'):
            self.fecha_cerrado = datetime.now()
            if self.saldo_deudor_cuenta > 0:
                self.saldo_deudor_cerrado = self.saldo_deudor_cuenta
            else:
                self.saldo_favor_cerrado = self.saldo_deudor_cuenta
            self.state = 'cerrado'


class SgtCarteraCobranzas(models.Model):
    _name = 'sgt_cartera_cobranza'
    _rec_name = 'codigo'

    codigo = fields.Char('Código')
    estatus = fields.Selection(ls_estatus_cobranza, 'Estatus')
    fecha_cerrado = fields.Datetime('Fecha de Cerrar Cartera')
    descripcion = fields.Char('Descripción')
    generado = fields.Boolean('Generada')
    tipo_morosidades = fields.Many2one('sgt_tipos_morosidades', 'Tipos de Morosidades')
    cuenta_ids = fields.Many2many('sgt_cuentas', 'aportant_cartera_rel', 'cartera_id', 'cuenta_id', string='Aportantes')

    @api.multi
    def generar_cartera(self):
        declaraciones = self.env['sgt_declaraciones'].search([('id', '>', 0)])
        cuentas = self.env['sgt_cuentas'].search([('id', '>', 0)])
        if self.tipo_morosidades.codigo == '01':
            for declaracion in declaraciones:
                    for cuenta in cuentas:
                        if cuenta.partner_id.id == declaracion.partner_id.id:
                            pass
                        else:
                            self.cuenta_ids = [(4, cuenta.id, None)]
            self.estatus = 'activo'
            self.generado = True
        elif self.tipo_morosidades.codigo == '02':
            for cuenta in cuentas:
                if cuenta.saldo_deudor < 0:
                    self.cuenta_ids = [(4, cuenta.id, None)]
                else:
                    pass
            self.estatus = 'activo'
            self.generado = True
        elif self.tipo_morosidades.codigo == '03':
            for cuenta in cuentas:
                if cuenta.credito_fiscal > 0:
                    self.cuenta_ids = [(4, cuenta.id, None)]
                else:
                    pass
            self.estatus = 'activo'
            self.generado = True

    @api.multi
    def cerrar_cartera(self):
            self.fecha_cerrado = datetime.now()
            self.estatus = 'cerrado'

    @api.model
    def create(self, values):
        values.update({'codigo': self.env['ir.sequence'].next_by_code('sgt_cartera_cobranza')})
        return super(SgtCarteraCobranzas, self).create(values)


class SgtTiposMorosidades(models.Model):
    _name = 'sgt_tipos_morosidades'

    codigo = fields.Char('Código', size=2)
    descripcion = fields.Char('Descripción')

    @api.multi
    @api.depends('codigo', 'descripcion')
    def name_get(self):
        result = []
        for registro in self:
            name = str(registro.codigo) + ' ' + str(registro.descripcion)
            result.append((registro.id, name))
        return result
