# -*- coding: utf-8 -*- import requests import logging import json from odoo import models, fields, api, _ from datetime import datetime, timedelta _logger = logging.getLogger(__name__) STATES = ['Active', 'Cancelled'] class HmsEmail(models.Model): _name = 'hms.email' _description = 'Hms Email' _rec_name = 'email' email = fields.Char(string="Email") class HmsPhones(models.Model): _name = 'hms.phones' _description = 'Hms Phones' _rec_name = 'phone' phone = fields.Char(string="Phone") class HmsCustomer(models.Model): _name = 'hms.customer' _description = 'Hms 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="hms.email", string="Emails") phones = fields.Many2many(comodel_name="hms.phones", string="Phones") gender = fields.Char(string="Gender") customerIndex = fields.Integer(string="customerIndex", index=True) name = fields.Char(string="Name") customerKind = fields.Selection([('0', 'Company'), ('1', 'individual')], string="CustomerType") inn = fields.Char(string="Tax ID") kpp = fields.Char(string="Tax Registration Reason Code") legalAddress = fields.Char(string="Legal Address") mailingAddress = fields.Char(string="Mailing Address") @api.depends('firstName', 'lastName') def _compute_display_name(self): for customer in self: customer.display_name = f"{customer.firstName} {customer.lastName}" if customer.firstName and customer.lastName else "" class HmsRooms(models.Model): _name = 'hms.rooms' _description = 'Hms Rooms' _rec_name = 'name' bid = fields.Char(string="Room ID", index=True) name = fields.Char(string="Name") roomTypeId = fields.Many2one(comodel_name="hms.room.types", string="Room Type") floorId = fields.Many2one(comodel_name="hms.floors", string="Floor") class HmsRoomTypes(models.Model): _name = 'hms.room.types' _description = 'Hms Room Types' _rec_name = 'name' bid = fields.Char(string="Room Type ID", index=True) name = fields.Char(string="Name") class HmsFloors(models.Model): _name = 'hms.floors' _description = 'Hms Floors' _rec_name = 'name' bid = fields.Char(string="Floor ID", index=True) name = fields.Char(string="Name") class HmsGuests(models.Model): _name = 'hms.guests' _description = 'Hms Guests' _rec_name = 'bid' bid = fields.Char(string="Guest 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="hms.email", string="Emails") phones = fields.Many2many(comodel_name="hms.phones", string="Phones") gender = fields.Char(string="Gender") class HmsAmenities(models.Model): _name = 'hms.amenities' _description = 'Hms Amenities' _rec_name = 'name' name = fields.Char(string="Name") class HmsRoomStays(models.Model): _name = 'hms.roomstays' _description = 'Hms RoomStays' _rec_name = 'bid' bid = fields.Char(string="Room raw ID", index=True) bookingId = fields.Char(string="Booking ID", index=True) roomId = fields.Many2one(comodel_name="hms.rooms", string="Room ID") roomTypeId = fields.Many2one(comodel_name="hms.room.types", string="Room Type ID") guestsIds = fields.Many2many(comodel_name="hms.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.Many2one(comodel_name="hms.status", string="Status") bookingStatus = fields.Many2one(comodel_name="hms.booking.status", string="Booking Status") guestCountInfo = fields.Json(string="Guest Count Info") totalPrice = fields.Json(string="Total Price") amenities = fields.Many2many(comodel_name="hms.amenities", string="Amenities") bookings_id = fields.Many2one(comodel_name="hms.bookings", string="Room Stay Id") class HmsSourceChannel(models.Model): _name = 'hms.source.channel' _description = 'Hms Source Channel' _rec_name = 'name' name = fields.Char(string="Name") class HmsBookings(models.Model): _name = 'hms.bookings' _description = 'Hms 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") groupName = fields.Char(string="Group Name") currencyId = fields.Char(string="Currency ID") customer = fields.Many2one(comodel_name="hms.customer", string="Customer") payment_ids = fields.One2many(comodel_name="hms.payments", inverse_name="booking_id", string="Booking Payments") roomStays = fields.One2many(comodel_name="hms.roomstays", inverse_name="bookings_id", string="RoomStays") reservation_ids = fields.One2many(comodel_name="hms.reservations", inverse_name="bookingNumber", string="Reservation Ids") customerCompany = fields.Json(string="Customer Company") source = fields.Json(string="RoomStays (Json)") sourceChannelName = fields.Many2one(comodel_name="hms.source.channel", string="Source Channel Name") checkin_date = fields.Datetime(string="Checkin Date", compute="_compute_checkin_checkout_date", store=True) checkout_date = fields.Datetime(string="Checkout Date", compute="_compute_checkin_checkout_date", store=True) booking_date = fields.Datetime(string="Booking Date", compute="_compute_checkin_checkout_date", store=True) night = fields.Integer(string="Night", compute="_compute_checkin_checkout_date", store=True) roomstays_count = fields.Integer(string="Roomstays Count", compute="_compute_checkin_checkout_date", store=True) total_amount = fields.Monetary(string="Total Amount", compute="_compute_checkin_checkout_date", currency_field='currency', store=True) paid = fields.Monetary(string="Paid Amount", compute="_compute_checkin_checkout_date", currency_field='currency', store=True) to_be_paid = fields.Monetary(string="To Pay Amount", compute="_compute_checkin_checkout_date", currency_field='currency', store=True) currency = fields.Many2one(comodel_name="res.currency", string="Currency") expected_payment = fields.Monetary(string="Expected Payment", compute="_compute_checkin_checkout_date", currency_field='currency', store=True) paymentMethod = fields.Many2one(comodel_name="hms.payment.methods", string="Payment Method", compute="_compute_checkin_checkout_date", store=True) payment_status = fields.Selection( [('completely_paid', 'Completely Paid'), ('partially_paid', 'Partially Paid'), ('not_paid', 'Not Paid')], string="Payment Status", compute="_compute_checkin_checkout_date", store=True) booking_status = fields.Many2one(comodel_name="hms.booking.status", string="Booking Status", compute="_compute_checkin_checkout_date", store=True) status = fields.Many2one(comodel_name="hms.status", string="Status", compute="_compute_checkin_checkout_date", store=True) booking_status_text = fields.Char(string="Booking Status ", compute="_compute_checkin_checkout_date", store=True) show_booking_status = fields.Boolean(string="Show Booking Status", compute="_compute_checkin_checkout_date", store=True) status_text = fields.Char(string="Status ", compute="_compute_checkin_checkout_date", store=True) show_status = fields.Boolean(string="Show Status", compute="_compute_checkin_checkout_date", store=True) @api.depends('roomStays', 'payment_ids') def _compute_checkin_checkout_date(self): for booking in self: # Status fields booking.show_booking_status = False booking.show_status = False if booking.roomStays.filtered(lambda stay: stay.bookingStatus.name == 'Confirmed'): booking.booking_status = self.env['hms.booking.status'].search([('name', '=', 'Confirmed')]).id booking.booking_status_text = f"Confirmed ({len(booking.roomStays.filtered(lambda stay: stay.bookingStatus.name == 'Confirmed'))} / {len(booking.roomStays)})" booking.show_booking_status = True elif not booking.roomStays.filtered(lambda stay: stay.bookingStatus.name != 'Cancelled'): booking.booking_status = self.env['hms.booking.status'].search([('name', '=', 'Cancelled')]).id elif not booking.roomStays.filtered(lambda stay: stay.bookingStatus.name != 'Pending'): booking.booking_status = self.env['hms.booking.status'].search([('name', '=', 'UpcoPendingming')]).id if not booking.roomStays.filtered(lambda stay: stay.status.name == 'CheckedIn') and not booking.roomStays.filtered(lambda stay: stay.status.name == 'CheckedOut') and booking.roomStays.filtered(lambda stay: stay.status.name == 'New'): booking.status = self.env['hms.status'].search([('name', '=', 'Upcoming')]).id elif booking.roomStays.filtered(lambda stay: stay.status.name == 'CheckedIn'): checked_in_records = self.env['hms.status'].search([('name', '=', 'CheckedIn')]) booking.status = checked_in_records.id booking.status_text = f"CheckedIn ({len(booking.roomStays.filtered(lambda stay: stay.status.name == 'CheckedIn'))} / {len(booking.roomStays)})" booking.show_status = True elif booking.roomStays.filtered(lambda stay: stay.status.name == 'CheckedOut'): checked_out_records = self.env['hms.status'].search([('name', '=', 'CheckedOut')]) booking.status = checked_out_records.id booking.status_text = f"CheckedOut ({len(booking.roomStays.filtered(lambda stay: stay.status.name == 'CheckedOut'))} / {len(booking.roomStays)})" booking.show_status = True elif not booking.roomStays.filtered(lambda stay: stay.status.name != 'Cancelled'): booking.status = self.env['hms.status'].search([('name', '=', 'Cancelled')]).id elif not booking.roomStays.filtered(lambda stay: stay.status.name != 'No Show'): booking.status = self.env['hms.status'].search([('name', '=', 'No Show')]).id # Computed fields checkin_dates = booking.roomStays.mapped('checkInDateTime') checkout_dates = booking.roomStays.mapped('checkOutDateTime') if checkin_dates: checkin_date = min(datetime.fromisoformat(date) for date in checkin_dates) - timedelta(hours=4) else: checkin_date = False if checkout_dates: checkout_date = max(datetime.fromisoformat(date) for date in checkout_dates) - timedelta(hours=4) else: checkout_date = False booking.checkin_date = checkin_date booking.checkout_date = checkout_date booking.booking_date = min(booking.reservation_ids.mapped('creationDateTime_date')) if booking.reservation_ids else False if checkin_date and checkout_date: booking.night = (checkout_date - checkin_date).days if checkout_date.time() > checkin_date.time() else (checkout_date - checkin_date).days + 1 booking.roomstays_count = len(booking.roomStays) booking.total_amount = sum(stay.totalPrice.get('amount', 0) for stay in booking.roomStays if stay.totalPrice) booking.paid = sum(booking.reservation_ids.mapped('paid')) if booking.reservation_ids else 0 booking.to_be_paid = sum(stay.totalPrice.get('toPayAmount', 0) for stay in booking.roomStays if stay.totalPrice) booking.currency = booking.reservation_ids[0].currency if booking.reservation_ids else False booking.paymentMethod = booking.reservation_ids[0].paymentMethod if booking.reservation_ids else False paid_amount = booking.compute_paid_amount() if booking.total_amount != 0: expected_payment = booking.total_amount - paid_amount booking.expected_payment = expected_payment if expected_payment <= 0: booking.payment_status = 'completely_paid' elif booking.total_amount > expected_payment: booking.payment_status = 'partially_paid' else: booking.payment_status = 'not_paid' else: booking.payment_status = 'not_paid' def compute_paid_amount(self): gel_currency_id = self.env['res.currency'].search([('name', '=', 'GEL')]) paid_amount = 0 if self.payment_ids: for payment in self.payment_ids: if self.currency.id == gel_currency_id.id: if payment.currency_id.id != gel_currency_id.id: paid_amount += payment.amount * payment.exchange_rate else: paid_amount += payment.amount else: if payment.currency_id.id == gel_currency_id.id: paid_amount += payment.amount / self.currency.rate_ids.sorted('id', reverse=True)[0].rate else: if self.currency.id == payment.currency_id.id: paid_amount += payment.amount else: paid_amount += payment.amount * gel_currency_id.rate_ids.sorted('id', reverse=True)[0].rate / self.currency.rate_ids.sorted('id', reverse=True)[0].rate return paid_amount # def add_bank_transactions(self): # return { # 'name': _('Add bank transactions'), # 'type': 'ir.actions.act_window', # 'view_mode': 'list', # 'res_model': 'brosse.bank.transactions', # 'view_id': self.env.ref('bross_bank_management.view_brosse_bank_transactions_operation_list').id, # 'target': 'new', # 'context': { # 'booking_id': self.id, # 'create': False, # 'edit': False # } # } def add_bank_transactions(self): gel_currency_id = self.env['res.currency'].search([('name', '=', 'GEL')]) wire_transfer_id = self.env.ref('bross_hms.payment_type_2').id expected_payment = self.total_amount paid_amount = self.compute_paid_amount() expected_payment = expected_payment - paid_amount return { 'name': _('Add Payments'), 'type': 'ir.actions.act_window', 'view_mode': 'form', 'res_model': 'add.payments.wizard', 'view_id': self.env.ref('bross_bank_management.add_payments_wizard_view_form').id, 'target': 'new', 'context': { 'default_payment_type': wire_transfer_id, 'default_booking_id': self.id, 'default_gel_currency_id': gel_currency_id.id, 'default_expected_payment': expected_payment, 'default_expected_payment_currency': self.currency.id, } } # @api.model # def _get_contextual_booking(self): # ctx = self.env.context # if self.env.context.get('booking_id') is not None: # return self.browse(ctx.get('booking_id')) # if self.env.context.get('default_booking_id') is not None: # return self.browse(ctx.get('default_booking_id')) # return False class HmsStatus(models.Model): _name = 'hms.status' _description = 'Hms Status' name = fields.Char(string="Status", required=True) # total_roomstays = fields.Integer(string="Total Roomstays", compute="_compute_roomstays") # checkedin_count = fields.Integer(string="CheckedIn", compute="_compute_roomstays") # checkedout_count = fields.Integer(string="CheckedOut", compute="_compute_roomstays") # def requested_display_name(self): # return self._context.get('status_display_name', True) and self._context.get('booking_id') # @api.depends_context('booking_id', 'default_booking_id') # def _compute_roomstays(self): # booking_id = self.env['hms.bookings']._get_contextual_booking() # if booking_id: # if booking_id.roomStays: # total_roomstays = len(booking_id.roomStays) # checkedin_count = len(booking_id.roomStays.filtered(lambda stay: stay.status.name == 'CheckedIn')) # checkedout_count = len(booking_id.roomStays.filtered(lambda stay: stay.status.name == 'CheckedOut')) # else: # total_roomstays = 0 # checkedin_count = 0 # checkedout_count = 0 # self.total_roomstays = total_roomstays # self.checkedin_count = checkedin_count # self.checkedout_count = checkedout_count # @api.depends('total_roomstays', 'checkedin_count', 'checkedin_count') # @api.depends_context('status_display_name', 'booking_id', 'default_booking_id') # def _compute_display_name(self): # if not self.requested_display_name(): # return super()._compute_display_name() # for record in self: # if record.name == 'CheckedIn': # name = _("%(name)s (%(time)g checkedin out of %(maximum)g days)", name=record.name, time=record.checkedin_count, maximum=record.total_roomstays) # elif record.name == 'CheckedOut': # name = _("%(name)s (%(time)g checkedout out of %(maximum)g days)", name=record.name, time=record.checkedout_count, maximum=record.total_roomstays) # record.display_name = name class HmsBookingStatus(models.Model): _name = 'hms.booking.status' _description = 'Hms Booking Status' name = fields.Char(string="Booking Status", required=True) class HmsAgents(models.Model): _name = 'hms.agents' _description = 'Hms Agents' _rec_name = 'name' index = fields.Integer(string="Index") bid = fields.Char(string="Agent ID", index=True) name = fields.Char(string="Name") inn = fields.Char(string="Tax ID") kpp = fields.Char(string="Tax Registration Reason Code") phone = fields.Many2one(comodel_name="hms.phones", string="Phone") email = fields.Many2one(comodel_name="hms.email", string="Email") legalAddress = fields.Char(string="Registered Address") mailingAddress = fields.Char(string="Postal Address") class HmsServiceKinds(models.Model): _name = 'hms.service.kinds' _description = 'Hms Service Kinds' _rec_name = 'name' name = fields.Char(string="Name") hms_id = fields.Integer(string="HMS ID") class HmsServiceVatKinds(models.Model): _name = 'hms.service.vat.kinds' _description = 'Hms Service Vat Kinds' _rec_name = 'name' name = fields.Char(string="Name") hms_id = fields.Integer(string="HMS ID") class HmsServices(models.Model): _name = 'hms.services' _description = 'Hms Services' _rec_name = 'bid' bid = fields.Char(string="Service ID") kind = fields.Many2one(comodel_name="hms.service.kinds", string="Kind") name = fields.Char(string="Name") amount = fields.Float(string="Amount") discount = fields.Float(string="Discount") vat_kind = fields.Many2one(comodel_name="hms.service.vat.kinds", string="VAT Kind") vat = fields.Float(string="VAT") quantity = fields.Integer(string="Quantity") service_date = fields.Datetime(string="Date") reservationId = fields.Many2one(comodel_name="hms.reservations", string="Reservation ID") optionCategory = fields.Char(string="Option Category") isIncluded = fields.Boolean(string="Is Included") class HmsPaymentMethods(models.Model): _name = 'hms.payment.methods' _description = 'Hms Payment Methods' _rec_name = 'name' name = fields.Char(string="Name") hms_id = fields.Integer(string="HMS ID") class HmsBookingSource(models.Model): _name = 'hms.booking.source' _description = 'Hms Booking Source' _rec_name = 'name' name = fields.Char(string="Name") class HmsReservations(models.Model): _name = 'hms.reservations' _description = 'Hms Reservations' bid = fields.Char(string="Reservation ID") customerIndex = fields.Many2one(comodel_name="hms.customer", string="Customer") agentIndex = fields.Many2one(comodel_name="hms.agents", string="Agent") currency = fields.Many2one(comodel_name="res.currency", string="Currency") currencyRate = fields.Float(string="Currency Rate", digits=(16, 4)) bookingNumber = fields.Many2one(comodel_name="hms.bookings", string="Booking Number") roomNumber = fields.Many2one(comodel_name="hms.rooms", string="Room Number") guestId = fields.Many2one(comodel_name="hms.guests", string="Guest ID") guestName = fields.Char(string="Guest Name") guestCount = fields.Integer(string="Guest Count") checkInDateTime = fields.Char(string="Check-In Char") checkOutDateTime = fields.Char(string="Check-Out Char") checkInDateTime_date = fields.Datetime(string="Check-In") checkOutDateTime_date = fields.Datetime(string="Check-Out") permitNumber = fields.Char(string="Permit Number") isDeparted = fields.Boolean(string="Is Departed", default=False) isArrived = fields.Boolean(string="Is Arrived", default=False) paymentMethod = fields.Many2one(comodel_name="hms.payment.methods", string="Payment Method") roomTypeId = fields.Many2one(comodel_name="hms.room.types", string="Room Type ID") customerCompany = fields.Char(string="Customer Company") payerCompany = fields.Char(string="Payer Company") total = fields.Monetary(string="Total", currency_field='currency') tax = fields.Monetary(string="Tax", currency_field='currency') paid = fields.Monetary(string="Paid", currency_field='currency') balance = fields.Monetary(string="Balance", currency_field='currency') creationDateTime = fields.Char(string="Creation Char") creationDateTime_date = fields.Datetime(string="Creation") folioNumber = fields.Char(string="Folio Number") marketCode = fields.Json(string="Market Code") bookingSource = fields.Many2one(comodel_name="hms.booking.source", string="Booking Source")