diff --git a/hotel/models/cardex.py b/hotel/models/cardex.py index 827dfc3e8..6b23fd574 100644 --- a/hotel/models/cardex.py +++ b/hotel/models/cardex.py @@ -4,7 +4,6 @@ import datetime from openerp import models, fields, api, _ from openerp.exceptions import except_orm, ValidationError -from odoo.addons.hotel import date_utils class Cardex(models.Model): @@ -53,7 +52,7 @@ class Cardex(models.Model): @api.onchange('enter_date', 'exit_date') def check_change_dates(self): if self.exit_date <= self.enter_date: - date_1 = date_utils.get_datetime(self.enter_date) + date_1 = fields.Date.from_string(self.enter_date) date_2 = date_1 + datetime.timedelta(days=1) self.update({'exit_date': date_2, }) raise ValidationError( diff --git a/hotel/models/hotel_folio.py b/hotel/models/hotel_folio.py index 72e6dae36..9e18492e6 100644 --- a/hotel/models/hotel_folio.py +++ b/hotel/models/hotel_folio.py @@ -14,7 +14,6 @@ from odoo.tools import ( DEFAULT_SERVER_DATETIME_FORMAT, DEFAULT_SERVER_DATE_FORMAT) from odoo import models, fields, api, _ -from odoo.addons.hotel import date_utils _logger = logging.getLogger(__name__) from odoo.addons import decimal_precision as dp @@ -267,10 +266,8 @@ class HotelFolio(models.Model): @api.multi def action_folios_amount(self): - now_utc_dt = date_utils.now() - now_utc_str = now_utc_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT) reservations = self.env['hotel.reservation'].search([ - ('checkout', '<=', now_utc_str) + ('checkout', '<=', fields.Date.today()) ]) folio_ids = reservations.mapped('folio_id.id') folios = self.env['hotel.folio'].search([('id', 'in', folio_ids)]) diff --git a/hotel/models/hotel_reservation.py b/hotel/models/hotel_reservation.py index eabdc9add..56a00dd74 100644 --- a/hotel/models/hotel_reservation.py +++ b/hotel/models/hotel_reservation.py @@ -284,7 +284,7 @@ class HotelReservation(models.Model): 'channel_type': vals.get('channel_type')}) #~ colors = self._generate_color() vals.update({ - 'last_updated_res': date_utils.now(hours=True).strftime(DEFAULT_SERVER_DATETIME_FORMAT), + 'last_updated_res': fields.Datetime.now(), #~ 'reserve_color': colors[0], #~ 'reserve_color_text': colors[1], }) @@ -306,8 +306,7 @@ class HotelReservation(models.Model): def write(self, vals): if self.notify_update(vals): vals.update({ - 'last_updated_res': date_utils.now(hours=True).strftime( - DEFAULT_SERVER_DATETIME_FORMAT) + 'last_updated_res': fields.Datetime.now() }) for record in self: if record.compute_price_out_vals(vals): @@ -902,15 +901,9 @@ class HotelReservation(models.Model): @api.model def daily_plan(self): _logger.info('daily_plan') - today_utc_dt = date_utils.now() - yesterday_utc_dt = today_utc_dt - timedelta(days=1) - hotel_tz = self.env['ir.default'].sudo().get('res.config.settings', - 'tz_hotel') - today_dt = date_utils.dt_as_timezone(today_utc_dt, hotel_tz) - yesterday_dt = date_utils.dt_as_timezone(yesterday_utc_dt, hotel_tz) - - today_str = today_dt.strftime(DEFAULT_SERVER_DATE_FORMAT) - yesterday_str = yesterday_dt.strftime(DEFAULT_SERVER_DATE_FORMAT) + today_str = fields.Date.today() + yesterday_utc_dt = datetime.now() - timedelta(days=1) + yesterday_str = yesterday_utc_dt.strftime(DEFAULT_SERVER_DATE_FORMAT) reservations_to_checkout = self.env['hotel.reservation'].search([ ('state', 'not in', ['done']), ('checkout', '<', today_str) diff --git a/hotel/models/hotel_room_type_restriction_item.py b/hotel/models/hotel_room_type_restriction_item.py index d704e1eaf..2533bc4b5 100644 --- a/hotel/models/hotel_room_type_restriction_item.py +++ b/hotel/models/hotel_room_type_restriction_item.py @@ -4,7 +4,6 @@ from datetime import datetime from odoo import models, fields, api, _ from odoo.exceptions import ValidationError from odoo.tools import DEFAULT_SERVER_DATE_FORMAT -from odoo.addons.hotel import date_utils class HotelRoomTypeRestrictionItem(models.Model): @@ -59,8 +58,8 @@ class HotelRoomTypeRestrictionItem(models.Model): self.date_start = False self.date_end = False elif self.date_start and self.date_end: - date_start_dt = date_utils.get_datetime(self.date_start) - date_end_dt = date_utils.get_datetime(self.date_end) + date_start_dt = fields.Date.from_string(self.date_start) + date_end_dt = fields.Date.from_string(self.date_end) if date_end_dt < date_start_dt: raise ValidationError(_("Invalid Dates")) diff --git a/hotel/models/hotel_service_line.py b/hotel/models/hotel_service_line.py index 74161fe08..0a7d42093 100644 --- a/hotel/models/hotel_service_line.py +++ b/hotel/models/hotel_service_line.py @@ -6,7 +6,6 @@ import logging from odoo import models, fields, api, _ from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT from odoo.exceptions import UserError -from odoo.addons.hotel import date_utils _logger = logging.getLogger(__name__) from odoo.addons import decimal_precision as dp @@ -91,12 +90,12 @@ class HotelServiceLine(models.Model): ('mail', 'Mail'), ('phone', 'Phone'), ('call', 'Call Center'), - ('web','Web')], 'Sales Channel') + ('web', 'Web')], 'Sales Channel') - ser_checkin = fields.Datetime('From Date', required=True, - default=_service_checkin) - ser_checkout = fields.Datetime('To Date', required=True, - default=_service_checkout) + ser_checkin = fields.Date('From Date', required=True, + default=_service_checkin) + ser_checkout = fields.Date('To Date', required=True, + default=_service_checkout) ser_room_line = fields.Many2one('hotel.reservation', 'Room', default=_default_ser_room_line) @@ -199,20 +198,17 @@ class HotelServiceLine(models.Model): ----------------------------------------------------------------- @param self: object pointer ''' - now_utc_dt = date_utils.now() + now_utc = fields.Date.today() if not self.ser_checkin: - self.ser_checkin = now_utc_dt.strftime( - DEFAULT_SERVER_DATETIME_FORMAT) + self.ser_checkin = now_utc if not self.ser_checkout: - self.ser_checkout = now_utc_dt.strftime( - DEFAULT_SERVER_DATETIME_FORMAT) - chkin_utc_dt = date_utils.get_datetime(self.ser_checkin) - chkout_utc_dt = date_utils.get_datetime(self.ser_checkout) + self.ser_checkout = now_utc + chkin_utc_dt = fields.Date.from_string(self.ser_checkin) + chkout_utc_dt = fields.Date.from_string(self.ser_checkout) if chkout_utc_dt < chkin_utc_dt: raise UserError(_('Checkout must be greater or equal checkin date')) if self.ser_checkin and self.ser_checkout: - diffDate = date_utils.date_diff(self.ser_checkin, - self.ser_checkout, hours=False) + 1 + diffDate = abs((self.ser_checkout - self.ser_checkin).days) + 1 # FIXME: Finalize method! @api.multi diff --git a/hotel/wizard/massive_changes.py b/hotel/wizard/massive_changes.py index 601105058..d15c6339f 100644 --- a/hotel/wizard/massive_changes.py +++ b/hotel/wizard/massive_changes.py @@ -5,7 +5,6 @@ from openerp import models, fields, api from openerp.tools import ( DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT) -from odoo.addons.hotel import date_utils class MassiveChangesWizard(models.TransientModel): @@ -17,8 +16,8 @@ class MassiveChangesWizard(models.TransientModel): ('1', 'Restrictions'), ('2', 'Pricelist'), ], string='Section', default='0') - date_start = fields.Datetime('Start Date', required=True) - date_end = fields.Datetime('End Date', required=True) + date_start = fields.Date('Start Date', required=True) + date_end = fields.Date('End Date', required=True) dmo = fields.Boolean('Monday', default=True) dtu = fields.Boolean('Tuesday', default=True) dwe = fields.Boolean('Wednesday', default=True) @@ -28,12 +27,11 @@ class MassiveChangesWizard(models.TransientModel): dsu = fields.Boolean('Sunday', default=True) applied_on = fields.Selection([ ('0', 'Global'), - ('1', 'Virtual Room'), + ('1', 'Room Type'), ], string='Applied On', default='0') # room_type_ids = fields.Many2many('hotel.virtual.room', # string="Virtual Rooms") - room_type_ids = fields.Many2many('hotel.room.type', - string="Room Types") + room_type_ids = fields.Many2many('hotel.room.type', string="Room Types") # Availability fields change_avail = fields.Boolean(default=False) @@ -251,12 +249,10 @@ class MassiveChangesWizard(models.TransientModel): def _do_massive_change(self): hotel_room_type_obj = self.env['hotel.room.type'] for record in self: - date_start_dt = date_utils.get_datetime(record.date_start, - hours=False) + date_start_dt = fields.Date.from_string(record.date_start) + date_end_dt = fields.Date.from_string(record.date_end) # Use min '1' for same date - diff_days = date_utils.date_diff(record.date_start, - record.date_end, - hours=False) + 1 + diff_days = abs((date_end_dt - date_start_dt).days) + 1 wedays = (record.dmo, record.dtu, record.dwe, record.dth, record.dfr, record.dsa, record.dsu) room_types = record.room_type_id if record.applied_on == '1' \ diff --git a/hotel/wizard/split_reservation.py b/hotel/wizard/split_reservation.py index a92e80f4a..1d5bc0677 100644 --- a/hotel/wizard/split_reservation.py +++ b/hotel/wizard/split_reservation.py @@ -21,10 +21,9 @@ class SplitReservationWizard(models.TransientModel): reservation_id = self.env['hotel.reservation'].browse( self.env.context.get('active_id')) if reservation_id: - date_start_dt = date_utils.get_datetime(reservation_id.checkin) - date_end_dt = date_utils.get_datetime(reservation_id.checkout) - date_diff = date_utils.date_diff(date_start_dt, date_end_dt, - hours=False) + date_start_dt = fields.Date.from_string(reservation_id.checkin) + date_end_dt = fields.Date.from_string(reservation_id.checkout) + date_diff = abs((date_end_dt - date_start_dt).days) for record in self: new_start_date_dt = date_start_dt + \ timedelta(days=date_diff-record.nights) @@ -41,7 +40,7 @@ class SplitReservationWizard(models.TransientModel): tprice = [0.0, 0.0] div_dt = date_utils.dt_no_hours(new_start_date_dt) for rline in reservation_id.reservation_lines: - rline_dt = date_utils.get_datetime(rline.date, hours=False) + rline_dt = fields.Date.from_string(rline.date) if rline_dt >= div_dt: reservation_lines[1].append((0, False, { 'date': rline.date, diff --git a/hotel_calendar/models/hotel_calendar_management.py b/hotel_calendar/models/hotel_calendar_management.py index 0c1bf9d5b..d282c1b4f 100644 --- a/hotel_calendar/models/hotel_calendar_management.py +++ b/hotel_calendar/models/hotel_calendar_management.py @@ -5,9 +5,8 @@ from datetime import datetime, timedelta from odoo.tools import ( DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT) -from odoo import models, api, _ +from odoo import models, api, _, fields from odoo.exceptions import ValidationError -from odoo.addons.hotel import date_utils _logger = logging.getLogger(__name__) @@ -176,8 +175,9 @@ class HotelCalendarManagement(models.TransientModel): @api.model def _hcalendar_availability_json_data(self, dfrom, dto): - date_start = date_utils.get_datetime(dfrom, hours=False) - date_diff = date_utils.date_diff(dfrom, dto, hours=False) + 1 + date_start = fields.Date.from_string(dfrom) + date_end = fields.Date.from_string(dto) + date_diff = abs((date_end - date_start).days) + 1 room_types = self.env['hotel.room.type'].search([]) json_data = {} @@ -208,7 +208,7 @@ class HotelCalendarManagement(models.TransientModel): @api.model def _hcalendar_events_json_data(self, dfrom, dto): - date_start = date_utils.get_datetime(dfrom, hours=False) - timedelta(days=1) + date_start = fields.Date.from_string(dfrom) - timedelta(days=1) date_start_str = date_start.strftime(DEFAULT_SERVER_DATETIME_FORMAT) user_id = self.env['res.users'].browse(self.env.uid) domain = [] @@ -239,8 +239,9 @@ class HotelCalendarManagement(models.TransientModel): @api.model def _hcalendar_get_count_reservations_json_data(self, dfrom, dto): - date_start = date_utils.get_datetime(dfrom, hours=False) - date_diff = date_utils.date_diff(dfrom, dto, hours=False) + 1 + date_start = fields.Date.from_string(dfrom) + date_end = fields.Date.from_string(dto) + date_diff = abs((date_end - date_start).days) + 1 room_type_obj = self.env['hotel.room.type'] room_types = room_type_obj.search([]) json_data = {} diff --git a/hotel_calendar/models/inherited_hotel_reservation.py b/hotel_calendar/models/inherited_hotel_reservation.py index edb4e6811..1034532f1 100644 --- a/hotel_calendar/models/inherited_hotel_reservation.py +++ b/hotel_calendar/models/inherited_hotel_reservation.py @@ -7,7 +7,6 @@ from odoo.exceptions import ValidationError from odoo.tools import ( DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT) -from odoo.addons.hotel import date_utils _logger = logging.getLogger(__name__) @@ -95,8 +94,7 @@ class HotelReservation(models.Model): @api.model def get_hcalendar_reservations_data(self, dfrom, dto, rooms): - date_start = date_utils.get_datetime(dfrom, hours=False) \ - - timedelta(days=1) + date_start = fields.Date.from_string(dfrom) - timedelta(days=1) date_start_str = date_start.strftime(DEFAULT_SERVER_DATETIME_FORMAT) reservations_raw = self.env['hotel.reservation'].search( [ @@ -122,9 +120,9 @@ class HotelReservation(models.Model): 'res.config.settings', 'parity_pricelist_id') if pricelist_id: pricelist_id = int(pricelist_id) - date_start = date_utils.get_datetime(dfrom, hours=False) \ - - timedelta(days=1) - date_diff = date_utils.date_diff(date_start, dto, hours=False) + 1 + date_start = fields.Date.from_string(dfrom) - timedelta(days=1) + date_end = fields.Date.from_string(dto) + date_diff = abs((date_end - date_start).days) + 1 # Get Prices json_rooms_prices = {pricelist_id: []} room_typed_ids = self.env['hotel.room.type'].search( @@ -162,9 +160,9 @@ class HotelReservation(models.Model): 'res.config.settings', 'parity_restrictions_id') if restriction_id: restriction_id = int(restriction_id) - date_start = date_utils.get_datetime(dfrom, hours=False) \ - - timedelta(days=1) - date_diff = date_utils.date_diff(dfrom, dto, hours=False) + 1 + date_start = fields.Date.from_string(dfrom) - timedelta(days=1) + date_end = fields.Date.from_string(dto) + date_diff = abs((date_end - date_sart).days) + 1 # Get Prices json_rooms_rests = {} room_types = self.env['hotel.room.type'].search( @@ -202,8 +200,7 @@ class HotelReservation(models.Model): @api.model def get_hcalendar_events_data(self, dfrom, dto): - date_start = date_utils.get_datetime(dfrom, hours=False) \ - - timedelta(days=1) + date_start = fields.Date.from_string(dfrom) - timedelta(days=1) date_start_str = date_start.strftime(DEFAULT_SERVER_DATETIME_FORMAT) user_id = self.env['res.users'].browse(self.env.uid) domain = [] diff --git a/hotel_calendar/models/inherited_ir_default.py b/hotel_calendar/models/inherited_ir_default.py index 1860de97f..60bc254a0 100644 --- a/hotel_calendar/models/inherited_ir_default.py +++ b/hotel_calendar/models/inherited_ir_default.py @@ -2,7 +2,6 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo import models, fields, api from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT -from odoo.addons.hotel import date_utils class IrDefault(models.Model): @@ -26,8 +25,7 @@ class IrDefault(models.Model): fixed_price = pitem.fixed_price room_type = room_type_obj.search([ ('product_id.product_tmpl_id', '=', product_tmpl_id), - ('date_start', '>=', date_utils.now().strftime( - DEFAULT_SERVER_DATETIME_FORMAT)) + ('date_start', '>=', fields.Date.today()) ], limit=1) room_pr_cached_obj.create({ 'room_type_id': room_type.id, diff --git a/hotel_calendar/models/res_config.py b/hotel_calendar/models/res_config.py index e1e6e96e3..9948dfd56 100644 --- a/hotel_calendar/models/res_config.py +++ b/hotel_calendar/models/res_config.py @@ -1,7 +1,6 @@ # Copyright 2018 Alexandre Díaz # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo import models, fields, api -from odoo.addons.hotel import date_utils class HotelConfiguration(models.TransientModel): diff --git a/hotel_calendar/static/src/js/views/calendar/hotel_calendar_model.js b/hotel_calendar/static/src/js/views/calendar/hotel_calendar_model.js index 909b6faed..43f98007a 100644 --- a/hotel_calendar/static/src/js/views/calendar/hotel_calendar_model.js +++ b/hotel_calendar/static/src/js/views/calendar/hotel_calendar_model.js @@ -13,7 +13,6 @@ var AbstractModel = require('web.AbstractModel'), return AbstractModel.extend({ init: function () { this._super.apply(this, arguments); - this.end_date = null; }, load: function (params) { diff --git a/hotel_calendar/wizard/wizard_reservation.py b/hotel_calendar/wizard/wizard_reservation.py index 5b909e740..f29a32b99 100644 --- a/hotel_calendar/wizard/wizard_reservation.py +++ b/hotel_calendar/wizard/wizard_reservation.py @@ -3,13 +3,12 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). import time import logging -from datetime import timedelta +from datetime import datetime, timedelta from openerp.exceptions import ValidationError from openerp.tools import ( DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT) from openerp import models, fields, api, _ -from odoo.addons.hotel import date_utils import odoo.addons.decimal_precision as dp _logger = logging.getLogger(__name__) @@ -25,46 +24,24 @@ class FolioWizard(models.TransientModel): @api.model def _get_default_checkin(self): folio = False - default_arrival_hour = self.env['ir.default'].sudo().get( - 'res.config.settings', 'default_arrival_hour') if 'folio_id' in self._context: folio = self.env['hotel.folio'].search([ ('id', '=', self._context['folio_id']) ]) if folio and folio.room_lines: return folio.room_lines[0].checkin - else: - tz_hotel = self.env['ir.default'].sudo().get( - 'res.config.settings', 'tz_hotel') - now_utc_dt = date_utils.now() - ndate = "%s %s:00" % \ - (now_utc_dt.strftime(DEFAULT_SERVER_DATE_FORMAT), - default_arrival_hour) - ndate_dt = date_utils.get_datetime(ndate, stz=tz_hotel) - ndate_dt = date_utils.dt_as_timezone(ndate_dt, 'UTC') - return ndate_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT) + return fields.Date.today() @api.model def _get_default_checkout(self): folio = False - default_departure_hour = self.env['ir.default'].sudo().get( - 'res.config.settings', 'default_departure_hour') if 'folio_id' in self._context: folio = self.env['hotel.folio'].search([ ('id', '=', self._context['folio_id']) ]) if folio and folio.room_lines: return folio.room_lines[0].checkout - else: - tz_hotel = self.env['ir.default'].sudo().get( - 'res.config.settings', 'tz_hotel') - now_utc_dt = date_utils.now() + timedelta(days=1) - ndate = "%s %s:00" % \ - (now_utc_dt.strftime(DEFAULT_SERVER_DATE_FORMAT), - default_departure_hour) - ndate_dt = date_utils.get_datetime(ndate, stz=tz_hotel) - ndate_dt = date_utils.dt_as_timezone(ndate_dt, 'UTC') - return ndate_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT) + return fields.Date.today() @api.model def _get_default_channel_type(self): @@ -109,10 +86,9 @@ class FolioWizard(models.TransientModel): if line.rooms_num > line.max_rooms: raise ValidationError(_("Too many rooms!")) elif line.room_type_id: - checkout_dt = date_utils.get_datetime(line.checkout) occupied = self.env['hotel.reservation'].occupied( line.checkin, - checkout_dt.strftime(DEFAULT_SERVER_DATE_FORMAT)) + line.checkout) rooms_occupied = occupied.mapped('product_id.id') free_rooms = self.env['hotel.room'].search([ ('product_id.id', 'not in', rooms_occupied), @@ -122,15 +98,9 @@ class FolioWizard(models.TransientModel): product_list = self.env['product.product'].search([ ('id', 'in', room_ids) ]) - nights = date_utils.date_diff(line.checkin, - line.checkout, - hours=False) - hotel_tz = self.env['ir.default'].sudo().get( - 'res.config.settings', - 'hotel_tz') - start_date_utc_dt = date_utils.get_datetime(self.checkin) - start_date_dt = date_utils.dt_as_timezone(start_date_utc_dt, - hotel_tz) + checkin_dt = fields.Date.from_string(line.checkin) + checkout_dt = fields.Date.from_string(line.checkout) + nights = abs((checkout_dt - checkin_dt).days) for room in product_list: pricelist_id = self.env['ir.default'].sudo().get( 'res.config.settings', 'parity_pricelist_id') @@ -138,7 +108,7 @@ class FolioWizard(models.TransientModel): pricelist_id = int(pricelist_id) res_price = 0 for i in range(0, nights): - ndate = start_date_dt + timedelta(days=i) + ndate = checkin_dt + timedelta(days=i) ndate_str = ndate.strftime(DEFAULT_SERVER_DATE_FORMAT) prod = line.room_type_id.product_id.with_context( lang=self.partner_id.lang, @@ -178,44 +148,30 @@ class FolioWizard(models.TransientModel): @param self: object pointer ''' self.ensure_one() - if not self.checkin: - self.checkin = time.strftime(DEFAULT_SERVER_DATETIME_FORMAT) - if not self.checkout: - self.checkout = time.strftime(DEFAULT_SERVER_DATETIME_FORMAT) + checkin_dt = datetime.now() if not self.checkin else fields.Date.from_string(self.checkin) + checkout_dt = datetime.now() if not self.checkout else fields.Date.from_string(self.checkout) + if checkin_dt >= checkout_dt: + checkout_dt = checkin_dt + timedelta(days=1) - # UTC -> Hotel tz - tz = self.env['ir.default'].sudo().get('res.config.settings', - 'tz_hotel') - chkin_utc_dt = date_utils.get_datetime(self.checkin) - chkout_utc_dt = date_utils.get_datetime(self.checkout) + chekin_str = checkin_dt.strftime(DEFAULT_SERVER_DATE_FORMAT) + chekout_str = checkout_dt.strftime(DEFAULT_SERVER_DATE_FORMAT) - if chkin_utc_dt >= chkout_utc_dt: - dpt_hour = self.env['ir.default'].sudo().get( - 'res.config.settings', 'default_departure_hour') - checkout_str = (chkin_utc_dt + timedelta(days=1)).strftime( - DEFAULT_SERVER_DATE_FORMAT) - checkout_str = "%s %s:00" % (checkout_str, dpt_hour) - checkout_dt = date_utils.get_datetime(checkout_str, stz=tz) - checkout_utc_dt = date_utils.dt_as_timezone(checkout_dt, 'UTC') - self.checkout = checkout_utc_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT) - checkout_dt = date_utils.get_datetime(self.checkout, stz=tz) - # Reservation end day count as free day. Not check it - checkout_dt -= timedelta(days=1) room_type_ids = self.env['hotel.room.type'].search([]) - room_types = [] - - for room_type in room_type_ids: - room_types.append((0, False, { - 'room_type_id': room_type.id, - 'checkin': self.checkin, - 'checkout': self.checkout, - 'folio_wizard_id': self.id, - })) - self.room_type_wizard_ids = room_types + cmds = room_type_ids.mapped(lambda x: (0, False, { + 'room_type_id': x.id, + 'checkin': chekin_str, + 'checkout': chekout_str, + 'folio_wizard_id': self.id, + })) + self.write({ + 'checkin': chekin_str, + 'checkout': chekout_str, + 'room_type_wizard_ids': cmds, + }) for room_type in self.room_type_wizard_ids: room_type.update_price() - @api.depends('room_type_wizard_ids','reservation_wizard_ids','service_wizard_ids') + @api.depends('room_type_wizard_ids', 'reservation_wizard_ids', 'service_wizard_ids') def _computed_total(self): total = 0 for line in self.service_wizard_ids: @@ -305,24 +261,25 @@ class HotelRoomTypeWizards(models.TransientModel): default=_get_default_checkout) can_confirm = fields.Boolean(compute="_can_confirm") + @api.multi def _can_confirm(self): - for room_type in self: - date_start = date_utils.get_datetime(room_type.checkin) - date_end = date_utils.get_datetime(room_type.checkout) - date_diff = date_utils.date_diff(date_start, date_end, hours=False) - room_type.can_confirm = room_type.max_rooms > 0 and room_type.min_stay <= date_diff + for record in self: + date_start = fields.Date.from_string(record.checkin) + date_end = fields.Date.from_string(record.checkout) + date_diff = abs((date_end - date_start).days) + record.can_confirm = record.max_rooms > 0 and record.min_stay <= date_diff def _compute_max(self): for res in self: user = self.env['res.users'].browse(self.env.uid) - date_start = date_utils.get_datetime(res.checkin) - date_end = date_utils.get_datetime(res.checkout) - date_diff = date_utils.date_diff(date_start, date_end, hours=False) + date_start = fields.Date.from_string(res.checkin) + date_end = fields.Date.from_string(res.checkout) + date_diff = abs((date_end - date_start).days) minstay_restrictions = self.env['hotel.room.type.restriction.item'].search([ - ('room_type_id','=',res.room_type_id.id), + ('room_type_id', '=', res.room_type_id.id), ]) avail_restrictions = self.env['hotel.room.type.availability'].search([ - ('room_type_id','=',res.room_type_id.id) + ('room_type_id', '=', res.room_type_id.id) ]) real_max = len(res.room_type_id.check_availability_room( res.checkin, @@ -361,32 +318,17 @@ class HotelRoomTypeWizards(models.TransientModel): @api.onchange('rooms_num', 'discount', 'price', 'room_type_id', 'checkin', 'checkout') def update_price(self): for record in self: - checkin = record.checkin or record.folio_wizard_id.checkin - checkout = record.checkout or record.folio_wizard_id.checkout if record.rooms_num > record.max_rooms: raise ValidationError(_("There are not enough rooms!")) - # UTC -> Hotel tz - tz = self.env['ir.default'].sudo().get('res.config.settings', - 'tz_hotel') - chkin_utc_dt = date_utils.get_datetime(checkin) - chkout_utc_dt = date_utils.get_datetime(checkout) + checkin = record.checkin or record.folio_wizard_id.checkin + checkout = record.checkout or record.folio_wizard_id.checkout + chkin_utc_dt = fields.Date.from_string(checkin) + chkout_utc_dt = fields.Date.from_string(checkout) if chkin_utc_dt >= chkout_utc_dt: - dpt_hour = self.env['ir.default'].sudo().get( - 'res.config.settings', 'default_departure_hour') - checkout_str = (chkin_utc_dt + timedelta(days=1)).strftime( - DEFAULT_SERVER_DATE_FORMAT) - checkout_str = "%s %s:00" % (checkout_str, dpt_hour) - checkout_dt = date_utils.get_datetime(checkout_str, stz=tz) - checkout_utc_dt = date_utils.dt_as_timezone(checkout_dt, 'UTC') - checkout = checkout_utc_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT) - checkout_dt = date_utils.get_datetime(checkout, stz=tz) - # Reservation end day count as free day. Not check it - checkout_dt -= timedelta(days=1) - nights = date_utils.date_diff(checkin, checkout, hours=False) - start_date_dt = date_utils.dt_as_timezone(chkin_utc_dt, tz) - # Reservation end day count as free day. Not check it - checkout_dt -= timedelta(days=1) + chkout_utc_dt = chkin_utc_dt + timedelta(days=1) + chkout_utc_dt -= timedelta(days=1) + nights = abs((chkout_utc_dt - chkin_utc_dt).days) pricelist_id = self.env['ir.default'].sudo().get( 'res.config.settings', 'parity_pricelist_id') @@ -395,7 +337,7 @@ class HotelRoomTypeWizards(models.TransientModel): res_price = 0 for i in range(0, nights): - ndate = start_date_dt + timedelta(days=i) + ndate = chkin_utc_dt + timedelta(days=i) ndate_str = ndate.strftime(DEFAULT_SERVER_DATE_FORMAT) prod = record.room_type_id.product_id.with_context( lang=record.folio_wizard_id.partner_id.lang, @@ -460,7 +402,7 @@ class ReservationWizard(models.TransientModel): if line.adults == 0: line.adults = room.capacity line.room_type_id = room.price_room_type.id - checkout_dt = date_utils.get_datetime(line.checkout) + checkout_dt = fields.Date.from_string(line.checkout) checkout_dt -= timedelta(days=1) occupied = self.env['hotel.reservation'].occupied( line.checkin, @@ -479,23 +421,18 @@ class ReservationWizard(models.TransientModel): if not self.checkout: self.checkout = self.folio_wizard_id.checkout - hotel_tz = self.env['ir.default'].sudo().get( - 'res.config.settings', 'hotel_tz') - start_date_utc_dt = date_utils.get_datetime(line.checkin) - start_date_dt = date_utils.dt_as_timezone(start_date_utc_dt, - hotel_tz) + start_date_utc_dt = fields.Date.from_string(line.checkin) + end_date_utc_dt = fields.Date.from_string(line.checkout) if line.room_type_id: pricelist_id = self.env['ir.default'].sudo().get( 'res.config.settings', 'parity_pricelist_id') if pricelist_id: pricelist_id = int(pricelist_id) - nights = date_utils.date_diff(line.checkin, - line.checkout, - hours=False) + nights = abs((end_date_utc_dt - start_date_utc_dt).days) res_price = 0 for i in range(0, nights): - ndate = start_date_dt + timedelta(days=i) + ndate = start_date_utc_dt + timedelta(days=i) ndate_str = ndate.strftime(DEFAULT_SERVER_DATE_FORMAT) prod = line.room_type_id.product_id.with_context( lang=self.partner_id.lang, @@ -508,11 +445,10 @@ class ReservationWizard(models.TransientModel): res_price = res_price - (res_price * self.discount) * 0.01 line.amount_reservation = res_price line.price = res_price - checkout_dt = date_utils.get_datetime(self.checkout) - checkout_dt -= timedelta(days=1) + end_date_utc_dt -= timedelta(days=1) occupied = self.env['hotel.reservation'].occupied( - self.checkin, - checkout_dt.strftime(DEFAULT_SERVER_DATE_FORMAT)) + line.checkin, + end_date_utc_dt.strftime(DEFAULT_SERVER_DATE_FORMAT)) rooms_occupied = occupied.mapped('product_id.id') domain_rooms = [ ('isroom', '=', True), diff --git a/hotel_channel_connector/__manifest__.py b/hotel_channel_connector/__manifest__.py index 2617b3cc5..7d82409d5 100644 --- a/hotel_channel_connector/__manifest__.py +++ b/hotel_channel_connector/__manifest__.py @@ -39,6 +39,8 @@ 'views/channel_hotel_room_type_availability_views.xml', 'views/channel_hotel_room_type_restriction_views.xml', 'views/channel_product_pricelist_views.xml', + 'views/channel_connector_backend_views.xml', + 'views/channel_connector_menu.xml', 'data/menus.xml', 'data/sequences.xml', #'security/ir.model.access.csv', diff --git a/hotel_channel_connector/components/backend_adapter.py b/hotel_channel_connector/components/backend_adapter.py index 8de7f03d0..ea5fd6836 100644 --- a/hotel_channel_connector/components/backend_adapter.py +++ b/hotel_channel_connector/components/backend_adapter.py @@ -1,6 +1,8 @@ # Copyright 2018 Alexandre Díaz # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from odoo import _ +from odoo.exceptions import ValidationError from odoo.addons.component.core import AbstractComponent from odoo.addons.queue_job.exception import RetryableJobError from odoo.tools import ( @@ -50,6 +52,14 @@ class WuBookServer(object): self._token = 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 and self._login_data.is_valid(): @@ -86,16 +96,6 @@ class HotelChannelInterfaceAdapter(AbstractComponent): _inherit = ['base.backend.adapter', 'base.hotel.channel.connector'] _usage = 'backend.adapter' - def _select_versions(self): - return [ - ('1.2', '1.2'), - ] - version = fields.Selection( - selection='_select_versions', - string='Version', - required=True, - ) - def create_room(self, shortcode, name, capacity, price, availability): raise NotImplementedError diff --git a/hotel_channel_connector/components/importer.py b/hotel_channel_connector/components/importer.py index 87675fd38..13bf9402f 100644 --- a/hotel_channel_connector/components/importer.py +++ b/hotel_channel_connector/components/importer.py @@ -2,11 +2,20 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). import logging -from odoo.addons.component.core import AbstractComponent +import pytz +import json +from datetime import timedelta +from odoo.exceptions import ValidationError +from odoo.addons.component.core import AbstractComponent, Component +from odoo.addons.hotel import date_utils +from odoo import _ from odoo.tools import ( DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT) -from .backend_adapter import DEFAULT_WUBOOK_DATE_FORMAT +from .backend_adapter import ( + DEFAULT_WUBOOK_DATE_FORMAT, + DEFAULT_WUBOOK_DATETIME_FORMAT, + WUBOOK_STATUS_BAD) from odoo import api _logger = logging.getLogger(__name__) @@ -28,8 +37,8 @@ class HotelChannelConnectorImporter(AbstractComponent): 'avail': day_vals.get('avail', 0), 'wpushed': True, } - if set_wmax_avail: - vals.update({'wmax_avail': day_vals.get('avail', 0)}) + if set_max_avail: + vals.update({'max_avail': day_vals.get('avail', 0)}) if room_type_avail: room_type_avail.with_context({ 'wubook_action': False, @@ -723,35 +732,6 @@ class HotelChannelConnectorImporter(AbstractComponent): return False return True - @api.model - def fetch_new_bookings(self): - try: - results = self.backend_adapter.fetch_new_bookings() - processed_rids, errors, checkin_utc_dt, checkout_utc_dt = \ - self._generate_reservations(results) - if any(processed_rids): - uniq_rids = list(set(processed_rids)) - rcodeb, resultsb = self.backend_adapter.mark_bookings(uniq_rids) - if rcodeb != 0: - self.create_issue( - 'wubook', - _("Problem trying mark bookings (%s)") % - str(processed_rids), - '') - # Update Odoo availability (don't wait for wubook) - # This cause abuse service in first import!! - if checkin_utc_dt and checkout_utc_dt: - self.backend_adapter.fetch_rooms_values( - checkin_utc_dt.strftime(DEFAULT_SERVER_DATE_FORMAT), - checkout_utc_dt.strftime(DEFAULT_SERVER_DATE_FORMAT)) - except ValidationError: - self.create_issue( - 'reservation', - _("Can't process reservations from wubook"), - results) - return False - return True - @api.model def fetch_booking(self, channel_reservation_id): try: @@ -770,7 +750,7 @@ class HotelChannelConnectorImporter(AbstractComponent): self.create_channel_connector_issue( 'reservation', _("Can't process reservations from wubook"), - results, wid=wrid) + results, channel_object_id=channel_reservation_id) return False return True diff --git a/hotel_channel_connector/models/channel_backend/common.py b/hotel_channel_connector/models/channel_backend/common.py index a517ff822..776bf5d04 100644 --- a/hotel_channel_connector/models/channel_backend/common.py +++ b/hotel_channel_connector/models/channel_backend/common.py @@ -3,7 +3,7 @@ from contextlib import contextmanager from odoo import models, api, fields -from ...components.backend_adapter import WuBookLogin, WuBookAdapter +from ...components.backend_adapter import WuBookLogin, WuBookServer class ChannelBackend(models.Model): _name = 'channel.backend' @@ -19,8 +19,8 @@ class ChannelBackend(models.Model): """ return [('1.2', '1.2+')] + name = fields.Char('Name') version = fields.Selection(selection='select_versions', required=True) - username = fields.Char('Channel Service Username') passwd = fields.Char('Channel Service Password') lcode = fields.Char('Channel Service lcode') @@ -28,21 +28,25 @@ class ChannelBackend(models.Model): default='https://wired.wubook.net/xrws/') pkey = fields.Char('Channel Service PKey') + @api.multi + def import_reservations(self): + channel_hotel_reservation = self.env['channel.hotel.reservation'] + for backend in self: + channel_hotel_reservation.import_reservations(backend) + return True + @contextmanager @api.multi def work_on(self, model_name, **kwargs): self.ensure_one() - lang = self.default_lang_id - if lang.code != self.env.context.get('lang'): - self = self.with_context(lang=lang.code) wubook_login = WuBookLogin( self.server, self.username, self.passwd, self.lcode, self.pkey) - with WuBookAdapter(wubook_login) as channel_api: + with WuBookServer(wubook_login) as channel_api: _super = super(ChannelBackend, self) - # from the components we'll be able to do: self.work.magento_api - with _super.work_on(model_name, **kwargs) as work: + # from the components we'll be able to do: self.work.channel_api + with _super.work_on(model_name, channel_api=channel_api, **kwargs) as work: yield work diff --git a/hotel_channel_connector/models/channel_binding/common.py b/hotel_channel_connector/models/channel_binding/common.py index d7ccb7a88..dc8b8616f 100644 --- a/hotel_channel_connector/models/channel_binding/common.py +++ b/hotel_channel_connector/models/channel_binding/common.py @@ -1,7 +1,8 @@ # Copyright 2018 Alexandre Díaz # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models, fields +from odoo import models, fields, api +from odoo.addons.queue_job.job import job class ChannelBinding(models.AbstractModel): diff --git a/hotel_channel_connector/models/hotel_reservation/__init__.py b/hotel_channel_connector/models/hotel_reservation/__init__.py index 257ab04fc..06e54858b 100644 --- a/hotel_channel_connector/models/hotel_reservation/__init__.py +++ b/hotel_channel_connector/models/hotel_reservation/__init__.py @@ -2,3 +2,4 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from . import common +from . import importer diff --git a/hotel_channel_connector/models/hotel_reservation/common.py b/hotel_channel_connector/models/hotel_reservation/common.py index f77f0dee5..bf92a9bca 100644 --- a/hotel_channel_connector/models/hotel_reservation/common.py +++ b/hotel_channel_connector/models/hotel_reservation/common.py @@ -49,6 +49,13 @@ class ChannelHotelReservation(models.Model): wstatus_reason = fields.Char("WuBook Status Reason", readonly=True) wmodified = fields.Boolean("WuBook Modified", readonly=True, default=False) + @job(default_channel='root.channel') + @api.model + def import_reservations(self, backend): + with backend.work_on(self._name) as work: + importer = work.component(usage='channel.hotel.reservation.importer') + return importer.fetch_new_bookings() + @api.depends('channel_reservation_id', 'ota_id') def _is_from_ota(self): for record in self: diff --git a/hotel_channel_connector/models/hotel_reservation/importer.py b/hotel_channel_connector/models/hotel_reservation/importer.py new file mode 100644 index 000000000..e4e673b1d --- /dev/null +++ b/hotel_channel_connector/models/hotel_reservation/importer.py @@ -0,0 +1,16 @@ +# Copyright 2018 Alexandre Díaz +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.exceptions import ValidationError +from odoo.addons.component.core import Component +from odoo import fields, api, _ +from odoo.tools import ( + DEFAULT_SERVER_DATE_FORMAT, + DEFAULT_SERVER_DATETIME_FORMAT) + + +class HotelReservationImporter(Component): + _name = 'channel.hotel.reservation.importer' + _inherit = 'hotel.channel.importer' + _apply_on = ['channel.hotel.reservation'] + _usage = 'hotel.reservation.importer' diff --git a/hotel_channel_connector/models/inherited_hotel_folio.py b/hotel_channel_connector/models/inherited_hotel_folio.py index f5b4b26fd..323cfc71e 100644 --- a/hotel_channel_connector/models/inherited_hotel_folio.py +++ b/hotel_channel_connector/models/inherited_hotel_folio.py @@ -11,7 +11,7 @@ class HotelFolio(models.Model): @api.depends('room_lines') def _has_channel_reservations(self): for record in self: - channel_reservations = record.room_lines.filtered(lambda x: x.channel_room_id) + channel_reservations = record.room_lines.filtered(lambda x: x.room_id) record.has_channel_reservations = any(channel_reservations) wseed = fields.Char("Wubook Session Seed", readonly=True) @@ -22,9 +22,8 @@ class HotelFolio(models.Model): old_name='whas_wubook_reservations') @job(default_channel='root.channel') - @api.multi + @api.model def import_reservations(self): - self.ensure_one() with self.backend_id.work_on(self._name) as work: importer = work.component(usage='channel.importer') importer.fetch_new_bookings() diff --git a/hotel_channel_connector/static/src/js/views/list/list_controller.js b/hotel_channel_connector/static/src/js/views/list/list_controller.js new file mode 100644 index 000000000..472c471f8 --- /dev/null +++ b/hotel_channel_connector/static/src/js/views/list/list_controller.js @@ -0,0 +1,187 @@ +odoo.define('hotel_channel_connector.ListController', function(require) { +'use strict'; +/* + * Hotel Channel Connector + * GNU Public License + * Alexandre Díaz + */ + +var ListController = require('web.ListController'); +var Core = require('web.core'); + +var _t = Core._t; + +ListController.include({ + + renderButtons: function () { + this._super.apply(this, arguments); // Sets this.$buttons + + if (this.modelName === 'hotel.room.type') { + this.$buttons.append(""); + this.$buttons.find('.o_channel_connector_import_rooms').on('click', this._importRooms.bind(this)); + } else if (this.modelName === 'hotel.folio') { + this.$buttons.append(""); + this.$buttons.find('.o_channel_connector_import_reservations').on('click', this._importReservations.bind(this)); + } else if (this.modelName === 'product.pricelist') { + this.$buttons.append(""); + this.$buttons.find('.o_channel_connector_import_price_plans').on('click', this._importPricePlans.bind(this)); + this.$buttons.append(""); + this.$buttons.find('.o_channel_connector_push_price_plans').on('click', this._pushPricePlans.bind(this)); + } else if (this.modelName === 'wubook.channel.info') { + this.$buttons.append(""); + this.$buttons.find('.o_channel_connector_import_channels_info').on('click', this._importChannelsInfo.bind(this)); + } else if (this.modelName === 'hotel.room.type.restriction') { + this.$buttons.append(""); + this.$buttons.find('.o_channel_connector_import_restriction_plans').on('click', this._importRestrictionPlans.bind(this)); + this.$buttons.append(""); + this.$buttons.find('.o_channel_connector_push_restriction_plans').on('click', this._pushRestrictionPlans.bind(this)); + } else if (this.modelName === 'hotel.room.type.availability') { + this.$buttons.append(""); + this.$buttons.find('.o_channel_connector_import_availability').on('click', this._importAvailability.bind(this)); + this.$buttons.append(""); + this.$buttons.find('.o_channel_connector_push_availability').on('click', this._pushAvailability.bind(this)); + } + }, + + _importRooms: function () { + var self = this; + this.dataset._model.call('import_rooms', [false]).then(function(results){ + if (!results[0]) { + self.do_warn(_t('Operation Errors'), _t('Errors while importing rooms. See issues registry.'), true); + } + if (results[0] || results[1] > 0) { + if (results[1] > 0) { + self.do_notify(_t('Operation Success'), `${results[1]}` + ' ' + _t('Rooms successfully imported'), false); + } else { + self.do_notify(_t('Operation Success'), _t('No new rooms found. Everything is done.'), false); + } + var active_view = self.ViewManager.active_view; + active_view.controller.reload(); // list view only has reload + } + }); + + return false; + }, + + _importReservations: function () { + var self = this; + console.log(this); + this.model.import_reservations().then(function(results){ + console.log(results); + if (!results[0]) { + self.do_warn(_t('Operation Errors'), _t('Errors while importing reservations. See issues registry.'), true); + } + if (results[0] || results[1] > 0) { + if (results[1] > 0) { + self.do_notify(_t('Operation Success'), `${results[1]}` + ' ' + _t('Reservations successfully imported'), false); + } else { + self.do_notify(_t('Operation Success'), _t('No new reservations found. Everything is done.'), false); + } + var active_view = self.ViewManager.active_view; + active_view.controller.reload(); // list view only has reload + } + }); + + return false; + }, + + _importPricePlans: function () { + var self = this; + this.dataset._model.call('import_price_plans', [false]).then(function(results){ + if (!results[0]) { + self.do_warn(_t('Operation Errors'), _t('Errors while importing price plans from WuBook. See issues log.'), true); + } + if (results[0] || results[1] > 0) { + if (results[1] > 0) { + self.do_notify(_t('Operation Success'), `${results[1]}` + ' ' + _t('Price Plans successfully imported'), false); + } else { + self.do_notify(_t('Operation Success'), _t('No new price plans found. Everything is done.'), false); + } + var active_view = self.ViewManager.active_view; + active_view.controller.reload(); // list view only has reload + } + }); + + return false; + }, + + _pushPricePlans: function () { + var self = this; + new Model('wubook').call('push_priceplans', [false]).then(function(results){ + self.do_notify(_t('Operation Success'), _t('Price Plans successfully pushed'), false); + }).fail(function(){ + self.do_warn(_t('Operation Errors'), _t('Errors while pushing price plans to WuBook. See issues log.'), true); + }); + + return false; + }, + + _importChannelsInfo: function () { + var self = this; + this.dataset._model.call('import_channels_info', [false]).then(function(results){ + if (!results[0]) { + self.do_warn(_t('Operation Errors'), _t('Errors while importing channels info from WuBook. See issues log.'), true); + } + if (results[0] || results[1] > 0) { + if (results[1] > 0) { + self.do_notify(_t('Operation Success'), `${results[1]}` + ' ' + _t('Channels Info successfully imported'), false); + } else { + self.do_notify(_t('Operation Success'), _t('No new channels info found. Everything is done.'), false); + } + var active_view = self.ViewManager.active_view; + active_view.controller.reload(); // list view only has reload + } + }); + + return false; + }, + + _importRestrictionPlans: function () { + var self = this; + this.dataset._model.call('import_restriction_plans', [false]).then(function(results){ + if (!results[0]) { + self.do_warn(_t('Operation Errors'), _t('Errors while importing restriction plans from WuBook. See issues log.'), true); + } + if (results[0] || results[1] > 0) { + if (results[1] > 0) { + self.do_notify(_t('Operation Success'), `${results[1]}` + ' ' + _t('Restriction Plans successfully imported'), false); + } else { + self.do_notify(_t('Operation Success'), _t('No new restriction plans found. Everything is done.'), false); + } + var active_view = self.ViewManager.active_view; + active_view.controller.reload(); // list view only has reload + } + }); + + return false; + }, + + _pushRestrictionPlans: function () { + var self = this; + new Model('wubook').call('push_restrictions', [false]).then(function(results){ + self.do_notify(_t('Operation Success'), _t('Restrictions successfully pushed'), false); + }).fail(function(){ + self.do_warn(_t('Operation Errors'), _t('Errors while pushing restrictions to WuBook. See issues log.'), true); + }); + + return false; + }, + + _importAvailability: function () { + this.do_action('hotel_wubook_proto.action_wubook_import_availability'); + return false; + }, + + _pushAvailability: function () { + var self = this; + new Model('wubook').call('push_availability', [false]).then(function(results){ + self.do_notify(_t('Operation Success'), _t('Availability successfully pushed'), false); + }).fail(function(){ + self.do_warn(_t('Operation Errors'), _t('Errors while pushing availability to Channel. See issues log.'), true); + }); + + return false; + } +}); + +}); diff --git a/hotel_channel_connector/static/src/js/views/list/list_model.js b/hotel_channel_connector/static/src/js/views/list/list_model.js new file mode 100644 index 000000000..8f1cd70f7 --- /dev/null +++ b/hotel_channel_connector/static/src/js/views/list/list_model.js @@ -0,0 +1,25 @@ +odoo.define('hotel_channel_connector.ListModel', function(require) { +'use strict'; +/* + * Hotel Channel Connector + * GNU Public License + * Alexandre Díaz + */ + +var BasicModel = require('web.BasicModel'), + Session = require('web.session'); + +return BasicModel.extend({ + + import_reservations: function() { + return this._rpc({ + model: 'hotel.folio', + method: 'import_reservations', + args: undefined, + context: Session.user_context, + }); + }, + +}); + +}); diff --git a/hotel_channel_connector/static/src/js/views/list/list_view.js b/hotel_channel_connector/static/src/js/views/list/list_view.js new file mode 100644 index 000000000..f3364bdcd --- /dev/null +++ b/hotel_channel_connector/static/src/js/views/list/list_view.js @@ -0,0 +1,18 @@ +odoo.define('hotel_channel_connector.ListView', function(require) { +'use strict'; +/* + * Hotel Channel Connector + * GNU Public License + * Alexandre Díaz + */ + +var ListView = require('web.ListView'), + ListModel = require('hotel_channel_connector.ListModel'); + +ListView.include({ + config: _.extend({}, ListView.prototype.config, { + Model: ListModel, + }), +}); + +}); diff --git a/hotel_channel_connector/static/src/js/wubook_listview_import_buttons.js b/hotel_channel_connector/static/src/js/wubook_listview_import_buttons.js deleted file mode 100644 index a521ed4e0..000000000 --- a/hotel_channel_connector/static/src/js/wubook_listview_import_buttons.js +++ /dev/null @@ -1,188 +0,0 @@ -odoo.define('hotel_channel_connector.listview_button_import_rooms', function(require) { -'use strict'; -/* - * Hotel Channel Connector - * GNU Public License - * Alexandre Díaz - */ - -var ListView = require('web.ListView'); -var Core = require('web.core'); -var Model = require('web.DataModel'); - -var _t = Core._t; - -function import_rooms(){ - var self = this; - this.dataset._model.call('import_rooms', [false]).then(function(results){ - if (!results[0]) { - self.do_warn(_t('Operation Errors'), _t('Errors while importing rooms. See issues registry.'), true); - } - if (results[0] || results[1] > 0) { - if (results[1] > 0) { - self.do_notify(_t('Operation Success'), `${results[1]}` + ' ' + _t('Rooms successfully imported'), false); - } else { - self.do_notify(_t('Operation Success'), _t('No new rooms found. Everything is done.'), false); - } - var active_view = self.ViewManager.active_view; - active_view.controller.reload(); // list view only has reload - } - }); - - return false; -} - -function import_reservations(){ - var self = this; - this.dataset._model.call('import_reservations', [false]).then(function(results){ - console.log(results); - if (!results[0]) { - self.do_warn(_t('Operation Errors'), _t('Errors while importing reservations. See issues registry.'), true); - } - if (results[0] || results[1] > 0) { - if (results[1] > 0) { - self.do_notify(_t('Operation Success'), `${results[1]}` + ' ' + _t('Reservations successfully imported'), false); - } else { - self.do_notify(_t('Operation Success'), _t('No new reservations found. Everything is done.'), false); - } - var active_view = self.ViewManager.active_view; - active_view.controller.reload(); // list view only has reload - } - }); - - return false; -} - -function import_price_plans(){ - var self = this; - this.dataset._model.call('import_price_plans', [false]).then(function(results){ - if (!results[0]) { - self.do_warn(_t('Operation Errors'), _t('Errors while importing price plans from WuBook. See issues log.'), true); - } - if (results[0] || results[1] > 0) { - if (results[1] > 0) { - self.do_notify(_t('Operation Success'), `${results[1]}` + ' ' + _t('Price Plans successfully imported'), false); - } else { - self.do_notify(_t('Operation Success'), _t('No new price plans found. Everything is done.'), false); - } - var active_view = self.ViewManager.active_view; - active_view.controller.reload(); // list view only has reload - } - }); - - return false; -} - - -function push_price_plans(){ - var self = this; - new Model('wubook').call('push_priceplans', [false]).then(function(results){ - self.do_notify(_t('Operation Success'), _t('Price Plans successfully pushed'), false); - }).fail(function(){ - self.do_warn(_t('Operation Errors'), _t('Errors while pushing price plans to WuBook. See issues log.'), true); - }); - - return false; -} - -function import_channels_info(){ - var self = this; - this.dataset._model.call('import_channels_info', [false]).then(function(results){ - if (!results[0]) { - self.do_warn(_t('Operation Errors'), _t('Errors while importing channels info from WuBook. See issues log.'), true); - } - if (results[0] || results[1] > 0) { - if (results[1] > 0) { - self.do_notify(_t('Operation Success'), `${results[1]}` + ' ' + _t('Channels Info successfully imported'), false); - } else { - self.do_notify(_t('Operation Success'), _t('No new channels info found. Everything is done.'), false); - } - var active_view = self.ViewManager.active_view; - active_view.controller.reload(); // list view only has reload - } - }); - - return false; -} - -function import_restriction_plans(){ - var self = this; - this.dataset._model.call('import_restriction_plans', [false]).then(function(results){ - if (!results[0]) { - self.do_warn(_t('Operation Errors'), _t('Errors while importing restriction plans from WuBook. See issues log.'), true); - } - if (results[0] || results[1] > 0) { - if (results[1] > 0) { - self.do_notify(_t('Operation Success'), `${results[1]}` + ' ' + _t('Restriction Plans successfully imported'), false); - } else { - self.do_notify(_t('Operation Success'), _t('No new restriction plans found. Everything is done.'), false); - } - var active_view = self.ViewManager.active_view; - active_view.controller.reload(); // list view only has reload - } - }); - - return false; -} - -function push_restriction_plans(){ - var self = this; - new Model('wubook').call('push_restrictions', [false]).then(function(results){ - self.do_notify(_t('Operation Success'), _t('Restrictions successfully pushed'), false); - }).fail(function(){ - self.do_warn(_t('Operation Errors'), _t('Errors while pushing restrictions to WuBook. See issues log.'), true); - }); - - return false; -} - -function import_availability(){ - this.do_action('hotel_wubook_proto.action_wubook_import_availability'); - return false; -} - - -function push_availability(){ - var self = this; - new Model('wubook').call('push_availability', [false]).then(function(results){ - self.do_notify(_t('Operation Success'), _t('Availability successfully pushed'), false); - }).fail(function(){ - self.do_warn(_t('Operation Errors'), _t('Errors while pushing availability to Channel. See issues log.'), true); - }); - - return false; -} - -ListView.include({ - render_buttons: function () { - this._super.apply(this, arguments); // Sets this.$buttons - - if (this.dataset.model === 'hotel.room.type') { - this.$buttons.append(""); - this.$buttons.find('.oe_channel_connector_import_rooms').on('click', import_rooms.bind(this)); - } else if (this.dataset.model === 'hotel.folio') { - this.$buttons.append(""); - this.$buttons.find('.oe_channel_connector_import_reservations').on('click', import_reservations.bind(this)); - } else if (this.dataset.model === 'product.pricelist') { - this.$buttons.append(""); - this.$buttons.find('.oe_channel_connector_import_price_plans').on('click', import_price_plans.bind(this)); - this.$buttons.append(""); - this.$buttons.find('.oe_channel_connector_push_price_plans').on('click', push_price_plans.bind(this)); - } else if (this.dataset.model === 'wubook.channel.info') { - this.$buttons.append(""); - this.$buttons.find('.oe_channel_connector_import_channels_info').on('click', import_channels_info.bind(this)); - } else if (this.dataset.model === 'hotel.room.type.restriction') { - this.$buttons.append(""); - this.$buttons.find('.oe_channel_connector_import_restriction_plans').on('click', import_restriction_plans.bind(this)); - this.$buttons.append(""); - this.$buttons.find('.oe_channel_connector_push_restriction_plans').on('click', push_restriction_plans.bind(this)); - } else if (this.dataset.model === 'hotel.room.type.availability') { - this.$buttons.append(""); - this.$buttons.find('.oe_channel_connector_import_availability').on('click', import_availability.bind(this)); - this.$buttons.append(""); - this.$buttons.find('.oe_channel_connector_push_availability').on('click', push_availability.bind(this)); - } - } -}); - -}); diff --git a/hotel_channel_connector/views/channel_connector_backend_views.xml b/hotel_channel_connector/views/channel_connector_backend_views.xml new file mode 100644 index 000000000..3724afa0a --- /dev/null +++ b/hotel_channel_connector/views/channel_connector_backend_views.xml @@ -0,0 +1,88 @@ + + + + + channel.backend.form + channel.backend + +
+
+
+ + +
+
+
+ + + channel.backend.tree + channel.backend + + + + + + + + + + Channel Backends + channel.backend + form + tree,form + + + +
diff --git a/hotel_channel_connector/views/channel_connector_menu.xml b/hotel_channel_connector/views/channel_connector_menu.xml new file mode 100644 index 000000000..3ffd1d7c9 --- /dev/null +++ b/hotel_channel_connector/views/channel_connector_menu.xml @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/hotel_channel_connector/views/general.xml b/hotel_channel_connector/views/general.xml index 50f93b754..e2867a141 100644 --- a/hotel_channel_connector/views/general.xml +++ b/hotel_channel_connector/views/general.xml @@ -4,7 +4,9 @@