You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

203 lines
8.6 KiB

# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# 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 (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import fields, models, api, _, exceptions
from datetime import datetime
from odoo.exceptions import ValidationError
class ReservationInvoice(models.Model):
_inherit = 'account.move'
@api.model
def create(self, vals):
res = super(ReservationInvoice, self).create(vals)
if self._context.get("reservation_id"):
reserv = self.env["room.reservation"].browse(self._context["reservation_id"])
reserv.write({"invoice_id": res.id, "invoice_status": "invoiced"})
return res
class Reservation(models.Model):
_name = "room.reservation"
_description = 'Reservation'
_rec_name = 'name'
name = fields.Char(string='Booking Reference', required=True, copy=False, readonly=True,
default=lambda self: _('New'))
num_person = fields.Integer(string='Number of Persons', default=1,required=True)
reservation_line_ids = fields.One2many('room.reservation.line', "reservation_id", string='Booking Info')
state = fields.Selection([('draft', 'Draft'), ('confirm',
'Confirm'), ('occupied', 'Occupied'), ('done', 'Done'),
('cancel', 'Cancel')],
default='draft')
sale_order_id = fields.Many2one('sale.order', 'sale Order', delegate=True, copy=False, ondelete="cascade")
service_ids = fields.One2many('hotel.service.line', 'reservation_id')
invoice_id = fields.Many2one('account.move')
meals_ids = fields.One2many('hotel.meals.line', 'reservation_id')
def action_confirm(self):
self.write({'state': 'confirm'})
self.sale_order_id.write({'invoice_status': 'to invoice', 'state': 'sale'})
def action_cancel(self):
self.state = 'cancel'
for rec in self.reservation_line_ids:
rec.room_id.write({'status': 'available'})
@api.model
def create(self, vals):
if vals.get('name', _('New')) == _('New'):
vals['name'] = self.env['ir.sequence'].next_by_code(
'room.reservation') or _('New')
persons = 0
for rec in vals['reservation_line_ids']:
room_type = self.env['room.types'].sudo().search([('categ_id','=',rec[2]['type_id'])])
persons += room_type.num_person
if vals.get('num_person') > persons:
raise ValidationError(_("Number of persons out of limit!"))
return super(Reservation, self).create(vals)
class ReservationLine(models.Model):
_name = "room.reservation.line"
_description = 'Reservation Lines'
reservation_id = fields.Many2one('room.reservation', ondelete="cascade")
type_id = fields.Many2one('product.category', string='Room type')
room_id = fields.Many2one('room.room', string='room Number')
checkin_date = fields.Date(string='Checkin Date', required=True)
checkout_date = fields.Date(string='Checkout Date', required=True)
order_line_id = fields.Many2one('sale.order.line', 'sale Order Line', delegate=True, copy=False, ondelete="cascade")
@api.constrains("checkin_date", "checkout_date")
def _check_dates(self):
if self.checkin_date >= self.checkout_date:
raise ValidationError(_(" Check In Date Should be less than the Check Out Date!"))
if self.reservation_id.date_order and self.checkin_date:
if self.checkin_date < self.reservation_id.date_order.date():
raise ValidationError(_("check in date should be greater than the current date."))
@api.model
def create(self, vals):
room = self.env['room.room'].sudo().search([('product_id', '=', vals['product_id'])])
vals['room_id'] = room.id
room.write({'status': 'book'})
if "reservation_id" in vals:
reserv = self.env["room.reservation"].browse(vals["reservation_id"])
vals.update({"order_id": reserv.sale_order_id.id})
duplicate = self.env['room.reservation.line'].sudo().search(
[
('product_id', '=', vals['product_id']), ('reservation_id', '!=', vals['reservation_id']),
('checkin_date', '>=', vals['checkin_date']), ('checkin_date', '<=', vals['checkout_date']),
('checkout_date', '<=', vals['checkout_date']), ('checkout_date', '>=', vals['checkin_date']),
('reservation_id.state', 'in', ('confirm', 'occupied'))
])
if duplicate:
raise ValidationError(_('Room not available'))
return super(ReservationLine, self).create(vals)
def write(self, vals):
if "reservation_id" in vals:
reserv = self.env["room.reservation"].browse(vals["reservation_id"])
vals.update({"order_id": reserv.sale_order_id.id})
return super(ReservationLine, self).write(vals)
@api.onchange('type_id')
def room_clear(self):
self.write({'product_id': [(5,)]}, )
@api.onchange('checkin_date', 'checkout_date')
def _compute_days(self):
for rec in self:
if rec.checkin_date and rec.checkout_date:
fmt = '%Y-%m-%d'
date_difference = (rec.checkout_date - rec.checkin_date)
float_days = date_difference.days + float(date_difference.seconds) / 86400
rec.product_uom_qty = float_days
@api.onchange('product_id')
def _compute_subtotoal(self):
self.price_unit = self.product_id.list_price
self.tax_id = self.product_id.taxes_id
class ServiceLine(models.Model):
_name = "hotel.service.line"
_description = 'service Lines'
order_line_id = fields.Many2one('sale.order.line', "Services", required=True, delegate=True, ondelete="cascade")
reservation_id = fields.Many2one("room.reservation", ondelete="cascade")
categ_id = fields.Many2one(related='product_id.categ_id')
checkin_date = fields.Datetime("From Date")
checkout_date = fields.Datetime("To Date")
@api.model
def create(self, vals):
self.price_unit = self.product_id.list_price
if "reservation_id" in vals:
reserv = self.env["room.reservation"].browse(vals["reservation_id"])
vals.update({"order_id": reserv.sale_order_id.id})
return super(ServiceLine, self).create(vals)
@api.onchange('product_id')
def _compute_subtotal(self):
self.price_unit = self.product_id.list_price
class MealsLine(models.Model):
_name = "hotel.meals.line"
_description = 'Meals Lines'
order_line_id = fields.Many2one('sale.order.line', "Services", required=True, delegate=True, ondelete="cascade")
reservation_id = fields.Many2one("room.reservation", ondelete="cascade")
categ_id = fields.Many2one('product.category', string='Type')
checkin_date = fields.Datetime("From Date")
checkout_date = fields.Datetime("To Date")
@api.model
def create(self, vals):
self.price_unit = self.product_id.list_price
if "reservation_id" in vals:
reserv = self.env["room.reservation"].browse(vals["reservation_id"])
vals.update({"order_id": reserv.sale_order_id.id})
return super(MealsLine, self).create(vals)
@api.onchange('product_id')
def _compute_subtotal(self):
self.price_unit = self.product_id.list_price
@api.onchange('categ_id')
def room_clear(self):
self.write({'product_id': [(5,)]}, )
@api.onchange('checkin_date', 'checkout_date')
def _compute_days(self):
for rec in self:
if rec.checkin_date and rec.checkout_date:
fmt = '%Y-%m-%d'
date_difference = (rec.checkout_date - rec.checkin_date)
float_days = date_difference.days + float(date_difference.seconds) / 86400
self.price_subtotal = self.price_unit * float_days
self.product_uom_qty = float_days