mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
[ADD] Hotel Management using Odoo Connector
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
from . import components
|
||||||
from . import models
|
from . import models
|
||||||
from . import wizards
|
from . import wizards
|
||||||
|
|||||||
@@ -8,13 +8,15 @@
|
|||||||
Odoo Community Association (OCA)',
|
Odoo Community Association (OCA)',
|
||||||
'category': 'Generic Modules/Hotel Management',
|
'category': 'Generic Modules/Hotel Management',
|
||||||
'depends': [
|
'depends': [
|
||||||
'project'
|
'project',
|
||||||
|
'connector'
|
||||||
],
|
],
|
||||||
'external_dependencies':
|
'external_dependencies':
|
||||||
{'python' : ['odoorpc']},
|
{'python' : ['odoorpc']},
|
||||||
'license': "AGPL-3",
|
'license': "AGPL-3",
|
||||||
'data': [
|
'data': [
|
||||||
'wizards/wizard_hotel_node_reservation.xml',
|
'wizards/wizard_hotel_node_reservation.xml',
|
||||||
|
'views/node_backend_views.xml',
|
||||||
'views/hotel_node.xml',
|
'views/hotel_node.xml',
|
||||||
'views/hotel_node_user.xml',
|
'views/hotel_node_user.xml',
|
||||||
'views/hotel_node_group.xml',
|
'views/hotel_node_group.xml',
|
||||||
@@ -22,7 +24,8 @@
|
|||||||
'views/hotel_node_room_type.xml',
|
'views/hotel_node_room_type.xml',
|
||||||
'views/inherited_res_partner_views.xml',
|
'views/inherited_res_partner_views.xml',
|
||||||
'security/hotel_node_security.xml',
|
'security/hotel_node_security.xml',
|
||||||
'security/ir.model.access.csv'
|
'security/ir.model.access.csv',
|
||||||
|
'data/menus.xml',
|
||||||
],
|
],
|
||||||
'demo': [],
|
'demo': [],
|
||||||
'auto_install': False,
|
'auto_install': False,
|
||||||
|
|||||||
9
hotel_node_master/components/__init__.py
Normal file
9
hotel_node_master/components/__init__.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from . import core
|
||||||
|
from . import backend_adapter
|
||||||
|
from . import binder
|
||||||
|
from . import importer
|
||||||
|
from . import exporter
|
||||||
|
from . import mapper
|
||||||
105
hotel_node_master/components/backend_adapter.py
Normal file
105
hotel_node_master/components/backend_adapter.py
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
import odoorpc
|
||||||
|
import logging
|
||||||
|
from odoo.addons.component.core import AbstractComponent
|
||||||
|
from odoo.addons.queue_job.exception import RetryableJobError
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class NodeLogin(object):
|
||||||
|
def __init__(self, address, protocol, port, db, user, passwd):
|
||||||
|
self.address = address
|
||||||
|
self.protocol = protocol
|
||||||
|
self.port = port
|
||||||
|
self.db = db
|
||||||
|
self.user = user
|
||||||
|
self.passwd = passwd
|
||||||
|
|
||||||
|
class NodeServer(object):
|
||||||
|
def __init__(self, login_data):
|
||||||
|
self._server = None
|
||||||
|
self._login_data = login_data
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
# we do nothing, api is lazy
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, type, value, traceback):
|
||||||
|
if self._server is not None:
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def server(self):
|
||||||
|
if self._server is None:
|
||||||
|
try:
|
||||||
|
self._server = odoorpc.ODOO(self._login_data.address,
|
||||||
|
self._login_data.protocol,
|
||||||
|
self._login_data.port)
|
||||||
|
self._server.login(self._login_data.db,
|
||||||
|
self._login_data.user,
|
||||||
|
self._login_data.passwd)
|
||||||
|
except Exception:
|
||||||
|
self._server = None
|
||||||
|
raise RetryableJobError("Can't connect with channel!")
|
||||||
|
return self._server
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self._server.logout()
|
||||||
|
self._server = None
|
||||||
|
|
||||||
|
class HotelNodeInterfaceAdapter(AbstractComponent):
|
||||||
|
_name = 'hotel.node.interface.adapter'
|
||||||
|
_inherit = ['base.backend.adapter', 'base.node.connector']
|
||||||
|
_usage = 'backend.adapter'
|
||||||
|
|
||||||
|
def create_room_type(self, name, room_ids):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def modify_room_type(self, room_type_id, name, room_ids):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def delete_room_type(self, room_type_id):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def fetch_room_types(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _server(self):
|
||||||
|
try:
|
||||||
|
node_server = getattr(self.work, 'node_api')
|
||||||
|
except AttributeError:
|
||||||
|
raise AttributeError(
|
||||||
|
'You must provide a node_api attribute with a '
|
||||||
|
'WuBookServer instance to be able to use the '
|
||||||
|
'Backend Adapter.'
|
||||||
|
)
|
||||||
|
return node_server.server
|
||||||
|
|
||||||
|
class HotelNodeAdapter(AbstractComponent):
|
||||||
|
_name = 'hotel.node.adapter'
|
||||||
|
_inherit = 'hotel.node.interface.adapter'
|
||||||
|
|
||||||
|
# === ROOMS
|
||||||
|
def create_room_type(self, name, room_ids):
|
||||||
|
return self._server.env['hotel.room.type'].create({
|
||||||
|
'name': name
|
||||||
|
})
|
||||||
|
|
||||||
|
def modify_room_type(self, room_type_id, name, rooms_id):
|
||||||
|
return self._server.env['hotel.room.type'].write(
|
||||||
|
room_type_id,
|
||||||
|
{
|
||||||
|
'name': name
|
||||||
|
})
|
||||||
|
|
||||||
|
def delete_room_type(self, room_type_id):
|
||||||
|
return self._server.env['hotel.room.type'].unlink(room_type_id)
|
||||||
|
|
||||||
|
def fetch_room_types(self):
|
||||||
|
return self._server.env['hotel.room.type'].search_read(
|
||||||
|
[],
|
||||||
|
['name']
|
||||||
|
)
|
||||||
11
hotel_node_master/components/binder.py
Normal file
11
hotel_node_master/components/binder.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from odoo.addons.component.core import Component
|
||||||
|
|
||||||
|
class NodeConnectorModelBinder(Component):
|
||||||
|
_name = 'node.connector.binder'
|
||||||
|
_inherit = ['base.binder', 'base.node.connector']
|
||||||
|
_apply_on = [
|
||||||
|
'node.room.type',
|
||||||
|
]
|
||||||
9
hotel_node_master/components/core.py
Normal file
9
hotel_node_master/components/core.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from odoo.addons.component.core import AbstractComponent
|
||||||
|
|
||||||
|
class BaseHotelChannelConnectorComponent(AbstractComponent):
|
||||||
|
_name = 'base.node.connector'
|
||||||
|
_inherit = 'base.connector'
|
||||||
|
_collection = 'node.backend'
|
||||||
12
hotel_node_master/components/exporter.py
Normal file
12
hotel_node_master/components/exporter.py
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from odoo.addons.component.core import AbstractComponent
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class NodeExporter(AbstractComponent):
|
||||||
|
_name = 'node.exporter'
|
||||||
|
_inherit = ['base.exporter', 'base.node.connector']
|
||||||
|
_usage = 'node.exporter'
|
||||||
11
hotel_node_master/components/importer.py
Normal file
11
hotel_node_master/components/importer.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from odoo.addons.component.core import AbstractComponent, Component
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class NodeImporter(AbstractComponent):
|
||||||
|
_name = 'node.importer'
|
||||||
|
_inherit = ['base.importer', 'base.node.connector']
|
||||||
|
_usage = 'node.importer'
|
||||||
16
hotel_node_master/components/mapper.py
Normal file
16
hotel_node_master/components/mapper.py
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from odoo.addons.component.core import AbstractComponent
|
||||||
|
|
||||||
|
|
||||||
|
class NodeImportMapper(AbstractComponent):
|
||||||
|
_name = 'node.import.mapper'
|
||||||
|
_inherit = ['base.node.connector', 'base.import.mapper']
|
||||||
|
_usage = 'import.mapper'
|
||||||
|
|
||||||
|
|
||||||
|
class NodeExportMapper(AbstractComponent):
|
||||||
|
_name = 'node.export.mapper'
|
||||||
|
_inherit = ['base.node.connector', 'base.export.mapper']
|
||||||
|
_usage = 'export.mapper'
|
||||||
15
hotel_node_master/data/menus.xml
Normal file
15
hotel_node_master/data/menus.xml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
|
||||||
|
<menuitem id="menu_node_connector_root"
|
||||||
|
parent="connector.menu_connector_root"
|
||||||
|
name="Hotel Node"
|
||||||
|
sequence="10"/>
|
||||||
|
|
||||||
|
<menuitem id="menu_node_backend"
|
||||||
|
name="Backends"
|
||||||
|
sequence="1"
|
||||||
|
parent="menu_node_connector_root"
|
||||||
|
action="action_node_backend"/>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from . import node_backend
|
||||||
|
from . import node_binding
|
||||||
from . import hotel_node
|
from . import hotel_node
|
||||||
from . import hotel_node_user
|
from . import hotel_node_user
|
||||||
from . import hotel_node_group
|
from . import hotel_node_group
|
||||||
@@ -7,3 +9,5 @@ from . import hotel_node_group_remote
|
|||||||
from . import hotel_node_room
|
from . import hotel_node_room
|
||||||
from . import hotel_node_room_type
|
from . import hotel_node_room_type
|
||||||
from . import inherited_res_partner
|
from . import inherited_res_partner
|
||||||
|
from . import hotel_room_type
|
||||||
|
|
||||||
|
|||||||
6
hotel_node_master/models/hotel_room_type/__init__.py
Normal file
6
hotel_node_master/models/hotel_room_type/__init__.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from . import common
|
||||||
|
from . import exporter
|
||||||
|
from . import importer
|
||||||
83
hotel_node_master/models/hotel_room_type/common.py
Normal file
83
hotel_node_master/models/hotel_room_type/common.py
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
import logging
|
||||||
|
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
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class NodeRoomType(models.Model):
|
||||||
|
_name = 'node.room.type'
|
||||||
|
_inherit = 'node.binding'
|
||||||
|
_description = 'Node Hotel Room Type'
|
||||||
|
|
||||||
|
name = fields.Char(required=True, translate=True)
|
||||||
|
room_ids = fields.Integer()
|
||||||
|
# fields.One2many('node.room', 'room_type_id', 'Rooms')
|
||||||
|
active = fields.Boolean(default=True)
|
||||||
|
sequence = fields.Integer(default=0)
|
||||||
|
|
||||||
|
@job(default_channel='root.channel')
|
||||||
|
@api.model
|
||||||
|
def create_room_type(self):
|
||||||
|
with self.backend_id.work_on(self._name) as work:
|
||||||
|
exporter = work.component(usage='node.room.type.exporter')
|
||||||
|
return exporter.create_room_type(self)
|
||||||
|
|
||||||
|
@job(default_channel='root.channel')
|
||||||
|
@api.model
|
||||||
|
def modify_room_type(self):
|
||||||
|
with self.backend_id.work_on(self._name) as work:
|
||||||
|
exporter = work.component(usage='node.room.type.exporter')
|
||||||
|
return exporter.modify_room_type(self)
|
||||||
|
|
||||||
|
@job(default_channel='root.channel')
|
||||||
|
@api.model
|
||||||
|
def delete_room_type(self):
|
||||||
|
with self.backend_id.work_on(self._name) as work:
|
||||||
|
exporter = work.component(usage='node.room.type.exporter')
|
||||||
|
return exporter.delete_room_type(self)
|
||||||
|
|
||||||
|
@job(default_channel='root.channel')
|
||||||
|
@api.model
|
||||||
|
def fetch_room_types(self, backend):
|
||||||
|
with backend.work_on(self._name) as work:
|
||||||
|
importer = work.component(usage='node.room.type.importer')
|
||||||
|
return importer.fetch_room_types()
|
||||||
|
|
||||||
|
class NodeRoomTypeAdapter(Component):
|
||||||
|
_name = 'node.room.type.adapter'
|
||||||
|
_inherit = 'hotel.node.adapter'
|
||||||
|
_apply_on = 'node.room.type'
|
||||||
|
|
||||||
|
def create_room_type(self, name, room_ids):
|
||||||
|
return super().create_room_type(name, room_ids)
|
||||||
|
|
||||||
|
def modify_room_type(self, room_type_id, name, room_ids):
|
||||||
|
return super().modify_room_type(room_type_id, name, room_ids)
|
||||||
|
|
||||||
|
def delete_room_type(self, room_type_id):
|
||||||
|
return super().delete_room_type(room_type_id)
|
||||||
|
|
||||||
|
def fetch_room_types(self):
|
||||||
|
return super().fetch_room_types()
|
||||||
|
|
||||||
|
|
||||||
|
class ChannelBindingRoomTypeListener(Component):
|
||||||
|
_name = 'node.binding.room.type.listener'
|
||||||
|
_inherit = 'base.connector.listener'
|
||||||
|
_apply_on = ['node.hotel.room.type']
|
||||||
|
|
||||||
|
@skip_if(lambda self, record, **kwargs: self.no_connector_export(record))
|
||||||
|
def on_record_create(self, record, fields=None):
|
||||||
|
record.create_room_type()
|
||||||
|
|
||||||
|
@skip_if(lambda self, record, **kwargs: self.no_connector_export(record))
|
||||||
|
def on_record_unlink(self, record, fields=None):
|
||||||
|
record.delete_room_type()
|
||||||
|
|
||||||
|
@skip_if(lambda self, record, **kwargs: self.no_connector_export(record))
|
||||||
|
def on_record_write(self, record, fields=None):
|
||||||
|
record.modify_room_type()
|
||||||
33
hotel_node_master/models/hotel_room_type/exporter.py
Normal file
33
hotel_node_master/models/hotel_room_type/exporter.py
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from odoo.addons.component.core import Component
|
||||||
|
from odoo import api, _
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class NodeRoomTypeExporter(Component):
|
||||||
|
_name = 'node.room.type.exporter'
|
||||||
|
_inherit = 'node.exporter'
|
||||||
|
_apply_on = ['node.room.type']
|
||||||
|
_usage = 'node.room.type.exporter'
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def modify_room(self, binding):
|
||||||
|
return self.backend_adapter.modify_room(
|
||||||
|
binding.room_type_id,
|
||||||
|
binding.name,
|
||||||
|
binding.room_ids
|
||||||
|
)
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def delete_room(self, binding):
|
||||||
|
return self.backend_adapter.delete_room(binding.room_type_id)
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def create_room(self, binding):
|
||||||
|
external_id = self.backend_adapter.create_room(
|
||||||
|
binding.name,
|
||||||
|
binding.room_ids
|
||||||
|
)
|
||||||
|
self.binder.bind(external_id, binding)
|
||||||
46
hotel_node_master/models/hotel_room_type/importer.py
Normal file
46
hotel_node_master/models/hotel_room_type/importer.py
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from odoo.addons.component.core import Component
|
||||||
|
from odoo.addons.connector.components.mapper import mapping
|
||||||
|
from odoo import fields, api, _
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class HotelRoomTypeImporter(Component):
|
||||||
|
_name = 'node.room.type.importer'
|
||||||
|
_inherit = 'node.importer'
|
||||||
|
_apply_on = ['node.room.type']
|
||||||
|
_usage = 'node.room.type.importer'
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def fetch_room_types(self):
|
||||||
|
results = self.backend_adapter.fetch_room_types()
|
||||||
|
room_type_mapper = self.component(usage='import.mapper',
|
||||||
|
model_name='node.room.type')
|
||||||
|
|
||||||
|
node_room_type_obj = self.env['node.room.type']
|
||||||
|
for rec in results:
|
||||||
|
map_record = room_type_mapper.map_record(rec)
|
||||||
|
room_bind = node_room_type_obj.search([('external_id', '=', rec['id'])],
|
||||||
|
limit=1)
|
||||||
|
if room_bind:
|
||||||
|
room_bind.write(map_record.values())
|
||||||
|
else:
|
||||||
|
room_bind.create(map_record.values(for_create=True))
|
||||||
|
|
||||||
|
|
||||||
|
class NodeRoomTypeImportMapper(Component):
|
||||||
|
_name = 'node.room.type.import.mapper'
|
||||||
|
_inherit = 'node.import.mapper'
|
||||||
|
_apply_on = 'node.room.type'
|
||||||
|
|
||||||
|
direct = [
|
||||||
|
('id', 'external_id'),
|
||||||
|
('name', 'name'),
|
||||||
|
]
|
||||||
|
|
||||||
|
@mapping
|
||||||
|
def backend_id(self, record):
|
||||||
|
return {'backend_id': self.backend_record.id}
|
||||||
4
hotel_node_master/models/node_backend/__init__.py
Normal file
4
hotel_node_master/models/node_backend/__init__.py
Normal file
@@ -0,0 +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
|
||||||
52
hotel_node_master/models/node_backend/common.py
Normal file
52
hotel_node_master/models/node_backend/common.py
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# 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 NodeLogin, NodeServer
|
||||||
|
|
||||||
|
class NodeBackend(models.Model):
|
||||||
|
_name = 'node.backend'
|
||||||
|
_description = 'Hotel Node Backend'
|
||||||
|
_inherit = 'connector.backend'
|
||||||
|
|
||||||
|
name = fields.Char('Name')
|
||||||
|
address = fields.Char('Host', required=True,
|
||||||
|
help='Full URL to the host.')
|
||||||
|
db = fields.Char('Database Name',
|
||||||
|
help='Odoo database name.')
|
||||||
|
user = fields.Char('Username',
|
||||||
|
help='Odoo administration user.')
|
||||||
|
passwd = fields.Char('Password',
|
||||||
|
help='Odoo password.')
|
||||||
|
port = fields.Integer(string='TCP Port', default=443,
|
||||||
|
help='Specify the TCP port for the XML-RPC protocol.')
|
||||||
|
protocol = fields.Selection([('jsonrpc', 'jsonrpc'), ('jsonrpc+ssl', 'jsonrpc+ssl')],
|
||||||
|
'Protocol', required=True, default='jsonrpc+ssl')
|
||||||
|
odoo_version = fields.Char()
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
@api.multi
|
||||||
|
def work_on(self, model_name, **kwargs):
|
||||||
|
self.ensure_one()
|
||||||
|
node_login = NodeLogin(
|
||||||
|
self.address,
|
||||||
|
self.protocol,
|
||||||
|
self.port,
|
||||||
|
self.db,
|
||||||
|
self.user,
|
||||||
|
self.passwd)
|
||||||
|
with NodeServer(node_login) as node_api:
|
||||||
|
_super = super(NodeBackend, self)
|
||||||
|
with _super.work_on(model_name, node_api=node_api, **kwargs) as work:
|
||||||
|
yield work
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def test_connection(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def import_room_types(self):
|
||||||
|
node_room_type_obj = self.env['node.room.type']
|
||||||
|
for backend in self:
|
||||||
|
node_room_type_obj.with_delay().fetch_room_types(backend)
|
||||||
4
hotel_node_master/models/node_binding/__init__.py
Normal file
4
hotel_node_master/models/node_binding/__init__.py
Normal file
@@ -0,0 +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
|
||||||
22
hotel_node_master/models/node_binding/common.py
Normal file
22
hotel_node_master/models/node_binding/common.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from odoo import models, fields, api
|
||||||
|
|
||||||
|
|
||||||
|
class NodeBinding(models.AbstractModel):
|
||||||
|
_name = 'node.binding'
|
||||||
|
_inherit = 'external.binding'
|
||||||
|
_description = 'Hotel Node Connector Binding (abstract)'
|
||||||
|
|
||||||
|
external_id = fields.Integer()
|
||||||
|
backend_id = fields.Many2one(
|
||||||
|
comodel_name='node.backend',
|
||||||
|
string='Hotel Node Connector Backend',
|
||||||
|
required=True,
|
||||||
|
ondelete='restrict')
|
||||||
|
|
||||||
|
_sql_constraints = [
|
||||||
|
('backend_external_id_uniq', 'unique(backend_id, external_id)',
|
||||||
|
'A binding already exists with the same Backend ID.'),
|
||||||
|
]
|
||||||
72
hotel_node_master/views/node_backend_views.xml
Normal file
72
hotel_node_master/views/node_backend_views.xml
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
|
||||||
|
<record id="node_backend_views_form" model="ir.ui.view">
|
||||||
|
<field name="name">node.backend.form</field>
|
||||||
|
<field name="model">node.backend</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="Hotel Node Backend">
|
||||||
|
<header>
|
||||||
|
<button name="test_connection"
|
||||||
|
type="object"
|
||||||
|
class="oe_highlight"
|
||||||
|
string="Test Connection"/>
|
||||||
|
</header>
|
||||||
|
<sheet>
|
||||||
|
<label for="name" class="oe_edit_only"/>
|
||||||
|
<h1>
|
||||||
|
<field name="name" class="oe_inline" />
|
||||||
|
</h1>
|
||||||
|
<group name="channel" string="Node Configuration">
|
||||||
|
<notebook>
|
||||||
|
<page string="API" name="api">
|
||||||
|
<group colspan="4" col="4">
|
||||||
|
<field name="address" colspan="2"/>
|
||||||
|
<field name="db" colspan="2"/>
|
||||||
|
<field name="user" colspan="2"/>
|
||||||
|
<field name="passwd" password="1" colspan="2"/>
|
||||||
|
<field name="port" colspan="2"/>
|
||||||
|
<field name="protocol" colspan="2"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
</group>
|
||||||
|
<notebook>
|
||||||
|
<page name="import" string="Imports">
|
||||||
|
<group>
|
||||||
|
<label string="Import Reservations" class="oe_inline"/>
|
||||||
|
<div>
|
||||||
|
<button name="import_room_types"
|
||||||
|
type="object"
|
||||||
|
class="oe_highlight"
|
||||||
|
string="Import in background"/>
|
||||||
|
</div>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="node_backend_views_tree" model="ir.ui.view">
|
||||||
|
<field name="name">node.backend.tree</field>
|
||||||
|
<field name="model">node.backend</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<tree string="Node Backend">
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="address"/>
|
||||||
|
<field name="db"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="action_node_backend" model="ir.actions.act_window">
|
||||||
|
<field name="name">Hotel Node Backends</field>
|
||||||
|
<field name="res_model">node.backend</field>
|
||||||
|
<field name="view_type">form</field>
|
||||||
|
<field name="view_mode">tree,form</field>
|
||||||
|
<field name="view_id" ref="node_backend_views_tree"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
Reference in New Issue
Block a user