From 32946ac91aa6d85d5a517c54036390d8a6efae35 Mon Sep 17 00:00:00 2001 From: Pablo Date: Fri, 7 Dec 2018 09:02:35 +0100 Subject: [PATCH 01/32] [FIX] AttributeError: 'hotel.room.type.class' object has no attribute 'class_code' --- .../models/hotel_room_type/exporter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hotel_channel_connector_wubook/models/hotel_room_type/exporter.py b/hotel_channel_connector_wubook/models/hotel_room_type/exporter.py index 7b045fc28..325e1406e 100644 --- a/hotel_channel_connector_wubook/models/hotel_room_type/exporter.py +++ b/hotel_channel_connector_wubook/models/hotel_room_type/exporter.py @@ -23,7 +23,7 @@ class HotelRoomTypeExporter(Component): binding.total_rooms_count, binding.channel_short_code, 'nb', - binding.class_id and binding.class_id.class_code or False) + binding.class_id and binding.class_id.code_class or False) except ChannelConnectorError as err: self.create_issue( section='room', @@ -42,7 +42,7 @@ class HotelRoomTypeExporter(Component): binding.list_price, binding.total_rooms_count, 'nb', - binding.class_id and binding.class_id.class_code or False) + binding.class_id and binding.class_id.code_class or False) except ChannelConnectorError as err: self.create_issue( section='room', From 36e65aef48720bbaa647447ae4957f6f563c2129 Mon Sep 17 00:00:00 2001 From: Pablo Date: Fri, 7 Dec 2018 09:21:25 +0100 Subject: [PATCH 02/32] [ADD] Missing new arguments for board and room type class --- .../components/backend_adapter.py | 4 ++-- .../models/hotel_room_type/common.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/hotel_channel_connector_wubook/components/backend_adapter.py b/hotel_channel_connector_wubook/components/backend_adapter.py index 14a05666d..4ff5bba63 100644 --- a/hotel_channel_connector_wubook/components/backend_adapter.py +++ b/hotel_channel_connector_wubook/components/backend_adapter.py @@ -132,7 +132,7 @@ class WuBookAdapter(AbstractComponent): availability, shortcode[:4], defboard, - rtype=rtype + rtype ) if rcode != 0: raise ChannelConnectorError(_("Can't create room in WuBook"), { @@ -151,7 +151,7 @@ class WuBookAdapter(AbstractComponent): availability, scode, defboard, - rtype=rtype + rtype ) if rcode != 0: raise ChannelConnectorError(_("Can't modify room in WuBook"), { diff --git a/hotel_channel_connector_wubook/models/hotel_room_type/common.py b/hotel_channel_connector_wubook/models/hotel_room_type/common.py index c61ae509c..85813bb05 100644 --- a/hotel_channel_connector_wubook/models/hotel_room_type/common.py +++ b/hotel_channel_connector_wubook/models/hotel_room_type/common.py @@ -9,16 +9,16 @@ class HotelRoomTypeAdapter(Component): _inherit = 'wubook.adapter' _apply_on = 'channel.hotel.room.type' - def create_room(self, shortcode, name, capacity, price, availability): + def create_room(self, shortcode, name, capacity, price, availability, defboard, rtype): return super(HotelRoomTypeAdapter, self).create_room( - shortcode, name, capacity, price, availability) + shortcode, name, capacity, price, availability, defboard, rtype) def fetch_rooms(self): return super(HotelRoomTypeAdapter, self).fetch_rooms() - def modify_room(self, channel_room_id, name, capacity, price, availability, scode): + def modify_room(self, channel_room_id, name, capacity, price, availability, scode, defboard, rtype): return super(HotelRoomTypeAdapter, self).modify_room( - channel_room_id, name, capacity, price, availability, scode) + channel_room_id, name, capacity, price, availability, scode, defboard, rtype) def delete_room(self, channel_room_id): return super(HotelRoomTypeAdapter, self).delete_room(channel_room_id) From 7579c2fda3e90842bfdbd0eaa8f306cc8b783253 Mon Sep 17 00:00:00 2001 From: Pablo Date: Fri, 7 Dec 2018 20:52:13 +0100 Subject: [PATCH 03/32] [ADD] Base Test for Cases Scenario 1 (TS001) --- .../tests/README.rst | 168 ++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 hotel_channel_connector_wubook/tests/README.rst diff --git a/hotel_channel_connector_wubook/tests/README.rst b/hotel_channel_connector_wubook/tests/README.rst new file mode 100644 index 000000000..d4135ce5c --- /dev/null +++ b/hotel_channel_connector_wubook/tests/README.rst @@ -0,0 +1,168 @@ +.. raw:: html + + + +.. role:: red + +============================== +HOTEL CHANNEL CONNECTOR WUBOOK +============================== + +The following list define the test to be covered by this module. + +Knowledge Base +============== +- WuBook uses a default Restrictions Plan with ``rpid=0`` for the Online Reception restrictions. +- WuBook uses a default Parity Rate Plan with ``pid=0`` for the Online Reception prices. +- You can not define a Parity Restriction Plan for Online Receptions. +- You can define a Parity Rate Plan for Online Receptions. +- Handling Rooms: https://tdocs.wubook.net/wired/rooms.html +- Wired: updating availability https://tdocs.wubook.net/wired/avail.html + +Scenario 1 (TS001) +================== +:Prerequisites: You have a new WuBook account ready to use **without** Rooms, + neither Rate plans, Pricelists or Restrictions plans. + +Test TC001 +---------- + +:Summary: **Install** the `Hotel Channel Connector Wubook` module and + **create** a `Hotel Channel Backend` will bind WuBook as the hotel channel manager. + +:Procedure: + 1. Install the ``hotel_channel_connector_wubook`` module. + 2. Create a new Hotel Channel Backend with your WuBook Account Credentials. + 3. Generate a new Channel Service Security Token. + +:Result: + - You can Import OTA's Info. + - You can Export Availability, Restrictions and Pricelists. + - You can bind Rooms and Restriction Plans. + +:Remarks: You can not Import Rooms, neither Availability, Restriction Plans and Restriction Values, + Pricelist Plans and Pricelist Values because it is a new WuBook Account. + +:Status: Test Passed. + +Test TC002 +------------ + +:Summary: Bind **Room Types** to the Hotel Channel Connector Backend. + +:Requirement: TC001 + +:Procedure: Add the Hotel Channel Connector Backend to the Room Type. + +:Result: + - The Room Type is created in WuBook. + - You can modify the following fields: ``name``, ``capacity``, ``price``, ``availability``, + ``scode``, ``dboard``, ``rtype``. + +:Remarks: Creating a Room Type in WuBook will `make available` + a **default WuBook Restrictions Plan** with ``rpid=0`` and + a **default WuBook Price Plan** with ``pid=0``. + +:Status: Test Passed. + +Test TC003 +------------ + +:Summary: Bind **Restriction Plans** to the Hotel Channel Connector Backend. + +:Requirement: TC001 + +:Procedure: Add the Hotel Channel Connector Backend to the Restriction Plan. + +:Result: + - The Restriction Plan is created in WuBook. + - You can modify the following fields: ``name``. + +:Remarks: Creating a Restriction Plan in WuBook will `create` + a **new WuBook Restrictions Plan** with ``rpid!=0``. + +:Status: Test Passed. + +Test TC004 +---------- + +:Summary: Bind **Product Pricelist** to the Hotel Channel Connector Backend. + +:Requirement: TC001 + +:Procedure: Add the Hotel Channel Connector Backend to the Product Pricelist. + +:Result: + - The Product Pricelist is created in WuBook. + - You can modify the following fields: ``name``. + +:Remarks: Creating a Product Pricelist in WuBook will `create` a + **new Rate WuBook Price Plan** with ``pid != 0``. + +:Status: Test Passed. + + +Test TC005 +---------- + +:Summary: Bind **Availability** to the Hotel Channel Connector Backend. + +:Requirement: TC001 + +:Procedure: Add the Hotel Channel Connector Backend to the Availability. + +:Result: The Availability is created in WuBook. + +:Status: Unknown. + + +Test TC006 +---------- + +:Summary: Bind the **default Restriction Plan** in Odoo to the Hotel Channel Connector Backend + will start its **parity** with the default Restriction Plan **in WuBook**. + +:Requirement: TC001 + +:Procedure: Not defined yet. + +:Result: + - The Odoo Restriction Plan created in WuBook is in parity with the + default WuBook Restrictions Plan with ``rpid=0``. + +:Status: Unknown. + +Test TC007 +---------- + +:Summary: Bind the **default Product Pricelist** in Odoo to the Hotel Channel Connector Backend + will start its **parity** with the default Price Plan **in WuBook**. + +:Requirement: TC001 + +:Procedure: Not defined yet. + +:Result: + - The Product Pricelist created in WuBook is in parity with the + default WuBook Restrictions Plan with ``rpid=0``. + +:Status: Unknown. + +Test TC008 +---------- + +:Summary: Update any **binded field** in a Room Type will update the corresponding field in **WuBook**. + +:Requirement: TC001, TC002 + +:Procedure: Edit a Room Type and modify the ``name``. + +:Result: The name in WuBook is also updated. + +:Status: :red:`Failed`. + +:Reason: The field was not updated in WuBook + + From 061643c9464184cd8f14e0d13ce1c822ec3f322b Mon Sep 17 00:00:00 2001 From: Pablo Date: Fri, 7 Dec 2018 22:19:52 +0100 Subject: [PATCH 04/32] Remove not recognized styles --- hotel_channel_connector_wubook/tests/README.rst | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/hotel_channel_connector_wubook/tests/README.rst b/hotel_channel_connector_wubook/tests/README.rst index d4135ce5c..8e6e76f1a 100644 --- a/hotel_channel_connector_wubook/tests/README.rst +++ b/hotel_channel_connector_wubook/tests/README.rst @@ -1,11 +1,3 @@ -.. raw:: html - - - -.. role:: red - ============================== HOTEL CHANNEL CONNECTOR WUBOOK ============================== @@ -161,7 +153,7 @@ Test TC008 :Result: The name in WuBook is also updated. -:Status: :red:`Failed`. +:Status: Failed. :Reason: The field was not updated in WuBook From cf4445c3e9b8c78596cf72321de5e39d0f7e4d00 Mon Sep 17 00:00:00 2001 From: Pablo Date: Thu, 13 Dec 2018 17:36:40 +0100 Subject: [PATCH 05/32] [UPD] Test TC006 Passed --- .../tests/README.rst | 9 +- .../test_channel_hotel_room_type_model.py | 87 +++++++++++++++++++ .../tests/test_hotel_virtual_room_model.py | 73 ---------------- 3 files changed, 91 insertions(+), 78 deletions(-) create mode 100644 hotel_channel_connector_wubook/tests/test_channel_hotel_room_type_model.py delete mode 100644 hotel_channel_connector_wubook/tests/test_hotel_virtual_room_model.py diff --git a/hotel_channel_connector_wubook/tests/README.rst b/hotel_channel_connector_wubook/tests/README.rst index 8e6e76f1a..a67afc178 100644 --- a/hotel_channel_connector_wubook/tests/README.rst +++ b/hotel_channel_connector_wubook/tests/README.rst @@ -114,17 +114,17 @@ Test TC006 ---------- :Summary: Bind the **default Restriction Plan** in Odoo to the Hotel Channel Connector Backend - will start its **parity** with the default Restriction Plan **in WuBook**. + using ``ID on Channel=0`` will start its **parity** with the default Restriction Plan **in WuBook**. :Requirement: TC001 -:Procedure: Not defined yet. +:Procedure: Add the Hotel Channel Connector Backend to the Restriction Plan using ``ID on Channel=0``. :Result: - - The Odoo Restriction Plan created in WuBook is in parity with the + - The Odoo Restriction Plan will be in parity with the default WuBook Restrictions Plan with ``rpid=0``. -:Status: Unknown. +:Status: Test Passed. Test TC007 ---------- @@ -157,4 +157,3 @@ Test TC008 :Reason: The field was not updated in WuBook - diff --git a/hotel_channel_connector_wubook/tests/test_channel_hotel_room_type_model.py b/hotel_channel_connector_wubook/tests/test_channel_hotel_room_type_model.py new file mode 100644 index 000000000..cb18beb7e --- /dev/null +++ b/hotel_channel_connector_wubook/tests/test_channel_hotel_room_type_model.py @@ -0,0 +1,87 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2017 Solucións Aloxa S.L. +# Alexandre Díaz +# +# +# 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 . +# +############################################################################## +from datetime import timedelta +from odoo.tools import ( + DEFAULT_SERVER_DATETIME_FORMAT, + DEFAULT_SERVER_DATE_FORMAT) +from odoo.exceptions import AccessError +from .common import TestChannelConnectorWubook + + +class TestChannelRoomType(TestChannelConnectorWubook): + + def create_room(self, shortcode, name, capacity, price, availability, defboard, rtype): + return True + + def fetch_rooms(self): + return True + + def modify_room(self, channel_room_id, name, capacity, price, availability, scode, defboard, rtype): + import wdb; wdb.set_trace() + self.hotel_room_type_simple.ota_capacity = 1 + return True + + def delete_room(self, channel_room_id): + return True + + # def test_get_capacity(self): + # self.assertEqual(self.room_type_0.wcapacity, + # 1, + # "Invalid wcapacity") + + # def test_check_wcapacity(self): + # with self.assertRaises(ValidationError): + # self.room_type_0.sudo(self.user_hotel_manager).write({ + # 'wcapacity': 0 + # }) + + # def test_check_wscode(self): + # with self.assertRaises(ValidationError): + # self.room_type_0.sudo(self.user_hotel_manager).write({ + # 'wscode': 'abcdefg' + # }) + + # def test_get_restrictions(self): + # now_utc_dt = date_utils.now() + # rests = self.hotel_room_type_budget.sudo( + # self.user_hotel_manager).get_restrictions( + # now_utc_dt.strftime( + # DEFAULT_SERVER_DATE_FORMAT)) + # self.assertTrue(any(rests), "Restrictions not found") + + # def test_import_rooms(self): + # self.room_type_0.sudo(self.user_hotel_manager).import_rooms() + + # def test_create(self): + # room_type_obj = self.env['hotel.room.type'] + # room_type = room_type_obj.sudo(self.user_hotel_manager).create({ + # 'name': 'Budget Room', + # 'virtual_code': '001', + # 'list_price': 50, + # 'wrid': 1234 + # }) + # room_type.unlink() + + # def test_unlink(self): + # with self.assertRaises(AccessError): + # self.hotel_room_type_simple.sudo(self.manager_hotel_demo).unlink() diff --git a/hotel_channel_connector_wubook/tests/test_hotel_virtual_room_model.py b/hotel_channel_connector_wubook/tests/test_hotel_virtual_room_model.py deleted file mode 100644 index 0259f6ca1..000000000 --- a/hotel_channel_connector_wubook/tests/test_hotel_virtual_room_model.py +++ /dev/null @@ -1,73 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2017 Solucións Aloxa S.L. -# Alexandre Díaz -# -# -# 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 . -# -############################################################################## -from datetime import timedelta -from openerp.tools import ( - DEFAULT_SERVER_DATETIME_FORMAT, - DEFAULT_SERVER_DATE_FORMAT) -from openerp.exceptions import ValidationError -from odoo.addons.hotel import date_utils -from .common import TestHotelWubook - - -class TestHotelVirtualRoom(TestHotelWubook): - - def test_get_capacity(self): - self.assertEqual(self.hotel_room_type_budget.wcapacity, - 1, - "Invalid wcapacity") - - def test_check_wcapacity(self): - with self.assertRaises(ValidationError): - self.hotel_room_type_budget.sudo(self.user_hotel_manager).write({ - 'wcapacity': 0 - }) - - def test_check_wscode(self): - with self.assertRaises(ValidationError): - self.hotel_room_type_budget.sudo(self.user_hotel_manager).write({ - 'wscode': 'abcdefg' - }) - - def test_get_restrictions(self): - now_utc_dt = date_utils.now() - rests = self.hotel_room_type_budget.sudo( - self.user_hotel_manager).get_restrictions( - now_utc_dt.strftime( - DEFAULT_SERVER_DATE_FORMAT)) - self.assertTrue(any(rests), "Restrictions not found") - - def test_import_rooms(self): - self.hotel_room_type_budget.sudo(self.user_hotel_manager).import_rooms() - - def test_create(self): - room_type_obj = self.env['hotel.room.type'] - room_type = room_type_obj.sudo(self.user_hotel_manager).create({ - 'name': 'Budget Room', - 'virtual_code': '001', - 'list_price': 50, - 'wrid': 1234 - }) - room_type.unlink() - - def test_unlink(self): - self.hotel_room_type_budget.sudo(self.user_hotel_manager).unlink() From e5e52b697fc99944bb2b54ddf4ad64ce659948c1 Mon Sep 17 00:00:00 2001 From: Pablo Date: Mon, 14 Jan 2019 10:33:39 +0100 Subject: [PATCH 06/32] [UPD] Update test procedures --- .../tests/README.rst | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/hotel_channel_connector_wubook/tests/README.rst b/hotel_channel_connector_wubook/tests/README.rst index a67afc178..e4d3b0013 100644 --- a/hotel_channel_connector_wubook/tests/README.rst +++ b/hotel_channel_connector_wubook/tests/README.rst @@ -107,18 +107,20 @@ Test TC005 :Result: The Availability is created in WuBook. -:Status: Unknown. +:Status: Test Failed. + +:Reason: The availability is not updated in WuBook. Test TC006 ---------- -:Summary: Bind the **default Restriction Plan** in Odoo to the Hotel Channel Connector Backend +:Summary: Bind the **Restriction Plan** in Odoo to the Hotel Channel Connector Backend using ``ID on Channel=0`` will start its **parity** with the default Restriction Plan **in WuBook**. :Requirement: TC001 -:Procedure: Add the Hotel Channel Connector Backend to the Restriction Plan using ``ID on Channel=0``. +:Procedure: Add the Hotel Channel Connector Backend to the Restriction Plan using **``ID on Channel=0``**. :Result: - The Odoo Restriction Plan will be in parity with the @@ -129,12 +131,12 @@ Test TC006 Test TC007 ---------- -:Summary: Bind the **default Product Pricelist** in Odoo to the Hotel Channel Connector Backend +:Summary: Bind the **Product Pricelist** in Odoo to the Hotel Channel Connector Backend will start its **parity** with the default Price Plan **in WuBook**. :Requirement: TC001 -:Procedure: Not defined yet. +:Procedure: Add the Hotel Channel Connector Backend to the Product Pricelis using **``ID on Channel=0``**. :Result: - The Product Pricelist created in WuBook is in parity with the @@ -155,5 +157,9 @@ Test TC008 :Status: Failed. -:Reason: The field was not updated in WuBook +:Reason: The field was not updated in WuBook. +Test for unbind and delete in progress +-------------------------------------- + +:Summary: Preparing the tests for unbind and delete actions. \ No newline at end of file From 9a71482a5bea742b0c51b6ec0fe9d408fa7743e6 Mon Sep 17 00:00:00 2001 From: Pablo Date: Mon, 14 Jan 2019 17:00:59 +0100 Subject: [PATCH 07/32] [UPD] Update tests status --- .../tests/README.rst | 70 +++++++++++++------ 1 file changed, 50 insertions(+), 20 deletions(-) diff --git a/hotel_channel_connector_wubook/tests/README.rst b/hotel_channel_connector_wubook/tests/README.rst index e4d3b0013..80c2e1990 100644 --- a/hotel_channel_connector_wubook/tests/README.rst +++ b/hotel_channel_connector_wubook/tests/README.rst @@ -16,7 +16,7 @@ Knowledge Base Scenario 1 (TS001) ================== :Prerequisites: You have a new WuBook account ready to use **without** Rooms, - neither Rate plans, Pricelists or Restrictions plans. + neither Rate plans or Restrictions plans. Test TC001 ---------- @@ -32,7 +32,7 @@ Test TC001 :Result: - You can Import OTA's Info. - You can Export Availability, Restrictions and Pricelists. - - You can bind Rooms and Restriction Plans. + - You can bind Rooms, Rate Plans and Restriction Plans. :Remarks: You can not Import Rooms, neither Availability, Restriction Plans and Restriction Values, Pricelist Plans and Pricelist Values because it is a new WuBook Account. @@ -54,8 +54,8 @@ Test TC002 ``scode``, ``dboard``, ``rtype``. :Remarks: Creating a Room Type in WuBook will `make available` - a **default WuBook Restrictions Plan** with ``rpid=0`` and - a **default WuBook Price Plan** with ``pid=0``. + a **default WuBook Restrictions Plan** named **WuBook Restrictions** with ``rpid=0`` and + a **default WuBook Rate Plan** named **WuBook Parity** with ``pid=0``. :Status: Test Passed. @@ -78,6 +78,22 @@ Test TC003 :Status: Test Passed. Test TC004 +------------ + +:Summary: Add **Restrictions** + +:Requirement: TC001, TC002, TC003 + +:Procedure: Add Restriction Items into the Restriction Plan. + +:Result: + - The Restriction Plan is updated in WuBook. + +:Remarks: For this test you need Push Restrictions in the Hotel Channel Backends Export form. + +:Status: Test Passed. + +Test TC005 ---------- :Summary: Bind **Product Pricelist** to the Hotel Channel Connector Backend. @@ -91,28 +107,46 @@ Test TC004 - You can modify the following fields: ``name``. :Remarks: Creating a Product Pricelist in WuBook will `create` a - **new Rate WuBook Price Plan** with ``pid != 0``. + **new WuBook Rate Plan** with ``pid!=0``. :Status: Test Passed. +Test TC006 +------------ -Test TC005 ----------- +:Summary: Add Room Type **Price** -:Summary: Bind **Availability** to the Hotel Channel Connector Backend. +:Requirement: TC001, TC002, TC005 -:Requirement: TC001 +:Procedure: Add Room Type Unit Price into the Rate Plan. -:Procedure: Add the Hotel Channel Connector Backend to the Availability. +:Result: + - The Rate Plan is updated in WuBook. -:Result: The Availability is created in WuBook. +:Remarks: For this test you use the Massive Changes Wizard. :Status: Test Failed. -:Reason: The availability is not updated in WuBook. +:Reason: ``File "/opt/odoo/auto/addons/hotel_channel_connector/models/product_pricelist_item/common.py", line 69, + in on_record_create for pricelist_bind in record.restriction_id.channel_bind_ids: + AttributeError: 'product.pricelist.item' object has no attribute 'restriction_id'`` +Test TC007 +---------- -Test TC006 +:Summary: Add **Availability** to the Hotel Room Type. + +:Requirement: TC001, TC002, T003 + +:Procedure: Add the availability to the Room Type using a Hotel Channel Connector Backend. + +:Result: The Availability is created in WuBook. + +:Remarks: The availability is updated in WuBook after Push Availability. + +:Status: Test Passed. + +Test TC008 ---------- :Summary: Bind the **Restriction Plan** in Odoo to the Hotel Channel Connector Backend @@ -124,11 +158,11 @@ Test TC006 :Result: - The Odoo Restriction Plan will be in parity with the - default WuBook Restrictions Plan with ``rpid=0``. + default WuBook Restrictions Plan with ``rpid=0`` named **WuBook Restrictions**. :Status: Test Passed. -Test TC007 +Test TC009 ---------- :Summary: Bind the **Product Pricelist** in Odoo to the Hotel Channel Connector Backend @@ -144,7 +178,7 @@ Test TC007 :Status: Unknown. -Test TC008 +Test TC010 ---------- :Summary: Update any **binded field** in a Room Type will update the corresponding field in **WuBook**. @@ -159,7 +193,3 @@ Test TC008 :Reason: The field was not updated in WuBook. -Test for unbind and delete in progress --------------------------------------- - -:Summary: Preparing the tests for unbind and delete actions. \ No newline at end of file From d464a5cc531e088929a7001feccdee0916239346 Mon Sep 17 00:00:00 2001 From: Pablo Date: Mon, 14 Jan 2019 17:54:12 +0100 Subject: [PATCH 08/32] [ADD] Scenario 2 (TS002) and TS001 minor updates --- .../tests/README.rst | 117 ++++++++++++------ 1 file changed, 81 insertions(+), 36 deletions(-) diff --git a/hotel_channel_connector_wubook/tests/README.rst b/hotel_channel_connector_wubook/tests/README.rst index 80c2e1990..fb004e2ff 100644 --- a/hotel_channel_connector_wubook/tests/README.rst +++ b/hotel_channel_connector_wubook/tests/README.rst @@ -13,12 +13,12 @@ Knowledge Base - Handling Rooms: https://tdocs.wubook.net/wired/rooms.html - Wired: updating availability https://tdocs.wubook.net/wired/avail.html -Scenario 1 (TS001) +Scenario 1 (TS100) ================== :Prerequisites: You have a new WuBook account ready to use **without** Rooms, neither Rate plans or Restrictions plans. -Test TC001 +Test TC101 ---------- :Summary: **Install** the `Hotel Channel Connector Wubook` module and @@ -39,12 +39,12 @@ Test TC001 :Status: Test Passed. -Test TC002 ------------- +Test TC102 +---------- :Summary: Bind **Room Types** to the Hotel Channel Connector Backend. -:Requirement: TC001 +:Requirement: TC101 :Procedure: Add the Hotel Channel Connector Backend to the Room Type. @@ -59,12 +59,12 @@ Test TC002 :Status: Test Passed. -Test TC003 ------------- +Test TC103 +---------- :Summary: Bind **Restriction Plans** to the Hotel Channel Connector Backend. -:Requirement: TC001 +:Requirement: TC101 :Procedure: Add the Hotel Channel Connector Backend to the Restriction Plan. @@ -77,28 +77,44 @@ Test TC003 :Status: Test Passed. -Test TC004 ------------- +Test TC104 +---------- :Summary: Add **Restrictions** -:Requirement: TC001, TC002, TC003 +:Requirement: TC101, TC102, TC103 :Procedure: Add Restriction Items into the Restriction Plan. -:Result: - - The Restriction Plan is updated in WuBook. +:Result: The Restriction Plan is updated in WuBook. :Remarks: For this test you need Push Restrictions in the Hotel Channel Backends Export form. :Status: Test Passed. -Test TC005 +Test TC105 +---------- + +:Summary: Delete **Restrictions** + +:Requirement: TC101, TC102, TC103 + +:Procedure: Delete a Restriction Items in Odoo. + +:Result: The Restriction Plan is updated in WuBook. + +:Remarks: For this test you need Push Restrictions in the Hotel Channel Backends Export form. + +:Status: Test Failed. + +:Reason: Restrictions remain in WuBook. + +Test TC106 ---------- :Summary: Bind **Product Pricelist** to the Hotel Channel Connector Backend. -:Requirement: TC001 +:Requirement: TC101 :Procedure: Add the Hotel Channel Connector Backend to the Product Pricelist. @@ -111,17 +127,16 @@ Test TC005 :Status: Test Passed. -Test TC006 ------------- +Test TC107 +---------- :Summary: Add Room Type **Price** -:Requirement: TC001, TC002, TC005 +:Requirement: TC101, TC102, TC105 :Procedure: Add Room Type Unit Price into the Rate Plan. -:Result: - - The Rate Plan is updated in WuBook. +:Result: The Rate Plan is updated in WuBook. :Remarks: For this test you use the Massive Changes Wizard. @@ -131,12 +146,12 @@ Test TC006 in on_record_create for pricelist_bind in record.restriction_id.channel_bind_ids: AttributeError: 'product.pricelist.item' object has no attribute 'restriction_id'`` -Test TC007 +Test TC108 ---------- :Summary: Add **Availability** to the Hotel Room Type. -:Requirement: TC001, TC002, T003 +:Requirement: TC101, TC102, T103 :Procedure: Add the availability to the Room Type using a Hotel Channel Connector Backend. @@ -146,44 +161,57 @@ Test TC007 :Status: Test Passed. -Test TC008 +Test TC109 +---------- + +:Summary: Delete **Availability** from the Hotel Room Type. + +:Requirement: TC101, TC102, T103 + +:Procedure: Delete Availability Items in Odoo. + +:Result: The Restriction Plan is updated in WuBook. + +:Remarks: The availability is updated in WuBook after Push Availability. + +:Status: Test Failed. + +Test TC110 ---------- :Summary: Bind the **Restriction Plan** in Odoo to the Hotel Channel Connector Backend using ``ID on Channel=0`` will start its **parity** with the default Restriction Plan **in WuBook**. -:Requirement: TC001 +:Requirement: TC101 :Procedure: Add the Hotel Channel Connector Backend to the Restriction Plan using **``ID on Channel=0``**. -:Result: - - The Odoo Restriction Plan will be in parity with the - default WuBook Restrictions Plan with ``rpid=0`` named **WuBook Restrictions**. +:Result: The Odoo Restriction Plan will be in parity with the + default WuBook Restrictions Plan with ``rpid=0`` named **WuBook Restrictions**. :Status: Test Passed. -Test TC009 +Test TC111 ---------- :Summary: Bind the **Product Pricelist** in Odoo to the Hotel Channel Connector Backend will start its **parity** with the default Price Plan **in WuBook**. -:Requirement: TC001 +:Requirement: TC101 :Procedure: Add the Hotel Channel Connector Backend to the Product Pricelis using **``ID on Channel=0``**. -:Result: - - The Product Pricelist created in WuBook is in parity with the - default WuBook Restrictions Plan with ``rpid=0``. +:Result: The Product Pricelist created in WuBook is in parity with the + default WuBook Restrictions Plan with ``rpid=0``. :Status: Unknown. -Test TC010 +Test TC112 ---------- -:Summary: Update any **binded field** in a Room Type will update the corresponding field in **WuBook**. +:Summary: Update any **binded field** in a Room Type will automatically update the corresponding field in **WuBook**. -:Requirement: TC001, TC002 +:Requirement: TC101, TC102 :Procedure: Edit a Room Type and modify the ``name``. @@ -191,5 +219,22 @@ Test TC010 :Status: Failed. -:Reason: The field was not updated in WuBook. +:Reason: Some fields (``name``, ``list_price``) are updated `only` if the Hotel Channel Connector Binding is updated. + +Scenario 2 (TS002) +================== +:Prerequisites: `Scenario 1 (TS100)`_ Tests passed. + +Test TC201 +---------- + +:Summary: **Create** a Reservation decreases the Room Type Availability in one in the corresponding Plan in Wubook. + +:Procedure: Create a reservation of any room type binded to the Hotel Channel Connector Backend. + +:Result: The availability is decreased by one. + +:Status: Test Failed. + +:Reason: The availability remains the same. \ No newline at end of file From 368bbd52fd117d7e89c9430cb816477f8fdaaa1b Mon Sep 17 00:00:00 2001 From: Pablo Date: Tue, 15 Jan 2019 16:30:44 +0100 Subject: [PATCH 09/32] [UPD] Test TC007 Passed --- hotel_channel_connector_wubook/tests/README.rst | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/hotel_channel_connector_wubook/tests/README.rst b/hotel_channel_connector_wubook/tests/README.rst index fb004e2ff..5214ff670 100644 --- a/hotel_channel_connector_wubook/tests/README.rst +++ b/hotel_channel_connector_wubook/tests/README.rst @@ -138,13 +138,9 @@ Test TC107 :Result: The Rate Plan is updated in WuBook. -:Remarks: For this test you use the Massive Changes Wizard. +:Remarks: For this test use the Massive Changes Wizard. -:Status: Test Failed. - -:Reason: ``File "/opt/odoo/auto/addons/hotel_channel_connector/models/product_pricelist_item/common.py", line 69, - in on_record_create for pricelist_bind in record.restriction_id.channel_bind_ids: - AttributeError: 'product.pricelist.item' object has no attribute 'restriction_id'`` +:Status: Test Passed. Test TC108 ---------- From f6c0e1603cddb12a7b5fbb3eefd5fc106612a58a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20D=C3=ADaz?= Date: Tue, 15 Jan 2019 16:22:18 +0100 Subject: [PATCH 10/32] [FIX] Connector Pricelist Item --- hotel_channel_connector/models/product_pricelist_item/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotel_channel_connector/models/product_pricelist_item/common.py b/hotel_channel_connector/models/product_pricelist_item/common.py index 6e25e546e..0dbc238c4 100644 --- a/hotel_channel_connector/models/product_pricelist_item/common.py +++ b/hotel_channel_connector/models/product_pricelist_item/common.py @@ -66,7 +66,7 @@ class BindingProductPricelistItemListener(Component): if not any(record.channel_bind_ids): channel_product_pricelist_item_obj = self.env[ 'channel.product.pricelist.item'] - for pricelist_bind in record.restriction_id.channel_bind_ids: + for pricelist_bind in record.pricelist_id.channel_bind_ids: pricelist_item_bind = channel_product_pricelist_item_obj.search([ ('odoo_id', '=', record.id), ('backend_id', '=', pricelist_bind.backend_id.id), From 00ca2d88458c364a789f3d8fa907fbd2cc978251 Mon Sep 17 00:00:00 2001 From: Pablo Date: Tue, 15 Jan 2019 19:34:40 +0100 Subject: [PATCH 11/32] [ADD] test cases for basic reservation management --- .../tests/README.rst | 55 ++++++++++++++++++- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/hotel_channel_connector_wubook/tests/README.rst b/hotel_channel_connector_wubook/tests/README.rst index 5214ff670..b72c4c3cc 100644 --- a/hotel_channel_connector_wubook/tests/README.rst +++ b/hotel_channel_connector_wubook/tests/README.rst @@ -222,15 +222,64 @@ Scenario 2 (TS002) ================== :Prerequisites: `Scenario 1 (TS100)`_ Tests passed. +:Summary: This tests review the basic reservation management. + Test TC201 ---------- -:Summary: **Create** a Reservation decreases the Room Type Availability in one in the corresponding Plan in Wubook. +:Summary: **Create** a Reservation **decreases** the Room Type Availability in one in the corresponding Plan in Wubook. -:Procedure: Create a reservation of any room type binded to the Hotel Channel Connector Backend. +:Procedure: Create a reservation with a room type binded to the Hotel Channel Connector Backend. :Result: The availability is decreased by one. :Status: Test Failed. -:Reason: The availability remains the same. \ No newline at end of file +:Reason: The availability remains the same. + +Test TC202 +---------- + +:Summary: **Cancel** a Reservation **increases** the Room Type Availability in one in the corresponding Plan in Wubook. + +:Procedure: Cancel a reservation with a room type binded to the Hotel Channel Connector Backend. + +:Result: The availability is increased by one. + +:Status: Not done yet. + +Test TC203 +---------- + +:Summary: **Change** the Room Type in a Reservation **modifies** the Room Type Availability + in the corresponding Plan in Wubook. + +:Procedure: Change the Room Type in a reservation to any room type binded to the Hotel Channel Connector Backend. + +:Result: The availability is modified according to the change done. + +:Status: Not done yet. + +Test TC204 +---------- + +:Summary: **Change** Checkin/Checkout dates in a Reservation **modifies** the Room Type Availability + in the corresponding Plan in Wubook. + +:Procedure: Change the Checkin/Checkout in a reservation with a room type binded to the Hotel Channel Connector Backend. + +:Result: The availability is modified according to the change done. + +:Status: Not done yet. + +Test TC205 +---------- + +:Summary: **Reselling** state in a Reservation **increases** the Room Type Availability + in the corresponding Plan in Wubook. + +:Procedure: Mark a reservation as `reselling` with a room type binded to the Hotel Channel Connector Backend. + +:Result: The availability is increased by one. + +:Status: Not done yet. \ No newline at end of file From bf3924f6046e89c0e4704c993cc07371bd74e4ba Mon Sep 17 00:00:00 2001 From: Pablo Date: Tue, 15 Jan 2019 20:51:14 +0100 Subject: [PATCH 12/32] [WIP] Add sketch unittests for addons hotel_channel_connector_wubook --- .../tests/__init__.py | 1 + .../tests/common.py | 512 +++++++++--------- ..._channel_hotel_room_type_adapter_model.py} | 15 +- 3 files changed, 269 insertions(+), 259 deletions(-) rename hotel_channel_connector_wubook/tests/{test_channel_hotel_room_type_model.py => test_channel_hotel_room_type_adapter_model.py} (85%) diff --git a/hotel_channel_connector_wubook/tests/__init__.py b/hotel_channel_connector_wubook/tests/__init__.py index c9580b6f0..4c8a86f24 100644 --- a/hotel_channel_connector_wubook/tests/__init__.py +++ b/hotel_channel_connector_wubook/tests/__init__.py @@ -1,2 +1,3 @@ # Copyright 2018 Alexandre Díaz # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from . import test_channel_hotel_room_type_adapter_model \ No newline at end of file diff --git a/hotel_channel_connector_wubook/tests/common.py b/hotel_channel_connector_wubook/tests/common.py index 336c2fd69..22144473d 100644 --- a/hotel_channel_connector_wubook/tests/common.py +++ b/hotel_channel_connector_wubook/tests/common.py @@ -22,13 +22,12 @@ ############################################################################## from datetime import timedelta from odoo import api -from odoo.addons.hotel import date_utils from odoo.addons.hotel.tests.common import TestHotel -from odoo.addons.hotel_wubook_proto.wubook import ( - DEFAULT_WUBOOK_DATE_FORMAT, - DEFAULT_WUBOOK_TIME_FORMAT, - WUBOOK_STATUS_CONFIRMED, - WUBOOK_STATUS_CANCELLED) +# from odoo.addons.hotel_wubook_proto.wubook import ( +# DEFAULT_WUBOOK_DATE_FORMAT, +# DEFAULT_WUBOOK_TIME_FORMAT, +# WUBOOK_STATUS_CONFIRMED, +# WUBOOK_STATUS_CANCELLED) from random import randint import logging _logger = logging.getLogger(__name__) @@ -38,7 +37,7 @@ class TestHotelWubook(TestHotel): @classmethod def _init_mock_hotel(cls): - super(TestHotelWubook, cls)._init_mock_hotel() + super()._init_mock_hotel() @api.multi def wubook_ommit(self, *args, **kwargs): @@ -49,262 +48,275 @@ class TestHotelWubook(TestHotel): wid=False, dfrom=False, dto=False): _logger.info("ISSUE CREATED:\n\t- %s\n\t--- %s", section, message) - cls.env['wubook']._patch_method('create_channel_connector_issue', - wubook_create_channel_connector_issue) - cls.env['wubook']._patch_method('is_valid_account', wubook_ommit) - cls.env['wubook']._patch_method('initialize', wubook_ommit) - cls.env['wubook']._patch_method('push_activation', wubook_ommit) - cls.env['wubook']._patch_method('init_connection', wubook_ommit) - cls.env['wubook']._patch_method('close_connection', wubook_ommit) - cls.env['wubook']._patch_method('create_room', wubook_ommit) - cls.env['wubook']._patch_method('modify_room', wubook_ommit) - cls.env['wubook']._patch_method('delete_room', wubook_ommit) - cls.env['wubook']._patch_method('import_rooms', wubook_ommit) - cls.env['wubook']._patch_method('fetch_rooms_values', wubook_ommit) - cls.env['wubook']._patch_method('update_availability', wubook_ommit) - cls.env['wubook']._patch_method('corporate_fetch', wubook_ommit) - cls.env['wubook']._patch_method('create_reservation', wubook_ommit) - cls.env['wubook']._patch_method('cancel_reservation', wubook_ommit) - cls.env['wubook']._patch_method('fetch_new_bookings', wubook_ommit) - cls.env['wubook']._patch_method('fetch_booking', wubook_ommit) - cls.env['wubook']._patch_method('mark_bookings', wubook_ommit) - cls.env['wubook']._patch_method('create_plan', wubook_ommit) - cls.env['wubook']._patch_method('delete_plan', wubook_ommit) - cls.env['wubook']._patch_method('update_plan_name', wubook_ommit) - cls.env['wubook']._patch_method('update_plan_prices', wubook_ommit) - cls.env['wubook']._patch_method('update_plan_periods', wubook_ommit) - cls.env['wubook']._patch_method('import_pricing_plans', wubook_ommit) - cls.env['wubook']._patch_method('fetch_plan_prices', wubook_ommit) - cls.env['wubook']._patch_method('fetch_all_plan_prices', wubook_ommit) - cls.env['wubook']._patch_method('import_restriction_plans', - wubook_ommit) - cls.env['wubook']._patch_method('fetch_rplan_restrictions', - wubook_ommit) - cls.env['wubook']._patch_method('update_rplan_values', wubook_ommit) - cls.env['wubook']._patch_method('create_rplan', wubook_ommit) - cls.env['wubook']._patch_method('rename_rplan', wubook_ommit) - cls.env['wubook']._patch_method('delete_rplan', wubook_ommit) - cls.env['wubook']._patch_method('import_channels_info', wubook_ommit) - cls.env['wubook']._patch_method('push_changes', wubook_ommit) - cls.env['wubook']._patch_method('push_availability', wubook_ommit) - cls.env['wubook']._patch_method('push_priceplans', wubook_ommit) - cls.env['wubook']._patch_method('push_restrictions', wubook_ommit) + # cls.env['wubook']._patch_method('create_channel_connector_issue', + # wubook_create_channel_connector_issue) + # cls.env['wubook']._patch_method('is_valid_account', wubook_ommit) + # cls.env['wubook']._patch_method('initialize', wubook_ommit) + # cls.env['wubook']._patch_method('push_activation', wubook_ommit) + # cls.env['wubook']._patch_method('init_connection', wubook_ommit) + # cls.env['wubook']._patch_method('close_connection', wubook_ommit) + # cls.env['wubook']._patch_method('create_room', wubook_ommit) + # cls.env['wubook']._patch_method('modify_room', wubook_ommit) + # cls.env['wubook']._patch_method('delete_room', wubook_ommit) + # cls.env['wubook']._patch_method('import_rooms', wubook_ommit) + # cls.env['wubook']._patch_method('fetch_rooms_values', wubook_ommit) + # cls.env['wubook']._patch_method('update_availability', wubook_ommit) + # cls.env['wubook']._patch_method('corporate_fetch', wubook_ommit) + # cls.env['wubook']._patch_method('create_reservation', wubook_ommit) + # cls.env['wubook']._patch_method('cancel_reservation', wubook_ommit) + # cls.env['wubook']._patch_method('fetch_new_bookings', wubook_ommit) + # cls.env['wubook']._patch_method('fetch_booking', wubook_ommit) + # cls.env['wubook']._patch_method('mark_bookings', wubook_ommit) + # cls.env['wubook']._patch_method('create_plan', wubook_ommit) + # cls.env['wubook']._patch_method('delete_plan', wubook_ommit) + # cls.env['wubook']._patch_method('update_plan_name', wubook_ommit) + # cls.env['wubook']._patch_method('update_plan_prices', wubook_ommit) + # cls.env['wubook']._patch_method('update_plan_periods', wubook_ommit) + # cls.env['wubook']._patch_method('import_pricing_plans', wubook_ommit) + # cls.env['wubook']._patch_method('fetch_plan_prices', wubook_ommit) + # cls.env['wubook']._patch_method('fetch_all_plan_prices', wubook_ommit) + # cls.env['wubook']._patch_method('import_restriction_plans', + # wubook_ommit) + # cls.env['wubook']._patch_method('fetch_rplan_restrictions', + # wubook_ommit) + # cls.env['wubook']._patch_method('update_rplan_values', wubook_ommit) + # cls.env['wubook']._patch_method('create_rplan', wubook_ommit) + # cls.env['wubook']._patch_method('rename_rplan', wubook_ommit) + # cls.env['wubook']._patch_method('delete_rplan', wubook_ommit) + # cls.env['wubook']._patch_method('import_channels_info', wubook_ommit) + # cls.env['wubook']._patch_method('push_changes', wubook_ommit) + # cls.env['wubook']._patch_method('push_availability', wubook_ommit) + # cls.env['wubook']._patch_method('push_priceplans', wubook_ommit) + # cls.env['wubook']._patch_method('push_restrictions', wubook_ommit) - def create_wubook_booking(self, creator, checkin, partner, rinfo, - channel=0, notes=''): - rcode = randint(100000, 999999) - crcode = randint(100000, 999999) - brate = randint(100000, 999999) - id_woodoo = randint(100000, 999999) + # def create_wubook_booking(self, creator, checkin, partner, rinfo, + # channel=0, notes=''): + # rcode = randint(100000, 999999) + # crcode = randint(100000, 999999) + # brate = randint(100000, 999999) + # id_woodoo = randint(100000, 999999) + # + # if not partner.email or partner.email == '': + # self.raiseException("Partner doesn't have a mail") + # + # now_utc_dt = date_utils.now() + # now_dt = date_utils.dt_as_timezone(now_utc_dt, self.tz_hotel) + # checkin_utc_dt = date_utils.get_datetime(checkin) + # checkin_dt = date_utils.dt_as_timezone(checkin_utc_dt, self.tz_hotel) + # numdays = 0 + # for k_room, v_room in rinfo.iteritems(): + # numdays = max(len(v_room['dayprices']), numdays) + # checkout_utc_dt = checkin_utc_dt + timedelta(days=numdays) + # checkout_dt = date_utils.dt_as_timezone(checkout_utc_dt, self.tz_hotel) + # date_diff = date_utils.date_diff(checkin_utc_dt, checkout_utc_dt, + # hours=False) + # + # # Generate Day Prices + # dayprices = {} + # total_amount = 0.0 + # for k_room, v_room in rinfo.iteritems(): + # for price in v_room['dayprices']: + # dayprices.setdefault(k_room, []).append(price) + # total_amount += price + # # Generate Values + # rooms = [] + # rooms_occu = [] + # booked_rooms = [] + # room_type_obj = self.env['hotel.room.type'] + # max_persons = 0 + # for k_room, v_room in rinfo.iteritems(): + # room_type = room_type_obj.search([ + # ('wrid', '=', k_room) + # ], limit=1) + # # Generate Rooms + # for price in range(0, len(v_room['occupancy'])): + # rooms.append(k_room) + # # Generate Rooms Occupancies + # for val in v_room['occupancy']: + # # Generate Rooms Occupancies + # rooms_occu.append({ + # 'id': k_room, + # 'occupancy': val, + # }) + # # Generate Booked Rooms + # roomdays = [] + # for k_price, v_price in enumerate(v_room['dayprices']): + # ndate = checkin_dt + timedelta(days=k_price) + # roomdays.append({ + # 'ancillary': {}, + # 'rate_id': 3, + # 'price': v_price,create_channel_connector_issue + # 'day': ndate.strftime(DEFAULT_WUBOOK_DATE_FORMAT) + # }) + # booked_rooms.append({ + # 'ancillary': { + # 'channel_room_id': 1, + # 'channel_room_name': room_type.name, + # 'addons': [], + # 'guests': val + # }, + # 'room_id': k_room, + # 'roomdays': roomdays + # }) + # if val > max_persons: + # max_persons = val + # + # return { + # 'id_channel': channel, + # 'special_offer': '', + # 'reservation_code': rcode, + # 'dayprices': dayprices, + # 'arrival_hour': checkin_dt.strftime(DEFAULT_WUBOOK_TIME_FORMAT), + # 'booked_rate': brate, + # 'rooms': ','.join(map(str, rooms)), + # 'customer_mail': partner.email, + # 'customer_country': 'ES', + # 'children': 0, + # 'payment_gateway_fee': '', + # 'modified_reservations': [], + # 'customer_surname': ' '.join(partner.name.split(' ')[1:]), + # 'date_departure': checkout_dt.strftime(DEFAULT_WUBOOK_DATE_FORMAT), + # 'amount_reason': '', + # 'customer_city': partner.city, + # 'opportunities': 0, + # 'date_received': now_dt.strftime(DEFAULT_WUBOOK_DATE_FORMAT), + # 'rooms_occupancies': rooms_occu, + # 'sessionSeed': '', + # 'booked_rooms': booked_rooms, + # 'customer_name': partner.name.split(' ')[0], + # 'date_arrival': checkin_dt.strftime(DEFAULT_WUBOOK_DATE_FORMAT), + # 'status': WUBOOK_STATUS_CONFIRMED, + # 'was_modified': 0, + # 'channel_reservation_code': crcode, + # 'men': max_persons, + # 'orig_amount': total_amount, + # 'customer_phone': partner.mobile or partner.phone or '', + # 'customer_notes': notes, + # 'customer_address': partner.street, + # 'device': -1, + # 'addons_list': [], + # 'status_reason': '', + # 'roomnight': date_diff-1, + # 'boards': '', + # 'customer_language': 32, + # 'fount': '', + # 'channel_data': {}, + # 'room_opportunities': 0, + # 'customer_zip': partner.zip, + # 'amount': total_amount, + # 'id_woodoo': id_woodoo, + # 'cc_info': 1, + # 'customer_language_iso': 'es' + # } - if not partner.email or partner.email == '': - self.raiseException("Partner doesn't have a mail") + # def create_wubook_rooms_values(self, rooms, values): + # json_data = {} + # _logger.info("=== PASA AAA") + # _logger.info(values) + # for room in rooms: + # for cvalue in values: + # json_data.setdefault(room.wrid, []).append({ + # 'closed_arrival': cvalue['closed_arrival'], + # 'booked': cvalue['booked'], + # 'max_stay_arrival': cvalue['max_stay_arrival'], + # 'max_stay': cvalue['max_stay'], + # 'price': cvalue['price'], + # 'min_stay': cvalue['min_stay'], + # 'closed_departure': cvalue['closed_departure'], + # 'avail': cvalue['avail'], + # 'closed': cvalue['closed'], + # 'min_stay_arrival': cvalue['min_stay_arrival'], + # 'no_ota': cvalue['no_ota'], + # }) + # return json_data - now_utc_dt = date_utils.now() - now_dt = date_utils.dt_as_timezone(now_utc_dt, self.tz_hotel) - checkin_utc_dt = date_utils.get_datetime(checkin) - checkin_dt = date_utils.dt_as_timezone(checkin_utc_dt, self.tz_hotel) - numdays = 0 - for k_room, v_room in rinfo.iteritems(): - numdays = max(len(v_room['dayprices']), numdays) - checkout_utc_dt = checkin_utc_dt + timedelta(days=numdays) - checkout_dt = date_utils.dt_as_timezone(checkout_utc_dt, self.tz_hotel) - date_diff = date_utils.date_diff(checkin_utc_dt, checkout_utc_dt, - hours=False) - - # Generate Day Prices - dayprices = {} - total_amount = 0.0 - for k_room, v_room in rinfo.iteritems(): - for price in v_room['dayprices']: - dayprices.setdefault(k_room, []).append(price) - total_amount += price - # Generate Values - rooms = [] - rooms_occu = [] - booked_rooms = [] - room_type_obj = self.env['hotel.room.type'] - max_persons = 0 - for k_room, v_room in rinfo.iteritems(): - room_type = room_type_obj.search([ - ('wrid', '=', k_room) - ], limit=1) - # Generate Rooms - for price in range(0, len(v_room['occupancy'])): - rooms.append(k_room) - # Generate Rooms Occupancies - for val in v_room['occupancy']: - # Generate Rooms Occupancies - rooms_occu.append({ - 'id': k_room, - 'occupancy': val, - }) - # Generate Booked Rooms - roomdays = [] - for k_price, v_price in enumerate(v_room['dayprices']): - ndate = checkin_dt + timedelta(days=k_price) - roomdays.append({ - 'ancillary': {}, - 'rate_id': 3, - 'price': v_price, - 'day': ndate.strftime(DEFAULT_WUBOOK_DATE_FORMAT) - }) - booked_rooms.append({ - 'ancillary': { - 'channel_room_id': 1, - 'channel_room_name': room_type.name, - 'addons': [], - 'guests': val - }, - 'room_id': k_room, - 'roomdays': roomdays - }) - if val > max_persons: - max_persons = val - - return { - 'id_channel': channel, - 'special_offer': '', - 'reservation_code': rcode, - 'dayprices': dayprices, - 'arrival_hour': checkin_dt.strftime(DEFAULT_WUBOOK_TIME_FORMAT), - 'booked_rate': brate, - 'rooms': ','.join(map(str, rooms)), - 'customer_mail': partner.email, - 'customer_country': 'ES', - 'children': 0, - 'payment_gateway_fee': '', - 'modified_reservations': [], - 'customer_surname': ' '.join(partner.name.split(' ')[1:]), - 'date_departure': checkout_dt.strftime(DEFAULT_WUBOOK_DATE_FORMAT), - 'amount_reason': '', - 'customer_city': partner.city, - 'opportunities': 0, - 'date_received': now_dt.strftime(DEFAULT_WUBOOK_DATE_FORMAT), - 'rooms_occupancies': rooms_occu, - 'sessionSeed': '', - 'booked_rooms': booked_rooms, - 'customer_name': partner.name.split(' ')[0], - 'date_arrival': checkin_dt.strftime(DEFAULT_WUBOOK_DATE_FORMAT), - 'status': WUBOOK_STATUS_CONFIRMED, - 'was_modified': 0, - 'channel_reservation_code': crcode, - 'men': max_persons, - 'orig_amount': total_amount, - 'customer_phone': partner.mobile or partner.phone or '', - 'customer_notes': notes, - 'customer_address': partner.street, - 'device': -1, - 'addons_list': [], - 'status_reason': '', - 'roomnight': date_diff-1, - 'boards': '', - 'customer_language': 32, - 'fount': '', - 'channel_data': {}, - 'room_opportunities': 0, - 'customer_zip': partner.zip, - 'amount': total_amount, - 'id_woodoo': id_woodoo, - 'cc_info': 1, - 'customer_language_iso': 'es' - } - - def create_wubook_rooms_values(self, rooms, values): - json_data = {} - _logger.info("=== PASA AAA") - _logger.info(values) - for room in rooms: - for cvalue in values: - json_data.setdefault(room.wrid, []).append({ - 'closed_arrival': cvalue['closed_arrival'], - 'booked': cvalue['booked'], - 'max_stay_arrival': cvalue['max_stay_arrival'], - 'max_stay': cvalue['max_stay'], - 'price': cvalue['price'], - 'min_stay': cvalue['min_stay'], - 'closed_departure': cvalue['closed_departure'], - 'avail': cvalue['avail'], - 'closed': cvalue['closed'], - 'min_stay_arrival': cvalue['min_stay_arrival'], - 'no_ota': cvalue['no_ota'], - }) - return json_data - - def cancel_booking(self, wbooking): - wbooking['status'] = WUBOOK_STATUS_CANCELLED - return wbooking + # def cancel_booking(self, wbooking): + # wbooking['status'] = WUBOOK_STATUS_CANCELLED + # return wbooking @classmethod def setUpClass(cls): - super(TestHotelWubook, cls).setUpClass() + super().setUpClass() - # Update Test Virtual Rooms - cls.hotel_room_type_budget.write({ - 'wcapacity': 1, - 'wrid': 3000, - 'wscode': 'T001', - }) - cls.hotel_room_type_special.write({ - 'wcapacity': 2, - 'wrid': 3001, - 'wscode': 'T002', + cls.manager_hotel_demo = cls.env.ref('base.user_demo') + cls.manager_hotel_demo.groups_id += cls.env.ref('hotel.group_hotel_manager') + + # Create a fake channel connector with WuBook + cls.channel_connector_wubook = cls.env['channel.backend'].create({ + 'version': '1.1', + 'lcode': 123456789, + 'pkey': 'YourProviderKey', + 'server': 'https://wired.wubook.net/xrws/' }) + # Update Hotel Test Room Type Records + # cls.room_type_0.write({ + # 'ota_capacity': 2, + # 'wrid': 3000, + # 'shortname': 'T000', + # # }) # formerly named hotel_room_type_budget + # cls.room_type_0.write({ + # 'ota_capacity': 1, + # 'wrid': 3001, + # 'shortname': 'T001', + # }) # formerly named hotel_room_type_budget + # cls.room_type_0.write({ + # 'ota_capacity': 2, + # 'wrid': 3002, + # 'shortname': 'T002', + # }) # formerly named hotel_room_type_special + # Update Restriction - room_type_restr_obj = cls.env['hotel.room.type.restriction'] - default_restriction = room_type_restr_obj.search([ - ('wpid', '=', '0') - ], limit=1) - if default_restriction: - cls.restriction_default_id = default_restriction.id - else: - cls.restriction_1.write({ - 'wpid': '0' - }) - cls.restriction_default_id = cls.restriction_1.id + # room_type_restr_obj = cls.env['hotel.room.type.restriction'] + # default_restriction = room_type_restr_obj.search([ + # ('wpid', '=', '0') + # ], limit=1) + # if default_restriction: + # cls.restriction_default_id = default_restriction.id + # else: + # cls.restriction_1.write({ + # 'wpid': '0' + # }) + # cls.restriction_default_id = cls.restriction_1.id + + # Create Wubook Channel Info - # Create Some Wubook Info - cls.wubook_channel_test = cls.env['wubook.channel.info'].create({ - 'wid': 1, - 'name': 'Channel Test' - }) @classmethod def tearDownClass(cls): # Remove mocks - cls.env['wubook']._revert_method('create_channel_connector_issue') - cls.env['wubook']._revert_method('is_valid_account') - cls.env['wubook']._revert_method('initialize') - cls.env['wubook']._revert_method('push_activation') - cls.env['wubook']._revert_method('init_connection') - cls.env['wubook']._revert_method('close_connection') - cls.env['wubook']._revert_method('create_room') - cls.env['wubook']._revert_method('modify_room') - cls.env['wubook']._revert_method('delete_room') - cls.env['wubook']._revert_method('import_rooms') - cls.env['wubook']._revert_method('fetch_rooms_values') - cls.env['wubook']._revert_method('update_availability') - cls.env['wubook']._revert_method('corporate_fetch') - cls.env['wubook']._revert_method('create_reservation') - cls.env['wubook']._revert_method('cancel_reservation') - cls.env['wubook']._revert_method('fetch_new_bookings') - cls.env['wubook']._revert_method('fetch_booking') - cls.env['wubook']._revert_method('mark_bookings') - cls.env['wubook']._revert_method('create_plan') - cls.env['wubook']._revert_method('delete_plan') - cls.env['wubook']._revert_method('update_plan_name') - cls.env['wubook']._revert_method('update_plan_prices') - cls.env['wubook']._revert_method('update_plan_periods') - cls.env['wubook']._revert_method('import_pricing_plans') - cls.env['wubook']._revert_method('fetch_plan_prices') - cls.env['wubook']._revert_method('fetch_all_plan_prices') - cls.env['wubook']._revert_method('import_restriction_plans') - cls.env['wubook']._revert_method('fetch_rplan_restrictions') - cls.env['wubook']._revert_method('update_rplan_values') - cls.env['wubook']._revert_method('create_rplan') - cls.env['wubook']._revert_method('rename_rplan') - cls.env['wubook']._revert_method('delete_rplan') - cls.env['wubook']._revert_method('import_channels_info') + # cls.env['wubook']._revert_method('create_channel_connector_issue') + # cls.env['wubook']._revert_method('is_valid_account') + # cls.env['wubook']._revert_method('initialize') + # cls.env['wubook']._revert_method('push_activation') + # cls.env['wubook']._revert_method('init_connection') + # cls.env['wubook']._revert_method('close_connection') + # cls.env['wubook']._revert_method('create_room') + # cls.env['wubook']._revert_method('modify_room') + # cls.env['wubook']._revert_method('delete_room') + # cls.env['wubook']._revert_method('import_rooms') + # cls.env['wubook']._revert_method('fetch_rooms_values') + # cls.env['wubook']._revert_method('update_availability') + # cls.env['wubook']._revert_method('corporate_fetch') + # cls.env['wubook']._revert_method('create_reservation') + # cls.env['wubook']._revert_method('cancel_reservation') + # cls.env['wubook']._revert_method('fetch_new_bookings') + # cls.env['wubook']._revert_method('fetch_booking') + # cls.env['wubook']._revert_method('mark_bookings') + # cls.env['wubook']._revert_method('create_plan') + # cls.env['wubook']._revert_method('delete_plan') + # cls.env['wubook']._revert_method('update_plan_name') + # cls.env['wubook']._revert_method('update_plan_prices') + # cls.env['wubook']._revert_method('update_plan_periods') + # cls.env['wubook']._revert_method('import_pricing_plans') + # cls.env['wubook']._revert_method('fetch_plan_prices') + # cls.env['wubook']._revert_method('fetch_all_plan_prices') + # cls.env['wubook']._revert_method('import_restriction_plans') + # cls.env['wubook']._revert_method('fetch_rplan_restrictions') + # cls.env['wubook']._revert_method('update_rplan_values') + # cls.env['wubook']._revert_method('create_rplan') + # cls.env['wubook']._revert_method('rename_rplan') + # cls.env['wubook']._revert_method('delete_rplan') + # cls.env['wubook']._revert_method('import_channels_info') - super(TestHotelWubook, cls).tearDownClass() + super().tearDownClass() \ No newline at end of file diff --git a/hotel_channel_connector_wubook/tests/test_channel_hotel_room_type_model.py b/hotel_channel_connector_wubook/tests/test_channel_hotel_room_type_adapter_model.py similarity index 85% rename from hotel_channel_connector_wubook/tests/test_channel_hotel_room_type_model.py rename to hotel_channel_connector_wubook/tests/test_channel_hotel_room_type_adapter_model.py index cb18beb7e..553ae18c6 100644 --- a/hotel_channel_connector_wubook/tests/test_channel_hotel_room_type_model.py +++ b/hotel_channel_connector_wubook/tests/test_channel_hotel_room_type_adapter_model.py @@ -20,28 +20,25 @@ # along with this program. If not, see . # ############################################################################## -from datetime import timedelta from odoo.tools import ( DEFAULT_SERVER_DATETIME_FORMAT, DEFAULT_SERVER_DATE_FORMAT) from odoo.exceptions import AccessError -from .common import TestChannelConnectorWubook +from .common import TestHotelWubook -class TestChannelRoomType(TestChannelConnectorWubook): +class TestChannelRoomType(TestHotelWubook): - def create_room(self, shortcode, name, capacity, price, availability, defboard, rtype): + def test_create_room(self): return True - def fetch_rooms(self): + def test_fetch_rooms(self): return True - def modify_room(self, channel_room_id, name, capacity, price, availability, scode, defboard, rtype): - import wdb; wdb.set_trace() - self.hotel_room_type_simple.ota_capacity = 1 + def test_modify_room(self): return True - def delete_room(self, channel_room_id): + def test_delete_room(self): return True # def test_get_capacity(self): From 6e7a074047acc342a19ec7c7aa7896a80995803a Mon Sep 17 00:00:00 2001 From: Pablo Date: Fri, 25 Jan 2019 16:54:13 +0100 Subject: [PATCH 13/32] [UPD] Use show_in_calendar as flag for showing services in calendar --- hotel/data/hotel_demo.xml | 14 +++++++------- hotel/models/inherited_product_template.py | 4 ++-- hotel/views/inherited_product_template_views.xml | 2 +- .../models/inherited_hotel_reservation.py | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/hotel/data/hotel_demo.xml b/hotel/data/hotel_demo.xml index 50be034ab..e6b6694e5 100644 --- a/hotel/data/hotel_demo.xml +++ b/hotel/data/hotel_demo.xml @@ -193,7 +193,7 @@ False 1 True - True + True @@ -206,7 +206,7 @@ - Menú A + Lunch 15.0 service False @@ -215,7 +215,7 @@ - Menú B + Dinner 20.0 service False @@ -224,8 +224,8 @@ - Menú C - 25.0 + Free Bar + 40.0 service False True @@ -249,7 +249,7 @@ eval="[(5, 0), (0, 0, { 'product_id': ref('hotel_service_0'), 'amount': 3}), - (0, 0, {'product_id': ref('hotel_service_4'), + (0, 0, {'product_id': ref('hotel_service_5'), 'amount': 8}) ]"/> fixed @@ -271,7 +271,7 @@ - + diff --git a/hotel/models/inherited_product_template.py b/hotel/models/inherited_product_template.py index 5a7ba560d..ce70952a1 100644 --- a/hotel/models/inherited_product_template.py +++ b/hotel/models/inherited_product_template.py @@ -11,5 +11,5 @@ class ProductTemplate(models.Model): per_person = fields.Boolean('Unit increment per person') daily_limit = fields.Integer('Daily limit') is_extra_bed = fields.Boolean('Is extra bed', default=False) - is_popoverable = fields.Boolean('Show in Popover', default=False, - help='Specifies if the product is shown in the popover information.') + show_in_calendar = fields.Boolean('Show in Calendar', default=False, + help='Specifies if the product is shown in the calendar information.') diff --git a/hotel/views/inherited_product_template_views.xml b/hotel/views/inherited_product_template_views.xml index c4233cbc7..2b3a54f1f 100644 --- a/hotel/views/inherited_product_template_views.xml +++ b/hotel/views/inherited_product_template_views.xml @@ -12,7 +12,7 @@ - + diff --git a/hotel_calendar/models/inherited_hotel_reservation.py b/hotel_calendar/models/inherited_hotel_reservation.py index 0bea4cc0b..5d685e90d 100644 --- a/hotel_calendar/models/inherited_hotel_reservation.py +++ b/hotel_calendar/models/inherited_hotel_reservation.py @@ -197,7 +197,7 @@ class HotelReservation(models.Model): pt.name as room_type, - array_agg(pt2.name) FILTER (WHERE pt2.is_popoverable = TRUE) as services, + array_agg(pt2.name) FILTER (WHERE pt2.show_in_calendar = TRUE) as services, rcr.name as closure_reason, @@ -426,7 +426,7 @@ class HotelReservation(models.Model): 'channel_type': self.channel_type, 'board_service_name': self.board_service_room_id.hotel_board_service_id.name, 'services': [service.product_id.name for service in self.service_ids - if service.product_id.is_popoverable] or False, + if service.product_id.show_in_calendar] or False, } @api.multi From 2d1da3dd9f6aed027b47d8cdf4fab4eee52cb72b Mon Sep 17 00:00:00 2001 From: Pablo Date: Mon, 28 Jan 2019 10:27:36 +0100 Subject: [PATCH 14/32] [WIP] Adjust styles --- hotel_calendar/models/bus_hotel_calendar.py | 2 +- .../models/inherited_hotel_reservation.py | 8 +- hotel_calendar/static/src/css/view.css | 48 +++++-- .../src/xml/hotel_calendar_templates.xml | 124 +++++++++--------- 4 files changed, 106 insertions(+), 76 deletions(-) diff --git a/hotel_calendar/models/bus_hotel_calendar.py b/hotel_calendar/models/bus_hotel_calendar.py index d369e8134..a40514443 100644 --- a/hotel_calendar/models/bus_hotel_calendar.py +++ b/hotel_calendar/models/bus_hotel_calendar.py @@ -52,7 +52,7 @@ class BusHotelCalendar(models.TransientModel): 'real_dates': vals['real_dates'], }, 'tooltip': { - 'folio_name': vals['folio_id'], + 'folio_name': vals['folio_name'], 'name': vals['partner_name'], 'phone': vals['partner_phone'], 'email': vals['partner_email'], diff --git a/hotel_calendar/models/inherited_hotel_reservation.py b/hotel_calendar/models/inherited_hotel_reservation.py index 5d685e90d..b09828a82 100644 --- a/hotel_calendar/models/inherited_hotel_reservation.py +++ b/hotel_calendar/models/inherited_hotel_reservation.py @@ -95,7 +95,7 @@ class HotelReservation(models.Model): 'real_dates': [reserv['real_checkin'], reserv['real_checkout']]}) json_reservation_tooltips.update({ reserv['id']: { - 'folio_name': reserv['folio_id'], + 'folio_name': reserv['folio_name'], 'name': _('Out of service') if reserv['reservation_type'] == 'out' else reserv['partner_name'], @@ -119,8 +119,7 @@ class HotelReservation(models.Model): 'splitted': reserv['splitted'], 'channel_type': reserv['channel_type'], 'real_dates': [reserv['real_checkin'], reserv['real_checkout']], - # TODO: Add Board Services and Extra Service as Cradle, Bed, ... - 'board_service_name': reserv['board_service_name'], + 'board_service_name': reserv['board_service_name'] or _('No board services'), 'services': reserv['services'], } }) @@ -393,6 +392,7 @@ class HotelReservation(models.Model): 'title': ntitle, 'room_id': self.room_id.id, 'reserv_id': self.id, + 'folio_name': self.folio_id.name, 'partner_name': (self.closure_reason_id.name or _('Out of service')) if self.reservation_type == 'out' else self.partner_id.name, 'adults': self.adults, @@ -424,7 +424,7 @@ class HotelReservation(models.Model): or _('No reason given'), 'real_dates': [self.real_checkin, self.real_checkout], 'channel_type': self.channel_type, - 'board_service_name': self.board_service_room_id.hotel_board_service_id.name, + 'board_service_name': self.board_service_room_id.hotel_board_service_id.name or _('No board services'), 'services': [service.product_id.name for service in self.service_ids if service.product_id.show_in_calendar] or False, } diff --git a/hotel_calendar/static/src/css/view.css b/hotel_calendar/static/src/css/view.css index 192e61c87..c3f64dd90 100644 --- a/hotel_calendar/static/src/css/view.css +++ b/hotel_calendar/static/src/css/view.css @@ -194,36 +194,41 @@ input#bookings_search { text-align: left; } -/** TOOLTIPS **/ +/** POPOVER **/ .popover-content { font-family: Garuda, sans-serif; font-size: 12px; - padding: 9px; + padding: 0px; } .popover h1, .h1, h2, .h2, h3, .h3 { margin-top: 2px; margin-bottom: 0px; } .popover { - max-width: 550px; + max-width: 400px; border-radius: 0px; + padding: 0px; } .popover .container { max-width: 100%; } .popover .container p { - margin-top: 3px; + margin-top: 2px; margin-bottom: 0px; } -.popover header { - font-size: 1.3em; +.popover .container p.email { + word-wrap: break-word; } -.popover .fa-border { - padding: .25em; - border: solid 0.1em #777777; - border-radius: .2em; +.popover .container p.board { + margin-top: 0px; +} +.popover header { + font-size: 1.2em; } +.fa-2_5x { + font-size: 2.5em; +} .fa-text-inside { font-family: Garuda, sans-serif; font-size: 14px; @@ -232,10 +237,29 @@ input#bookings_search { padding-top: 3px; padding-bottom: 3px; } +/* custom styles for popover info */ +.circle { + width:35px; + height:35px; + border-radius:50px; + line-height:35px; + text-align:center; + color:#fff; + background:#777; + margin-right: .65em; +} + +.bg-gray-lighter { + background-color: #ddd; +} + /* Spacing in Bootstrap v4.0 */ .mt-3 { margin-top: 3px; } +.mt-5 { + margin-top: 5px; +} .mt-10 { margin-top: 10px !important; } @@ -257,6 +281,10 @@ input#bookings_search { padding-bottom: 10px; } +.pr-0 { + padding-right: 0px; +} + /* WARNING: The .row-eq-height class uses CSS3's flexbox layout mode, which is not supported in Internet Explorer 9 and below. */ .row-eq-height { diff --git a/hotel_calendar/static/src/xml/hotel_calendar_templates.xml b/hotel_calendar/static/src/xml/hotel_calendar_templates.xml index 3fcc9628d..1686be60d 100644 --- a/hotel_calendar/static/src/xml/hotel_calendar_templates.xml +++ b/hotel_calendar/static/src/xml/hotel_calendar_templates.xml @@ -103,50 +103,30 @@ - -
-
- + +
+
+ +
+

+
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
-
- - - - - - -

This reservation is part of splitted reservation. You can check it in the corresponding Folio.

-
+
+ +
+ +

+ + +

Adults:

+

Children:

-
+

Folio Pending

@@ -169,7 +149,7 @@
-
+