# -*- coding: utf-8 -*-
###############################################################################
#
#    Tech-Receptives Solutions Pvt. Ltd.
#    Copyright (C) 2009-TODAY Tech-Receptives(<http://www.techreceptives.com>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Lesser General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Lesser General Public License for more details.
#
#    You should have received a copy of the GNU Lesser General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################

from odoo.osv import expression
from odoo.tools.float_utils import float_round as round
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
from odoo.exceptions import UserError, ValidationError
from odoo import api, fields, models, _
import time
import datetime

class ProductTemplate(models.Model):
    _inherit = "product.template"

    @api.multi
    def _compute_currency_id(self):
        try:
            main_company = self.sudo().env.ref('base.main_company')
        except ValueError:
            main_company = self.env['res.company'].sudo().search([], limit=1, order="id")
        for template in self:
            if template.enterprise_id.ebusiness_id.sudo().currency_id:
                template.currency_id = template.enterprise_id.ebusiness_id.sudo().currency_id
            else:
                template.currency_id = template.company_id.sudo().currency_id.id or main_company.currency_id.id

    enterprise_id = fields.Many2one('etourism.enterprise', string='Enterprise')
    name = fields.Char('Name', index=True, required=True, translate=False)
    tourist_tax = fields.Boolean(
        'Type tourist tax', default=False,
        help="Specify if the product is a tourist tax.")
    is_room = fields.Boolean('Is Room', default=False)

    @api.model
    def default_get(self, fields):
        res = super(ProductTemplate, self).default_get(fields)
        enterprise_id = self.env['res.users'].browse([self.env.uid])[0].enterprise_id
        if enterprise_id:
            res.update({'enterprise_id': enterprise_id.id})
        return res

class ProductProduct(models.Model):
    _inherit = "product.product"

    isroom = fields.Boolean('Is Room')
    isroom_available = fields.Boolean('Is Room Available?', default=False)
    iscategid = fields.Boolean('Is categ id')
    isservice = fields.Boolean('Is Service id')

    @api.model
    def default_get(self, fields):
        res = super(ProductProduct, self).default_get(fields)
        enterprise_id = self.env['res.users'].browse([self.env.uid])[0].enterprise_id
        if enterprise_id:
            res.update({'enterprise_id': enterprise_id.id})
        return res

class EtourismRoom(models.Model):
    _name = 'etourism.room'
    _inherits = {'product.product': 'product_id'}
    _inherit = ['ir.needaction_mixin', 'mail.thread']
    _description = "Rooms"

    enterprise_id = fields.Many2one('etourism.enterprise', 'Enterprise')
    product_id = fields.Many2one(
        'product.product', 'Product', required=True, ondelete="cascade", track_visibility='onchange')
    #Amenities
    amenities_ids = fields.Many2many('etourism.amenities', string='Amenities')

    status = fields.Selection([('Available', 'Available'),
                              ('Unvailable', 'Unavailable'),
                              ], 'Status', default='Available', track_visibility='onchange')
    images = fields.One2many('etourism.room.image', 'room_id',
                             string='Images')
    room_booking_line_ids = fields.One2many('etourism.booking','room_id',string='Room Reserve Line')
    has_default_enterprise = fields.Boolean('Has Default Enterprise', help="True, if User creating Booking group has related Enterprise.")
    room_type_id = fields.Many2one(related="product_id.product_tmpl_id.categ_id", string='Room Type', store=True)
    start_date = fields.Date(string='Start date unavailability', track_visibility='onchange')
    end_date = fields.Date(string='End date unavailability', track_visibility='onchange')
    reason_unavailability = fields.Char(string='Reason for unavailability', track_visibility='onchange')
    #JCF - 29-04-2018
    room_max_capacity = fields.Integer(string='Max capacity', compute="_compute_max_capacity")
    availability = fields.Selection([('occupied', 'Occupied'),
                              ('unoccupied', 'Unoccupied'),
                              ],string='Availability', compute="_compute_availability", search='_search_availability')

    @api.one
    def _compute_availability(self):
        available,room_id,room_type_id,enterprise_id = 0, False, False, False
        for room in self:
            room_id = room.id
            room_type_id = room.room_type_id.id
            enterprise_id = room.enterprise_id.id
            if room_id and room_type_id and enterprise_id:
                self._cr.execute("""select room_current_availability(%s,%s,%s) as counter"""%(room_id, room_type_id, enterprise_id))
                result = self._cr.fetchone()
                if result:
                    available = result[0]
                if available > 0:
                    room.availability = 'unoccupied'
                else:
                    room.availability = 'occupied'

    @api.one
    def _compute_max_capacity(self):
        max_occupancy,room_id,room_type_id,enterprise_id = 0, False, False, False
        for room in self:
            room_id = room.id
            room_type_id = room.room_type_id.id
            enterprise_id = room.enterprise_id.id
            if room_id and room_type_id and enterprise_id:
                self._cr.execute("""select i.max_occupancy from product_pricelist p, product_pricelist_item i
where p.id=i.pricelist_id and p.enterprise_id=%s and i.categ_id=%s and now() between p.start_date and p.end_date order by i.max_occupancy desc limit 1"""%(enterprise_id,room_type_id))
                result = self._cr.fetchone()
                if result:
                    max_occupancy = result[0]
            room.room_max_capacity = max_occupancy

    def _search_availability(self, operator, value):
        res = []
        if value=='occupied':
            self._cr.execute("""select * from (select id, room_current_availability(id,room_type_id,enterprise_id) as counter from etourism_room) v where v.counter=0""")
            result = self._cr.fetchall()
            for rlt in result:
                res.append(rlt[0])
        elif value=='unoccupied':
            self._cr.execute("""select * from (select id, room_current_availability(id,room_type_id,enterprise_id) as counter from etourism_room) v where v.counter>0""")
            result = self._cr.fetchall()
            for rlt in result:
                res.append(rlt[0])
        return [('id', '=', res)]

    @api.constrains('start_date', 'end_date')
    def check_start_end_dates(self):
        """
        Unavailability end date should be greater than start date.
        """
        if self.start_date and self.end_date:
            start_date = datetime.datetime.strptime(self.start_date, '%Y-%m-%d').date()
            end_date = datetime.datetime.strptime(self.end_date, '%Y-%m-%d').date()
            if self.end_date < self.start_date:
                raise ValidationError(_('Unavailability end date should be equal or greater than start date.'))

    @api.model
    def name_search(self, name, args=None, operator='ilike', limit=100):        
        """ This function filters Rooms on Etoursim Booking Lines based on Enterprise, Checkin & Checkout
        """
        context = self._context or {}
        if context and 'filter_enterprise_id' in context and 'filter_checkin' in context and 'filter_checkout' in context:
            rooms = []

            if context['filter_enterprise_id']:
                enterprise_id = context['filter_enterprise_id']
                checkin_date=context['filter_checkin']
                checkout_date=context['filter_checkout']
                self._cr.execute("""select v.id from (select r.id,rooms_availability('%s', '%s', r.id) as availability 
                                from etourism_room r 
                                where r.enterprise_id=%s) v where v.availability > 0;"""%(checkin_date, checkout_date, enterprise_id)
                            )

                result = self._cr.fetchall()
                if result:
                    for res in result:
                        rooms.append(res[0])

                #print "ROOMS #1:::::::::::::::::::::::::::::::::::::::"
                #print rooms
                stop_all_sales = False
                rooms_to_remove,room_type_stop_sales = [],[]
                self._cr.execute("""select room_type_id from etourism_stop_sales 
                                where enterprise_id=%s and '%s' between start_date and end_date"""%(enterprise_id,checkin_date)
                            )

                result = self._cr.fetchall()
                if result:
                    for res in result:
                        if not res[0]:
                            stop_all_sales = True
                        else:
                            self._cr.execute("""select id from etourism_room 
                                where enterprise_id=%s and room_type_id=%s"""%(enterprise_id,res[0])
                            )
                            result2 = self._cr.fetchall()
                            for res2 in result2:
                                rooms_to_remove.append(res2[0])

                #print "ROOMS TO REMOVE:::::::::::::::::::::::::::::::::::::::"
                #print rooms_to_remove

                counter = 0
                if rooms_to_remove:
                    while counter < len(rooms_to_remove):
                        #print "COUNTER:::::::::::::::::::::::::::",counter
                        rooms = [x for x in rooms if x != rooms_to_remove[counter]]
                        counter += 1
                #print "STOP SALES:::::::::::::::::::::::::::::::::::::::"
                #print stop_all_sales

                #print "ROOMS #2:::::::::::::::::::::::::::::::::::::::"
                #print rooms

                if stop_all_sales:
                    rooms = []

            #print "CONTEXT:::::::::::::::::::::::"
            #print context
            if 'filter_booking_id' in context:
                if context['filter_booking_id']:
                    booking_id=context['filter_booking_id']
                    if isinstance(booking_id, int):
                        booking = self.env['etourism.booking'].search([('id', '=', booking_id)], limit=1)
                        if booking:
                            room_id = booking.room_id.id
                            rooms.append(room_id)
            args += ([('id','in', rooms)])
        return super(EtourismRoom, self).name_search(name, args, operator=operator, limit=limit)

    @api.model
    def search(self, args, offset=0, limit=None, order=None, count=False):
        """ This function filters Rooms on Etoursim Booking Lines based on Enterprise, Checkin & Checkout
        """
        #print "SEARCH ROOMS:::::::::::::::::::::::::::::::::::"
        context = self._context or {}

        if context and 'filter_enterprise_id' in context and 'filter_checkin' in context and 'filter_checkout' in context:
            rooms = []
            #print "ENTROU NO IF:::::::::::::::::::::::::::::::::::"

            if context['filter_enterprise_id']:
                enterprise_id = context['filter_enterprise_id']
                checkin_date=context['filter_checkin']
                checkout_date=context['filter_checkout']
                self._cr.execute("""select v.id from (select r.id,rooms_availability('%s', '%s', r.id) as availability 
                                from etourism_room r 
                                where r.enterprise_id=%s) v where v.availability > 0;"""%(checkin_date, checkout_date, enterprise_id)
                            )

                result = self._cr.fetchall()
                if result:
                    for res in result:
                        rooms.append(res[0])
                #print "SEARCH ROOMS:::::::::::::::::::::::::::::::"
                #print rooms
                stop_all_sales = False
                rooms_to_remove,room_type_stop_sales = [],[]
                self._cr.execute("""select room_type_id from etourism_stop_sales 
                                where enterprise_id=%s and '%s' between start_date and end_date"""%(enterprise_id,checkin_date)
                            )

                result = self._cr.fetchall()
                if result:
                    for res in result:
                        if not res[0]:
                            stop_all_sales = True
                        else:
                            room_type_stop_sales.append(res[0])
                            self._cr.execute("""select id from etourism_room 
                                where enterprise_id=%s and room_type_id=%s"""%(enterprise_id,res[0])
                            )
                            result2 = self._cr.fetchall()
                            for res2 in result2:
                                rooms_to_remove.append(res2[0])

                counter = 0
                if rooms_to_remove:
                    while counter < len(rooms_to_remove):
                        rooms = [x for x in rooms if x != rooms_to_remove[counter]]
                        counter += 1

                if stop_all_sales:
                    rooms = []
                    
            if 'filter_booking_id' in context:
                if context['filter_booking_id']:
                    booking_id=context['filter_booking_id']
                    if isinstance(booking_id, int):
                        booking = self.env['etourism.booking'].search([('id', '=', booking_id)], limit=1)
                        if booking:
                            room_id = booking.room_id.id
                            rooms.append(room_id)
            args += ([('id','in', rooms)])
        return super(EtourismRoom, self).search(args, offset, limit, order, count=count)

    @api.model
    def default_get(self, fields):
        res = super(EtourismRoom, self).default_get(fields)
        if self.env.uid:
            enterprise_id = self.env['res.users'].browse([self.env.uid])[0].enterprise_id
            if enterprise_id:
                res.update({'enterprise_id': enterprise_id.id, 'has_default_enterprise': True,'isroom': True, 'is_room': True,'isroom_available':True,'available_in_pos':False})
            else:
                res.update({'isroom': True, 'is_room': True,'isroom_available':True,'available_in_pos':False})
        return res

    @api.model
    def create(self, vals):
        #print "########################### CREATE ROOM ###########################"
        var_product_id=False
        var_enterprise_id=False
        if not vals:
            vals = {}
        if self._context is None:
            self._context = {}
        vals['isroom'] = True
        vals['is_room'] = True
        vals['isroom_available'] = True
        res=super(EtourismRoom, self).create(vals)
        if res.product_id and res.enterprise_id:
            var_product_id = res.product_id.id
            var_enterprise_id = res.enterprise_id.id

            room_product = self.env['product.product'].search([('id', '=', var_product_id)], limit=1)
            if room_product:
                product_tmpl_id=room_product.product_tmpl_id.id
                self._cr.execute("""UPDATE product_template SET enterprise_id=%s,website_published=true WHERE id=%s"""%(var_enterprise_id,product_tmpl_id))

        return res

    @api.multi
    def write(self, vals):
        """
        Overrides orm write method.
        @param self: The object pointer
        @param vals: dictionary of fields value.
        update Hotel Room history"""
        count=0
        var_product_id=False
        var_enterprise_id=False
        for room in self:
            if 'enterprise_id' in vals:
                var_enterprise_id = vals['enterprise_id']
            else:
                var_enterprise_id = self.enterprise_id.id

            if 'product_id' in vals:
                var_product_id = vals['product_id']
            else:
                var_product_id = self.product_id.id

            if var_product_id:
                room_product = self.env['product.product'].search([('id', '=', var_product_id)], limit=1)
                if room_product:
                    product_tmpl_id=room_product.product_tmpl_id.id
                    self._cr.execute("""UPDATE product_template SET enterprise_id=%s,website_published=true  WHERE id=%s"""%(var_enterprise_id,product_tmpl_id))

        return super(EtourismRoom, self).write(vals)

    @api.multi
    def action_update_rooms_availability(self):
        from_dt = datetime.date.today()
        rooms = []
        self._cr.execute("""SELECT id FROM etourism_room WHERE end_date < '%s'"""%(from_dt))
        result = self._cr.fetchall()
        for res in result:
            rooms.append(res[0])
        if rooms:
            room_selected = self.env['etourism.room'].search([('id', 'in', rooms)])
            for rm in room_selected:
                rm.write({'start_date': None,'end_date': None,'status': 'Available','reason_unavailability': ''})
                #print "UPDATE ROOMS AVAILABILITY:::::::::::::::::::::::::::::::::::::::: ", rm.id

class EtourismRoomType(models.Model):
    _inherit = 'product.category'
    _description = "Room Types"

    isroomtype = fields.Boolean(string='Is room type?',default=False)
    isservicetype = fields.Boolean(string='Is service type?',default=False)
    num_adults = fields.Integer(string='Number of adults')
    num_children = fields.Integer(string='Number of children')
    num_rooms = fields.Integer(string='Number of rooms')
    is_standard = fields.Boolean(string='Is Standard?',default=False)
    #enterprise_id = fields.Many2one('etourism.enterprise', 'Enterprise')

    @api.model
    def name_search(self, name, args=None, operator='ilike', limit=80):
        """ This function filters subjects list on Student List - by course wizard 
        to show subjects from Inscriptions related to selected Course and/or Academic Year 
        and/or Course Year. (works on drop down option)
        """
        context = self._context or {}
        user = context.get('uid', False)
        imd = self.env['ir.model.data']
        hotel_access_groups = ['ecom.group_ecom_hotel', 'ecom.group_ecom_hotel_own_pms','etourism.group_etourism_directory_tms_operator']
        allowed_group_ids = []
        if self.user_has_groups('ecom.group_ecom_back_office_admin'):
            if context and 'product_category_pos_filter' in context and context['product_category_pos_filter'] is True:
                is_room = context['is_room']
                #print "IS ROOM:::::::::::::::::::::::::::::::"
                #print is_room
                categories_not_rooms = []
                if is_room is False:
                    query = """select id from product_category where isroomtype=false"""
                else:
                    query = """select id from product_category where isroomtype=true"""
                self._cr.execute(query)
                result = self._cr.fetchall()
                for res in result:
                    res = list(res)
                    categories_not_rooms.append(res[0])
                args += [('id', 'in', categories_not_rooms)]

        for group in hotel_access_groups:
            group_id = imd.xmlid_to_res_id(group)
            if group_id:
                allowed_group_ids.append(group_id)
        user_groups = []
        groups = [user_groups.append(group.id) for group in self.env['res.users'].browse(user).groups_id]
        university_center_id = False
        for user_group in user_groups:
            if user_group in allowed_group_ids:

                """ Below section is to filter room types on pricelists based on enterprise selected:
                """
                if context and 'product_category_filter_by_enterprise' in context and context['product_category_filter_by_enterprise'] is True:
                    enterprise_id = context['enterprise_id']
                    if enterprise_id:
                        room_types = []
                        query = """select room_type_id from etourism_room where enterprise_id=%s"""%(enterprise_id)
                        self._cr.execute(query)
                        result = self._cr.fetchall()
                    
                        for res in result:
                            res = list(res)
                            room_types.append(res[0])
                        args += [('id', 'in', room_types)]

                if context and 'product_category_pos_filter' in context and context['product_category_pos_filter'] is True:
                    is_room = context['is_room']
                    #print "IS ROOM:::::::::::::::::::::::::::::::"
                    #print is_room
                    categories_not_rooms = []
                    if is_room is False:
                        query = """select id from product_category where isroomtype=false"""
                    else:
                        query = """select id from product_category where isroomtype=true"""
                    self._cr.execute(query)
                    result = self._cr.fetchall()
                    for res in result:
                        res = list(res)
                        categories_not_rooms.append(res[0])
                    args += [('id', 'in', categories_not_rooms)]

        return super(EtourismRoomType, self).name_search(name, args, operator, limit)

class EtourismRoomImage(models.Model):
    _name = 'etourism.room.image'
    _order = 'sequence, id DESC'

    name = fields.Char('Name')
    description = fields.Text('Description')
    sequence = fields.Integer('Sequence')
    image_alt = fields.Text('Image Label')
    image = fields.Binary('Image')
    image_small = fields.Binary('Small Image')
    room_id = fields.Many2one('etourism.room', 'Room', index=True)
    from_main_image = fields.Boolean('From Main Image', default=False)
	
class EtourismViewRooms(models.Model):
    _name = 'etourism.view.rooms'
    _description = "Rooms"

    name = fields.Char(string='Name',required=True)
    room_type = fields.Char(string='Room Type',required=True)
    room_type_id = fields.Integer(string='Room Type ID',required=True)

    @api.multi
    def action_load_rooms(self):
        """Load rooms
        """
        room_ids = self.env['etourism.view.rooms'].search([('id','>',4199)])
        room_number = 1
        categ_id = False
        enterprise_id = False
        for room in room_ids:
            enterprise_name=room.name
            room_type_name=room.room_type
            enterprise_ids = self.env['etourism.enterprise'].search([('name','=',enterprise_name),('type_id','=',111)],limit=1)
            categ_ids = self.env['product.category'].search([('name','=',room_type_name)],limit=1)
            if enterprise_ids:
                for ent in enterprise_ids:
                    enterprise_id=ent.id
                    room_name=enterprise_name + ' ' + str(room_number)
            if categ_ids:
                for cat in categ_ids:
                    categ_id=cat.id
            self.env['etourism.room'].create({
                'name': room_name,
                'enterprise_id': enterprise_id,
                'categ_id': categ_id,
                'status': 'Available',
                    })
            room_number = room_number +1

		
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
