# -*- coding: utf-8 -*-
########################################################################################################################
#  Adaptacion de MERPLUS para nos nuevos formato NCF 
#  See LICENSE file for full copyright and licensing details.
#
# Odoo Proprietary License v1.0
#
# This software and associated files (the "Software") may only be used
# (nobody can redistribute (or sell) your module once they have bought it, unless you gave them your consent)
# if you have purchased a valid license
# from the authors, typically via Odoo Apps, or if you have received a written
# agreement from the authors of the Software (see the COPYRIGHT file).
#
# You may develop Odoo modules that use the Software as a library (typically
# by depending on it, importing it and using its resources), but without copying
# any source code or material from the Software. You may distribute those
# modules under the license of your choice, provided that this license is
# compatible with the terms of the Odoo Proprietary License (For example:
# LGPL, MIT, or proprietary licenses similar to this one).
#
# It is forbidden to publish, distribute, sublicense, or sell copies of the Software
# or modified copies of the Software.
#
# The above copyright notice and this permission notice must be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
########################################################################################################################
from odoo import models, fields, api, exceptions
import calendar
import base64
import time
import re
from datetime import datetime

class DgiiCancelReport(models.Model):
    _name = "dgii.cancel.report.plus"

    def get_default_period(self):
        self.year = int(time.strftime("%Y"))

    company_id = fields.Many2one('res.company', string='Company', required=True,
                                 default=lambda self: self.env['res.company']._company_default_get(
                                     'dgii.cancel.report'))
    name = fields.Char(u"Descripción")
    year = fields.Integer(u"Año", size=4, default=lambda s: int(time.strftime("%Y")))
    month = fields.Integer("Mes", size=2, default=lambda s: int(time.strftime("%m")))
    CANTIDAD_REGISTRO = fields.Integer(u"Cantidad de registros")
    report_lines = fields.One2many("dgii.cancel.report.line.plus", "cancel_report_id")
    txt = fields.Binary("Reporte TXT", readonly=True)
    txt_name = fields.Char("Nombre", readonly=True)
    state = fields.Selection([('draft', 'Nuevo'), ('done', 'Generado')], default="draft")

    @api.model
    def create(self, vals):
        vals.update({"name": "{}/{}".format(vals["month"], vals["year"])})
        self = super(DgiiCancelReport, self).create(vals)
        self.create_report()
        return self

    def get_date_range(self):
        if self.month > 12 or self.month < 1:
            self.month = False
            raise exceptions.ValidationError("El mes es invalido!")
        last_day = calendar.monthrange(self.year, self.month)[1]
        return ("{}-{}-{}".format(str(self.year), str(self.month).zfill(2), "01"),
                "{}-{}-{}".format(str(self.year), str(self.month).zfill(2), str(last_day).zfill(2)))

    def create_report_lines(self, invoices):
        if self._context.get("recreate", False):
            self.report_lines.unlink()
            self.txt = False
        lines = []
        line_number = 1
        for inv in invoices:
            line = []

            LINE = line_number
            NUMERO_COMPROBANTE_FISCAL = inv.reference
            FECHA_COMPROBANTE = inv.date_invoice
            TIPO_ANULACION = inv.anulation_type

            lines.append((0, False, {"LINE": LINE,
                                     "NUMERO_COMPROBANTE_FISCAL": NUMERO_COMPROBANTE_FISCAL,
                                     "FECHA_COMPROBANTE": FECHA_COMPROBANTE,
                                     "TIPO_ANULACION": TIPO_ANULACION
                                     }))

            line_number += 1

        CANTIDAD_REGISTRO = len(lines)

        res = self.write({"report_lines": lines,
                          "CANTIDAD_REGISTRO": CANTIDAD_REGISTRO,
                          "state": "done"})

        return res

    def generate_txt(self):

        company_fiscal_identificacion = re.sub("[^0-9]", "", self.company_id.vat)

        path = '/tmp/608{}.txt'.format(company_fiscal_identificacion)
        file = open(path, 'w')
        lines = []

        header = "608" + "|"
        header += company_fiscal_identificacion + "|"
        header += str(self.year)
        header += str(self.month).zfill(2) + "|"
        header += str(self.CANTIDAD_REGISTRO)
        lines.append(header)

        for line in self.report_lines:
            fecha_comprobante_str = datetime.strftime(line.FECHA_COMPROBANTE, '%Y%m%d')
            ln = ""
            ln += line.NUMERO_COMPROBANTE_FISCAL + "|"
            ln += fecha_comprobante_str + "|"
            ln += "{}".format(line.TIPO_ANULACION).zfill(2)
            lines.append(ln)

        for line in lines:
            file.write(line + "\n")

        file.close()
        file = open(path, 'rb')
        report = base64.b64encode(file.read())
        report_name = 'DGII_608_{}_{}{}.TXT'.format(company_fiscal_identificacion, str(self.year),
                                                    str(self.month).zfill(2))
        self.write({'txt': report, 'txt_name': report_name})

    @api.multi
    def create_report(self):
        start_date, end_date = self.get_date_range()
        invoices = self.env["account.invoice"].search([('date_invoice', '>=', start_date),
                                                       ('date_invoice', '<=', end_date),
                                                       ('state', '=', 'cancel'),
                                                       ('journal_id.ncf_control','=',True),
                                                       ('type', 'in', ('out_invoice', 'out_refund'))])

        self.create_report_lines(invoices)
        self.generate_txt()
        return True


class DgiiCancelReportline(models.Model):
    _name = "dgii.cancel.report.line.plus"

    cancel_report_id = fields.Many2one("dgii.cancel.report.plus")
    LINE = fields.Integer("Linea")
    NUMERO_COMPROBANTE_FISCAL = fields.Char("NCF", size=19)
    FECHA_COMPROBANTE = fields.Date("Fecha")
    TIPO_ANULACION = fields.Char(u"Tipo de anulación", size=2)
