mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
277 lines
11 KiB
Python
277 lines
11 KiB
Python
# Copyright 2017 Alexandre Díaz
|
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
from datetime import timedelta
|
|
from openerp import models, fields, api
|
|
from openerp.tools import (
|
|
DEFAULT_SERVER_DATE_FORMAT,
|
|
DEFAULT_SERVER_DATETIME_FORMAT)
|
|
from odoo.addons.hotel import date_utils
|
|
|
|
|
|
class MassiveChangesWizard(models.TransientModel):
|
|
_name = 'hotel.wizard.massive.changes'
|
|
|
|
# Common fields
|
|
section = fields.Selection([
|
|
('0', 'Availability'),
|
|
('1', 'Restrictions'),
|
|
('2', 'Pricelist'),
|
|
], string='Section', default='0')
|
|
date_start = fields.Datetime('Start Date', required=True)
|
|
date_end = fields.Datetime('End Date', required=True)
|
|
dmo = fields.Boolean('Monday', default=True)
|
|
dtu = fields.Boolean('Tuesday', default=True)
|
|
dwe = fields.Boolean('Wednesday', default=True)
|
|
dth = fields.Boolean('Thursday', default=True)
|
|
dfr = fields.Boolean('Friday', default=True)
|
|
dsa = fields.Boolean('Saturday', default=True)
|
|
dsu = fields.Boolean('Sunday', default=True)
|
|
applied_on = fields.Selection([
|
|
('0', 'Global'),
|
|
('1', 'Virtual Room'),
|
|
], string='Applied On', default='0')
|
|
# room_type_ids = fields.Many2many('hotel.virtual.room',
|
|
# string="Virtual Rooms")
|
|
room_type_ids = fields.Many2many('hotel.room.type',
|
|
string="Room Types")
|
|
|
|
# Availability fields
|
|
change_avail = fields.Boolean(default=False)
|
|
avail = fields.Integer('Avail', default=0)
|
|
change_no_ota = fields.Boolean(default=False)
|
|
no_ota = fields.Boolean('No OTA', default=False)
|
|
|
|
# Restriction fields
|
|
restriction_id = fields.Many2one('hotel.room.type.restriction',
|
|
'Restriction Plan')
|
|
change_min_stay = fields.Boolean(default=False)
|
|
min_stay = fields.Integer("Min. Stay")
|
|
change_min_stay_arrival = fields.Boolean(default=False)
|
|
min_stay_arrival = fields.Integer("Min. Stay Arrival")
|
|
change_max_stay = fields.Boolean(default=False)
|
|
max_stay = fields.Integer("Max. Stay")
|
|
change_max_stay_arrival = fields.Boolean(default=False)
|
|
max_stay_arrival = fields.Integer("Max. Stay Arrival")
|
|
change_closed = fields.Boolean(default=False)
|
|
closed = fields.Boolean('Closed')
|
|
change_closed_departure = fields.Boolean(default=False)
|
|
closed_departure = fields.Boolean('Closed Departure')
|
|
change_closed_arrival = fields.Boolean(default=False)
|
|
closed_arrival = fields.Boolean('Closed Arrival')
|
|
|
|
# Pricelist fields
|
|
pricelist_id = fields.Many2one('product.pricelist', 'Pricelist')
|
|
price = fields.Char('Price', help="Can use '+','-' \
|
|
or '%'...\nExamples:\n a) +12.3 \
|
|
\t> Increase the price in 12.3\n \
|
|
b) -1.45% \t> Substract 1.45%\n c) 45 \
|
|
\t\t> Sets the price to 45")
|
|
|
|
@api.onchange('date_start')
|
|
def onchange_date_start(self):
|
|
self.ensure_one()
|
|
self.date_end = self.date_start
|
|
|
|
@api.multi
|
|
def is_valid_date(self, chkdate):
|
|
self.ensure_one()
|
|
wday = chkdate.timetuple()[6]
|
|
wedays = (self.dmo, self.dtu, self.dwe, self.dth, self.dfr, self.dsa,
|
|
self.dsu)
|
|
return (chkdate >= self.date_start and chkdate <= self.date_end
|
|
and wedays[wday])
|
|
|
|
@api.model
|
|
def _save_prices(self, ndate, room_types, record):
|
|
product_pricelist_item_obj = self.env['product.pricelist.item']
|
|
price = 0.0
|
|
operation = 'a'
|
|
if record.price[0] == '+' or record.price[0] == '-':
|
|
if record.price[-1] == '%':
|
|
price = float(record.price[1:-1])
|
|
operation = 'ap' if (record.price[0] == '+') else 'sp'
|
|
else:
|
|
price = float(record.price[1:])
|
|
operation = 'a' if (record.price[0] == '+') else 's'
|
|
else:
|
|
if record.price[-1] == '%':
|
|
price = float(record.price[:-1])
|
|
operation = 'np'
|
|
else:
|
|
price = float(record.price)
|
|
operation = 'n'
|
|
|
|
domain = [
|
|
('pricelist_id', '=', record.pricelist_id.id),
|
|
('date_start', '>=', ndate.strftime(
|
|
DEFAULT_SERVER_DATE_FORMAT)),
|
|
('date_end', '<=', ndate.strftime(
|
|
DEFAULT_SERVER_DATE_FORMAT)),
|
|
('compute_price', '=', 'fixed'),
|
|
('applied_on', '=', '1_product'),
|
|
]
|
|
|
|
for room_type in room_types:
|
|
prod_tmpl_id = room_type.product_id.product_tmpl_id
|
|
pricelist_item_ids = product_pricelist_item_obj.search(
|
|
domain+[('product_tmpl_id', '=', prod_tmpl_id.id)])
|
|
if any(pricelist_item_ids):
|
|
if operation != 'n':
|
|
for pli in pricelist_item_ids:
|
|
pli_price = pli.fixed_price
|
|
if operation == 'a':
|
|
pli.write({
|
|
'fixed_price': pli_price + price})
|
|
elif operation == 'ap':
|
|
pli.write({'fixed_price': pli_price + price * pli_price * 0.01})
|
|
elif operation == 's':
|
|
pli.write({
|
|
'fixed_price': pli_price - price})
|
|
elif operation == 'sp':
|
|
pli.write({'fixed_price': pli_price - price * pli_price * 0.01})
|
|
elif operation == 'np':
|
|
pli.write({'fixed_price': price * pli_price * 0.01})
|
|
else:
|
|
pricelist_item_ids.write({'fixed_price': price})
|
|
else:
|
|
product_pricelist_item_obj.create({
|
|
'pricelist_id': record.pricelist_id.id,
|
|
'date_start': ndate.strftime(
|
|
DEFAULT_SERVER_DATE_FORMAT),
|
|
'date_end': ndate.strftime(
|
|
DEFAULT_SERVER_DATE_FORMAT),
|
|
'compute_price': 'fixed',
|
|
'applied_on': '1_product',
|
|
'product_tmpl_id': prod_tmpl_id.id,
|
|
'fixed_price': price,
|
|
})
|
|
|
|
def _get_restrictions_values(self, record):
|
|
vals = {}
|
|
if record.change_min_stay:
|
|
vals.update({'min_stay': record.min_stay})
|
|
if record.change_min_stay_arrival:
|
|
vals.update({'min_stay_arrival': record.min_stay_arrival})
|
|
if record.change_max_stay:
|
|
vals.update({'max_stay': record.max_stay})
|
|
if record.change_max_stay_arrival:
|
|
vals.update({'max_stay_arrival': record.max_stay_arrival})
|
|
if record.change_closed:
|
|
vals.update({'closed': record.closed})
|
|
if record.change_closed_departure:
|
|
vals.update({'closed_departure': record.closed_departure})
|
|
if record.change_closed_arrival:
|
|
vals.update({'closed_arrival': record.closed_arrival})
|
|
return vals
|
|
|
|
@api.model
|
|
def _save_restrictions(self, ndate, room_types, record):
|
|
hotel_room_type_re_it_obj = self.env['hotel.room.type.restriction.item']
|
|
domain = [
|
|
('date_start', '>=', ndate.strftime(DEFAULT_SERVER_DATE_FORMAT)),
|
|
('date_end', '<=', ndate.strftime(DEFAULT_SERVER_DATE_FORMAT)),
|
|
('restriction_id', '=', record.restriction_id.id),
|
|
('applied_on', '=', '0_room_type'),
|
|
]
|
|
|
|
for room_type in room_types:
|
|
vals = self._get_restrictions_values(record)
|
|
if not any(vals):
|
|
continue
|
|
|
|
rrest_item_ids = hotel_room_type_re_it_obj.search(
|
|
domain+[('room_type_id', '=', room_type.id)])
|
|
if any(rrest_item_ids):
|
|
rrest_item_ids.write(vals)
|
|
else:
|
|
vals.update({
|
|
'date_start': ndate.strftime(DEFAULT_SERVER_DATE_FORMAT),
|
|
'date_end': ndate.strftime(DEFAULT_SERVER_DATE_FORMAT),
|
|
'restriction_id': record.restriction_id.id,
|
|
'room_type_id': room_type.id,
|
|
'applied_on': '0_room_type',
|
|
})
|
|
hotel_room_type_re_it_obj.create(vals)
|
|
|
|
@api.model
|
|
def _get_availability_values(self, ndate, room_type, record):
|
|
hotel_room_type_obj = self.env['hotel.room.type']
|
|
vals = {}
|
|
if record.change_no_ota:
|
|
vals.update({'no_ota': record.no_ota})
|
|
if record.change_avail:
|
|
cavail = len(hotel_room_type_obj.check_availability_room(
|
|
ndate.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
|
|
ndate.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
|
|
room_type_id=room_type.id))
|
|
vals.update({
|
|
'avail': min(cavail, room_type.total_rooms_count, record.avail),
|
|
})
|
|
return vals
|
|
|
|
@api.model
|
|
def _save_availability(self, ndate, room_types, record):
|
|
hotel_room_type_avail_obj = self.env['hotel.room.type.availability']
|
|
domain = [('date', '=', ndate.strftime(DEFAULT_SERVER_DATE_FORMAT))]
|
|
|
|
for room_type in room_types:
|
|
vals = self._get_availability_values(ndate, room_type, record)
|
|
if not any(vals):
|
|
continue
|
|
|
|
room_types_avail = hotel_room_type_avail_obj.search(
|
|
domain+[('room_type_id', '=', room_type.id)]
|
|
)
|
|
if any(room_types_avail):
|
|
# Mail module want a singleton
|
|
for vr_avail in room_types_avail:
|
|
vr_avail.write(vals)
|
|
else:
|
|
vals.update({
|
|
'date': ndate.strftime(DEFAULT_SERVER_DATE_FORMAT),
|
|
'room_type_id': room_type.id
|
|
})
|
|
hotel_room_type_avail_obj.with_context({
|
|
'mail_create_nosubscribe': True,
|
|
}).create(vals)
|
|
|
|
@api.multi
|
|
def massive_change_close(self):
|
|
self._do_massive_change()
|
|
return True
|
|
|
|
@api.multi
|
|
def massive_change(self):
|
|
self._do_massive_change()
|
|
return {
|
|
"type": "ir.actions.do_nothing",
|
|
}
|
|
|
|
@api.multi
|
|
def _do_massive_change(self):
|
|
hotel_room_type_obj = self.env['hotel.room.type']
|
|
for record in self:
|
|
date_start_dt = date_utils.get_datetime(record.date_start,
|
|
hours=False)
|
|
# Use min '1' for same date
|
|
diff_days = date_utils.date_diff(record.date_start,
|
|
record.date_end,
|
|
hours=False) + 1
|
|
wedays = (record.dmo, record.dtu, record.dwe, record.dth,
|
|
record.dfr, record.dsa, record.dsu)
|
|
room_types = record.room_type_id if record.applied_on == '1' \
|
|
else hotel_room_type_obj.search([])
|
|
|
|
for i in range(0, diff_days):
|
|
ndate = date_start_dt + timedelta(days=i)
|
|
if not wedays[ndate.timetuple()[6]]:
|
|
continue
|
|
|
|
if record.section == '0':
|
|
self._save_availability(ndate, room_types, record)
|
|
elif record.section == '1':
|
|
self._save_restrictions(ndate, room_types, record)
|
|
elif record.section == '2':
|
|
self._save_prices(ndate, room_types, record)
|
|
return True
|