def post(self): self.set_header("Content-Type", "application/json") ret = {} date = self.get_argument('date') master_id = self.get_argument('master_id', '') # convert arguments date = dt.datetime.strptime(date, '%Y%m%d') try: session = Session() userdao = UserDAO() result = session.query(Booking, User, UserAddress) \ .join(User, Booking.user_id == User.id) \ .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \ .filter(Booking.master_id == master_id) \ .filter(func.date(Booking.start_time) == date) \ .filter(or_(Booking.cleaning_status == BC.BOOKING_UPCOMMING, Booking.cleaning_status == BC.BOOKING_STARTED, Booking.cleaning_status == BC.BOOKING_COMPLETED)) \ .order_by(Booking.start_time) \ .all() booking_list = [] for row in result: key = userdao.get_user_salt_by_id(row.Booking.user_id)[:16] crypto = aes.MyCrypto(key) booking = {} tooktime = time_to_minutes(timedelta_to_time(row.Booking.estimated_end_time - row.Booking.start_time)) if row.Booking.appointment_type == BC.ONE_TIME or row.Booking.appointment_type == BC.ONE_TIME_BUT_CONSIDERING: if row.Booking.is_dirty == 1: tooktime -= 120 start_time = row.Booking.start_time request_count = session.query(MasterBookingModifyRequest) \ .filter(MasterBookingModifyRequest.master_id == master_id) \ .filter(MasterBookingModifyRequest.booking_id == row.Booking.id) \ .filter(MasterBookingModifyRequest.org_time == start_time) \ .count() booking['booking_id'] = row.Booking.id booking['start_time'] = convert_time_format(row.Booking.start_time.time()) booking['name'] = crypto.decodeAES(row.User.name) booking['address'] = crypto.decodeAES(row.UserAddress.address) #booking['jibun_address'] = convert_to_jibun_address(booking['address']) booking['size'] = row.UserAddress.size booking['kind'] = row.UserAddress.kind booking['additional_task'] = row.Booking.additional_task booking['appointment_type'] = row.Booking.appointment_type booking['index'] = row.Booking.appointment_index booking['tooktime'] = int(tooktime / 6) booking['status'] = row.Booking.status booking['cleaning_status'] = row.Booking.cleaning_status booking['payment_status'] = row.Booking.payment_status booking['is_dirty'] = row.Booking.is_dirty booking['request_modify'] = request_count booking_list.append(booking) dayoff = False is_open_time = False free_from = None free_to = None row = session.query(MasterScheduleByDate) \ .filter(MasterScheduleByDate.master_id == master_id) \ .filter(MasterScheduleByDate.date == date) \ .first() if row != None: if row.active == 0: dayoff = True is_open_time = True free_from = row.free_from.strftime('%H:%M') free_to = row.free_to.strftime('%H:%M') ret['response'] = {'booking_list' : booking_list, 'free_from' : free_from, 'free_to' : free_to, 'is_open_time' : is_open_time, 'dayoff' : dayoff} self.set_status(Response.RESULT_OK) except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
class EditBookingHandler(tornado.web.RequestHandler): def post(self): self.set_header("Content-Type", "application/json") booking_id = self.get_argument('booking_id', '') changed = self.get_argument('ischange', '') date = self.get_argument('date', dt.datetime.now()) start_time_range_begin = self.get_argument('range_begin', BC.START_TIME_RANGE_BEGIN) start_time_range_begin_min = self.get_argument('range_begin_min', 0) start_time_range_end = self.get_argument('range_end', BC.START_TIME_RANGE_END) start_time_range_end_min = self.get_argument('range_end_min', 0) price = self.get_argument('price', 0) taking_time = self.get_argument('taking_time', 25) additional_task = self.get_argument('additional_task', 0) message = self.get_argument('msg', '') laundry_apply_all = self.get_argument( 'laundry_apply_all', 0) # -1 - 없앰, 0 - one time, 1 - all time print 'edit booking params....' print booking_id, changed, date, additional_task, taking_time, price # convert datetime price = int(price) taking_time = int(taking_time) additional_task = int(additional_task) taking_time_in_minutes = taking_time * 6 laundry_apply_all = int(laundry_apply_all) changed = "{0:03b}".format(int(changed)) mongo_logger = get_mongo_logger() mongo_logger.debug('%s was called to updated' % booking_id, extra={ 'changed': changed, 'date': date, 'start_time_range_begin': start_time_range_begin, 'start_time_range_end': start_time_range_end, 'price': price, 'taking_time': taking_time, 'additional_task': additional_task, 'user_message': message }) ret = {} mix = get_mixpanel() try: session = Session() userdao = UserDAO() addrdao = AddressDAO() masterdao = MasterDAO() try: row = session.query(Booking).filter( Booking.id == booking_id).one() except NoResultFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_no_record']) return except MultipleResultsFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_multiple_record']) return uid = row.user_id price_with_task = row.price_with_task appointment_type = row.appointment_type org_master_id = row.master_id holder = IntermediateValueHolder() org_date = dt.datetime.strftime(row.start_time, '%m월%d일') time_changed = changed[2] task_changed = changed[1] msg_changed = changed[0] # booking can not be updated within 24 hours ahead appointment_time = row.start_time current_time = dt.datetime.now() diff_in_hours = (appointment_time - current_time).total_seconds() / 3600 if diff_in_hours < 24: # 못바꾸도록 함 time_changed = 0 task_changed = 0 havetools = 1 if additional_task >= 64: havetools = 0 # time이 변경되었다면 무조건 scheduling if time_changed == '1': date = dt.datetime.strptime(date, '%Y%m%d') start_time_range_begin = int(start_time_range_begin) start_time_range_begin_min = int(start_time_range_begin_min) start_time_range_end = int(start_time_range_end) start_time_range_end_min = int(start_time_range_end_min) appointment_type = 0 # 여기서는 1회 청소로 한다. 편집이기 때문에 start_time = row.start_time end_time = row.estimated_end_time have_pet = row.havepet master_gender = row.master_gender price_with_task = row.price_with_task addr_idx = row.addr_idx org_taking_time_in_minutes = time_to_minutes( timedelta_to_time(end_time - start_time)) new_taking_time_in_minutes = org_taking_time_in_minutes + taking_time_in_minutes address, geohash5, geohash6 = userdao.get_user_address_by_index( uid, addr_idx) gu_id = addrdao.get_gu_id(address) dates = [int(dt.datetime.strftime(date, '%Y%m%d'))] schedule_by_date_list = masterdao.get_master_schedule_by_dates( gu_id, have_pet, master_gender, dates) success, msg, store_key, search_keys, result = masterdao.find_master_by_score(schedule_by_date_list, \ gu_id, \ uid, \ appointment_type, \ dates, \ start_time_range_begin, \ start_time_range_begin_min, \ start_time_range_end, \ start_time_range_end_min, \ new_taking_time_in_minutes, \ geohash6) # if not successful if success != 'SUCCESS': session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response( ret, err_dict['err_no_hm_at_that_time']) self.write(json.dumps(ret)) return else: # find matching homemaster item = result[0] master_id = item['mid'] dow = dt.datetime.strptime(item['date'], '%Y%m%d').date().weekday() start_time = dt.datetime.combine( dt.datetime.strptime(item['date'], '%Y%m%d'), item['start_time']) estimated_end_time = dt.datetime.combine( dt.datetime.strptime(item['date'], '%Y%m%d'), item['end_time']) status = row.payment_status if status == BC.BOOKING_PAID: # 미리 지불한 경우는 취소 하고 다시 결제함 # 전거래 취소 및 재결제 cancel_ret_code, msg = cancel_payment(uid, booking_id, price_with_task, partial='0') if cancel_ret_code: user_name = userdao.get_user_name(uid) pay_ret_code, pay_msg = request_payment( uid, user_name, booking_id, price, appointment_type, status='UPDATED') if pay_ret_code: row.tid = pay_msg row.payment_status = BC.BOOKING_PAID else: row.payment_status = BC.BOOKING_PAYMENT_FAILED session.commit() session.close() self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, pay_msg) self.write(json.dumps(ret)) return row.master_id = master_id row.dow = dow row.price_with_task = price row.start_time = start_time row.message = message row.additional_task = additional_task row.havetools = havetools row.estimated_end_time = estimated_end_time row.laundry_apply_all = laundry_apply_all if org_master_id != master_id: row.is_master_changed = 1 # about laundry request_id = row.request_id appointment_index = row.appointment_index all_bookings = session.query(Booking) \ .filter(Booking.request_id == request_id) \ .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \ .filter(Booking.appointment_index > appointment_index) \ .all() if laundry_apply_all == 1: for booking in all_bookings: booking.additional_task += 4 # 빨래 booking.laundry_apply_all = laundry_apply_all else: for booking in all_bookings: bits = "{0:07b}".format(booking.additional_task) if bits[4] == '1': booking.additional_task -= 4 # 빨래 제거 booking.laundry_apply_all = laundry_apply_all session.commit() holder.remove(store_key) for sk in search_keys: holder.remove(sk) else: if task_changed == '1': if taking_time_in_minutes > 0: # 실제 시간이 늘어났을 경우에만 뒷 스케쥴 확인 master_id, start_date_int = masterdao.get_masterid_and_starttime_from_booking( booking_id) search_key = '%s_%d' % (master_id, start_date_int) new_estimated_end_time = masterdao.is_master_available_next_schedule( booking_id, taking_time_in_minutes) print new_estimated_end_time, '&&&&' if new_estimated_end_time != None and holder.store( search_key, 1): # 실제로 시간이 가능하면 status = row.payment_status if status == BC.BOOKING_PAID: # 미리 지불한 경우는 취소 하고 다시 결제함 # 전거래 취소 및 재결제 cancel_ret_code, msg = cancel_payment( uid, booking_id, price_with_task, partial='0') if cancel_ret_code: user_name = userdao.get_user_name(uid) pay_ret_code, pay_msg = request_payment( uid, user_name, booking_id, price, appointment_type, status='UPDATED') if pay_ret_code: row.tid = pay_msg row.payment_status = BC.BOOKING_PAID else: row.payment_status = BC.BOOKING_PAYMENT_FAILED session.commit() session.close() self.set_status(Response.RESULT_OK) add_err_ko_message_to_response( ret, pay_msg) self.write(json.dumps(ret)) return row.estimated_end_time = new_estimated_end_time row.additional_task = additional_task row.message = message row.price_with_task = price row.havetools = havetools row.laundry_apply_all = laundry_apply_all # about laundry request_id = row.request_id appointment_index = row.appointment_index all_bookings = session.query(Booking) \ .filter(Booking.request_id == request_id) \ .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \ .filter(Booking.appointment_index > appointment_index) \ .all() if laundry_apply_all == 1: for booking in all_bookings: booking.additional_task += 4 # 빨래 booking.laundry_apply_all = laundry_apply_all else: for booking in all_bookings: bits = "{0:07b}".format( booking.additional_task) if bits[4] == '1': booking.additional_task -= 4 # 빨래 제거 booking.laundry_apply_all = laundry_apply_all session.commit() # 메모리에서 삭제 holder.remove(search_key) else: # 스케쥴이 있어서 불가능 함 session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response( ret, err_dict['err_hm_have_next_schedule']) self.write(json.dumps(ret)) return else: # 시간이 줄어들었거나, 그대로인경우에는 additional task 값만 바꾸면 됨 status = row.payment_status if status == BC.BOOKING_PAID: # 미리 지불한 경우는 취소 하고 다시 결제함 # 전거래 취소 및 재결제 cancel_ret_code, msg = cancel_payment( uid, booking_id, price_with_task, partial='0') if cancel_ret_code: user_name = userdao.get_user_name(uid) pay_ret_code, pay_msg = request_payment( uid, user_name, booking_id, price, appointment_type, status='UPDATED') if pay_ret_code: row.tid = pay_msg row.payment_status = BC.BOOKING_PAID else: row.payment_status = BC.BOOKING_PAYMENT_FAILED session.commit() session.close() self.set_status(Response.RESULT_OK) add_err_ko_message_to_response( ret, pay_msg) self.write(json.dumps(ret)) return print row.estimated_end_time, taking_time_in_minutes row.estimated_end_time = row.estimated_end_time + dt.timedelta( minutes=taking_time_in_minutes) row.additional_task = additional_task row.message = message row.price_with_task = price row.havetools = havetools row.laundry_apply_all = laundry_apply_all # about laundry request_id = row.request_id appointment_index = row.appointment_index all_bookings = session.query(Booking) \ .filter(Booking.request_id == request_id) \ .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \ .filter(Booking.appointment_index > appointment_index) \ .all() if laundry_apply_all == 1: for booking in all_bookings: booking.additional_task += 4 # 빨래 booking.laundry_apply_all = laundry_apply_all else: for booking in all_bookings: bits = "{0:07b}".format( booking.additional_task) if bits[4] == '1': booking.additional_task -= 4 # 빨래 제거 booking.laundry_apply_all = laundry_apply_all session.commit() else: row.message = message session.commit() # 문자 전송 #send_updated_text(booking_id, org_date) ret['response'] = Response.SUCCESS self.set_status(Response.RESULT_OK) mix.track( uid, 'update', { 'time': dt.datetime.now(), 'booking_id': booking_id, 'additional_task': additional_task }) mongo_logger.debug('%s was updated' % booking_id, extra={ 'user_id': uid, 'booking_id': booking_id }) print booking_id, 'successfully updated...'
class RequestAvailableSchedulesForChangeCircleHandler( tornado.web.RequestHandler): def post(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') ret = {} booking_id = self.get_argument('booking_id', '') appointment_type = self.get_argument('appointment_type', 0) is_admin = self.get_argument('is_admin', 1) appointment_type = int(appointment_type) is_admin = int(is_admin) print 'appointment_type', appointment_type # logging part mix = get_mixpanel() mongo_logger = get_mongo_logger() try: session = Session() try: row = session.query(Booking).filter( Booking.id == booking_id).one() except NoResultFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_no_record']) return except MultipleResultsFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_multiple_record']) return uid = row.user_id have_pet = row.havepet master_gender = row.master_gender isdirty = row.is_dirty start_time = row.start_time estimated_end_time = row.estimated_end_time appointment_date = row.org_start_time request_id = row.request_id addr_idx = row.addr_idx print "orginal apointment type : " + str(row.appointment_type) total_taking_time_in_minutes = time_to_minutes( timedelta_to_time(estimated_end_time - start_time)) scheduler = HMScheduler() userdao = UserDAO() addrdao = AddressDAO() address, geohash5, geohash6 = userdao.get_user_address_by_index( uid, addr_idx) # 편집의 경우에는, 예약된 주소를 이용한다. gu_id = addrdao.get_gu_id(address) if gu_id == '': raise Exception('gu id is incorrect') update = True available_schedules = scheduler.get_available_slots( gu_id=gu_id, geohash=geohash6, appointment_type=appointment_type, taking_time=total_taking_time_in_minutes, prefer_women=True if master_gender == 1 else False, have_pet=True if have_pet == 1 else False, isdirty=True if isdirty == 1 else False, user_id=uid) if is_admin == 0: # is_admin == False now = dt.datetime.now() if now.hour >= 17: # 7시 이후 라면 -> 5시로 변경 tomorrow = now + dt.timedelta(days=1) tomorrow = dt.datetime.strftime(tomorrow, '%Y%m%d') if tomorrow in available_schedules: del available_schedules[tomorrow] for day in available_schedules: print '[', day, ']' print available_schedules[day]['by_time'] print 'schdules for update...' print 'have_pet', have_pet print 'master_gender', master_gender print 'isdirty', isdirty print 'taking_time', total_taking_time_in_minutes print 'appointment_date', appointment_date print 'gu_id', gu_id # log to mixpanel mix.track( uid, 'request change circle schedule', { 'time': dt.datetime.now(), 'appointment_type': appointment_type, 'have_pet': have_pet, 'master_gender': master_gender, 'isdirty': isdirty }) # log to mongo mongo_logger.debug('request change circle schedule', extra={ 'user_id': uid, 'appointment_type': appointment_type, 'have_pet': have_pet, 'master_gender': master_gender, 'isdirty': isdirty }) if len(available_schedules) > 0: # 가능한 날짜가 있다면 ret['response'] = { 'schedule': available_schedules, 'first_date': available_schedules.keys()[0] } else: add_err_message_to_response(ret, err_dict['err_not_available']) self.set_status(Response.RESULT_OK)
class UpdateScheduleHandler(tornado.web.RequestHandler): def get_amount_day_of_week_change(self, org_date, sel_date): if org_date.weekday() in BC.WEEKDAYS and sel_date.weekday() in BC.WEEKEND: return 10000 elif org_date.weekday() in BC.WEEKEND and sel_date.weekday() in BC.WEEKDAYS: return -10000 else: return 0 def post(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') ret = {} booking_id = self.get_argument('booking_id', '') uid = self.get_argument('uid', '') date = self.get_argument('date', dt.datetime.strftime(dt.datetime.now(), '%Y%m%d')) time = self.get_argument('time', '08:00') master_ids = self.get_argument('master_ids', []) apply_to_all_behind = self.get_argument('apply_to_all_behind', 0) by_manager = self.get_argument('by_manager', 0) # convert parameters apply_to_all_behind = int(apply_to_all_behind) selected_date_str = date time_str = time selected_date = dt.datetime.strptime(date, '%Y%m%d') master_ids = master_ids.split(',') by_manager = int(by_manager) # logging part mix = get_mixpanel() mongo_logger = get_mongo_logger() print 'update schedule' print selected_date_str, time_str, apply_to_all_behind print '*' * 100 try: session = Session() booking_info = {} userdao = UserDAO() masterdao = MasterDAO() holder = IntermediateValueHolder() try: row = session.query(Booking).filter(Booking.id == booking_id).one() except NoResultFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_no_record']) return except MultipleResultsFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_multiple_record']) return request_id = row.request_id user_id = row.user_id user_name = userdao.get_user_name(user_id) appointment_type = row.appointment_type appointment_index = row.appointment_index additional_task = row.additional_task org_master_id = row.master_id org_start_time = row.start_time org_estimated_end_time = row.estimated_end_time payment_status = row.payment_status price_with_task = row.price_with_task # 결제가 된 경우, 상황에 따라 if payment_status == BC.BOOKING_PAID \ and not userdao.is_b2b(user_id) \ and row.source == 'hm': amount = self.get_amount_day_of_week_change(org_start_time, selected_date) if amount != 0: ret_code, msg = cancel_payment(user_id, booking_id, price_with_task, '0', 'weeked_update_cancel') if ret_code == True: new_price = price_with_task + amount ret_code, msg = request_payment(user_id, user_name, booking_id, new_price, appointment_type, status = 'PAID') if ret_code == True: row.payment_status = BC.BOOKING_PAID row.tid = msg else: row.payment_status = BC.BOOKING_PAYMENT_FAILED duration = time_to_minutes(timedelta_to_time(org_estimated_end_time - org_start_time)) if appointment_type == BC.ONE_TIME_BUT_CONSIDERING: appointment_type = BC.ONE_TIME if apply_to_all_behind == 0: # 단일 적용이라면 appointment_type = BC.ONE_TIME count_of_iteration = appointment_type * 2 + 2 # 2 months # 편집 에러 기존 예약은 무조건 4개인데, 편집시 3개만 생성해서 에러가 발생 # 꼼수로 4주 1회인 경우, iteration하나 늘림. if appointment_type == BC.ONE_TIME_A_MONTH: count_of_iteration += 1 date_list = [] for i in xrange(count_of_iteration): if appointment_type == 0: appointment_type = 4 date = selected_date + dt.timedelta(weeks = (4 / appointment_type) * i) date = dt.datetime.strftime(date, '%Y%m%d') date_list.append(date) booking_info['dates'] = date_list booking_info['time'] = time # 각 마스터별로 예약이 가능한지 메모리에서 다시 한번 확인. # 선택한 값을 메모리에 키로 저장하여 중복되는 예약 방지. # 선택 했으면 선택된 정보를 가지고 있어야 함 master_num = len(master_ids) i = 0 while i < master_num: # 랭킹이 높은 홈마스터별로 확인 mid = master_ids[i] master_date_keys = [] # 날짜별 키 생성 for date in date_list: key = '%s_%s' % (mid, date) master_date_keys.append(key) # 저장할 키 생성 booking_item_key = '%s_%s_%d' % (user_id, master_date_keys[0], appointment_type) if holder.store_keys(master_date_keys) and not masterdao.is_master_off_date(mid, selected_date.date()): # 메모리에 키가 하나도 없을 때, 즉 예약이 가능할 때 holder.store(booking_item_key, booking_info) #master_date_keys = ','.join(master_date_keys) if apply_to_all_behind == 0 or appointment_type == 0: # 1회성 booking_time = dt.time(hour = int(time.split(':')[0]), minute = int(time.split(':')[1])) start_time = dt.datetime.combine(selected_date.date(), booking_time) org_master_id = row.master_id changed_master_id = mid row.start_time = start_time row.estimated_end_time = start_time + dt.timedelta(minutes = duration) row.master_id = mid row.additional_task = additional_task if org_master_id != mid: # 기존 마스터님과 다르면 row.is_master_changed = 1 bid = row.id org_time = convert_datetime_format2(org_start_time) changed_time = convert_datetime_format2(start_time) amount = self.get_amount_day_of_week_change(org_start_time, selected_date) row.price += amount row.price_with_task += amount # 추가 결제 하거나, 부분 취소로 대체 mongo_logger.debug('update logs', extra = {'user_id' : user_id, 'org_time' : org_time, 'changed_time' : changed_time, 'booking_id' : bid, 'apply_to_all_behind' : apply_to_all_behind, 'org_master_id' : org_master_id, 'changed_master_id' : changed_master_id, 'by_manager' : by_manager}) else: # 전체 변경 print "idx", appointment_index all_bookings = session.query(Booking) \ .filter(Booking.request_id == request_id) \ .filter(Booking.appointment_index >= appointment_index) \ .filter(Booking.cleaning_status > BC.BOOKING_CANCELED) \ .order_by(Booking.start_time) \ .all() former_bookings = session.query(Booking) \ .filter(Booking.request_id == request_id) \ .filter(Booking.appointment_index < appointment_index) \ .order_by(Booking.start_time) \ .all() for former in former_bookings: former.is_master_changed = 1 amount = self.get_amount_day_of_week_change(org_start_time, selected_date) index = 0 for booking in all_bookings: print 'booking udate loop' if booking.cleaning_status != BC.BOOKING_COMPLETED and booking.cleaning_status != BC.BOOKING_STARTED: booking.is_master_changed = 0 booking_time = dt.time(hour = int(time.split(':')[0]), minute = int(time.split(':')[1])) start_time = dt.datetime.combine(dt.datetime.strptime(date_list[index], '%Y%m%d'), booking_time) org_start_time = booking.start_time org_estimated_end_time = booking.estimated_end_time duration = time_to_minutes(timedelta_to_time(org_estimated_end_time - org_start_time)) org_master_id = booking.master_id changed_master_id = mid booking.master_id = mid booking.org_start_time = start_time booking.start_time = start_time booking.estimated_end_time = start_time + dt.timedelta(minutes = duration) booking.price += amount booking.price_with_task += amount bid = booking.id org_time = convert_datetime_format2(org_start_time) changed_time = convert_datetime_format2(start_time) ''' mongo_logger.debug('update logs', extra = {'user_id' : user_id, 'org_time' : org_time, 'changed_time' : changed_time, 'booking_id' : bid, 'apply_to_all_behind' : apply_to_all_behind, 'org_master_id' : org_master_id, 'changed_master_id' : changed_master_id, 'by_manager' : by_manager}) ''' index += 1 else: continue ret['response'] = Response.SUCCESS self.set_status(Response.RESULT_OK) session.commit() holder.remove(booking_item_key) for sk in master_date_keys: print 'key : ', sk holder.remove(sk) user_name = userdao.get_user_name(user_id) # manager alimtalk #for manager_phone in MANAGERS_CALL.split(','): # send_alimtalk(manager_phone, 'noti_manager_modify_date', user_name, selected_date_str + time) #master_pushkey = masterdao.get_master_pushkey(mid) #send_booking_schedule_updated('android', [master_pushkey], booking_id, selected_date_str + ' ' + time_str) # log to mixpanel mix.track(user_id, 'update schedule', {'user_id' : user_id, 'date' : selected_date_str, 'time' : time, 'booking_id' : booking_id, 'apply_to_all_behind' : apply_to_all_behind}) # log to mongo mongo_logger.debug('update schedule', extra = {'user_id' : user_id, 'date' : selected_date_str, 'time' : time, 'booking_id' : booking_id, 'apply_to_all_behind' : apply_to_all_behind}) return i += 1 # log to mixpanel mix.track(user_id, 'cannot update schedule', {'time' : dt.datetime.now(), 'user_id' : user_id, 'date' : selected_date_str, 'time' : time, 'apply_to_all_behind' : apply_to_all_behind}) # log to mongo mongo_logger.debug('cannot update schedule', extra = {'user_id' : user_id, 'date' : selected_date_str, 'time' : time, 'apply_to_all_behind' : apply_to_all_behind}) # other users preempt homemasters, so no homemaster available self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_homemaster_occupied']) return
def get_mybookings(self, session, user_id, mode): bookings = [] now = dt.datetime.now() bookingdao = BookingDAO() try: if mode == 'upcoming': results = session.query(Booking) \ .group_by(Booking.request_id) \ .having(Booking.user_id == user_id) \ .order_by(func.min(Booking.start_time)) \ .all() for booking_row in results: booking_result = session.query(Booking, Master, User) \ .join(Master, Booking.master_id == Master.id) \ .join(User, Booking.user_id == User.id) \ .filter(Booking.request_id == booking_row.request_id) \ .filter(or_(Booking.cleaning_status == BC.BOOKING_UPCOMMING, Booking.cleaning_status == BC.BOOKING_STARTED, Booking.cleaning_status == BC.BOOKING_CANCELED)) \ .filter(func.date(Booking.start_time) >= now.date()) \ .order_by(Booking.start_time) \ .all() for row in booking_result: tooktime = time_to_minutes( timedelta_to_time(row.Booking.estimated_end_time - row.Booking.start_time)) if row.Booking.appointment_type == BC.ONE_TIME or row.Booking.appointment_type == BC.ONE_TIME_BUT_CONSIDERING: if row.Booking.is_dirty == 1: tooktime -= 120 booking = {} booking['id'] = row.Booking.id booking['request_id'] = row.Booking.request_id booking['index'] = row.Booking.appointment_index booking['devicetype'] = row.User.devicetype booking['datetime'] = convert_datetime_format( row.Booking.start_time) booking['tooktime'] = int(tooktime / 6) # to make 2.5 to 25 booking[ 'additional_task'] = row.Booking.additional_task booking[ 'master_name'] = row.Master.name if row.Master != None else '' booking[ 'master_img_url'] = row.Master.img_url if row.Master != None else '' booking['status'] = row.Booking.cleaning_status booking['payment_status'] = row.Booking.payment_status booking[ 'appointment_type'] = row.Booking.appointment_type booking['cancel_reason'] = bookingdao.get_cancel_reason( row.Booking.id ) if row.Booking.cleaning_status == BC.BOOKING_CANCELED else '' bookings.append(booking) elif mode == 'past': results = session.query(Booking) \ .group_by(Booking.request_id) \ .having(Booking.user_id == user_id) \ .order_by(func.min(Booking.start_time)) \ .all() print now.date() for booking_row in results: booking_result = session.query(Booking, Master) \ .join(Master, Booking.master_id == Master.id) \ .filter(Booking.request_id == booking_row.request_id) \ .filter(or_(Booking.cleaning_status == BC.BOOKING_COMPLETED, Booking.cleaning_status == BC.BOOKING_STARTED, Booking.cleaning_status == BC.BOOKING_CANCELED)) \ .filter(func.date(Booking.start_time) <= now.date()) \ .order_by(Booking.start_time) \ .all() for row in booking_result: if row.Booking.cleaning_status == BC.BOOKING_COMPLETED: end_time = row.Booking.end_time else: end_time = row.Booking.estimated_end_time if row.Booking.working_start_time != None: tooktime = time_to_minutes( timedelta_to_time( end_time - row.Booking.working_start_time)) else: tooktime = time_to_minutes( timedelta_to_time(end_time - row.Booking.start_time)) #if row.Booking.appointment_type == BC.ONE_TIME or row.Booking.appointment_type == BC.ONE_TIME_BUT_CONSIDERING: # if row.Booking.is_dirty == 1: # tooktime -= 120 booking = {} booking['id'] = row.Booking.id booking['request_id'] = row.Booking.request_id booking['index'] = row.Booking.appointment_index booking['datetime'] = convert_datetime_format( row.Booking.start_time) booking['tooktime'] = int(tooktime / 6) # to make 2.5 to 25 booking['havereview'] = row.Booking.havereview booking[ 'additional_task'] = row.Booking.additional_task booking[ 'master_name'] = row.Master.name if row.Master != None else '' booking[ 'master_img_url'] = row.Master.img_url if row.Master != None else '' booking['status'] = row.Booking.cleaning_status booking['payment_status'] = row.Booking.payment_status booking[ 'appointment_type'] = row.Booking.appointment_type booking['cancel_reason'] = bookingdao.get_cancel_reason( row.Booking.id ) if row.Booking.cleaning_status == BC.BOOKING_CANCELED else '' bookings.append(booking) except Exception, e: print_err_detail(e) raise Exception(e)
# time이 변경되었다면 무조건 scheduling if time_changed == '1': date = dt.datetime.strptime(date, '%Y%m%d') start_time_range_begin = int(start_time_range_begin) start_time_range_begin_min = int(start_time_range_begin_min) start_time_range_end = int(start_time_range_end) start_time_range_end_min = int(start_time_range_end_min) appointment_type = 0 # 여기서는 1회 청소로 한다. 편집이기 때문에 start_time = row.start_time end_time = row.estimated_end_time have_pet = row.havepet master_gender = row.master_gender price_with_task = row.price_with_task org_taking_time_in_minutes = time_to_minutes( timedelta_to_time(end_time - start_time)) new_taking_time_in_minutes = org_taking_time_in_minutes + taking_time_in_minutes address, geohash5, geohash6 = userdao.get_user_address(uid) gu_id = addrdao.get_gu_id(address) dates = [int(dt.datetime.strftime(date, '%Y%m%d'))] schedule_by_date_list = masterdao.get_master_schedule_by_dates( gu_id, have_pet, master_gender, dates) success, msg, store_key, search_keys, result = masterdao.find_master_by_score(schedule_by_date_list, \ gu_id, \ uid, \ appointment_type, \ dates, \ start_time_range_begin, \ start_time_range_begin_min, \
def post(self): self.set_header("Content-Type", "application/json") ret = {} booking_id = self.get_argument('booking_id', '') additional_task = self.get_argument('additional_task', '') new_price = self.get_argument('new_price', 0) total_taking_time = self.get_argument('total_taking_time', '') laundry_apply_all = self.get_argument( 'laundry_apply_all', 0) # -2 - 전체없앰 -1 - 하나 없앰, 0 - one time, 1 - all time # convert parameter new_price = int(new_price) additional_task = int(additional_task) total_taking_time = int(total_taking_time) total_taking_time_in_minutes = total_taking_time * 6 laundry_apply_all = int(laundry_apply_all) print 'update additional task params' print booking_id print additional_task print new_price print total_taking_time print laundry_apply_all mix = get_mixpanel() mongo_logger = get_mongo_logger() try: print 'total_minutes :', total_taking_time_in_minutes if total_taking_time_in_minutes >= 720: self.set_status(Response.RESULT_OK) add_err_ko_message_to_response( ret, '클리닝 가능 시간을 초과하였습니다. (최대 12시간) 이전 화면으로 돌아가 추가사항을 2개이하로 줄여주세요.' ) return session = Session() masterdao = MasterDAO() userdao = UserDAO() holder = IntermediateValueHolder() row = session.query(Booking).filter(Booking.id == booking_id).one() uid = row.user_id start_time = row.start_time end_time = row.estimated_end_time request_id = row.request_id appointment_index = row.appointment_index appointment_type = row.appointment_type payment_status = row.payment_status price_with_task = row.price_with_task isdirty = row.is_dirty if isdirty == 1: total_taking_time_in_minutes += 120 org_taking_time_in_minutes = time_to_minutes( timedelta_to_time(end_time - start_time)) is_event = session.query(UserFreeEvent) \ .filter(UserFreeEvent.booking_request_id == request_id) \ .first() is_event = True if is_event != None else False user_name = userdao.get_user_name(uid) # 추가 업무로 인해 소요된 시간이 더 크다면 앞 뒤 일정을 고려. # 고려해서 이동이 가능하다면 추가 업무 할당함. if total_taking_time_in_minutes > org_taking_time_in_minutes: print '2' master_id, time = masterdao.get_masterid_and_starttime_from_booking( booking_id) search_key = '%s_%d' % (master_id, time) new_estimated_end_time = masterdao.is_schedule_extend_available( booking_id, total_taking_time_in_minutes) if new_estimated_end_time != None and holder.store( search_key, 1): # 변경이 가능함. if payment_status == BC.BOOKING_PAID: # 미리 지불한 경우는 취소 하고 다시 결제함 # 전거래 취소 및 재결제 if not (is_event and appointment_index == 1): print 'in this case' cancel_ret_code, msg = cancel_payment( uid, booking_id, price_with_task, partial='0') if cancel_ret_code: pay_ret_code, pay_msg = request_payment( uid, user_name, booking_id, new_price, appointment_type, status='UPDATED') if pay_ret_code: row.tid = pay_msg row.payment_status = BC.BOOKING_PAID else: row.payment_status = BC.BOOKING_PAYMENT_FAILED session.commit() session.close() self.set_status(Response.RESULT_OK) add_err_ko_message_to_response( ret, pay_msg) return else: # 정기 1회 이벤트 일 때 print 'hahaha' charge_amount = new_price - row.price print charge_amount if row.price_with_task != row.price: # 다르면 charge_amount = new_price - row.price_with_task pay_ret_code, pay_msg = request_payment( uid, user_name, booking_id, charge_amount, appointment_type, status='UPDATED') if pay_ret_code: row.tid = pay_msg row.payment_status = BC.BOOKING_PAID else: row.payment_status = BC.BOOKING_PAYMENT_FAILED session.commit() session.close() self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, pay_msg) return row.estimated_end_time = new_estimated_end_time row.additional_task = additional_task row.price_with_task = new_price row.laundry_apply_all = laundry_apply_all session.commit() holder.remove(search_key) else: print '3' session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response( ret, err_dict['err_hm_have_next_schedule']) # 메모리에서 삭제 holder.remove(search_key) return else: # 같거나 작은 경우는 바로 변경 print '4' if payment_status == BC.BOOKING_PAID: # 미리 지불한 경우는 취소 하고 다시 결제함 # 전거래 취소 및 재결제 if not (is_event and appointment_index == 1): cancel_ret_code, msg = cancel_payment(uid, booking_id, price_with_task, partial='0') if cancel_ret_code: user_name = userdao.get_user_name(uid) pay_ret_code, pay_msg = request_payment( uid, user_name, booking_id, new_price, appointment_type, status='UPDATED') if pay_ret_code: row.tid = pay_msg row.payment_status = BC.BOOKING_PAID else: row.payment_status = BC.BOOKING_PAYMENT_FAILED session.commit() session.close() self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, pay_msg) return else: if row.price_with_task != row.price: # 다르면 charge_amount = row.price_with_task - new_price cancel_payment(uid, booking_id, charge_amount, partial='0') row.additional_task = additional_task row.estimated_end_time = end_time + dt.timedelta( minutes=total_taking_time_in_minutes - org_taking_time_in_minutes) row.price_with_task = new_price row.laundry_apply_all = laundry_apply_all # 빨래의 경우는 시간 변경이 없으므로 마지막에 바로 적용 # about laundry print '5' all_upcoming_bookings = session.query(Booking) \ .filter(Booking.request_id == request_id) \ .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \ .filter(Booking.appointment_index >= appointment_index) \ .all() if laundry_apply_all == 1: # 전체 선택 for booking in all_upcoming_bookings: bits = "{0:07b}".format(booking.additional_task) if bits[4] == '0': # 빨래가 세팅되어 있다면 booking.additional_task += 4 # 빨래 booking.laundry_apply_all = laundry_apply_all elif laundry_apply_all == -2: # 선택 해제 for booking in all_upcoming_bookings: bits = "{0:07b}".format(booking.additional_task) if bits[4] == '1': # 빨래가 세팅되어 있다면 booking.additional_task -= 4 # 빨래 제거 booking.laundry_apply_all = laundry_apply_all print '6' session.commit() # alim talk user_name = userdao.get_user_name(uid) additional_task_str = additional_task_string(additional_task) #for manager_phone in MANAGERS_CALL.split(','): # send_alimtalk(manager_phone, 'noti_manager_modify_task', user_name, additional_task_str) # log to mixpanel mix.track( uid, 'update additional task', { 'time': dt.datetime.now(), 'booking_id': booking_id, 'additional_task': additional_task, 'new_price': new_price, 'total_taking_time': total_taking_time, 'laundry_apply_all': laundry_apply_all }) # log to mongo mongo_logger.debug('update additional task', extra={ 'user_id': uid, 'booking_id': booking_id, 'additional_task': additional_task, 'new_price': new_price, 'total_taking_time': total_taking_time, 'laundry_apply_all': laundry_apply_all }) ret['response'] = Response.SUCCESS self.set_status(Response.RESULT_OK) except NoResultFound, e: print_err_detail(e) session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_no_record']) return
cur_date, master['free_to']): # add available time list #while cur_time + dt.timedelta(minutes = taking_time) <= master['free_to']: # add available time list master['available_times'].append( self.time_to_str(cur_time)) # for json serialization cur_time += dt.timedelta(minutes=30) #if master_id == 'e1d543b5-a0d5-4ed0-b5db-24cf63db4453' and dt.datetime.strftime(cur_date, '%Y%m%d') == '20160603': #print cur_date, cur_time else: for i, slot in enumerate(master['occupied_times']): time1 = slot[1] time2 = master['occupied_times'][i + 1][0] if i + 1 < len( master['occupied_times']) else master['free_to'] if time2 > time1 and time_to_minutes( timedelta_to_time(time2 - time1)) > taking_time: geohash1 = slot[2] geohash2 = master['occupied_times'][ i + 1][2] if i + 1 < len( master['occupied_times']) else None moving_time1 = get_moving_time(geohash1, geohash) moving_time2 = get_moving_time(geohash2, geohash) # 앞 뒤 2시간 이상이 걸리거나, 합계로 150분 초과로 걸리는 것 상황은 일을 배정하지 않는다. #if moving_time1 >= 120 or moving_time2 >= 120 or moving_time1 + moving_time2 > 150: # continue cur_time = time1 + dt.timedelta(minutes=moving_time1) while dt.datetime.combine(
def post(self): self.set_header("Content-Type", "application/json") booking_id = self.get_argument('booking_id', '') new_master_id = self.get_argument('new_master_id', '') ret = {} try: session = Session() userdao = UserDAO() addrdao = AddressDAO() masterdao = MasterDAO() holder = IntermediateValueHolder() row = session.query(Booking).filter(Booking.id == booking_id).one() uid = row.user_id master_id_to_change = row.master_id org_start_time = row.start_time org_end_time = row.estimated_end_time appointment_type = 0 # 여기서는 1회 청소로 한다. 편집이기 때문에 have_pet = row.havepet master_gender = row.master_gender addr_idx = row.addr_idx taking_time_in_minutes = time_to_minutes(timedelta_to_time(org_end_time - org_start_time)) address, geohash5, geohash6 = userdao.get_user_address_by_index(uid, addr_idx) gu_id = addrdao.get_gu_id(address) dates = [int(dt.datetime.strftime(org_start_time, '%Y%m%d'))] time_range_begin = org_start_time.hour time_range_begin_min = org_start_time.minute time_range_end = org_start_time.hour time_range_end_min = org_start_time.minute print gu_id, dates print time_range_begin print time_range_begin_min print time_range_end print time_range_end_min print taking_time_in_minutes schedule_by_date_list = masterdao.get_master_schedule_by_dates(gu_id, have_pet, master_gender, dates, new_master_id) print schedule_by_date_list success, msg, store_key, search_keys, result = masterdao.find_master_by_score(schedule_by_date_list, \ gu_id, \ uid, \ appointment_type, \ dates, \ time_range_begin, \ time_range_begin_min, \ time_range_end, \ time_range_end_min, \ taking_time_in_minutes, \ geohash6) if success != 'SUCCESS': session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_no_hm_at_that_time']) #self.write(json.dumps(ret)) print booking_id, ' WAS NOT ... successfully updated to master_id : ', new_master_id return else: row.master_id = result[0]['mid'] if master_id_to_change != row.master_id: row.is_master_changed = 1 session.commit() holder.remove(store_key) for sk in search_keys: holder.remove(sk) ret['response'] = Response.SUCCESS self.set_status(Response.RESULT_OK) print booking_id, ' was successfully updated to master_id : ', new_master_id except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
class MyBookingsDetailHandler(tornado.web.RequestHandler): def get(self): self.set_header("Content-Type", "application/json") booking_id = self.get_argument('booking_id', '') ret = {} mongo_logger = get_mongo_logger() mix = get_mixpanel() try: booking_detail = {} session = Session() print booking_id try: row = session.query(Booking, Master, UserAddress, Promotion, UserCoupon) \ .join(Master, Booking.master_id == Master.id) \ .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \ .outerjoin(Promotion, Booking.id == Promotion.booking_id) \ .outerjoin(UserCoupon, Booking.id == UserCoupon.booking_id) \ .filter(Booking.id == booking_id) \ .one() except NoResultFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_no_record']) return except MultipleResultsFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_multiple_record']) return tooktime = time_to_minutes(timedelta_to_time(row.Booking.estimated_end_time - row.Booking.start_time)) if row.Booking.appointment_type == BC.ONE_TIME or row.Booking.appointment_type == BC.ONE_TIME_BUT_CONSIDERING: if row.Booking.is_dirty == 1: tooktime -= 120 masterdao = MasterDAO() master_name, master_img_url, master_rating = masterdao.get_master_name_img_and_average_rating(row.Master.id) booking_detail['id'] = row.Booking.id booking_detail['index'] = row.Booking.appointment_index booking_detail['havereview'] = row.Booking.havereview booking_detail['master_name'] = master_name booking_detail['master_img_url'] = master_img_url booking_detail['master_img_url'] = master_img_url booking_detail['master_rating'] = str(float(master_rating)) booking_detail['size'] = row.UserAddress.size booking_detail['kind'] = row.UserAddress.kind booking_detail['datetime'] = convert_datetime_format(row.Booking.start_time) booking_detail['tooktime'] = int(tooktime / 6) # to make 2.5 to 25 booking_detail['address_idx'] = row.Booking.addr_idx booking_detail['period'] = row.Booking.appointment_type booking_detail['additional_task'] = row.Booking.additional_task booking_detail['price'] = row.Booking.price booking_detail['actual_price'] = row.Booking.price_with_task booking_detail['card_idx'] = row.Booking.card_idx booking_detail['message'] = row.Booking.message booking_detail['cleaning_status'] = row.Booking.cleaning_status booking_detail['payment_status'] = row.Booking.payment_status booking_detail['promotion_applied'] = 1 if row.Promotion != None else 0 booking_detail['coupon_applied'] = 1 if row.UserCoupon != None else 0 discount_price = 0 if row.UserCoupon != None: discount_price = row.UserCoupon.discount_price price = row.Booking.price_with_task if discount_price <= 100: amount_discount_percent = 100 - discount_price before_price = int(price * 100 / float(amount_discount_percent)) print 'before_price : ', before_price discount_price = int(before_price * float(discount_price) / 100) print 'discount_price : ', discount_price booking_detail['coupon_discount_price'] = discount_price #booking_detail['laundry_apply_all'] = row.Booking.laundry_apply_all start_time = row.Booking.start_time request_id = row.Booking.request_id next_start_time = session.query(Booking.start_time) \ .filter(Booking.request_id == request_id) \ .filter(Booking.start_time > start_time) \ .order_by(Booking.start_time) \ .first() if next_start_time != None: booking_detail['next_datetime'] = dt.datetime.strftime(next_start_time[0], '%Y%m%d %H%M') else: booking_detail['next_datetime'] = '' ret['response'] = booking_detail self.set_status(Response.RESULT_OK) user_id = row.Booking.user_id mix.track(user_id, 'got booking detail', {'time' : dt.datetime.now(), 'id' : row.Booking.id}) mongo_logger.debug('got booking detail', extra = {'user_id' : user_id}) print booking_id, 'successfully retrieved...by', user_id
def post(self): self.set_header("Content-Type", "application/json") ret = {} store_key = self.get_argument('store_key', '') uid = self.get_argument('uid', '') mid = self.get_argument('mid', '') appointment_type = self.get_argument('appointment_type', BC.ONE_TIME) additional_task = self.get_argument('additional_task', 0) discounted_price = self.get_argument('discounted_price', 0) price = self.get_argument('price', 0) price_with_task = self.get_argument('price_with_task', 0) promotion_code = self.get_argument('promotion_code', '') have_pet = self.get_argument('have_pet', 0) search_keys = self.get_argument('search_keys', '') master_gender = self.get_argument('master_gender', 0) isdirty = self.get_argument('isdirty', 0) first_added_time = self.get_argument('first_added_time', 0) additional_time = self.get_argument('additional_time', 10) laundry_apply_all = self.get_argument('laundry_apply_all', 0) # -1 - 없앰, 0 - one time, 1 - all time # convert datetime appointment_type = int(appointment_type) additional_task = int(additional_task) price = int(price) price_with_task = int(price_with_task) discounted_price = int(discounted_price) have_pet = int(have_pet) master_gender = int(master_gender) isdirty = int(isdirty) laundry_apply_all = int(laundry_apply_all) first_added_time = int(first_added_time) additional_time = int(additional_time) first_added_time_in_minutes = first_added_time * 6 additional_time_in_minutes = additional_time * 6 print first_added_time, additional_time search_keys = search_keys.split(',') havetools = 1 if additional_task >= 64: havetools = 0 mongo_logger = get_mongo_logger() mongo_logger.debug('%s request booking' % uid, extra = { 'uid' : uid, 'mid' : mid, 'appointment_type' : appointment_type, 'have_pet' : have_pet, 'master_gender' : master_gender, 'isdirty' : isdirty}) mix = get_mixpanel() try: session = Session() userdao = UserDAO() promotiondao = PromotionDAO() holder = IntermediateValueHolder() card_idx = 0 addr_idx = 0 # get card and address idx addr_idx = userdao.get_user_default_address_index(uid) card_idx = userdao.get_user_default_card_index(uid) # hasids to generate unique booking id now = dt.datetime.strftime(dt.datetime.now(), '%Y%m%d%H%M%S') hashids = Hashids(min_length = 16, salt = now + uid) print 'salt : ', now + uid # request id to group each individual bookings request_id = str(uuid.uuid4()) obj = holder.retrieve(store_key) if obj == None: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_booking_timeout']) mix.track(uid, 'request timeout', {'time' : dt.datetime.now()}) mongo_logger.error('%s got timed out' % uid) self.write(json.dumps(ret)) return i = 1 booking_ids = [] start_time_list = [] obj = sorted(obj, key = lambda x: x['date']) for item in obj: print item['date'] booking_id = hashids.encode(int(item['date'] + time_to_str(item['start_time']))) master_id = item['mid'] dow = dt.datetime.strptime(item['date'], '%Y%m%d').date().weekday() start_time = dt.datetime.combine(dt.datetime.strptime(item['date'], '%Y%m%d'), item['start_time']) estimated_end_time = dt.datetime.combine(dt.datetime.strptime(item['date'], '%Y%m%d'), item['end_time']) cleaning_duration = time_to_minutes(timedelta_to_time(estimated_end_time - dt.timedelta(minutes=additional_time_in_minutes + first_added_time_in_minutes) - start_time)) actual_price = 0 if i == 1: # 1 번째 클리닝 actual_price = price_with_task - discounted_price # 할인은 1회만 적용됨 else: # 나머지 actual_price = price if havetools == 1: additional_task = 0 else: additional_task = 64 #actual_price += BC.VACCUM_CHARGE if laundry_apply_all == 1: additional_task += 4 # 빨래 isdirty = 0 # 첫째 이후에는 is dirty는 0 estimated_end_time = estimated_end_time - dt.timedelta(minutes=additional_time_in_minutes + first_added_time_in_minutes) booking = Booking(id = booking_id, request_id = request_id, user_id = uid, master_id = mid, appointment_type = appointment_type, appointment_index = i, dow = dow, booking_time = dt.datetime.now(), org_start_time = start_time, start_time = start_time, estimated_end_time = estimated_end_time, end_time = estimated_end_time, # update after homemaster finish their job cleaning_duration = cleaning_duration, additional_task = additional_task, price = price, price_with_task = actual_price, charging_price = 0, card_idx = card_idx, addr_idx = addr_idx, havetools = havetools, havepet = have_pet, laundry_apply_all = laundry_apply_all, is_dirty = isdirty, master_gender = master_gender, status = BC.BOOKING_UPCOMMING, cleaning_status = BC.BOOKING_UPCOMMING, payment_status = BC.BOOKING_UNPAID_YET) i += 1 session.add(booking) booking_ids.append(booking_id) start_time_list.append(start_time) #print 'booking_id', booking_id, 'was added..' # charge for first appointment date user_name = userdao.get_user_name(uid) if price_with_task - discounted_price <= 0: ret_code = True msg = '' else: ret_code, msg = request_payment(uid, user_name, booking_ids[0], price_with_task - discounted_price, appointment_type) # 결제 정보 출력 print user_name, ret_code, msg if ret_code: session.commit() # remove store_key and related_keys holder.remove(store_key) for sk in search_keys: holder.remove(sk) # promotion code 와 연결 if promotion_code != '': promotiondao.set_promotion_code_status(promotion_code, 1, booking_ids[0], price_with_task) # change status to paid try: first_booking = session.query(Booking).filter(Booking.id == booking_ids[0]).one() except NoResultFound, e: session.close() self.set_status(Response.RESULT_OK) mongo_logger.debug('no first booking record', extra = { 'uid' : uid, 'mid' : mid,'appointment_type' : appointment_type, 'have_pet' : have_pet, 'master_gender' : master_gender, 'isdirty' : isdirty}) add_err_message_to_response(ret, err_dict['err_no_record']) return except MultipleResultsFound, e: session.close() self.set_status(Response.RESULT_OK) mongo_logger.debug('multiple first booking record', extra = { 'uid' : uid, 'mid' : mid, 'appointment_type' : appointment_type, 'have_pet' : have_pet, 'master_gender' : master_gender, 'isdirty' : isdirty}) add_err_message_to_response(ret, err_dict['err_multiple_record']) return
def get_mybookings(self, session, user_id, mode): bookings = [] try: if mode == 'upcoming': results = session.query(Booking) \ .group_by(Booking.request_id) \ .having(Booking.user_id == user_id) \ .order_by(func.min(Booking.start_time)) \ .all() for booking_row in results: booking_result = session.query(Booking, Master, User) \ .join(Master, Booking.master_id == Master.id) \ .join(User, Booking.user_id == User.id) \ .filter(Booking.request_id == booking_row.request_id) \ .filter(or_(Booking.cleaning_status == BC.BOOKING_UPCOMMING, Booking.cleaning_status == BC.BOOKING_STARTED)) \ .order_by(Booking.start_time) \ .all() for row in booking_result: try: tooktime = time_to_minutes(timedelta_to_time(row.Booking.estimated_end_time - row.Booking.start_time)) except Exception, e: print_err_detail(e) tooktime = 180 if row.Booking.appointment_type == BC.ONE_TIME or row.Booking.appointment_type == BC.ONE_TIME_BUT_CONSIDERING: if row.Booking.is_dirty == 1: tooktime -= 120 booking = {} booking['id'] = row.Booking.id booking['request_id'] = row.Booking.request_id booking['index'] = row.Booking.appointment_index booking['devicetype'] = row.User.devicetype booking['datetime'] = convert_datetime_format(row.Booking.start_time) booking['tooktime'] = int(tooktime / 6) # to make 2.5 to 25 booking['additional_task'] = row.Booking.additional_task booking['master_name'] = row.Master.name if row.Master != None else '' booking['master_img_url'] = row.Master.img_url if row.Master != None else '' bookings.append(booking) elif mode == 'cancel': results = session.query(Booking) \ .group_by(Booking.request_id) \ .having(Booking.user_id == user_id) \ .order_by(func.min(Booking.start_time)) \ .all() for booking_row in results: booking_result = session.query(Booking, Master, User) \ .join(Master, Booking.master_id == Master.id) \ .join(User, Booking.user_id == User.id) \ .filter(Booking.request_id == booking_row.request_id) \ .filter(Booking.cleaning_status == BC.BOOKING_CANCELED) \ .order_by(Booking.start_time) \ .all() for row in booking_result: try: tooktime = time_to_minutes(timedelta_to_time(row.Booking.estimated_end_time - row.Booking.start_time)) except Exception, e: print_err_detail(e) tooktime = 180 if row.Booking.appointment_type == BC.ONE_TIME or row.Booking.appointment_type == BC.ONE_TIME_BUT_CONSIDERING: if row.Booking.is_dirty == 1: tooktime -= 120 booking = {} booking['id'] = row.Booking.id booking['request_id'] = row.Booking.request_id booking['index'] = row.Booking.appointment_index booking['devicetype'] = row.User.devicetype booking['datetime'] = convert_datetime_format(row.Booking.start_time) booking['tooktime'] = int(tooktime / 6) # to make 2.5 to 25 booking['additional_task'] = row.Booking.additional_task booking['master_name'] = row.Master.name if row.Master != None else '' booking['master_img_url'] = row.Master.img_url if row.Master != None else '' bookings.append(booking)
results = session.query(Booking) \ .group_by(Booking.request_id) \ .having(Booking.user_id == user_id) \ .order_by(func.min(Booking.start_time)) \ .all() for booking_row in results: booking_result = session.query(Booking, Master) \ .join(Master, Booking.master_id == Master.id) \ .filter(Booking.request_id == booking_row.request_id) \ .filter(Booking.cleaning_status == BC.BOOKING_COMPLETED) \ .order_by(Booking.start_time) \ .all() for row in booking_result: try: tooktime = time_to_minutes(timedelta_to_time(row.Booking.estimated_end_time - row.Booking.start_time)) except Exception, e: print_err_detail(e) tooktime = 180 #if row.Booking.appointment_type == BC.ONE_TIME or row.Booking.appointment_type == BC.ONE_TIME_BUT_CONSIDERING: # if row.Booking.is_dirty == 1: # tooktime -= 120 # 클리닝 및 홈마스터 평가를 클리닝 후 2일 이내로 제한 두기 havereview = row.Booking.havereview if row.Booking.havereview == 0: diff = now - row.Booking.end_time havereview = 0 if diff.days < 2 else 1 booking = {}
def post(self): self.set_header("Content-Type", "application/json") master_id = self.get_argument('master_id', '') ret = {} # 해당 마스터의 상태를 deactivate 시킨다. # 남아있는 일정이 있다면 모든 일정을 다른 마스터에게 양도 한다. try: session = Session() userdao = UserDAO() addrdao = AddressDAO() masterdao = MasterDAO() holder = IntermediateValueHolder() # deactivate master row = session.query(Master).filter(Master.id == master_id).one() row.active = 0 session.commit() # automatically assign that master's remain jobs to other masters masterdao = MasterDAO() request_ids = masterdao.get_distinct_req_ids(master_id) matched_booking_groups = [] unmatched_booking_groups = [] for req_id in request_ids: reqs = session.query(Booking, User, UserAddress) \ .join(User, User.id == Booking.user_id) \ .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \ .filter(Booking.request_id == req_id).filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \ .order_by(Booking.start_time) \ .all() key = userdao.get_user_salt_by_id(reqs.User.id)[:16] crypto = aes.MyCrypto(key) dates = [] datetimes = [] max_taking_time_in_minutes = 0 for item in reqs: appointment_type = item.Booking.appointment_type address = crypto.decodeAES(item.UserAddress.address) geohash5 = item.UserAddress.geohash5 geohash6 = item.UserAddress.geohash6 start_time = item.Booking.start_time end_time = item.Booking.estimated_end_time # 최대 시간 기준으로 할당을 잡음 taking_time_in_minutes = time_to_minutes( timedelta_to_time(end_time - start_time)) if taking_time_in_minutes > max_taking_time_in_minutes: max_taking_time_in_minutes = taking_time_in_minutes gu_id = addrdao.get_gu_id(address) dates.append( int(dt.datetime.strftime(start_time, '%Y%m%d'))) datetimes.append(start_time) uid = item.Booking.user_id time_range_begin = datetimes[0].hour time_range_begin_min = datetimes[0].minute time_range_end = datetimes[0].hour time_range_end_min = datetimes[0].minute have_pet = item.Booking.havepet master_gedner = item.Booking.master_gender schedule_by_date_list = masterdao.get_master_schedule_by_dates( gu_id, have_pet, master_gender, dates) success, msg, store_key, search_keys, result = masterdao.find_master_by_score(schedule_by_date_list, \ gu_id, \ uid, \ appointment_type, \ dates, \ time_range_begin, \ time_range_begin_min, \ time_range_end, \ time_range_end_min, \ max_taking_time_in_minutes, \ geohash6) if success == 'SUCCESS': matched_booking_groups.append(req_id) matched_list = session.query(Booking) \ .filter(Booking.request_id == req_id) \ .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \ .all() for match in matched_list: match.master_id = result[0]['mid'] session.commit() holder.remove(store_key) for sk in search_keys: holder.remove(sk) else: unmatched_booking_groups.append(req_id) unmatched_list = session.query(Booking) \ .filter(Booking.request_id == req_id) \ .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \ .all() for unmatch in unmatched_list: print unmatch unmatch.master_id = None session.commit() ret['response'] = { 'matched_group': matched_booking_groups, 'unmatched_group': unmatched_booking_groups } self.set_status(Response.RESULT_OK) except NoResultFound, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_no_record'])