/*
* Distributable under LGPL v3 license.
* See terms of license at https://github.com/Yunfeng/schotel/blob/master/LICENSE
*/
package cn.buk.hotel.service;
import cn.buk.hotel.dao.CityDao;
import cn.buk.hotel.dao.HotelDao;
import cn.buk.hotel.dto.*;
import cn.buk.hotel.entity.*;
import cn.buk.hotel.sc.HotelSearchCriteria;
import cn.buk.util.DateUtil;
import cn.buk.util.EncryptUtil;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import org.apache.log4j.Logger;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
/**
* @author william dai(yunfeng2005@gmail.com)
* @website http://www.buk.cn/
* Date: 14-10-29
* Time: 下午1:41
*/
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class HotelServiceImpl implements HotelService {
private static Logger logger = Logger.getLogger(HotelServiceImpl.class);
private HotelDao hotelDao;
private CityDao cityDao;
private static final CacheManager cacheManager = CacheManager.getInstance();
private static Cache getCache() {
String cacheName = "hotelSearchCache";
Cache cache = cacheManager.getCache(cacheName);
if (cache == null) {
cacheManager.addCache(cacheName);
cache = cacheManager.getCache(cacheName);
}
return cache;
}
@Override
public int createHotelInfo(HotelInfo hotelInfo) {
return hotelDao.createHotelInfo(hotelInfo);
}
@Override
public HotelInfo getHotelInfoByHotelCode(String hotelCode) {
return hotelDao.getHotelInfoByHotelCode(hotelCode);
}
@Override
public HotelSearchResult searchHotel(String cityCode, Date checkInDate, Date checkOutDate, String hotelName, int pageNo, String star, int districtId, int zoneId) {
HotelSearchResult searchResult = new HotelSearchResult();
if (checkInDate.getTime() < DateUtil.getCurDate().getTime())
checkInDate = DateUtil.getCurDate();
if (checkInDate.getTime() >= checkOutDate.getTime())
checkOutDate = DateUtil.add(checkInDate, 1);
City city = cityDao.getCityByCode(cityCode);
Date baseTime = DateUtil.getCurDateTime();
int cityId = city.getOpenApiId();
List<HotelInfoDto> dtos = new ArrayList<HotelInfoDto>();
HotelSearchCriteria sc = new HotelSearchCriteria();
sc.setCityId(cityId );
sc.setCheckInDate(checkInDate);
sc.setCheckOutDate(checkOutDate);
sc.setHotelName(hotelName);
sc.getPage().setPageNo(pageNo);
sc.setStar(star);
sc.setDistrictId(districtId);
sc.setZoneId(zoneId);
/**
* 查看缓存中是否存在
*/
String cacheKey = null;
try {
String scToString = sc.toString();
cacheKey = EncryptUtil.MD5Encoding(scToString);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
if (cacheKey != null) {
logger.debug("cacheKey: " + cacheKey);
net.sf.ehcache.Element cacheElement = getCache().get(cacheKey);
if (cacheElement != null) {
searchResult = (HotelSearchResult) cacheElement.getObjectValue();
logger.debug("Nothing for key: " + searchResult);
return searchResult;
} else {
logger.debug("Nothing for key: " + cacheKey);
}
}
List<HotelInfo> hotelInfos = hotelDao.searchAvailableHotel(sc);
int span0 = DateUtil.getPastTime(baseTime);
//计算查询条件的提前天数和入住天数
int bookingDays = DateUtil.getPastDays(checkOutDate, checkInDate);
int bookingAdvancedDays = DateUtil.getPastDays(checkInDate, DateUtil.getCurDate());
Date baseTime2 = DateUtil.getCurDateTime();
for(HotelInfo hotelInfo: hotelInfos) {
//
HotelInfoDto dto = new HotelInfoDto();
dtos.add(dto);
dto.setHotelCode(hotelInfo.getHotelCode());
dto.setHotelName(hotelInfo.getHotelName());
dto.setHotelAddress(hotelInfo.getAddress());
dto.setHotelStarRate(hotelInfo.getHotelStarRate());
dto.setHotelUserRate(hotelInfo.getHotelUserRate());
Date baseTime1 = DateUtil.getCurDateTime();
//获取酒店的多媒体信息
List<HotelMultimediaInfo> medias = hotelDao.getHotelMultimediaList(hotelInfo.getId());
for(HotelMultimediaInfo media: medias) {
if (media.getMediaType().equalsIgnoreCase("image") && media.getCategory()==HotelMultimediaInfo.HOTEL_PICTURE_EXTERIOR_VIEW)
dto.setHotelExteriorPictureUrl(media.getUrl());
else if (media.getMediaType().equalsIgnoreCase("text") && media.getCategory()==HotelMultimediaInfo.HOTEL_TEXT_DESC)
dto.setHotelDesc(media.getDescription().trim());
}
//查找对应的价格计划
List<HotelRatePlan> ratePlans = hotelDao.searchAvailableHotelRatePlan(hotelInfo.getId(), checkInDate, checkOutDate);
//将价格计划中的ratePlanCode与roomTypeCode是等值的,表示子房型,invBlockCode表示房型代码 yfdai 2015-1-8
List<HotelGuestRoom> rooms = hotelDao.getHotelRoomInfoList(hotelInfo.getId());
for(HotelGuestRoom room: rooms) {
for (HotelRatePlan rp : ratePlans) {
if (rp.getHotelRatePlanRates() == null || rp.getHotelRatePlanRates().size() == 0) continue;
if (!room.getRoomTypeCode().equalsIgnoreCase(Integer.toString(rp.getRatePlanCode()))) continue;
//判断预定的提前天数
if (rp.getHotelRatePlanBookingRules() != null && rp.getHotelRatePlanBookingRules().size() > 0) {
HotelRatePlanBookingRule rule = rp.getHotelRatePlanBookingRules().get(0);
if (rule.getMinAdvancedBookingOffset() > 0 && rule.getMinAdvancedBookingOffset() > bookingAdvancedDays) continue;
if (rule.getMaxAdvancedBookingOffset() > 0 && rule.getMaxAdvancedBookingOffset() > bookingAdvancedDays) continue;
if (rule.getLengthOfStay() > 0 && rule.getLengthOfStay() > bookingDays) continue;
}
//offer中限制的时限
if (rp.getHotelRatePlanOffers() != null && rp.getHotelRatePlanOffers().size() > 0) {
boolean b = true;
for(HotelRatePlanOffer offer: rp.getHotelRatePlanOffers()) {
//1002-礼盒
if (offer.getOfferCode() == 1002) continue;
//1001- 促销
if (offer.getOfferCode() == 1001) {
if (offer.getRatePlanOfferRules() != null && offer.getRatePlanOfferRules().size() > 0) {
//<!-- 活动时间限制规则-->
//<!-- Start属性:开始时间;End属性:结束时间;RestrictionTyp:booking可预订;RestrictionDateCode :501表示促销活动的时间区间,502表示活动在每天的开始和结束时间,一般作用于限时特价-->
for(HotelRatePlanOfferRule rule: offer.getRatePlanOfferRules()) {
for(HotelRatePlanOfferRuleDateRestriction restriction: rule.getRatePlanOfferRuleDateRestrictions()) {
DateRange dateRange = restriction.getDateRange();
if (dateRange == null || dateRange.getRestrictionDateCode() == null) continue;
if (!dateRange.getRestrictionType().equalsIgnoreCase("booking") ) continue;
if (dateRange.getRestrictionDateCode() == null) continue;
if(dateRange.getRestrictionDateCode().equalsIgnoreCase("501")) {
//日期范围
if(DateUtil.isLowerEqualDate(dateRange.getStartTime())) b = false;
if(DateUtil.isGreaterEqualDate(dateRange.getEndTime())) b = false;
} else if (dateRange.getRestrictionDateCode().equalsIgnoreCase("502")) {
//时间范围
if(DateUtil.isLowerEqualOnlyTime(dateRange.getStartTime())) b = false;
if(DateUtil.isGreaterEqualOnlyTime(dateRange.getEndTime())) b = false;
}
}
}
}
}
}
if (!b) continue;
}
HotelRatePlanDto rpDto = new HotelRatePlanDto();
rpDto.setRatePlanCode(rp.getRatePlanCode());
rpDto.setRatePlanName(rp.getName());
rpDto.setInvBlockCode(room.getInvBlockCode());
rpDto.setRoomTypeCode(Integer.toString(rp.getRatePlanCode()));
rpDto.setRoomTypeName(room.getRoomTypeName());
if (room.getBedTypeCode() != null)
rpDto.setBedTypeCode(Integer.parseInt(room.getBedTypeCode()));
for (HotelGuestRoomAmenity amenity : room.getHotelGuestRoomAmenities()) {
HotelRoomAmenityDto amenityDto = new HotelRoomAmenityDto();
amenityDto.setAmenityCode(amenity.getCode());
amenityDto.setAmenityName(amenity.getDescription());
rpDto.getAmenities().add(amenityDto);
}
//rpDto.setRoomTypeName(rp.getName());
int price = 0;
for (HotelRatePlanRate rate0 : rp.getHotelRatePlanRates()) {
//price += rate.getHotelRatePlanRateBaseByGuestAmounts().get(0).getAmountBeforeTax();
HotelRatePlanRateDto rate1 = new HotelRatePlanRateDto();
rpDto.getRates().add(rate1);
rate1.setStartDate(rate0.getStartDate());
rate1.setPrice(rate0.getHotelRatePlanRateBaseByGuestAmounts().get(0).getAmountBeforeTax());
rate1.setBreakfast(rate0.getBreakfast());
//返现
if (rate0.getHotelRatePlanRatePromotions() != null && rate0.getHotelRatePlanRatePromotions().size() > 0) {
rate1.setRebateAmount(rate0.getHotelRatePlanRatePromotions().get(0).getAmount());
rate1.setRebateDesc(rate0.getHotelRatePlanRatePromotions().get(0).getDescription());
}
//担保
if (rate0.getHotelRatePlanRateGuaranteePolicies() != null && rate0.getHotelRatePlanRateGuaranteePolicies().size() > 0) {
rate1.setGuaranteeCode(rate0.getHotelRatePlanRateGuaranteePolicies().get(0).getGuaranteeCode());
rate1.setHoldTime(rate0.getHotelRatePlanRateGuaranteePolicies().get(0).getHoldTime());
}
//取消政策
if (rate0.getHotelRatePlanRateCancelPolicies() != null && rate0.getHotelRatePlanRateCancelPolicies().size() > 0) {
HotelRatePlanRateCancelPolicy policy = rate0.getHotelRatePlanRateCancelPolicies().get(0);
rate1.setCancelPolicyStart(policy.getStartTime());
rate1.setCancelPolicyEnd(policy.getEndTime());
rate1.setCancelPenaltyAmount((int)policy.getAmount());
}
}
rpDto.calcAveragePrice();
int breakfast = rp.getHotelRatePlanRates().get(0).getBreakfast();
int breakfastCount = rp.getHotelRatePlanRates().get(0).getNumberOfBreakfast();
if (breakfast == 0) breakfastCount = 0;
rpDto.setBreakfast(breakfastCount);
dto.addRatePlan(rpDto);
}
}
int span4 = DateUtil.getPastTime(baseTime1);
logger.info("elapsed time span4: " + span4 + " ms.");
}
int span2 = DateUtil.getPastTime(baseTime2);
int spanTotal = DateUtil.getPastTime(baseTime);
logger.info("elapsed time: total=" + spanTotal + "ms, span0=" + span0 + ", span2=" + span2 + ".");
searchResult.setHotels(dtos);
searchResult.setPageNo(sc.getPage().getPageNo());
searchResult.setPageTotal(sc.getPage().getPageTotal());
searchResult.setRowCount(sc.getPage().getRowCount());
if (cacheKey != null) {
getCache().put(new net.sf.ehcache.Element(cacheKey, searchResult));
logger.debug("Put object into cache with key " + cacheKey);
}
return searchResult;
}
@Override
public HotelAvailResult checkHotelAvail(String hotelCode, Date checkInDate, Date checkOutDate, String ratePlanCode, int roomQuantity, int guestCount, Date lateArrivalTime) {
return null;
}
@Override
public List<LocationDto> getLocations(String cityCode, String locationType) {
City city = cityDao.getCityByCode(cityCode);
int cityId = city.getOpenApiId();
List<LocationDto> dtos = new ArrayList<LocationDto>();
if (locationType.equalsIgnoreCase("district")) {
List<District> districts = hotelDao.getDistrictByCityId(cityId);
for(District district: districts) {
LocationDto dto = new LocationDto();
dtos.add(dto);
dto.setId(district.getDistrictId());
dto.setName(district.getName());
}
} else if (locationType.equalsIgnoreCase("zone")) {
List<Zone> zones = hotelDao.getZoneByCityId(cityId);
for(Zone zone: zones) {
LocationDto dto = new LocationDto();
dtos.add(dto);
dto.setId(zone.getZoneId());
dto.setName(zone.getName());
}
}
return dtos;
}
@Override
public HotelRoomInfoResult getHotelRoomInfo(String hotelCode, String ratePlanCode, Date checkInDate, Date checkOutDate) {
HotelInfo hotelInfo = hotelDao.getHotelInfoByHotelCode(hotelCode);
HotelInfoDto dto = new HotelInfoDto();
dto.setHotelCode(hotelInfo.getHotelCode());
dto.setHotelName(hotelInfo.getHotelName());
dto.setHotelAddress(hotelInfo.getAddress());
dto.setHotelStarRate(hotelInfo.getHotelStarRate());
dto.setHotelUserRate(hotelInfo.getHotelUserRate());
//Date baseTime1 = DateUtil.getCurDateTime();
//获取酒店的多媒体信息
List<HotelMultimediaInfo> medias = hotelDao.getHotelMultimediaList(hotelInfo.getId());
for(HotelMultimediaInfo media: medias) {
if (media.getMediaType().equalsIgnoreCase("image") && media.getCategory()==HotelMultimediaInfo.HOTEL_PICTURE_EXTERIOR_VIEW)
dto.setHotelExteriorPictureUrl(media.getUrl());
else if (media.getMediaType().equalsIgnoreCase("text") && media.getCategory()==HotelMultimediaInfo.HOTEL_TEXT_DESC)
dto.setHotelDesc(media.getDescription().trim());
}
//查看房型信息
HotelRoomDto roomDto = new HotelRoomDto();
HotelRatePlan ratePlan = hotelDao.getHotelRatePlanInfo(hotelInfo.getId(), ratePlanCode);
roomDto.setRoomTypeName(ratePlan.getName());
HotelGuestRoom room = hotelDao.getHotelRoomInfo(hotelInfo.getId(), ratePlanCode);
roomDto.setFloor(room.getFloor());
roomDto.setBedTypeCode(room.getBedTypeCode());
roomDto.setRoomSize(room.getRoomSize());
HotelRoomInfoResult hotelRoomInfoResult = new HotelRoomInfoResult();
hotelRoomInfoResult.setHotelInfo(dto);
hotelRoomInfoResult.setRoomInfo(roomDto);
//查看价格
HotelRatePlan hotelRatePlan = hotelDao.searchAvailableHotelRatePlan(hotelInfo.getId(), checkInDate, checkOutDate, Integer.parseInt(ratePlanCode));
roomDto.setPrice(hotelRatePlan.getHotelRatePlanRates().get(0).getHotelRatePlanRateBaseByGuestAmounts().get(0).getAmountBeforeTax());
return hotelRoomInfoResult;
}
@Override
public int createHotelOrder(HotelOrder hotelOrder) {
return hotelDao.createHotelOrder(hotelOrder);
}
public HotelDao getHotelDao() {
return hotelDao;
}
public void setHotelDao(HotelDao hotelDao) {
this.hotelDao = hotelDao;
}
public CityDao getCityDao() {
return cityDao;
}
public void setCityDao(CityDao cityDao) {
this.cityDao = cityDao;
}
public void stopService() {
try {
//cacheManager.clearAll();
System.out.println("cacheManager.shutdown();");
cacheManager.shutdown();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}