# -*- coding: utf-8 -*- import requests import logging from odoo import models, fields, api, _ from datetime import datetime, timedelta _logger = logging.getLogger(__name__) HEADERS = { 'X-API-KEY': 'b84f2c33-d9dc-439a-84ff-3deed4b18e10', 'Content-Type': 'application/json', } STATES = ['Active', 'Cancelled'] class ExelyModifiedData(models.Model): _name = 'exely.modified.bookings' _description = 'Exely Modified Bookings' _rec_name = 'booking_number' mod_period_start = fields.Datetime(string="Start Date") mod_period_end = fields.Datetime(string="End Date") booking_number = fields.Char(string="Booking Number") status = fields.Char(string="Status") class ExelyEmail(models.Model): _name = 'exely.email' _description = 'Exely Email' _rec_name = 'email' email = fields.Char(string="Email") class ExelyPhones(models.Model): _name = 'exely.phones' _description = 'Exely Phones' _rec_name = 'phone' phone = fields.Char(string="Phone") class ExelyCustomer(models.Model): _name = 'exely.customer' _description = 'Exely Customer' _rec_name = 'bid' bid = fields.Char(string="Customer ID", index=True) lastName = fields.Char(string="Last Name") firstName = fields.Char(string="First Name") middleName = fields.Char(string="Middle Name") birthDate = fields.Char(string="Birth Date") citizenshipCode = fields.Char(string="Citizenship Code") status = fields.Json(string="Status") emails = fields.Many2many(comodel_name="exely.email", string="Emails") phones = fields.Many2many(comodel_name="exely.phones", string="Phones") gender = fields.Char(string="Gender") class ExelyGuests(models.Model): _name = 'exely.guests' _description = 'Exely Guests' _rec_name = 'bid' bid = fields.Char(string="Guest ID", index=True) class ExelyAmenities(models.Model): _name = 'exely.amenities' _description = 'Exely Amenities' _rec_name = 'name' name = fields.Char(string="Name") class ExelyRoomStays(models.Model): _name = 'exely.roomstays' _description = 'Exely RoomStays' _rec_name = 'bid' bid = fields.Char(string="Room ID", index=True) bookingId = fields.Char(string="Booking ID", index=True) roomId = fields.Char(string="Room ID") roomTypeId = fields.Char(string="Room Type ID") guestsIds = fields.Many2many(comodel_name="exely.guests", string="Guests Ids") checkInDateTime = fields.Char(string="Check In Date Time") checkOutDateTime = fields.Char(string="Check Out Date Time") actualCheckInDateTime = fields.Char(string="Actual Check In Date Time") actualCheckOutDateTime = fields.Char(string="Actual Check Out Date Time") status = fields.Char(string="Status") bookingStatus = fields.Char(string="Booking Status") guestCountInfo = fields.Json(string="Guest Count Info") totalPrice = fields.Json(string="Total Price") amenities = fields.Many2many(comodel_name="exely.amenities", string="Amenities") bookings_id = fields.Many2one(comodel_name="exely.bookings", string="Room Stay Id") class ExcelyBookings(models.Model): _name = 'exely.bookings' _description = 'Exely Bookings' _rec_name = 'bid' bid = fields.Char(string="Booking ID", index=True) number = fields.Char(string="Booking Number", index=True) customerLanguage = fields.Char(string="Customer Language") visitPurpose = fields.Json(string="Visit Purpose") customerComment = fields.Char(string="Customer Comment") lastModified = fields.Char(string="Last Modified") currencyId = fields.Char(string="Currency ID") customer = fields.Many2one(comodel_name="exely.customer", string="Customer") roomStays = fields.One2many(comodel_name="exely.roomstays", inverse_name="bookings_id", string="RoomStays") customerCompany = fields.Json(string="Customer Company") source = fields.Json(string="RoomStays") sourceChannelName = fields.Char(string="Source Channel Name") def json_data_store_visit(self): self.visitPurpose = { 'id': self.id, 'key': self.number, 'value': self.number, } def generate_date_ranges(self, start_date, end_date): date_ranges = [] current_date = start_date while current_date < end_date: period_start = current_date period_end = min(current_date + timedelta(days=29), end_date) if period_end.date() < end_date.date(): period_end = period_end.replace(hour=23, minute=59) else: period_end = end_date date_ranges.append(( period_start.strftime("%Y-%m-%dT%H:%M"), period_end.strftime("%Y-%m-%dT%H:%M") )) current_date = period_end + timedelta(days=1) return date_ranges def get_exely_data(self): start_date = datetime(2024, 1, 1) end_date = datetime.now() date_ranges = self.generate_date_ranges(start_date, end_date) to_create = [] for status in STATES: for start, end in date_ranges: print(f"{start} to {end}") url = f"https://connect.hopenapi.com/api/exelypms/v1/bookings?modifiedFrom={start}&modifiedTo={end}&state={status}" # try: response = requests.get(url, headers=HEADERS) if response.status_code == 200: data = response.json() for booking_number in data['bookingNumbers']: start_write = datetime.strptime(start, "%Y-%m-%dT%H:%M") - timedelta(hours=4) end_write = datetime.strptime(end, "%Y-%m-%dT%H:%M") - timedelta(hours=4) found_modified_booking = self.env['exely.modified.bookings'].search([ ('mod_period_start', '=', start_write), ('mod_period_end', '=', end_write), ('booking_number', '=', booking_number), ('status', '=', status)] ) if not found_modified_booking: self.env['exely.modified.bookings'].create({ 'mod_period_start': start_write, 'mod_period_end': end_write, 'booking_number': booking_number, 'status': status }) url = f"https://connect.hopenapi.com/api/exelypms/v1/bookings/{booking_number}" response = requests.get(url, headers=HEADERS) if response.status_code == 200: data = response.json() data['bid'] = data.pop('id') customer = data.pop('customer', None) if customer: customer['bid'] = customer.pop('id') emails = customer.get('emails', None) phones = customer.get('phones', None) if emails: email_ids = [] for email in emails: found_email = self.env['exely.email'].search([('email', '=', email)]) if found_email: email_id = found_email.id else: email_id = self.env['exely.email'].create({'email': email}).id email_ids.append(email_id) if email_ids: customer['emails'] = [(6, 0, email_ids)] if phones: phone_ids = [] for phone in phones: found_phone = self.env['exely.phones'].search([('phone', '=', phone)]) if found_phone: phone_id = found_phone.id else: phone_id = self.env['exely.phones'].create({'phone': phone}).id phone_ids.append(phone_id) if phone_ids: customer['phones'] = [(6, 0, phone_ids)] found_customer = self.env['exely.customer'].search([('bid', '=', customer['bid'])]) if found_customer: customer_id = found_customer.id else: customer_id = self.env['exely.customer'].create(customer).id data['customer'] = customer_id roomstays = data.pop('roomStays', None) if roomstays: roomstays_ids = [] for roomstay in roomstays: roomstay['bid'] = roomstay.pop('id') guests = roomstay.pop('guestsIds', None) if guests: guest_ids = [] for guest in guests: found_guest = self.env['exely.guests'].search([('bid', '=', guest)]) if found_guest: guest_id = found_guest.id else: guest_id = self.env['exely.guests'].create({'bid': guest}).id guest_ids.append(guest_id) if guest_ids: roomstay['guestsIds'] = [(6, 0, guest_ids)] amenities = roomstay.pop('amenities', None) if not amenities: amenity_ids = [] for amenity in amenities: found_amenity = self.env['exely.amenities'].search([('name', '=', amenity)]) if found_amenity: amenity_id = found_amenity.id else: amenity_id = self.env['exely.amenities'].create({'name': amenity}).id amenity_ids.append(amenity_id) if amenity_ids: roomstay['amenities'] = [(6, 0, amenity_ids)] found_roomstay = self.env['exely.roomstays'].search([('bid', '=', roomstay['bid'])]) if found_roomstay: roomstay_id = found_roomstay.id else: roomstay_id = self.env['exely.roomstays'].create(roomstay).id roomstays_ids.append(roomstay_id) if roomstays_ids: data['roomStays'] = [(6, 0, roomstays_ids)] print(data) to_create.append(data) else: _logger.warning(f"Failed to retrieve data. Status code: {response.status_code}") # except Exception as e: # _logger.warning(f"Error processing data: {e}") if to_create: for i in to_create: try: self.env['exely.bookings'].create(i) except Exception as e: _logger.warning(f"##############################: {i}") break # if to_create: # self.env['exely.bookings'].create(to_create)