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 vrooms = self.env['hotel.virtual.room'].search([]) json_data = {} for vroom in vrooms: json_data[vroom.id] = [] for i in range(0, date_diff): cur_date = date_start + timedelta(days=i) cur_date_str = cur_date.strftime(DEFAULT_SERVER_DATE_FORMAT) avail = self.env['hotel.virtual.room.availability'].search([ ('date', '=', cur_date_str), ('virtual_room_id', '=', vroom.id) ]) if avail: json_data[vroom.id].append({ 'id': avail.id, 'date': avail.date, 'avail': avail.avail, 'no_ota': avail.no_ota, }) else: json_data[vroom.id].append({ 'id': False, 'date': cur_date_str, 'avail': vroom.max_real_rooms, 'no_ota': False, }) return json_data
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")
def _hcalendar_get_count_reservations_json_data(self, dfrom, dto): vrooms = self.env['hotel.virtual.room'].search([]) date_start = date_utils.get_datetime(dfrom, hours=False) date_diff = date_utils.date_diff(dfrom, dto, hours=False) + 1 hotel_vroom_obj = self.env['hotel.virtual.room'] vrooms = hotel_vroom_obj.search([]) json_data = {} for vroom in vrooms: for i in range(0, date_diff): cur_date = date_start + timedelta(days=i) cur_date_str = cur_date.strftime(DEFAULT_SERVER_DATE_FORMAT) json_data.setdefault(vroom.id, []).append({ 'date': cur_date_str, 'num': len( hotel_vroom_obj.check_availability_virtual_room( cur_date_str, cur_date_str, virtual_room_id=vroom.id)), }) return json_data
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")
def _can_confirm(self): for vroom in self: date_start = date_utils.get_datetime(vroom.checkin) date_end = date_utils.get_datetime(vroom.checkout) date_diff = date_utils.date_diff(date_start, date_end, hours=False) if vroom.max_rooms > 0 and vroom.min_stay <= date_diff: vroom.can_confirm = True else: vroom.can_confirm = False
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
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")
def _generate_pricelist_items(self, channel_plan_id, date_from, date_to, plan_prices): hotel_room_type_obj = self.env['hotel.room.type'] pricelist = self.env['product.pricelist'].search( [('wpid', '=', channel_plan_id)], limit=1) if pricelist: pricelist_item_obj = self.env['product.pricelist.item'] dfrom_dt = date_utils.get_datetime(date_from) dto_dt = date_utils.get_datetime(date_to) days_diff = date_utils.date_diff(dfrom_dt, dto_dt, hours=False) + 1 for i in range(0, days_diff): ndate_dt = dfrom_dt + timedelta(days=i) for k_rid, v_rid in plan_prices.iteritems(): room_type = hotel_room_type_obj.search( [('wrid', '=', k_rid)], limit=1) if room_type: pricelist_item = pricelist_item_obj.search( [('pricelist_id', '=', pricelist.id), ('date_start', '=', ndate_dt.strftime(DEFAULT_SERVER_DATE_FORMAT)), ('date_end', '=', ndate_dt.strftime(DEFAULT_SERVER_DATE_FORMAT)), ('compute_price', '=', 'fixed'), ('applied_on', '=', '1_product'), ('product_tmpl_id', '=', room_type.product_id.product_tmpl_id.id)], limit=1) vals = { 'fixed_price': plan_prices[k_rid][i], 'wpushed': True, } if pricelist_item: pricelist_item.with_context({ 'wubook_action': False }).write(vals) else: vals.update({ 'pricelist_id': pricelist.id, 'date_start': ndate_dt.strftime(DEFAULT_SERVER_DATE_FORMAT), 'date_end': ndate_dt.strftime(DEFAULT_SERVER_DATE_FORMAT), 'compute_price': 'fixed', 'applied_on': '1_product', 'product_tmpl_id': room_type.product_id.product_tmpl_id.id }) pricelist_item_obj.with_context({ 'wubook_action': False }).create(vals) return True
def push_priceplans(self): unpushed = self.env['product.pricelist.item'].search( [('wpushed', '=', False), ('date_start', '>=', date_utils.now( hours=False).strftime(DEFAULT_SERVER_DATE_FORMAT))], order="date_start ASC") if any(unpushed): date_start = date_utils.get_datetime( unpushed[0].date_start, dtformat=DEFAULT_SERVER_DATE_FORMAT) date_end = date_utils.get_datetime( unpushed[-1].date_start, dtformat=DEFAULT_SERVER_DATE_FORMAT) days_diff = date_utils.date_diff(date_start, date_end, hours=False) + 1 prices = {} pricelist_ids = self.env['product.pricelist'].search([ ('wpid', '!=', False), ('active', '=', True) ]) for pr in pricelist_ids: prices.update({pr.wpid: {}}) unpushed_pl = self.env['product.pricelist.item'].search([ ('wpushed', '=', False), ('pricelist_id', '=', pr.id) ]) product_tmpl_ids = unpushed_pl.mapped('product_tmpl_id') for pt_id in product_tmpl_ids: room_type = self.env['hotel.room.type'].search( [('product_id.product_tmpl_id', '=', pt_id.id)], limit=1) if room_type: prices[pr.wpid].update({room_type.wrid: []}) for i in range(0, days_diff): prod = room_type.product_id.with_context({ 'quantity': 1, 'pricelist': pr.id, 'date': (date_start + timedelta(days=i) ).strftime(DEFAULT_SERVER_DATE_FORMAT), }) prices[pr.wpid][room_type.wrid].append(prod.price) _logger.info("UPDATING PRICES IN WUBOOK...") _logger.info(prices) for k_pk, v_pk in prices.iteritems(): if any(v_pk): self.backend_adapter.update_plan_prices( k_pk, date_start.strftime(DEFAULT_SERVER_DATE_FORMAT), v_pk) unpushed.with_context({ 'wubook_action': False }).write({'wpushed': True}) return True
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")
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")
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}}
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) minstay_restrictions = self.env[ 'hotel.virtual.room.restriction.item'].search([ ('virtual_room_id', '=', res.virtual_room_id.id), ]) avail_restrictions = self.env[ 'hotel.virtual.room.availability'].search([ ('virtual_room_id', '=', res.virtual_room_id.id) ]) real_max = len( res.virtual_room_id.check_availability_virtual_room( res.checkin, res.checkout, res.virtual_room_id.id)) res.real_avail = real_max avail = 100000 min_stay = 0 dates = [] for i in range(0, date_diff): ndate_dt = date_start + timedelta(days=i) ndate_str = ndate_dt.strftime(DEFAULT_SERVER_DATE_FORMAT) dates.append(ndate_str) if minstay_restrictions: date_min_days = minstay_restrictions.filtered( lambda r: r.date_start <= ndate_str and \ r.date_end >= ndate_str).min_stay if date_min_days > min_stay: min_stay = date_min_days if user.has_group('hotel.group_hotel_call'): if avail_restrictions: max_avail = avail_restrictions.filtered( lambda r: r.date == ndate_str).wmax_avail if max_avail < avail: avail = min(max_avail, real_max) else: avail = real_max if avail < 100000 and avail > 0: res.max_rooms = avail else: res.max_rooms = 0 if min_stay > 0: res.min_stay = min_stay
def get_hcalendar_restrictions_data(self, dfrom, dto): restriction_id = self.env['ir.values'].sudo().get_default( 'hotel.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 # Get Prices json_rooms_rests = {} vrooms = self.env['hotel.virtual.room'].search( [], order='hcal_sequence ASC') vroom_rest_obj = self.env['hotel.virtual.room.restriction.item'] for vroom in vrooms: days = {} for i in range(0, date_diff): ndate = date_start + timedelta(days=i) ndate_str = ndate.strftime(DEFAULT_SERVER_DATE_FORMAT) rest_id = vroom_rest_obj.search([ ('virtual_room_id', '=', vroom.id), ('date_start', '>=', ndate_str), ('date_end', '<=', ndate_str), ('applied_on', '=', '0_virtual_room'), ('restriction_id', '=', restriction_id) ], limit=1) if rest_id and (rest_id.min_stay or rest_id.min_stay_arrival or rest_id.max_stay or rest_id.max_stay_arrival or rest_id.closed or rest_id.closed_arrival or rest_id.closed_departure): days.update({ ndate.strftime("%d/%m/%Y"): ( rest_id.min_stay, rest_id.min_stay_arrival, rest_id.max_stay, rest_id.max_stay_arrival, rest_id.closed, rest_id.closed_arrival, rest_id.closed_departure) }) json_rooms_rests.update({vroom.id: days}) return json_rooms_rests
def create_reservation(self, creator, folio, checkin, checkout, room, resname, adults=1, children=0): # Create Reservation (Special Room) reservation = self.env['hotel.reservation'].sudo(creator).create({ 'name': resname, 'adults': adults, 'children': children, 'checkin': checkin.strftime(DEFAULT_SERVER_DATETIME_FORMAT), 'checkout': checkout.strftime(DEFAULT_SERVER_DATETIME_FORMAT), 'folio_id': folio.id, 'room_type_id': room.price_room_type.id, 'product_id': room.product_id.id, }) self.assertTrue(reservation, "Hotel Calendar can't create a new reservation!") # Create Reservation Lines + Update Reservation Price days_diff = date_utils.date_diff(checkin, checkout, hours=False) res = reservation.sudo(creator).prepare_reservation_lines( checkin.strftime(DEFAULT_SERVER_DATETIME_FORMAT), days_diff) reservation.sudo(creator).write({ 'reservation_lines': res['commands'], 'price_unit': res['total_price'], }) return reservation
def refresh_availability(self, checkin, checkout, product_id): date_start = date_utils.get_datetime(checkin) # Not count end day of the reservation date_diff = date_utils.date_diff(checkin, checkout, hours=False) vroom_obj = self.env['hotel.virtual.room'] virtual_room_avail_obj = self.env['hotel.virtual.room.availability'] vrooms = vroom_obj.search([('room_ids.product_id', '=', product_id)]) for vroom in vrooms: if vroom.wrid and vroom.wrid != '': for i in range(0, date_diff): ndate_dt = date_start + timedelta(days=i) ndate_str = ndate_dt.strftime(DEFAULT_SERVER_DATE_FORMAT) avail = len( vroom_obj.check_availability_virtual_room( ndate_str, ndate_str, virtual_room_id=vroom.id)) max_avail = vroom.max_real_rooms vroom_avail_id = virtual_room_avail_obj.search( [('virtual_room_id', '=', vroom.id), ('date', '=', ndate_str)], limit=1) if vroom_avail_id and vroom_avail_id.wmax_avail >= 0: max_avail = vroom_avail_id.wmax_avail avail = max(min(avail, vroom.total_rooms_count, max_avail), 0) if vroom_avail_id: vroom_avail_id.write({'avail': avail}) else: virtual_room_avail_obj.create({ 'virtual_room_id': vroom.id, 'date': ndate_str, 'avail': avail, })
def get_hcalendar_pricelist_data(self, dfrom, dto): pricelist_id = self.env['ir.values'].sudo().get_default( 'hotel.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 # Get Prices json_rooms_prices = {pricelist_id: []} vrooms = self.env['hotel.virtual.room'].search( [], order='hcal_sequence ASC') vroom_pr_cached_obj = self.env['virtual.room.pricelist.cached'] for vroom in vrooms: days = {} for i in range(0, date_diff): ndate = date_start + timedelta(days=i) ndate_str = ndate.strftime(DEFAULT_SERVER_DATE_FORMAT) prod_price_id = vroom_pr_cached_obj.search([ ('virtual_room_id', '=', vroom.id), ('date', '=', ndate_str) ], limit=1) days.update({ ndate.strftime("%d/%m/%Y"): prod_price_id and prod_price_id.price or vroom.product_id.with_context( quantity=1, date=ndate_str, pricelist=pricelist_id).price }) json_rooms_prices[pricelist_id].append({ 'room': vroom.id, 'days': days, 'title': vroom.name, }) return json_rooms_prices
def push_restrictions(self): room_type_rest_obj = self.env['hotel.room.type.restriction'] rest_item_obj = self.env['hotel.room.type.restriction.item'] unpushed = rest_item_obj.search([ ('wpushed', '=', False), ('date_start', '>=', date_utils.now(hours=False).strftime(DEFAULT_SERVER_DATE_FORMAT)) ], order="date_start ASC") if any(unpushed): date_start = date_utils.get_datetime( unpushed[0].date_start, dtformat=DEFAULT_SERVER_DATE_FORMAT) date_end = date_utils.get_datetime( unpushed[-1].date_start, dtformat=DEFAULT_SERVER_DATE_FORMAT) days_diff = date_utils.date_diff(date_start, date_end, hours=False) + 1 restrictions = {} restriction_plan_ids = room_type_rest_obj.search([ ('wpid', '!=', False), ('active', '=', True) ]) for rp in restriction_plan_ids: restrictions.update({rp.wpid: {}}) unpushed_rp = rest_item_obj.search([('wpushed', '=', False), ('restriction_id', '=', rp.id)]) room_type_ids = unpushed_rp.mapped('room_type_id') for room_type in room_type_ids: restrictions[rp.wpid].update({room_type.wrid: []}) for i in range(0, days_diff): ndate_dt = date_start + timedelta(days=i) restr = room_type.get_restrictions( ndate_dt.strftime(DEFAULT_SERVER_DATE_FORMAT)) if restr: restrictions[rp.wpid][room_type.wrid].append({ 'min_stay': restr.min_stay or 0, 'min_stay_arrival': restr.min_stay_arrival or 0, 'max_stay': restr.max_stay or 0, 'max_stay_arrival': restr.max_stay_arrival or 0, 'closed': restr.closed and 1 or 0, 'closed_arrival': restr.closed_arrival and 1 or 0, 'closed_departure': restr.closed_departure and 1 or 0, }) else: restrictions[rp.wpid][room_type.wrid].append({}) _logger.info("UPDATING RESTRICTIONS IN WUBOOK...") _logger.info(restrictions) for k_res, v_res in restrictions.iteritems(): if any(v_res): self.backend_adapter.update_rplan_values( int(k_res), date_start.strftime(DEFAULT_SERVER_DATE_FORMAT), v_res) unpushed.with_context({ 'wubook_action': False }).write({'wpushed': True}) return True
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' }
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')
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")
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
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")