class BookingCost(object): ''' 各小时的单价定义,提供预定时间的总价,以及取消时的违约金 ''' HOUR_9_TO_12 = BookingTime((9, 12)) HOUR_12_TO_18 = BookingTime((12, 18)) HOUR_18_TO_20 = BookingTime((18, 20)) HOUR_20_TO_22 = BookingTime((20, 22)) HOUR_18_TO_22 = BookingTime((18, 22)) WEEKDAY_PRICE = [[ HOUR_9_TO_12, HOUR_12_TO_18, HOUR_18_TO_20, HOUR_20_TO_22 ], [THIRTY_CNY, FIFTY_CNY, EIGHTY_CNY, SIXTY_CNY]] WEEKEND_PRICE = [[HOUR_9_TO_12, HOUR_12_TO_18, HOUR_18_TO_22], [FORTY_CNY, FIFTY_CNY, SIXTY_CNY]] def __init__(self, date, bookingTime, isCancel=False): ''' @date 预定日志,datetime对象 @bookingTime BookingTime实例 @isCancel boolean ''' self.isWeekend = self._is_weekend(date) self.bookingCost = 0 self.income = 0 self.cost = 0 self._calc_booking_cost(bookingTime) self._calc_cost_and_income(isCancel) def _calc_booking_cost(self, bookingTime): window = BookingTime.new_booking_time() + 1 for _ in range(BADMINTON_URATION_HOURS): if bookingTime.contain(window): self.bookingCost += self._get_price_peer_hour(window) window <<= 1 def _calc_cost_and_income(self, isCancel): if isCancel: if self.isWeekend: self.cost = int(self.bookingCost * WEEKEND_CANCEL_DISCOUNT) else: self.cost = int(self.bookingCost * WEEKDAY_CANCEL_DISCOUNT) self.income = self.cost - self.bookingCost else: self.cost = self.income = self.bookingCost def _get_price_peer_hour(self, whichHour): if self.isWeekend: hourDurtion = self.WEEKEND_PRICE[FIRST] priceDefine = self.WEEKEND_PRICE[SECOND] else: hourDurtion = self.WEEKDAY_PRICE[FIRST] priceDefine = self.WEEKDAY_PRICE[SECOND] for i in range(len(hourDurtion)): if hourDurtion[i].contain(whichHour): return priceDefine[i] return 0 def _is_weekend(self, date): return date.isoweekday() > Friday
def _format_time(self, timeStr): continueFlag = self._get_starthour_endhour(timeStr) if continueFlag: return BookingTime((self.startHour, self.endHour)) else: self.isValid = False return None
def cancel_booking(self, bookMessage): areaBookedTime = self.hasBookedByDatetime.get(bookMessage.date, BookingTime()) if areaBookedTime.has_booking(): self._fresh_booked_time(areaBookedTime, bookMessage, True) self._fresh_history(bookMessage, True) self.totalIncome += bookMessage.income return BOOKING_RESPONSE_DEFINE.get(BOOKING_SUCCESS) else: return BOOKING_RESPONSE_DEFINE.get(CANCEL_NOT_EXIST)
def new_booking(self, bookMessage): areaBookedTime = self.hasBookedByDatetime.get(bookMessage.date, BookingTime()) if areaBookedTime.is_conflict(bookMessage.time): return BOOKING_RESPONSE_DEFINE.get(BOOKING_CONFLICT) else: self._fresh_booked_time(areaBookedTime, bookMessage) self._fresh_history(bookMessage) self.totalIncome += bookMessage.income return BOOKING_RESPONSE_DEFINE.get(BOOKING_SUCCESS)
def _calc_booking_cost(self, bookingTime): window = BookingTime.new_booking_time() + 1 for _ in range(BADMINTON_URATION_HOURS): if bookingTime.contain(window): self.bookingCost += self._get_price_peer_hour(window) window <<= 1
def _is_time_valid(self, timeSplit): return len(timeSplit) == 2 and timeSplit[SECOND] == "00" and BookingTime.is_open(timeSplit[0])
def test_9_to_10(self): result = BookingTime.convert_time_to_byte(9, 10) assert result == int("1000000000000", 2)
def test_9_to_22(self): result = BookingTime.convert_time_to_byte(9, 22) assert result == int("1111111111111", 2)
def test_weekday_price5(self): date = datetime.datetime.strptime("2019-05-31", "%Y-%m-%d") time = BookingTime((18, 19)) bookingCost = BookingCost(date, time) result = bookingCost.cost assert result == 80, "Fail: " + str(result)
def test_weekend_price8(self): date = datetime.datetime.strptime("2019-06-01", "%Y-%m-%d") time = BookingTime((17, 19)) bookingCost = BookingCost(date, time) result = bookingCost.cost assert result == 110, "Fail: " + str(result)