3017 lines
135 KiB
Python
3017 lines
135 KiB
Python
# -*- encoding: utf-8 -*-
|
|
|
|
import time
|
|
from dateutil.relativedelta import relativedelta
|
|
import datetime
|
|
from datetime import date
|
|
from odoo import api, fields, models, tools, _, SUPERUSER_ID
|
|
from odoo.exceptions import ValidationError, UserError
|
|
from odoo.exceptions import UserError
|
|
from odoo.tools import config
|
|
# import odoo.addons.decimal_precision as dp
|
|
from odoo.tools.translate import _
|
|
from odoo.tools import format_amount
|
|
import calendar
|
|
from datetime import datetime, timedelta, timezone
|
|
import logging
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
from dateutil.parser import *
|
|
import pytz
|
|
import math
|
|
|
|
utc_time = datetime.utcnow()
|
|
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
|
|
|
|
|
# @api.multi
|
|
def get_price(self, pricelist_ids, price):
|
|
price_amt = 0.0
|
|
pricelist_item_ids = []
|
|
if self._context is None:
|
|
self._context = {}
|
|
|
|
date = time.strftime('%Y-%m-%d')
|
|
if 'date' in self._context:
|
|
date = self._context['date']
|
|
|
|
currency_obj = self.env['res.currency']
|
|
product_pricelist_version_obj = self.env['product.pricelist.item']
|
|
user_browse = self.env['res.users']
|
|
company_obj = self.env['res.company']
|
|
company_id = company_obj.browse(user_browse.company_id.id)
|
|
pricelist_obj = self.env[
|
|
'product.pricelist'].browse(pricelist_ids)
|
|
if pricelist_ids:
|
|
pricelist_item_ids.append(pricelist_ids)
|
|
pricelist_obj = self.env[
|
|
'product.pricelist'].browse(pricelist_ids)
|
|
|
|
pricelist_item_ids = list(set(pricelist_item_ids))
|
|
plversions_search_args = [
|
|
('pricelist_id', 'in', pricelist_item_ids),
|
|
'|',
|
|
('date_start', '=', False),
|
|
('date_start', '<=', date),
|
|
'|',
|
|
('date_end', '=', False),
|
|
('date_end', '>=', date),
|
|
]
|
|
|
|
plversion_ids = product_pricelist_version_obj.search(
|
|
plversions_search_args)
|
|
if not plversion_ids:
|
|
msg = "At least one pricelist item has not declared !\nPlease create pricelist item."
|
|
raise UserError(_('Warning !'), _(msg))
|
|
|
|
self._cr.execute(
|
|
'SELECT i.* '
|
|
'FROM product_pricelist_item AS i '
|
|
'WHERE id = ' + str(plversion_ids[0].id) + '')
|
|
|
|
res1 = self._cr.dictfetchall()
|
|
if pricelist_obj:
|
|
price = currency_obj.compute(
|
|
price, pricelist_obj.currency_id.id, round=False)
|
|
for res in res1:
|
|
if res:
|
|
price_limit = price
|
|
x = (1.0 + (res['price_discount'] or 0.0))
|
|
price = price * (1.0 + (res['price_discount'] or 0.0))
|
|
price += (res['price_surcharge'] or 0.0)
|
|
if res['price_min_margin']:
|
|
price = max(price, price_limit + res['price_min_margin'])
|
|
if res['price_max_margin']:
|
|
price = min(price, price_limit + res['price_max_margin'])
|
|
break
|
|
|
|
price_amt = price
|
|
return price_amt
|
|
|
|
|
|
# Class creation for ID Master
|
|
|
|
|
|
class id_master(models.Model):
|
|
_name = 'id.master'
|
|
_description = 'Clients ID details'
|
|
|
|
name = fields.Char('ID Name', required=True)
|
|
id_code = fields.Char('ID Code', required=True)
|
|
|
|
|
|
class checkout_configuration(models.Model):
|
|
_name = 'checkout.configuration'
|
|
_description = 'Checkout Configuration'
|
|
|
|
name = fields.Selection([('custom', 'Custom'), ('24hour', '24 Hours')],
|
|
'Checkout Time', default='24hour', required=True)
|
|
time = fields.Selection([
|
|
('01', '1 AM'), ('02', '2 AM'), ('03', '3 AM'), ('04', '4 AM'), ('05', '5 AM'), (
|
|
'06', '6 AM'), ('07', '7 AM'), ('08', '8 AM'), ('09', '9 AM'), ('10', '10 AM'),
|
|
('11', '11 AM'), ('12', '12 Noon'), ('13', '1 PM'), ('14', '2 PM'), ('15', '3 PM'), (
|
|
'16', '4 PM'), ('17', '5 PM'), ('18', '6 PM'), ('19', '7 PM'), ('20', '8 PM'),
|
|
('21', '9 PM'), ('22', '10 PM'), ('23',
|
|
'11 PM'), ('24', '12 Mid Night')
|
|
], 'Time', default='10')
|
|
shop_id = fields.Many2one('sale.shop', 'Hotel', domain="[('company_id', '=', [current_company_id])]",
|
|
required=True,
|
|
help="Will show list of shop that belongs to allowed companies of logged-in user. \n -Assign a shop to configure shop-wise check out policy.")
|
|
company_id = fields.Many2one(
|
|
'res.company', related='shop_id.company_id', string='Company', store=True)
|
|
|
|
# _sql_constraints = [
|
|
# ('shop_id_uniq', 'unique(shop_id)', 'Shop must be unique !'),
|
|
# ]
|
|
|
|
|
|
class sale_order(models.Model):
|
|
_inherit = "sale.order"
|
|
_description = "Sale Order Inherit "
|
|
|
|
def _amount_line_tax(self, line):
|
|
val = 0.0
|
|
if line.product_uom_qty == 0:
|
|
num_of_days = 1
|
|
else:
|
|
num_of_days = line.product_uom_qty
|
|
taxes = line.tax_id.compute_all(
|
|
line.price_unit * (1 - (line.discount or 0.0) / 100.0), quantity=num_of_days)
|
|
val = taxes['total_included'] - taxes['total_excluded']
|
|
return val
|
|
|
|
# def _amount_all(self):
|
|
# for order in self:
|
|
# order.update({
|
|
# 'amount_untaxed': 0.0,
|
|
# 'amount_tax': 0.0,
|
|
# 'amount_total': 0.0,
|
|
# })
|
|
# val = val1 = 0.0
|
|
# cur = order.pricelist_id.currency_id
|
|
# for line in order.order_line:
|
|
# val1 += line.price_subtotal
|
|
# val += self._amount_line_tax(line)
|
|
# if cur:
|
|
# total = cur.round(val1) + cur.round(val)
|
|
# order.update({
|
|
# 'amount_untaxed': cur.round(val1),
|
|
# 'amount_tax': cur.round(val),
|
|
# 'amount_total': total,
|
|
# })
|
|
|
|
# state = fields.Selection(selection_add=[
|
|
# ('draft', 'Quotation'),
|
|
# ('sent', 'Quotation Sent'),
|
|
# ('sale', 'To Invoice'),
|
|
# ('progress', 'In Progress'),
|
|
# ('check_out', 'CheckOut'),
|
|
# ('done', 'Done'),
|
|
# ('cancel', 'Cancelled')
|
|
# ], string='Order State', readonly=True, index=True)
|
|
|
|
|
|
# amount_untaxed = fields.Monetary(string='Untaxed Amount', store=True, readonly=True, compute='_amount_all',
|
|
# tracking=5)
|
|
|
|
# amount_tax = fields.Monetary(
|
|
# string='Taxes', store=True, readonly=True, compute='_amount_all')
|
|
|
|
# amount_total = fields.Monetary(
|
|
# string='Total', store=True, readonly=True, compute='_amount_all')
|
|
|
|
transfer_invoice_ids = fields.Many2many('account.move', 'sale_transfer_account_invoice_rel', 'sale_id',
|
|
'invoice_id', "Transfer Invoice Details")
|
|
|
|
|
|
class hotel_reservation(models.Model):
|
|
_name = "hotel.reservation"
|
|
_description = "Reservation"
|
|
_inherit = ['mail.thread', 'mail.activity.mixin', 'portal.mixin']
|
|
|
|
def unlink(self):
|
|
for record in self:
|
|
if record.state in ['confirm', 'done']:
|
|
raise UserError(
|
|
"Reservation could not be Deleted once it is Confirm")
|
|
else:
|
|
for hotel_id in record:
|
|
hotel_id.reservation_line.unlink()
|
|
return super(hotel_reservation, self).unlink()
|
|
|
|
def hotel_reservation_web_unlink(self):
|
|
hotel_reservation_ids = self.search(
|
|
[('state', '=', 'draft')])
|
|
remove_web_draft = self.env['ir.config_parameter'].get_param('remove_draft_web_reservation')
|
|
time_diff = 0
|
|
for reservation in hotel_reservation_ids:
|
|
|
|
current_datetime = fields.Datetime.now()
|
|
reservation_line = self.env['hotel.reservation.line'].search([('line_id', '=', reservation.id)], limit=1)
|
|
if reservation_line.checkin:
|
|
diff = current_datetime - reservation_line.checkin
|
|
time_diff = int(diff.seconds // 60)
|
|
if remove_web_draft:
|
|
if time_diff > int(remove_web_draft):
|
|
reservation.cancel_reservation()
|
|
|
|
# @api.multi
|
|
|
|
def state_scheduler(self):
|
|
room_ids = self.env['hotel.room'].search([])
|
|
current_date = fields.Datetime.now()
|
|
for room_id in room_ids:
|
|
room_folio_ids = self.env['hotel.room.booking.history'].search(
|
|
[('history_id', '=', room_id.id)])
|
|
for room_folio_id in room_folio_ids:
|
|
# print(room_folio_id.check_out.strftime('%Y-%m-%d'))
|
|
# print(current_date.strftime('%Y-%m-%d'))
|
|
if room_folio_id.check_out.strftime('%Y-%m-%d') < current_date.strftime('%Y-%m-%d') and room_folio_id.booking_id.state in ['draft', 'confirm']:
|
|
room_folio_id.booking_id.write({
|
|
'state': 'cancel'
|
|
})
|
|
|
|
def _get_report_base_filename(self):
|
|
return "Hotel-Report"
|
|
|
|
def action_set_to_dirty(self):
|
|
self.write({'state': 'draft'})
|
|
|
|
return True
|
|
|
|
@api.depends('total_cost1', )
|
|
def _get_advance_payment(self):
|
|
sum = 0.00
|
|
remaining = 0.00
|
|
for obj in self:
|
|
obj.update({
|
|
'total_advance': 0.0,
|
|
'remaining_amt': 0.0,
|
|
})
|
|
sum = 0
|
|
for line in obj.account_move_ids:
|
|
move_lines = self.env['account.move.line'].search(
|
|
[('move_id', '=', line.id)])
|
|
if move_lines:
|
|
for mv in move_lines:
|
|
sum = sum + mv.debit
|
|
obj.update({
|
|
'total_advance': sum,
|
|
'remaining_amt': obj.total_cost1 - sum
|
|
})
|
|
|
|
def advance_payment(self):
|
|
reservation = self
|
|
res_id = reservation.id
|
|
value = {}
|
|
data_id = self.env['ir.model.data']._xmlid_to_res_id('hotel_management.advance_payment_wizard1')
|
|
if self._context is None:
|
|
self._context = {}
|
|
ctx = dict(self._context)
|
|
ctx['active_ids'] = [reservation]
|
|
ctx['reservation_id'] = res_id
|
|
if data_id:
|
|
view_id1 = data_id
|
|
|
|
value = {
|
|
'name': _('Deposit amount entry'),
|
|
'view_type': 'form',
|
|
'view_mode': 'form',
|
|
'res_model': 'advance.payment.wizard',
|
|
'view_id': view_id1,
|
|
'context': ctx,
|
|
'views': [(view_id1, 'form')],
|
|
'type': 'ir.actions.act_window',
|
|
'target': 'new',
|
|
|
|
}
|
|
|
|
return value
|
|
|
|
def update_resevation(self):
|
|
for reservation in self:
|
|
room_his_id_search = self.env['hotel.room.booking.history'].search(
|
|
[('booking_id', '=', reservation.id)])
|
|
room_his_id_search.unlink()
|
|
if not reservation.reservation_line:
|
|
raise ValidationError("Reservation line Details are missing.")
|
|
for line in reservation.reservation_line:
|
|
room_line_id = self.env['hotel.room'].search(
|
|
[('product_id', '=', line.room_number.id)])
|
|
###############################################by pornima######
|
|
housekeeping_room = self.env['hotel.housekeeping'].search([
|
|
('room_no', '=', room_line_id.product_id.id), ('state', '=', 'dirty')])
|
|
if housekeeping_room:
|
|
for house1 in housekeeping_room:
|
|
# house = self.env['hotel.housekeeping'].browse(house1)
|
|
house = house1
|
|
|
|
house_current_date = (datetime.strptime(
|
|
str(house.current_date), '%Y-%m-%d')).date()
|
|
house_end_date = (datetime.strptime(
|
|
str(house.end_date), '%Y-%m-%d')).date()
|
|
start_reser = datetime.strptime(
|
|
str(line.checkin), '%Y-%m-%d %H:%M:%S').date()
|
|
end_reser = datetime.strptime(
|
|
str(line.checkout), '%Y-%m-%d %H:%M:%S').date()
|
|
if (house_current_date <= start_reser <= house_end_date) or (
|
|
house_current_date <= end_reser <= house_end_date) or (
|
|
(start_reser < house_current_date) and (end_reser > house_end_date)):
|
|
# if (((start_reser < house_current_date) and (end_reser > house_end_date)) or (house_current_date <= start_reser < house_end_date) or (house_current_date < end_reser <= house_end_date)) and (house.state == 'dirty'):
|
|
# print "i am in if loop--------------"
|
|
raise ValidationError(
|
|
"Room %s is not clean for reservation period !" % (room_line_id.name))
|
|
|
|
###############################################
|
|
|
|
if room_line_id.room_folio_ids:
|
|
for history in room_line_id.room_folio_ids:
|
|
if history.state == 'done':
|
|
history_start_date = history.check_in
|
|
history_end_date = history.check_out
|
|
reservation_start_date = datetime.strptime(
|
|
str(line.checkin), '%Y-%m-%d %H:%M:%S')
|
|
reservation_end_date = datetime.strptime(
|
|
str(line.checkout), '%Y-%m-%d %H:%M:%S')
|
|
if (history_start_date <= reservation_start_date < history_end_date) or (
|
|
history_start_date < reservation_end_date <= history_end_date) or (
|
|
(reservation_start_date < history_start_date) and (
|
|
reservation_end_date > history_end_date)):
|
|
# print "Already Reserved......."
|
|
if not (reservation.id == history.booking_id.id):
|
|
raise UserError("Room %s is booked in this reservation period !" % (
|
|
room_line_id.name,))
|
|
for line in reservation.reservation_line:
|
|
# print reservation,"reservation"
|
|
room_line_id = self.env['hotel.room'].search(
|
|
[('product_id', '=', line.room_number.id)])
|
|
room_his_id = self.env['hotel.room.booking.history'].create({
|
|
'partner_id': reservation.partner_id.id,
|
|
'check_in': line.checkin,
|
|
'check_out': line.checkout,
|
|
'history_id': room_line_id.id,
|
|
'product_id': line.room_number.id,
|
|
'booking_id': reservation.id,
|
|
'state': 'done',
|
|
'category_id': room_line_id.categ_id.id,
|
|
'name': line.room_number.name,
|
|
'check_in_date': (line.checkin).date(),
|
|
'check_out_date': (line.checkout).date(),
|
|
})
|
|
|
|
def write(self, vals):
|
|
ret = super(hotel_reservation, self).write(vals)
|
|
for res in self:
|
|
if res:
|
|
no_of_adults_room = 0
|
|
no_of_child_room = 0
|
|
if res.reservation_line:
|
|
for line in res.reservation_line:
|
|
if line:
|
|
no_of_adults_room += line.room_number.max_adult
|
|
no_of_child_room += line.room_number.max_child
|
|
_logger.info('\n\n\n{}\n{}\n{}\n\n\n'.format(res.name, res.adults, vals))
|
|
# if res.adults <= 0:
|
|
# raise ValidationError('Please set no of adults for reservation')
|
|
#
|
|
# if res.adults > no_of_adults_room:
|
|
# raise ValidationError('You can not exceed the number of adults than the set limit on '
|
|
# 'individual room.')
|
|
#
|
|
# if res.childs > no_of_child_room:
|
|
# raise ValidationError('You can not exceed the number of children than the set limit on '
|
|
# 'individual room.')
|
|
return ret
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals):
|
|
for val in vals:
|
|
val['name'] = self.env['ir.sequence'].next_by_code(
|
|
'hotel.reservation') or _('New')
|
|
val['reservation_no'] = val['name']
|
|
res = super(hotel_reservation, self).create(val)
|
|
res.compute()
|
|
if res:
|
|
no_of_adults_room = 0
|
|
no_of_child_room = 0
|
|
if res.reservation_line:
|
|
for line in res.reservation_line:
|
|
if line:
|
|
no_of_adults_room += line.room_number.max_adult
|
|
no_of_child_room += line.room_number.max_child
|
|
|
|
# if res.adults <= 0:
|
|
# raise ValidationError('Please set no of adults for reservation')
|
|
#
|
|
# if res.adults > no_of_adults_room:
|
|
# raise ValidationError('You can not exceed the number of adults than the set limit on '
|
|
# 'individual room.')
|
|
#
|
|
# if res.childs > no_of_child_room:
|
|
# raise ValidationError('You can not exceed the number of children than the set limit on '
|
|
# 'individual room.')
|
|
return res
|
|
|
|
# @api.multi
|
|
def _count_total_rooms(self):
|
|
for order in self:
|
|
count = 0
|
|
for line in order.reservation_line:
|
|
count += 1
|
|
order.update({
|
|
'number_of_rooms': count,
|
|
})
|
|
|
|
@api.onchange('pricelist_id')
|
|
def onchange_pricelist_id(self):
|
|
self.show_update_pricelist = True
|
|
if 'checkin' in self._context and 'checkout' in self._context:
|
|
room_obj = self.env['product.product']
|
|
room_brw = room_obj.search(
|
|
[('id', '=', self._context['hotel_resource'])])
|
|
pricelist = self.env['sale.shop'].browse(
|
|
int(self._context['shop_id'])).pricelist_id.id
|
|
if pricelist == False:
|
|
raise UserError(
|
|
('Please set the Pricelist on the shop %s to proceed further') % room_brw.shop_id.name)
|
|
ctx = self._context and self._context.copy() or {}
|
|
ctx.update({'date': self._context['checkin']})
|
|
from dateutil import parser
|
|
day_count1 = parser.isoparse(self._context['checkout']) - parser.isoparse(self._context['checkin'])
|
|
|
|
day_count2 = day_count1.total_seconds()
|
|
_logger.info("DIFF SECONDS===>>>>>>>>>{}".format(day_count2))
|
|
day_count2 = day_count2 / 86400
|
|
day_count2 = "{:.2f}".format(day_count2)
|
|
day_count2 = math.ceil(float(day_count2))
|
|
|
|
_logger.info("SELF CONTEXT====>>>>>{}".format(self._context['checkin']))
|
|
res_line = {
|
|
'categ_id': room_brw.categ_id.id,
|
|
'room_number': room_brw.id,
|
|
'checkin': parser.isoparse(self._context['checkin']),
|
|
'checkout': parser.isoparse(self._context['checkout']),
|
|
'number_of_days': int(day_count2),
|
|
'price': self.env['product.pricelist'].with_context(ctx)._price_get(room_brw, 1)[pricelist]
|
|
}
|
|
if self.reservation_line:
|
|
self.reservation_line.write(res_line)
|
|
else:
|
|
_logger.info("RES LINE===>>>>>>>>>>>>>>>{}".format(res_line))
|
|
self.reservation_line = [[0, 0, res_line]]
|
|
if not self.pricelist_id:
|
|
return {}
|
|
if not self.reservation_line:
|
|
return {}
|
|
if len(self.reservation_line) != 1:
|
|
warning = {
|
|
'title': _('Pricelist Warning!'),
|
|
'message': _(
|
|
'If you change the pricelist of this order (and eventually the currency), prices of existing order lines will not be updated.')
|
|
}
|
|
return {'warning': warning}
|
|
|
|
def update_prices(self):
|
|
lines_to_update = []
|
|
for line in self.reservation_line:
|
|
product = line.room_number.with_context(
|
|
quantity=line.number_of_days,
|
|
date=line.checkin,
|
|
pricelist=self.pricelist_id.id,
|
|
)
|
|
price_unit = self.env['account.tax']._fix_tax_included_price_company(
|
|
line._get_display_price(product), line.room_number.taxes_id, line.taxes_id, line.company_id)
|
|
if self.pricelist_id.discount_policy == 'without_discount' and price_unit:
|
|
discount = max(0, (price_unit - product.price)
|
|
* 100 / price_unit)
|
|
else:
|
|
discount = 0
|
|
lines_to_update.append(
|
|
(1, line.id, {'price': price_unit, 'discount': discount}))
|
|
self.update({'reservation_line': lines_to_update})
|
|
self.show_update_pricelist = False
|
|
self.message_post(body=_(
|
|
"Product prices have been recomputed according to pricelist <b>%s<b> " %self.pricelist_id.display_name))
|
|
|
|
def _amount_line_tax(self, line):
|
|
val = 0.0
|
|
taxes = line.taxes_id.compute_all(
|
|
line.price * (1 - (line.discount or 0.0) / 100.0), quantity=line.number_of_days)
|
|
val = taxes['total_included'] - taxes['total_excluded']
|
|
return val
|
|
|
|
# @api.multi
|
|
def _get_subtotal_amount(self):
|
|
total = 0.0
|
|
if self:
|
|
for obj in self:
|
|
if obj.id:
|
|
for line in obj.reservation_line:
|
|
total += line.sub_total1
|
|
print('------obj.pricelist_id', obj.pricelist_id)
|
|
print('------obj.pricelist_id.currency_id', obj.pricelist_id.currency_id)
|
|
obj.update({
|
|
'untaxed_amt': obj.pricelist_id.currency_id.round(total),
|
|
})
|
|
else:
|
|
obj.update({
|
|
'untaxed_amt': 0,
|
|
})
|
|
|
|
# @api.multi
|
|
def _get_total_tax(self):
|
|
# get total tax on the room
|
|
val1 = 0.0
|
|
total1 = 0.0
|
|
for obj in self:
|
|
for line in obj.reservation_line:
|
|
total1 += line.sub_total1
|
|
val1 += self._amount_line_tax(line)
|
|
if obj.pricelist_id:
|
|
obj.update({
|
|
'total_tax': obj.pricelist_id.currency_id.round(val1),
|
|
})
|
|
|
|
@api.depends('reservation_line')
|
|
def _get_total_rental_cost(self):
|
|
# total amount after deduction by tax
|
|
for order in self:
|
|
order.update({
|
|
'total_cost1': 0.0,
|
|
})
|
|
total1 = val1 = 0.0
|
|
cur = order.pricelist_id.currency_id
|
|
for line in order.reservation_line:
|
|
total1 += line.sub_total1
|
|
val1 += self._amount_line_tax(line)
|
|
if cur:
|
|
sum = cur.round(total1) + cur.round(val1)
|
|
order.update({
|
|
'total_cost1': sum,
|
|
})
|
|
|
|
# @api.multi
|
|
@api.depends('adv_amount')
|
|
def _get_advance_cost(self):
|
|
total = 0
|
|
for obj in self:
|
|
total = 0
|
|
if obj.adv_amount:
|
|
total = obj.adv_amount
|
|
obj.update({
|
|
'deposit_cost2': total,
|
|
})
|
|
|
|
# @api.multi
|
|
def _get_default_shop(self):
|
|
user = self.env['res.users'].browse(self._uid)
|
|
company_id = user.company_id.id
|
|
shop_ids = self.env['sale.shop'].search(
|
|
[('company_id', '=', company_id)])
|
|
if not shop_ids:
|
|
raise UserError(
|
|
'There is no default shop for the current user\'s company!')
|
|
return shop_ids[0]
|
|
|
|
@api.onchange('shop_id')
|
|
def onchange_shop(self):
|
|
if self.shop_id:
|
|
shop = self.shop_id
|
|
if shop.pricelist_id:
|
|
self.pricelist_id = shop.pricelist_id.id
|
|
|
|
@api.onchange('partner_id')
|
|
def onchange_patner(self):
|
|
if self.partner_id:
|
|
partner = self.partner_id
|
|
if partner.property_product_pricelist:
|
|
self.pricelist_id = partner.property_product_pricelist.id
|
|
print('-------------commits', self.pricelist_id)
|
|
# self.env.cr.commit()
|
|
|
|
name = fields.Char('Event type', default=lambda self: _('New'))
|
|
gds_id = fields.Char('GDS ID', readonly=True)
|
|
reservation_no = fields.Char(
|
|
'Reservation No', readonly=True, index=True)
|
|
date_order = fields.Datetime('Date Ordered', required=True, default=datetime.today(), readonly=True)
|
|
shop_id = fields.Many2one('sale.shop', 'Hotel', required=True,
|
|
domain="[('company_id', '=', [current_company_id])]",
|
|
default=_get_default_shop, readonly=True)
|
|
partner_id = fields.Many2one(
|
|
'res.partner', 'Guest Name', required=True)
|
|
pricelist_id = fields.Many2one(
|
|
'product.pricelist', 'Pricelist')
|
|
# 'checkin': fields.datetime('Expected-Date-Arrival',required=True,readonly=True, states={'draft':[('readonly',False)],'confirm':[('readonly',False)]}),
|
|
# 'checkout': fields.datetime('Expected-Date-Departure',required=True, readonly=True, states={'draft':[('readonly',False)],'confirm':[('readonly',False)]}),
|
|
adults = fields.Integer('Adults', )
|
|
childs = fields.Integer('Children',)
|
|
reservation_line = fields.One2many(
|
|
'hotel.reservation.line', 'line_id', 'Reservation Line', readonly=False)
|
|
state = fields.Selection([('draft', 'Draft'), ('confirm', 'Confirm'), (
|
|
'done', 'Done'), ('cancel', 'Cancelled')], 'State', default='draft', readonly=True)
|
|
folio_id = fields.Many2many(
|
|
'hotel.folio', 'hotel_folio_reservation_rel', 'order_id', 'invoice_id', 'Folio')
|
|
folio_state = fields.Selection(
|
|
string="Status",
|
|
readonly=True, copy=False, index=True,
|
|
tracking=3,
|
|
related='hotel_folio_id.state')
|
|
hotel_folio_id = fields.Many2one('hotel.folio', string = "Hotel Folio", compute = "_compute_folio_state", store=True)
|
|
dummy = fields.Datetime('Dummy')
|
|
source = fields.Selection([('internal_reservation', 'Internal Reservation'), ('through_web', 'Through Web'), (
|
|
'through_gds', 'Through GDS')], 'Source', default='internal_reservation', index=True, readonly=True)
|
|
number_of_rooms = fields.Integer(
|
|
compute="_count_total_rooms", string="Number Of Rooms")
|
|
untaxed_amt = fields.Float(
|
|
compute="_get_subtotal_amount", string="Untaxed Amount")
|
|
|
|
total_tax = fields.Float(string="Reservation Tax",store = True,
|
|
compute="_get_total_tax")
|
|
deposit_cost1 = fields.Float(string="deposit cost", )
|
|
total_cost1 = fields.Float(
|
|
string="Total Reservation cost", compute="_get_total_rental_cost", readonly=True)
|
|
company_id = fields.Many2one(
|
|
'res.company', related='shop_id.company_id', string='Company', store=True)
|
|
|
|
id_line_ids = fields.One2many('hotel.resv.id.details', 'reservation_id',
|
|
'ID Line', readonly=False)
|
|
via = fields.Selection([('direct', 'Direct'), ('agent', 'Agent')], "Via",
|
|
readonly=True, default='direct')
|
|
agent_id = fields.Many2one('res.partner', 'Agent', readonly=True)
|
|
invoiced = fields.Boolean('Invoiced', default=False)
|
|
adv_amount = fields.Float("Advance Amount")
|
|
|
|
deposit_recv_acc = fields.Many2one(
|
|
'account.account', string="Deposit Account", required=False)
|
|
|
|
deposit_cost2 = fields.Float(
|
|
compute="_get_advance_cost", string="Advance Payment", store=True)
|
|
agent_comm = fields.Float("Commision")
|
|
currency_id = fields.Many2one('res.currency', 'Currency', required=True, related='company_id.currency_id',
|
|
default=lambda self: self.env.user.company_id.currency_id.id)
|
|
note = fields.Text(string='Note')
|
|
account_move_ids = fields.Many2many('account.move', 'reservation_account_move_rel', 'reservation_id', 'move_id',
|
|
"Payment Details")
|
|
total_advance = fields.Float(
|
|
compute="_get_advance_payment", string="Total Advance Payment", )
|
|
remaining_amt = fields.Float(
|
|
compute="_get_advance_payment", string="Total Remaining Amount", )
|
|
show_update_pricelist = fields.Boolean(string='Has Pricelist Changed')
|
|
|
|
folio_count = fields.Integer(
|
|
compute="_compute_folio", string='Folio Count', copy=False, default=0, readonly=True)
|
|
folio_ids = fields.Many2many('hotel.folio', compute="_compute_folio", string='Invoices', copy=False,
|
|
readonly=True)
|
|
reference = fields.Char('Rederence')
|
|
|
|
@api.depends('name')
|
|
def _compute_folio_state(self):
|
|
for record in self:
|
|
hotel_folio = self.env['hotel.folio'].sudo().search([('reservation_id', '=', record.id)])
|
|
if hotel_folio:
|
|
record.hotel_folio_id = hotel_folio.id
|
|
else:
|
|
record.hotel_folio_id = ''
|
|
|
|
|
|
def _compute_folio(self):
|
|
for order in self:
|
|
folio = self.env['hotel.folio'].search(
|
|
[('reservation_id', '=', order.id)])
|
|
order.folio_ids = folio
|
|
order.folio_count = len(folio)
|
|
|
|
def action_view_folio(self):
|
|
folio = self.mapped('folio_ids')
|
|
action = self.env.ref('hotel.open_hotel_folio1_form_tree').sudo().read()[0]
|
|
if len(folio) > 1:
|
|
action['domain'] = [('id', 'in', folio.ids)]
|
|
elif len(folio) == 1:
|
|
form_view = [
|
|
(self.env.ref('hotel.view_hotel_folio1_form').id, 'form')]
|
|
if 'views' in action:
|
|
action['views'] = form_view + \
|
|
[(state, view)
|
|
for state, view in action['views'] if view != 'form']
|
|
else:
|
|
action['views'] = form_view
|
|
action['res_id'] = folio.id
|
|
else:
|
|
action = {'type': 'ir.actions.act_window_close'}
|
|
|
|
return action
|
|
|
|
# @api.multi
|
|
|
|
def compute(self):
|
|
total = 0
|
|
val = 0
|
|
for obj in self:
|
|
for line in obj.reservation_line:
|
|
# line.count_price()
|
|
total += line.sub_total1
|
|
val += self._amount_line_tax(line)
|
|
if self.pricelist_id:
|
|
self.total_tax = self.pricelist_id.currency_id.round(val)
|
|
self.untaxed_amt = self.pricelist_id.currency_id.round(total)
|
|
else:
|
|
self.total_tax = val
|
|
self.untaxed_amt = total
|
|
sum = self.total_tax + self.untaxed_amt
|
|
self.total_cost1 = sum
|
|
return True
|
|
|
|
# @api.multi
|
|
def onchange_partner_id(self, cr, uid, ids, part):
|
|
if not part:
|
|
return {'value': {'partner_invoice_id': False, 'partner_shipping_id': False, }}
|
|
addr = self.pool.get('res.partner').address_get(
|
|
cr, uid, [part], ['delivery', 'invoice', 'contact'])
|
|
result = {}
|
|
warning = {}
|
|
title = False
|
|
message = False
|
|
partner = self.pool.get('res.partner').browse(cr, uid, part)
|
|
if partner.reservation_warn != 'no-message':
|
|
if partner.reservation_warn == 'block':
|
|
raise UserError(
|
|
_('Alert for %s!') % (partner.name), partner.reservation_msg)
|
|
title = _("Warning for %s") % partner.name
|
|
message = partner.reservation_msg
|
|
warning = {
|
|
'title': title,
|
|
'message': message
|
|
}
|
|
|
|
if result.get('warning', False):
|
|
warning['title'] = title and title + ' & ' + \
|
|
result['warning']['title'] or result['warning']['title']
|
|
warning['message'] = message and message + ' ' + \
|
|
result['warning']['message'] or result['warning']['message']
|
|
|
|
return {'value': {'partner_invoice_id': addr['invoice'], 'partner_shipping_id': addr['delivery'],
|
|
'value1': result.get('value', {}), },
|
|
'warning': warning}
|
|
|
|
@api.onchange('adv_amount')
|
|
def onchange_adv_amount(self):
|
|
if self.adv_amount:
|
|
self.deposite = self.adv_amount
|
|
|
|
# @api.multi
|
|
def cancel_reservation(self):
|
|
for reservation in self:
|
|
if reservation.state in ['draft', 'confirm']:
|
|
room_his_id_search = self.env['hotel.room.booking.history'].search(
|
|
[('booking_id', '=', reservation.id)])
|
|
room_his_id_search.unlink()
|
|
self.status = 'cancelled'
|
|
self.write({'state': 'cancel'})
|
|
|
|
def back_to_dashboard(self):
|
|
return {
|
|
'type': 'ir.actions.act_url',
|
|
'url': 'localhost:3000/dashboards',
|
|
'target': 'current'
|
|
}
|
|
|
|
# @api.multi
|
|
def confirmed_reservation(self):
|
|
for reservation in self:
|
|
if reservation.source == 'internal_reservation':
|
|
if not reservation.reservation_line:
|
|
raise UserError(_('Please Select Room'))
|
|
if reservation.total_cost1 < reservation.deposit_cost2:
|
|
raise ValidationError(
|
|
"Advance Amount Should not be greater than Total Reservation Cost.")
|
|
if not reservation.reservation_line:
|
|
raise ValidationError("Reservation line Details are missing.")
|
|
for line in reservation.reservation_line:
|
|
room_line_id = self.env['hotel.room'].search(
|
|
[('product_id', '=', line.room_number.id)])
|
|
###############################################by pornima######
|
|
housekeeping_room = self.env['hotel.housekeeping'].search([
|
|
('room_no', '=', room_line_id.product_id.id), ('state', '=', 'dirty')])
|
|
if housekeeping_room:
|
|
for house1 in housekeeping_room:
|
|
house_brw = self.env[
|
|
'hotel.housekeeping'].browse(house1)
|
|
house = house_brw.id
|
|
house_current_date = (datetime.strptime(
|
|
str(house.current_date), '%Y-%m-%d')).date()
|
|
house_end_date = (datetime.strptime(
|
|
str(house.end_date), '%Y-%m-%d')).date()
|
|
start_reser = datetime.strptime(
|
|
str(line.checkin), '%Y-%m-%d %H:%M:%S').date()
|
|
end_reser = datetime.strptime(
|
|
str(line.checkout), '%Y-%m-%d %H:%M:%S').date()
|
|
if (house_current_date <= start_reser <= house_end_date) or (
|
|
house_current_date <= end_reser <= house_end_date) or (
|
|
(start_reser < house_current_date) and (end_reser > house_end_date)):
|
|
raise ValidationError(
|
|
"Room %s is not clean for reservation period !" % (room_line_id.name))
|
|
#
|
|
###############################################
|
|
if room_line_id.room_folio_ids:
|
|
for history in room_line_id.room_folio_ids:
|
|
if history.state == 'done':
|
|
history_start_date = history.check_in
|
|
history_end_date = history.check_out
|
|
reservation_start_date = line.checkin
|
|
reservation_end_date = line.checkout
|
|
if (history_start_date <= reservation_start_date < history_end_date) or (
|
|
history_start_date < reservation_end_date <= history_end_date) or (
|
|
(reservation_start_date < history_start_date) and (
|
|
reservation_end_date >= history_end_date)):
|
|
if not (reservation.id == history.booking_id.id):
|
|
raise UserError("Room %s is booked in this reservation period !" % (
|
|
room_line_id.name))
|
|
|
|
for line in reservation.reservation_line:
|
|
room_line_id = self.env['hotel.room'].search(
|
|
[('product_id', '=', line.room_number.id)])
|
|
room_his_id = self.env['hotel.room.booking.history'].create({
|
|
'partner_id': reservation.partner_id.id,
|
|
'check_in': line.checkin,
|
|
'check_out': line.checkout,
|
|
'history_id': room_line_id.id,
|
|
'product_id': line.room_number.id,
|
|
'booking_id': reservation.id,
|
|
'state': 'done',
|
|
'category_id': room_line_id.categ_id.id,
|
|
'name': line.room_number.name,
|
|
'check_in_date': line.checkin,
|
|
'check_out_date': line.checkout
|
|
})
|
|
self.status = 'confirmed'
|
|
self.write({'state': 'confirm'})
|
|
return True
|
|
|
|
def update_history(self):
|
|
for reservation in self:
|
|
room_his_id_search = self.env['hotel.room.booking.history'].search(
|
|
[('booking_id', '=', reservation.id)])
|
|
room_his_id_search.unlink()
|
|
if not reservation.reservation_line:
|
|
raise ValidationError("Reservation line Details are missing.")
|
|
for line in reservation.reservation_line:
|
|
room_line_id = self.env['hotel.room'].search(
|
|
[('product_id', '=', line.room_number.id)])
|
|
###############################################by pornima######
|
|
housekeeping_room = self.env['hotel.housekeeping'].search([
|
|
('room_no', '=', room_line_id.product_id.id), ('state', '=', 'dirty')])
|
|
if housekeeping_room:
|
|
for house1 in housekeeping_room:
|
|
# house = self.env['hotel.housekeeping'].browse(house1)
|
|
house = house1
|
|
|
|
house_current_date = (datetime.strptime(
|
|
str(house.current_date), '%Y-%m-%d')).date()
|
|
house_end_date = (datetime.strptime(
|
|
str(house.end_date), '%Y-%m-%d')).date()
|
|
start_reser = datetime.strptime(
|
|
str(line.checkin), '%Y-%m-%d %H:%M:%S').date()
|
|
end_reser = datetime.strptime(
|
|
str(line.checkout), '%Y-%m-%d %H:%M:%S').date()
|
|
if (house_current_date <= start_reser <= house_end_date) or (
|
|
house_current_date <= end_reser <= house_end_date) or (
|
|
(start_reser < house_current_date) and (end_reser > house_end_date)):
|
|
# if (((start_reser < house_current_date) and (end_reser > house_end_date)) or (house_current_date <= start_reser < house_end_date) or (house_current_date < end_reser <= house_end_date)) and (house.state == 'dirty'):
|
|
# print "i am in if loop--------------"
|
|
raise ValidationError("Room %s is not clean for reservation period !") % (
|
|
room_line_id.name)
|
|
|
|
###############################################
|
|
|
|
if room_line_id.room_folio_ids:
|
|
for history in room_line_id.room_folio_ids:
|
|
if history.state == 'done':
|
|
history_start_date = history.check_in
|
|
history_end_date = history.check_out
|
|
reservation_start_date = datetime.strptime(
|
|
str(line.checkin), '%Y-%m-%d %H:%M:%S')
|
|
reservation_end_date = datetime.strptime(
|
|
str(line.checkout), '%Y-%m-%d %H:%M:%S')
|
|
if (history_start_date <= reservation_start_date < history_end_date) or (
|
|
history_start_date < reservation_end_date <= history_end_date) or (
|
|
(reservation_start_date < history_start_date) and (
|
|
reservation_end_date > history_end_date)):
|
|
# print "Already Reserved......."
|
|
if not (reservation.id == history.booking_id.id):
|
|
raise UserError("Room %s is booked in this reservation period !" % (
|
|
room_line_id.name,))
|
|
for line in reservation.reservation_line:
|
|
# print reservation,"reservation"
|
|
room_line_id = self.env['hotel.room'].search(
|
|
[('product_id', '=', line.room_number.id)])
|
|
room_his_id = self.env['hotel.room.booking.history'].create({
|
|
'partner_id': reservation.partner_id.id,
|
|
'check_in': line.checkin,
|
|
'check_out': line.checkout,
|
|
'history_id': room_line_id.id,
|
|
'product_id': line.room_number.id,
|
|
'booking_id': reservation.id,
|
|
'state': 'done',
|
|
'category_id': room_line_id.categ_id.id,
|
|
'name': line.room_number.name,
|
|
'check_in_date': (line.checkin).date(),
|
|
'check_out_date': (line.checkout).date(),
|
|
})
|
|
return True
|
|
|
|
def create_folio(self):
|
|
for reservation in self:
|
|
room_his_id_search = self.env['hotel.room.booking.history'].search(
|
|
[('booking_id', '=', reservation.id)])
|
|
room_his_id_search.unlink()
|
|
if not reservation.reservation_line:
|
|
raise ValidationError("Reservation line Details are missing.")
|
|
for line in reservation.reservation_line:
|
|
room_line_id = self.env['hotel.room'].search(
|
|
[('product_id', '=', line.room_number.id)])
|
|
###############################################by pornima######
|
|
housekeeping_room = self.env['hotel.housekeeping'].search(
|
|
[('room_no', '=', room_line_id.product_id.id), ('state', '=', 'dirty')])
|
|
# "housekeeping_room--------------------------------------------------------------------",housekeeping_room
|
|
if housekeeping_room:
|
|
for house1 in housekeeping_room:
|
|
house_brw = self.env[
|
|
'hotel.housekeeping'].browse(house1)
|
|
house = house_brw.id
|
|
house_current_date = (
|
|
datetime.strptime(str(house.current_date), '%Y-%m-%d')).date()
|
|
house_end_date = (
|
|
datetime.strptime(str(house.end_date), '%Y-%m-%d')).date()
|
|
start_reser = datetime.strptime(
|
|
str(line.checkin), '%Y-%m-%d %H:%M:%S').date()
|
|
end_reser = datetime.strptime(
|
|
str(line.checkout), '%Y-%m-%d %H:%M:%S').date()
|
|
if (house_current_date <= start_reser <= house_end_date) or (
|
|
house_current_date <= end_reser <= house_end_date) or (
|
|
(start_reser < house_current_date) and (end_reser > house_end_date)):
|
|
# if (((start_reser < house_current_date) and (end_reser > house_end_date)) or (house_current_date <= start_reser < house_end_date) or (house_current_date < end_reser <= house_end_date)) :
|
|
# print "i am in if loop--------------\n\n\n\n\n"
|
|
raise ValidationError("Room %s is not clean for reservation period !" % (
|
|
room_line_id.name))
|
|
|
|
###############################################
|
|
|
|
if room_line_id.room_folio_ids:
|
|
for history in room_line_id.room_folio_ids:
|
|
if history.state == 'done':
|
|
history_start_date = history.check_in
|
|
history_end_date = history.check_out
|
|
reservation_start_date = line.checkin
|
|
reservation_end_date = line.checkout
|
|
if (history_start_date <= reservation_start_date < history_end_date) or (
|
|
history_start_date < reservation_end_date <= history_end_date) or (
|
|
(reservation_start_date < history_start_date) and (
|
|
reservation_end_date > history_end_date)):
|
|
|
|
if not (reservation.id == history.booking_id.id):
|
|
raise UserError("Room %s is booked in this reservation period !" % (
|
|
room_line_id.name,))
|
|
|
|
line = reservation.reservation_line
|
|
|
|
folio = self.env['hotel.folio'].create({
|
|
'date_order': reservation.date_order,
|
|
'shop_id': reservation.shop_id.id,
|
|
'partner_id': reservation.partner_id.id,
|
|
'pricelist_id': reservation.pricelist_id.id,
|
|
'partner_invoice_id': reservation.partner_id.id,
|
|
'partner_shipping_id': reservation.partner_id.id,
|
|
|
|
# 'checkin_date': line.checkin,
|
|
# 'checkout_date': line.checkout,
|
|
'reservation_id': reservation.id,
|
|
# 'duration': line1.number_of_days,
|
|
'note': reservation.note,
|
|
# 'service_lines': reservation.other_items_ids,
|
|
})
|
|
for line in reservation.reservation_line:
|
|
room_line_id = self.env['hotel.room'].search(
|
|
[('product_id', '=', line.room_number.id)])
|
|
room_his_id = self.env['hotel.room.booking.history'].create({
|
|
'partner_id': reservation.partner_id.id,
|
|
'check_in': line.checkin,
|
|
'check_out': line.checkout,
|
|
'history_id': room_line_id.id,
|
|
'product_id': line.room_number.id,
|
|
'booking_id': reservation.id,
|
|
'state': 'done',
|
|
'category_id': line.room_number.categ_id.id, # room_line_id.categ_id.id,
|
|
'name': line.room_number.name,
|
|
'check_in_date': line.checkin,
|
|
'check_out_date': line.checkout,
|
|
})
|
|
tax_ids = []
|
|
for tax_line in line.taxes_id:
|
|
tax_ids.append(tax_line.id)
|
|
vals = {
|
|
'folio_id': folio.id,
|
|
'product_id': line.room_number.id,
|
|
'name': line.room_number.name,
|
|
'product_uom': line.room_number.uom_id.id,
|
|
'price_unit': line.price,
|
|
'product_uom_qty': line.number_of_days,
|
|
# 'checkin_date': datetime.now(),
|
|
'checkin_date': line.checkin,
|
|
'checkout_date': line.checkout,
|
|
'discount': line.discount,
|
|
'tax_id': [(6, 0, tax_ids)],
|
|
'categ_id': line.room_number.categ_id.id, # room_line_id.categ_id.id,
|
|
'hotel_reservation_line_id': line.id
|
|
}
|
|
self.env["hotel_folio.line"].create(vals)
|
|
# for service_line in reservation.other_items_ids:
|
|
# product_id = self.env['product.product'].search(
|
|
# [('id', '=', service_line.product_id.id)])
|
|
# vals = {
|
|
# 'folio_id': folio.id,
|
|
# 'product_id': product_id.id,
|
|
# 'name': product_id.name,
|
|
# 'product_uom': service_line.product_uom.id,
|
|
# 'product_uom_qty': service_line.product_uom_qty,
|
|
# 'price_unit': service_line.price_unit,
|
|
#
|
|
# }
|
|
# self.env["hotel_service.line"].create(vals)
|
|
|
|
for rec_id in reservation.id_line_ids:
|
|
rec_id.write({'folio_id': folio.id})
|
|
for mv in reservation.account_move_ids:
|
|
self._cr.execute('insert into sale_account_move_rel(sale_id, move_id) values (%s,%s)',
|
|
(folio.id, mv.id))
|
|
|
|
reservation.reservation_line.write({
|
|
'checkin': line.checkin,
|
|
})
|
|
reservation.status = 'checkin'
|
|
reservation.write(
|
|
{'state': 'done', 'agent_comm': reservation.total_cost1, })
|
|
return True
|
|
|
|
def done(self):
|
|
active_id = self._context.get('active_ids')
|
|
for reservation in self:
|
|
# print "reservation.deposit_cost2=======================",
|
|
# reservation.total_cost1
|
|
if reservation.deposit_cost2:
|
|
data_obj = self.env['ir.model.data']
|
|
data_id = data_obj._get_id(
|
|
'hotel_management', 'deposit_journal_entry_wizard1')
|
|
# print data_id,"data_id=------------------------"
|
|
view_id1 = False
|
|
if self._context is None:
|
|
self_context = {}
|
|
ctx = dict(self._context)
|
|
ctx['active_ids'] = [reservation.id]
|
|
ctx['booking_id'] = reservation.id
|
|
if data_id:
|
|
view_id1 = data_obj.browse(data_id).res_id
|
|
value = {
|
|
'name': _('Advance Payment Entry'),
|
|
'view_type': 'form',
|
|
'view_mode': 'form',
|
|
'res_model': 'deposit_journal_entry.wizard1',
|
|
'view_id': False,
|
|
'context': ctx,
|
|
'views': [(view_id1, 'form')],
|
|
'type': 'ir.actions.act_window',
|
|
'target': 'new',
|
|
'nodestroy': True
|
|
}
|
|
return value
|
|
else:
|
|
so = self.create_folio()
|
|
return so
|
|
|
|
def _send_order_confirmation_mail(self):
|
|
if self.env.su:
|
|
# sending mail in sudo was meant for it being sent from superuser
|
|
self = self.with_user(SUPERUSER_ID)
|
|
# template_id = self._find_mail_template(force_confirmation_template=True)
|
|
# if template_id:
|
|
# for order in self:
|
|
# order.with_context(force_send=True).message_post_with_template(template_id, composition_mode='comment', email_layout_xmlid="mail.mail_notification_paynow")
|
|
|
|
|
|
class hotel_reservation_line(models.Model):
|
|
_name = "hotel.reservation.line"
|
|
_description = "Reservation Line"
|
|
|
|
def write(self, vals):
|
|
res = super(hotel_reservation_line, self).write(vals)
|
|
for ret in self:
|
|
if 'checkin' in vals or 'checkout' in vals:
|
|
ret.onchange_date_count_total_days()
|
|
return res
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals):
|
|
for val in vals:
|
|
checkin = val['checkin']
|
|
checkout = val['checkout']
|
|
if checkout and checkin > checkout:
|
|
raise UserError(
|
|
'Error! Departure date must be greater than Arrival Date')
|
|
so = super(hotel_reservation_line, self).create(val)
|
|
return so
|
|
|
|
@api.onchange('checkin', 'checkout')
|
|
# @api.depends('line_id.shop_id')
|
|
def onchange_date_count_total_days(self):
|
|
shop_id = None
|
|
if not self.checkin:
|
|
return False
|
|
if not self.checkout:
|
|
return False
|
|
|
|
current_date = datetime.today().date()
|
|
date_object = (self.checkout, '%Y-%m-%d %H:%M:%S')
|
|
|
|
if current_date != date_object:
|
|
if self.checkin >= self.checkout:
|
|
checkout = self.checkin
|
|
checkout += timedelta(days=1)
|
|
self.checkout = checkout
|
|
_logger.info("TYPE==>>>>%s", checkout)
|
|
|
|
if self.line_id:
|
|
shop_id = self.line_id.shop_id.id
|
|
_logger.info("SHOP ID===>>>>>>>>>>>>{}".format(shop_id))
|
|
if not shop_id:
|
|
raise UserError('Shop must be set before selection of room.')
|
|
policy_obj = self.env['checkout.configuration'].sudo().search(
|
|
[('shop_id', '=', shop_id)])
|
|
_logger.info("Policy OBJ===>>>>>>>>>>>>>>>>>>{}".format(policy_obj))
|
|
if not policy_obj:
|
|
raise UserError('Checkout policy is not define for selected Hotel.')
|
|
|
|
check_in = self.checkin
|
|
|
|
check_out = self.checkout
|
|
|
|
_logger.info("DAY COUNT====>>>>%s", check_in)
|
|
_logger.info("DAY COUNT====>>>>%s", check_out)
|
|
day_count1 = check_out - check_in
|
|
|
|
day_count2 = day_count1.total_seconds()
|
|
|
|
day_count2 = day_count2 / 86400
|
|
day_count2 = "{:.2f}".format(day_count2)
|
|
_logger.info("DIFFERENCE==>>>>>>>>>{}".format(day_count2))
|
|
day_count2 = math.ceil(float(day_count2))
|
|
|
|
_logger.info("DAY COUNT22===>>>>>>>>>>>>>>>>{}".format(day_count2))
|
|
|
|
self.number_of_days = day_count2
|
|
|
|
@api.onchange('room_number', 'checkin', 'checkout')
|
|
@api.depends('checkin', 'checkout', 'banquet_id.pricelist_id', 'banquet_id', 'line_id.partner_id', 'number_of_days',
|
|
'banquet_id.source')
|
|
def onchange_room_id(self):
|
|
v = {}
|
|
res_list = []
|
|
warning = ''
|
|
|
|
if self.room_number:
|
|
product_browse = self.room_number
|
|
product_id = product_browse.id
|
|
price = product_browse.lst_price
|
|
if price is False:
|
|
raise ValidationError("Couldn't find a pricelist line matching this product!")
|
|
pricelist = self.line_id.pricelist_id.id
|
|
|
|
ctx = self._context and self._context.copy() or {}
|
|
ctx.update({'date': self.checkin})
|
|
|
|
if pricelist:
|
|
price = self.env['product.pricelist'].with_context(ctx)._price_get(
|
|
self.room_number, self.number_of_days)[pricelist]
|
|
# price = self.env['product.pricelist'].with_context(ctx).price_get(
|
|
# self.room_number.id, self.number_of_days, {
|
|
# 'uom': product_browse.uom_id.id,
|
|
# 'date': self.checkin,
|
|
# })[pricelist]
|
|
|
|
v['price'] = price
|
|
tax_ids = []
|
|
for tax_line in product_browse.taxes_id:
|
|
tax_ids.append(tax_line.id)
|
|
v['taxes_id'] = [(6, 0, tax_ids)]
|
|
v['checkin'] = self.checkin
|
|
v['checkout'] = self.checkout
|
|
|
|
reservation_start_date = self.checkin
|
|
|
|
reservation_end_date = self.checkout
|
|
|
|
check_config = self.env['ir.model'].search([('model', '=', 'hotel.reservation.through.gds.configuration')])
|
|
if check_config:
|
|
config_id = self.env['hotel.reservation.through.gds.configuration'].search([])
|
|
config_browse = config_id
|
|
if config_browse and self.line_id.source != 'through_gds':
|
|
for record in config_browse:
|
|
config_start_date = record.name
|
|
|
|
config_end_date = record.to_date
|
|
config_start_date = datetime.strptime(str(config_start_date), '%Y-%m-%d %H:%M:%S')
|
|
config_end_date = datetime.strptime(str(config_end_date), '%Y-%m-%d %H:%M:%S')
|
|
|
|
if (config_start_date <= reservation_start_date < config_end_date) or (
|
|
config_start_date < reservation_end_date <= config_end_date) or (
|
|
(reservation_start_date < config_start_date) and (
|
|
reservation_end_date > config_end_date)):
|
|
for line in record.line_ids:
|
|
room_list = []
|
|
for room in line.room_number:
|
|
room_list.append(room.id)
|
|
if self.room_number.id in room_list:
|
|
raise UserError("Room is reserved in this period for GDS reservation!")
|
|
|
|
room_line_id = self.env['hotel.room'].search([('product_id', '=', product_id)])
|
|
|
|
housekeeping_room = self.env['hotel.housekeeping'].search([('room_no', '=', room_line_id.product_id.id)])
|
|
if housekeeping_room:
|
|
for house1 in housekeeping_room:
|
|
house = house1
|
|
house_current_date = house.current_date
|
|
house_current_date = datetime.combine(house_current_date, datetime.min.time())
|
|
house_current_date = datetime.strptime(str(house_current_date), '%Y-%m-%d %H:%M:%S')
|
|
|
|
house_end_date = house.end_date
|
|
house_end_date = datetime.combine(house_end_date, datetime.min.time())
|
|
house_end_date = datetime.strptime(str(house_end_date), '%Y-%m-%d %H:%M:%S')
|
|
|
|
start_reser = self.checkin
|
|
end_reser = self.checkout
|
|
|
|
if (((start_reser < house_current_date) and (end_reser > house_end_date)) or (
|
|
house_current_date <= start_reser < house_end_date) or (
|
|
house_current_date < end_reser <= house_end_date)) and (house.state == 'dirty'):
|
|
raise UserError("Warning! Room %s is not clean for reservation period !" % (room_line_id.name))
|
|
|
|
if room_line_id.room_folio_ids:
|
|
for history in room_line_id.room_folio_ids:
|
|
if history.state == 'done':
|
|
history_start_date = history.check_in
|
|
history_end_date = history.check_out
|
|
|
|
room_line_id = self.env['hotel.room'].search([('product_id', '=', product_id)])
|
|
housekeeping_room = self.env['hotel.housekeeping'].search([
|
|
('room_no', '=', room_line_id.product_id.id), ('state', '=', 'dirty')])
|
|
if housekeeping_room:
|
|
for house1 in housekeeping_room:
|
|
house = house1
|
|
house_current_date = (datetime.strptime(str(house.current_date), '%Y-%m-%d')).date()
|
|
house_end_date = (datetime.strptime(str(house.end_date), '%Y-%m-%d')).date()
|
|
start_reser = datetime.strptime(str(self.checkin), '%Y-%m-%d %H:%M:%S').date()
|
|
end_reser = datetime.strptime(str(self.checkout), '%Y-%m-%d %H:%M:%S').date()
|
|
if (house_current_date <= start_reser <= house_end_date) or (
|
|
house_current_date <= end_reser <= house_end_date) or (
|
|
(start_reser < house_current_date) and (end_reser > house_end_date)):
|
|
raise UserError("Room %s is not clean for reservation period !" % (
|
|
room_line_id.name))
|
|
|
|
if (history_start_date <= reservation_start_date < history_end_date) or (
|
|
history_start_date < reservation_end_date <= history_end_date) or (
|
|
(reservation_start_date < history_start_date) and (
|
|
reservation_end_date > history_end_date)):
|
|
if not (self.line_id.id == history.booking_id.id):
|
|
raise UserError("Room %s is booked in this reservation period !" % (room_line_id.name))
|
|
return {'value': v, 'warning': warning}
|
|
|
|
@api.depends('number_of_days', 'discount', 'price', 'taxes_id')
|
|
def count_sub_total1(self):
|
|
for line in self:
|
|
tax_amount = 0
|
|
price = line.price * (1 - (line.discount or 0.0) / 100.0)
|
|
taxes = line.taxes_id.compute_all(price, line.line_id.currency_id, line.number_of_days,
|
|
product=line.room_number,
|
|
partner=line.line_id.partner_id)
|
|
for tax in taxes['taxes']:
|
|
tax_amount = tax_amount + tax['amount']
|
|
line.update({
|
|
'sub_total1': taxes['total_excluded'],
|
|
})
|
|
|
|
currency_id = fields.Many2one(
|
|
related='line_id.currency_id', store=True, string='Currency', readonly=True)
|
|
line_id = fields.Many2one('hotel.reservation')
|
|
room_number = fields.Many2one('product.product', 'Room Number',
|
|
domain="[('isroom','=',True),('categ_id','=',categ_id)]",
|
|
help="Will list out all the rooms that belong to selected shop.", required=True)
|
|
categ_id = fields.Many2one('product.category', 'Room Type', required=True, )
|
|
price = fields.Float("Price")
|
|
discount = fields.Float('Discount (%)', digits=(16, 2))
|
|
number_of_days = fields.Integer(string="Number Of Days", default=1)
|
|
sub_total1 = fields.Float(
|
|
string='Sub Total', store=True, readonly=True, compute='count_sub_total1', compute_sudo=False)
|
|
taxes_id = fields.Many2many('account.tax', 'reservation_taxes_rel', 'prod_id', 'tax_id', 'Taxes', domain=[
|
|
('type_tax_use', 'in', ['sale', 'all'])])
|
|
checkin = fields.Datetime('Checkin Date', required=True, default=lambda self: fields.Datetime.now())
|
|
checkout = fields.Datetime('Checkout Date', required=True, )
|
|
company_id = fields.Many2one(related='line_id.company_id', comodel_name='res.company', string='Company', store=True)
|
|
|
|
@api.model
|
|
def default_get(self, default_fields):
|
|
# _logger.info("USER===>>>>>>>>>>>{}".format(self.env.user))
|
|
_logger.info("\n\n\n\nSELF CONTEXT===>>>>>>>>>>>>>{}".format(self._context))
|
|
if self.env.user.id == 4:
|
|
user_id = self.env['res.users'].search([('id', '=', 2)])
|
|
else:
|
|
user_id = self.env.user
|
|
|
|
# _logger.info("TZ===>>>>>>>>>>>>>>>{}".format(user_id.tz))
|
|
tz = pytz.timezone(user_id.tz)
|
|
time_difference = tz.utcoffset(utc_time).total_seconds()
|
|
|
|
# _logger.info("TIME DIFFERENCE===>>>>>>>>>>>>>>>>>>{}".format(time_difference))
|
|
|
|
vals = super(hotel_reservation_line, self).default_get(default_fields)
|
|
# _logger.info("VALS===>>>>>>>>>>>>>>>>{}".format(self.room_number))
|
|
tax_ids = []
|
|
if self.room_number:
|
|
for tax_line in self.room_number.taxes_id:
|
|
tax_ids.append(tax_line.id)
|
|
|
|
_logger.info("TAXES ID===>>>>>>>>>>>>>>{}".format(tax_ids))
|
|
|
|
if self._context.get('shop_id'):
|
|
sale_shop_id = self.env['sale.shop'].search([('id', '=', self._context.get('shop_id'))])
|
|
_logger.info("SALE SHOP===>>>>>{}".format(sale_shop_id))
|
|
checkout_policy_id = self.env['checkout.configuration'].search(
|
|
[('shop_id', '=', self._context.get('shop_id'))])
|
|
if len(checkout_policy_id) > 1:
|
|
raise ValidationError('It looks like you have setup multiple checkout policy for one shop.\nPlease check the configuration.')
|
|
# _logger.info("Checkout Policy===>>>{}".format(checkout_policy_id))
|
|
|
|
if checkout_policy_id.name == 'custom':
|
|
time = int(checkout_policy_id.time)
|
|
if vals.get('checkin'):
|
|
checkin = vals.get('checkin')
|
|
checkin = datetime(checkin.year, checkin.month, checkin.day)
|
|
checkout_date = checkin + timedelta(days=1)
|
|
checkout = checkout_date + timedelta(hours=00, minutes=00, seconds=00)
|
|
|
|
to_string = fields.Datetime.to_string(checkout)
|
|
# _logger.info("TO STRING====>>>>{}".format(to_string))
|
|
from_string = fields.Datetime.from_string(to_string)
|
|
# _logger.info("FROM STRING====>>>>{}".format(from_string))
|
|
|
|
checkout = from_string
|
|
checkout = checkout + timedelta(hours=time)
|
|
checkout = checkout - timedelta(seconds=time_difference)
|
|
|
|
# _logger.info("\n\n\n\n\nVALS=====>>>>>>>>>>>>>>>>>>{}".format(checkout))
|
|
vals.update({'checkout': checkout})
|
|
|
|
elif self._context.get('checkin'):
|
|
|
|
checkin = self._context.get('checkin')
|
|
check_in_from_string = fields.Datetime.from_string(self._context.get('checkin'))
|
|
checkin = datetime(check_in_from_string.year, check_in_from_string.month, check_in_from_string.day)
|
|
checkin = checkin + timedelta(hours=int(time))
|
|
|
|
checkout = self._context.get('checkout')
|
|
checkout_from_string = fields.Datetime.from_string(self._context.get('checkout'))
|
|
checkout = datetime(checkout_from_string.year, checkout_from_string.month, checkout_from_string.day)
|
|
checkout = checkout + timedelta(hours=int(time))
|
|
|
|
checkout = checkout - timedelta(seconds=time_difference)
|
|
checkin = checkin - timedelta(seconds=time_difference)
|
|
|
|
vals.update({'checkout': checkout, 'checkin': checkin})
|
|
|
|
else:
|
|
if vals.get('checkin'):
|
|
checkin = vals.get('checkin')
|
|
checkout_date = checkin + timedelta(days=1)
|
|
checkout = checkout_date
|
|
_logger.info("CHECKOUT ====>>>>>>>>>>>{}".format(checkout_date))
|
|
vals.update({'checkout': checkout, })
|
|
if tax_ids:
|
|
vals.update({'taxes_id': [(6, 0, tax_ids)]})
|
|
_logger.info("\n\n\n\n\n\n\n\nVals====>>>>>>>>>>>>>>>>>>>>{}".format(vals))
|
|
return vals
|
|
|
|
def _get_display_price(self, product):
|
|
# TO DO: move me in master/saas-16 on sale.order
|
|
# awa: don't know if it's still the case since we need the "product_no_variant_attribute_value_ids" field now
|
|
# to be able to compute the full price
|
|
|
|
# it is possible that a no_variant attribute is still in a variant if
|
|
# the type of the attribute has been changed after creation.
|
|
# no_variant_attributes_price_extra = [
|
|
# ptav.price_extra for ptav in self.product_no_variant_attribute_value_ids.filtered(
|
|
# lambda ptav:
|
|
# ptav.price_extra and
|
|
# ptav not in product.product_template_attribute_value_ids
|
|
# )
|
|
# ]
|
|
# if no_variant_attributes_price_extra:
|
|
# product = product.with_context(
|
|
# no_variant_attributes_price_extra=tuple(
|
|
# no_variant_attributes_price_extra)
|
|
# )
|
|
|
|
if self.line_id.pricelist_id.discount_policy == 'with_discount':
|
|
|
|
return product.with_context(pricelist=self.line_id.pricelist_id.id).price
|
|
product_context = dict(self.env.context, partner_id=self.line_id.partner_id.id,
|
|
date=self.line_id.date_order)
|
|
|
|
final_price, rule_id = self.line_id.pricelist_id.with_context(product_context).get_product_price_rule(
|
|
product or self.product_id, self.product_uom_qty or 1.0, self.line_id.partner_id)
|
|
base_price, currency = self.with_context(product_context)._get_real_price_currency(
|
|
product, rule_id, self.product_uom_qty, self.line_id.pricelist_id.id)
|
|
if currency != self.line_id.pricelist_id.currency_id:
|
|
base_price = currency._convert(
|
|
base_price, self.line_id.pricelist_id.currency_id,
|
|
self.line_id.company_id or self.env.company, self.line_id.date_order or fields.Date.today())
|
|
# negative discounts (= surcharge) are included in the display price
|
|
return max(base_price, final_price)
|
|
|
|
|
|
class hotel_room(models.Model):
|
|
_inherit = "hotel.room"
|
|
_description = "room Inherit "
|
|
|
|
room_folio_ids = fields.One2many(
|
|
"hotel.room.booking.history", "history_id", "Room Rental History", copy=False)
|
|
|
|
@api.onchange('shop_id')
|
|
def on_change_shop_id(self):
|
|
if not self.shop_id:
|
|
return {'value': {}}
|
|
temp = self.shop_id
|
|
self.company_id = temp.company_id.id
|
|
|
|
|
|
class hotel_room_booking_history(models.Model):
|
|
_name = "hotel.room.booking.history"
|
|
_description = "Hotel Room Booking History"
|
|
|
|
product_id = fields.Integer("Product ID", readonly=True)
|
|
history_id = fields.Many2one("hotel.room", "Room No", readonly=True)
|
|
name = fields.Char('Product Name', readonly=True, required=True)
|
|
category_id = fields.Many2one(
|
|
"product.category", "room category", readonly=True)
|
|
check_in = fields.Datetime('CheckIn Date', readonly=True)
|
|
check_out = fields.Datetime('CheckOut Date', readonly=True)
|
|
check_in_date = fields.Date('Check In Date', readonly=True)
|
|
check_out_date = fields.Date('Check Out Date', readonly=True)
|
|
partner_id = fields.Many2one('res.partner', "Partner Name", readonly=True)
|
|
booking_id = fields.Many2one(
|
|
'hotel.reservation', "Booking Ref", readonly=True)
|
|
state = fields.Selection([('draft', 'Draft'), ('confirm', 'Confirm'),
|
|
('cancle', 'Cancel'), ('done', 'Done')], 'State', readonly=True)
|
|
company_id = fields.Many2one(
|
|
'res.company', string='Company', default=lambda self: self.env.user.company_id)
|
|
|
|
|
|
class hotel_food_line(models.Model):
|
|
_name = 'hotel_food.line'
|
|
_description = 'hotel Food line'
|
|
_inherits = {'sale.order.line': 'food_line_id'}
|
|
|
|
food_line_id = fields.Many2one(
|
|
'sale.order.line', 'food_line_id', required=True, ondelete='cascade')
|
|
folio_id = fields.Many2one('hotel.folio', 'folio_id', ondelete='cascade')
|
|
source_origin = fields.Char('Source Origin')
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
_logger.info("VALS====>>>>>>>{}".format(vals_list))
|
|
for rec in vals_list:
|
|
folio = self.env["hotel.folio"].browse([rec['folio_id']])
|
|
# if "product_id" in vals.keys():
|
|
# self.env["product.product"].browse(
|
|
# vals['product_id']).write({'state': 'sellable'})
|
|
rec.update({'order_id': folio.order_id.id})
|
|
res = super(hotel_food_line, self).create(vals_list)
|
|
return res
|
|
|
|
@api.onchange('product_id')
|
|
def product_id_change(self):
|
|
if self.product_id:
|
|
self.product_uom = self.product_id.uom_id
|
|
self.price_unit = self.product_id.lst_price
|
|
self.name = self.product_id.description_sale
|
|
|
|
|
|
class hotel_folio(models.Model):
|
|
_inherit = "hotel.folio"
|
|
_description = "Hotel Folio"
|
|
|
|
state = fields.Selection(
|
|
selection=[
|
|
('draft', "Quotation"),
|
|
('sent', "Quotation Sent"),
|
|
('sale', "Sales Order"),
|
|
('progress', "Progress"),
|
|
('check_out', 'Check Out'),
|
|
('done', "Locked"),
|
|
('cancel', "Cancelled"),
|
|
],
|
|
string="Status",
|
|
readonly=True, copy=False, index=True,
|
|
tracking=3,
|
|
default='draft')
|
|
|
|
def unlink(self):
|
|
for rec in self:
|
|
if rec.state not in ['sale', 'done']:
|
|
res = super(hotel_folio, rec).unlink()
|
|
else:
|
|
raise UserError("Folio Cannot be Deleted once it is Confirm")
|
|
return res
|
|
|
|
@api.depends('amount_total', )
|
|
def _get_advance_payment(self):
|
|
|
|
sum = 0.00
|
|
remaining = 0.00
|
|
for obj in self:
|
|
obj.update({
|
|
'total_advance': 0.0,
|
|
'remaining_amt': 0.0,
|
|
})
|
|
sum = 0
|
|
|
|
for line in obj.account_move_ids:
|
|
move_lines = self.env['account.move.line'].search(
|
|
[('move_id', '=', line.id)])
|
|
if move_lines:
|
|
for mv in move_lines:
|
|
sum = sum + mv.debit
|
|
obj.update({
|
|
'total_advance': sum,
|
|
'remaining_amt': obj.amount_total - sum
|
|
})
|
|
|
|
total_advance = fields.Float(
|
|
compute="_get_advance_payment", string="Total Advance Payment", )
|
|
remaining_amt = fields.Float(
|
|
compute="_get_advance_payment", string="Total Remaining Amount", )
|
|
|
|
account_move_ids = fields.Many2many('account.move', 'sale_account_move_rel', 'sale_id', 'move_id',
|
|
"Payment Details")
|
|
is_agent_commission_created = fields.Boolean('Is Agent Commission Created')
|
|
|
|
def _rooms_reference(self):
|
|
for order in self:
|
|
order_ref = ''
|
|
for line in order.room_lines:
|
|
if line.product_id:
|
|
order_ref += line.product_id.name + ','
|
|
if order_ref and order_ref[-1] == ',':
|
|
order.update({
|
|
'rooms_ref': order_ref[:-1],
|
|
'rooms_ref1': order_ref[:-1],
|
|
})
|
|
else:
|
|
order.update({
|
|
'rooms_ref': order_ref,
|
|
'rooms_ref1': order_ref,
|
|
})
|
|
|
|
transport_line_ids = fields.One2many(
|
|
'hotel_folio_transport.line', 'folio_id')
|
|
laundry_line_ids = fields.One2many(
|
|
'hotel_folio_laundry.line', 'folio_id', 'Folio Ref')
|
|
|
|
reservation_id = fields.Many2one('hotel.reservation', 'Reservation Ref')
|
|
laundry_invoice_ids = fields.Many2many(
|
|
'account.move', 'laundry_folio_invoice_rel', 'folio_id', 'invoice_id', 'Laundry Related Invoices',
|
|
readonly=True)
|
|
transport_invoice_ids = fields.Many2many(
|
|
'account.move', 'transport_folio_invoice_rel', 'folio_id', 'invoice_id', 'Transport Related Invoices',
|
|
readonly=True)
|
|
id_line_ids = fields.One2many(
|
|
'hotel.resv.id.details', 'folio_id', 'ID Line')
|
|
food_lines = fields.One2many('hotel_food.line', 'folio_id')
|
|
rooms_ref = fields.Char(compute="_rooms_reference", string="Room No", compute_sudo=False)
|
|
rooms_ref1 = fields.Char(compute="_rooms_reference", compute_sudo=False,
|
|
string="Room Number")
|
|
|
|
|
|
def advance_payment(self):
|
|
reservation = self
|
|
res_id = reservation.reservation_id
|
|
data_obj = self.env['ir.model.data'].sudo().search([('name', '=', 'advance_payment_wizard1')])
|
|
data_id = data_obj.id
|
|
view_id1 = False
|
|
if self._context is None:
|
|
self._context = {}
|
|
ctx = dict(self._context)
|
|
ctx['active_ids'] = [reservation.id]
|
|
ctx['reservation_id'] = res_id.id
|
|
if data_id:
|
|
view_id1 = data_obj.browse(data_id).res_id
|
|
value = {
|
|
'name': _('Deposit amount entry'),
|
|
'view_type': 'form',
|
|
'view_mode': 'form',
|
|
'res_model': 'advance.payment.wizard',
|
|
'view_id': False,
|
|
'context': ctx,
|
|
'views': [(view_id1, 'form')],
|
|
'type': 'ir.actions.act_window',
|
|
'target': 'new',
|
|
'nodestroy': True
|
|
}
|
|
return value
|
|
|
|
# @api.multi
|
|
def action_checkout(self):
|
|
folio = self.browse(self._ids)[0]
|
|
for room in folio.room_lines:
|
|
sdate = room.checkout_date
|
|
housekeeping_id = self.env['hotel.housekeeping'].create({
|
|
'current_date': sdate,
|
|
'end_date': (sdate + timedelta(1)).date(),
|
|
'clean_type': 'checkout',
|
|
'room_no': room.product_id.id,
|
|
'inspector': self._uid,
|
|
'inspect_date_time': sdate + timedelta(1),
|
|
'state': 'dirty',
|
|
'quality': 'clean',
|
|
})
|
|
self.reservation_id.status = 'checkout'
|
|
self.write({'state': 'check_out'})
|
|
return True
|
|
|
|
# @api.multi
|
|
def action_done(self):
|
|
for line in self:
|
|
# for invoice in line.invoice_ids:
|
|
# if (invoice.partner_id.id == line.partner_id.id) and invoice.payment_state not in ['paid',
|
|
# 'in_payment']:
|
|
# raise UserError('Invoice is not paid !')
|
|
for invoice in line.transfer_invoice_ids:
|
|
if invoice.payment_state != 'paid':
|
|
raise UserError('Transfer Invoice is not paid !')
|
|
self.write({'state': 'done'})
|
|
return True
|
|
|
|
# @api.multi
|
|
def action_cancel(self):
|
|
today = time.strftime('%Y-%m-%d %H:%M:%S')
|
|
today = datetime.strptime(str(today), '%Y-%m-%d %H:%M:%S')
|
|
for obj in self:
|
|
for room_id in obj.room_lines:
|
|
if room_id.checkin_date <= today:
|
|
if obj.order_reserve_invoice_ids:
|
|
raise UserError(
|
|
'Error ! Invoice has been created, so You can not delete this record!')
|
|
if obj.table_order_invoice_ids:
|
|
raise UserError(
|
|
'Error ! Invoice has been created, so You can not delete this record!')
|
|
if obj.invoice_ids:
|
|
raise UserError(
|
|
'Error ! Invoice has been created, so You can not delete this record!')
|
|
if obj.picking_ids:
|
|
raise UserError(
|
|
'Error !', 'Invoice has been created, so You can not delete this record!')
|
|
|
|
so = super(hotel_folio, self).action_cancel()
|
|
for room in obj.room_lines:
|
|
room_line_id = self.env['hotel.room'].search(
|
|
[('product_id', '=', room.product_id.id)])
|
|
history_obj = self.env['hotel.room.booking.history'].search([
|
|
('history_id', '=', room_line_id.id), ('booking_id', '=', obj.reservation_id.id)])
|
|
if history_obj:
|
|
history_browse = history_obj
|
|
history_browse.unlink()
|
|
return so
|
|
|
|
# @api.multi
|
|
def action_wait(self, cr, uid, ids, context=None):
|
|
for obj in self.browse(cr, uid, ids, context):
|
|
if (not obj.invoice_ids):
|
|
self.write(cr, uid, [obj.id], {'state': 'manual'})
|
|
else:
|
|
self.write(cr, uid, [obj.id], {'state': 'progress'})
|
|
today = time.strftime('%Y-%m-%d')
|
|
if obj.reservation_id.id:
|
|
self.pool.get('hotel.reservation').compute(
|
|
cr, uid, [obj.reservation_id.id])
|
|
for room in obj.room_lines:
|
|
room_line_id = self.pool.get('hotel.room').search(
|
|
cr, uid, [('product_id', '=', room.product_id.id)])
|
|
room_line_browse = self.pool.get(
|
|
'hotel.room').browse(cr, uid, room_line_id)
|
|
history_obj = self.pool.get('hotel.room.booking.history').search(cr, uid, [
|
|
('history_id', '=', room_line_browse[0].id), ('booking_id', '=', obj.reservation_id.id)])
|
|
if history_obj:
|
|
history_browse = self.pool.get(
|
|
'hotel.room.booking.history').browse(cr, uid, history_obj)
|
|
self.pool.get('hotel.room.booking.history').write(cr, uid, history_browse[0].id, {
|
|
'check_in': room.checkin_date, 'check_out': room.checkout_date,
|
|
'check_in_date': room.checkin_date[0:10],
|
|
'check_out_date': room.checkout_date[0:10]})
|
|
return {}
|
|
|
|
# @api.multi
|
|
def print_relatedinvoice(self, cr, uid, ids, context=None):
|
|
'''
|
|
This function prints the sales order and mark it as sent, so that we can see more easily the next step of the workflow
|
|
'''
|
|
id_list = []
|
|
assert len(
|
|
ids) == 1, 'This option should only be used for a single id at a time'
|
|
for obj in self.browse(cr, uid, ids, context={}):
|
|
if obj.invoice_ids:
|
|
for invoice_id in obj.invoice_ids:
|
|
id_list.append(invoice_id.id)
|
|
if obj.laundry_invoice_ids:
|
|
for invoice_id in obj.laundry_invoice_ids:
|
|
id_list.append(invoice_id.id)
|
|
if obj.transport_invoice_ids:
|
|
for invoice_id in obj.transport_invoice_ids:
|
|
id_list.append(invoice_id.id)
|
|
if obj.order_reserve_invoice_ids:
|
|
for invoice_id in obj.order_reserve_invoice_ids:
|
|
id_list.append(invoice_id.id)
|
|
if obj.table_order_invoice_ids:
|
|
for invoice_id in obj.table_order_invoice_ids:
|
|
id_list.append(invoice_id.id)
|
|
datas = {
|
|
'model': 'account.move',
|
|
'ids': id_list,
|
|
'form': self.pool.get('account.move').read(cr, uid, id_list, context=context),
|
|
}
|
|
return {'type': 'ir.actions.report.xml', 'report_name': 'account.move', 'datas': datas, 'nodestroy': True}
|
|
|
|
# @api.multi
|
|
def update_folio_history(self):
|
|
tax_ids = []
|
|
folio = self
|
|
if not folio.room_lines:
|
|
raise ValidationError("Rooms line Details are missing.")
|
|
book_search = self.env['hotel.room.booking.history'].search(
|
|
[('booking_id', '=', folio.reservation_id.id)])
|
|
if book_search:
|
|
# self.env['hotel.room.booking.history'].unlink(book_search)
|
|
book_search.unlink()
|
|
if folio.reservation_id.reservation_line:
|
|
# print
|
|
# "folio.reservation_id.reservation_line=======================================",folio.reservation_id.reservation_line
|
|
for res_line in folio.reservation_id.reservation_line:
|
|
res_line.unlink()
|
|
for folio_line in folio.room_lines:
|
|
#
|
|
for tax_line in folio_line.tax_id:
|
|
tax_ids.append(tax_line.id)
|
|
res_line_id = self.env['hotel.reservation.line'].create({
|
|
'checkin': folio_line.checkin_date,
|
|
'checkout': folio_line.checkout_date,
|
|
'categ_id': folio_line.categ_id.id,
|
|
'room_number': folio_line.product_id.id,
|
|
'line_id': folio.reservation_id.id,
|
|
'shop_id': folio.shop_id.id,
|
|
'price': folio_line.price_unit,
|
|
'discount': folio_line.discount,
|
|
'taxes_id': [(6, 0, tax_ids)],
|
|
'number_of_days': folio_line.product_uom_qty,
|
|
})
|
|
tax_ids = []
|
|
room_line_id = self.env['hotel.room'].search(
|
|
[('product_id', '=', folio_line.product_id.id)])
|
|
room_his_id = self.env['hotel.room.booking.history'].create({
|
|
'partner_id': folio.partner_id.id,
|
|
'check_in': folio_line.checkin_date,
|
|
'check_out': folio_line.checkout_date,
|
|
'history_id': room_line_id.id,
|
|
'product_id': folio_line.product_id.id,
|
|
'booking_id': folio.reservation_id.id,
|
|
'state': 'done',
|
|
'category_id': folio_line.categ_id.id,
|
|
'name': folio_line.product_id.name,
|
|
'check_in_date': str(folio_line.checkin_date)[0:10],
|
|
'check_out_date': str(folio_line.checkout_date)[0:10],
|
|
})
|
|
return True
|
|
|
|
def write(self, vals):
|
|
res = super(hotel_folio, self).write(vals)
|
|
if 'state' in vals and vals['state'] == 'sale':
|
|
if self.room_lines:
|
|
for rec in self.room_lines:
|
|
rec.on_change_checkout()
|
|
return res
|
|
|
|
|
|
class hotel_folio_line(models.Model):
|
|
_inherit = 'hotel_folio.line'
|
|
_description = 'hotel folio1 room line'
|
|
|
|
_s = {'sale.order.line': 'order_line_id'}
|
|
|
|
hotel_reservation_line_id = fields.Many2one(
|
|
'hotel.reservation.line', 'hotel reservation line id=')
|
|
state = fields.Selection(
|
|
selection=[
|
|
('draft', "Quotation"),
|
|
('sent', "Quotation Sent"),
|
|
('sale', "Sales Order"),
|
|
('progress', "Progress"),
|
|
('check_out', 'Check Out'),
|
|
('done', "Locked"),
|
|
('cancel', "Cancelled"),
|
|
],
|
|
string="Status",
|
|
readonly=True, copy=False, index=True,
|
|
tracking=3,
|
|
default='draft')
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals):
|
|
for val in vals:
|
|
checkin = val['checkin_date']
|
|
checkout = val['checkout_date']
|
|
if checkout and checkin > checkout:
|
|
raise UserError(
|
|
'Error! Departure date must be greater than Arrival Date')
|
|
return super(hotel_folio_line, self).create(val)
|
|
|
|
@api.onchange('product_id', 'checkin_date', 'checkout_date')
|
|
@api.depends('folio_id.pricelist_id', 'checkin_date', 'checkout_date', 'folio_id.partner_id', 'product_uom_qty',
|
|
'parent_id')
|
|
def onchange_product_id(self):
|
|
if self.checkout_date and self.checkin_date > self.checkout_date:
|
|
return {'warning': {'title': "Error", 'message': "Departure date must be greater than Arrival Date"}, }
|
|
|
|
v = {}
|
|
warning = ''
|
|
if not self.folio_id.pricelist_id:
|
|
raise ValidationError("PriceList is not Selected !")
|
|
# if not (self.checkin_date and self.checkout_date):
|
|
# raise UserError(
|
|
# "Please Select Expected-Date-Arrival and Expected-Date-Departure before selecting room number!")
|
|
date = str(self.checkin_date)[0:10]
|
|
if self.product_id:
|
|
product_browse = self.product_id
|
|
price = product_browse.lst_price
|
|
if price is False:
|
|
raise ValidationError(
|
|
"Couldn't find a pricelist line matching this product!2")
|
|
|
|
v['price'] = price
|
|
tax_ids = []
|
|
for tax_line in product_browse.taxes_id:
|
|
tax_ids.append(tax_line.id)
|
|
v['taxes_id'] = [(6, 0, tax_ids)]
|
|
v['checkin'] = self.checkin_date
|
|
v['checkout'] = self.checkout_date
|
|
room_line_id = self.env['hotel.room'].search(
|
|
[('product_id', '=', self.product_id.id)])
|
|
|
|
#############################Added by Pornima######################
|
|
housekeeping_room = self.env['hotel.housekeeping'].search([
|
|
('room_no', '=', room_line_id.product_id.id), ('state', '=', 'dirty')])
|
|
# print
|
|
# "housekeeping_room--------------------------------------------------------------------",housekeeping_room
|
|
if housekeeping_room:
|
|
for house1 in housekeeping_room:
|
|
house = house1
|
|
|
|
house_current_date = (datetime.strptime(
|
|
str(house.current_date), '%Y-%m-%d')).date()
|
|
house_end_date = (datetime.strptime(
|
|
str(house.end_date), '%Y-%m-%d')).date()
|
|
start_reser = datetime.strptime(
|
|
str(self.checkin_date), '%Y-%m-%d %H:%M:%S').date()
|
|
end_reser = datetime.strptime(
|
|
str(self.checkout_date), '%Y-%m-%d %H:%M:%S').date()
|
|
if (house_current_date <= start_reser <= house_end_date) or (
|
|
house_current_date <= end_reser <= house_end_date) or (
|
|
(start_reser < house_current_date) and (end_reser > house_end_date)):
|
|
raise UserError("Room %s is not clean for reservation period !" % (
|
|
room_line_id.name))
|
|
|
|
###################################################################
|
|
|
|
if room_line_id.room_folio_ids:
|
|
for history in room_line_id.room_folio_ids:
|
|
if history.state == 'done' and history.booking_id.id != self.folio_id.reservation_id.id:
|
|
history_start_date = history.check_in
|
|
history_end_date = history.check_out
|
|
reservation_start_date = self.checkin_date
|
|
reservation_end_date = self.checkout_date
|
|
if (history_start_date <= reservation_start_date < history_end_date) or (
|
|
history_start_date < reservation_end_date <= history_end_date) or (
|
|
(reservation_start_date < history_start_date) and (
|
|
reservation_end_date > history_end_date)):
|
|
# self.folio_id, history.booking_id.id)
|
|
if not (self.folio_id.id == history.booking_id.id):
|
|
raise UserError(
|
|
"Room %s is booked in this reservation period !" % (room_line_id.name,))
|
|
v['product_uom'] = product_browse.uom_id.id
|
|
v['name'] = product_browse.name
|
|
v['price_unit'] = product_browse.list_price
|
|
return {'value': v}
|
|
|
|
def unlink(self):
|
|
booking_history_obj = self.env['hotel.room.booking.history']
|
|
for categ in self:
|
|
room_id = self.env['hotel.room'].search(
|
|
[('product_id', '=', categ.product_id.id)])
|
|
reservation_line = categ.hotel_reservation_line_id
|
|
booking_history_id = booking_history_obj.search([('booking_id', '=', reservation_line.line_id.id),
|
|
('hostory_id', '=', room_id.id)])
|
|
booking_history_id.unlink()
|
|
reservation_line.unlink()
|
|
categ.order_line_id.unlink()
|
|
return super(hotel_folio_line, self).unlink()
|
|
|
|
def write(self, vals):
|
|
room_book_history_obj = self.env['hotel.room.booking.history']
|
|
for folio_line in self:
|
|
room_id = self.env['hotel.room'].search(
|
|
[('product_id', '=', folio_line.product_id.id)])
|
|
booking_history_rec = room_book_history_obj.search(
|
|
[('booking_id', '=', folio_line.folio_id.reservation_id.id),
|
|
('history_id', '=', room_id.id)])
|
|
history_vals = {
|
|
'partner_id': folio_line.folio_id.reservation_id.partner_id.id,
|
|
'check_in': folio_line.checkin_date,
|
|
'check_out': folio_line.checkout_date,
|
|
'product_id': folio_line.product_id.id,
|
|
'booking_id': folio_line.folio_id.reservation_id.id,
|
|
'state': 'done',
|
|
'check_in_date': folio_line.checkin_date,
|
|
'check_out_date': folio_line.checkout_date,
|
|
}
|
|
|
|
history_vals.update({'history_id': room_id.id,
|
|
'category_id': room_id.categ_id.id, # room_line_id.categ_id.id,
|
|
'name': room_id.name, })
|
|
if not booking_history_rec:
|
|
room_book_history_obj.create(history_vals)
|
|
else:
|
|
booking_history_rec.write(history_vals)
|
|
return super(hotel_folio_line, self).write(vals)
|
|
|
|
class hotel_service_line(models.Model):
|
|
_inherit = 'hotel_service.line'
|
|
_description = 'hotel Service line'
|
|
_s = {'sale.order.line': 'service_line_id'}
|
|
|
|
@api.onchange('product_id')
|
|
def onchange_product_id(self):
|
|
v = {}
|
|
if self.product_id:
|
|
date = time.strftime('%Y-%m-%d')
|
|
self.product_uom = self.product_id.uom_id.id
|
|
self.name = self.product_id.name if not self.product_id.description_sale else self.product_id.description_sale
|
|
_logger.info('------------- {} {}'.format(self.name, self.product_id.name))
|
|
tax_ids = []
|
|
for tax_line in self.product_id.taxes_id:
|
|
tax_ids.append(tax_line.id)
|
|
self.tax_id = [(6, 0, tax_ids)]
|
|
self.product_uom_qty = 1
|
|
self.price_unit = self.product_id.lst_price
|
|
# return {'value': v}
|
|
|
|
|
|
class hotel_restaurant_tables(models.Model):
|
|
_inherit = "hotel.restaurant.tables"
|
|
_description = "Includes Hotel Restaurant Table"
|
|
|
|
name = fields.Char('Table number', required=True)
|
|
capacity = fields.Integer('Capacity')
|
|
shop_id = fields.Many2one('sale.shop', 'Hotel',domain="[('company_id', '=', [current_company_id])]",
|
|
help="Will show list of shop that belongs to allowed companies of logged-in user. \n -Assigning shop name to which this table no belongs to.")
|
|
avl_state = fields.Selection([('available', 'Available'), ('book', 'Booked')], 'Availability Status',
|
|
default='available', index=True, required=True)
|
|
state = fields.Selection(selection_add=[('draft', 'Draft'), ('edit', 'Edit'), ('confirmed', 'Confirmed'), (
|
|
'canceled', 'Cancel')], string='State', required=True, readonly=True,
|
|
ondelete={'draft': 'set default', 'edit': 'set default', 'confirmed': 'set default',
|
|
'canceled': 'set default'})
|
|
|
|
company_id = fields.Many2one(
|
|
'res.company', related='shop_id.company_id', string='Company', store=True)
|
|
|
|
def confirm(self):
|
|
self.write({'state': 'confirmed'})
|
|
return True
|
|
|
|
def cancel_supplier(self):
|
|
self.write({'state': 'cancel'})
|
|
return True
|
|
|
|
def update_record(self):
|
|
self.write({'state': 'edit'})
|
|
return True
|
|
|
|
|
|
class hotel_restaurant_order(models.Model):
|
|
_inherit = "hotel.restaurant.order"
|
|
_description = "Includes Hotel Restaurant Order"
|
|
|
|
def domain_change(self):
|
|
new_ids = []
|
|
room_lines = self.env['hotel.folio'].search([('state', '=', 'draft')]).mapped('room_lines')
|
|
for rec in room_lines:
|
|
if rec.product_id:
|
|
room_id = self.env['hotel.room'].search([('product_id', '=', rec.product_id.id)])
|
|
if room_id:
|
|
new_ids.append(room_id.id)
|
|
return [('id', 'in', new_ids)]
|
|
|
|
@api.depends('order_list', 'order_list.tax_id', 'order_list.item_rate', 'order_list.item_qty')
|
|
def _amount_tax(self):
|
|
# print " In amount :::::: Tax"
|
|
val = 0.00
|
|
for line in self.order_list:
|
|
taxes = line.tax_id.compute_all(
|
|
line.item_rate, None, int(line.item_qty))
|
|
val += taxes['total_included'] - taxes['total_excluded']
|
|
if self.pricelist_id:
|
|
self.amount_tax = self.pricelist_id.currency_id.round(val)
|
|
else:
|
|
self.amount_tax = val
|
|
|
|
@api.depends('order_list')
|
|
def _sub_total(self):
|
|
# print "Sub Total :::::: Tax"
|
|
val = 0.00
|
|
for line in self.order_list:
|
|
val += line.price_subtotal
|
|
# print "SubTotal ::::::", val
|
|
if self.pricelist_id:
|
|
self.amount_subtotal = self.pricelist_id.currency_id.round(val)
|
|
else:
|
|
self.amount_subtotal = val
|
|
|
|
def _amount_untaxed(self):
|
|
for line in self:
|
|
total = sum(order.price_subtotal for order in line.order_list)
|
|
# total += sum(fee.price_subtotal for fee in line.fees_lines)
|
|
line.amount_untaxed = line.pricelist_id.currency_id.round(total)
|
|
|
|
def _total(self):
|
|
val = val1 = 0.0
|
|
for line in self.order_list:
|
|
taxes = line.tax_id.compute_all(
|
|
line.item_rate, None, int(line.item_qty))
|
|
val1 += line.price_subtotal
|
|
# print "SubTotal -------", val1
|
|
val += taxes['total_included'] - taxes['total_excluded']
|
|
# print "Tax ------", val
|
|
if self.pricelist_id:
|
|
self.amount_tax = self.pricelist_id.currency_id.round(val)
|
|
self.amount_untaxed = self.pricelist_id.currency_id.round(val1)
|
|
else:
|
|
self.amount_tax = val
|
|
self.amount_untaxed = val1
|
|
# print "subtotal ------ ", self.amount_untaxed
|
|
|
|
self.amount_total = self.amount_untaxed + self.amount_tax
|
|
|
|
def _get_default_shop(self):
|
|
company_id = self.env['res.users'].browse(self.env.uid).company_id.id
|
|
shop_ids = self.env['sale.shop'].search(
|
|
[('company_id', '=', company_id)]).ids
|
|
if not shop_ids:
|
|
raise UserError(
|
|
'There is no default shop for the current user\'s company!')
|
|
return shop_ids[0]
|
|
|
|
@api.onchange('shop_id')
|
|
def onchange_shop_id(self):
|
|
v = {}
|
|
if self.shop_id:
|
|
shop = self.env['sale.shop'].browse(self.shop_id.id)
|
|
if shop.pricelist_id:
|
|
v['pricelist_id'] = shop.pricelist_id.id
|
|
v['company_id'] = shop.company_id.id
|
|
return {'value': v}
|
|
|
|
waiter_name1 = fields.Many2one('res.users', 'Waiter User Name')
|
|
partner_id = fields.Many2one('res.partner', 'Customer', required=True,
|
|
help="Will show customer name corresponding to selected room no.")
|
|
room_no = fields.Many2one(
|
|
'hotel.room', 'Room No', domain=domain_change,help="Will show list of currently occupied room no that belongs to selected shop.")
|
|
pricelist_id = fields.Many2one(
|
|
'product.pricelist', 'Pricelist',
|
|
domain="[('company_id', '=', [current_company_id])]",
|
|
required=True, readonly=True)
|
|
shop_id = fields.Many2one('sale.shop', 'Hotel', default=_get_default_shop, required=True, readonly=True,
|
|
help="Will show list of shop that belongs to allowed companies of logged-in user.")
|
|
|
|
company_id = fields.Many2one(
|
|
'res.company', related='shop_id.company_id', string='Company', store=True)
|
|
|
|
state = fields.Selection(selection_add=[('draft', 'Draft'), ('confirm', 'Confirmed'), ('order', 'Order Done'), (
|
|
'done', 'Done'), ('cancel', 'Cancelled')], string='State', index=True, required=True, readonly=True)
|
|
flag = fields.Boolean("Flag", default=False)
|
|
amount_subtotal = fields.Float(
|
|
compute="_sub_total", string='SubTotal', compute_sudo=False)
|
|
amount_tax = fields.Float(compute="_amount_tax", string='Tax')
|
|
amount_total = fields.Float(compute="_total", string='Total')
|
|
amount_untaxed = fields.Float(
|
|
'Untaxed Amount', compute='_amount_untaxed', store=True)
|
|
|
|
def confirm_order(self):
|
|
for obj in self:
|
|
for line in obj.table_no:
|
|
line.write({'avl_state': 'book'})
|
|
self.write({'state': 'confirm'})
|
|
return True
|
|
|
|
# @api.multi
|
|
|
|
|
|
@api.onchange('pricelist_id')
|
|
def onchange_pricelist_id(self):
|
|
if not self.pricelist_id:
|
|
return {}
|
|
if not self.order_list or self.order_list == [(6, 0, [])]:
|
|
return {}
|
|
if len(self.order_list) != 1:
|
|
warning = {
|
|
'title': _('Pricelist Warning!'),
|
|
'message': _(
|
|
'If you change the pricelist of this order (and eventually the currency), prices of existing order lines will not be updated.')
|
|
}
|
|
return {'warning': warning}
|
|
|
|
@api.onchange('o_date')
|
|
def onchange_odate(self):
|
|
new_ids = []
|
|
|
|
# Old Logic
|
|
# main_obj_ids = self.env['hotel.room.booking.history'].search([
|
|
# ('check_in', '<=', self.o_date), ('check_out', '>=', self.o_date), ('state', '=', 'done')])
|
|
# for dest_line in main_obj_ids:
|
|
# new_ids.append(dest_line.history_id.id)
|
|
|
|
# New Logic
|
|
room_lines = self.env['hotel.folio'].search([('state', '=', 'draft')]).mapped('room_lines')
|
|
for rec in room_lines:
|
|
if rec.product_id:
|
|
room_id = self.env['hotel.room'].search([('product_id', '=', rec.product_id.id)])
|
|
if room_id:
|
|
new_ids.append(room_id.id)
|
|
return {
|
|
'domain': {
|
|
'room_no': [('id', 'in', new_ids)],
|
|
}}
|
|
|
|
|
|
@api.depends('o_date')
|
|
@api.onchange('room_no')
|
|
def onchange_room_no(self):
|
|
res = {}
|
|
booking_id = 0
|
|
# history_obj = self.env["hotel.room.booking.history"]
|
|
if not self.room_no:
|
|
return {'value': {'partner_id': False}}
|
|
# for folio_hsry_id in history_obj.search([('history_id', '=', self.room_no.id), ('state', '=', 'done')]):
|
|
# hstry_line_id = folio_hsry_id
|
|
# start_dt = hstry_line_id.check_in
|
|
# end_dt = hstry_line_id.check_out
|
|
# if (start_dt <= self.o_date) and (end_dt >= self.o_date):
|
|
# booking_id = hstry_line_id.booking_id.id
|
|
# folio_obj_id = self.env["hotel.folio"].search(
|
|
# [('reservation_id', '=', booking_id)])
|
|
# if not folio_obj_id:
|
|
# raise UserError(
|
|
# 'Please create folio for selected room first.')
|
|
# res['folio_id'] = folio_obj_id[0].id
|
|
# res['partner_id'] = hstry_line_id.partner_id.id
|
|
# new logic updated on 13-June-2022
|
|
room_lines = self.env['hotel.folio'].search([('state', '=', 'draft')]).mapped('room_lines')
|
|
for rec in room_lines:
|
|
if rec.product_id.id == self.room_no.product_id.id:
|
|
folio_id = rec.folio_id
|
|
if folio_id:
|
|
res['folio_id'] = folio_id.id
|
|
res['partner_id'] = folio_id.partner_id.id
|
|
break
|
|
return {'value': res}
|
|
|
|
# @api.multi
|
|
|
|
|
|
|
|
|
|
class hotel_restaurant_reservation(models.Model):
|
|
_inherit = "hotel.restaurant.reservation"
|
|
_description = "Includes Hotel Restaurant Reservation"
|
|
|
|
def _get_default_shop(self):
|
|
company_id = self.env['res.users'].browse(self.env.uid).company_id.id
|
|
shop_ids = self.env['sale.shop'].search(
|
|
[('company_id', '=', company_id)]).ids
|
|
if not shop_ids:
|
|
raise UserError(
|
|
'There is no default shop for the current user\'s company!')
|
|
return shop_ids[0]
|
|
|
|
@api.onchange('shop_id')
|
|
def onchange_shop_id(self):
|
|
v = {}
|
|
if self.shop_id:
|
|
shop = self.env['sale.shop'].browse(self.shop_id.id)
|
|
if shop.pricelist_id:
|
|
v['pricelist_id'] = shop.pricelist_id.id
|
|
return {'value': v}
|
|
|
|
cname = fields.Many2one('res.partner', 'Customer Name', required=True,
|
|
help="Will show customer name corresponding to selected room no.")
|
|
room_no = fields.Many2one('hotel.room', 'Room No',
|
|
help="Will show list of currently occupied room no that belongs to selected shop.")
|
|
pricelist_id = fields.Many2one(
|
|
'product.pricelist', 'Pricelist', required=True)
|
|
shop_id = fields.Many2one('sale.shop', 'Hotel', default=_get_default_shop, required=True,
|
|
help="Will show list of shop that belongs to allowed companies of logged-in user.")
|
|
|
|
company_id = fields.Many2one(
|
|
'res.company', related='shop_id.company_id', string='Company', store=True)
|
|
|
|
@api.onchange('pricelist_id')
|
|
def onchange_pricelist_id(self):
|
|
if not self.pricelist_id:
|
|
return {}
|
|
if not self.order_list_ids or self.order_list_ids == [(6, 0, [])]:
|
|
return {}
|
|
if len(self.order_list_ids) != 1:
|
|
warning = {
|
|
'title': _('Pricelist Warning!'),
|
|
'message': _(
|
|
'If you change the pricelist of this order (and eventually the currency), prices of existing order lines will not be updated.')
|
|
}
|
|
return {'warning': warning}
|
|
|
|
@api.onchange('start_date', 'end_date')
|
|
def onchange_date(self):
|
|
new_ids = []
|
|
|
|
main_obj_ids = self.env['hotel.room.booking.history'].search(
|
|
[('check_in', '<=', self.start_date), ('check_out', '>=', self.end_date), ('state', '!=', 'cancel')])
|
|
for dest_line in main_obj_ids:
|
|
new_ids.append(dest_line.history_id.id)
|
|
return {
|
|
'domain': {
|
|
'room_no': [('id', 'in', new_ids)],
|
|
}}
|
|
|
|
@api.onchange('room_no', 'start_date', 'end_date')
|
|
def onchange_room_no(self):
|
|
res = {}
|
|
booking_id = 0
|
|
history_obj = self.env["hotel.room.booking.history"]
|
|
folio_obj = self.env["hotel.folio"]
|
|
if not self.room_no:
|
|
return {'value': {'partner_id': False}}
|
|
for folio_hsry_id in history_obj.search([('history_id', '=', self.room_no.id), ('state', '=', 'done')]):
|
|
history_start_date = folio_hsry_id.check_in
|
|
history_end_date = folio_hsry_id.check_out
|
|
if (history_start_date <= self.start_date < history_end_date) or (
|
|
history_start_date < self.end_date <= history_end_date) or (
|
|
(self.start_date < history_start_date) and (self.end_date >= history_end_date)):
|
|
booking_id = folio_hsry_id.booking_id.id
|
|
folio_obj_id = folio_obj.search(
|
|
[('reservation_id', '=', booking_id)])
|
|
res['folio_id'] = folio_obj_id
|
|
res['cname'] = folio_obj_id.partner_id.id
|
|
return {'value': res}
|
|
|
|
def create_order(self):
|
|
for i in self:
|
|
table_ids = [x.id for x in i.tableno]
|
|
order_list_ids = [x.id for x in i.order_list_ids]
|
|
kot_data = self.env['hotel.reservation.order'].create({
|
|
'reservation_id': i.id,
|
|
'date1': i.start_date,
|
|
'partner_id': i.cname.id,
|
|
'room_no': i.room_no.id,
|
|
'folio_id': i.folio_id.id,
|
|
'table_no': [(6, 0, table_ids)],
|
|
# 'order_list_ids': [(6, 0, order_list_ids)],
|
|
'pricelist_id': i.pricelist_id.id,
|
|
'shop_id': i.shop_id.id,
|
|
})
|
|
|
|
for line in i.order_list_ids:
|
|
line.write({'o_l': kot_data.id})
|
|
kot_browse = self.env[
|
|
'hotel.reservation.order'].browse(kot_data.id)
|
|
self.write({'state': 'order'})
|
|
return True
|
|
|
|
def table_reserved(self):
|
|
for reservation in self:
|
|
self.write({'state': 'confirm'})
|
|
return True
|
|
|
|
|
|
class hotel_reservation_order(models.Model):
|
|
_inherit = "hotel.reservation.order"
|
|
_description = "Includes Hotel Reservation order"
|
|
|
|
def _sub_total(self):
|
|
# print "In reservation order Sub_total"
|
|
val = 0.00
|
|
for line in self.order_list:
|
|
val += line.price_subtotal
|
|
# print "SubTotal ::::::", val
|
|
self.amount_subtotal = self.pricelist_id.currency_id.round(val)
|
|
# print " Subtotal", self.amount_subtotal
|
|
|
|
def _amount_tax(self):
|
|
val = 0.00
|
|
for line in self.order_list:
|
|
taxes = line.tax_id.compute_all(
|
|
line.item_rate, None, int(line.item_qty), line.product_id.product_id, False)
|
|
val += taxes['total_included'] - taxes['total_excluded']
|
|
self.amount_tax = self.pricelist_id.currency_id.round(val)
|
|
|
|
def _amount_untaxed(self):
|
|
for line in self:
|
|
total = sum(order.price_subtotal for order in line.order_list)
|
|
# total += sum(fee.price_subtotal for fee in line.fees_lines)
|
|
line.amount_untaxed = line.pricelist_id.currency_id.round(total)
|
|
|
|
def _total(self):
|
|
val = val1 = 0.0
|
|
for line in self.order_list:
|
|
taxes = line.tax_id.compute_all(
|
|
line.item_rate, None, int(line.item_qty))
|
|
val1 += line.price_subtotal
|
|
# print "SubTotal -------", val1
|
|
val += taxes['total_included'] - taxes['total_excluded']
|
|
# print "Tax ------", val
|
|
self.amount_tax = self.pricelist_id.currency_id.round(val)
|
|
# print "amount Tax ------ ", self.amount_tax
|
|
self.amount_untaxed = self.pricelist_id.currency_id.round(val1)
|
|
# print "subtotal ------ ", self.amount_untaxed
|
|
self.amount_total = self.amount_untaxed + self.amount_tax
|
|
# print "Total ------ ", self.amount_subtotal
|
|
|
|
def _get_default_shop(self):
|
|
company_id = self.env['res.users'].browse(self.env.uid).company_id.id
|
|
shop_ids = self.env['sale.shop'].search(
|
|
[('company_id', '=', company_id)]).ids
|
|
if not shop_ids:
|
|
raise UserError(
|
|
'There is no default shop for the current user\'s company!')
|
|
return shop_ids[0]
|
|
|
|
@api.onchange('shop_id')
|
|
def onchange_shop_id(self):
|
|
v = {}
|
|
if self.shop_id:
|
|
shop = self.env['sale.shop'].browse(self.shop_id.id)
|
|
if shop.pricelist_id:
|
|
v['pricelist_id'] = shop.pricelist_id.id
|
|
return {'value': v}
|
|
|
|
waitername1 = fields.Many2one('res.users', 'Waiter User Name')
|
|
pricelist_id = fields.Many2one(
|
|
'product.pricelist', 'Pricelist', required=True)
|
|
shop_id = fields.Many2one('sale.shop', 'Hotel', required=True, default=_get_default_shop)
|
|
|
|
company_id = fields.Many2one(
|
|
'res.company', related='shop_id.company_id', string='Company', store=True)
|
|
flag1 = fields.Boolean("Flag", default=False)
|
|
amount_subtotal = fields.Float(compute="_sub_total", string='Subtotal')
|
|
amount_tax = fields.Float(compute="_amount_tax", string='Tax')
|
|
amount_total = fields.Float(compute="_total", string='Total')
|
|
amount_untaxed = fields.Float(
|
|
'Untaxed Amount', compute='_amount_untaxed', store=True)
|
|
|
|
@api.onchange('pricelist_id')
|
|
def onchange_pricelist_id(self):
|
|
if not self.pricelist_id:
|
|
return {}
|
|
if not self.order_list or self.order_list == [(6, 0, [])]:
|
|
return {}
|
|
if len(self.order_list) != 1:
|
|
warning = {
|
|
'title': _('Pricelist Warning!'),
|
|
'message': _(
|
|
'If you change the pricelist of this order (and eventually the currency), prices of existing order lines will not be updated.')
|
|
}
|
|
return {'warning': warning}
|
|
|
|
def confirm_order(self):
|
|
for obj in self:
|
|
for line in obj.table_no:
|
|
self.env['hotel.restaurant.tables'].write(
|
|
{'avl_state': 'book'})
|
|
|
|
self.write({'state': 'confirm'})
|
|
return True
|
|
|
|
def create_invoice(self):
|
|
for obj in self:
|
|
for line in obj.table_no:
|
|
self.env['hotel.restaurant.tables'].write(
|
|
{'avl_state': 'available'})
|
|
|
|
acc_id = obj.partner_id.property_account_receivable_id.id
|
|
journal_ids = self.env['account.journal'].search(
|
|
[('type', '=', 'sale')], limit=1)
|
|
journal_id = None
|
|
if journal_ids:
|
|
journal_id = journal_ids.id
|
|
# added this id for pricing calculation for different pricelists
|
|
type = 'out_invoice'
|
|
if not obj.room_no:
|
|
inv = {
|
|
'name': obj.order_number,
|
|
'invoice_origin': obj.order_number,
|
|
'move_type': type,
|
|
'ref': "Order Invoice",
|
|
# 'account_id': acc_id,
|
|
'partner_id': obj.partner_id.id,
|
|
'currency_id': obj.pricelist_id.currency_id.id,
|
|
'journal_id': journal_id,
|
|
# 'amount_tax': obj.amount_tax,
|
|
# 'amount_untaxed': (obj.amount_total - obj.amount_tax),
|
|
# 'amount_total': obj.amount_total,
|
|
}
|
|
inv_id = self.env['account.move'].create(inv)
|
|
todo = []
|
|
for ol in obj.order_list:
|
|
todo.append(ol.id)
|
|
|
|
if ol.product_id.categ_id:
|
|
a = ol.product_id.categ_id.property_account_income_categ_id.id
|
|
if not a:
|
|
raise ValidationError(_('Error !'), _(
|
|
'There is no expense account defined for this product: "%s" (id:%d)') % (
|
|
ol.product_id.name, ol.product_id.id,))
|
|
|
|
else:
|
|
|
|
a = self.env['ir.property'].get(
|
|
'property_account_income_categ', 'product.category').id
|
|
tax_ids = []
|
|
for tax_line in ol.tax_id:
|
|
tax_ids.append(tax_line.id)
|
|
inv_id.write({
|
|
|
|
'invoice_line_ids': [(0, 0, {
|
|
'name': ol.product_id.name,
|
|
'move_id': inv_id.id,
|
|
'account_id': a,
|
|
'price_unit': ol.item_rate,
|
|
'quantity': float(ol.item_qty),
|
|
'product_id': ol.product_id.product_id.id,
|
|
|
|
# 'uos_id': False,
|
|
# 'origin': obj.order_number,
|
|
# 'move_id': inv_id.id,
|
|
# 'pay_date':obj.date1,
|
|
# 'order_amt': ol.price_subtotal,
|
|
'tax_ids': [(6, 0, tax_ids)],
|
|
})]
|
|
})
|
|
# self.env['account.move.line'].create(il)
|
|
self.write({'state': 'done'})
|
|
self.mapped('table_no').write({'avl_state': 'available'})
|
|
if self.folio_id:
|
|
for r in self.order_list:
|
|
tax_ids = []
|
|
for tax_line in r.tax_id:
|
|
tax_ids.append(tax_line.id)
|
|
so_line = {
|
|
'name': r.product_id.name,
|
|
'product_uom_qty': r.item_qty,
|
|
'product_id': r.product_id.product_id.id,
|
|
'price_unit': r.item_rate,
|
|
'product_uom': r.product_id.product_id.uom_id.id,
|
|
'order_id': self.folio_id.order_id.id,
|
|
'tax_id': [(6, 0, tax_ids)],
|
|
}
|
|
so_line_id = self.env['sale.order.line'].create(so_line)
|
|
service_line = {
|
|
'folio_id': self.folio_id.id,
|
|
'food_line_id': so_line_id.id,
|
|
'source_origin': obj.order_number,
|
|
}
|
|
service_line_id = self.env[
|
|
'hotel_food.line'].create(service_line)
|
|
return True
|
|
|
|
# @api.multi
|
|
def reservation_generate_kot(self):
|
|
kot_flag = True
|
|
bot_flag = True
|
|
kot_data = False
|
|
bot_data = False
|
|
for order in self:
|
|
table_ids = [x.id for x in order.table_no]
|
|
for order_line in order.order_list:
|
|
product_id = order_line.product_id
|
|
product_nature = product_id.product_nature
|
|
if product_nature == 'kot' and kot_flag:
|
|
order_reservation_data = {
|
|
'resno': order.order_number,
|
|
'room_no': order.room_no.name,
|
|
'kot_date': order.date1,
|
|
'w_name': order.waitername1.name,
|
|
'shop_id': order.shop_id.id,
|
|
'tableno': [(6, 0, table_ids)],
|
|
'product_nature': product_id.product_nature,
|
|
'pricelist_id': order.pricelist_id.id,
|
|
}
|
|
kot_flag = False
|
|
if product_nature == 'kot' and order_line.states == True:
|
|
current_qty = int(
|
|
order_line.item_qty) - order_line.previous_qty
|
|
if current_qty > 0:
|
|
kot_data_reserve = self.env['hotel.restaurant.kitchen.order.tickets'].create(
|
|
order_reservation_data)
|
|
o_line = {
|
|
'product_id': order_line.product_id.id,
|
|
'name': order_line.product_id.name,
|
|
'item_qty': current_qty,
|
|
'item_rate': order_line.item_rate,
|
|
'kot_order_list': kot_data_reserve,
|
|
'product_nature': product_id.product_nature,
|
|
}
|
|
self.env['hotel.restaurant.order.list'].create(o_line)
|
|
self.env['hotel.restaurant.order.list'].write(
|
|
{'previous_qty': order_line.item_qty})
|
|
if product_nature == 'kot' and order_line.states == False:
|
|
kot_data = self.env['hotel.restaurant.kitchen.order.tickets'].create(
|
|
order_reservation_data)
|
|
total_qty = int(order_line.item_qty) + \
|
|
order_line.previous_qty
|
|
o_line = {
|
|
'product_id': order_line.product_id.id,
|
|
'name': order_line.product_id.id,
|
|
'item_qty': order_line.item_qty,
|
|
'item_rate': order_line.item_rate,
|
|
'kot_order_list': kot_data.id,
|
|
'product_nature': product_id.product_nature,
|
|
# 'total_qty': total_qty,
|
|
}
|
|
self.env['hotel.restaurant.order.list'].create(o_line)
|
|
self.env['hotel.restaurant.order.list'].write(
|
|
{'states': 'True', 'previous_qty': order_line.item_qty})
|
|
|
|
if product_nature == 'bot' and bot_flag:
|
|
order_reservation_data_bot = {
|
|
'resno': order.order_number,
|
|
'room_no': order.room_no.name,
|
|
'kot_date': order.date1,
|
|
'w_name': order.waitername1.name,
|
|
'shop_id': order.shop_id.id,
|
|
'tableno': [(6, 0, table_ids)],
|
|
'product_nature': product_id.product_nature,
|
|
'pricelist_id': order.pricelist_id.id,
|
|
}
|
|
|
|
bot_flag = False
|
|
if product_nature == 'bot' and order_line.states == True:
|
|
current_qty = int(order_line.item_qty) - \
|
|
order_line.previous_qty
|
|
if current_qty > 0:
|
|
bot_data = self.env['hotel.restaurant.kitchen.order.tickets'].create(
|
|
order_reservation_data_bot)
|
|
o_line = {
|
|
'product_id': order_line.product_id.id,
|
|
'name': order_line.product_id.name,
|
|
'item_qty': current_qty,
|
|
'item_rate': order_line.item_rate,
|
|
'kot_order_list': bot_data.id,
|
|
'product_nature': product_id.product_nature,
|
|
}
|
|
self.env['hotel.restaurant.order.list'].create(o_line)
|
|
self.env['hotel.restaurant.order.list'].write(
|
|
{'states': 'True', 'previous_qty': order_line.item_qty})
|
|
|
|
if product_nature == 'bot' and order_line.states == False:
|
|
current_qty = int(order_line.item_qty) - \
|
|
order_line.previous_qty
|
|
if current_qty > 0:
|
|
bot_data = self.env['hotel.restaurant.kitchen.order.tickets'].create(
|
|
order_reservation_data_bot)
|
|
o_line = {
|
|
'product_id': order_line.product_id.id,
|
|
'name': order_line.product_id.id,
|
|
'item_qty': order_line.item_qty,
|
|
'item_rate': order_line.item_rate,
|
|
'kot_order_list': bot_data.id,
|
|
'product_nature': product_id.product_nature,
|
|
}
|
|
self.env['hotel.restaurant.order.list'].create(o_line)
|
|
self.env['hotel.restaurant.order.list'].write(
|
|
{'states': 'True', 'previous_qty': order_line.item_qty})
|
|
|
|
stock_brw = self.env['stock.picking'].search(
|
|
[('origin', '=', order.order_number)])
|
|
if stock_brw:
|
|
for order_items in order.order_list:
|
|
order_list = self.env['hotel.restaurant.order.list'].search([(
|
|
'product_id', '=', order_items.product_id.id),
|
|
('kot_order_list.resno', '=', order.order_number)])
|
|
total_qty1 = 0
|
|
for order_qty in order_list:
|
|
p_qty1 = order_qty.item_qty
|
|
total_qty1 = total_qty1 + int(p_qty1)
|
|
product_id = self.env['hotel.menucard'].browse(
|
|
order_items.product_id.id).product_id.id
|
|
if product_id:
|
|
move_id = self.env['stock.move'].search(
|
|
[('product_id', '=', product_id), ('picking_id', '=', stock_brw.id)])
|
|
if move_id:
|
|
self.env['stock.move'].write(
|
|
{'product_uom_qty': total_qty1, })
|
|
|
|
self.write({'state': 'order'})
|
|
return True
|
|
|
|
|
|
class res_partner(models.Model):
|
|
_inherit = 'res.partner'
|
|
_description = 'Partner'
|
|
|
|
agent = fields.Boolean('Agent')
|
|
commission = fields.Float('Commission Percentage')
|
|
login_password = fields.Char('Login Password')
|
|
reservation_warn = fields.Selection([
|
|
('no-message', 'No Message'),
|
|
('warning', 'Warning'),
|
|
('block', 'Blocking Message')
|
|
], 'Hotel Reservation', default='no-message', required=True)
|
|
reservation_msg = fields.Text('Message for Hotel Reservation')
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals):
|
|
if ('agent' in vals) and (vals['agent']):
|
|
if not ('commission' in vals):
|
|
raise ValidationError("Commission Percentage is not define.")
|
|
if ('commission' in vals) and not vals['commission']:
|
|
raise ValidationError("Commission Percentage is not define.")
|
|
return super(res_partner, self).create(vals)
|
|
|
|
# def write(self, vals):
|
|
# """
|
|
# Overriding the write method
|
|
# """
|
|
# if ('agent' in vals) and (vals['agent']):
|
|
# if not ('commission' in vals):
|
|
# raise UserError("Commission Percentage is not define.")
|
|
# return super(res_partner, self).sudo().write(vals)
|
|
|
|
|
|
class hotel_restaurant_order_list(models.Model):
|
|
_inherit = "hotel.restaurant.order.list"
|
|
_description = "Inherits Hotel Restaurant Order"
|
|
|
|
# @api.one
|
|
@api.depends("item_qty", "item_rate")
|
|
def _sub_total(self):
|
|
cur = False
|
|
for line in self:
|
|
price = line.item_rate
|
|
taxes = line.tax_id.compute_all(
|
|
price, None, int(line.item_qty), line.product_id.product_id, False)
|
|
# print "Taxessssssssss", taxes
|
|
if line.o_list:
|
|
cur = line.o_list.pricelist_id.currency_id
|
|
# print cur, "---o_list"
|
|
if line.order_l:
|
|
cur = line.order_l.pricelist_id.currency_id
|
|
# print cur, "---order_l"
|
|
if line.o_l:
|
|
cur = line.o_l.pricelist_id.currency_id
|
|
# print cur, "---o_l"
|
|
if line.kot_order_list:
|
|
cur = line.kot_order_list.pricelist_id.currency_id
|
|
|
|
# print cur, "---kot_order_list"
|
|
|
|
if cur:
|
|
line.price_subtotal += cur.round(taxes['total_excluded'])
|
|
else:
|
|
line.price_subtotal += taxes['total_excluded']
|
|
|
|
product_id = fields.Many2one('hotel.menucard', 'Item Name')
|
|
product_qty = fields.Integer('quantity')
|
|
states = fields.Boolean('States', default=False)
|
|
previous_qty = fields.Integer('quantities')
|
|
total = fields.Integer('total')
|
|
tax_id = fields.Many2many(
|
|
'account.tax', 'restaurant_order_tax', 'order_line_id', 'tax_id', 'Taxes', )
|
|
price_subtotal = fields.Float(
|
|
compute="_sub_total", string='Subtotal')
|
|
|
|
@api.depends('order_l.pricelist_id', 'order_l.start_date', 'o_l.pricelist_id', 'o_l.date1', 'o_list.pricelist_id',
|
|
'o_list.o_date', 'product_id', 'item_qty')
|
|
@api.onchange('product_id')
|
|
def on_change_item_name(self):
|
|
# if not self.order_l.pricelist_id:
|
|
# raise UserError("Heloooo PriceList is not Selected !")
|
|
if not self.product_id:
|
|
return {'value': {}}
|
|
temp = self.product_id
|
|
taxx_id = self.product_id.taxes_id
|
|
tax_id = self.env['account.fiscal.position'].map_tax(
|
|
self.product_id.taxes_id)
|
|
price_value = 0
|
|
|
|
if self.o_l:
|
|
if not self.o_l.pricelist_id:
|
|
raise ValidationError("Orders PriceList is not Selected!")
|
|
if self.o_l.date1:
|
|
ol_date = self.o_l.date1
|
|
else:
|
|
ol_date = time.strftime('%Y-%m-%d')
|
|
elif self.o_list:
|
|
if not self.o_list.pricelist_id:
|
|
raise ValidationError("Table Order PriceList is not Selected !")
|
|
if self.o_list.o_date:
|
|
olist_date = self.o_list.o_date
|
|
else:
|
|
olist_date = time.strftime('%Y-%m-%d')
|
|
elif self.order_l:
|
|
if not self.order_l.pricelist_id:
|
|
raise ValidationError("Table Booking PriceList is not Selected !")
|
|
if self.order_l.start_date:
|
|
orderl_date = self.order_l.start_date
|
|
else:
|
|
orderl_date = time.strftime('%Y-%m-%d')
|
|
|
|
if self.item_qty:
|
|
if self.o_l:
|
|
price_value = self.o_l.pricelist_id._price_get(
|
|
temp.product_id.id, self.item_qty, uom=temp.uom_id.id, date=ol_date)[self.o_l.pricelist_id.id]
|
|
elif self.o_list:
|
|
price_value = self.o_list.pricelist_id._price_get(
|
|
temp.product_id.id, self.item_qty, uom=temp.uom_id.id,date=olist_date)[self.o_list.pricelist_id.id]
|
|
|
|
elif self.order_l:
|
|
price_value = self.order_l.pricelist_id._price_get(
|
|
temp.product_id.id, self.item_qty, uom=temp.uom_id.id, date=orderl_date)[self.order_l.pricelist_id.id]
|
|
# else:
|
|
# if price_value is False:
|
|
# raise UserError(
|
|
# "Couldn't find a pricelist line matching this product!")
|
|
else:
|
|
if self.o_l:
|
|
price_value = self.o_l.pricelist_id._price_get(temp.product_id, self.item_qty)[self.o_l.pricelist_id.id]
|
|
elif self.o_list:
|
|
price_value = self.o_list.pricelist_id._price_get(
|
|
temp.product_id, self.item_qty)[self.o_list.pricelist_id.id]
|
|
elif self.order_l:
|
|
price_value = self.order_l.pricelist_id._price_get(
|
|
temp.product_id,
|
|
temp.uom_id.id,
|
|
)[self.order_l.pricelist_id.id]
|
|
self.item_rate = price_value
|
|
self.tax_id = tax_id
|
|
|
|
|
|
class product_template(models.Model):
|
|
_inherit = "product.template"
|
|
|
|
@tools.ormcache()
|
|
def _get_default_category_id(self):
|
|
# Deletion forbidden (at least through unlink)
|
|
return self.env.ref('product.product_category_all')
|
|
|
|
shop_id = fields.Many2one('sale.shop', string='Hotel',domain="[('company_id', 'in', [current_company_id])]",
|
|
help="Will show list of shop that belongs to allowed companies of logged-in user. \n -Assigning a shop will make product exclusive for selected shop.")
|
|
product_nature = fields.Selection(
|
|
[('kot', 'KOT'), ('bot', 'BOT')], 'Product Nature')
|
|
company_id = fields.Many2one('res.company', string='Company'
|
|
, domain="[('id', 'in', [current_company_id])]")
|
|
categ_id = fields.Many2one(
|
|
'product.category', 'Product Category',
|
|
domain="[('company_id', 'in', [current_company_id])]",
|
|
change_default=True, default=_get_default_category_id, group_expand='_read_group_categ_id',
|
|
required=True, help="Select category for the current product")
|
|
|
|
@api.onchange('shop_id')
|
|
def on_change_shop_id(self):
|
|
if not self.shop_id:
|
|
return {'value': {}}
|
|
temp = self.shop_id
|
|
self.company_id = temp.company_id.id
|
|
|
|
@api.model
|
|
def _construct_tax_string(self, price):
|
|
|
|
user_id = self.env['res.users'].search([('id', '=', self._context.get('uid'))])
|
|
if self.currency_id:
|
|
currency = self.currency_id
|
|
elif user_id.currency_id:
|
|
currency = user_id.company_id.currency_id
|
|
|
|
res = self.taxes_id.compute_all(price, product=self, partner=self.env['res.partner'])
|
|
joined = []
|
|
included = res['total_included']
|
|
if currency.compare_amounts(included, price):
|
|
joined.append(_('%s Incl. Taxes', format_amount(self.env, included, currency)))
|
|
excluded = res['total_excluded']
|
|
if currency.compare_amounts(excluded, price):
|
|
joined.append(_('%s Excl. Taxes', format_amount(self.env, excluded, currency)))
|
|
if joined:
|
|
tax_string = f"(= {', '.join(joined)})"
|
|
else:
|
|
tax_string = " "
|
|
return tax_string
|
|
|
|
|
|
class hotel_restaurant_kitchen_order_tickets(models.Model):
|
|
_inherit = "hotel.restaurant.kitchen.order.tickets"
|
|
_description = "Includes Hotel Restaurant Order"
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals):
|
|
for rec in vals:
|
|
product_nature = rec['product_nature']
|
|
if product_nature != 'kot':
|
|
rec['ordernobot'] = self.env['ir.sequence'].next_by_code(
|
|
'hotel.reservation.botorder')
|
|
return super(hotel_restaurant_kitchen_order_tickets, self).create(vals)
|
|
|
|
ordernobot = fields.Char('BOT Number', readonly=True)
|
|
product_nature = fields.Selection(
|
|
[('kot', 'KOT'), ('bot', 'BOT')], 'Product Nature')
|
|
shop_id = fields.Many2one('sale.shop', 'Hotel', required=True)
|
|
pricelist_id = fields.Many2one('product.pricelist', 'Pricelist', )
|
|
|
|
company_id = fields.Many2one(
|
|
'res.company', related='shop_id.company_id', string='Company', store=True)
|
|
|
|
|
|
class hotel_menucard(models.Model):
|
|
_inherit = "hotel.menucard"
|
|
_description = "Hotel menucard Inherit "
|
|
|
|
# company_id = fields.Many2one('res.company', related='shop_id.company_id', string='Company', default=lambda *a: False)
|
|
company_id = fields.Many2one(
|
|
'res.company', string='Company', default=lambda *a: False)
|
|
|
|
product_nature = fields.Selection(
|
|
[('kot', 'KOT'), ('bot', 'BOT')], 'Product Nature', default='kot')
|
|
|
|
@api.onchange('shop_id')
|
|
def on_change_shop_id(self):
|
|
if not self.shop_id:
|
|
return {'value': {}}
|
|
temp = self.shop_id
|
|
self.company_id = temp.company_id.id
|
|
|
|
@api.onchange('shop_id')
|
|
def on_change_shop_id(self):
|
|
if self.shop_id:
|
|
temp = self.shop_id
|
|
self.company_id = temp.company_id.id
|
|
else:
|
|
self.company_id = False
|
|
|
|
|
|
class database_configuration(models.Model):
|
|
_name = 'database.configuration'
|
|
_description = 'Database Configuration'
|
|
|
|
name = fields.Char('Database Name', required=True)
|
|
company_name = fields.Char('Company Name', required=True)
|
|
user_name = fields.Char('User Name', required=True)
|
|
password = fields.Char('Password', required=True)
|
|
|
|
|
|
class hotel_resv_id_details(models.Model):
|
|
_name = 'hotel.resv.id.details'
|
|
_description = 'Clients ID details during reservation'
|
|
|
|
name = fields.Char('ID Card Number')
|
|
client_id = fields.Many2one("id.master", "Document Type")
|
|
partner_name = fields.Char('Guest Name')
|
|
issuing_auth = fields.Char('Issuing Authority')
|
|
gender = fields.Selection(
|
|
[('M', 'Male'), ('F', 'Female')], 'Gender')
|
|
country_id = fields.Many2one("res.country", "Country")
|
|
date_birth = fields.Date('Date of Birth')
|
|
valid_from = fields.Date('Valid From')
|
|
valid_to = fields.Date('Valid To')
|
|
reservation_id = fields.Many2one('hotel.reservation', 'Reservation Id')
|
|
folio_id = fields.Many2one('hotel.folio', 'Folio Id')
|
|
|
|
|
|
# class for dashboard URL
|
|
class dashboard_url(models.Model):
|
|
_name = "dashboard.url"
|
|
_description = 'dashboard url'
|
|
|
|
url = fields.Char("Dashboard URL")
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals):
|
|
ids = self.env['dashboard.url'].search(self._ids, [])
|
|
if ids:
|
|
# self.env['dashboard.url'].unlink(self._ids)
|
|
ids.unlink()
|
|
return super(dashboard_url, self).create(vals)
|
|
|
|
|
|
class account_invoice(models.Model):
|
|
_name = "account.move"
|
|
_inherit = "account.move"
|
|
_description = 'Invoice'
|
|
|
|
exchange_rate = fields.Float('Exchange Rate', digits=(12, 6), )
|
|
create_date = fields.Datetime('Creation Date', )
|
|
|
|
@api.onchange('currency_id')
|
|
@api.depends('journal_id')
|
|
def onchange_currency_id(self):
|
|
# on change of the journal, we need to set also the default value for
|
|
# payment_rate and payment_rate_currency_id
|
|
res = {}
|
|
if self._context is None:
|
|
self._context = {}
|
|
currency_obj = self.env['res.currency']
|
|
if not self.journal_id:
|
|
raise ValidationError('Journal is not selected.')
|
|
journal = self.env['account.journal'].browse(self.journal_id.id)
|
|
# company_id = journal.company_id.id
|
|
exchange_rate = 1.0
|
|
payment_rate_currency_id = self.currency_id
|
|
company_currency_id = journal.company_id.currency_id.id
|
|
ctx = self._context and self._context.copy() or {}
|
|
ctx.update({'date': str(time.strftime('%Y-%m-%d'))})
|
|
if payment_rate_currency_id and payment_rate_currency_id.id != company_currency_id:
|
|
tmp = currency_obj.browse(payment_rate_currency_id).rate
|
|
exchange_rate = tmp / currency_obj.browse(company_currency_id).rate
|
|
res['exchange_rate'] = exchange_rate
|
|
res['currency_id'] = payment_rate_currency_id.id
|
|
return {'value': res}
|
|
|
|
|
|
class hotel_folio_transport_line(models.Model):
|
|
_name = 'hotel_folio_transport.line'
|
|
_description = 'hotel folio transport line'
|
|
_inherits = {'sale.order.line': 'transport_line_id'}
|
|
|
|
transport_line_id = fields.Many2one(
|
|
'sale.order.line', 'food_line_id', required=True, ondelete='cascade')
|
|
folio_id = fields.Many2one('hotel.folio', 'Folio ref', ondelete='cascade')
|
|
source_origin = fields.Char('Source Origin')
|
|
|
|
@api.onchange('product_id')
|
|
def product_id_change(self):
|
|
if self.product_id:
|
|
self.product_uom = self.product_id.uom_id
|
|
self.price_unit = self.product_id.lst_price
|
|
self.name = self.product_id.description_sale
|
|
|
|
|
|
class hotel_folio_laundry_line(models.Model):
|
|
_name = 'hotel_folio_laundry.line'
|
|
_description = 'hotel folio laundry line'
|
|
_inherits = {'sale.order.line': 'laundry_line_id'}
|
|
|
|
laundry_line_id = fields.Many2one(
|
|
'sale.order.line', 'laundry ref', required=True, ondelete='cascade')
|
|
folio_id = fields.Many2one('hotel.folio', 'Folio ref', ondelete='cascade')
|
|
source_origin = fields.Char('Source Origin')
|
|
|
|
@api.onchange('product_id')
|
|
def product_id_change(self):
|
|
if self.product_id:
|
|
self.product_uom = self.product_id.uom_id
|
|
self.price_unit = self.product_id.lst_price
|
|
self.name = self.product_id.description_sale
|
|
|
|
# class StockChangeStandardPrice(models.TransientModel):
|
|
# _inherit = "stock.change.standard.price"
|
|
# _description = "Change Standard Price"
|
|
#
|
|
# def change_price(self):
|
|
# """ Changes the Standard Price of Product and creates an account move accordingly. """
|
|
# self.ensure_one()
|
|
# if self._context['active_model'] == 'product.template':
|
|
# products = self.env['product.template'].browse(self._context['active_id']).product_variant_ids
|
|
# elif self._context['active_model'] == 'product.product':
|
|
# products = self.env['product.product'].browse(self._context['active_id'])
|
|
#
|
|
# elif self._context['active_model'] == 'hotel.room':
|
|
# products = self.env['hotel.room'].browse(self._context['active_id']).product_variant_ids
|
|
#
|
|
# elif self._context['active_model'] == 'hotel.menucard':
|
|
# products = self.env['hotel.menucard'].browse(self._context['active_id']).product_variant_ids
|
|
#
|
|
# elif self._context['active_model'] == 'hotel.services':
|
|
# products = self.env['hotel.services'].browse(self._context['active_id']).product_variant_ids
|
|
#
|
|
# else:
|
|
# pass
|
|
#
|
|
# products._change_standard_price(self.new_price, counterpart_account_id=self.counterpart_account_id.id)
|
|
# return {'type': 'ir.actions.act_window_close'}
|