# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

import time
import datetime
from dateutil.relativedelta import relativedelta
import math

from odoo.osv import expression
from odoo.tools.float_utils import float_round as round
from odoo.tools import float_is_zero, float_compare, DEFAULT_SERVER_DATETIME_FORMAT
from odoo.exceptions import UserError, ValidationError
from odoo import api, fields, models, _
from odoo.tools.misc import formatLang
import json

import urlparse
import uuid

from datetime import date

class EtourismBookingInvoice(models.TransientModel):
    _name = 'etourism.booking.invoice.wizard'
    _description = 'Open Booking Invoice Wizard'

    @api.model
    def default_get(self, fields):
        context = self.env.context
        res = super(EtourismBookingInvoice, self).default_get(fields)
        booking_line = self.env['etourism.booking'].browse(context.get('active_ids'))
        lines,partner_id = [],False
        for folio in booking_line.folio_line:
            #temp = [lines.append(line.id) for line in folio.room_lines if line.status in ('not_invoiced')]
            for line in folio.room_lines:
                print "STATUS::::::::",line.status
                if line.status == 'not_invoiced':
                    lines.append(line.id)			
                    partner_id=line.folio_id.partner_id.id
        res.update(folio_line_ids=[[6,0, lines]],partner_id=partner_id)
        return res

    booking_id = fields.Many2one('etourism.booking', string='Booking')
    folio_id = fields.Many2one('etourism.enterprise.folio', string='Folio')
    partner_id = fields.Many2one('res.partner', string='Customer')
    folio_line_ids = fields.Many2many('etourism.enterprise.folio.line', 'booking_folio_lines')

    @api.multi
    def action_invoice(self, grouped=False, final=False):
        for booking in self:
            booking_id=booking.booking_id
            booking_group_id=booking_id.booking_group_id.id
            folio_id=booking.folio_id
            partner_id=booking.partner_id
            inv_obj = self.env['account.invoice']
            booking_group_obj = self.env['etourism.booking.group']
            precision = self.env['decimal.precision'].precision_get('Product Unit of Measure')
            invoices = {}
            references = {}
            folio_lines = []
            enterprise_id=booking.booking_id.booking_group_id.enterprise_id.id
            if booking.folio_line_ids:
                group_key = folio_id.id if grouped else (partner_id.id, folio_id.currency_id.id)
                for line in booking.folio_line_ids:
                    line_obj = self.env['sale.order.line'].browse([line.order_line_id.id])
                    if float_is_zero(line.product_uom_qty, precision_digits=precision):
                        continue
                    if group_key not in invoices:
                        inv_data = folio_id.order_id._prepare_invoice()
                        inv_data.update({'enterprise_id':enterprise_id,'booking_group_id':booking_group_id,'booking_id':booking_id.id,'partner_id':partner_id.id,'partner_shipping_id':partner_id.id})
                        invoice = inv_obj.create(inv_data)
                        references[invoice] = folio_id
                        invoices[group_key] = invoice
                    elif group_key in invoices:
                        vals = {}
                        if folio_id.name not in invoices[group_key].origin.split(', '):
                            vals['origin'] = invoices[group_key].origin + ', ' + folio_id.name
                        if folio_id.client_order_ref and folio_id.client_order_ref not in invoices[group_key].name.split(', '):
                            vals['name'] = invoices[group_key].name + ', ' + folio_id.client_order_ref
                        invoices[group_key].write(vals)
                    if line.product_uom_qty > 0:
                        line_obj.invoice_line_create(invoices[group_key].id, line.product_uom_qty)
                    elif line.product_uom_qty < 0 and final:
                        line_obj.invoice_line_create(invoices[group_key].id, line.product_uom_qty)

                    folio_lines.append(line.id)
                if references.get(invoices.get(group_key)):
                    if folio_id not in references[invoices[group_key]]:
                        references[invoice] = references[invoice] | folio_id

            if not invoices:
                raise UserError(_('There is no invoicable line.'))

            for invoice in invoices.values():
                if not invoice.invoice_line_ids:
                    raise UserError(_('There is no invoicable line.'))
                # If invoice is negative, do a refund invoice instead
                if invoice.amount_untaxed < 0:
                    invoice.type = 'out_refund'
                    for line in invoice.invoice_line_ids:
                        line.quantity = -line.quantity
                # Use additional field helper function (for account extensions)
                for line in invoice.invoice_line_ids:
                    line._set_additional_fields(invoice)
                # Necessary to force computation of taxes. In account_invoice, they are triggered
                # by onchanges, which are not triggered when doing a create.
                invoice.compute_taxes()
                invoice.message_post_with_view('mail.message_origin_link',values={'self': invoice, 'origin': references[invoice]},subtype_id=self.env.ref('mail.mt_note').id)

            f_lines = self.env['etourism.enterprise.folio.line'].search([('id','in',folio_lines)])
            for f_line in f_lines:
                print "STATUS::::::::::::::::::",f_line.status
                f_line.write(({'status': 'invoiced'}))

            if folio_id.state in ('draft','sent'):
                print "IF FOLIO::::::::::::::::::"
                folio_id.action_confirm()
        #raise UserError(_('Test.'))
        print "AFTER IF FOLIO::::::::::::::::::"

        return [inv.id for inv in invoices.values()]


class EtourismBookingGroupInvoice(models.TransientModel):
    _name = 'etourism.booking.group.invoice.wizard'
    _description = 'Open Booking Group Invoice Wizard'

    @api.model
    def default_get(self, fields):
        context = self.env.context
        res = super(EtourismBookingGroupInvoice, self).default_get(fields)
        booking_group = self.env['etourism.booking.group'].browse(context.get('active_ids'))
        lines,partner_id = [],False
        for folio in booking_group.folio_line:
            for line in folio.room_lines:
                if line.status == 'not_invoiced':
                    lines.append(line.id)			
                    partner_id=line.folio_id.booking_group_id.guest_id.id

        res.update(folio_line_ids=[[6,0, lines]],partner_id=partner_id)
        return res

    booking_group_id = fields.Many2one('etourism.booking.group', string='Booking Group')
    folio_line_ids = fields.Many2many('etourism.enterprise.folio.line', 'booking_group_folio_lines')
    partner_id = fields.Many2one('res.partner', string='Customer')

    @api.multi
    def action_invoice(self, grouped=False, final=False):
        for booking_group in self:
            booking_group_id=booking_group.booking_group_id
            partner_id=booking_group.partner_id
            inv_obj = self.env['account.invoice']
            booking_group_obj = self.env['etourism.booking.group']
            precision = self.env['decimal.precision'].precision_get('Product Unit of Measure')
            invoices = {}
            references = {}
            folio_lines,folios = [],[]
            enterprise_id=booking_group_id.enterprise_id.id
            if booking_group.folio_line_ids:
                group_key = booking_group_id.id if grouped else (booking_group_id.guest_id.id, booking_group_id.enterprise_id.ebusiness_id.currency_id.id)
                for line in booking_group.folio_line_ids:
                    line_obj = self.env['sale.order.line'].browse([line.order_line_id.id])
                    if float_is_zero(line.product_uom_qty, precision_digits=precision):
                        continue
                    if group_key not in invoices:
                        inv_data = line.folio_id.order_id._prepare_invoice()
                        inv_data.update({'enterprise_id':enterprise_id,'booking_group_id':booking_group_id.id,'booking_id':line.folio_id.booking_id.id,'partner_id':partner_id.id,'partner_shipping_id':partner_id.id})
                        invoice = inv_obj.create(inv_data)
                        print "INVOICE CREATED::::::::::::::::::::"
                        references[invoice] = line.folio_id
                        invoices[group_key] = invoice
                    elif group_key in invoices:
                        vals = {}
                        if line.folio_id.name not in invoices[group_key].origin.split(', '):
                            vals['origin'] = invoices[group_key].origin + ', ' + line.folio_id.name
                        if line.folio_id.client_order_ref and line.folio_id.client_order_ref not in invoices[group_key].name.split(', '):
                            vals['name'] = invoices[group_key].name + ', ' + line.folio_id.client_order_ref
                        invoices[group_key].write(vals)
                        print "INVOICE UPDATED::::::::::::::::::::"
                    if line.product_uom_qty > 0:
                        line_obj.invoice_line_create(invoices[group_key].id, line.product_uom_qty)
                        print "LINE CREATED #1::::::::::::::::::::"
                    elif line.product_uom_qty < 0 and final:
                        line_obj.invoice_line_create(invoices[group_key].id, line.product_uom_qty)
                        print "LINE CREATED #2::::::::::::::::::::"

                    folio_lines.append(line.id)
                    folios.append(line.folio_id.id)
                folios = list(set(folios))
                counter = 0
                while counter < len(folios):
                    print "COUNTER:::::::::::::::::::::::::::",counter
                    fl_obj = self.env['etourism.enterprise.folio'].browse([folios[counter]])
                    if references.get(invoices.get(group_key)):
                        if fl_obj not in references[invoices[group_key]]:
                            references[invoice] = references[invoice] | fl_obj
                    counter += 1


            if not invoices:
                raise UserError(_('There is no invoicable line.'))

            for invoice in invoices.values():
                if not invoice.invoice_line_ids:
                    raise UserError(_('There is no invoicable line.'))
                # If invoice is negative, do a refund invoice instead
                if invoice.amount_untaxed < 0:
                    invoice.type = 'out_refund'
                    for line in invoice.invoice_line_ids:
                        line.quantity = -line.quantity
                # Use additional field helper function (for account extensions)
                for line in invoice.invoice_line_ids:
                    line._set_additional_fields(invoice)
                # Necessary to force computation of taxes. In account_invoice, they are triggered
                # by onchanges, which are not triggered when doing a create.
                invoice.compute_taxes()
                invoice.message_post_with_view('mail.message_origin_link',values={'self': invoice, 'origin': references[invoice]},subtype_id=self.env.ref('mail.mt_note').id)

            f_lines = self.env['etourism.enterprise.folio.line'].search([('id','in',folio_lines)])
            for f_line in f_lines:
                f_line.write(({'status': 'invoiced'}))
            print "FOLIOS::::::::::::::::::::::::::"
            print folios
            folios_obj = self.env['etourism.enterprise.folio'].search([('id','in',folios)])
            for fl in folios_obj:
                print "FOR FOLIOS::::::::::::::::::::::::::",fl.id
                print fl.state
                if fl.state in ('draft','sent'):
                    fl.action_confirm()
                    print "FOLIO CONFIRMED::::::::::::::::::::"


        #raise UserError(_('Test.'))

        return [inv.id for inv in invoices.values()]
