Пример #1
0
    def test_create_reservation(self):
        now_utc_dt = date_utils.now()
        reserv_start_utc_dt = now_utc_dt + timedelta(days=3)
        reserv_end_utc_dt = reserv_start_utc_dt + timedelta(days=3)
        folio = self.create_folio(self.user_hotel_manager, self.partner_2)
        reservation = self.create_reservation(self.user_hotel_manager, folio,
                                              reserv_start_utc_dt,
                                              reserv_end_utc_dt,
                                              self.hotel_room_double_200,
                                              "Reservation Test #1")

        reserv_start_dt = date_utils.dt_as_timezone(reserv_start_utc_dt,
                                                    self.tz_hotel)
        reserv_end_dt = date_utils.dt_as_timezone(
            reserv_end_utc_dt - timedelta(days=1), self.tz_hotel)
        self.assertEqual(reservation.reservation_lines[0].date,
                         reserv_start_dt.strftime(DEFAULT_SERVER_DATE_FORMAT),
                         "Reservation lines don't start in the correct date")
        self.assertEqual(reservation.reservation_lines[-1].date,
                         reserv_end_dt.strftime(DEFAULT_SERVER_DATE_FORMAT),
                         "Reservation lines don't end in the correct date")

        total_price = 0.0
        for rline in reservation.reservation_lines:
            total_price += rline.price
        self.assertEqual(folio.amount_untaxed, total_price,
                         "Folio amount doesn't match with reservation lines")
Пример #2
0
    def update_price(self):
        for line in self:
            now_utc_dt = date_utils.now()
            if not self.checkin:
                self.checkin = self.folio_wizard_id.checkin
            if not self.checkout:
                self.checkout = self.folio_wizard_id.checkout
            if self.rooms_num > self.max_rooms:
                raise ValidationError(_("There are not enough rooms!"))
            # UTC -> Hotel tz
            tz = self.env['ir.values'].get_default('hotel.config.settings',
                                                   'tz_hotel')
            chkin_utc_dt = date_utils.get_datetime(self.checkin)
            chkout_utc_dt = date_utils.get_datetime(self.checkout)

            if chkin_utc_dt >= chkout_utc_dt:
                dpt_hour = self.env['ir.values'].get_default(
                    'hotel.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)
            nights = days_diff = date_utils.date_diff(self.checkin,
                                                      self.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)

            pricelist_id = self.env['ir.values'].sudo().get_default(
                'hotel.config.settings', 'parity_pricelist_id')
            if pricelist_id:
                pricelist_id = int(pricelist_id)

            res_price = 0
            for i in range(0, nights):
                ndate = start_date_dt + timedelta(days=i)
                ndate_str = ndate.strftime(DEFAULT_SERVER_DATE_FORMAT)
                prod = self.virtual_room_id.product_id.with_context(
                    lang=self.folio_wizard_id.partner_id.lang,
                    partner=self.folio_wizard_id.partner_id.id,
                    quantity=1,
                    date=ndate_str,
                    pricelist=pricelist_id,
                    uom=self.virtual_room_id.product_id.uom_id.id)
                res_price += prod.price
            self.price = res_price - (res_price * self.discount) / 100
            self.total_price = self.rooms_num * self.price
            self.amount_reservation = self.total_price
Пример #3
0
    def test_action_cancel(self):
        now_utc_dt = date_utils.now()
        checkin_utc_dt = now_utc_dt + timedelta(days=3)
        checkin_dt = date_utils.dt_as_timezone(checkin_utc_dt, self.tz_hotel)
        checkout_utc_dt = checkin_utc_dt + timedelta(days=2)
        date_diff = date_utils.date_diff(
            checkin_utc_dt, checkout_utc_dt, hours=False) + 1

        wbooks = [
            self.create_wubook_booking(
                self.user_hotel_manager,
                checkin_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
                self.partner_2,
                {
                    self.hotel_vroom_budget.wrid: {
                        'occupancy': [1],  # 1 Reservation Line
                        'dayprices': [15.0, 15.0]  # 2 Days
                    }
                })
        ]
        processed_rids, errors, checkin_utc_dt, checkout_utc_dt = \
            self.env['wubook'].sudo().generate_reservations(wbooks)

        # Check Creation
        self.assertTrue(any(processed_rids), "Reservation not found")
        self.assertFalse(errors, "Reservation errors")

        hotel_reserv_obj = self.env['hotel.reservation']
        nreserv = hotel_reserv_obj.sudo(self.user_hotel_manager).search([
            ('wrid', 'in', processed_rids)
        ])
        self.assertTrue(nreserv, "Reservation not found")
        nreserv.sudo(self.user_hotel_manager).action_cancel()
        self.assertEqual(nreserv.state, 'cancelled',
                         "Rervation don't cancelled")
Пример #4
0
    def test_action_confirm(self):
        now_utc_dt = date_utils.now()
        checkin_utc_dt = now_utc_dt + timedelta(days=3)
        checkin_dt = date_utils.dt_as_timezone(checkin_utc_dt, self.tz_hotel)
        checkout_utc_dt = checkin_utc_dt + timedelta(days=2)
        date_diff = date_utils.date_diff(
            checkin_utc_dt, checkout_utc_dt, hours=False) + 1

        wbooks = [
            self.create_wubook_booking(
                self.user_hotel_manager,
                checkin_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
                self.partner_2, {
                    self.hotel_room_type_budget.wrid: {
                        'occupancy': [1],
                        'dayprices': [15.0, 15.0]
                    }
                })
        ]
        processed_rids, errors, checkin_utc_dt, checkout_utc_dt = \
            self.env['wubook'].sudo().generate_reservations(wbooks)
        self.assertTrue(any(processed_rids), "Reservation not found")
        self.assertFalse(errors, "Reservation errors")
        nreserv = self.env['hotel.reservation'].search(
            [('wrid', '=', processed_rids[0])], order='id ASC', limit=1)
        self.assertTrue(nreserv, "Can't found reservation")
        nreserv.folio_id.action_confirm()
        self.assertEqual(nreserv.folio_id.state, 'sale',
                         "Reservation not confirmed")
Пример #5
0
    def test_excluded_taxes(self):
        now_utc_dt = date_utils.now()
        checkin_utc_dt = now_utc_dt + timedelta(days=3)
        checkin_dt = date_utils.dt_as_timezone(checkin_utc_dt, self.tz_hotel)

        # Invalid Occupancy
        wbooks = [
            self.create_wubook_booking(
                self.user_hotel_manager,
                checkin_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
                self.partner_2,
                {
                    self.hotel_vroom_budget.wrid: {
                        'occupancy': [1],
                        'dayprices': [15.0, 15.0]
                    }
                },
                brooms_ancillary={
                    "tax_inclusive": False,
                    "taxes": 9.99,
                    "fees": 0.0,
                }
            )]
        processed_rids, errors, checkin_utc_dt, checkout_utc_dt = \
            self.env['wubook'].sudo().generate_reservations(wbooks)
        self.assertFalse(errors)
        self.assertTrue(any(processed_rids))
        nreserv = self.env['hotel.reservation'].search([
            ('wrid', 'in', processed_rids)
        ], order="id ASC", limit=1)
        self.assertNotEqual(nreserv.amount_room, 30.0, "Invalid Prices!")
Пример #6
0
    def text_invalid_booking_amount(self):
        now_utc_dt = date_utils.now()
        checkin_utc_dt = now_utc_dt + timedelta(days=3)
        checkin_dt = date_utils.dt_as_timezone(checkin_utc_dt,
                                               self.tz_hotel)

        # Create Reservation
        num_issues = self.env['wubook.issue'].search_count([])
        nbook = self.create_wubook_booking(
            self.user_hotel_manager,
            checkin_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
            self.partner_2,
            {
                self.hotel_vroom_special.wrid: {
                    'occupancy': [2],   # 2 Reservation Line
                    'dayprices': [15.0, 15.0]   # 2 Days
                }
            }, channel=self.wubook_channel_test.wid)
        nbook['amount'] = 30.75
        wbooks = [nbook]
        processed_rids, errors, checkin_utc_dt, checkout_utc_dt = \
            self.env['wubook'].sudo().generate_reservations(wbooks)
        self.assertEqual(len(processed_rids), 1, "Reservation not found")
        self.assertFalse(errors, "Reservation errors")
        self.assertNotEqual(self.env['wubook.issue'].search_count([]), num_issues)
Пример #7
0
    def test_complex_booking(self):
        now_utc_dt = date_utils.now()
        checkin_utc_dt = now_utc_dt + timedelta(days=3)
        checkin_dt = date_utils.dt_as_timezone(checkin_utc_dt,
                                               self.tz_hotel)
        checkout_utc_dt = checkin_utc_dt + timedelta(days=2)
        date_diff = date_utils.date_diff(checkin_utc_dt, checkout_utc_dt,
                                         hours=False) + 1

        wbooks = [self.create_wubook_booking(
            self.user_hotel_manager,
            checkin_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
            self.partner_2,
            {
                self.hotel_vroom_budget.wrid: {
                    'occupancy': [1, 1],   # 2 Reservation Line
                    'dayprices': [15.0, 15.0]   # 2 Days
                }
            }
        )]
        processed_rids, errors, checkin_utc_dt, checkout_utc_dt = \
            self.env['wubook'].sudo().generate_reservations(wbooks)

        # Check Creation
        self.assertTrue(any(processed_rids), "Reservation not found")
        self.assertFalse(errors, "Reservation errors")
        nreservs = self.env['hotel.reservation'].search([
            ('wrid', 'in', processed_rids)
        ], order='id ASC')
        self.assertEqual(len(nreservs), 2, "Reservations not found")

        for nreserv in nreservs:
            # Check State
            self.assertEqual(nreserv.state, 'draft',
                             "Invalid reservation state")

            # Check Dates
            self.assertEqual(
                nreserv.checkin,
                checkin_utc_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
                "Invalid Checkin Reservation Date")
            self.assertEqual(
                nreserv.checkout,
                checkout_utc_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
                "Invalid Checkout Reservation Date")
            # Check Price
            self.assertEqual(nreserv.price_unit, 30.0,
                             "Invalid Reservation Price")
            # Check Reservation Lines
            self.assertTrue(any(nreserv.reservation_lines),
                            "Reservation lines snot found")
            dates_arr = date_utils.generate_dates_list(checkin_dt, date_diff-1)
            for k_line, v_line in enumerate(nreserv.reservation_lines):
                self.assertEqual(dates_arr[k_line], v_line['date'],
                                 "Invalid Reservation Lines Dates")
Пример #8
0
    def test_overbooking(self):
        now_utc_dt = date_utils.now()
        checkin_utc_dt = now_utc_dt + timedelta(days=3)
        checkin_dt = date_utils.dt_as_timezone(checkin_utc_dt, self.tz_hotel)

        # Invalid Occupancy
        wbooks = [
            self.create_wubook_booking(
                self.user_hotel_manager,
                checkin_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
                self.partner_2,
                {
                    self.hotel_vroom_budget.wrid: {
                        'occupancy': [1],
                        'dayprices': [15.0, 15.0]
                    }
                }
            ),
            self.create_wubook_booking(
                self.user_hotel_manager,
                checkin_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
                self.partner_2,
                {
                    self.hotel_vroom_budget.wrid: {
                        'occupancy': [1],
                        'dayprices': [15.0, 15.0]
                    }
                }
            ),
            self.create_wubook_booking(
                self.user_hotel_manager,
                checkin_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
                self.partner_2,
                {
                    self.hotel_vroom_budget.wrid: {
                        'occupancy': [1],
                        'dayprices': [15.0, 15.0]
                    }
                }
            )]
        processed_rids, errors, checkin_utc_dt, checkout_utc_dt = \
            self.env['wubook'].sudo().generate_reservations(wbooks)
        self.assertFalse(errors, "Overbooking don't handled")
        self.assertTrue(any(processed_rids), "Overbooking don't handled")
        nreservs = self.env['hotel.reservation'].search([
            ('wrid', 'in', processed_rids)
        ], order="id ASC")
        self.assertFalse(nreservs[0].overbooking,
                         "Overbooking don't handled")
        self.assertFalse(nreservs[1].overbooking,
                         "Overbooking don't handled")
        self.assertTrue(nreservs[2].overbooking,
                        "Overbooking don't handled")
Пример #9
0
    def test_write(self):
        now_utc_dt = date_utils.now()
        checkin_utc_dt = now_utc_dt + timedelta(days=3)
        checkin_dt = date_utils.dt_as_timezone(checkin_utc_dt,
                                               self.tz_hotel)
        checkout_utc_dt = checkin_utc_dt + timedelta(days=2)
        date_diff = date_utils.date_diff(checkin_utc_dt, checkout_utc_dt,
                                         hours=False) + 1

        wbooks = [
            self.create_wubook_booking(
                self.user_hotel_manager,
                checkin_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
                self.partner_2,
                {
                    self.hotel_room_type_budget.wrid: {
                        'occupancy': [1],
                        'dayprices': [15.0, 15.0]
                    }
                }
            ),
            self.create_wubook_booking(
                self.user_hotel_manager,
                checkin_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
                self.partner_1,
                {
                    self.hotel_room_type_budget.wrid: {
                        'occupancy': [1],
                        'dayprices': [15.0, 15.0]
                    }
                }
            )
        ]
        processed_rids, errors, checkin_utc_dt, checkout_utc_dt = \
            self.env['wubook'].sudo().generate_reservations(wbooks)
        self.assertTrue(any(processed_rids), "Reservation not found")
        self.assertFalse(errors, "Reservation errors")
        self.partner_2.sudo(self.user_hotel_manager).write({
            'vat': 'ES00000000T'
        })
        self.partner_1.sudo(self.user_hotel_manager).write({
            'vat': 'ES00000000T',
            'unconfirmed': True,
        })
        reservation = self.env['hotel.reservation'].search([
            ('wrid', '=', processed_rids[1])
        ], order='id ASC', limit=1)
        self.assertTrue(reservation, "Can't found reservation")
        self.assertFalse(self.partner_1.active, "Uncofirmed user still active")
        self.assertEqual(reservation.partner_id.id,
                         self.partner_2.id,
                         "Old Partner not changed")
Пример #10
0
    def test_complex_bookings(self):
        now_utc_dt = date_utils.now()
        checkin_utc_dt = now_utc_dt + timedelta(days=3)
        checkin_dt = date_utils.dt_as_timezone(checkin_utc_dt,
                                               self.tz_hotel)
        checkout_utc_dt = checkin_utc_dt + timedelta(days=2)
        date_diff = date_utils.date_diff(checkin_utc_dt, checkout_utc_dt,
                                         hours=False) + 1

        wbooks = [
            self.create_wubook_booking(
                self.user_hotel_manager,
                checkin_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
                self.partner_2,
                {
                    self.hotel_vroom_special.wrid: {
                        'occupancy': [2],   # 2 Reservation Line
                        'dayprices': [15.0, 15.0]   # 2 Days
                    }
                }
            ),
            self.create_wubook_booking(
                self.user_hotel_manager,
                (checkin_dt - timedelta(days=3)).strftime(
                                            DEFAULT_SERVER_DATETIME_FORMAT),
                self.partner_2,
                {
                    self.hotel_vroom_special.wrid: {
                        'occupancy': [2],   # 2 Reservation Line
                        'dayprices': [15.0, 15.0]   # 2 Days
                    }
                }
            ),
            self.create_wubook_booking(
                self.user_hotel_manager,
                (checkin_dt + timedelta(days=3)).strftime(
                                            DEFAULT_SERVER_DATETIME_FORMAT),
                self.partner_2,
                {
                    self.hotel_vroom_special.wrid: {
                        'occupancy': [2],   # 2 Reservation Line
                        'dayprices': [15.0, 15.0]   # 2 Days
                    }
                }
            )
        ]
        processed_rids, errors, checkin_utc_dt, checkout_utc_dt = \
            self.env['wubook'].sudo().generate_reservations(wbooks)
        self.assertEqual(len(processed_rids), 3, "Reservation not found")
        self.assertFalse(errors, "Reservation errors")
Пример #11
0
    def onchange_dates(self):
        for line in self:
            if not self.checkin:
                self.checkin = self.folio_wizard_id.checkin
            if not self.checkout:
                self.checkout = self.folio_wizard_id.checkout

            hotel_tz = self.env['ir.values'].sudo().get_default(
                'hotel.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)

            if line.virtual_room_id:
                pricelist_id = self.env['ir.values'].sudo().get_default(
                    'hotel.config.settings', 'parity_pricelist_id')
                if pricelist_id:
                    pricelist_id = int(pricelist_id)
                nights = days_diff = date_utils.date_diff(line.checkin,
                                                          line.checkout,
                                                          hours=False)
                res_price = 0
                res_partner = self.partner_id or self.env[
                    'res.partner'].browse('1')
                for i in range(0, nights):
                    ndate = start_date_dt + timedelta(days=i)
                    ndate_str = ndate.strftime(DEFAULT_SERVER_DATE_FORMAT)
                    prod = line.virtual_room_id.product_id.with_context(
                        lang=self.partner_id.lang,
                        partner=self.partner_id.id,
                        quantity=1,
                        date=ndate_str,
                        pricelist=pricelist_id,
                        uom=line.product_id.uom_id.id)
                    res_price += prod.price
                adults = self.env['hotel.room'].search([
                    ('product_id.id', '=', line.product_id.id)
                ]).capacity
                res_price = res_price - (res_price * self.discount) / 100
                line.amount_reservation = res_price
                line.price = res_price
            checkout_dt = date_utils.get_datetime(self.checkout)
            checkout_dt -= timedelta(days=1)
            occupied = self.env['hotel.reservation'].occupied(
                self.checkin, checkout_dt.strftime(DEFAULT_SERVER_DATE_FORMAT))
            rooms_occupied = occupied.mapped('product_id.id')
            domain_rooms = [('isroom', '=', True),
                            ('id', 'not in', rooms_occupied)]
            return {'domain': {'product_id': domain_rooms}}
Пример #12
0
    def onchange_checks(self):
        '''
        When you change checkin or checkout it will checked it
        and update the qty of hotel folio line
        -----------------------------------------------------------------
        @param self: object pointer
        '''
        self.ensure_one()
        now_utc_dt = date_utils.now()
        if not self.checkin:
            self.checkin = time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
        if not self.checkout:
            self.checkout = time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)

        # UTC -> Hotel tz
        tz = self.env['ir.values'].get_default('hotel.config.settings',
                                               'tz_hotel')
        chkin_utc_dt = date_utils.get_datetime(self.checkin)
        chkout_utc_dt = date_utils.get_datetime(self.checkout)

        if chkin_utc_dt >= chkout_utc_dt:
            dpt_hour = self.env['ir.values'].get_default(
                'hotel.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)
        virtual_room_ids = self.env['hotel.virtual.room'].search([])
        virtual_rooms = []

        for virtual in virtual_room_ids:
            virtual_rooms.append((0, False, {
                'virtual_room_id': virtual.id,
                'checkin': self.checkin,
                'checkout': self.checkout,
                'folio_wizard_id': self.id,
            }))
        self.virtual_room_wizard_ids = virtual_rooms
        for virtual in self.virtual_room_wizard_ids:
            virtual.update_price()
Пример #13
0
 def _get_default_checkout(self):
     folio = False
     default_departure_hour = self.env['ir.values'].get_default(
         'hotel.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.values'].get_default(
             'hotel.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)
    def test_save_changes(self):
        now_utc_dt = date_utils.now()
        adv_utc_dt = now_utc_dt + timedelta(days=3)
        room_types = (self.hotel_room_type_budget, )

        hotel_cal_mngt_obj = self.env['hotel.calendar.management'].sudo(
            self.user_hotel_manager)

        # Generate new prices
        prices = (144.0, 170.0, 30.0, 50.0)
        cprices = {}
        for k_item, v_item in enumerate(prices):
            ndate_utc_dt = now_utc_dt + timedelta(days=k_item)
            cprices.setdefault(self.hotel_room_type_budget.id, []).append({
                'date':
                ndate_utc_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
                'price':
                v_item
            })

        # Generate new restrictions
        restrictions = {
            'min_stay': (3, 2, 4, 1),
            'max_stay': (5, 8, 9, 3),
            'min_stay_arrival': (2, 3, 6, 2),
            'max_stay_arrival': (4, 7, 7, 4),
            'closed_departure': (False, True, False, True),
            'closed_arrival': (True, False, False, False),
            'closed': (False, False, True, True),
        }
        crestrictions = {}
        for i in range(0, 4):
            ndate_utc_dt = now_utc_dt + timedelta(days=i)
            crestrictions.setdefault(
                self.hotel_room_type_budget.id, []).append({
                    'date':
                    ndate_utc_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
                    'closed_arrival':
                    restrictions['closed_arrival'][i],
                    'max_stay':
                    restrictions['max_stay'][i],
                    'min_stay':
                    restrictions['min_stay'][i],
                    'closed_departure':
                    restrictions['closed_departure'][i],
                    'closed':
                    restrictions['closed'][i],
                    'min_stay_arrival':
                    restrictions['min_stay_arrival'][i],
                    'max_stay_arrival':
                    restrictions['max_stay_arrival'][i],
                })

        # Generate new availability
        avails = (1, 2, 2, 1)
        cavails = {}
        for k_item, v_item in enumerate(avails):
            ndate_utc_dt = now_utc_dt + timedelta(days=k_item)
            ndate_dt = date_utils.dt_as_timezone(ndate_utc_dt, self.tz_hotel)
            cavails.setdefault(self.hotel_room_type_budget.id, []).append({
                'date':
                ndate_dt.strftime(DEFAULT_SERVER_DATE_FORMAT),
                'avail':
                v_item,
                'no_ota':
                False,
            })

        # Save new values
        hotel_cal_mngt_obj.save_changes(self.parity_pricelist_id,
                                        self.parity_restrictions_id, cprices,
                                        crestrictions, cavails)

        # Check data integrity
        hcal_data = hotel_cal_mngt_obj.get_hcalendar_all_data(
            now_utc_dt.strftime(DEFAULT_SERVER_DATE_FORMAT),
            adv_utc_dt.strftime(DEFAULT_SERVER_DATE_FORMAT),
            self.parity_pricelist_id, self.parity_restrictions_id, True)

        for room_type in room_types:
            for k_pr, v_pr in hcal_data['availability'].iteritems():
                if k_pr == room_type.id:  # Only Check Test Cases
                    for k_info, v_info in enumerate(v_pr):
                        self.assertEqual(
                            v_info['avail'], avails[k_info],
                            "Hotel Calendar Management \
                                                Availability doesn't match!")
            for k_pr, v_pr in hcal_data['restrictions'].iteritems():
                if k_pr == room_type.id:  # Only Check Test Cases
                    for k_info, v_info in enumerate(v_pr):
                        self.assertEqual(
                            v_info['min_stay'],
                            restrictions['min_stay'][k_info],
                            "Hotel Calendar Management \
                                                Restrictions doesn't match!")
                        self.assertEqual(
                            v_info['max_stay'],
                            restrictions['max_stay'][k_info],
                            "Hotel Calendar Management \
                                                Restrictions doesn't match!")
                        self.assertEqual(
                            v_info['min_stay_arrival'],
                            restrictions['min_stay_arrival'][k_info],
                            "Hotel Calendar Management Restrictions \
                                                            doesn't match!")
                        self.assertEqual(
                            v_info['max_stay_arrival'],
                            restrictions['max_stay_arrival'][k_info],
                            "Hotel Calendar Management Restrictions \
                                                            doesn't match!")
                        self.assertEqual(
                            v_info['closed_departure'],
                            restrictions['closed_departure'][k_info],
                            "Hotel Calendar Management Restrictions \
                                                            doesn't match!")
                        self.assertEqual(
                            v_info['closed_arrival'],
                            restrictions['closed_arrival'][k_info],
                            "Hotel Calendar Management Restrictions \
                                                            doesn't match!")
                        self.assertEqual(
                            v_info['closed'], restrictions['closed'][k_info],
                            "Hotel Calendar Management Restrictions \
                                                            doesn't match!")
            for k_pr, v_pr in hcal_data['prices'].iteritems():
                if k_pr == room_type.id:  # Only Check Test Cases
                    for k_info, v_info in enumerate(v_pr):
                        self.assertEqual(
                            v_info['price'], prices[k_info], "Hotel Calendar \
                                            Management Prices doesn't match!")
Пример #15
0
    def create_wubook_booking(self,
                              creator,
                              checkin,
                              partner,
                              rinfo,
                              channel=0,
                              notes='',
                              brooms_ancillary=None):
        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 = []
        vroom_obj = self.env['hotel.virtual.room']
        max_persons = 0
        for k_room, v_room in rinfo.iteritems():
            vroom = vroom_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': vroom.name,
                        'addons': [],
                        'guests': val
                    },
                    'room_id': k_room,
                    'roomdays': roomdays
                })
                if brooms_ancillary:
                    booked_rooms[len(booked_rooms) -
                                 1]['ancillary'].update(brooms_ancillary)
                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'
        }
Пример #16
0
    def test_splitted_booking(self):
        now_utc_dt = date_utils.now()
        checkin_utc_dt = now_utc_dt + timedelta(days=3)
        checkin_dt = date_utils.dt_as_timezone(checkin_utc_dt,
                                               self.tz_hotel)
        checkout_utc_dt = checkin_utc_dt + timedelta(days=2)
        date_diff = date_utils.date_diff(checkin_utc_dt, checkout_utc_dt,
                                         hours=False) + 1

        book_a = self.create_wubook_booking(
            self.user_hotel_manager,
            checkin_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
            self.partner_2,
            {
                self.hotel_vroom_budget.wrid: {
                    'occupancy': [1],
                    'dayprices': [15.0, 15.0]
                }
            }
        )
        book_b = self.create_wubook_booking(
            self.user_hotel_manager,
            (checkin_dt + timedelta(days=2)).strftime(
                                        DEFAULT_SERVER_DATETIME_FORMAT),
            self.partner_2,
            {
                self.hotel_vroom_budget.wrid: {
                    'occupancy': [1],
                    'dayprices': [15.0, 15.0]
                }
            }
        )
        wbooks = [book_a, book_b]
        processed_rids, errors, checkin_utc_dt, checkout_utc_dt = \
            self.env['wubook'].sudo().generate_reservations(wbooks)
        self.assertEqual(len(processed_rids), 2, "Reservation not found")
        self.assertFalse(errors, "Reservation errors")
        reserv = self.env['hotel.reservation'].search([
            ('wrid', '=', book_b['reservation_code'])
        ], order='id ASC', limit=1)
        self.assertTrue(reserv, "Rervation doesn't exists")
        self.assertEqual(
            reserv.product_id.id,
            self.hotel_room_simple_100.product_id.id,
            "Unexpected room assigned")
        reserv.product_id = \
            self.hotel_room_simple_101.product_id.id

        wbooks = [
            self.create_wubook_booking(
                self.user_hotel_manager,
                checkin_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
                self.partner_2,
                {
                    self.hotel_vroom_budget.wrid: {
                        'occupancy': [1],
                        'dayprices': [15.0, 15.0, 20.0, 17.0]
                    }
                }
            )
        ]
        processed_rids, errors, checkin_utc_dt, checkout_utc_dt = \
            self.env['wubook'].sudo().generate_reservations(wbooks)
        self.assertEqual(len(processed_rids), 1, "Reservation not found")
        self.assertFalse(errors, "Reservation errors")

        # Check Splitted Integrity
        nreservs = self.env['hotel.reservation'].search([
            ('wrid', 'in', processed_rids)
        ], order="id ASC")
        _logger.info(nreservs)
        self.assertEqual(len(nreservs), 2, "Reservations not found")
        date_dt = date_utils.get_datetime(nreservs[0].checkin)
        self.assertEqual(nreservs[0].reservation_lines[0].date,
                         date_dt.strftime(DEFAULT_SERVER_DATE_FORMAT),
                         "Invalid split")
        date_dt = date_utils.get_datetime(nreservs[1].checkin)
        self.assertEqual(nreservs[1].reservation_lines[0].date,
                         date_dt.strftime(DEFAULT_SERVER_DATE_FORMAT),
                         "Invalid split")
        self.assertEqual(nreservs[0].price_unit,
                         30.0,
                         "Invalid split price")
        self.assertEqual(nreservs[1].price_unit,
                         37.0,
                         "Invalid split price")
        self.assertEqual(nreservs[1].parent_reservation.id,
                         nreservs[0].id,
                         "Invalid split parent reservation")
        self.assertEqual(nreservs[0].product_id.id,
                         self.hotel_room_simple_101.product_id.id,
                         "Invalid room assigned")
        self.assertEqual(nreservs[1].product_id.id,
                         self.hotel_room_simple_100.product_id.id,
                         "Invalid room assigned")
Пример #17
0
 def create_reservations(self):
     self.ensure_one()
     total = 0
     cmds = []
     for line in self.virtual_room_wizard_ids:
         if line.rooms_num == 0:
             continue
         if line.rooms_num > line.max_rooms:
             raise ValidationError(_("Too many rooms!"))
         elif line.virtual_room_id:
             checkout_dt = date_utils.get_datetime(line.checkout)
             occupied = self.env['hotel.reservation'].occupied(
                 line.checkin,
                 checkout_dt.strftime(DEFAULT_SERVER_DATE_FORMAT))
             rooms_occupied = occupied.mapped('product_id.id')
             free_rooms = self.env['hotel.room'].search(
                 [('product_id.id', 'not in', rooms_occupied),
                  ('price_virtual_room.id', '=', line.virtual_room_id.id)],
                 order='sequence',
                 limit=line.rooms_num)
             room_ids = free_rooms.mapped('product_id.id')
             product_list = self.env['product.product'].search([('id', 'in',
                                                                 room_ids)])
             nights = days_diff = date_utils.date_diff(line.checkin,
                                                       line.checkout,
                                                       hours=False)
             hotel_tz = self.env['ir.values'].sudo().get_default(
                 'hotel.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)
             for room in product_list:
                 pricelist_id = self.env['ir.values'].sudo().get_default(
                     'hotel.config.settings', 'parity_pricelist_id')
                 if pricelist_id:
                     pricelist_id = int(pricelist_id)
                 res_price = 0
                 res_partner = self.partner_id or self.env[
                     'res.partner'].browse('1')
                 for i in range(0, nights):
                     ndate = start_date_dt + timedelta(days=i)
                     ndate_str = ndate.strftime(DEFAULT_SERVER_DATE_FORMAT)
                     prod = line.virtual_room_id.product_id.with_context(
                         lang=self.partner_id.lang,
                         partner=self.partner_id.id,
                         quantity=1,
                         date=ndate_str,
                         pricelist=pricelist_id,
                         uom=room.uom_id.id)
                     res_price += prod.price
                 adults = self.env['hotel.room'].search([
                     ('product_id.id', '=', room.id)
                 ]).capacity
                 res_price = res_price - (res_price * line.discount) / 100
                 total += res_price
                 cmds.append((0, False, {
                     'checkin': line.checkin,
                     'checkout': line.checkout,
                     'discount': line.discount,
                     'product_id': room.id,
                     'nights': nights,
                     'adults': adults,
                     'children': 0,
                     'virtual_room_id': line.virtual_room_id,
                     'price': res_price,
                     'amount_reservation': res_price
                 }))
     self.reservation_wizard_ids = cmds
     self.total = total
Пример #18
0
    def test_generate_room_values(self):
        now_utc_dt = date_utils.now()
        checkin_utc_dt = now_utc_dt + timedelta(days=3)
        checkin_dt = date_utils.dt_as_timezone(checkin_utc_dt,
                                               self.tz_hotel)
        checkout_utc_dt = checkin_utc_dt + timedelta(days=1)
        checkout_dt = date_utils.dt_as_timezone(checkout_utc_dt,
                                                self.tz_hotel)
        vroom_restr_item_obj = self.env['hotel.virtual.room.restriction.item']

        vrooms = [self.hotel_vroom_budget, self.hotel_vroom_special]
        values = self.create_wubook_rooms_values(
            vrooms,
            [{
                'closed_arrival': 0,
                'booked': 0,
                'max_stay_arrival': 9,
                'max_stay': 0,
                'price': 150.0,
                'min_stay': 0,
                'closed_departure': '1',
                'avail': 0,
                'closed': 0,
                'min_stay_arrival': 0,
                'no_ota': 0,
            }, {
                'closed_arrival': 0,
                'booked': 0,
                'max_stay_arrival': 9,
                'max_stay': 0,
                'price': 50.0,
                'min_stay': 0,
                'closed_departure': '1',
                'avail': 0,
                'closed': 0,
                'min_stay_arrival': 0,
                'no_ota': 0,
            }])
        self.env['wubook'].sudo().generate_room_values(
            checkin_dt.strftime(DEFAULT_WUBOOK_DATE_FORMAT),
            checkout_dt.strftime(DEFAULT_WUBOOK_DATE_FORMAT),
            values)

        for vroom in vrooms:
            items = vroom_restr_item_obj.search([
                ('virtual_room_id', '=', vroom.id),
                ('date_start',
                 '>=', checkin_dt.strftime(DEFAULT_SERVER_DATE_FORMAT)),
                ('date_end',
                 '<=', checkout_dt.strftime(DEFAULT_SERVER_DATE_FORMAT)),
                ('restriction_id', '=', self.restriction_default_id)
            ])
            self.assertTrue(any(items),
                            "Hotel Wubook Invalid fetch room values")
            for item in items:
                self.assertTrue(
                    item.closed_departure,
                    "Hotel Wubook Invalid fetch room values")
                self.assertEqual(
                    item.max_stay_arrival,
                    9,
                    "Hotel Wubook Invalid fetch room values")
Пример #19
0
    def test_cancel_booking(self):
        now_utc_dt = date_utils.now()
        checkin_utc_dt = now_utc_dt + timedelta(days=3)
        checkin_dt = date_utils.dt_as_timezone(checkin_utc_dt,
                                               self.tz_hotel)
        checkout_utc_dt = checkin_utc_dt + timedelta(days=2)
        date_diff = date_utils.date_diff(checkin_utc_dt, checkout_utc_dt,
                                         hours=False) + 1

        def check_state(wrids, state):
            reservs = self.env['hotel.reservation'].sudo().search([
                    ('wrid', 'in', wrids)
                ])
            self.assertTrue(any(reservs), "Reservations not found")
            for reserv in reservs:
                self.assertEqual(
                        reserv.state, state, "Reservation state invalid")

        # Create Reservation
        nbook = self.create_wubook_booking(
            self.user_hotel_manager,
            checkin_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
            self.partner_2,
            {
                self.hotel_vroom_special.wrid: {
                    'occupancy': [2],   # 2 Reservation Line
                    'dayprices': [15.0, 15.0]   # 2 Days
                }
            }, channel=self.wubook_channel_test.wid)
        wbooks = [nbook]
        processed_rids, errors, checkin_utc_dt, checkout_utc_dt = \
            self.env['wubook'].sudo().generate_reservations(wbooks)
        self.assertEqual(len(processed_rids), 1, "Reservation not found")
        self.assertFalse(errors, "Reservation errors")

        # Cancel It
        wbooks = [self.cancel_booking(nbook)]
        processed_rids, errors, checkin_utc_dt, checkout_utc_dt = \
            self.env['wubook'].sudo().generate_reservations(wbooks)
        self.assertEqual(len(processed_rids), 1, "Reservation not found")
        self.assertFalse(errors, "Reservation errors")
        check_state(processed_rids, 'cancelled')
        # Can't confirm cancelled bookings
        reserv = self.env['hotel.reservation'].sudo().search([
            ('wrid', 'in', processed_rids)
        ], limit=1)
        with self.assertRaises(ValidationError):
            reserv.confirm()

        # Create Reservation and Cancel It
        nbook = self.create_wubook_booking(
            self.user_hotel_manager,
            checkin_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
            self.partner_2,
            {
                self.hotel_vroom_special.wrid: {
                    'occupancy': [2],   # 2 Reservation Line
                    'dayprices': [15.0, 15.0]   # 2 Days
                }
            })
        cbook = self.cancel_booking(nbook)
        wbooks = [nbook, cbook]
        processed_rids, errors, checkin_utc_dt, checkout_utc_dt = \
            self.env['wubook'].sudo().generate_reservations(wbooks)
        self.assertEqual(len(processed_rids), 2, "Reservation not found")
        self.assertFalse(errors, "Reservation errors")
        check_state(processed_rids, 'cancelled')
Пример #20
0
    def _generate_reservations(self, bookings):
        _logger.info("=== BOOKINGS FROM WUBOOK")
        _logger.info(bookings)
        default_arrival_hour = self.env['ir.default'].sudo().get(
            'res.config.settings', 'default_arrival_hour')
        default_departure_hour = self.env['ir.default'].sudo().get(
            'res.config.settings', 'default_departure_hour')

        # Get user timezone
        tz_hotel = self.env['ir.default'].sudo().get('res.config.settings',
                                                     'tz_hotel')
        res_partner_obj = self.env['res.partner']
        channel_reserv_obj = self.env['channel.hotel.reservation']
        hotel_reserv_obj = self.env['hotel.reservation']
        hotel_folio_obj = self.env['hotel.folio']
        channel_room_type_obj = self.env['channel.hotel.room.type']
        hotel_room_type_obj = self.env['hotel.room.type']
        # Space for store some data for construct folios
        processed_rids = []
        failed_reservations = []
        checkin_utc_dt = False
        checkout_utc_dt = False
        split_booking = False
        for book in bookings:  # This create a new folio
            splitted_map = {}
            is_cancellation = book['status'] in WUBOOK_STATUS_BAD
            bstatus = str(book['status'])
            rcode = str(book['reservation_code'])
            crcode = str(book['channel_reservation_code']) \
                if book['channel_reservation_code'] else 'undefined'

            # Can't process failed reservations
            #  (for example set a invalid new reservation and receive in
            # the same transaction an cancellation)
            if crcode in failed_reservations:
                self.create_issue(
                    'reservation',
                    "Can't process a reservation that previusly failed!",
                    '',
                    channel_object_id=book['reservation_code'])
                continue

            # Get dates for the reservation (GMT->UTC)
            arr_hour = default_arrival_hour if book['arrival_hour'] == "--" \
                else book['arrival_hour']
            checkin = "%s %s" % (book['date_arrival'], arr_hour)
            checkin_dt = date_utils.get_datetime(
                checkin, dtformat=DEFAULT_WUBOOK_DATETIME_FORMAT, stz=tz_hotel)
            checkin_utc_dt = date_utils.dt_as_timezone(checkin_dt, 'UTC')
            checkin = checkin_utc_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT)

            checkout = "%s %s" % (book['date_departure'],
                                  default_departure_hour)
            checkout_dt = date_utils.get_datetime(
                checkout,
                dtformat=DEFAULT_WUBOOK_DATETIME_FORMAT,
                stz=tz_hotel)
            checkout_utc_dt = date_utils.dt_as_timezone(checkout_dt, 'UTC')
            checkout = checkout_utc_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT)

            # Search Folio. If exists.
            folio_id = False
            if crcode != 'undefined':
                reserv_folio = channel_reserv_obj.search(
                    [('ota_reservation_id', '=', crcode)], limit=1)
                if reserv_folio:
                    folio_id = reserv_folio.odoo_id.folio_id
            else:
                reserv_folio = channel_reserv_obj.search(
                    [('channel_reservation_id', '=', rcode)], limit=1)
                if reserv_folio:
                    folio_id = reserv_folio.odoo_id.folio_id

            # Need update reservations?
            sreservs = channel_reserv_obj.search([('channel_reservation_id',
                                                   '=', rcode)])
            reservs = folio_id.room_lines if folio_id else sreservs.mapped(
                lambda x: x.odoo_id)
            reservs_processed = False
            if any(reservs):
                folio_id = reservs[0].folio_id
                for reserv in reservs:
                    if reserv.channel_reservation_id == rcode:
                        binding_id = reserv.channel_bind_ids[0]
                        binding_id.write({
                            'channel_raw_data':
                            json.dumps(book),
                            'wstatus':
                            str(book['status']),
                            'wstatus_reason':
                            book.get('status_reason', ''),
                        })
                        reserv.with_context({
                            'wubook_action': False
                        }).write({
                            'to_read': True,
                            'to_assign': True,
                            'price_unit': book['amount'],
                            'customer_notes': book['customer_notes'],
                        })
                        if reserv.partner_id.unconfirmed:
                            reserv.partner_id.write(
                                self._generate_partner_vals(book))
                        reservs_processed = True
                        if is_cancellation:
                            reserv.with_context({
                                'wubook_action': False
                            }).action_cancel()
                        elif reserv.state == 'cancelled':
                            reserv.with_context({
                                'wubook_action': False,
                            }).write({
                                'discount': 0.0,
                                'state': 'confirm',
                            })

            # Do Nothing if already processed 'wrid'
            if reservs_processed:
                processed_rids.append(rcode)
                continue

            # Search Customer
            customer_mail = book.get('customer_mail', False)
            partner_id = False
            if customer_mail:
                partner_id = res_partner_obj.search(
                    [('email', '=', customer_mail)], limit=1)
            if not partner_id:
                partner_id = res_partner_obj.create(
                    self._generate_partner_vals(book))

            # Search Wubook Channel Info
            channel_info = self.env['hotel.channel.connector.ota.info'].search(
                [('ota_id', '=', str(book['id_channel']))], limit=1)

            reservations = []
            used_rooms = []
            # Iterate booked rooms
            for broom in book['booked_rooms']:
                room_type = channel_room_type_obj.search(
                    [('channel_room_id', '=', broom['room_id'])], limit=1)
                if not room_type:
                    self.create_issue(
                        'reservation',
                        "Can't found any room type associated to '%s' \
                                                in this hotel" % book['rooms'],
                        '',
                        channel_object_id=book['reservation_code'])
                    failed_reservations.append(crcode)
                    continue

                dates_checkin = [checkin_utc_dt, False]
                dates_checkout = [checkout_utc_dt, False]
                split_booking = False
                split_booking_parent = False
                # This perhaps create splitted reservation
                while dates_checkin[0]:
                    checkin_str = dates_checkin[0].strftime(
                        DEFAULT_SERVER_DATETIME_FORMAT)
                    checkout_str = dates_checkout[0].strftime(
                        DEFAULT_SERVER_DATETIME_FORMAT)
                    vals = self._generate_booking_vals(
                        broom,
                        checkin_str,
                        checkout_str,
                        is_cancellation,
                        channel_info,
                        bstatus,
                        crcode,
                        rcode,
                        room_type.odoo_id,
                        split_booking,
                        dates_checkin,
                        dates_checkout,
                        book,
                    )
                    if vals['price_unit'] != book['amount']:
                        self.create_issue(
                            'reservation',
                            "Invalid reservation total price! %.2f != %.2f" %
                            (vals['price_unit'], book['amount']),
                            '',
                            channel_object_id=book['reservation_code'])

                    free_rooms = room_type.odoo_id.check_availability_room(
                        checkin_str,
                        checkout_str,
                        room_type_id=room_type.odoo_id.id,
                        notthis=used_rooms)
                    if any(free_rooms):
                        vals.update({
                            'product_id': free_rooms[0].product_id.id,
                            'name': free_rooms[0].name,
                        })
                        reservations.append((0, False, vals))
                        used_rooms.append(free_rooms[0].id)

                        if split_booking:
                            if not split_booking_parent:
                                split_booking_parent = len(reservations)
                            else:
                                splitted_map.setdefault(
                                    split_booking_parent,
                                    []).append(len(reservations))
                        dates_checkin = [dates_checkin[1], False]
                        dates_checkout = [dates_checkout[1], False]
                    else:
                        date_diff = (
                            dates_checkout[0].replace(
                                hour=0, minute=0, second=0, microsecond=0) -
                            dates_checkin[0].replace(
                                hour=0, minute=0, second=0,
                                microsecond=0)).days
                        if date_diff <= 0:
                            if split_booking:
                                if split_booking_parent:
                                    del reservations[split_booking_parent - 1:]
                                    if split_booking_parent in splitted_map:
                                        del splitted_map[split_booking_parent]
                            # Can't found space for reservation
                            vals = self._generate_booking_vals(
                                broom,
                                checkin_utc_dt,
                                checkout_utc_dt,
                                is_cancellation,
                                channel_info,
                                bstatus,
                                crcode,
                                rcode,
                                room_type.odoo_id,
                                False,
                                (checkin_utc_dt, False),
                                (checkout_utc_dt, False),
                                book,
                            )
                            vals.update({
                                'product_id':
                                room_type.odoo_id.room_ids[0].product_id.id,
                                'name':
                                room_type.odoo_id.name,
                                'overbooking':
                                True,
                            })
                            reservations.append((0, False, vals))
                            self.create_issue(
                                'reservation',
                                "Reservation imported with overbooking state",
                                '',
                                channel_object_id=rcode)
                            dates_checkin = [False, False]
                            dates_checkout = [False, False]
                            split_booking = False
                        else:
                            split_booking = True
                            dates_checkin = [
                                dates_checkin[0], dates_checkin[0] +
                                timedelta(days=date_diff - 1)
                            ]
                            dates_checkout = [
                                dates_checkout[0] - timedelta(days=1),
                                checkout_utc_dt
                            ]

            if split_booking:
                self.create_issue('reservation',
                                  "Reservation Splitted",
                                  '',
                                  channel_object_id=rcode)

            # Create Folio
            if not any(failed_reservations) and any(reservations):
                try:
                    # TODO: Improve 'addons_list' & discounts
                    addons = str(book['addons_list']) if any(
                        book['addons_list']) else ''
                    discounts = book.get('discount', '')
                    vals = {
                        'room_lines':
                        reservations,
                        'wcustomer_notes':
                        "%s\nADDONS:\n%s\nDISCOUNT:\n%s" %
                        (book['customer_notes'], addons, discounts),
                        'channel_type':
                        'web',
                    }
                    _logger.info("=== FOLIO CREATE")
                    _logger.info(reservations)
                    if folio_id:
                        folio_id.with_context({
                            'wubook_action': False
                        }).write(vals)
                    else:
                        vals.update({
                            'partner_id': partner_id.id,
                            'wseed': book['sessionSeed']
                        })
                        folio_id = hotel_folio_obj.with_context({
                            'wubook_action':
                            False
                        }).create(vals)

                    # Update Reservation Spitted Parents
                    sorted_rlines = folio_id.room_lines.sorted(key='id')
                    for k_pid, v_pid in splitted_map.iteritems():
                        preserv = sorted_rlines[k_pid - 1]
                        for pid in v_pid:
                            creserv = sorted_rlines[pid - 1]
                            creserv.parent_reservation = preserv.id

                    processed_rids.append(rcode)
                except ChannelConnectorError as err:
                    self.create_issue('reservation',
                                      err.data['message'],
                                      '',
                                      channel_object_id=rcode)
                    failed_reservations.append(crcode)
        return (processed_rids, any(failed_reservations), checkin_utc_dt,
                checkout_utc_dt)
Пример #21
0
    def test_invalid_booking(self):
        now_utc_dt = date_utils.now()
        checkin_utc_dt = now_utc_dt + timedelta(days=3)
        checkin_dt = date_utils.dt_as_timezone(checkin_utc_dt,
                                               self.tz_hotel)
        checkout_utc_dt = checkin_utc_dt + timedelta(days=2)
        date_diff = date_utils.date_diff(checkin_utc_dt, checkout_utc_dt,
                                         hours=False) + 1

        # Invalid Occupancy
        wbooks = [self.create_wubook_booking(
            self.user_hotel_manager,
            checkin_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
            self.partner_2,
            {
                self.hotel_vroom_budget.wrid: {
                    'occupancy': [3],
                    'dayprices': [15.0, 15.0]
                }
            }
        )]
        processed_rids, errors, checkin_utc_dt, checkout_utc_dt = \
            self.env['wubook'].sudo().generate_reservations(wbooks)
        self.assertTrue(errors, "Invalid reservation created")
        self.assertFalse(any(processed_rids), "Invalid reservation created")

        # No Real Rooms Avail
        wbooks = [self.create_wubook_booking(
            self.user_hotel_manager,
            checkin_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
            self.partner_2,
            {
                self.hotel_vroom_special.wrid: {
                    'occupancy': [2, 1],
                    'dayprices': [15.0, 15.0]
                }
            }
        )]
        processed_rids, errors, checkin_utc_dt, checkout_utc_dt = \
            self.env['wubook'].sudo().generate_reservations(wbooks)
        self.assertFalse(errors, "Invalid reservation created")
        self.assertTrue(any(processed_rids), "Invalid reservation created")

        nreservs = self.env['hotel.reservation'].search([
            ('wrid', 'in', processed_rids)
        ], order='id ASC')

        self.assertEqual(nreservs[0].state,
                         'draft',
                         "Overbooking don't handled")
        self.assertTrue(nreservs[1].overbooking,
                        "Overbooking don't handled")

        # No Real Rooms Avail
        wbooks = [
            self.create_wubook_booking(
                self.user_hotel_manager,
                checkin_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
                self.partner_2,
                {
                    self.hotel_vroom_special.wrid: {
                        'occupancy': [2],   # 2 Reservation Line
                        'dayprices': [15.0, 15.0]   # 2 Days
                    }
                }
            ),
            self.create_wubook_booking(
                self.user_hotel_manager,
                (checkin_dt - timedelta(days=1)).strftime(
                                            DEFAULT_SERVER_DATETIME_FORMAT),
                self.partner_2,
                {
                    self.hotel_vroom_special.wrid: {
                        'occupancy': [2],   # 2 Reservation Line
                        'dayprices': [15.0, 15.0]   # 2 Days
                    }
                }
            ),
            self.create_wubook_booking(
                self.user_hotel_manager,
                (checkin_dt + timedelta(days=1)).strftime(
                                            DEFAULT_SERVER_DATETIME_FORMAT),
                self.partner_2,
                {
                    self.hotel_vroom_special.wrid: {
                        'occupancy': [2],   # 2 Reservation Line
                        'dayprices': [15.0, 15.0]   # 2 Days
                    }
                }
            ),
        ]

        processed_rids, errors, checkin_utc_dt, checkout_utc_dt = \
            self.env['wubook'].sudo().generate_reservations(wbooks)
        self.assertEqual(len(processed_rids), 3, "Invalid Reservation created")
        self.assertFalse(errors, "Invalid Reservation created")
        nreservs = self.env['hotel.reservation'].search([
            ('wrid', 'in', processed_rids)
        ], order='id ASC')
        for nreserv in nreservs:
            self.assertTrue(nreserv.overbooking, "Overbooking don't handled")