mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
[WIP][MIG][11.0] Odoo Connector
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from . import channel_backend
|
||||
from . import channel_binding
|
||||
from . import res_config
|
||||
from . import hotel_virtual_room
|
||||
from . import hotel_room_type
|
||||
from . import product_pricelist
|
||||
from . import inherited_product_pricelist_item
|
||||
from . import hotel_virtual_room_restriction
|
||||
@@ -10,5 +13,5 @@ from . import hotel_virtual_room_availability
|
||||
from . import hotel_reservation
|
||||
from . import inherited_hotel_folio
|
||||
from . import inherited_res_partner
|
||||
from . import wubook_channel_info
|
||||
from . import hotel_channel_connector_ota_info
|
||||
from . import hotel_channel_connector_issue
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from . import common
|
||||
|
||||
@@ -1,11 +1,22 @@
|
||||
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from contextlib import contextmanager
|
||||
from odoo import models, api, fields
|
||||
from ...components.backend_adapter import WuBookLogin, WuBookAdapter
|
||||
|
||||
class ChannelBackend(models.Model):
|
||||
_name = 'channel.backend'
|
||||
_description = 'Hotel Channel Backend'
|
||||
_inherit = 'connector.backend'
|
||||
|
||||
username = fields.Char('Channel Service Username')
|
||||
passwd = fields.Char('Channel Service Password')
|
||||
lcode = fields.Char('Channel Service lcode')
|
||||
server = fields.Char('Channel Service Server',
|
||||
default='https://wired.wubook.net/xrws/')
|
||||
pkey = fields.Char('Channel Service PKey')
|
||||
|
||||
@contextmanager
|
||||
@api.multi
|
||||
def work_on(self, model_name, **kwargs):
|
||||
@@ -13,23 +24,12 @@ class ChannelBackend(models.Model):
|
||||
lang = self.default_lang_id
|
||||
if lang.code != self.env.context.get('lang'):
|
||||
self = self.with_context(lang=lang.code)
|
||||
user = self.env['ir.default'].sudo().get(
|
||||
'res.config.settings', 'hotel_connector_user')
|
||||
passwd = self.env['ir.default'].sudo().get(
|
||||
'res.config.settings', 'hotel_connector_passwd')
|
||||
lcode = self.env['ir.default'].sudo().get(
|
||||
'res.config.settings', 'hotel_connector_lcode')
|
||||
pkey = self.env['ir.default'].sudo().get(
|
||||
'res.config.settings', 'hotel_connector_pkey')
|
||||
server_addr = self.env['ir.default'].sudo().get(
|
||||
'res.config.settings', 'hotel_connector_server')
|
||||
wubook_login = WuBookLogin(
|
||||
server_addr,
|
||||
user,
|
||||
passwd,
|
||||
lcode,
|
||||
pkey
|
||||
)
|
||||
self.server,
|
||||
self.username,
|
||||
self.passwd,
|
||||
self.lcode,
|
||||
self.pkey)
|
||||
with WuBookAdapter(wubook_login) as channel_api:
|
||||
_super = super(ChannelBackend, self)
|
||||
# from the components we'll be able to do: self.work.magento_api
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from . import common
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import api, models, fields
|
||||
from odoo.addons.queue_job.job import job, related_action
|
||||
from odoo import models, fields
|
||||
|
||||
|
||||
class ChannelBinding(models.AbstractModel):
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import models, fields, api, _
|
||||
from openerp.exceptions import ValidationError
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from openerp import models, fields, api
|
||||
|
||||
from openerp import models, fields, api
|
||||
from odoo.addons.queue_job.job import job
|
||||
|
||||
class HotelChannelConnectorOTAInfo(models.Model):
|
||||
_name = 'hote.channel.connector.ota.info'
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from . import common
|
||||
|
||||
@@ -3,6 +3,15 @@
|
||||
|
||||
from odoo import api, models, fields
|
||||
from odoo.addons.queue_job.job import job, related_action
|
||||
from odoo.addons.component.core import Component
|
||||
from odoo.addons.component_event import skip_if
|
||||
from odoo.addons.hotel_channel_connector.components.backend_adapter import (
|
||||
WUBOOK_STATUS_CONFIRMED,
|
||||
WUBOOK_STATUS_WAITING,
|
||||
WUBOOK_STATUS_REFUSED,
|
||||
WUBOOK_STATUS_ACCEPTED,
|
||||
WUBOOK_STATUS_CANCELLED,
|
||||
WUBOOK_STATUS_CANCELLED_PENALTY)
|
||||
|
||||
class ChannelHotelReservation(models.Model):
|
||||
_name = 'channel.hotel.reservation'
|
||||
@@ -10,11 +19,6 @@ class ChannelHotelReservation(models.Model):
|
||||
_inherits = {'hotel.reservation': 'odoo_id'}
|
||||
_description = 'Channel Hotel Reservation'
|
||||
|
||||
@api.depends('channel_reservation_id', 'ota_id')
|
||||
def _is_from_ota(self):
|
||||
for record in self:
|
||||
record.is_from_ota = (record.channel_reservation_id and record.ota_id)
|
||||
|
||||
odoo_id = fields.Many2one(comodel_names='hotel.reservation',
|
||||
string='Reservation',
|
||||
required=True,
|
||||
@@ -27,25 +31,18 @@ class ChannelHotelReservation(models.Model):
|
||||
ota_reservation_id = fields.Char("Channel OTA Reservation Code",
|
||||
readonly=True,
|
||||
old_name='wchannel_reservation_code')
|
||||
is_from_ota = fields.Boolean('Is From OTA',
|
||||
compute=_is_from_ota, store=False,
|
||||
readonly=True,
|
||||
old_name='wis_from_channel')
|
||||
to_read = fields.Boolean('To Read', default=False)
|
||||
able_to_modify_channel = fields.Boolean(compute=set_access_for_wubook_fields,
|
||||
string='Is user able to modify wubook fields?',
|
||||
old_name='able_to_modify_wubook')
|
||||
channel_raw_data = fields.Text(readonly=True, old_name='wbook_json')
|
||||
|
||||
wstatus = fields.Selection([
|
||||
('0', 'No WuBook'),
|
||||
('0', 'No Channel'),
|
||||
(str(WUBOOK_STATUS_CONFIRMED), 'Confirmed'),
|
||||
(str(WUBOOK_STATUS_WAITING), 'Waiting'),
|
||||
(str(WUBOOK_STATUS_REFUSED), 'Refused'),
|
||||
(str(WUBOOK_STATUS_ACCEPTED), 'Accepted'),
|
||||
(str(WUBOOK_STATUS_CANCELLED), 'Cancelled'),
|
||||
(str(WUBOOK_STATUS_CANCELLED_PENALTY), 'Cancelled with penalty')],
|
||||
string='WuBook Status', default='0',
|
||||
string='WuBook Status',
|
||||
default='0',
|
||||
readonly=True)
|
||||
wstatus_reason = fields.Char("WuBook Status Reason", readonly=True)
|
||||
customer_notes = fields.Text(related='folio_id.customer_notes',
|
||||
@@ -68,23 +65,39 @@ class ChannelHotelReservation(models.Model):
|
||||
def cancel_reservation(self):
|
||||
self.ensure_one()
|
||||
if self._context.get('channel_action', True):
|
||||
user = self.env['res.user'].browse(self.env.uid)
|
||||
with self.backend_id.work_on(self._name) as work:
|
||||
adapter = work.component(usage='backend.adapter')
|
||||
wres = adapter.cancel_reservation(
|
||||
self.channel_reservation_id,
|
||||
_('Cancelled by %s') % partner_id.name)
|
||||
_('Cancelled by %s') % user.partner_id.name)
|
||||
if not wres:
|
||||
raise ValidationError(_("Can't cancel reservation on WuBook"))
|
||||
|
||||
class HotelReservation(models.Model):
|
||||
_inherit = 'hotel.reservation'
|
||||
|
||||
@api.depends('channel_bind_ids.channel_reservation_id', 'channel_bind_ids.ota_id')
|
||||
def _is_from_ota(self):
|
||||
for record in self:
|
||||
record.is_from_ota = (record.channel_bind_ids.channel_reservation_id and \
|
||||
record.channel_bind_ids.ota_id)
|
||||
|
||||
@api.multi
|
||||
def set_access_for_wubook_fields(self):
|
||||
def _set_access_for_wubook_fields(self):
|
||||
for rec in self:
|
||||
user = self.env['res.users'].browse(self.env.uid)
|
||||
rec.able_to_modify_channel = user.has_group('base.group_system')
|
||||
|
||||
is_from_ota = fields.Boolean('Is From OTA',
|
||||
compute=_is_from_ota, store=False,
|
||||
readonly=True,
|
||||
old_name='wis_from_channel')
|
||||
able_to_modify_channel = fields.Boolean(compute=_set_access_for_wubook_fields,
|
||||
string='Is user able to modify wubook fields?',
|
||||
old_name='able_to_modify_wubook')
|
||||
to_read = fields.Boolean('To Read', default=False)
|
||||
|
||||
@api.depends('channel_type', 'ota_id')
|
||||
def _get_origin_sale(self):
|
||||
for record in self:
|
||||
@@ -211,30 +224,27 @@ class HotelReservation(models.Model):
|
||||
raise ValidationError(_("Can't confirm OTA's cancelled reservations"))
|
||||
return super(HotelReservation, self).confirm()
|
||||
|
||||
@api.multi
|
||||
def generate_copy_values(self, checkin=False, checkout=False):
|
||||
self.ensure_one()
|
||||
res = super().generate_copy_values(checkin=checkin, checkout=checkout)
|
||||
res.update({
|
||||
'channel_reservation_id': self.channel_reservation_id,
|
||||
'ota_id': self.ota_id and self.ota_id.id or False,
|
||||
'ota_reservation_code': self.ota_reservation_code,
|
||||
'is_from_ota': self.is_from_ota,
|
||||
'to_read': self.to_read,
|
||||
'wstatus': self.wstatus,
|
||||
'wstatus_reason': self.wstatus_reason,
|
||||
'customer_notes': self.customer_notes,
|
||||
})
|
||||
return res
|
||||
# @api.multi
|
||||
# def generate_copy_values(self, checkin=False, checkout=False):
|
||||
# self.ensure_one()
|
||||
# res = super().generate_copy_values(checkin=checkin, checkout=checkout)
|
||||
# res.update({
|
||||
# 'channel_reservation_id': self.channel_reservation_id,
|
||||
# 'ota_id': self.ota_id and self.ota_id.id or False,
|
||||
# 'ota_reservation_code': self.ota_reservation_code,
|
||||
# 'is_from_ota': self.is_from_ota,
|
||||
# 'to_read': self.to_read,
|
||||
# 'wstatus': self.wstatus,
|
||||
# 'wstatus_reason': self.wstatus_reason,
|
||||
# 'customer_notes': self.customer_notes,
|
||||
# })
|
||||
# return res
|
||||
|
||||
@api.multi
|
||||
def action_reservation_checkout(self):
|
||||
for record in self:
|
||||
if record.state == 'cancelled':
|
||||
return
|
||||
else:
|
||||
return super(HotelReservation, record).\
|
||||
action_reservation_checkout()
|
||||
if record.state != 'cancelled':
|
||||
return super(HotelReservation, record).action_reservation_checkout()
|
||||
|
||||
@api.model
|
||||
def _hcalendar_reservation_data(self, reservations):
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from . import common
|
||||
@@ -3,12 +3,14 @@
|
||||
|
||||
from odoo import api, models, fields
|
||||
from odoo.addons.queue_job.job import job, related_action
|
||||
from odoo.addons.component.core import Component
|
||||
from odoo.addons.component_event import skip_if
|
||||
|
||||
class ChannelHotelVirtualRoom(models.Model):
|
||||
_name = 'channel.hotel.virtual.room'
|
||||
class ChannelHotelRoomType(models.Model):
|
||||
_name = 'channel.hotel.room.type'
|
||||
_inherit = 'channel.binding'
|
||||
_inherits = {'hotel.virtual.room': 'odoo_id'}
|
||||
_description = 'Channel Hotel Virtual Room'
|
||||
_inherits = {'hotel.room.type': 'odoo_id'}
|
||||
_description = 'Channel Hotel Room'
|
||||
|
||||
@api.depends('ota_capacity')
|
||||
@api.onchange('room_ids', 'room_type_ids')
|
||||
@@ -16,8 +18,8 @@ class ChannelHotelVirtualRoom(models.Model):
|
||||
for rec in self:
|
||||
rec.ota_capacity = rec.get_capacity()
|
||||
|
||||
odoo_id = fields.Many2one(comodel_names='hotel.virtual.room',
|
||||
string='Reservation',
|
||||
odoo_id = fields.Many2one(comodel_names='hotel.room.type',
|
||||
string='Room Type',
|
||||
required=True,
|
||||
ondelete='cascade')
|
||||
channel_room_id = fields.Char("Channel Room ID", readonly=True, old_name='wrid')
|
||||
@@ -102,11 +104,11 @@ class ChannelHotelVirtualRoom(models.Model):
|
||||
importer = work.component(usage='channel.importer')
|
||||
return importer.import_rooms()
|
||||
|
||||
class HotelVirtualRoom(models.Model):
|
||||
_inherit = 'hotel.virtual.room'
|
||||
class HotelRoomType(models.Model):
|
||||
_inherit = 'hotel.room.type'
|
||||
|
||||
channel_bind_ids = fields.One2many(
|
||||
comodel_name='channel.hotel.virtual.room',
|
||||
comodel_name='channel.hotel.room.type',
|
||||
inverse_name='odoo_id',
|
||||
string='Hotel Channel Connector Bindings')
|
||||
|
||||
@@ -124,10 +126,10 @@ class HotelVirtualRoom(models.Model):
|
||||
], limit=1)
|
||||
return restriction
|
||||
|
||||
class ChannelBindingVirtualRoomListener(Component):
|
||||
_name = 'channel.binding.virtual.room.listener'
|
||||
class ChannelBindingRoomTypeListener(Component):
|
||||
_name = 'channel.binding.room.type.listener'
|
||||
_inherit = 'base.connector.listener'
|
||||
_apply_on = ['channel.virtual.room']
|
||||
_apply_on = ['channel.room.type']
|
||||
|
||||
@skip_if(lambda self, record, **kwargs: self.no_connector_export(record))
|
||||
def on_record_write(self, record, fields=None):
|
||||
@@ -1,3 +1,4 @@
|
||||
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from . import common
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
from odoo import api, models, fields
|
||||
from odoo.addons.queue_job.job import job, related_action
|
||||
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'
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from . import common
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
from odoo import api, models, fields
|
||||
from odoo.addons.queue_job.job import job, related_action
|
||||
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'
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import models, fields, api
|
||||
from odoo.addons.queue_job.job import job
|
||||
|
||||
|
||||
class HotelFolio(models.Model):
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import models, fields, api
|
||||
from openerp.exceptions import ValidationError
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import models, fields, api
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import models, fields, api
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from . import common
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
from odoo import api, models, fields
|
||||
from odoo.addons.queue_job.job import job, related_action
|
||||
from odoo.addons.component.core import Component
|
||||
from odoo.addons.component_event import skip_if
|
||||
|
||||
class ChannelProductPricelist(models.Model):
|
||||
_name = 'channel.product.pricelist'
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
import os
|
||||
import binascii
|
||||
import logging
|
||||
@@ -10,49 +11,30 @@ from odoo.addons.hotel import date_utils
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class WubookConfiguration(models.TransientModel):
|
||||
_name = 'wubook.config.settings'
|
||||
class HotelChannelConnectorConfiguration(models.TransientModel):
|
||||
_inherit = 'res.config.settings'
|
||||
|
||||
wubook_user = fields.Char('WuBook User')
|
||||
wubook_passwd = fields.Char('WuBook Password')
|
||||
wubook_lcode = fields.Char('WuBook lcode')
|
||||
wubook_server = fields.Char('WuBook Server',
|
||||
default='https://wired.wubook.net/xrws/')
|
||||
wubook_pkey = fields.Char('WuBook PKey')
|
||||
wubook_push_security_token = fields.Char('WuBook Push Notification \
|
||||
Security Token')
|
||||
channel_push_security_token = fields.Char('WuBook Push Notification Security Token')
|
||||
|
||||
@api.multi
|
||||
def set_wubook_user(self):
|
||||
return self.env['ir.default'].sudo().set(
|
||||
'wubook.config.settings', 'wubook_user', self.wubook_user)
|
||||
def set_values(self):
|
||||
super(HotelChannelConnectorConfiguration, self).set_values()
|
||||
|
||||
@api.multi
|
||||
def set_wubook_passwd(self):
|
||||
return self.env['ir.default'].sudo().set(
|
||||
'wubook.config.settings', 'wubook_passwd', self.wubook_passwd)
|
||||
self.env['ir.default'].sudo().set(
|
||||
'res.config.settings', 'channel_push_security_token',
|
||||
self.channel_push_security_token)
|
||||
|
||||
@api.multi
|
||||
def set_wubook_lcode(self):
|
||||
return self.env['ir.default'].sudo().set(
|
||||
'wubook.config.settings', 'wubook_lcode', self.wubook_lcode)
|
||||
@api.model
|
||||
def get_values(self):
|
||||
res = super(HotelChannelConnectorConfiguration, self).get_values()
|
||||
|
||||
@api.multi
|
||||
def set_wubook_server(self):
|
||||
return self.env['ir.default'].sudo().set(
|
||||
'wubook.config.settings', 'wubook_server', self.wubook_server)
|
||||
|
||||
@api.multi
|
||||
def set_wubook_pkey(self):
|
||||
return self.env['ir.default'].sudo().set(
|
||||
'wubook.config.settings', 'wubook_pkey', self.wubook_pkey)
|
||||
|
||||
@api.multi
|
||||
def set_wubook_push_security_token(self):
|
||||
return self.env['ir.default'].sudo().set(
|
||||
'wubook.config.settings',
|
||||
'wubook_push_security_token', self.wubook_push_security_token)
|
||||
# ONLY FOR v11. DO NOT FORWARD-PORT
|
||||
channel_push_security_token = self.env['ir.default'].sudo().get(
|
||||
'res.config.settings', 'channel_push_security_token')
|
||||
res.update(
|
||||
channel_push_security_token=channel_push_security_token,
|
||||
)
|
||||
return res
|
||||
|
||||
# Dangerus method: Usefull for cloned instances with new wubook account
|
||||
@api.multi
|
||||
|
||||
Reference in New Issue
Block a user