mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
[WIP][MIG][11.0] Hotel module review
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
|
||||
<record model="hotel.virtual.room.restriction">
|
||||
<record model="hotel.room.type.restriction">
|
||||
<field name="name">Default Restrictions</field>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -4356,7 +4356,7 @@ msgid "Gives the sequence order when displaying a product list"
|
||||
msgstr "Proporciona el orden de secuencia al mostrar una lista de productos"
|
||||
|
||||
#. module: hotel
|
||||
#: selection:hotel.virtual.room.restriction.item,applied_on:0
|
||||
#: selection:hotel.room.type.restriction.item,applied_on:0
|
||||
#: selection:hotel.wizard.massive.changes,applied_on:0
|
||||
msgid "Global"
|
||||
msgstr "Global"
|
||||
@@ -7285,7 +7285,7 @@ msgstr "Proveedores"
|
||||
|
||||
#. module: hotel
|
||||
#: selection:hotel.room,sale_price_type:0
|
||||
#: selection:hotel.virtual.room.restriction.item,applied_on:0
|
||||
#: selection:hotel.room.type.restriction.item,applied_on:0
|
||||
#: selection:hotel.wizard.massive.changes,applied_on:0
|
||||
#: model:ir.model.fields,field_description:hotel.field_hotel_virtual_room_availability_virtual_room_id
|
||||
#: model:ir.model.fields,field_description:hotel.field_hotel_virtual_room_restriction_item_virtual_room_id
|
||||
@@ -7585,8 +7585,8 @@ msgstr "hotel.virtual.room"
|
||||
|
||||
#. module: hotel
|
||||
#: model:ir.model,name:hotel.model_hotel_virtual_room_availability
|
||||
msgid "hotel.virtual.room.availability"
|
||||
msgstr "hotel.virtual.room.availability"
|
||||
msgid "hotel.room.type.availability"
|
||||
msgstr "hotel.room.type.availability"
|
||||
|
||||
#. module: hotel
|
||||
#: model:ir.model,name:hotel.model_hotel_virtual_room_availabity
|
||||
@@ -7595,13 +7595,13 @@ msgstr "hotel.virtual.room.availabity"
|
||||
|
||||
#. module: hotel
|
||||
#: model:ir.model,name:hotel.model_hotel_virtual_room_restriction
|
||||
msgid "hotel.virtual.room.restriction"
|
||||
msgstr "hotel.virtual.room.restriction"
|
||||
msgid "hotel.room.type.restriction"
|
||||
msgstr "hotel.room.type.restriction"
|
||||
|
||||
#. module: hotel
|
||||
#: model:ir.model,name:hotel.model_hotel_virtual_room_restriction_item
|
||||
msgid "hotel.virtual.room.restriction.item"
|
||||
msgstr "hotel.virtual.room.restriction.item"
|
||||
msgid "hotel.room.type.restriction.item"
|
||||
msgstr "hotel.room.type.restriction.item"
|
||||
|
||||
#. module: hotel
|
||||
#: model:ir.model,name:hotel.model_hotel_wizard_duplicate_reservation
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2018 Alexandre Díaz
|
||||
# Copyright 2018 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from . import currency_exchange
|
||||
@@ -21,11 +21,11 @@ from . import inherit_product_product
|
||||
from . import inherit_res_company
|
||||
# from . import virtual_room
|
||||
from . import inherit_account_payment
|
||||
from . import hotel_virtual_room_restriction
|
||||
from . import hotel_virtual_room_restriction_item
|
||||
from . import hotel_room_type_restriction
|
||||
from . import hotel_room_type_restriction_item
|
||||
from . import hotel_reservation_line
|
||||
from . import cardex
|
||||
from . import hotel_virtual_room_availability
|
||||
from . import hotel_room_type_availability
|
||||
from . import inherit_product_pricelist
|
||||
from . import res_config
|
||||
from . import inherit_res_partner
|
||||
|
||||
@@ -1,25 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2017 Solucións Aloxa S.L. <info@aloxa.eu>
|
||||
# Dario Lodeiros <>
|
||||
#
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# Copyright 2018 Alexandre Díaz
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
import datetime
|
||||
from openerp import models, fields, api, _
|
||||
from openerp.exceptions import except_orm, ValidationError
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2018 Dario Lodeiros
|
||||
# Copyright 2018 Alexandre Díaz
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from decimal import Decimal
|
||||
import time
|
||||
# For Python 3.0 and later
|
||||
from urllib.request import urlopen
|
||||
from openerp import models, fields, api, _
|
||||
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
|
||||
|
||||
class CurrencyExchangeRate(models.Model):
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2018 Alexandre Díaz
|
||||
# Copyright 2018 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
import json
|
||||
from datetime import datetime, timedelta
|
||||
@@ -11,17 +10,19 @@ from odoo.tools.misc import formatLang
|
||||
class HotelDashboard(models.Model):
|
||||
_name = "hotel.dashboard"
|
||||
|
||||
# FIXME
|
||||
def _get_count(self):
|
||||
resevations_count = self.env['hotel.reservation'].search(
|
||||
resevations_count = self.env['hotel.reservation'].search_count(
|
||||
[('sate', '=', 'confirm')])
|
||||
folios_count = self.env['hotel.folio'].search(
|
||||
folios_count = self.env['hotel.folio'].search_count(
|
||||
[('sate', '=', 'sales_order')])
|
||||
next_arrivals_count = self.env['hotel.reservation'].search(
|
||||
next_arrivals_count = self.env['hotel.reservation'].search_count(
|
||||
[('is_checkin', '=', True)])
|
||||
|
||||
self.orders_count = len(orders_count)
|
||||
self.quotations_count = len(quotations_count)
|
||||
self.orders_done_count = len(orders_done_count)
|
||||
|
||||
@api.one
|
||||
def _kanban_dashboard(self):
|
||||
if self.graph_type == 'bar':
|
||||
@@ -40,25 +41,33 @@ class HotelDashboard(models.Model):
|
||||
color = fields.Integer(string='Color Index')
|
||||
name = fields.Char(string="Name")
|
||||
type = fields.Char(default="sale")
|
||||
graph_type = fields.Selection([('line','Line'),('bar','Bar'),('none','None')])
|
||||
reservations_count = fields.Integer(compute = '_get_count')
|
||||
folios_count = fields.Integer(compute= '_get_count')
|
||||
next_arrivals_count = fields.Integer(compute= '_get_count')
|
||||
graph_type = fields.Selection([
|
||||
('line', 'Line'),
|
||||
('bar', 'Bar'),
|
||||
('none', 'None')])
|
||||
reservations_count = fields.Integer(compute='_get_count')
|
||||
folios_count = fields.Integer(compute='_get_count')
|
||||
next_arrivals_count = fields.Integer(compute='_get_count')
|
||||
kanban_dashboard = fields.Text(compute='_kanban_dashboard')
|
||||
kanban_dashboard_graph = fields.Text(compute='_kanban_dashboard_graph')
|
||||
show_on_dashboard = fields.Boolean(string='Show journal on dashboard', help="Whether this journal should be displayed on the dashboard or not", default=True)
|
||||
show_on_dashboard = fields.Boolean(
|
||||
string='Show journal on dashboard',
|
||||
help="Whether this journal should be displayed on the dashboard or not",
|
||||
default=True)
|
||||
|
||||
@api.multi
|
||||
def get_bar_graph_datas(self):
|
||||
data = []
|
||||
today = datetime.strptime(fields.Date.context_today(self), DF)
|
||||
day_of_week = int(format_datetime(today, 'e', locale=self._context.get('lang') or 'en_US'))
|
||||
for i in range(0,15):
|
||||
if i==0:
|
||||
for i in range(0, 15):
|
||||
if i == 0:
|
||||
label = _('Today')
|
||||
else:
|
||||
label = format_date(today + timedelta(days=i) , 'd', locale=self._context.get('lang') or 'en_US')
|
||||
data.append({'label':label,'value':0.0, 'type': 'past' if i<0 else 'future'})
|
||||
label = format_date(today + timedelta(days=i),
|
||||
'd',
|
||||
locale=self._context.get('lang') or 'en_US')
|
||||
data.append({'label':label, 'value':0.0, 'type': 'past' if i < 0 else 'future'})
|
||||
# Build SQL query to find amount aggregated by week
|
||||
select_sql_clause = """SELECT count(id) as total from hotel_reservation where state != 'cancelled'"""
|
||||
query = "("+select_sql_clause+" and date(checkin) = '"+today.strftime(DF)+"')"
|
||||
@@ -68,8 +77,8 @@ class HotelDashboard(models.Model):
|
||||
|
||||
self.env.cr.execute(query)
|
||||
query_results = self.env.cr.dictfetchall()
|
||||
for index in range(0, len(query_results)):
|
||||
data[index]['value'] = query_results[index].get('total')
|
||||
for index_k, index_v in enumerate(query_results):
|
||||
data[index_k]['value'] = index_v.get('total')
|
||||
return [{'values': data}]
|
||||
|
||||
@api.multi
|
||||
|
||||
@@ -1,30 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2017 Solucións Aloxa S.L. <info@aloxa.eu>
|
||||
# Dario Lodeiros <>
|
||||
#
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from openerp import models, fields, api, _
|
||||
|
||||
|
||||
class HotelFloor(models.Model):
|
||||
|
||||
_name = "hotel.floor"
|
||||
_description = "Ubication"
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# Copyright 2017-2018 Alexandre Díaz
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
import datetime
|
||||
from datetime import datetime
|
||||
import time
|
||||
import pytz
|
||||
import logging
|
||||
@@ -78,9 +77,9 @@ class HotelFolio(models.Model):
|
||||
help="Hotel room reservation detail.",)
|
||||
|
||||
service_line_ids = fields.One2many('hotel.service', 'folio_id',
|
||||
readonly=False,
|
||||
states={'done': [('readonly', True)]},
|
||||
help="Hotel services detail provide to "
|
||||
readonly=False,
|
||||
states={'done': [('readonly', True)]},
|
||||
help="Hotel services detail provide to "
|
||||
"customer and it will include in "
|
||||
"main Invoice.")
|
||||
hotel_invoice_id = fields.Many2one('account.invoice', 'Invoice')
|
||||
@@ -98,23 +97,21 @@ class HotelFolio(models.Model):
|
||||
'sent': [('readonly', False)]},
|
||||
help="Pricelist for current folio.")
|
||||
pending_amount = fields.Monetary(compute='compute_amount',
|
||||
store=True,
|
||||
string="Pending in Folio")
|
||||
store=True,
|
||||
string="Pending in Folio")
|
||||
refund_amount = fields.Monetary(compute='compute_amount',
|
||||
store=True,
|
||||
string="Payment Returns")
|
||||
invoices_paid = fields.Monetary(compute='compute_amount',
|
||||
store=True, track_visibility='onchange',
|
||||
string="Payments")
|
||||
store=True, track_visibility='onchange',
|
||||
string="Payments")
|
||||
|
||||
booking_pending = fields.Integer('Booking pending',
|
||||
compute='_compute_cardex_count')
|
||||
cardex_count = fields.Integer('Cardex counter',
|
||||
compute='_compute_cardex_count')
|
||||
cardex_pending = fields.Boolean('Cardex Pending',
|
||||
compute='_compute_cardex_count')
|
||||
cardex_pending_num = fields.Integer('Cardex Pending',
|
||||
compute='_compute_cardex_count')
|
||||
cardex_pending_count = fields.Integer('Cardex Pending',
|
||||
compute='_compute_cardex_count')
|
||||
checkins_reservations = fields.Integer('checkins reservations')
|
||||
checkouts_reservations = fields.Integer('checkouts reservations')
|
||||
partner_internal_comment = fields.Text(string='Internal Partner Notes',
|
||||
@@ -173,12 +170,11 @@ class HotelFolio(models.Model):
|
||||
sequence = fields.Integer(string='Sequence', default=10)
|
||||
# sale.order
|
||||
amount_total = fields.Float(string='Total', store=True, readonly=True,
|
||||
track_visibility='always')
|
||||
track_visibility='always')
|
||||
|
||||
def _computed_rooms_char(self):
|
||||
for record in self:
|
||||
rooms = ', '.join(record.mapped('room_lines.room_id.name'))
|
||||
record.rooms_char = rooms
|
||||
record.rooms_char = ', '.join(record.mapped('room_lines.room_id.name'))
|
||||
|
||||
@api.multi
|
||||
def _compute_num_invoices(self):
|
||||
@@ -219,9 +215,8 @@ class HotelFolio(models.Model):
|
||||
def action_payments(self):
|
||||
self.ensure_one()
|
||||
payments_obj = self.env['account.payment']
|
||||
payments = payments_obj.search([('folio_id','=',self.id)])
|
||||
payment_ids = payments.mapped('id')
|
||||
invoices = self.mapped('invoice_ids.id')
|
||||
payments = payments_obj.search([('folio_id', '=', self.id)])
|
||||
#invoices = self.mapped('invoice_ids.id')
|
||||
return{
|
||||
'name': _('Payments'),
|
||||
'view_type': 'form',
|
||||
@@ -229,7 +224,7 @@ class HotelFolio(models.Model):
|
||||
'res_model': 'account.payment',
|
||||
'target': 'new',
|
||||
'type': 'ir.actions.act_window',
|
||||
'domain': [('id', 'in', payment_ids)],
|
||||
'domain': [('id', 'in', payments.ids)],
|
||||
}
|
||||
|
||||
@api.multi
|
||||
@@ -251,16 +246,16 @@ class HotelFolio(models.Model):
|
||||
return_move_ids = []
|
||||
acc_pay_obj = self.env['account.payment']
|
||||
payments = acc_pay_obj.search([
|
||||
'|',
|
||||
('invoice_ids', 'in', self.invoice_ids.ids),
|
||||
('folio_id', '=', self.id)
|
||||
])
|
||||
'|',
|
||||
('invoice_ids', 'in', self.invoice_ids.ids),
|
||||
('folio_id', '=', self.id)
|
||||
])
|
||||
return_move_ids += self.invoice_ids.filtered(
|
||||
lambda invoice: invoice.type == 'out_refund').mapped(
|
||||
'payment_move_line_ids.move_id.id')
|
||||
return_lines = self.env['payment.return.line'].search([(
|
||||
'move_line_ids','in',payments.mapped(
|
||||
'move_line_ids.id'))])
|
||||
'payment_move_line_ids.move_id.id')
|
||||
return_lines = self.env['payment.return.line'].search([
|
||||
('move_line_ids', 'in', payments.mapped('move_line_ids.id')),
|
||||
])
|
||||
return_move_ids += return_lines.mapped('return_id.move_id.id')
|
||||
|
||||
return{
|
||||
@@ -323,19 +318,24 @@ class HotelFolio(models.Model):
|
||||
# }
|
||||
|
||||
@api.model
|
||||
def create(self, vals, check=True):
|
||||
def create(self, vals):
|
||||
if vals.get('name', _('New')) == _('New'):
|
||||
if 'company_id' in vals:
|
||||
vals['name'] = self.env['ir.sequence'].with_context(force_company=vals['company_id']).next_by_code('sale.order') or _('New')
|
||||
vals['name'] = self.env['ir.sequence'].with_context(
|
||||
force_company=vals['company_id']
|
||||
).next_by_code('sale.order') or _('New')
|
||||
else:
|
||||
vals['name'] = self.env['ir.sequence'].next_by_code('hotel.folio') or _('New')
|
||||
|
||||
# Makes sure partner_invoice_id' and 'pricelist_id' are defined
|
||||
if any(f not in vals for f in ['partner_invoice_id', 'partner_shipping_id', 'pricelist_id']):
|
||||
lfields = ('partner_invoice_id', 'partner_shipping_id', 'pricelist_id')
|
||||
if any(f not in vals for f in lfields):
|
||||
partner = self.env['res.partner'].browse(vals.get('partner_id'))
|
||||
addr = partner.address_get(['delivery', 'invoice'])
|
||||
vals['partner_invoice_id'] = vals.setdefault('partner_invoice_id', addr['invoice'])
|
||||
vals['pricelist_id'] = vals.setdefault('pricelist_id', partner.property_product_pricelist and partner.property_product_pricelist.id)
|
||||
vals['pricelist_id'] = vals.setdefault(
|
||||
'pricelist_id',
|
||||
partner.property_product_pricelist and partner.property_product_pricelist.id)
|
||||
result = super(HotelFolio, self).create(vals)
|
||||
return result
|
||||
|
||||
@@ -358,12 +358,15 @@ class HotelFolio(models.Model):
|
||||
|
||||
addr = self.partner_id.address_get(['invoice'])
|
||||
values = {
|
||||
'pricelist_id': self.partner_id.property_product_pricelist and self.partner_id.property_product_pricelist.id or False,
|
||||
'pricelist_id': self.partner_id.property_product_pricelist and \
|
||||
self.partner_id.property_product_pricelist.id or False,
|
||||
'partner_invoice_id': addr['invoice'],
|
||||
'user_id': self.partner_id.user_id.id or self.env.uid
|
||||
}
|
||||
if self.env['ir.config_parameter'].sudo().get_param('sale.use_sale_note') and self.env.user.company_id.sale_note:
|
||||
values['note'] = self.with_context(lang=self.partner_id.lang).env.user.company_id.sale_note
|
||||
if self.env['ir.config_parameter'].sudo().get_param('sale.use_sale_note') and \
|
||||
self.env.user.company_id.sale_note:
|
||||
values['note'] = self.with_context(
|
||||
lang=self.partner_id.lang).env.user.company_id.sale_note
|
||||
|
||||
if self.partner_id.team_id:
|
||||
values['team_id'] = self.partner_id.team_id.id
|
||||
@@ -409,10 +412,11 @@ class HotelFolio(models.Model):
|
||||
|
||||
@api.multi
|
||||
def action_done(self):
|
||||
for line in self.room_lines:
|
||||
room_lines = self.mapped('room_lines')
|
||||
for line in room_lines:
|
||||
if line.state == "booking":
|
||||
line.action_reservation_checkout()
|
||||
|
||||
|
||||
@api.multi
|
||||
def action_cancel(self):
|
||||
'''
|
||||
@@ -457,7 +461,7 @@ class HotelFolio(models.Model):
|
||||
'domain': [('reservation_id', 'in', rooms)],
|
||||
'target': 'new',
|
||||
}
|
||||
|
||||
|
||||
@api.model
|
||||
def daily_plan(self):
|
||||
_logger.info('daily_plan')
|
||||
@@ -486,26 +490,19 @@ class HotelFolio(models.Model):
|
||||
@api.multi
|
||||
def _compute_cardex_count(self):
|
||||
_logger.info('_compute_cardex_amount')
|
||||
for fol in self:
|
||||
num_cardex = 0
|
||||
pending = False
|
||||
if fol.reservation_type == 'normal':
|
||||
for reser in fol.room_lines:
|
||||
if reser.state != 'cancelled' and \
|
||||
not reser.parent_reservation:
|
||||
num_cardex += len(reser.cardex_ids)
|
||||
fol.cardex_count = num_cardex
|
||||
pending = 0
|
||||
for reser in fol.room_lines:
|
||||
if reser.state != 'cancelled' and \
|
||||
not reser.parent_reservation:
|
||||
pending += (reser.adults + reser.children) \
|
||||
- len(reser.cardex_ids)
|
||||
if pending <= 0:
|
||||
fol.cardex_pending = False
|
||||
else:
|
||||
fol.cardex_pending = True
|
||||
fol.cardex_pending_num = pending
|
||||
for record in self:
|
||||
if record.reservation_type == 'normal':
|
||||
write_vals = {}
|
||||
filtered_reservs = record.filtered(
|
||||
lambda x: x.room_lines.state != 'cancelled' and \
|
||||
not x.room_lines.parent_reservation)
|
||||
|
||||
mapped_cardex = filtered_reservs.mapped('cardex_ids.id')
|
||||
write_vals.update({'cardex_count': len(mapped_cardex)})
|
||||
mapped_cardex_count = filtered_reservs.mapped(
|
||||
lambda x: (x.adults + x.children) - len(x.cardex_ids))
|
||||
write_vals.update({'cardex_pending_count': sum(mapped_cardex_count)})
|
||||
record.write(write_vals)
|
||||
|
||||
"""
|
||||
MAILING PROCESS
|
||||
@@ -586,15 +583,15 @@ class HotelFolio(models.Model):
|
||||
self.ensure_one()
|
||||
ir_model_data = self.env['ir.model.data']
|
||||
try:
|
||||
template_id = (ir_model_data.get_object_reference
|
||||
('hotel',
|
||||
'mail_template_hotel_reservation')[1])
|
||||
template_id = ir_model_data.get_object_reference(
|
||||
'hotel',
|
||||
'mail_template_hotel_reservation')[1]
|
||||
except ValueError:
|
||||
template_id = False
|
||||
try:
|
||||
compose_form_id = (ir_model_data.get_object_reference
|
||||
('mail',
|
||||
'email_compose_message_wizard_form')[1])
|
||||
compose_form_id = ir_model_data.get_object_reference(
|
||||
'mail',
|
||||
'email_compose_message_wizard_form')[1]
|
||||
except ValueError:
|
||||
compose_form_id = False
|
||||
ctx = dict()
|
||||
@@ -632,15 +629,15 @@ class HotelFolio(models.Model):
|
||||
self.ensure_one()
|
||||
ir_model_data = self.env['ir.model.data']
|
||||
try:
|
||||
template_id = (ir_model_data.get_object_reference
|
||||
('hotel',
|
||||
'mail_template_hotel_exit')[1])
|
||||
template_id = ir_model_data.get_object_reference(
|
||||
'hotel',
|
||||
'mail_template_hotel_exit')[1]
|
||||
except ValueError:
|
||||
template_id = False
|
||||
try:
|
||||
compose_form_id = (ir_model_data.get_object_reference
|
||||
('mail',
|
||||
'email_compose_message_wizard_form')[1])
|
||||
compose_form_id = ir_model_data.get_object_reference(
|
||||
'mail',
|
||||
'email_compose_message_wizard_form')[1]
|
||||
except ValueError:
|
||||
compose_form_id = False
|
||||
ctx = dict()
|
||||
@@ -679,15 +676,15 @@ class HotelFolio(models.Model):
|
||||
self.ensure_one()
|
||||
ir_model_data = self.env['ir.model.data']
|
||||
try:
|
||||
template_id = (ir_model_data.get_object_reference
|
||||
('hotel',
|
||||
'mail_template_hotel_cancel')[1])
|
||||
template_id = ir_model_data.get_object_reference(
|
||||
'hotel',
|
||||
'mail_template_hotel_cancel')[1]
|
||||
except ValueError:
|
||||
template_id = False
|
||||
try:
|
||||
compose_form_id = (ir_model_data.get_object_reference
|
||||
('mail',
|
||||
'email_compose_message_wizard_form')[1])
|
||||
compose_form_id = ir_model_data.get_object_reference(
|
||||
'mail',
|
||||
'email_compose_message_wizard_form')[1]
|
||||
except ValueError:
|
||||
compose_form_id = False
|
||||
ctx = dict()
|
||||
@@ -722,15 +719,14 @@ class HotelFolio(models.Model):
|
||||
@param self: The object pointer
|
||||
@return: send a mail
|
||||
"""
|
||||
now_str = time.strftime(dt)
|
||||
now_date = datetime.strptime(now_str, dt)
|
||||
now_date = fields.Datetime.now()
|
||||
ir_model_data = self.env['ir.model.data']
|
||||
template_id = (ir_model_data.get_object_reference
|
||||
('hotel_reservation',
|
||||
'mail_template_reservation_reminder_24hrs')[1])
|
||||
template_id = ir_model_data.get_object_reference(
|
||||
'hotel_reservation',
|
||||
'mail_template_reservation_reminder_24hrs')[1]
|
||||
template_rec = self.env['mail.template'].browse(template_id)
|
||||
for reserv_rec in self.search([]):
|
||||
checkin_date = (datetime.strptime(reserv_rec.checkin, dt))
|
||||
checkin_date = datetime.strptime(reserv_rec.checkin, dt)
|
||||
difference = relativedelta(now_date, checkin_date)
|
||||
if(difference.days == -1 and reserv_rec.partner_id.email and
|
||||
reserv_rec.state == 'confirm'):
|
||||
@@ -742,11 +738,17 @@ class HotelFolio(models.Model):
|
||||
self.ensure_one()
|
||||
info_grouped = []
|
||||
for rline in self.room_lines:
|
||||
if (import_all or rline.to_send) and not rline.parent_reservation and rline.state == state:
|
||||
if (import_all or rline.to_send) and \
|
||||
not rline.parent_reservation and rline.state == state:
|
||||
dates = rline.get_real_checkin_checkout()
|
||||
vals = {
|
||||
'num': len(
|
||||
self.room_lines.filtered(lambda r: r.get_real_checkin_checkout()[0] == dates[0] and r.get_real_checkin_checkout()[1] == dates[1] and r.room_type_id.id == rline.room_type_id.id and (r.to_send or import_all) and not r.parent_reservation and r.state == rline.state)
|
||||
self.room_lines.filtered(
|
||||
lambda r: r.get_real_checkin_checkout()[0] == dates[0] and \
|
||||
r.get_real_checkin_checkout()[1] == dates[1] and \
|
||||
r.room_type_id.id == rline.room_type_id.id and \
|
||||
(r.to_send or import_all) and not r.parent_reservation and \
|
||||
r.state == rline.state)
|
||||
),
|
||||
'room_type': {
|
||||
'id': rline.room_type_id.id,
|
||||
@@ -760,10 +762,13 @@ class HotelFolio(models.Model):
|
||||
}
|
||||
founded = False
|
||||
for srline in info_grouped:
|
||||
if srline['num'] == vals['num'] and srline['room_type']['id'] == vals['room_type']['id'] and srline['checkin'] == vals['checkin'] and srline['checkout'] == vals['checkout']:
|
||||
if srline['num'] == vals['num'] and \
|
||||
srline['room_type']['id'] == vals['room_type']['id'] and \
|
||||
srline['checkin'] == vals['checkin'] and \
|
||||
srline['checkout'] == vals['checkout']:
|
||||
founded = True
|
||||
break
|
||||
if not founded:
|
||||
info_grouped.append(vals)
|
||||
return sorted(sorted(info_grouped, key=lambda k: k['num'], reverse=True), key=lambda k: k['room_type']['id'])
|
||||
|
||||
return sorted(sorted(info_grouped,key=lambda k: k['num'], reverse=True),
|
||||
key=lambda k: k['room_type']['id'])
|
||||
|
||||
@@ -1,24 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# Copyright 2017-2018 Alexandre Díaz
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo.exceptions import except_orm, UserError, ValidationError
|
||||
import logging
|
||||
import time
|
||||
from datetime import timedelta
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.tools import (
|
||||
misc,
|
||||
DEFAULT_SERVER_DATE_FORMAT,
|
||||
DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
from odoo import models, fields, api, _
|
||||
from decimal import Decimal
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from dateutil import tz
|
||||
from datetime import datetime, timedelta, date
|
||||
from odoo.addons import decimal_precision as dp
|
||||
from odoo.addons.hotel import date_utils
|
||||
import pytz
|
||||
import time
|
||||
import logging
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
from odoo.addons import decimal_precision as dp
|
||||
|
||||
class HotelReservation(models.Model):
|
||||
|
||||
@@ -48,7 +43,8 @@ class HotelReservation(models.Model):
|
||||
tz_hotel = self.env['ir.default'].sudo().get(
|
||||
'res.config.settings', 'tz_hotel')
|
||||
today = fields.Date.context_today(self.with_context(tz=tz_hotel))
|
||||
return (fields.Date.from_string(today) + timedelta(days=1)).strftime(DEFAULT_SERVER_DATE_FORMAT)
|
||||
return (fields.Date.from_string(today) + timedelta(days=1)).strftime(
|
||||
DEFAULT_SERVER_DATE_FORMAT)
|
||||
|
||||
def _get_default_arrival_hour(self):
|
||||
folio = False
|
||||
@@ -102,18 +98,17 @@ class HotelReservation(models.Model):
|
||||
# Has this reservation more charges associates in folio?, Yes?, then, this is share folio ;)
|
||||
for record in self:
|
||||
if record.folio_id:
|
||||
if len(record.folio_id.room_lines) > 1 or \
|
||||
record.folio_id.service_line_ids.filtered(lambda x: (
|
||||
x.ser_room_line != record.id)):
|
||||
record.shared_folio = True
|
||||
else:
|
||||
record.shared_folio = False
|
||||
record.shared_folio = len(record.folio_id.room_lines) > 1 or \
|
||||
any(record.folio_id.service_line_ids.filtered(
|
||||
lambda x: x.ser_room_line != record.id))
|
||||
|
||||
@api.depends('checkin', 'checkout')
|
||||
def _computed_nights(self):
|
||||
for res in self:
|
||||
if res.checkin and res.checkout:
|
||||
res.nights = (fields.Date.from_string(res.checkout) - fields.Date.from_string(res.checkin)).days
|
||||
res.nights = (
|
||||
fields.Date.from_string(res.checkout) - fields.Date.from_string(res.checkin)
|
||||
).days
|
||||
|
||||
_name = 'hotel.reservation'
|
||||
_description = 'Hotel Reservation'
|
||||
@@ -191,11 +186,9 @@ class HotelReservation(models.Model):
|
||||
# The value is a method name returning a Domains
|
||||
cardex_count = fields.Integer('Cardex counter',
|
||||
compute='_compute_cardex_count')
|
||||
cardex_pending = fields.Boolean('Cardex Pending',
|
||||
compute='_compute_cardex_count',
|
||||
search='_search_cardex_pending')
|
||||
cardex_pending_num = fields.Integer('Cardex Pending Num',
|
||||
compute='_compute_cardex_count')
|
||||
cardex_pending_count = fields.Integer('Cardex Pending Num',
|
||||
compute='_compute_cardex_count',
|
||||
search='_search_cardex_pending')
|
||||
# check_rooms = fields.Boolean('Check Rooms')
|
||||
is_checkin = fields.Boolean()
|
||||
is_checkout = fields.Boolean()
|
||||
@@ -226,29 +219,31 @@ class HotelReservation(models.Model):
|
||||
preconfirm = fields.Boolean('Auto confirm to Save', default=True)
|
||||
to_send = fields.Boolean('To Send', default=True)
|
||||
has_confirmed_reservations_to_send = fields.Boolean(
|
||||
related='folio_id.has_confirmed_reservations_to_send',
|
||||
readonly=True)
|
||||
related='folio_id.has_confirmed_reservations_to_send',
|
||||
readonly=True)
|
||||
has_cancelled_reservations_to_send = fields.Boolean(
|
||||
related='folio_id.has_cancelled_reservations_to_send',
|
||||
readonly=True)
|
||||
related='folio_id.has_cancelled_reservations_to_send',
|
||||
readonly=True)
|
||||
has_checkout_to_send = fields.Boolean(
|
||||
related='folio_id.has_checkout_to_send',
|
||||
readonly=True)
|
||||
related='folio_id.has_checkout_to_send',
|
||||
readonly=True)
|
||||
# order_line = fields.One2many('sale.order.line', 'order_id', string='Order Lines', states={'cancel': [('readonly', True)], 'done': [('readonly', True)]}, copy=True, auto_join=True)
|
||||
# product_id = fields.Many2one('product.product', related='order_line.product_id', string='Product')
|
||||
# product_uom = fields.Many2one('product.uom', string='Unit of Measure', required=True)
|
||||
# product_uom_qty = fields.Float(string='Quantity', digits=dp.get_precision('Product Unit of Measure'), required=True, default=1.0)
|
||||
|
||||
currency_id = fields.Many2one('res.currency',
|
||||
related='pricelist_id.currency_id',
|
||||
string='Currency', readonly=True, required=True)
|
||||
related='pricelist_id.currency_id',
|
||||
string='Currency', readonly=True, required=True)
|
||||
# invoice_status = fields.Selection([
|
||||
# ('upselling', 'Upselling Opportunity'),
|
||||
# ('invoiced', 'Fully Invoiced'),
|
||||
# ('to invoice', 'To Invoice'),
|
||||
# ('no', 'Nothing to Invoice')
|
||||
# ], string='Invoice Status', compute='_compute_invoice_status', store=True, readonly=True, default='no')
|
||||
tax_id = fields.Many2many('account.tax', string='Taxes', domain=['|', ('active', '=', False), ('active', '=', True)])
|
||||
tax_id = fields.Many2many('account.tax',
|
||||
string='Taxes',
|
||||
domain=['|', ('active', '=', False), ('active', '=', True)])
|
||||
# qty_to_invoice = fields.Float(
|
||||
# string='To Invoice', store=True, readonly=True,
|
||||
# digits=dp.get_precision('Product Unit of Measure'))
|
||||
@@ -257,9 +252,18 @@ class HotelReservation(models.Model):
|
||||
# digits=dp.get_precision('Product Unit of Measure'))
|
||||
# qty_delivered = fields.Float(string='Delivered', copy=False, digits=dp.get_precision('Product Unit of Measure'), default=0.0)
|
||||
# qty_delivered_updateable = fields.Boolean(compute='_compute_qty_delivered_updateable', string='Can Edit Delivered', readonly=True, default=True)
|
||||
price_subtotal = fields.Monetary(string='Subtotal', readonly=True, store=True, compute='_compute_amount_reservation')
|
||||
price_total = fields.Monetary(string='Total', readonly=True, store=True, compute='_compute_amount_reservation')
|
||||
price_tax = fields.Float(string='Taxes', readonly=True, store=True, compute='_compute_amount_reservation')
|
||||
price_subtotal = fields.Monetary(string='Subtotal',
|
||||
readonly=True,
|
||||
store=True,
|
||||
compute='_compute_amount_reservation')
|
||||
price_total = fields.Monetary(string='Total',
|
||||
readonly=True,
|
||||
store=True,
|
||||
compute='_compute_amount_reservation')
|
||||
price_tax = fields.Float(string='Taxes',
|
||||
readonly=True,
|
||||
store=True,
|
||||
compute='_compute_amount_reservation')
|
||||
# FIXME discount per night
|
||||
discount = fields.Float(string='Discount (%)', digits=dp.get_precision('Discount'), default=0.0)
|
||||
|
||||
@@ -286,11 +290,13 @@ class HotelReservation(models.Model):
|
||||
#~ 'reserve_color_text': colors[1],
|
||||
})
|
||||
if self.compute_price_out_vals(vals):
|
||||
days_diff = (fields.Date.from_string(vals['checkout']) - fields.Date.from_string(vals['checkin'])).days
|
||||
vals.update(record.prepare_reservation_lines(
|
||||
days_diff = (
|
||||
fields.Date.from_string(vals['checkout']) - fields.Date.from_string(vals['checkin'])
|
||||
).days
|
||||
vals.update(self.prepare_reservation_lines(
|
||||
vals['checkin'],
|
||||
days_diff,
|
||||
vals = vals)) #REVISAR el unlink
|
||||
vals=vals)) #REVISAR el unlink
|
||||
record = super(HotelReservation, self).create(vals)
|
||||
#~ if (record.state == 'draft' and record.folio_id.state == 'sale') or \
|
||||
#~ record.preconfirm:
|
||||
@@ -301,18 +307,22 @@ class HotelReservation(models.Model):
|
||||
def write(self, vals):
|
||||
if self.notify_update(vals):
|
||||
vals.update({
|
||||
'last_updated_res': date_utils.now(hours=True).strftime(DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
'last_updated_res': date_utils.now(hours=True).strftime(
|
||||
DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
})
|
||||
for record in self:
|
||||
if record.compute_price_out_vals(vals):
|
||||
days_diff = (fields.Date.from_string(record.checkout) - fields.Date.from_string(record.checkin)).days
|
||||
days_diff = (
|
||||
fields.Date.from_string(record.checkout) - \
|
||||
fields.Date.from_string(record.checkin)
|
||||
).days
|
||||
record.update(record.prepare_reservation_lines(
|
||||
vals['checkin'],
|
||||
days_diff,
|
||||
vals = vals)) #REVISAR el unlink
|
||||
vals=vals)) #REVISAR el unlink
|
||||
if ('checkin' in vals and record.checkin != vals['checkin']) or \
|
||||
('checkout' in vals and record.checkout != vals['checkout']) or \
|
||||
('state' in vals and record.state != vals['state']) :
|
||||
('state' in vals and record.state != vals['state']):
|
||||
vals.update({'to_send': True})
|
||||
res = super(HotelReservation, self).write(vals)
|
||||
return res
|
||||
@@ -321,9 +331,9 @@ class HotelReservation(models.Model):
|
||||
def _prepare_add_missing_fields(self, values):
|
||||
""" Deduce missing required fields from the onchange """
|
||||
res = {}
|
||||
onchange_fields = ['room_id', 'pricelist_id',
|
||||
'reservation_type', 'currency_id']
|
||||
if values.get('partner_id') and values.get('room_type_id') and any(f not in values for f in onchange_fields):
|
||||
onchange_fields = ['room_id', 'pricelist_id', 'reservation_type', 'currency_id']
|
||||
if values.get('partner_id') and values.get('room_type_id') and \
|
||||
any(f not in values for f in onchange_fields):
|
||||
line = self.new(values)
|
||||
line.onchange_room_id()
|
||||
for field in onchange_fields:
|
||||
@@ -345,7 +355,7 @@ class HotelReservation(models.Model):
|
||||
@api.multi
|
||||
def overbooking_button(self):
|
||||
self.ensure_one()
|
||||
return self.write({'overbooking': not self.overbooking})
|
||||
self.overbooking = not self.overbooking
|
||||
|
||||
@api.multi
|
||||
def open_folio(self):
|
||||
@@ -388,8 +398,8 @@ class HotelReservation(models.Model):
|
||||
def _check_adults(self):
|
||||
for record in self:
|
||||
if record.adults > record.room_id.capacity:
|
||||
raise ValidationError(
|
||||
_("Reservation persons can't be higher than room capacity"))
|
||||
raise ValidationError(
|
||||
_("Reservation persons can't be higher than room capacity"))
|
||||
if record.adults == 0:
|
||||
raise ValidationError(_("Reservation has no adults"))
|
||||
|
||||
@@ -399,22 +409,24 @@ class HotelReservation(models.Model):
|
||||
|
||||
@api.onchange('adults', 'room_id')
|
||||
def onchange_room_id(self):
|
||||
# TODO: Usar vals y write
|
||||
if self.room_id:
|
||||
write_vals = {}
|
||||
if self.room_id.capacity < self.adults:
|
||||
self.adults = self.room_id.capacity
|
||||
raise UserError(
|
||||
_('%s people do not fit in this room! ;)') % (persons))
|
||||
_('%s people do not fit in this room! ;)') % (self.adults))
|
||||
if self.adults == 0:
|
||||
self.adults = self.room_id.capacity
|
||||
if not self.room_type_id: #Si el registro no existe, modificar room_type aunque ya esté establecido
|
||||
self.room_type_id = self.room_id.room_type_id
|
||||
write_vals.update({'adults': self.room_id.capacity})
|
||||
#Si el registro no existe, modificar room_type aunque ya esté establecido
|
||||
if not self.room_type_id:
|
||||
write_vals.update({'room_type_id': self.room_id.room_type_id.id})
|
||||
self.write(write_vals)
|
||||
|
||||
@api.onchange('partner_id')
|
||||
def onchange_partner_id(self):
|
||||
#TODO: Change parity pricelist by default pricelist
|
||||
values = {
|
||||
'pricelist_id': self.partner_id.property_product_pricelist and self.partner_id.property_product_pricelist.id or \
|
||||
'pricelist_id': self.partner_id.property_product_pricelist and \
|
||||
self.partner_id.property_product_pricelist.id or \
|
||||
self.env['ir.default'].sudo().get('res.config.settings', 'parity_pricelist_id'),
|
||||
}
|
||||
self.update(values)
|
||||
@@ -423,11 +435,13 @@ class HotelReservation(models.Model):
|
||||
@api.onchange('room_type_id', 'pricelist_id', 'reservation_type')
|
||||
def onchange_overwrite_price_by_day(self):
|
||||
if self.room_type_id and self.checkin and self.checkout:
|
||||
days_diff = (fields.Date.from_string(self.checkout) - fields.Date.from_string(self.checkin)).days
|
||||
days_diff = (
|
||||
fields.Date.from_string(self.checkout) - fields.Date.from_string(self.checkin)
|
||||
).days
|
||||
self.update(self.prepare_reservation_lines(
|
||||
self.checkin,
|
||||
days_diff,
|
||||
update_old_prices = True))
|
||||
update_old_prices=True))
|
||||
|
||||
# When we need to update prices respecting those that were already established
|
||||
@api.onchange('checkin', 'checkout')
|
||||
@@ -439,15 +453,16 @@ class HotelReservation(models.Model):
|
||||
checkin_dt = fields.Date.from_string(self.checkin)
|
||||
checkout_dt = fields.Date.from_string(self.checkout)
|
||||
if checkin_dt >= checkout_dt:
|
||||
self.checkout = (fields.Date.from_string(self.checkin) + timedelta(days=1)).strftime(DEFAULT_SERVER_DATE_FORMAT)
|
||||
self.checkout = (fields.Date.from_string(self.checkin) + timedelta(days=1)).strftime(
|
||||
DEFAULT_SERVER_DATE_FORMAT)
|
||||
if self.room_type_id:
|
||||
days_diff = (fields.Date.from_string(self.checkout) - fields.Date.from_string(self.checkin)).days
|
||||
days_diff = (
|
||||
fields.Date.from_string(self.checkout) - fields.Date.from_string(self.checkin)
|
||||
).days
|
||||
self.update(self.prepare_reservation_lines(
|
||||
self.checkin,
|
||||
days_diff,
|
||||
update_old_prices = False))
|
||||
|
||||
|
||||
update_old_prices=False))
|
||||
|
||||
@api.onchange('checkin', 'checkout', 'room_type_id')
|
||||
def onchange_compute_reservation_description(self):
|
||||
@@ -468,8 +483,9 @@ class HotelReservation(models.Model):
|
||||
return
|
||||
occupied = self.env['hotel.reservation'].get_reservations(
|
||||
self.checkin,
|
||||
fields.Date.from_string(self.checkout).strftime(DEFAULT_SERVER_DATE_FORMAT)).filtered(
|
||||
lambda r: r.id != self._origin.id)
|
||||
fields.Date.from_string(self.checkout).strftime(
|
||||
DEFAULT_SERVER_DATE_FORMAT)).filtered(
|
||||
lambda r: r.id != self._origin.id)
|
||||
rooms_occupied = occupied.mapped('room_id.id')
|
||||
if self.room_id and self.room_id.id in rooms_occupied:
|
||||
warning_msg = _('You tried to change \
|
||||
@@ -488,7 +504,7 @@ class HotelReservation(models.Model):
|
||||
@api.multi
|
||||
def _generate_color(self):
|
||||
self.ensure_one()
|
||||
now_utc_dt = date_utils.now()
|
||||
now_utc_dt = fields.Datetime.now()
|
||||
# unused variables
|
||||
# diff_checkin_now = date_utils.date_diff(now_utc_dt, self.checkin,
|
||||
# hours=False)
|
||||
@@ -502,26 +518,22 @@ class HotelReservation(models.Model):
|
||||
return ('#4E9DC4', '#000000')
|
||||
|
||||
if self.reservation_type == 'staff':
|
||||
reserv_color = ir_values_obj.get('res.config.settings',
|
||||
'color_staff')
|
||||
reserv_color = ir_values_obj.get('res.config.settings', 'color_staff')
|
||||
reserv_color_text = ir_values_obj.get(
|
||||
'res.config.settings',
|
||||
'color_letter_staff')
|
||||
elif self.reservation_type == 'out':
|
||||
reserv_color = ir_values_obj.get('res.config.settings',
|
||||
'color_dontsell')
|
||||
reserv_color = ir_values_obj.get('res.config.settings', 'color_dontsell')
|
||||
reserv_color_text = ir_values_obj.get(
|
||||
'res.config.settings',
|
||||
'color_letter_dontsell')
|
||||
elif self.to_assign:
|
||||
reserv_color = ir_values_obj.get('res.config.settings',
|
||||
'color_to_assign')
|
||||
reserv_color = ir_values_obj.get('res.config.settings', 'color_to_assign')
|
||||
reserv_color_text = ir_values_obj.get(
|
||||
'res.config.settings',
|
||||
'color_letter_to_assign')
|
||||
elif self.state == 'draft':
|
||||
reserv_color = ir_values_obj.get('res.config.settings',
|
||||
'color_pre_reservation')
|
||||
reserv_color = ir_values_obj.get('res.config.settings', 'color_pre_reservation')
|
||||
reserv_color_text = ir_values_obj.get(
|
||||
'res.config.settings',
|
||||
'color_letter_pre_reservation')
|
||||
@@ -563,13 +575,13 @@ class HotelReservation(models.Model):
|
||||
@api.depends('state', 'reservation_type', 'folio_id.pending_amount', 'to_assign')
|
||||
def _compute_color(self):
|
||||
_logger.info('_compute_color')
|
||||
for rec in self:
|
||||
colors = rec._generate_color()
|
||||
rec.update({
|
||||
for record in self:
|
||||
colors = record._generate_color()
|
||||
record.update({
|
||||
'reserve_color': colors[0],
|
||||
'reserve_color_text': colors[1],
|
||||
})
|
||||
rec.folio_id.color = colors[0]
|
||||
record.folio_id.color = colors[0]
|
||||
|
||||
# hotel_reserv_obj = self.env['hotel.reservation']
|
||||
# if rec.splitted:
|
||||
@@ -595,27 +607,28 @@ class HotelReservation(models.Model):
|
||||
_logger.info('confirm')
|
||||
hotel_folio_obj = self.env['hotel.folio']
|
||||
hotel_reserv_obj = self.env['hotel.reservation']
|
||||
for r in self:
|
||||
for record in self:
|
||||
vals = {}
|
||||
if r.cardex_ids:
|
||||
if record.cardex_ids:
|
||||
vals.update({'state': 'booking'})
|
||||
else:
|
||||
vals.update({'state': 'confirm'})
|
||||
if r.checkin_is_today():
|
||||
if record.checkin_is_today():
|
||||
vals.update({'is_checkin': True})
|
||||
folio = hotel_folio_obj.browse(r.folio_id.id)
|
||||
folio = hotel_folio_obj.browse(record.folio_id.id)
|
||||
folio.checkins_reservations = folio.room_lines.search_count([
|
||||
('folio_id', '=', folio.id), ('is_checkin', '=', True)])
|
||||
r.write(vals)
|
||||
record.write(vals)
|
||||
|
||||
if r.splitted:
|
||||
master_reservation = r.parent_reservation or r
|
||||
if record.splitted:
|
||||
master_reservation = record.parent_reservation or record
|
||||
splitted_reservs = hotel_reserv_obj.search([
|
||||
('splitted', '=', True),
|
||||
'|', ('parent_reservation', '=', master_reservation.id),
|
||||
('id', '=', master_reservation.id),
|
||||
('folio_id', '=', r.folio_id.id),
|
||||
('id', '!=', r.id),
|
||||
'|',
|
||||
('parent_reservation', '=', master_reservation.id),
|
||||
('id', '=', master_reservation.id),
|
||||
('folio_id', '=', record.folio_id.id),
|
||||
('id', '!=', record.id),
|
||||
('state', '!=', 'confirm')
|
||||
])
|
||||
splitted_reservs.confirm()
|
||||
@@ -626,8 +639,8 @@ class HotelReservation(models.Model):
|
||||
'''
|
||||
@param self: object pointer
|
||||
'''
|
||||
for res in self:
|
||||
res.action_reservation_checkout()
|
||||
for record in self:
|
||||
record.action_reservation_checkout()
|
||||
return True
|
||||
|
||||
@api.multi
|
||||
@@ -649,8 +662,9 @@ class HotelReservation(models.Model):
|
||||
master_reservation = record.parent_reservation or record
|
||||
splitted_reservs = self.env['hotel.reservation'].search([
|
||||
('splitted', '=', True),
|
||||
'|', ('parent_reservation', '=', master_reservation.id),
|
||||
('id', '=', master_reservation.id),
|
||||
'|',
|
||||
('parent_reservation', '=', master_reservation.id),
|
||||
('id', '=', master_reservation.id),
|
||||
('folio_id', '=', record.folio_id.id),
|
||||
('id', '!=', record.id),
|
||||
('state', '!=', 'cancelled')
|
||||
@@ -661,14 +675,14 @@ class HotelReservation(models.Model):
|
||||
@api.multi
|
||||
def draft(self):
|
||||
for record in self:
|
||||
record.write({'state': 'draft'})
|
||||
|
||||
record.state = 'draft'
|
||||
if record.splitted:
|
||||
master_reservation = record.parent_reservation or record
|
||||
splitted_reservs = self.env['hotel.reservation'].search([
|
||||
('splitted', '=', True),
|
||||
'|', ('parent_reservation', '=', master_reservation.id),
|
||||
('id', '=', master_reservation.id),
|
||||
'|',
|
||||
('parent_reservation', '=', master_reservation.id),
|
||||
('id', '=', master_reservation.id),
|
||||
('folio_id', '=', record.folio_id.id),
|
||||
('id', '!=', record.id),
|
||||
('state', '!=', 'draft')
|
||||
@@ -696,21 +710,19 @@ class HotelReservation(models.Model):
|
||||
"""
|
||||
Compute the amounts of the reservation.
|
||||
"""
|
||||
for line in self:
|
||||
amount_room = 0
|
||||
for day in line.reservation_line_ids:
|
||||
amount_room += day.price
|
||||
for record in self:
|
||||
amount_room = sum(record.reservation_line_ids.mapped('price'))
|
||||
if amount_room > 0:
|
||||
product = line.room_type_id.product_id
|
||||
price = amount_room * (1 - (line.discount or 0.0) / 100.0)
|
||||
taxes = line.tax_id.compute_all(price, line.currency_id, 1, product=product)
|
||||
line.update({
|
||||
product = record.room_type_id.product_id
|
||||
price = amount_room * (1 - (record.discount or 0.0) * 0.01)
|
||||
taxes = record.tax_id.compute_all(price, record.currency_id, 1, product=product)
|
||||
record.update({
|
||||
'price_tax': sum(t.get('amount', 0.0) for t in taxes.get('taxes', [])),
|
||||
'price_total': taxes['total_included'],
|
||||
'price_subtotal': taxes['total_excluded'],
|
||||
})
|
||||
|
||||
@api.multi
|
||||
@api.model
|
||||
def prepare_reservation_lines(self, dfrom, days, vals=False, update_old_prices=False):
|
||||
total_price = 0.0
|
||||
cmds = [(5, 0, 0)]
|
||||
@@ -719,23 +731,24 @@ class HotelReservation(models.Model):
|
||||
pricelist_id = self.env['ir.default'].sudo().get(
|
||||
'res.config.settings', 'parity_pricelist_id')
|
||||
#~ pricelist_id = vals.get('pricelist_id') or self.pricelist_id.id
|
||||
product = self.env['hotel.room.type'].browse(vals.get('room_type_id') or self.room_type_id.id).product_id
|
||||
room_type_id = vals.get('room_type_id') or self.room_type_id.id
|
||||
product = self.env['hotel.room.type'].browse(room_type_id).product_id
|
||||
old_lines_days = self.mapped('reservation_line_ids.date')
|
||||
partner = self.env['res.partner'].browse(vals.get('partner_id') or self.partner_id.id)
|
||||
total_price = 0
|
||||
for i in range(0, days):
|
||||
idate = (fields.Date.from_string(dfrom) + timedelta(days=i)).strftime(DEFAULT_SERVER_DATE_FORMAT)
|
||||
idate = (fields.Date.from_string(dfrom) + timedelta(days=i)).strftime(
|
||||
DEFAULT_SERVER_DATE_FORMAT)
|
||||
old_line = self.reservation_line_ids.filtered(lambda r: r.date == idate)
|
||||
if update_old_prices or (idate not in old_lines_days):
|
||||
_logger.info("PASA 3")
|
||||
product = product.with_context(
|
||||
lang=partner.lang,
|
||||
partner=partner.id,
|
||||
quantity=1,
|
||||
date=idate,
|
||||
pricelist=pricelist_id,
|
||||
uom=product.uom_id.id)
|
||||
line_price = self.env['account.tax']._fix_tax_included_price_company(product.price, product.taxes_id, self.tax_id, self.company_id)
|
||||
lang=partner.lang,
|
||||
partner=partner.id,
|
||||
quantity=1,
|
||||
date=idate,
|
||||
pricelist=pricelist_id,
|
||||
uom=product.uom_id.id)
|
||||
line_price = self.env['account.tax']._fix_tax_included_price_company(
|
||||
product.price, product.taxes_id, self.tax_id, self.company_id)
|
||||
if old_line:
|
||||
cmds.append((1, old_line.id, {
|
||||
'price': line_price
|
||||
@@ -748,7 +761,6 @@ class HotelReservation(models.Model):
|
||||
else:
|
||||
line_price = old_line.price
|
||||
cmds.append((4, old_line.id))
|
||||
total_price += line_price
|
||||
return {'reservation_line_ids': cmds}
|
||||
|
||||
@api.multi
|
||||
@@ -798,7 +810,6 @@ class HotelReservation(models.Model):
|
||||
('reservation_line_ids.date', '<', dto),
|
||||
('state', '!=', 'cancelled'),
|
||||
('overbooking', '=', False)]
|
||||
reservations = self.env['hotel.reservation'].search(domain)
|
||||
return self.env['hotel.reservation'].search(domain)
|
||||
|
||||
@api.model
|
||||
@@ -860,21 +871,19 @@ class HotelReservation(models.Model):
|
||||
@api.multi
|
||||
def _compute_cardex_count(self):
|
||||
_logger.info('_compute_cardex_count')
|
||||
for res in self:
|
||||
res.cardex_count = len(res.cardex_ids)
|
||||
res.cardex_pending_num = (res.adults + res.children) \
|
||||
- len(res.cardex_ids)
|
||||
if (res.adults + res.children - len(res.cardex_ids)) <= 0:
|
||||
res.cardex_pending = False
|
||||
else:
|
||||
res.cardex_pending = True
|
||||
for record in self:
|
||||
record.write({
|
||||
'cardex_count': len(record.cardex_ids),
|
||||
'cardex_pending_count': (record.adults + record.children) \
|
||||
- len(record.cardex_ids)
|
||||
})
|
||||
|
||||
# https://www.odoo.com/es_ES/forum/ayuda-1/question/calculated-fields-in-search-filter-possible-118501
|
||||
@api.multi
|
||||
def _search_cardex_pending(self, operator, value):
|
||||
recs = self.search([]).filtered(lambda x: x.cardex_pending is True)
|
||||
if recs:
|
||||
return [('id', 'in', [x.id for x in recs])]
|
||||
self.ensure_one()
|
||||
recs = self.search([]).filtered(lambda x: x.cardex_pending_count > 0)
|
||||
return [('id', 'in', [x.id for x in recs])] if recs else []
|
||||
|
||||
@api.multi
|
||||
def action_reservation_checkout(self):
|
||||
@@ -908,8 +917,7 @@ class HotelReservation(models.Model):
|
||||
res.action_reservation_checkout()
|
||||
|
||||
reservations = self.env['hotel.reservation'].search([
|
||||
('reservation_line_ids.date', 'in', [today_str,
|
||||
yesterday_str]),
|
||||
('reservation_line_ids.date', 'in', [today_str, yesterday_str]),
|
||||
('state', 'in', ['confirm', 'booking'])
|
||||
])
|
||||
self._cr.execute("update hotel_reservation set is_checkin = False, \
|
||||
@@ -932,8 +940,7 @@ class HotelReservation(models.Model):
|
||||
@api.model
|
||||
def checkin_is_today(self):
|
||||
self.ensure_one()
|
||||
tz_hotel = self.env['ir.default'].sudo().get(
|
||||
'res.config.settings', 'tz_hotel')
|
||||
tz_hotel = self.env['ir.default'].sudo().get('res.config.settings', 'tz_hotel')
|
||||
today = fields.Date.context_today(self.with_context(tz=tz_hotel))
|
||||
return self.checkin == today
|
||||
|
||||
|
||||
@@ -1,26 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2017 Solucións Aloxa S.L. <info@aloxa.eu>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from odoo import models, fields, api, _
|
||||
# Copyright 2017-2018 Alexandre Díaz
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo import models, fields
|
||||
from odoo.addons import decimal_precision as dp
|
||||
from odoo.exceptions import except_orm, UserError, ValidationError
|
||||
|
||||
class HotelReservationLine(models.Model):
|
||||
_name = "hotel.reservation.line"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
@@ -12,7 +11,7 @@ class HotelRoom(models.Model):
|
||||
_name = 'hotel.room'
|
||||
_description = 'Hotel Room'
|
||||
_order = "sequence, room_type_id, name"
|
||||
|
||||
|
||||
name = fields.Char('Room Name', required=True)
|
||||
active = fields.Boolean('Active', default=True)
|
||||
sequence = fields.Integer('Sequence', default=0)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
@@ -6,7 +5,6 @@ from odoo import models, fields, api, _
|
||||
|
||||
|
||||
class HotelRoomAmenities(models.Model):
|
||||
|
||||
_name = 'hotel.room.amenities'
|
||||
_description = 'Room amenities'
|
||||
# The record's name
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
@@ -6,7 +5,6 @@ from odoo import models, fields, api, _
|
||||
|
||||
|
||||
class HotelRoomAmenitiesType(models.Model):
|
||||
|
||||
_name = 'hotel.room.amenities.type'
|
||||
_description = 'Amenities Type'
|
||||
# The record's name
|
||||
|
||||
@@ -1,20 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from decimal import Decimal
|
||||
from datetime import datetime, timedelta
|
||||
import dateutil.parser
|
||||
# For Python 3.0 and later
|
||||
from urllib.request import urlopen
|
||||
import time
|
||||
from odoo.exceptions import except_orm, UserError, ValidationError
|
||||
from odoo.tools import (
|
||||
misc,
|
||||
DEFAULT_SERVER_DATE_FORMAT,
|
||||
DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.addons.hotel import date_utils
|
||||
from odoo import models, fields, api
|
||||
|
||||
class HotelRoomType(models.Model):
|
||||
""" Before creating a 'room type', you need to consider the following:
|
||||
@@ -68,7 +55,7 @@ class HotelRoomType(models.Model):
|
||||
"""
|
||||
self.ensure_one()
|
||||
capacities = self.room_ids.mapped('capacity')
|
||||
return any(capacities) and min(capacities) or 0
|
||||
return min(capacities) if any(capacities) else 0
|
||||
|
||||
@api.model
|
||||
# TODO Rename to check_availability_room_type
|
||||
@@ -93,7 +80,7 @@ class HotelRoomType(models.Model):
|
||||
room_type_id = self.env['hotel.room.type'].search([
|
||||
('id', '=', room_type_id)
|
||||
])
|
||||
# QUESTION What linked represent? Rooms in this type ?
|
||||
# QUESTION What linked represent? Rooms in this type ?
|
||||
rooms_linked = self.room_ids
|
||||
free_rooms = free_rooms & rooms_linked
|
||||
return free_rooms.sorted(key=lambda r: r.sequence)
|
||||
@@ -106,9 +93,11 @@ class HotelRoomType(models.Model):
|
||||
@param vals: dictionary of fields value.
|
||||
@return: new record set for hotel room type.
|
||||
"""
|
||||
vals.update({'is_room_type': True})
|
||||
vals.update({'purchase_ok': False})
|
||||
vals.update({'type': 'service'})
|
||||
vals.update({
|
||||
'is_room_type': True,
|
||||
'purchase_ok': False,
|
||||
'type': 'service',
|
||||
})
|
||||
return super().create(vals)
|
||||
|
||||
@api.multi
|
||||
|
||||
@@ -1,33 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2017 Solucións Aloxa S.L. <info@aloxa.eu>
|
||||
# Alexandre Díaz <alex@aloxa.eu>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
import logging
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.exceptions import ValidationError
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class HotelVirtualRoomAvailability(models.Model):
|
||||
class HotelRoomTypeAvailability(models.Model):
|
||||
_inherit = 'mail.thread'
|
||||
_name = 'hotel.virtual.room.availability'
|
||||
_name = 'hotel.room.type.availability'
|
||||
|
||||
# virtual_room_id = fields.Many2one('hotel.virtual.room', 'Virtual Room',
|
||||
# required=True, track_visibility='always',
|
||||
@@ -41,16 +22,19 @@ class HotelVirtualRoomAvailability(models.Model):
|
||||
track_visibility='always')
|
||||
date = fields.Date('Date', required=True, track_visibility='always')
|
||||
|
||||
_sql_constraints = [('vroom_registry_unique', 'unique(room_type_id, date)',
|
||||
'Only can exists one availability in the same day for the same room type!')]
|
||||
_sql_constraints = [
|
||||
('room_type_registry_unique',
|
||||
'unique(room_type_id, date)',
|
||||
'Only can exists one availability in the same day for the same room type!')
|
||||
]
|
||||
|
||||
@api.constrains('avail')
|
||||
def _check_avail(self):
|
||||
if self.avail < 0:
|
||||
self.avail = 0
|
||||
|
||||
vroom_obj = self.env['hotel.room.type']
|
||||
cavail = len(vroom_obj.check_availability_virtual_room(
|
||||
room_type_obj = self.env['hotel.room.type']
|
||||
cavail = len(room_type_obj.check_availability_virtual_room(
|
||||
self.date,
|
||||
self.date,
|
||||
room_type_id=self.room_type_id.id))
|
||||
31
hotel/models/hotel_room_type_restriction.py
Normal file
31
hotel/models/hotel_room_type_restriction.py
Normal file
@@ -0,0 +1,31 @@
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo import models, fields, api
|
||||
|
||||
|
||||
class HotelRoomTypeRestriction(models.Model):
|
||||
_name = 'hotel.room.type.restriction'
|
||||
|
||||
name = fields.Char('Restriction Plan Name', required=True)
|
||||
item_ids = fields.One2many('hotel.room.type.restriction.item',
|
||||
'restriction_id', string='Restriction Items',
|
||||
copy=True)
|
||||
active = fields.Boolean('Active',
|
||||
help='If unchecked, it will allow you to hide the \
|
||||
restriction plan without removing it.',
|
||||
default=True)
|
||||
|
||||
@api.multi
|
||||
@api.depends('name')
|
||||
def name_get(self):
|
||||
restriction_id = self.env['ir.default'].sudo().get(
|
||||
'res.config.settings', 'parity_restrictions_id')
|
||||
if restriction_id:
|
||||
restriction_id = int(restriction_id)
|
||||
names = []
|
||||
for record in self:
|
||||
if record.id == restriction_id:
|
||||
names.append((record.id, '%s (Parity)' % record.name))
|
||||
else:
|
||||
names.append((record.id, record.name))
|
||||
return names
|
||||
@@ -1,24 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2017 Solucións Aloxa S.L. <info@aloxa.eu>
|
||||
# Alexandre Díaz <alex@aloxa.eu>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from datetime import datetime
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.exceptions import ValidationError
|
||||
@@ -26,10 +7,10 @@ from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
|
||||
from odoo.addons.hotel import date_utils
|
||||
|
||||
|
||||
class HotelVirtualRoomRestrictionItem(models.Model):
|
||||
_name = 'hotel.virtual.room.restriction.item'
|
||||
class HotelRoomTypeRestrictionItem(models.Model):
|
||||
_name = 'hotel.room.type.restriction.item'
|
||||
|
||||
restriction_id = fields.Many2one('hotel.virtual.room.restriction',
|
||||
restriction_id = fields.Many2one('hotel.room.type.restriction',
|
||||
'Restriction Plan', ondelete='cascade',
|
||||
index=True)
|
||||
# virtual_room_id = fields.Many2one('hotel.virtual.room', 'Virtual Room',
|
||||
@@ -54,7 +35,7 @@ class HotelVirtualRoomRestrictionItem(models.Model):
|
||||
closed_departure = fields.Boolean('Closed Departure')
|
||||
closed_arrival = fields.Boolean('Closed Arrival')
|
||||
|
||||
_sql_constraints = [('vroom_registry_unique',
|
||||
_sql_constraints = [('room_type_registry_unique',
|
||||
'unique(restriction_id, room_type_id, date_start, date_end)',
|
||||
'Only can exists one restriction in the same day for the same room type!')]
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
import time
|
||||
import datetime
|
||||
import logging
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.tools import misc, DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from odoo.addons.hotel import date_utils
|
||||
from odoo.addons import decimal_precision as dp
|
||||
from odoo import models, fields, api
|
||||
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
class HotelService(models.Model):
|
||||
@@ -29,8 +25,9 @@ class HotelService(models.Model):
|
||||
def _default_ser_room_line(self):
|
||||
if 'room_lines' in self.env.context and self.env.context['room_lines']:
|
||||
ids = [item[1] for item in self.env.context['room_lines']]
|
||||
return self.env['hotel.reservation'].search([('id', 'in', ids)],
|
||||
limit=1)
|
||||
return self.env['hotel.reservation'].search([
|
||||
('id', 'in', ids),
|
||||
], limit=1)
|
||||
return False
|
||||
|
||||
_name = 'hotel.service'
|
||||
@@ -56,9 +53,9 @@ class HotelService(models.Model):
|
||||
('web', 'Web')], 'Sales Channel')
|
||||
|
||||
ser_checkin = fields.Datetime('From Date', required=True,
|
||||
default=_service_checkin)
|
||||
default=_service_checkin)
|
||||
ser_checkout = fields.Datetime('To Date', required=True,
|
||||
default=_service_checkout)
|
||||
default=_service_checkout)
|
||||
|
||||
|
||||
# TODO Hierarchical relationship for parent-child tree
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
import time
|
||||
import datetime
|
||||
import logging
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.tools import misc, DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.addons.hotel import date_utils
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -14,6 +13,8 @@ from odoo.addons import decimal_precision as dp
|
||||
|
||||
|
||||
class HotelServiceLine(models.Model):
|
||||
_name = 'hotel.service.line'
|
||||
_description = 'hotel Service line'
|
||||
|
||||
@api.one
|
||||
def copy(self, default=None):
|
||||
@@ -32,10 +33,11 @@ class HotelServiceLine(models.Model):
|
||||
@param field_name: Names of fields.
|
||||
@param arg: User defined arguments
|
||||
'''
|
||||
for folio in self:
|
||||
line = folio.service_line_id
|
||||
x = line._amount_line(field_name, arg)
|
||||
return x
|
||||
total_amount = 0
|
||||
for record in self:
|
||||
line = record.service_line_id
|
||||
total_amount += line._amount_line(field_name, arg)
|
||||
return total_amount
|
||||
|
||||
@api.multi
|
||||
def _number_packages(self, field_name, arg):
|
||||
@@ -44,10 +46,11 @@ class HotelServiceLine(models.Model):
|
||||
@param field_name: Names of fields.
|
||||
@param arg: User defined arguments
|
||||
'''
|
||||
for folio in self:
|
||||
line = folio.service_line_id
|
||||
x = line._number_packages(field_name, arg)
|
||||
return x
|
||||
total_packages = 0
|
||||
for record in self:
|
||||
line = record.service_line_id
|
||||
total_packages = line._number_packages(field_name, arg)
|
||||
return total_packages
|
||||
|
||||
@api.model
|
||||
def _service_checkin(self):
|
||||
@@ -69,8 +72,6 @@ class HotelServiceLine(models.Model):
|
||||
limit=1)
|
||||
return False
|
||||
|
||||
_name = 'hotel.service.line'
|
||||
_description = 'hotel Service line'
|
||||
# The record's name
|
||||
name = fields.Char('Service line', required=True)
|
||||
# services in the hotel are products
|
||||
@@ -93,13 +94,14 @@ class HotelServiceLine(models.Model):
|
||||
('web','Web')], 'Sales Channel')
|
||||
|
||||
ser_checkin = fields.Datetime('From Date', required=True,
|
||||
default=_service_checkin)
|
||||
default=_service_checkin)
|
||||
ser_checkout = fields.Datetime('To Date', required=True,
|
||||
default=_service_checkout)
|
||||
ser_room_line = fields.Many2one('hotel.reservation','Room', default=_default_ser_room_line)
|
||||
default=_service_checkout)
|
||||
ser_room_line = fields.Many2one('hotel.reservation', 'Room',
|
||||
default=_default_ser_room_line)
|
||||
|
||||
@api.model
|
||||
def create(self, vals, check=True):
|
||||
def create(self, vals):
|
||||
"""
|
||||
Overrides orm create method.
|
||||
@param self: The object pointer
|
||||
@@ -134,14 +136,17 @@ class HotelServiceLine(models.Model):
|
||||
@param self: object pointer
|
||||
'''
|
||||
if self.product_id:
|
||||
write_vals = {}
|
||||
if not (self.folio_id and self.folio_id.partner_id) and \
|
||||
self.ser_room_line:
|
||||
self.folio_id = self.ser_room_line.folio_id
|
||||
|
||||
self.name = self.product_id.name
|
||||
self.price_unit = self.product_id.lst_price
|
||||
self.product_uom = self.product_id.uom_id
|
||||
self.price_unit = self.product_id.price
|
||||
write_vals.update({'folio_id': self.ser_room_line.folio_id.id})
|
||||
write_vals.update({
|
||||
'name': self.product_id.name,
|
||||
'price_unit': self.product_id.lst_price,
|
||||
'product_uom': self.product_id.uom_id,
|
||||
'price_unit': self.product_id.price,
|
||||
})
|
||||
self.write(write_vals)
|
||||
|
||||
#~ self.price_unit = tax_obj._fix_tax_included_price(prod.price,
|
||||
#~ prod.taxes_id,
|
||||
@@ -208,26 +213,23 @@ class HotelServiceLine(models.Model):
|
||||
if self.ser_checkin and self.ser_checkout:
|
||||
diffDate = date_utils.date_diff(self.ser_checkin,
|
||||
self.ser_checkout, hours=False) + 1
|
||||
# FIXME: Finalize method!
|
||||
|
||||
@api.multi
|
||||
def button_confirm(self):
|
||||
'''
|
||||
@param self: object pointer
|
||||
'''
|
||||
for folio in self:
|
||||
line = folio.service_line_id
|
||||
x = line.button_confirm()
|
||||
return x
|
||||
self.ensure_one()
|
||||
self.service_line_id.button_confirm()
|
||||
|
||||
@api.multi
|
||||
def button_done(self):
|
||||
'''
|
||||
@param self: object pointer
|
||||
'''
|
||||
for folio in self:
|
||||
line = folio.service_line_id
|
||||
x = line.button_done()
|
||||
return x
|
||||
self.ensure_one()
|
||||
self.service_line_id.button_done()
|
||||
|
||||
@api.one
|
||||
def copy_data(self, default=None):
|
||||
@@ -235,8 +237,7 @@ class HotelServiceLine(models.Model):
|
||||
@param self: object pointer
|
||||
@param default: dict of default values to be set
|
||||
'''
|
||||
sale_line_obj = self.env['sale.order.line'
|
||||
].browse(self.service_line_id.id)
|
||||
sale_line_obj = self.env['sale.order.line'].browse(self.service_line_id.id)
|
||||
return sale_line_obj.copy_data(default=default)
|
||||
|
||||
@api.multi
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
@@ -6,10 +5,9 @@ from odoo import models, fields, api, _
|
||||
|
||||
|
||||
class HotelServiceType(models.Model):
|
||||
|
||||
_name = "hotel.service.type"
|
||||
_description = "Service Type"
|
||||
# The record's name
|
||||
|
||||
name = fields.Char('Service Type', required=True)
|
||||
# Used for activate records
|
||||
active = fields.Boolean('Active?', default=True)
|
||||
@@ -19,7 +17,7 @@ class HotelServiceType(models.Model):
|
||||
service_ids = fields.One2many('hotel.services', 'service_type_id',
|
||||
'Services in this category')
|
||||
|
||||
@api.multi
|
||||
def unlink(self):
|
||||
# self.ser_id.unlink()
|
||||
return super(HotelServiceType, self).unlink()
|
||||
# @api.multi
|
||||
# def unlink(self):
|
||||
# # self.ser_id.unlink()
|
||||
# return super(HotelServiceType, self).unlink()
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2017 Solucións Aloxa S.L. <info@aloxa.eu>
|
||||
# Alexandre Díaz <alex@aloxa.eu>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from odoo import models, fields, api
|
||||
|
||||
|
||||
class VirtualRoomRestriction(models.Model):
|
||||
_name = 'hotel.virtual.room.restriction'
|
||||
|
||||
name = fields.Char('Restriction Plan Name', required=True)
|
||||
item_ids = fields.One2many('hotel.virtual.room.restriction.item',
|
||||
'restriction_id', string='Restriction Items',
|
||||
copy=True)
|
||||
active = fields.Boolean('Active',
|
||||
help='If unchecked, it will allow you to hide the \
|
||||
restriction plan without removing it.',
|
||||
default=True)
|
||||
|
||||
@api.multi
|
||||
@api.depends('name')
|
||||
def name_get(self):
|
||||
restriction_id = self.env['ir.default'].sudo().get(
|
||||
'res.config.settings', 'parity_restrictions_id')
|
||||
if restriction_id:
|
||||
restriction_id = int(restriction_id)
|
||||
names = []
|
||||
for record in self:
|
||||
if record.id == restriction_id:
|
||||
names.append((record.id, '%s (Parity)' % record.name))
|
||||
else:
|
||||
names.append((record.id, record.name))
|
||||
return names
|
||||
@@ -1,16 +1,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
|
||||
import logging
|
||||
from openerp import models, fields, api, _
|
||||
from openerp.exceptions import UserError, ValidationError
|
||||
|
||||
import logging
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AccountInvoice(models.Model):
|
||||
|
||||
_inherit = 'account.invoice'
|
||||
|
||||
@api.model
|
||||
@@ -64,7 +61,8 @@ class AccountInvoice(models.Model):
|
||||
|
||||
@api.multi
|
||||
def action_invoice_open(self):
|
||||
to_open_invoices_without_vat = self.filtered(lambda inv: inv.state != 'open' and inv.partner_id.vat == False)
|
||||
to_open_invoices_without_vat = self.filtered(
|
||||
lambda inv: inv.state != 'open' and inv.partner_id.vat == False)
|
||||
if to_open_invoices_without_vat:
|
||||
vat_error = _("We need the VAT of the following companies")
|
||||
for invoice in to_open_invoices_without_vat:
|
||||
|
||||
@@ -1,15 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from decimal import Decimal
|
||||
import datetime
|
||||
# For Python 3.0 and later
|
||||
from urllib.request import urlopen
|
||||
import time
|
||||
import logging
|
||||
from openerp.exceptions import except_orm, UserError, ValidationError
|
||||
from openerp.tools import misc, DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from openerp.exceptions import except_orm
|
||||
from openerp import models, fields, api, _
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -40,7 +32,7 @@ class AccountPayment(models.Model):
|
||||
}
|
||||
return_vals = {
|
||||
'journal_id': journal.id,
|
||||
'line_ids': [(0,0,return_line_vals)],
|
||||
'line_ids': [(0, 0, return_line_vals)],
|
||||
}
|
||||
return_pay = self.env['payment.return'].create(return_vals)
|
||||
return {
|
||||
@@ -73,6 +65,7 @@ class AccountPayment(models.Model):
|
||||
@api.multi
|
||||
@api.depends('state')
|
||||
def _compute_folio_amount(self):
|
||||
# FIXME: Finalize method
|
||||
res = []
|
||||
fol = ()
|
||||
for payment in self:
|
||||
@@ -84,7 +77,7 @@ class AccountPayment(models.Model):
|
||||
])
|
||||
else:
|
||||
return
|
||||
if len(fol) == 0:
|
||||
if not any(fol):
|
||||
return
|
||||
elif len(fol) > 1:
|
||||
raise except_orm(_('Warning'), _('This pay is related with \
|
||||
|
||||
@@ -1,28 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# --------------------------------------------------------------------------
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2018-Darío Lodeiros Vázquez
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
# ---------------------------------------------------------------------------
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from openerp import models, fields, api, _
|
||||
|
||||
|
||||
class PaymentReturn(models.Model):
|
||||
|
||||
_inherit = 'payment.return'
|
||||
|
||||
folio_id = fields.Many2one('hotel.folio', string='Folio')
|
||||
@@ -33,7 +14,9 @@ class PaymentReturn(models.Model):
|
||||
if pay:
|
||||
folio_ids = []
|
||||
for line in self.line_ids:
|
||||
payments = self.env['account.payment'].search([('move_line_ids','in',line.move_line_ids.ids)])
|
||||
folio_ids += payments.mapped('folio_id.id')
|
||||
payments = self.env['account.payment'].search([
|
||||
('move_line_ids', 'in', line.move_line_ids.ids)
|
||||
])
|
||||
folio_ids += payments.mapped('folio_id.id')
|
||||
folios = self.env['hotel.folio'].browse(folio_ids)
|
||||
folios.compute_amount()
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from openerp import models, fields, api, _
|
||||
|
||||
|
||||
class ProductCategory(models.Model):
|
||||
|
||||
_inherit = "product.category"
|
||||
|
||||
# isroomtype = fields.Boolean('Is Room Type')
|
||||
|
||||
@@ -1,23 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2017 Solucións Aloxa S.L. <info@aloxa.eu>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from openerp import models, api
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
@@ -6,7 +5,6 @@ from openerp import models, fields, api, _
|
||||
|
||||
|
||||
class ProductProduct(models.Model):
|
||||
|
||||
_inherit = "product.product"
|
||||
|
||||
is_room_type = fields.Boolean('Is a Room Type', default=False)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
@@ -6,7 +5,6 @@ from openerp import models, fields, api, _
|
||||
|
||||
|
||||
class ResCompany(models.Model):
|
||||
|
||||
_inherit = 'res.company'
|
||||
|
||||
additional_hours = fields.Integer('Additional Hours',
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
@@ -6,23 +5,22 @@ from openerp import models, fields, api, _
|
||||
|
||||
|
||||
class ResPartner(models.Model):
|
||||
|
||||
_inherit = 'res.partner'
|
||||
|
||||
reservations_count = fields.Integer('Reservations',
|
||||
compute='_compute_reservations_count')
|
||||
folios_count = fields.Integer('Folios', compute='_compute_folios_count')
|
||||
|
||||
def _compute_reservations_count(self):
|
||||
hotel_reservation_obj = self.env['hotel.reservation']
|
||||
for partner in self:
|
||||
partner.reservations_count = hotel_reservation_obj.search_count([
|
||||
('partner_id.id', '=', partner.id)
|
||||
for record in self:
|
||||
record.reservations_count = hotel_reservation_obj.search_count([
|
||||
('partner_id.id', '=', record.id)
|
||||
])
|
||||
|
||||
def _compute_folios_count(self):
|
||||
hotel_folio_obj = self.env['hotel.folio']
|
||||
for partner in self:
|
||||
partner.folios_count = hotel_folio_obj.search_count([
|
||||
('partner_id.id', '=', partner.id)
|
||||
for record in self:
|
||||
record.folios_count = hotel_folio_obj.search_count([
|
||||
('partner_id.id', '=', record.id)
|
||||
])
|
||||
|
||||
reservations_count = fields.Integer('Reservations',
|
||||
compute='_compute_reservations_count')
|
||||
folios_count = fields.Integer('Folios', compute='_compute_folios_count')
|
||||
|
||||
@@ -1,24 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2018 Alexandre Díaz <dev@redneboa.es>
|
||||
#
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import api, models
|
||||
|
||||
@@ -28,13 +9,14 @@ class MailComposeMessage(models.TransientModel):
|
||||
|
||||
@api.multi
|
||||
def send_mail(self, auto_commit=False):
|
||||
if self._context.get('default_model') == 'hotel.folio' and self._context.get('default_res_id') and self._context.get('mark_so_as_sent'):
|
||||
if self._context.get('default_model') == 'hotel.folio' and \
|
||||
self._context.get('default_res_id') and self._context.get('mark_so_as_sent'):
|
||||
folio = self.env['hotel.folio'].browse([
|
||||
self._context['default_res_id']
|
||||
])
|
||||
if folio:
|
||||
cmds = []
|
||||
for lid in folio.room_lines._ids:
|
||||
for lid in folio.room_lines.ids:
|
||||
cmds.append((
|
||||
1,
|
||||
lid,
|
||||
|
||||
@@ -1,24 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2017 Solucións Aloxa S.L. <info@aloxa.eu>
|
||||
# Alexandre Díaz <alex@aloxa.eu>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
# Copyright 2017-2018 Alexandre Díaz
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
import re
|
||||
import pytz
|
||||
from openerp import models, fields, api, _
|
||||
@@ -39,7 +21,7 @@ class HotelConfiguration(models.TransientModel):
|
||||
|
||||
parity_pricelist_id = fields.Many2one('product.pricelist',
|
||||
'Product Pricelist')
|
||||
parity_restrictions_id = fields.Many2one('hotel.virtual.room.restriction',
|
||||
parity_restrictions_id = fields.Many2one('hotel.room.type.restriction',
|
||||
'Restrictions')
|
||||
default_arrival_hour = fields.Char('Default Arrival Hour (GMT)',
|
||||
help="HH:mm Format", default="14:00")
|
||||
|
||||
@@ -84,7 +84,7 @@ class TestHotel(TestMail):
|
||||
cls._init_mock_hotel()
|
||||
|
||||
# Restriction Plan
|
||||
cls.restriction_1 = cls.env['hotel.virtual.room.restriction'].create({
|
||||
cls.restriction_1 = cls.env['hotel.room.type.restriction'].create({
|
||||
'name': 'Restriction Test #1',
|
||||
'active': True
|
||||
})
|
||||
@@ -221,8 +221,8 @@ class TestHotel(TestMail):
|
||||
cls.hotel_vroom_budget.id: budget_product_id.product_tmpl_id.id,
|
||||
cls.hotel_vroom_special.id: special_product_id.product_tmpl_id.id,
|
||||
}
|
||||
vroom_avail_obj = cls.env['hotel.virtual.room.availability']
|
||||
vroom_rest_item_obj = cls.env['hotel.virtual.room.restriction.item']
|
||||
vroom_avail_obj = cls.env['hotel.room.type.availability']
|
||||
vroom_rest_item_obj = cls.env['hotel.room.type.restriction.item']
|
||||
pricelist_item_obj = cls.env['product.pricelist.item']
|
||||
for k_vr, v_vr in cls.avails_tmp.iteritems():
|
||||
for i in range(0, len(v_vr)):
|
||||
|
||||
@@ -43,11 +43,11 @@
|
||||
id="cardex_smart_button"
|
||||
icon="fa-user-plus"
|
||||
name="%(launch_checkin_wizard_add)d"
|
||||
attrs="{'invisible': [('cardex_pending_num','<=',0)]}"
|
||||
attrs="{'invisible': [('cardex_pending_count','<=',0)]}"
|
||||
context="{'partner_id': partner_id,'reservation_ids': room_lines,
|
||||
'hidden_cardex': True, 'folio': active_id}">
|
||||
<div class="o_form_field o_stat_info">
|
||||
<span class="o_stat_value"><field name="cardex_pending_num"
|
||||
<span class="o_stat_value"><field name="cardex_pending_count"
|
||||
widget="statinfo" nolabel="1"/></span>
|
||||
<span class="o_stat_text">Pending Checks</span>
|
||||
</div>
|
||||
@@ -189,7 +189,7 @@
|
||||
context="{'partner_id': partner_id,'enter_date': checkin,
|
||||
'exit_date': checkout,'reservation_id': id, 'hidden_cardex': True, 'edit_cardex': True }"
|
||||
attrs="{'invisible':['|','|', ('state','not in',('confirm','booking')),
|
||||
('cardex_pending','=', False),('parent_reservation','!=',False)]}"
|
||||
('cardex_pending_count','=', 0),('parent_reservation','!=',False)]}"
|
||||
/>
|
||||
<field name="partner_id"/>
|
||||
<field name="splitted" invisible="1" />
|
||||
@@ -202,7 +202,7 @@
|
||||
<field name="checkout" widget="date"/>
|
||||
<field name="cardex_ids" invisible ="1"/>
|
||||
<field name="to_assign" invisible="1"/>
|
||||
<field name="cardex_pending" invisible="1"/>
|
||||
<field name="cardex_pending_count" invisible="1"/>
|
||||
<!-- <field name="qty_delivered" invisible="1"/> -->
|
||||
<!-- attrs="{'readonly': [('qty_delivered_updateable', '=', False)]}"/> -->
|
||||
<!-- <field name="qty_invoiced" invisible="1"/> -->
|
||||
@@ -339,7 +339,7 @@
|
||||
<group invisible="1">
|
||||
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
|
||||
<!-- <field name="check_rooms" invisible="1"/> -->
|
||||
<field name="cardex_pending" invisible="1"/>
|
||||
<field name="cardex_pending_count" invisible="1"/>
|
||||
<!-- <field name="pricelist_id" invisible="1"/> -->
|
||||
<field name="nights" invisible="1"/>
|
||||
</group>
|
||||
@@ -524,8 +524,7 @@
|
||||
<field name="invoices_paid"/>
|
||||
<field name="booking_pending"/>
|
||||
<field name="cardex_count"/>
|
||||
<field name="cardex_pending"/>
|
||||
<field name="cardex_pending_num"/>
|
||||
<field name="cardex_pending_count"/>
|
||||
<field name="checkins_reservations"/>
|
||||
<field name="checkouts_reservations"/>
|
||||
<field name="partner_internal_comment"/>
|
||||
@@ -541,7 +540,7 @@
|
||||
<ul>
|
||||
<li t-if="record.name.raw_value"><field name="name"/></li>
|
||||
<span t-if="record.cardex_count.value>0" class="badge"><i class="fa fa-fw fa-bed"/><t t-esc="record.cardex_count.value"/></span>
|
||||
<span t-if="record.cardex_pending_num.value>0" class="badge"><i class="fa fa-fw fa-user-plus"/><t t-esc="record.cardex_pending_num.value"/></span>
|
||||
<span t-if="record.cardex_pending_count.value>0" class="badge"><i class="fa fa-fw fa-user-plus"/><t t-esc="record.cardex_pending_count.value"/></span>
|
||||
</ul>
|
||||
<div class="oe_kanban_partner_links"/>
|
||||
</div>
|
||||
|
||||
@@ -129,9 +129,9 @@
|
||||
context="{'partner_id': partner_id,'enter_date': checkin,
|
||||
'exit_date': checkout,'reservation_id': id, 'hidden_cardex': True, 'edit_cardex': True }"
|
||||
attrs="{'invisible':['|', '|', ('state','not in',('confirm','booking')),
|
||||
('cardex_pending','=', False),('parent_reservation','!=',False)]}">
|
||||
('cardex_pending_count','=', 0),('parent_reservation','!=',False)]}">
|
||||
<div class="o_form_field o_stat_info">
|
||||
<span class="o_stat_value"><field name="cardex_pending_num"
|
||||
<span class="o_stat_value"><field name="cardex_pending_count"
|
||||
widget="statinfo" nolabel="1"/></span>
|
||||
<span class="o_stat_text">Pending Checks</span>
|
||||
</div>
|
||||
@@ -194,7 +194,7 @@
|
||||
</group>
|
||||
<group class="oe_subtotal_footer" style="margin-right: 20px; !important" colspan="2" name="reservation_total" string="Amounts" attrs="{'invisible':[('folio_id','=', False)]}">
|
||||
<!--
|
||||
<field name="discount" string="Room Discount" attrs="{'invisible': [('discount_type','=','fixed')]}" />
|
||||
<field name="discount" string="Room Discount" attrs="{'invisible': [('discount_type','=','fixed')]}" />
|
||||
-->
|
||||
<div class="oe_subtotal_footer_separator oe_inline o_td_label">
|
||||
<!--
|
||||
@@ -202,7 +202,7 @@
|
||||
-->
|
||||
<button name="%(action_hotel_massive_price_change_reservation_days)d" string="Massive Day Prices"
|
||||
type="action" class="oe_edit_only oe_link" icon="fa-bolt"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <field name="amount_discount" nolabel="1" widget='monetary' class="oe_subtotal_footer_separator" options="{'currency_field': 'currency_id'}"/> -->
|
||||
<!--
|
||||
<div class="oe_subtotal_footer_separator oe_inline o_td_label">
|
||||
@@ -215,7 +215,7 @@
|
||||
<field name="state" invisible="1"/>
|
||||
<!-- <field name="invoice_status" invisible="1"/> -->
|
||||
<!-- <field name="customer_lead" invisible="1"/> -->
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="price_subtotal" widget="monetary"/>
|
||||
</group>
|
||||
</group>
|
||||
@@ -223,7 +223,7 @@
|
||||
<group invisible="1">
|
||||
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
|
||||
<!-- <field name="check_rooms" invisible="1"/> -->
|
||||
<field name="cardex_pending" invisible="1"/>
|
||||
<field name="cardex_pending_count" invisible="1"/>
|
||||
<!-- <field name="pricelist_id" invisible="1"/> -->
|
||||
<field name="nights" invisible="1"/>
|
||||
<!-- <field name="product_uom" string="Rent(UOM)" invisible="1" /> -->
|
||||
@@ -326,7 +326,7 @@
|
||||
name="%(launch_checkin_wizard_add)d"
|
||||
context="{'partner_id': partner_id,'enter_date': checkin,
|
||||
'exit_date': checkout,'reservation_id': id, 'hidden_cardex': True, 'edit_cardex': True }"
|
||||
attrs="{'invisible':['|','|', ('state','not in',('confirm','booking')),('cardex_pending','=', False),('parent_reservation','!=',False)]}"
|
||||
attrs="{'invisible':['|','|', ('state','not in',('confirm','booking')),('cardex_pending_count','=', 0),('parent_reservation','!=',False)]}"
|
||||
/>
|
||||
<button type="action" class="oe_stat_button"
|
||||
icon="fa fa-2x fa-list-ul"
|
||||
@@ -347,7 +347,7 @@
|
||||
<field name="cardex_ids" invisible ="1"/>
|
||||
<field name="to_assign" invisible="1"/>
|
||||
<!-- cardex_smart_button attrs depends on cardex_pending to be showed -->
|
||||
<field name="cardex_pending" invisible="1"/>
|
||||
<field name="cardex_pending_count" invisible="1"/>
|
||||
<field name="folio_pending_amount" string="Folio Pending Amount"/>
|
||||
<button type="object" class="oe_stat_button"
|
||||
icon="fa fa-3x fa-money"
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
<!-- FORM restriction -->
|
||||
<record id="reservation_restriction_item_view_form" model="ir.ui.view">
|
||||
<field name="name">hotel.virtual.room.restriction.item.form</field>
|
||||
<field name="model">hotel.virtual.room.restriction.item</field>
|
||||
<field name="name">hotel.room.type.restriction.item.form</field>
|
||||
<field name="model">hotel.room.type.restriction.item</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Restrictions">
|
||||
<group>
|
||||
@@ -38,8 +38,8 @@
|
||||
|
||||
<!-- TREE restriction -->
|
||||
<record id="reservation_restriction_item_view_tree" model="ir.ui.view">
|
||||
<field name="name">hotel.virtual.room.restriction.item.tree</field>
|
||||
<field name="model">hotel.virtual.room.restriction.item</field>
|
||||
<field name="name">hotel.room.type.restriction.item.tree</field>
|
||||
<field name="model">hotel.room.type.restriction.item</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Restrictions">
|
||||
<field name="applied_on"/>
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
<!-- FORM restriction -->
|
||||
<record id="reservation_restriction_view_form" model="ir.ui.view">
|
||||
<field name="name">hotel.virtual.room.restriction.form</field>
|
||||
<field name="model">hotel.virtual.room.restriction</field>
|
||||
<field name="name">hotel.room.type.restriction.form</field>
|
||||
<field name="model">hotel.room.type.restriction</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Restrictions">
|
||||
<sheet>
|
||||
@@ -35,8 +35,8 @@
|
||||
|
||||
<!-- TREE restriction -->
|
||||
<record id="reservation_restriction_view_tree" model="ir.ui.view">
|
||||
<field name="name">hotel.virtual.room.restriction.tree</field>
|
||||
<field name="model">hotel.virtual.room.restriction</field>
|
||||
<field name="name">hotel.room.type.restriction.tree</field>
|
||||
<field name="model">hotel.room.type.restriction</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Restrictions">
|
||||
<field name="name"/>
|
||||
@@ -48,7 +48,7 @@
|
||||
<!-- Action of reservation restriction -->
|
||||
<record model="ir.actions.act_window" id="reservation_restriction_action">
|
||||
<field name="name">Reservation restrictions</field>
|
||||
<field name="res_model">hotel.virtual.room.restriction</field>
|
||||
<field name="res_model">hotel.room.type.restriction</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
<!-- FORM availability -->
|
||||
<record id="virtual_room_availability_view_form" model="ir.ui.view">
|
||||
<field name="name">hotel.virtual.room.availability.form</field>
|
||||
<field name="model">hotel.virtual.room.availability</field>
|
||||
<field name="name">hotel.room.type.availability.form</field>
|
||||
<field name="model">hotel.room.type.availability</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Availability">
|
||||
<sheet>
|
||||
@@ -29,8 +29,8 @@
|
||||
|
||||
<!-- TREE restriction -->
|
||||
<record id="virtual_room_availability_view_tree" model="ir.ui.view">
|
||||
<field name="name">hotel.virtual.room.availability.tree</field>
|
||||
<field name="model">hotel.virtual.room.availability</field>
|
||||
<field name="name">hotel.room.type.availability.tree</field>
|
||||
<field name="model">hotel.room.type.availability</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Restrictions">
|
||||
<!-- <field name="virtual_room_id" required="1"/> -->
|
||||
@@ -46,7 +46,7 @@
|
||||
<!-- Action of reservation restriction -->
|
||||
<record model="ir.actions.act_window" id="virtual_room_availability_action">
|
||||
<field name="name">Virtual Room Availability</field>
|
||||
<field name="res_model">hotel.virtual.room.availability</field>
|
||||
<field name="res_model">hotel.room.type.availability</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import logging
|
||||
from openerp import models, fields, api
|
||||
from openerp.exceptions import UserError
|
||||
from openerp.tools.translate import _
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Wizard(models.TransientModel):
|
||||
_name = 'checkin.wizard'
|
||||
|
||||
@@ -40,7 +36,8 @@ class Wizard(models.TransientModel):
|
||||
for res in reservations:
|
||||
# return the first room line with free space for a cardex
|
||||
# TODO: add 'done' to res.state condition... Maybe too restrictive right now
|
||||
if res.cardex_count < (res.adults + res.children) and res.state not in ["cancelled"]:
|
||||
if res.cardex_count < (res.adults + res.children) and \
|
||||
res.state not in ["cancelled"]:
|
||||
return res
|
||||
elif 'reservation_id' in self.env.context:
|
||||
return self.env['hotel.reservation'].browse(
|
||||
@@ -131,9 +128,8 @@ class Wizard(models.TransientModel):
|
||||
|
||||
op_select_partner = fields.Selection([
|
||||
('S', 'Select a partner for checkin'),
|
||||
('C', 'Create a new partner for checkin')],
|
||||
default='S',
|
||||
string='Partner for checkin')
|
||||
('C', 'Create a new partner for checkin')
|
||||
], default='S', string='Partner for checkin')
|
||||
# checkin mode:
|
||||
# 0 - no selection made by the user, so hide the client fields
|
||||
# 1 - select a client for update his values and do the checkin
|
||||
@@ -151,7 +147,7 @@ class Wizard(models.TransientModel):
|
||||
'email': self.email_cardex,
|
||||
'mobile': self.mobile_cardex,
|
||||
}
|
||||
self.partner_id.sudo().write(partner_vals);
|
||||
self.partner_id.sudo().write(partner_vals)
|
||||
elif self.op_select_partner == 'C':
|
||||
partner_vals = {
|
||||
'firstname': self.firstname_cardex,
|
||||
@@ -164,9 +160,9 @@ class Wizard(models.TransientModel):
|
||||
|
||||
# prepare checkin values
|
||||
cardex_val = {
|
||||
'partner_id': self.partner_id.id,
|
||||
'enter_date': self.enter_date,
|
||||
'exit_date': self.exit_date
|
||||
'partner_id': self.partner_id.id,
|
||||
'enter_date': self.enter_date,
|
||||
'exit_date': self.exit_date
|
||||
}
|
||||
record_id = self.env['hotel.reservation'].browse(
|
||||
self.reservation_id.id)
|
||||
@@ -207,19 +203,22 @@ class Wizard(models.TransientModel):
|
||||
@api.onchange('partner_id')
|
||||
def onchange_partner_id(self):
|
||||
# update partner fields
|
||||
self.firstname_cardex = self.partner_id.firstname;
|
||||
self.lastname_cardex = self.partner_id.lastname;
|
||||
self.email_cardex = self.partner_id.email;
|
||||
self.mobile_cardex = self.partner_id.mobile;
|
||||
write_vals = {
|
||||
'firstname_cardex': self.partner_id.firstname,
|
||||
'lastname_cardex': self.partner_id.lastname,
|
||||
'email_cardex': self.partner_id.email,
|
||||
'mobile_cardex': self.partner_id.mobile,
|
||||
}
|
||||
# show the checkin fields if a partner is selected
|
||||
if self.op_select_partner == 'S' and self.partner_id.id != False:
|
||||
self.checkin_mode = 1;
|
||||
write_vals.update({'checkin_mode': 1})
|
||||
self.write(write_vals)
|
||||
|
||||
@api.onchange('op_select_partner')
|
||||
def onchange_op_select_partner(self):
|
||||
# field one2many return false is record does not exist
|
||||
if self.op_select_partner == 'S' and self.partner_id.id != False:
|
||||
self.checkin_mode = 1;
|
||||
if self.op_select_partner == 'S' and self.partner_id.id:
|
||||
self.checkin_mode = 1
|
||||
# field one2many return 0 on empty record (nothing typed)
|
||||
elif self.op_select_partner == 'C' and self.partner_id.id == 0:
|
||||
self.checkin_mode = 2;
|
||||
self.checkin_mode = 2
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<group col="4">
|
||||
<field options="{'no_quick_create': True, 'no_create_edit' : True, 'no_open': True}"
|
||||
name="reservation_id" nolabel="1"
|
||||
domain="[('folio_id','=',context.get('folio')), ('state', '!=', 'cancelled'), ('cardex_pending', '=', True)]"
|
||||
domain="[('folio_id','=',context.get('folio')), ('state', '!=', 'cancelled'), ('cardex_pending_count', '>', 0)]"
|
||||
style="max-width: 95%; width: 32.2em"/>
|
||||
</group>
|
||||
<group col="4">
|
||||
|
||||
@@ -1,30 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2017 Solucións Aloxa S.L. <info@aloxa.eu>
|
||||
# Alexandre Díaz <dev@redneboa.es>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from datetime import datetime, timedelta
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# Copyright 2018 Alexandre Díaz
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from openerp.exceptions import ValidationError
|
||||
from openerp import models, fields, api, _
|
||||
from openerp.tools import (
|
||||
DEFAULT_SERVER_DATETIME_FORMAT,
|
||||
DEFAULT_SERVER_DATE_FORMAT)
|
||||
|
||||
|
||||
class DuplicateReservationWizard(models.TransientModel):
|
||||
@@ -44,16 +22,7 @@ class DuplicateReservationWizard(models.TransientModel):
|
||||
if reservation_id.splitted:
|
||||
raise ValidationError(_("Can't duplicate splitted reservations"))
|
||||
|
||||
hotel_room_obj = self.env['hotel.room']
|
||||
hotel_vroom_obj = self.env['hotel.virtual.room']
|
||||
|
||||
room_id = hotel_room_obj.search([
|
||||
('product_id', '=', reservation_id.product_id.id)
|
||||
], limit=1)
|
||||
vroom_ids = hotel_vroom_obj.search([
|
||||
'|', ('room_ids', 'in', [room_id.id]),
|
||||
('room_type_ids', 'in', [room_id.categ_id.id])
|
||||
])
|
||||
hotel_room_type_obj = self.env['hotel.room.type']
|
||||
|
||||
cmds_reservation_lines = []
|
||||
for rline in reservation_id.reservation_lines:
|
||||
@@ -63,41 +32,38 @@ class DuplicateReservationWizard(models.TransientModel):
|
||||
}))
|
||||
|
||||
# Check Input
|
||||
total_free_rooms = 0
|
||||
for vroom in vroom_ids:
|
||||
avails = otel_vroom_obj.check_availability_virtual_room(
|
||||
reservation_id.checkin,
|
||||
reservation_id.checkout,
|
||||
virtual_room_id=vroom.id)
|
||||
total_free_rooms += len(avails)
|
||||
avails = hotel_room_type_obj.check_availability_virtual_room(
|
||||
reservation_id.checkin,
|
||||
reservation_id.checkout,
|
||||
room_type_id=reservation_id.room_type_id.id)
|
||||
total_free_rooms = len(avails)
|
||||
|
||||
if total_free_rooms < self.num:
|
||||
raise ValidationError(_("Too much duplicated reservations! \
|
||||
There are no '%d' free rooms") % self.num)
|
||||
|
||||
for i in range(0, self.num):
|
||||
for vroom in vroom_ids:
|
||||
free_rooms = hotel_vroom_obj.check_availability_virtual_room(
|
||||
reservation_id.checkin,
|
||||
reservation_id.checkout,
|
||||
virtual_room_id=vroom.id)
|
||||
if any(free_rooms):
|
||||
new_reservation_id = hotel_reservation_obj.create({
|
||||
'product_id': free_rooms[0].product_id.id,
|
||||
'folio_id': reservation_id.folio_id.id,
|
||||
'checkin': reservation_id.checkin,
|
||||
'checkout': reservation_id.checkout,
|
||||
'adults': reservation_id.adults,
|
||||
'children': reservation_id.children,
|
||||
'name': reservation_id.name,
|
||||
'reservation_lines': cmds_reservation_lines,
|
||||
'price_unit': reservation_id.price_unit,
|
||||
})
|
||||
if new_reservation_id:
|
||||
rpartner_id = reservation_id.order_id.partner_id
|
||||
new_reservation_id.order_id.partner_id = rpartner_id
|
||||
break
|
||||
else:
|
||||
raise ValidationError(_("Unexpected Error: Can't found a \
|
||||
free room"))
|
||||
free_rooms = hotel_room_type_obj.check_availability_virtual_room(
|
||||
reservation_id.checkin,
|
||||
reservation_id.checkout,
|
||||
virtual_room_id=reservation_id.room_type_id.id)
|
||||
if any(free_rooms):
|
||||
new_reservation_id = hotel_reservation_obj.create({
|
||||
'room_id': free_rooms[0].id,
|
||||
'room_type_id': free_rooms[0].room_type_id.id,
|
||||
'folio_id': reservation_id.folio_id.id,
|
||||
'checkin': reservation_id.checkin,
|
||||
'checkout': reservation_id.checkout,
|
||||
'adults': reservation_id.adults,
|
||||
'children': reservation_id.children,
|
||||
'name': reservation_id.name,
|
||||
'reservation_lines': cmds_reservation_lines,
|
||||
})
|
||||
if new_reservation_id:
|
||||
rpartner_id = reservation_id.order_id.partner_id
|
||||
new_reservation_id.order_id.partner_id = rpartner_id
|
||||
break
|
||||
else:
|
||||
raise ValidationError(_("Unexpected Error: Can't found a \
|
||||
free room"))
|
||||
return True
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import time
|
||||
@@ -20,15 +19,16 @@ class FolioAdvancePaymentInv(models.TransientModel):
|
||||
if self._count() == 1:
|
||||
sale_obj = self.env['sale.order']
|
||||
folio_obj = self.env['hotel.folio']
|
||||
folio = folio_obj.browse(self._context.get('active_ids'))[0]
|
||||
order = sale_obj.browse(folio_obj.mapped('order_id.id'))
|
||||
if all([line.product_id.invoice_policy == 'order' for line in order.order_line]) or order.invoice_count:
|
||||
if all([line.product_id.invoice_policy == 'order' for line in order.order_line]) \
|
||||
or order.invoice_count:
|
||||
return 'all'
|
||||
return 'delivered'
|
||||
|
||||
@api.model
|
||||
def _default_product_id(self):
|
||||
product_id = self.env['ir.default'].sudo().get('sale.config.settings', 'deposit_product_id_setting')
|
||||
product_id = self.env['ir.default'].sudo().get('sale.config.settings',
|
||||
'deposit_product_id_setting')
|
||||
return self.env['product.product'].browse(product_id)
|
||||
|
||||
@api.model
|
||||
@@ -44,14 +44,21 @@ class FolioAdvancePaymentInv(models.TransientModel):
|
||||
('all', 'Invoiceable lines (deduct down payments)'),
|
||||
('percentage', 'Down payment (percentage)'),
|
||||
('fixed', 'Down payment (fixed amount)')
|
||||
], string='What do you want to invoice?', default=_get_advance_payment_method, required=True)
|
||||
product_id = fields.Many2one('product.product', string='Down Payment Product', domain=[('type', '=', 'service')],
|
||||
default=_default_product_id)
|
||||
], string='What do you want to invoice?', default=_get_advance_payment_method,
|
||||
required=True)
|
||||
product_id = fields.Many2one('product.product', string='Down Payment Product',
|
||||
domain=[('type', '=', 'service')], default=_default_product_id)
|
||||
count = fields.Integer(default=_count, string='# of Orders')
|
||||
amount = fields.Float('Down Payment Amount', digits=dp.get_precision('Account'), help="The amount to be invoiced in advance, taxes excluded.")
|
||||
deposit_account_id = fields.Many2one("account.account", string="Income Account", domain=[('deprecated', '=', False)],
|
||||
help="Account used for deposits", default=_default_deposit_account_id)
|
||||
deposit_taxes_id = fields.Many2many("account.tax", string="Customer Taxes", help="Taxes used for deposits", default=_default_deposit_taxes_id)
|
||||
amount = fields.Float('Down Payment Amount',
|
||||
digits=dp.get_precision('Account'),
|
||||
help="The amount to be invoiced in advance, taxes excluded.")
|
||||
deposit_account_id = fields.Many2one("account.account", string="Income Account",
|
||||
domain=[('deprecated', '=', False)],
|
||||
help="Account used for deposits",
|
||||
default=_default_deposit_account_id)
|
||||
deposit_taxes_id = fields.Many2many("account.tax", string="Customer Taxes",
|
||||
help="Taxes used for deposits",
|
||||
default=_default_deposit_taxes_id)
|
||||
|
||||
@api.onchange('advance_payment_method')
|
||||
def onchange_advance_payment_method(self):
|
||||
@@ -66,7 +73,8 @@ class FolioAdvancePaymentInv(models.TransientModel):
|
||||
|
||||
account_id = False
|
||||
if self.product_id.id:
|
||||
account_id = self.product_id.property_account_income_id.id or self.product_id.categ_id.property_account_income_categ_id.id
|
||||
account_id = self.product_id.property_account_income_id.id \
|
||||
or self.product_id.categ_id.property_account_income_categ_id.id
|
||||
if not account_id:
|
||||
inc_acc = ir_property_obj.get('property_account_income_categ_id', 'product.category')
|
||||
account_id = order.fiscal_position_id.map_account(inc_acc).id if inc_acc else False
|
||||
@@ -85,7 +93,8 @@ class FolioAdvancePaymentInv(models.TransientModel):
|
||||
amount = self.amount
|
||||
name = _('Down Payment')
|
||||
del context
|
||||
taxes = self.product_id.taxes_id.filtered(lambda r: not order.company_id or r.company_id == order.company_id)
|
||||
taxes = self.product_id.taxes_id.filtered(
|
||||
lambda r: not order.company_id or r.company_id == order.company_id)
|
||||
if order.fiscal_position_id and taxes:
|
||||
tax_ids = order.fiscal_position_id.map_tax(taxes).ids
|
||||
else:
|
||||
@@ -114,15 +123,17 @@ class FolioAdvancePaymentInv(models.TransientModel):
|
||||
})],
|
||||
'currency_id': order.pricelist_id.currency_id.id,
|
||||
'payment_term_id': order.payment_term_id.id,
|
||||
'fiscal_position_id': order.fiscal_position_id.id or order.partner_id.property_account_position_id.id,
|
||||
'fiscal_position_id': order.fiscal_position_id.id \
|
||||
or order.partner_id.property_account_position_id.id,
|
||||
'team_id': order.team_id.id,
|
||||
'user_id': order.user_id.id,
|
||||
'comment': order.note,
|
||||
})
|
||||
invoice.compute_taxes()
|
||||
invoice.message_post_with_view('mail.message_origin_link',
|
||||
values={'self': invoice, 'origin': order},
|
||||
subtype_id=self.env.ref('mail.mt_note').id)
|
||||
invoice.message_post_with_view(
|
||||
'mail.message_origin_link',
|
||||
values={'self': invoice, 'origin': order},
|
||||
subtype_id=self.env.ref('mail.mt_note').id)
|
||||
return invoice
|
||||
|
||||
@api.multi
|
||||
@@ -139,7 +150,10 @@ class FolioAdvancePaymentInv(models.TransientModel):
|
||||
if not self.product_id:
|
||||
vals = self._prepare_deposit_product()
|
||||
self.product_id = self.env['product.product'].create(vals)
|
||||
self.env['ir.default'].sudo().set('sale.config.settings', 'deposit_product_id_setting', self.product_id.id)
|
||||
self.env['ir.default'].sudo().set(
|
||||
'sale.config.settings',
|
||||
'deposit_product_id_setting',
|
||||
self.product_id.id)
|
||||
|
||||
sale_line_obj = self.env['sale.order.line']
|
||||
for order in sale_orders:
|
||||
@@ -151,7 +165,8 @@ class FolioAdvancePaymentInv(models.TransientModel):
|
||||
raise UserError(_('The product used to invoice a down payment should have an invoice policy set to "Ordered quantities". Please update your deposit product to be able to create a deposit invoice.'))
|
||||
if self.product_id.type != 'service':
|
||||
raise UserError(_("The product used to invoice a down payment should be of type 'Service'. Please use another product or update this product."))
|
||||
taxes = self.product_id.taxes_id.filtered(lambda r: not order.company_id or r.company_id == order.company_id)
|
||||
taxes = self.product_id.taxes_id.filtered(
|
||||
lambda r: not order.company_id or r.company_id == order.company_id)
|
||||
if order.fiscal_position_id and taxes:
|
||||
tax_ids = order.fiscal_position_id.map_tax(taxes).ids
|
||||
else:
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
@@ -1,26 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2017 Solucións Aloxa S.L. <info@aloxa.eu>
|
||||
# Alexandre Díaz <dev@redneboa.es>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from datetime import datetime, timedelta
|
||||
from openerp.exceptions import ValidationError
|
||||
# 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,
|
||||
@@ -53,7 +33,7 @@ class MassiveChangesWizard(models.TransientModel):
|
||||
# virtual_room_ids = fields.Many2many('hotel.virtual.room',
|
||||
# string="Virtual Rooms")
|
||||
room_type_ids = fields.Many2many('hotel.room.type',
|
||||
string="Room Types")
|
||||
string="Room Types")
|
||||
|
||||
# Availability fields
|
||||
change_avail = fields.Boolean(default=False)
|
||||
@@ -62,7 +42,7 @@ class MassiveChangesWizard(models.TransientModel):
|
||||
no_ota = fields.Boolean('No OTA', default=False)
|
||||
|
||||
# Restriction fields
|
||||
restriction_id = fields.Many2one('hotel.virtual.room.restriction',
|
||||
restriction_id = fields.Many2one('hotel.room.type.restriction',
|
||||
'Restriction Plan')
|
||||
change_min_stay = fields.Boolean(default=False)
|
||||
min_stay = fields.Integer("Min. Stay")
|
||||
@@ -95,8 +75,6 @@ class MassiveChangesWizard(models.TransientModel):
|
||||
@api.multi
|
||||
def is_valid_date(self, chkdate):
|
||||
self.ensure_one()
|
||||
date_start_dt = fields.Datetime.from_string(self.date_start)
|
||||
date_end_dt = fields.Datetime.from_string(self.date_end)
|
||||
wday = chkdate.timetuple()[6]
|
||||
wedays = (self.dmo, self.dtu, self.dwe, self.dth, self.dfr, self.dsa,
|
||||
self.dsu)
|
||||
@@ -104,17 +82,17 @@ class MassiveChangesWizard(models.TransientModel):
|
||||
and wedays[wday])
|
||||
|
||||
@api.model
|
||||
def _save_prices(self, ndate, vrooms, record):
|
||||
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 = (record.price[0] == '+') and 'ap' or 'sp'
|
||||
operation = 'ap' if (record.price[0] == '+') else 'sp'
|
||||
else:
|
||||
price = float(record.price[1:])
|
||||
operation = (record.price[0] == '+') and 'a' or 's'
|
||||
operation = 'a' if (record.price[0] == '+') else 's'
|
||||
else:
|
||||
if record.price[-1] == '%':
|
||||
price = float(record.price[:-1])
|
||||
@@ -126,17 +104,15 @@ class MassiveChangesWizard(models.TransientModel):
|
||||
domain = [
|
||||
('pricelist_id', '=', record.pricelist_id.id),
|
||||
('date_start', '>=', ndate.strftime(
|
||||
DEFAULT_SERVER_DATE_FORMAT)),
|
||||
DEFAULT_SERVER_DATE_FORMAT)),
|
||||
('date_end', '<=', ndate.strftime(
|
||||
DEFAULT_SERVER_DATE_FORMAT)),
|
||||
DEFAULT_SERVER_DATE_FORMAT)),
|
||||
('compute_price', '=', 'fixed'),
|
||||
('applied_on', '=', '1_product'),
|
||||
]
|
||||
|
||||
product_tmpl_ids = vrooms.mapped(
|
||||
'product_id.product_tmpl_id')
|
||||
for vroom in vrooms:
|
||||
prod_tmpl_id = vroom.product_id.product_tmpl_id
|
||||
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):
|
||||
@@ -161,17 +137,16 @@ class MassiveChangesWizard(models.TransientModel):
|
||||
product_pricelist_item_obj.create({
|
||||
'pricelist_id': record.pricelist_id.id,
|
||||
'date_start': ndate.strftime(
|
||||
DEFAULT_SERVER_DATE_FORMAT),
|
||||
DEFAULT_SERVER_DATE_FORMAT),
|
||||
'date_end': ndate.strftime(
|
||||
DEFAULT_SERVER_DATE_FORMAT),
|
||||
DEFAULT_SERVER_DATE_FORMAT),
|
||||
'compute_price': 'fixed',
|
||||
'applied_on': '1_product',
|
||||
'product_tmpl_id': prod_tmpl_id.id,
|
||||
'fixed_price': price,
|
||||
})
|
||||
|
||||
@api.model
|
||||
def _get_restrictions_values(self, ndate, vroom, record):
|
||||
def _get_restrictions_values(self, record):
|
||||
vals = {}
|
||||
if record.change_min_stay:
|
||||
vals.update({'min_stay': record.min_stay})
|
||||
@@ -190,8 +165,8 @@ class MassiveChangesWizard(models.TransientModel):
|
||||
return vals
|
||||
|
||||
@api.model
|
||||
def _save_restrictions(self, ndate, vrooms, record):
|
||||
hotel_vroom_re_it_obj = self.env['hotel.virtual.room.restriction.item']
|
||||
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)),
|
||||
@@ -199,13 +174,13 @@ class MassiveChangesWizard(models.TransientModel):
|
||||
('applied_on', '=', '0_virtual_room'),
|
||||
]
|
||||
|
||||
for vroom in vrooms:
|
||||
vals = self._get_restrictions_values(ndate, vroom, record)
|
||||
for room_type in room_types:
|
||||
vals = self._get_restrictions_values(record)
|
||||
if not any(vals):
|
||||
continue
|
||||
|
||||
rrest_item_ids = hotel_vroom_re_it_obj.search(
|
||||
domain+[('virtual_room_id', '=', vroom.id)])
|
||||
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:
|
||||
@@ -213,51 +188,50 @@ class MassiveChangesWizard(models.TransientModel):
|
||||
'date_start': ndate.strftime(DEFAULT_SERVER_DATE_FORMAT),
|
||||
'date_end': ndate.strftime(DEFAULT_SERVER_DATE_FORMAT),
|
||||
'restriction_id': record.restriction_id.id,
|
||||
'virtual_room_id': vroom.id,
|
||||
'room_type_id': room_type.id,
|
||||
'applied_on': '0_virtual_room',
|
||||
})
|
||||
hotel_vroom_re_it_obj.create(vals)
|
||||
hotel_room_type_re_it_obj.create(vals)
|
||||
|
||||
@api.model
|
||||
def _get_availability_values(self, ndate, vroom, record):
|
||||
hotel_vroom_obj = self.env['hotel.virtual.room']
|
||||
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_vroom_obj.check_availability_virtual_room(
|
||||
cavail = len(hotel_room_type_obj.check_availability_virtual_room(
|
||||
ndate.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
|
||||
ndate.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
|
||||
virtual_room_id=vroom.id))
|
||||
room_type_id=room_type.id))
|
||||
vals.update({
|
||||
'avail': min(cavail, vroom.total_rooms_count, record.avail),
|
||||
'avail': min(cavail, room_type.total_rooms_count, record.avail),
|
||||
})
|
||||
return vals
|
||||
|
||||
@api.model
|
||||
def _save_availability(self, ndate, vrooms, record):
|
||||
hotel_vroom_obj = self.env['hotel.virtual.room']
|
||||
hotel_vroom_avail_obj = self.env['hotel.virtual.room.availability']
|
||||
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 vroom in vrooms:
|
||||
vals = self._get_availability_values(ndate, vroom, record)
|
||||
for room_type in room_types:
|
||||
vals = self._get_availability_values(ndate, room_type, record)
|
||||
if not any(vals):
|
||||
continue
|
||||
|
||||
vrooms_avail = hotel_vroom_avail_obj.search(
|
||||
domain+[('virtual_room_id', '=', vroom.id)]
|
||||
room_types_avail = hotel_room_type_avail_obj.search(
|
||||
domain+[('room_type_id', '=', room_type.id)]
|
||||
)
|
||||
if any(vrooms_avail):
|
||||
if any(room_types_avail):
|
||||
# Mail module want a singleton
|
||||
for vr_avail in vrooms_avail:
|
||||
for vr_avail in room_types_avail:
|
||||
vr_avail.write(vals)
|
||||
else:
|
||||
vals.update({
|
||||
'date': ndate.strftime(DEFAULT_SERVER_DATE_FORMAT),
|
||||
'virtual_room_id': vroom.id
|
||||
'room_type_id': room_type.id
|
||||
})
|
||||
hotel_vroom_avail_obj.with_context({
|
||||
hotel_room_type_avail_obj.with_context({
|
||||
'mail_create_nosubscribe': True,
|
||||
}).create(vals)
|
||||
|
||||
@@ -275,7 +249,7 @@ class MassiveChangesWizard(models.TransientModel):
|
||||
|
||||
@api.multi
|
||||
def _do_massive_change(self):
|
||||
hotel_vroom_obj = self.env['hotel.virtual.room']
|
||||
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)
|
||||
@@ -285,8 +259,8 @@ class MassiveChangesWizard(models.TransientModel):
|
||||
hours=False) + 1
|
||||
wedays = (record.dmo, record.dtu, record.dwe, record.dth,
|
||||
record.dfr, record.dsa, record.dsu)
|
||||
vrooms = record.applied_on == '1' and record.room_type_id \
|
||||
or hotel_vroom_obj.search([])
|
||||
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)
|
||||
@@ -294,9 +268,9 @@ class MassiveChangesWizard(models.TransientModel):
|
||||
continue
|
||||
|
||||
if record.section == '0':
|
||||
self._save_availability(ndate, vrooms, record)
|
||||
self._save_availability(ndate, room_types, record)
|
||||
elif record.section == '1':
|
||||
self._save_restrictions(ndate, vrooms, record)
|
||||
self._save_restrictions(ndate, room_types, record)
|
||||
elif record.section == '2':
|
||||
self._save_prices(ndate, vrooms, record)
|
||||
self._save_prices(ndate, room_types, record)
|
||||
return True
|
||||
|
||||
@@ -1,24 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2017 Solucións Aloxa S.L. <info@aloxa.eu>
|
||||
# Alexandre Díaz <dev@redneboa.es>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from openerp import models, fields, api
|
||||
|
||||
|
||||
|
||||
@@ -1,26 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2017 Solucións Aloxa S.L. <info@aloxa.eu>
|
||||
# Alexandre Díaz <dev@redneboa.es>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
import logging
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import timedelta
|
||||
from openerp.exceptions import ValidationError
|
||||
from openerp import models, fields, api, _
|
||||
from openerp.tools import (
|
||||
@@ -38,7 +19,7 @@ class SplitReservationWizard(models.TransientModel):
|
||||
@api.multi
|
||||
def split_reservation(self):
|
||||
reservation_id = self.env['hotel.reservation'].browse(
|
||||
self.env.context.get('active_id'))
|
||||
self.env.context.get('active_id'))
|
||||
if reservation_id:
|
||||
date_start_dt = date_utils.get_datetime(reservation_id.checkin)
|
||||
date_end_dt = date_utils.get_datetime(reservation_id.checkout)
|
||||
@@ -72,8 +53,7 @@ class SplitReservationWizard(models.TransientModel):
|
||||
tprice[0] += rline.price
|
||||
|
||||
reservation_id.write({
|
||||
'checkout': new_start_date_dt.strftime(
|
||||
DEFAULT_SERVER_DATETIME_FORMAT),
|
||||
'checkout': new_start_date_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
|
||||
'price_unit': tprice[0],
|
||||
'splitted': True,
|
||||
})
|
||||
|
||||
@@ -1213,13 +1213,13 @@ msgstr "hotel.virtual.room"
|
||||
|
||||
#. module: hotel_calendar
|
||||
#: model:ir.model,name:hotel_calendar.model_hotel_virtual_room_availability
|
||||
msgid "hotel.virtual.room.availability"
|
||||
msgstr "hotel.virtual.room.availability"
|
||||
msgid "hotel.room.type.availability"
|
||||
msgstr "hotel.room.type.availability"
|
||||
|
||||
#. module: hotel_calendar
|
||||
#: model:ir.model,name:hotel_calendar.model_hotel_virtual_room_restriction_item
|
||||
msgid "hotel.virtual.room.restriction.item"
|
||||
msgstr "hotel.virtual.room.restriction.item"
|
||||
msgid "hotel.room.type.restriction.item"
|
||||
msgstr "hotel.room.type.restriction.item"
|
||||
|
||||
#. module: hotel_calendar
|
||||
#: model:ir.model,name:hotel_calendar.model_virtual_room_pricelist_cached
|
||||
|
||||
@@ -51,8 +51,8 @@ class HotelCalendarManagement(models.TransientModel):
|
||||
restrictions, availability):
|
||||
vroom_obj = self.env['hotel.room.type']
|
||||
product_pricelist_item_obj = self.env['product.pricelist.item']
|
||||
vroom_rest_item_obj = self.env['hotel.virtual.room.restriction.item']
|
||||
vroom_avail_obj = self.env['hotel.virtual.room.availability']
|
||||
vroom_rest_item_obj = self.env['hotel.room.type.restriction.item']
|
||||
vroom_avail_obj = self.env['hotel.room.type.availability']
|
||||
|
||||
# Save Pricelist
|
||||
for k_price in pricelist.keys():
|
||||
@@ -186,7 +186,7 @@ class HotelCalendarManagement(models.TransientModel):
|
||||
for i in range(0, date_diff):
|
||||
cur_date = date_start + timedelta(days=i)
|
||||
cur_date_str = cur_date.strftime(DEFAULT_SERVER_DATE_FORMAT)
|
||||
avail = self.env['hotel.virtual.room.availability'].search([
|
||||
avail = self.env['hotel.room.type.availability'].search([
|
||||
('date', '=', cur_date_str),
|
||||
('virtual_room_id', '=', vroom.id)
|
||||
])
|
||||
@@ -280,7 +280,7 @@ class HotelCalendarManagement(models.TransientModel):
|
||||
restriction_id = int(restriction_id)
|
||||
vals.update({'restriction_id': restriction_id})
|
||||
|
||||
vroom_rest_it_obj = self.env['hotel.virtual.room.restriction.item']
|
||||
vroom_rest_it_obj = self.env['hotel.room.type.restriction.item']
|
||||
restriction_item_ids = vroom_rest_it_obj.search([
|
||||
('date_start', '>=', dfrom), ('date_end', '<=', dto),
|
||||
('restriction_id', '=', restriction_id),
|
||||
|
||||
@@ -171,7 +171,7 @@ class HotelReservation(models.Model):
|
||||
room_type_ids = self.env['hotel.room.type'].search(
|
||||
[],
|
||||
order='hcal_sequence ASC')
|
||||
vroom_rest_obj = self.env['hotel.virtual.room.restriction.item']
|
||||
vroom_rest_obj = self.env['hotel.room.type.restriction.item']
|
||||
for room_type_id in room_type_ids:
|
||||
days = {}
|
||||
for i in range(0, date_diff):
|
||||
|
||||
@@ -4,7 +4,7 @@ from odoo import models, fields, api
|
||||
|
||||
|
||||
class HotelVirtualRoomAvailability(models.Model):
|
||||
_inherit = 'hotel.virtual.room.availability'
|
||||
_inherit = 'hotel.room.type.availability'
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
|
||||
@@ -6,7 +6,7 @@ _logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class HotelVirtualRoomResrtrictionItem(models.Model):
|
||||
_inherit = 'hotel.virtual.room.restriction.item'
|
||||
_inherit = 'hotel.room.type.restriction.item'
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
|
||||
@@ -49,7 +49,7 @@ return AbstractModel.extend({
|
||||
|
||||
get_restrictions: function () {
|
||||
return this._rpc({
|
||||
model: 'hotel.virtual.room.restriction',
|
||||
model: 'hotel.room.type.restriction',
|
||||
method: 'search_read',
|
||||
args: [false, ['id','name']],
|
||||
context: Session.user_context,
|
||||
|
||||
@@ -231,7 +231,7 @@ var HotelCalendarManagementView = View.extend({
|
||||
|
||||
// Get Restrictions
|
||||
self._restriction_id = results['restriction_id'];
|
||||
new Model('hotel.virtual.room.restriction').query(['id','name']).all().then(function(resultsRestrictions){
|
||||
new Model('hotel.room.type.restriction').query(['id','name']).all().then(function(resultsRestrictions){
|
||||
var $list = self.$el.find('#mpms-search #restriction_list');
|
||||
$list.html('');
|
||||
resultsRestrictions.forEach(function(item, index){
|
||||
|
||||
@@ -109,7 +109,7 @@ class TestManagementCalendar(TestHotelCalendar):
|
||||
doesn't match!")
|
||||
|
||||
# REMOVE RESTRICTIONS
|
||||
rest_it_obj = self.env['hotel.virtual.room.restriction.item'].sudo(
|
||||
rest_it_obj = self.env['hotel.room.type.restriction.item'].sudo(
|
||||
self.user_hotel_manager)
|
||||
rest_ids = rest_it_obj.search([
|
||||
('applied_on', '=', '0_virtual_room'),
|
||||
@@ -137,7 +137,7 @@ class TestManagementCalendar(TestHotelCalendar):
|
||||
|
||||
hotel_cal_mngt_obj = self.env['hotel.calendar.management'].sudo(
|
||||
self.user_hotel_manager)
|
||||
vroom_avail_obj = self.env['hotel.virtual.room.availability'].sudo(
|
||||
vroom_avail_obj = self.env['hotel.room.type.availability'].sudo(
|
||||
self.user_hotel_manager)
|
||||
|
||||
hcal_data = hotel_cal_mngt_obj.get_hcalendar_all_data(
|
||||
|
||||
@@ -345,10 +345,10 @@ class VirtualRoomWizars(models.TransientModel):
|
||||
date_start = date_utils.get_datetime(res.checkin)
|
||||
date_end = date_utils.get_datetime(res.checkout)
|
||||
date_diff = date_utils.date_diff(date_start, date_end, hours=False)
|
||||
minstay_restrictions = self.env['hotel.virtual.room.restriction.item'].search([
|
||||
minstay_restrictions = self.env['hotel.room.type.restriction.item'].search([
|
||||
('virtual_room_id','=',res.virtual_room_id.id),
|
||||
])
|
||||
avail_restrictions = self.env['hotel.virtual.room.availability'].search([
|
||||
avail_restrictions = self.env['hotel.room.type.availability'].search([
|
||||
('virtual_room_id','=',res.virtual_room_id.id)
|
||||
])
|
||||
real_max = len(res.virtual_room_id.check_availability_virtual_room(
|
||||
|
||||
@@ -53,8 +53,6 @@
|
||||
<field name="origin_sale"/>
|
||||
<field name="overbooking" invisible="1" />
|
||||
<field name="to_assign" invisible="1"/>
|
||||
<!-- cardex_smart_button attrs depends on cardex_pending to be showed -->
|
||||
<field name="cardex_pending" invisible="1"/>
|
||||
<field name="price_unit" string="Reservation Price"/>
|
||||
<field name="discount" groups="sale.group_discount_per_so_line"/>
|
||||
<field name="price_total" string="Final Price"/>
|
||||
|
||||
@@ -9,7 +9,7 @@ class HotelConnectorModelBinder(Component):
|
||||
_apply_on = [
|
||||
'channel.hotel.reservation',
|
||||
'channel.hotel.virtual.room',
|
||||
'channel.hotel.virtual.room.availability',
|
||||
'channel.hotel.virtual.room.restriction',
|
||||
'channel.hotel.room.type.availability',
|
||||
'channel.hotel.room.type.restriction',
|
||||
'channel.product.pricelist',
|
||||
]
|
||||
|
||||
@@ -23,7 +23,7 @@ class HotelChannelConnectorExporter(AbstractComponent):
|
||||
|
||||
@api.model
|
||||
def push_availability(self):
|
||||
vroom_avail_ids = self.env['hotel.virtual.room.availability'].search([
|
||||
vroom_avail_ids = self.env['hotel.room.type.availability'].search([
|
||||
('wpushed', '=', False),
|
||||
('date', '>=', date_utils.now(hours=False).strftime(
|
||||
DEFAULT_SERVER_DATE_FORMAT))
|
||||
@@ -110,8 +110,8 @@ class HotelChannelConnectorExporter(AbstractComponent):
|
||||
|
||||
@api.model
|
||||
def push_restrictions(self):
|
||||
vroom_rest_obj = self.env['hotel.virtual.room.restriction']
|
||||
rest_item_obj = self.env['hotel.virtual.room.restriction.item']
|
||||
vroom_rest_obj = self.env['hotel.room.type.restriction']
|
||||
rest_item_obj = self.env['hotel.room.type.restriction.item']
|
||||
unpushed = rest_item_obj.search([
|
||||
('wpushed', '=', False),
|
||||
('date_start', '>=', date_utils.now(hours=False).strftime(
|
||||
|
||||
@@ -17,7 +17,7 @@ class HotelChannelConnectorImporter(AbstractComponent):
|
||||
|
||||
@api.model
|
||||
def _get_room_values_availability(self, vroom_id, date_str, day_vals, set_max_avail):
|
||||
virtual_room_avail_obj = self.env['hotel.virtual.room.availability']
|
||||
virtual_room_avail_obj = self.env['hotel.room.type.availability']
|
||||
vroom_avail = virtual_room_avail_obj.search([
|
||||
('virtual_room_id', '=', vroom_id),
|
||||
('date', '=', date_str)
|
||||
@@ -46,7 +46,7 @@ class HotelChannelConnectorImporter(AbstractComponent):
|
||||
|
||||
@api.model
|
||||
def _get_room_values_restrictions(self, restriction_plan_id, vroom_id, date_str, day_vals):
|
||||
vroom_restr_item_obj = self.env['hotel.virtual.room.restriction.item']
|
||||
vroom_restr_item_obj = self.env['hotel.room.type.restriction.item']
|
||||
vroom_restr = vroom_restr_item_obj.search([
|
||||
('virtual_room_id', '=', vroom_id),
|
||||
('applied_on', '=', '0_virtual_room'),
|
||||
@@ -90,7 +90,7 @@ class HotelChannelConnectorImporter(AbstractComponent):
|
||||
|
||||
@api.model
|
||||
def _generate_room_values(self, dfrom, dto, values, set_max_avail=False):
|
||||
virtual_room_restr_obj = self.env['hotel.virtual.room.restriction']
|
||||
virtual_room_restr_obj = self.env['hotel.room.type.restriction']
|
||||
hotel_virtual_room_obj = self.env['hotel.room.type']
|
||||
def_restr_plan = virtual_room_restr_obj.search([('wpid', '=', '0')])
|
||||
_logger.info("==== ROOM VALUES (%s -- %s)", dfrom, dto)
|
||||
@@ -565,7 +565,7 @@ class HotelChannelConnectorImporter(AbstractComponent):
|
||||
|
||||
@api.model
|
||||
def _generate_restrictions(self, restriction_plans):
|
||||
restriction_obj = self.env['hotel.virtual.room.restriction']
|
||||
restriction_obj = self.env['hotel.room.type.restriction']
|
||||
count = 0
|
||||
for plan in restriction_plans:
|
||||
vals = {
|
||||
@@ -590,8 +590,8 @@ class HotelChannelConnectorImporter(AbstractComponent):
|
||||
@api.model
|
||||
def _generate_restriction_items(self, plan_restrictions):
|
||||
hotel_virtual_room_obj = self.env['hotel.room.type']
|
||||
reserv_restriction_obj = self.env['hotel.virtual.room.restriction']
|
||||
restriction_item_obj = self.env['hotel.virtual.room.restriction.item']
|
||||
reserv_restriction_obj = self.env['hotel.room.type.restriction']
|
||||
restriction_item_obj = self.env['hotel.room.type.restriction.item']
|
||||
_logger.info("===== RESTRICTIONS")
|
||||
_logger.info(plan_restrictions)
|
||||
for k_rpid, v_rpid in plan_restrictions.iteritems():
|
||||
|
||||
@@ -84,7 +84,7 @@ class website_wubook(http.Controller):
|
||||
parity_restr_id = request.env['ir.default'].sudo().get(
|
||||
'res.config.settings', 'parity_restrictions_id')
|
||||
if parity_restr_id:
|
||||
vroom_restr_obj = request.env['hotel.virtual.room.restriction']
|
||||
vroom_restr_obj = request.env['hotel.room.type.restriction']
|
||||
restr_id = vroom_restr_obj.sudo().browse(int(parity_restr_id))
|
||||
if restr_id and restr_id.wpid and restr_id.wpid != '0':
|
||||
wubook_obj.fetch_rplan_restrictions(dfrom, dto,
|
||||
|
||||
@@ -1023,18 +1023,18 @@ msgstr "hotel.virtual.room"
|
||||
|
||||
#. module: hotel_wubook_proto
|
||||
#: model:ir.model,name:hotel_wubook_proto.model_hotel_virtual_room_availability
|
||||
msgid "hotel.virtual.room.availability"
|
||||
msgstr "hotel.virtual.room.availability"
|
||||
msgid "hotel.room.type.availability"
|
||||
msgstr "hotel.room.type.availability"
|
||||
|
||||
#. module: hotel_wubook_proto
|
||||
#: model:ir.model,name:hotel_wubook_proto.model_hotel_virtual_room_restriction
|
||||
msgid "hotel.virtual.room.restriction"
|
||||
msgstr "hotel.virtual.room.restriction"
|
||||
msgid "hotel.room.type.restriction"
|
||||
msgstr "hotel.room.type.restriction"
|
||||
|
||||
#. module: hotel_wubook_proto
|
||||
#: model:ir.model,name:hotel_wubook_proto.model_hotel_virtual_room_restriction_item
|
||||
msgid "hotel.virtual.room.restriction.item"
|
||||
msgstr "hotel.virtual.room.restriction.item"
|
||||
msgid "hotel.room.type.restriction.item"
|
||||
msgstr "hotel.room.type.restriction.item"
|
||||
|
||||
#. module: hotel_wubook_proto
|
||||
#: model:ir.model,name:hotel_wubook_proto.model_hotel_wizard_duplicate_reservation
|
||||
|
||||
@@ -124,7 +124,7 @@ class HotelReservation(models.Model):
|
||||
if user.has_group('hotel.group_hotel_call'):
|
||||
vals.update({'to_read': True})
|
||||
res = super(HotelReservation, self).create(vals)
|
||||
self.env['hotel.virtual.room.availability'].refresh_availability(
|
||||
self.env['hotel.room.type.availability'].refresh_availability(
|
||||
vals['checkin'],
|
||||
vals['checkout'],
|
||||
vals['product_id'])
|
||||
@@ -155,7 +155,7 @@ class HotelReservation(models.Model):
|
||||
|
||||
res = super(HotelReservation, self).write(vals)
|
||||
|
||||
vroom_avail_obj = self.env['hotel.virtual.room.availability']
|
||||
vroom_avail_obj = self.env['hotel.room.type.availability']
|
||||
for i in range(0, len(older_vals)):
|
||||
vroom_avail_obj.refresh_availability(
|
||||
older_vals[i]['checkin'],
|
||||
@@ -183,7 +183,7 @@ class HotelReservation(models.Model):
|
||||
res = super(HotelReservation, self).unlink()
|
||||
if self._context.get('wubook_action', True) and \
|
||||
self.env['wubook'].is_valid_account():
|
||||
vroom_avail_obj = self.env['hotel.virtual.room.availability']
|
||||
vroom_avail_obj = self.env['hotel.room.type.availability']
|
||||
for record in vals:
|
||||
vroom_avail_obj.refresh_availability(
|
||||
record['checkin'],
|
||||
|
||||
@@ -118,7 +118,7 @@ class HotelRoomType(models.Model):
|
||||
restriction_plan_id = int(self.env['ir.default'].sudo().get(
|
||||
'res.config.settings', 'parity_restrictions_id'))
|
||||
self.ensure_one()
|
||||
restriction = self.env['hotel.virtual.room.restriction.item'].search([
|
||||
restriction = self.env['hotel.room.type.restriction.item'].search([
|
||||
('date_start', '=', date),
|
||||
('date_end', '=', date),
|
||||
('virtual_room_id', '=', self.id),
|
||||
|
||||
@@ -7,9 +7,9 @@ from odoo.addons.component.core import Component
|
||||
from odoo.addons.component_event import skip_if
|
||||
|
||||
class ChannelHotelVirtualRoomAvailability(models.Model):
|
||||
_name = 'channel.hotel.virtual.room.availability'
|
||||
_name = 'channel.hotel.room.type.availability'
|
||||
_inherit = 'channel.binding'
|
||||
_inherits = {'hotel.virtual.room.availability': 'odoo_id'}
|
||||
_inherits = {'hotel.room.type.availability': 'odoo_id'}
|
||||
_description = 'Channel Product Pricelist'
|
||||
|
||||
@api.model
|
||||
@@ -54,10 +54,10 @@ class ChannelHotelVirtualRoomAvailability(models.Model):
|
||||
}])
|
||||
|
||||
class HotelVirtualRoomAvailability(models.Model):
|
||||
_inherit = 'hotel.virtual.room.availability'
|
||||
_inherit = 'hotel.room.type.availability'
|
||||
|
||||
channel_bind_ids = fields.One2many(
|
||||
comodel_name='channel.hotel.virtual.room.availability',
|
||||
comodel_name='channel.hotel.room.type.availability',
|
||||
inverse_name='odoo_id',
|
||||
string='Hotel Virtual Room Availability Connector Bindings')
|
||||
|
||||
@@ -105,7 +105,7 @@ class HotelVirtualRoomAvailability(models.Model):
|
||||
date_diff = date_utils.date_diff(checkin, checkout, hours=False)
|
||||
|
||||
vroom_obj = self.env['hotel.virtual.room']
|
||||
virtual_room_avail_obj = self.env['hotel.virtual.room.availability']
|
||||
virtual_room_avail_obj = self.env['hotel.room.type.availability']
|
||||
|
||||
vrooms = vroom_obj.search([
|
||||
('room_ids.product_id', '=', product_id)
|
||||
@@ -138,9 +138,9 @@ class HotelVirtualRoomAvailability(models.Model):
|
||||
})
|
||||
|
||||
class ChannelBindingHotelVirtualRoomAvailabilityListener(Component):
|
||||
_name = 'channel.binding.hotel.virtual.room.availability.listener'
|
||||
_name = 'channel.binding.hotel.room.type.availability.listener'
|
||||
_inherit = 'base.connector.listener'
|
||||
_apply_on = ['channel.hotel.virtual.room.availability']
|
||||
_apply_on = ['channel.hotel.room.type.availability']
|
||||
|
||||
@skip_if(lambda self, record, **kwargs: self.no_connector_export(record))
|
||||
def on_fix_channel_availability(self, record, fields=None):
|
||||
|
||||
@@ -7,12 +7,12 @@ from odoo.addons.component.core import Component
|
||||
from odoo.addons.component_event import skip_if
|
||||
|
||||
class ChannelHotelVirtualRoomRestriction(models.Model):
|
||||
_name = 'channel.hotel.virtual.room.restriction'
|
||||
_name = 'channel.hotel.room.type.restriction'
|
||||
_inherit = 'channel.binding'
|
||||
_inherits = {'hotel.virtual.room.restriction': 'odoo_id'}
|
||||
_inherits = {'hotel.room.type.restriction': 'odoo_id'}
|
||||
_description = 'Channel Hotel Virtual Room Restriction'
|
||||
|
||||
odoo_id = fields.Many2one(comodel_names='hotel.virtual.room.restriction',
|
||||
odoo_id = fields.Many2one(comodel_names='hotel.room.type.restriction',
|
||||
string='Hotel Virtual Room Restriction',
|
||||
required=True,
|
||||
ondelete='cascade')
|
||||
@@ -71,17 +71,17 @@ class ChannelHotelVirtualRoomRestriction(models.Model):
|
||||
return importer.import_restriction_plans()
|
||||
|
||||
class HotelVirtualRoomRestriction(models.Model):
|
||||
_inherit = 'hotel.virtual.room.restriction'
|
||||
_inherit = 'hotel.room.type.restriction'
|
||||
|
||||
channel_bind_ids = fields.One2many(
|
||||
comodel_name='channel.hotel.virtual.room.restriction',
|
||||
comodel_name='channel.hotel.room.type.restriction',
|
||||
inverse_name='odoo_id',
|
||||
string='Hotel Channel Connector Bindings')
|
||||
|
||||
@api.multi
|
||||
@api.depends('name')
|
||||
def name_get(self):
|
||||
vroom_restriction_obj = self.env['hotel.virtual.room.restriction']
|
||||
vroom_restriction_obj = self.env['hotel.room.type.restriction']
|
||||
org_names = super(HotelVirtualRoomRestriction, self).name_get()
|
||||
names = []
|
||||
for name in org_names:
|
||||
@@ -93,9 +93,9 @@ class HotelVirtualRoomRestriction(models.Model):
|
||||
return names
|
||||
|
||||
class ChannelBindingHotelVirtualRoomRestrictionListener(Component):
|
||||
_name = 'channel.binding.hotel.virtual.room.restriction.listener'
|
||||
_name = 'channel.binding.hotel.room.type.restriction.listener'
|
||||
_inherit = 'base.connector.listener'
|
||||
_apply_on = ['channel.hotel.virtual.room.restriction']
|
||||
_apply_on = ['channel.hotel.room.type.restriction']
|
||||
|
||||
@skip_if(lambda self, record, **kwargs: self.no_connector_export(record))
|
||||
def on_record_write(self, record, fields=None):
|
||||
|
||||
@@ -5,7 +5,7 @@ from openerp import models, fields, api
|
||||
|
||||
|
||||
class ReservationRestrictionItem(models.Model):
|
||||
_inherit = 'hotel.virtual.room.restriction.item'
|
||||
_inherit = 'hotel.room.type.restriction.item'
|
||||
|
||||
channel_pushed = fields.Boolean("WuBook Pushed", default=False, readonly=True,
|
||||
old_name='wpushed')
|
||||
|
||||
@@ -77,7 +77,7 @@ class HotelChannelConnectorConfiguration(models.TransientModel):
|
||||
'wscode': '',
|
||||
})
|
||||
# Create Restrictions
|
||||
vroom_rest_obj = self.env['hotel.virtual.room.restriction']
|
||||
vroom_rest_obj = self.env['hotel.room.type.restriction']
|
||||
restriction_ids = vroom_rest_obj.search([])
|
||||
for restriction in restriction_ids:
|
||||
if restriction.wpid != '0':
|
||||
@@ -119,7 +119,7 @@ class HotelChannelConnectorConfiguration(models.TransientModel):
|
||||
restriction_id = int(self.env['ir.default'].sudo().get(
|
||||
'res.config.settings', 'parity_restrictions_id'))
|
||||
|
||||
vroom_restr_it_obj = self.env['hotel.virtual.room.restriction.item']
|
||||
vroom_restr_it_obj = self.env['hotel.room.type.restriction.item']
|
||||
# Secure Wubook Input
|
||||
restriction_item_ids = vroom_restr_it_obj.search([
|
||||
('applied_on', '=', '0_virtual_room'),
|
||||
@@ -165,7 +165,7 @@ class HotelChannelConnectorConfiguration(models.TransientModel):
|
||||
})
|
||||
|
||||
# Secure Wubook Input
|
||||
availabity_ids = self.env['hotel.virtual.room.availability'].search([
|
||||
availabity_ids = self.env['hotel.room.type.availability'].search([
|
||||
('date', '<', now_utc_str),
|
||||
])
|
||||
if any(availabity_ids):
|
||||
@@ -173,7 +173,7 @@ class HotelChannelConnectorConfiguration(models.TransientModel):
|
||||
'wpushed': True
|
||||
})
|
||||
# Put to push availability
|
||||
availabity_ids = self.env['hotel.virtual.room.availability'].search([
|
||||
availabity_ids = self.env['hotel.room.type.availability'].search([
|
||||
('wpushed', '=', True),
|
||||
('date', '>=', now_utc_str),
|
||||
])
|
||||
|
||||
@@ -171,12 +171,12 @@ ListView.include({
|
||||
} else if (this.dataset.model === 'wubook.channel.info') {
|
||||
this.$buttons.append("<button class='oe_button oe_channel_connector_import_channels_info oe_highlight' type='button'>"+_t('Fetch from Channel')+"</button>");
|
||||
this.$buttons.find('.oe_channel_connector_import_channels_info').on('click', import_channels_info.bind(this));
|
||||
} else if (this.dataset.model === 'hotel.virtual.room.restriction') {
|
||||
} else if (this.dataset.model === 'hotel.room.type.restriction') {
|
||||
this.$buttons.append("<button class='oe_button oe_channel_connector_import_restriction_plans oe_highlight' type='button'>"+_t('Fetch from Channel')+"</button>");
|
||||
this.$buttons.find('.oe_channel_connector_import_restriction_plans').on('click', import_restriction_plans.bind(this));
|
||||
this.$buttons.append("<button class='oe_button oe_channel_connector_push_restriction_plans' style='background-color:red; color:white;' type='button'>"+_t('Push to Channel')+"</button>");
|
||||
this.$buttons.find('.oe_channel_connector_push_restriction_plans').on('click', push_restriction_plans.bind(this));
|
||||
} else if (this.dataset.model === 'hotel.virtual.room.availability') {
|
||||
} else if (this.dataset.model === 'hotel.room.type.availability') {
|
||||
this.$buttons.append("<button class='oe_button oe_channel_connector_import_availability oe_highlight' type='button'>"+_t('Fetch from Channel')+"</button>");
|
||||
this.$buttons.find('.oe_channel_connector_import_availability').on('click', import_availability.bind(this));
|
||||
this.$buttons.append("<button class='oe_button oe_channel_connector_push_availability' style='background-color:red; color:white;' type='button'>"+_t('Push to Channel')+"</button>");
|
||||
|
||||
@@ -252,7 +252,7 @@ class TestHotelWubook(TestHotel):
|
||||
})
|
||||
|
||||
# Update Restriction
|
||||
vroom_restr_obj = cls.env['hotel.virtual.room.restriction']
|
||||
vroom_restr_obj = cls.env['hotel.room.type.restriction']
|
||||
default_restriction = vroom_restr_obj.search([
|
||||
('wpid', '=', '0')
|
||||
], limit=1)
|
||||
|
||||
@@ -34,7 +34,7 @@ class TestReservationRestrictionItem(TestHotelWubook):
|
||||
now_utc_dt = date_utils.now()
|
||||
day_utc_dt = now_utc_dt + timedelta(days=20)
|
||||
day_utc_str = day_utc_dt.strftime(DEFAULT_SERVER_DATE_FORMAT)
|
||||
rest_item_obj = self.env['hotel.virtual.room.restriction.item']
|
||||
rest_item_obj = self.env['hotel.room.type.restriction.item']
|
||||
restriction = rest_item_obj.search([], limit=1)
|
||||
self.assertTrue(restriction, "Can't found restriction for test")
|
||||
restriction.write({
|
||||
|
||||
@@ -33,7 +33,7 @@ class TestReservationRestriction(TestHotelWubook):
|
||||
self.assertTrue(any(wrests), "Any restriction found")
|
||||
|
||||
def test_create(self):
|
||||
vroo_restriction_obj = self.env['hotel.virtual.room.restriction']
|
||||
vroo_restriction_obj = self.env['hotel.room.type.restriction']
|
||||
# Restriction Plan
|
||||
restriction = vroo_restriction_obj.sudo(self.user_hotel_manager).\
|
||||
create({
|
||||
@@ -43,7 +43,7 @@ class TestReservationRestriction(TestHotelWubook):
|
||||
self.assertTrue(restriction, "Can't create new restriction")
|
||||
|
||||
def test_write(self):
|
||||
vroo_restriction_obj = self.env['hotel.virtual.room.restriction']
|
||||
vroo_restriction_obj = self.env['hotel.room.type.restriction']
|
||||
# Restriction Plan
|
||||
restriction = vroo_restriction_obj.sudo(self.user_hotel_manager).\
|
||||
create({
|
||||
@@ -60,7 +60,7 @@ class TestReservationRestriction(TestHotelWubook):
|
||||
"Can't modif restriction")
|
||||
|
||||
def test_unlink(self):
|
||||
vroo_restriction_obj = self.env['hotel.virtual.room.restriction']
|
||||
vroo_restriction_obj = self.env['hotel.room.type.restriction']
|
||||
# Restriction Plan
|
||||
restriction = vroo_restriction_obj.sudo(self.user_hotel_manager).\
|
||||
create({
|
||||
@@ -72,7 +72,7 @@ class TestReservationRestriction(TestHotelWubook):
|
||||
restriction.sudo(self.user_hotel_manager).unlink()
|
||||
|
||||
def test_import_restriction_plans(self):
|
||||
vroo_restriction_obj = self.env['hotel.virtual.room.restriction']
|
||||
vroo_restriction_obj = self.env['hotel.room.type.restriction']
|
||||
# Restriction Plan
|
||||
restriction = vroo_restriction_obj.sudo(self.user_hotel_manager).\
|
||||
create({
|
||||
@@ -84,7 +84,7 @@ class TestReservationRestriction(TestHotelWubook):
|
||||
restriction.sudo(self.user_hotel_manager).import_restriction_plans()
|
||||
|
||||
def test_name_get(self):
|
||||
vroo_restriction_obj = self.env['hotel.virtual.room.restriction']
|
||||
vroo_restriction_obj = self.env['hotel.room.type.restriction']
|
||||
# Restriction Plan
|
||||
restriction = vroo_restriction_obj.sudo(self.user_hotel_manager).\
|
||||
create({
|
||||
|
||||
@@ -32,7 +32,7 @@ class TestVirtualRoomAvailability(TestHotelWubook):
|
||||
def test_write(self):
|
||||
now_utc_dt = date_utils.now()
|
||||
day_utc_dt = now_utc_dt + timedelta(days=1)
|
||||
vroom_avail_obj = self.env['hotel.virtual.room.availability']
|
||||
vroom_avail_obj = self.env['hotel.room.type.availability']
|
||||
avail = vroom_avail_obj.search([
|
||||
('virtual_room_id', '=', self.hotel_vroom_budget.id),
|
||||
('date', '=', now_utc_dt.strftime(DEFAULT_SERVER_DATE_FORMAT))
|
||||
|
||||
@@ -552,7 +552,7 @@ class TestWubook(TestHotelWubook):
|
||||
checkout_utc_dt = checkin_utc_dt + timedelta(days=1)
|
||||
checkout_dt = date_utils.dt_as_timezone(checkout_utc_dt,
|
||||
self.tz_hotel)
|
||||
vroom_restr_item_obj = self.env['hotel.virtual.room.restriction.item']
|
||||
vroom_restr_item_obj = self.env['hotel.room.type.restriction.item']
|
||||
|
||||
vrooms = [self.hotel_vroom_budget, self.hotel_vroom_special]
|
||||
values = self.create_wubook_rooms_values(
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<odoo>
|
||||
|
||||
<record id="view_channel_hotel_virtual_room_availability_form" model="ir.ui.view">
|
||||
<field name="name">channel.hotel.virtual.room.availability.form</field>
|
||||
<field name="model">channel.hotel.virtual.room.availability</field>
|
||||
<field name="name">channel.hotel.room.type.availability.form</field>
|
||||
<field name="model">channel.hotel.room.type.availability</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Hotel Channel Room Availability">
|
||||
<group>
|
||||
@@ -15,7 +15,7 @@
|
||||
</record>
|
||||
|
||||
<record id="view_channel_hotel_virtual_room_availability_tree" model="ir.ui.view">
|
||||
<field name="name">channel.hotel.virtual.room.availability.tree</field>
|
||||
<field name="name">channel.hotel.room.type.availability.tree</field>
|
||||
<field name="model">channel.hotel.virtual.availability.room</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Hotel Channel Room Availability">
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<odoo>
|
||||
|
||||
<record id="view_channel_hotel_virtual_room_restriction_form" model="ir.ui.view">
|
||||
<field name="name">channel.hotel.virtual.room.restriction.form</field>
|
||||
<field name="model">channel.hotel.virtual.room.restriction</field>
|
||||
<field name="name">channel.hotel.room.type.restriction.form</field>
|
||||
<field name="model">channel.hotel.room.type.restriction</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Hotel Channel Room Restriction">
|
||||
<group>
|
||||
@@ -15,7 +15,7 @@
|
||||
</record>
|
||||
|
||||
<record id="view_channel_hotel_virtual_room_restriction_tree" model="ir.ui.view">
|
||||
<field name="name">channel.hotel.virtual.room.restriction.tree</field>
|
||||
<field name="name">channel.hotel.room.type.restriction.tree</field>
|
||||
<field name="model">channel.hotel.virtual.restriction.room</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Hotel Channel Room Restriction">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
<!-- FORM availability -->
|
||||
<record id="virtual_room_availability_view_form" model="ir.ui.view">
|
||||
<field name="model">hotel.virtual.room.availability</field>
|
||||
<field name="model">hotel.room.type.availability</field>
|
||||
<field name="inherit_id" ref="hotel.virtual_room_availability_view_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//sheet" position="inside">
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
<!-- TREE restriction -->
|
||||
<record id="virtual_room_availability_view_tree" model="ir.ui.view">
|
||||
<field name="model">hotel.virtual.room.availability</field>
|
||||
<field name="model">hotel.room.type.availability</field>
|
||||
<field name="inherit_id" ref="hotel.virtual_room_availability_view_tree" />
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<odoo>
|
||||
|
||||
<record id="reservation_restriction_item_form_view" model="ir.ui.view">
|
||||
<field name="model">hotel.virtual.room.restriction.item</field>
|
||||
<field name="model">hotel.room.type.restriction.item</field>
|
||||
<field name="inherit_id" ref="hotel.reservation_restriction_item_view_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='date_end']" position="attributes">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<odoo>
|
||||
|
||||
<record id="reservation_restriction_view" model="ir.ui.view">
|
||||
<field name="model">hotel.virtual.room.restriction</field>
|
||||
<field name="model">hotel.room.type.restriction</field>
|
||||
<field name="inherit_id" ref="hotel.reservation_restriction_view_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//form[1]//sheet" position="before">
|
||||
|
||||
@@ -33,7 +33,7 @@ class ImportPlanRestrictionsWizard(models.TransientModel):
|
||||
|
||||
@api.multi
|
||||
def import_plan_restrictions(self):
|
||||
restriction_id = self.env['hotel.virtual.room.restriction'].browse(
|
||||
restriction_id = self.env['hotel.room.type.restriction'].browse(
|
||||
self.env.context.get('active_id'))
|
||||
if restriction_id:
|
||||
for record in self:
|
||||
|
||||
@@ -72,7 +72,7 @@ class WuBookInstaller(models.TransientModel):
|
||||
self.env.cr.commit() # FIXME: Need do this
|
||||
|
||||
# Create Wubook Base Restrictions
|
||||
restr_obj = self.env['hotel.virtual.room.restriction'].with_context({
|
||||
restr_obj = self.env['hotel.room.type.restriction'].with_context({
|
||||
'wubook_action': False
|
||||
})
|
||||
base_rest = restr_obj.search([('wpid', '=', '0')], limit=1)
|
||||
@@ -108,7 +108,7 @@ class WuBookInstallerParity(models.TransientModel):
|
||||
|
||||
parity_pricelist_id = fields.Many2one('product.pricelist',
|
||||
'Product Pricelist')
|
||||
parity_restrictions_id = fields.Many2one('hotel.virtual.room.restriction',
|
||||
parity_restrictions_id = fields.Many2one('hotel.room.type.restriction',
|
||||
'Restrictions')
|
||||
import_data = fields.Boolean('Import Data From WuBook', default=False)
|
||||
date_start = fields.Date('Date Start')
|
||||
|
||||
Reference in New Issue
Block a user