hms_bak/exely_integration/models/exely_raw_data.py
2024-10-29 14:44:52 +04:00

493 lines
23 KiB
Python

# -*- coding: utf-8 -*-
import requests
import logging
import hashlib
import json
from odoo import models, fields, api, _
from datetime import datetime, timedelta
from odoo.exceptions import UserError
_logger = logging.getLogger(__name__)
STATES = ['Active', 'Cancelled']
class ExelyRawBookings(models.Model):
_name = 'exely.raw.bookings'
_description = 'Exely Raw Bookings'
json_data = fields.Json(string="Json Data")
json_hash_code = fields.Char(string="Hash Code")
bid = fields.Char(string="Booking Id")
parent_id = fields.Many2one('exely.raw.bookings', string="Parent Record")
history_ids = fields.One2many(comodel_name="exely.raw.bookings", inverse_name='parent_id', string="History")
modified_booking_id = fields.Many2one(comodel_name="exely.modified.bookings", string="Modified Bookings Id")
class ExelyRawCompanies(models.Model):
_name = 'exely.raw.companies'
_description = 'Exely Raw Companies'
json_data = fields.Json(string="Json Data")
json_hash_code = fields.Char(string="Hash Code")
bid = fields.Char(string="Company Id")
parent_id = fields.Many2one('exely.raw.companies', string="Parent Record")
history_ids = fields.One2many(comodel_name="exely.raw.companies", inverse_name='parent_id', string="History")
class ExelyRawRooms(models.Model):
_name = 'exely.raw.rooms'
_description = 'Exely Raw Rooms'
json_data = fields.Json(string="Json Data")
json_hash_code = fields.Char(string="Hash Code")
bid = fields.Char(string="Room Id")
parent_id = fields.Many2one('exely.raw.rooms', string="Parent Record")
history_ids = fields.One2many(comodel_name="exely.raw.rooms", inverse_name='parent_id', string="History")
class ExelyRawCustomers(models.Model):
_name = 'exely.raw.customers'
_description = 'Exely Raw Customers'
json_data = fields.Json(string="Json Data")
json_hash_code = fields.Char(string="Hash Code")
bid = fields.Char(string="Customer Id")
parent_id = fields.Many2one('exely.raw.customers', string="Parent Record")
history_ids = fields.One2many(comodel_name="exely.raw.customers", inverse_name='parent_id', string="History")
class ExelyRawRoomstays(models.Model):
_name = 'exely.raw.roomstays'
_description = 'Exely Raw Roomstays'
json_data = fields.Json(string="Json Data")
json_hash_code = fields.Char(string="Hash Code")
bid = fields.Char(string="Roomstays Id")
parent_id = fields.Many2one('exely.raw.roomstays', string="Parent Record")
history_ids = fields.One2many(comodel_name="exely.raw.roomstays", inverse_name='parent_id', string="History")
class ExelyRawGuests(models.Model):
_name = 'exely.raw.guests'
_description = 'Exely Raw Guests'
json_data = fields.Json(string="Json Data")
json_hash_code = fields.Char(string="Hash Code")
bid = fields.Char(string="Guest Id")
parent_id = fields.Many2one('exely.raw.guests', string="Parent Record")
history_ids = fields.One2many(comodel_name="exely.raw.guests", inverse_name='parent_id', string="History")
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")
def generate_date_ranges(self, start_date, end_date):
date_ranges = []
current_date = start_date
while current_date < end_date:
period_start = current_date.replace(hour=0, minute=0, second=0, microsecond=0)
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_api(self, url, headers):
response = requests.get(url, headers=headers)
if response.status_code == 200:
data = response.json()
return data
else:
return False
def create_or_update_raw_data(self, data, model, bid):
json_data = json.dumps(data, sort_keys=True)
hash_object = hashlib.sha256(json_data.encode())
hash_hex = hash_object.hexdigest()
found_raw_record = self.env[model].search([
('bid', '=', bid),
])
if found_raw_record:
if found_raw_record.json_hash_code != hash_hex:
# found_raw_record.write({
# 'json_data': json_data,
# 'json_hash_code': hash_hex
# })
new_created_record = self.env[model].create({
'json_data': json_data,
'json_hash_code': hash_hex,
'bid': bid,
})
found_raw_record.parent_id = new_created_record.id
else:
found_raw_record = self.env[model].create({
'json_data': json_data,
'json_hash_code': hash_hex,
'bid': bid
})
def get_exely_data(self):
exely_api_conf = self.env['exely.api.conf'].search([], limit=1)
if exely_api_conf:
headers = {
'X-API-KEY': exely_api_conf.api_key,
'Content-Type': 'application/json',
}
else:
raise UserError(_("Please configure Exely API Key"))
companies = self.get_exely_data_api("https://connect.hopenapi.com/api/exelypms/v1/companies", headers)
if companies:
for company in companies:
self.create_or_update_raw_data(company, 'exely.raw.companies', company['id'])
rooms = self.get_exely_data_api("https://connect.hopenapi.com/api/exelypms/v1/rooms", headers)
if rooms:
for room in rooms:
self.create_or_update_raw_data(room, 'exely.raw.rooms', room['id'])
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}")
data = self.get_exely_data_api(f"https://connect.hopenapi.com/api/exelypms/v1/bookings?modifiedFrom={start}&modifiedTo={end}&state={status}", headers)
if data:
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)
modified_booking_id = self.env['exely.modified.bookings'].search([
('mod_period_start', '=', start_write),
('mod_period_end', '=', end_write),
('booking_number', '=', booking_number),
('status', '=', status)]
)
if not modified_booking_id:
modified_booking_id = self.env['exely.modified.bookings'].create({
'mod_period_start': start_write,
'mod_period_end': end_write,
'booking_number': booking_number,
'status': status
})
booking = self.get_exely_data_api(f"https://connect.hopenapi.com/api/exelypms/v1/bookings/{booking_number}", headers)
if booking:
self.create_or_update_raw_data(booking, 'exely.raw.bookings', booking['id'])
customer = booking['customer']
self.create_or_update_raw_data(customer, 'exely.raw.customers', customer['id'])
roomstays = booking['roomStays']
for roomstay in roomstays:
self.create_or_update_raw_data(roomstay, 'exely.raw.roomstays', roomstay['id'])
guests = roomstay['guestsIds']
for bid in guests:
guest = self.get_exely_data_api(f"https://connect.hopenapi.com/api/exelypms/v1/guests/{bid}", headers)
self.create_or_update_raw_data(guest, 'exely.raw.guests', bid)
break
def process_exely_data(self):
found_booking_record = self.env['exely.bookings'].search([], order="write_date desc", limit=1)
if found_booking_record:
max_date = found_booking_record.write_date
else:
max_date = datetime.strptime('1970-01-01', "%Y-%m-%d").date()
to_process_modified_bookings = self.env['exely.raw.bookings'].search([('write_date', '>', max_date), ('parent_id', '=', False)])
to_create = []
for modified in to_process_modified_bookings:
data = json.loads(modified.json_data)
data['bid'] = data.pop('id')
customer = data.pop('customer', None)
if customer:
customer['bid'] = customer.pop('id')
if customer.get('emails', None):
customer['emails'] = [(6, 0, [
self.env['exely.email'].search([('email', '=', email)], limit=1).id or
self.env['exely.email'].create({'email': email}).id
for email in customer['emails']
])]
if customer.get('phones', None):
customer['phones'] = [(6, 0, [
self.env['exely.phones'].search([('phone', '=', phone)], limit=1).id or
self.env['exely.phones'].create({'phone': phone}).id
for phone in customer['phones']
])]
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')
if roomstay.get('roomId', None):
roomstay['roomId'] = self.env['exely.rooms'].search([('bid', '=', roomstay['roomId'])]).id
guests = roomstay.pop('guestsIds', None)
if guests:
guest_ids = []
for guest in guests:
guest_data = json.loads(self.env['exely.raw.guests'].search([('bid', '=', guest)]).json_data)
guest_data['bid'] = guest_data.pop('id')
if guest_data:
if guest_data.get('emails', None):
guest_data['emails'] = [(6, 0, [
self.env['exely.email'].search([('email', '=', email)], limit=1).id or
self.env['exely.email'].create({'email': email}).id
for email in guest_data['emails']
])]
if guest_data.get('phones', None):
guest_data['phones'] = [(6, 0, [
self.env['exely.phones'].search([('phone', '=', phone)], limit=1).id or
self.env['exely.phones'].create({'phone': phone}).id
for phone in guest_data['phones']
])]
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(guest_data).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)]
to_create.append(data)
if to_create:
for i in to_create:
try:
self.env['exely.bookings'].create(i)
except Exception as e:
_logger.warning(f"##############################: {i}")
# DIRECTLY FROM EXELY
# def process_exely_data(self):
# self.sync_room_numbers()
# 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}")
# data = self.get_modified_bookings(start, end, status)
# if data:
# 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
# })
# data = self.get_booking_info(booking_number)
# if data:
# data['bid'] = data.pop('id')
# customer = data.pop('customer', None)
# if customer:
# customer['bid'] = customer.pop('id')
# if customer.get('emails', None):
# customer['emails'] = [(6, 0, [
# self.env['exely.email'].search([('email', '=', email)], limit=1).id or
# self.env['exely.email'].create({'email': email}).id
# for email in customer['emails']
# ])]
# if customer.get('phones', None):
# customer['phones'] = [(6, 0, [
# self.env['exely.phones'].search([('phone', '=', phone)], limit=1).id or
# self.env['exely.phones'].create({'phone': phone}).id
# for phone in customer['phones']
# ])]
# 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')
# if roomstay.get('roomId', None):
# roomstay['roomId'] = self.env['exely.rooms'].search([('bid', '=', roomstay['roomId'])]).id
# guests = roomstay.pop('guestsIds', None)
# if guests:
# guest_ids = []
# for guest in guests:
# guest_data = self.get_guest_info(guest)
# guest_data['bid'] = guest_data.pop('id')
# if guest_data:
# if guest_data.get('emails', None):
# guest_data['emails'] = [(6, 0, [
# self.env['exely.email'].search([('email', '=', email)], limit=1).id or
# self.env['exely.email'].create({'email': email}).id
# for email in guest_data['emails']
# ])]
# if guest_data.get('phones', None):
# guest_data['phones'] = [(6, 0, [
# self.env['exely.phones'].search([('phone', '=', phone)], limit=1).id or
# self.env['exely.phones'].create({'phone': phone}).id
# for phone in guest_data['phones']
# ])]
# 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(guest_data).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)]
# 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
# cr.commit()
# if to_create:
# self.env['exely.bookings'].create(to_create)
class ExcelyBookings(models.Model):
_inherit = 'exely.bookings'
_description = 'Exely Bookings'
_rec_name = 'bid'