def get(self):
        self.set_header("Content-Type", "application/json")
        self.set_header('Access-Control-Allow-Origin', '*')

        user_id = self.get_argument('user_id', '')
        havepet = self.get_argument('havepet', '')
        master_gender = self.get_argument('master_gender', '')

        havepet = int(havepet)
        master_gender = int(master_gender)

        ret = {}

        try:
            session = Session()
            userdao = UserDAO()
            addressdao = AddressDAO()

            masters = []

            row = session.query(UserDefaultAddress) \
                        .filter(UserDefaultAddress.user_id == user_id) \
                        .one()

            address, _, _ = userdao.get_user_address_by_index(
                user_id, row.address_idx)

            gu_id = addressdao.get_gu_id(address)

            pet_filter = 2
            if havepet == 1:
                pet_filter = 1

            gender_filter = 2
            if master_gender == 1:
                gender_filter = 0

            result = session.query(Master, MasterPreferedArea) \
                            .join(MasterPreferedArea, Master.id == MasterPreferedArea.master_id) \
                            .filter(Master.active == 1) \
                            .filter(Master.pet_alergy != pet_filter) \
                            .filter(Master.gender != gender_filter) \
                            .filter(MasterPreferedArea.prefered_gu == gu_id) \
                            .order_by(Master.name) \
                            .all()

            for row in result:
                masters.append({'id': row.Master.id, 'name': row.Master.name})

            ret['response'] = masters
            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'])
Ejemplo n.º 2
0
    def post(self):
        self.set_header("Content-Type", "application/json")

        ret = {}

        uid     = self.get_argument('user_id', '')
        master_gender    = self.get_argument('master_gender', 1)

        mongo_logger = get_mongo_logger()
        master_gender = int(master_gender)
        
        if master_gender == 2: # 남자일 경우 남자코드인 0으로 변경
            master_gender = 0

        try:
            session = Session()

            userdao = UserDAO()
            addressdao = AddressDAO()

            address = userdao.get_user_address(uid)[0]
            gu_id = addressdao.get_gu_id(address)

            master_count_by_gender = session.query(MasterPreferedArea, Master) \
                    .join(Master, MasterPreferedArea.master_id == Master.id) \
                    .filter(MasterPreferedArea.prefered_gu == gu_id) \
                    .filter(Master.gender == master_gender) \
                    .filter(Master.active == 1) \
                    .count()

            ret['response'] = {'master_count_by_gender' : master_count_by_gender}
            self.set_status(Response.RESULT_OK)

            print uid, 'request master gender, value of ', master_gender, master_count_by_gender
            mongo_logger.debug('%s request master gender count' % uid, extra={'user_id' : uid, 'master_gender' : master_gender})

        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'])
            mongo_logger.error('%s failed to posted memo' % uid, extra = {'err' : str(e)})
Ejemplo n.º 3
0
    def post(self):
        self.set_header("Content-Type", "application/json")

        uid = self.get_argument('uid', '')
        taking_time = self.get_argument('taking_time', 25)
        additional_time = self.get_argument('additional_time', 10)
        appointment_type = self.get_argument('appointment_type', 0)
        have_pet = self.get_argument('have_pet', 0)
        master_gender = self.get_argument('master_gender', 0)
        isdirty = self.get_argument('isdirty', 0)

        # convert
        appointment_type = int(appointment_type)
        have_pet = int(have_pet)

        taking_time = int(taking_time)
        additional_time = int(additional_time)
        taking_time_in_minutes = taking_time * 6
        additional_time_in_minutes = additional_time * 6
        total_taking_time_in_minutes = taking_time_in_minutes + additional_time_in_minutes

        master_gender = int(master_gender)  # 0 dont care 1 women 2 men
        isdirty = int(isdirty)

        ret = {}

        print 'recommend schedule'
        print 'taking time :', taking_time_in_minutes

        mongo_logger = get_mongo_logger()

        mongo_logger.debug('%s request recommendation' % uid,
                           extra={
                               'taking_time': taking_time,
                               'additional_time': additional_time,
                               'appointment_type': appointment_type,
                               'have_pet': have_pet,
                               'master_gender': master_gender,
                               'isdirty': isdirty
                           })

        mix = get_mixpanel()

        try:
            session = Session()

            userdao = UserDAO()
            addrdao = AddressDAO()
            masterdao = MasterDAO()

            holder = IntermediateValueHolder()

            # request id to group each individual bookings
            request_id = str(uuid.uuid4())

            # get user's address and cover address to gu code
            address, geohash5, geohash6 = userdao.get_user_address(uid)
            gu_id = addrdao.get_gu_id(address)

            start_time_range_begin = 8
            start_time_range_end = 18

            # 똥집인 경우 3시간 추가됨.
            if isdirty == 1:
                if appointment_type == BC.ONE_TIME or appointment_type == BC.ONE_TIME_BUT_CONSIDERING:
                    total_taking_time_in_minutes += 120

            #get available homemaster's time table day by day
            schedule_by_date_list = masterdao.get_recommended_schedule(
                gu_id, have_pet, master_gender, appointment_type, geohash6,
                dt.datetime.now().date())
            success, msg, store_key, search_keys, result = masterdao.find_master_by_score(schedule_by_date_list, \
                                                gu_id, \
                                                uid, \
                                                appointment_type, \
                                                None, \
                                                start_time_range_begin, \
                                                0,
                                                start_time_range_end, \
                                                0,
                                                total_taking_time_in_minutes, \
                                                geohash6,
                                                True)

            # if not successful
            if success != 'SUCCESS':
                print 'haha no recommendation.....'
                self.set_status(Response.RESULT_OK)
                ret['response'] = 'NoRecommendation'
                mongo_logger.error('have no recommendation',
                                   extra={'err': msg})
                #add_err_message_to_response(ret, err_dict['err_hm_no_recommendation'])
                #self.write(json.dumps(ret))
                return
            else:
                schedules = []

                for row in result:
                    s = {}
                    s['date'] = row['date']
                    s['start_time'] = time_to_str(row['start_time'])
                    s['end_time'] = time_to_str(row['end_time'])

                    schedules.append(s)

                # 스케쥴이 이미 해당 날짜에 있다면, 있다고 표시하고 리턴함
                num_schedules_on_dates = userdao.get_user_schedule_on_dates(
                    uid, [
                        dt.datetime.strptime(str(s['date']), '%Y%m%d').date()
                        for s in schedules
                    ])
                if num_schedules_on_dates > 0:
                    print 'already have appointment on that days, no recommendation.....'

                    holder.remove(store_key)
                    for sk in search_keys:
                        holder.remove(sk)

                    self.set_status(Response.RESULT_OK)
                    ret['response'] = 'NoRecommendation'
                    mongo_logger.error(
                        'have no recommendation',
                        extra={'err': 'already have cleaning on that day'})
                    #add_err_message_to_response(ret, err_dict['err_hm_no_recommendation'])
                    #self.write(json.dumps(ret))
                    return

                mid = row['mid']
                name, img_url, avg_rating = masterdao.get_master_name_img_and_average_rating(
                    mid)

                search_keys_str = ','.join(search_keys)
                print 'search key string :', search_keys_str
                ret['response'] = {
                    'store_key': store_key,
                    'search_keys': search_keys_str,
                    'schedules': schedules,
                    'uid': uid,
                    'mid': row['mid'],
                    'name': name,
                    'img_url': img_url,
                    'avg_rating': str(float(avg_rating))
                }

                mix.track(uid, 'recommend', {
                    'time': dt.datetime.now(),
                    'master_gender': master_gender
                })
                mongo_logger.debug('%s got recommendation' % uid,
                                   extra={'user_id': uid})

                self.set_status(Response.RESULT_OK)

                print uid, 'got recommendation '

                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'])
            mongo_logger.error('error occurred when make recommendation',
                               extra={'err': str(e)})

            # if error occur, then remove all keys
            holder.remove(store_key)
            for sk in search_keys:
                holder.remove(sk)
    def post(self):
        self.set_header("Content-Type", "application/json")

        ret = {}

        uid = self.get_argument('uid', '')
        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)
        appointment_type = self.get_argument('appointment_type', BC.ONE_TIME)
        taking_time = self.get_argument('taking_time', 25)
        first_added_time = self.get_argument('first_added_time', 0)
        additional_time = self.get_argument('additional_time', 10)
        have_pet = self.get_argument('have_pet', 0)
        master_gender = self.get_argument('master_gender', 0)
        isdirty = self.get_argument('isdirty', 0)

        # convert datetime
        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 = int(appointment_type)
        taking_time = int(taking_time)
        first_added_time = int(first_added_time)
        additional_time = int(additional_time)

        taking_time_in_minutes = taking_time * 6
        first_added_time_in_minutes = first_added_time * 6
        additional_time_in_minutes = additional_time * 6
        total_taking_time_in_minutes = taking_time_in_minutes + first_added_time_in_minutes + additional_time_in_minutes

        have_pet = int(have_pet)
        master_gender = int(master_gender)  # 0 dont care 1 women 2 men
        isdirty = int(isdirty)

        print 'request schedule'
        print 'taking time :', taking_time_in_minutes

        mongo_logger = get_mongo_logger()

        mongo_logger.debug('%s request schedule' % uid,
                           extra={
                               'date': dt.datetime.strftime(date, '%Y%m%d'),
                               'start_time_range_begin':
                               start_time_range_begin,
                               'start_time_range_end': start_time_range_end,
                               'taking_time': taking_time,
                               'additional_time': additional_time,
                               'appointment_type': appointment_type,
                               'have_pet': have_pet,
                               'master_gender': master_gender,
                               'isdirty': isdirty
                           })

        mix = get_mixpanel()

        try:
            session = Session()

            userdao = UserDAO()
            addrdao = AddressDAO()
            masterdao = MasterDAO()

            holder = IntermediateValueHolder()

            # request id to group each individual bookings
            request_id = str(uuid.uuid4())

            # get user's address and cover address to gu code
            address, geohash5, geohash6 = userdao.get_user_address(uid)
            gu_id = addrdao.get_gu_id(address)

            # four consecutive appointment days to make booking if regular , otherwise just one day
            dates = [int(dt.datetime.strftime(date, '%Y%m%d'))]

            if appointment_type == BC.ONE_TIME_A_MONTH or appointment_type == BC.TWO_TIME_A_MONTH or appointment_type == BC.FOUR_TIME_A_MONTH:
                dates = [
                    int(
                        dt.datetime.strftime(
                            date + dt.timedelta(days=i * BC.DAYS_IN_A_WEEK *
                                                (4 / appointment_type)),
                            '%Y%m%d')) for i in xrange(4)
                ]

            # 크리스마스 및 새해 임시로 막음.
            if date.date() == dt.date(2016, 2, 7) or date.date() == dt.date(
                    2016, 2, 8) or date.date() == dt.date(
                        2016, 2, 9) or date.date() == dt.date(2016, 2, 10):
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(ret, '설날 연휴동안은, 예약이 불가능합니다.')
                self.write(json.dumps(ret))
                return

            # 스케쥴이 이미 해당 날짜에 있다면, 있다고 표시하고 리턴함
            num_schedules_on_dates = userdao.get_user_schedule_on_dates(
                uid,
                [dt.datetime.strptime(str(d), '%Y%m%d').date() for d in dates])
            if num_schedules_on_dates > 0:
                self.set_status(Response.RESULT_OK)
                add_err_message_to_response(ret,
                                            err_dict['err_schedules_on_dates'])
                self.write(json.dumps(ret))
                return

            # 똥집인 경우 3시간 추가됨.
            if isdirty == 1:
                if appointment_type == BC.ONE_TIME or appointment_type == BC.ONE_TIME_BUT_CONSIDERING:
                    total_taking_time_in_minutes += 120

            print 'gu_id', gu_id, have_pet, master_gender, dates

            #get available homemaster's time table day by day
            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, \
                                                total_taking_time_in_minutes, \
                                                geohash6)

            # if not successful
            if success != 'SUCCESS':
                self.set_status(Response.RESULT_OK)
                add_err_message_to_response(ret,
                                            err_dict['err_no_hm_at_that_time'])
                mix.track(
                    uid, 'request schedule', {
                        'time': dt.datetime.now(),
                        'date': dt.datetime.strftime(date, '%Y%m%d'),
                        'start_time_range_begin': start_time_range_begin,
                        'start_time_range_begin_min':
                        start_time_range_begin_min,
                        'start_time_range_end': start_time_range_end,
                        'start_time_range_end_min': start_time_range_end_min,
                        'taking_time': taking_time,
                        'additional_time': additional_time,
                        'appointment_type': appointment_type,
                        'have_pet': have_pet,
                        'master_gender': master_gender,
                        'isdirty': isdirty,
                        'status': 'no homemaster'
                    })
                print uid, 'was not able to find any homemasters....'
            else:
                schedules = []

                for row in result:
                    s = {}
                    s['date'] = row['date']
                    s['start_time'] = time_to_str(row['start_time'])
                    s['end_time'] = time_to_str(row['end_time'])

                    schedules.append(s)

                mid = row['mid']
                name, img_url, avg_rating = masterdao.get_master_name_img_and_average_rating(
                    mid)

                search_keys_str = ','.join(search_keys)
                ret['response'] = {
                    'store_key': store_key,
                    'search_keys': search_keys_str,
                    'schedules': schedules,
                    'uid': uid,
                    'mid': row['mid'],
                    'name': name,
                    'img_url': img_url,
                    'avg_rating': str(float(avg_rating))
                }
                print uid, 'successfully made booking requests...'

                mix.track(
                    uid, 'request schedule', {
                        'time': dt.datetime.now(),
                        'date': dt.datetime.strftime(date, '%Y%m%d'),
                        'start_time_range_begin': start_time_range_begin,
                        'start_time_range_begin_min':
                        start_time_range_begin_min,
                        'start_time_range_end': start_time_range_end,
                        'start_time_range_end_min': start_time_range_end_min,
                        'taking_time': taking_time,
                        'additional_time': additional_time,
                        'appointment_type': appointment_type,
                        'have_pet': have_pet,
                        'master_gender': master_gender,
                        'isdirty': isdirty,
                        'status': 'find homemaster'
                    })
                mongo_logger.debug('%s made booking requests' % uid,
                                   extra={'user_id': uid})

            self.set_status(Response.RESULT_OK)

        except Exception, e:
            session.rollback()
            add_err_message_to_response(ret, err_dict['err_mysql'])
            self.set_status(Response.RESULT_SERVERERROR)
            print_err_detail(e)
            mongo_logger.error('error occurred when request schedule',
                               extra={'err': str(e)})

            # if error occur, then remove all keys
            holder.remove(store_key)
            for sk in search_keys:
                holder.remove(sk)
    def post(self):
        self.set_header("Content-Type", "application/json")
        self.set_header('Access-Control-Allow-Origin', '*')

        ret = {}

        uid                         = self.get_argument('uid', '')
        appointment_type            = self.get_argument('appointment_type', BC.ONE_TIME)
        taking_time                 = self.get_argument('taking_time', 25)
        first_added_time            = self.get_argument('first_added_time', 0)
        additional_time             = self.get_argument('additional_time', 10)
        have_pet                    = self.get_argument('have_pet', 0)
        master_gender               = self.get_argument('master_gender', 0)
        isdirty                     = self.get_argument('isdirty', 0)
        for_manager                 = self.get_argument('for_manager', '')

        # for address parameter
        address = self.get_argument('address', '')
        size    = self.get_argument('size', 25)
        kind    = self.get_argument('kind', 0)

        size = int(size)
        kind = int(kind)

        # convert parameters
        appointment_type                = int(appointment_type)
        taking_time                     = int(taking_time)
        first_added_time                = int(first_added_time)
        additional_time                 = int(additional_time)

        taking_time_in_minutes          = taking_time * 6
        first_added_time_in_minutes     = first_added_time * 6
        additional_time_in_minutes      = additional_time * 6
        total_taking_time_in_minutes    = taking_time_in_minutes + first_added_time_in_minutes + additional_time_in_minutes

        have_pet                        = int(have_pet)
        master_gender                   = int(master_gender) # 0 dont care 1 women
        isdirty                         = int(isdirty)


        # logging part
        mix = get_mixpanel()
        mongo_logger = get_mongo_logger()

        try:
            print uid
            if self.is_user_block(ret, uid) == True:
                return

            if appointment_type == BC.ONE_TIME_A_MONTH:
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(ret, '4주 1회 서비스는 신규 예약을 지원하지 않습니다.')
                mongo_logger.debug('not booking one time a month', extra = { 'user_id' : uid })
                ret['err_code'] = '4038' # 임시 처리
                return

            if total_taking_time_in_minutes <= 0 or taking_time_in_minutes <= 0:
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(ret, '클리닝 시간이 잘못 설정되었습니다.')
                ret['err_code'] = '9999' # 임시 처리
                return


            if total_taking_time_in_minutes >= 600:
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(ret, '클리닝 가능 시간을 초과하였습니다. (최대 10시간) 이전 화면으로 돌아가 추가사항을 2개이하로 줄여주세요.')
                ret['err_code'] = '4036' # 임시 처리
                return

            scheduler = HMScheduler()

            session = Session()
            userdao = UserDAO()
            addrdao = AddressDAO()

            # add user address
            latlng = get_latlng_from_address(address)
            if len(latlng) > 1:
                latitude = latlng[0]
                longitude = latlng[1]

                geohash5 = get_geohash(latitude, longitude, 5)
                geohash6 = get_geohash(latitude, longitude, 6)
            else:
                latitude = 0.0
                longitude = 0.0
                geohash5 = ''
                geohash6 = ''

            key = userdao.get_user_salt_by_id(uid)[:16]
            crypto = aes.MyCrypto(key)

            encrypted_address = crypto.encodeAES(str(address))

            count = session.query(UserAddress).filter(UserAddress.user_id == uid).count()
            last_index = session.query(UserAddress).filter(UserAddress.user_id == uid).order_by(desc(UserAddress.user_addr_index)).first()

            index = 0
            if last_index != None:
                index = last_index.user_addr_index + 1

            new_address = UserAddress(user_id = uid, address = encrypted_address, size = size, kind = kind,
                                        user_addr_index = index, latitude = latitude, longitude = longitude,
                                        geohash5 = geohash5, geohash6 = geohash6)
            session.add(new_address)
            session.commit()

            # set default address index
            if count == 0:
                new_default_address = UserDefaultAddress(user_id=uid, address_idx=index)
                session.add(new_default_address)
            else:
                record = session.query(UserDefaultAddress).filter(UserDefaultAddress.user_id == uid).one()
                record.address_idx = index

            session.commit()

            address, geohash5, geohash6 = userdao.get_user_address(uid)
            _, size, kind = userdao.get_user_address_detail(uid)

            gu_id = addrdao.get_gu_id(address)

            if gu_id == '':
                raise Exception('gu id is incorrect')
                return

            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)


            now = dt.datetime.now()
            if now.hour >= 17: # 7시 이후 라면 -> 5시로 변경 2016.06.03
                if for_manager == '': # 사용자 앱에서는 내일 예약 불가능
                    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']
            # log to mixpanel
            mix.track(uid, 'request available schedule', {'time' : dt.datetime.now(), 'taking_time' : taking_time, 'additional_time' : additional_time, 'appointment_type' : appointment_type, 'have_pet' : have_pet, 'master_gender' : master_gender,'isdirty' : isdirty})

            # log to mongo
            mongo_logger.debug('request available schedule', extra = {'log_time' : dt.datetime.now(),  'user_id' : uid, 'taking_time' : taking_time, 'additional_time' : additional_time, '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'])

                mongo_logger.debug('no masters', extra = {'log_time' : dt.datetime.now(), 'user_id' : uid, 'taking_time' : total_taking_time_in_minutes, 'gu_id' : gu_id, 'address' : address})
                user_name = userdao.get_user_name(uid)
                user_phone = userdao.get_user_phone(uid)
                send_jandi('BOOKING_NOT_AVAILABE', '예약 불가능 알림', '고객 : {} 전번 : {}'.format(user_name, user_phone),
                            '주기 : {}, 주소 : {}'.format(appointment_type, address))

            self.set_status(Response.RESULT_OK)
        except Exception, e:
            add_err_message_to_response(ret, err_dict['err_mysql'])
            self.set_status(Response.RESULT_SERVERERROR)
            print_err_detail(e)
            mongo_logger.error('error request available schedules', extra = {'user_id' : uid, 'err' : str(e)})
Ejemplo n.º 6
0
    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'])
    def post(self):
        self.set_header("Content-Type", "application/json")
        self.set_header('Access-Control-Allow-Origin', '*')

        ret = {}

        uid                         = self.get_argument('uid', '')
        appointment_type            = self.get_argument('appointment_type', BC.ONE_TIME)
        taking_time                 = self.get_argument('taking_time', 25)
        first_added_time            = self.get_argument('first_added_time', 0)
        additional_time             = self.get_argument('additional_time', 0)
        have_pet                    = self.get_argument('have_pet', 0)
        master_gender               = self.get_argument('master_gender', 0)
        isdirty                     = self.get_argument('isdirty', 0)
        for_manager                 = self.get_argument('for_manager', '')

        # for b2b appointment
        user_address_idx            = self.get_argument('user_address_idx', -1)
        b2b                         = self.get_argument('b2b', '')

        # convert parameters
        appointment_type                = int(appointment_type)
        taking_time                     = int(taking_time)
        first_added_time                = int(first_added_time)
        additional_time                 = int(additional_time)

        taking_time_in_minutes          = taking_time * 6
        first_added_time_in_minutes     = first_added_time * 6
        additional_time_in_minutes      = additional_time * 6
        total_taking_time_in_minutes    = taking_time_in_minutes + first_added_time_in_minutes + additional_time_in_minutes

        have_pet                        = int(have_pet)
        master_gender                   = int(master_gender) # 0 dont care 1 women
        isdirty                         = int(isdirty)


        # logging part
        mix = get_mixpanel()
        mongo_logger = get_mongo_logger()

        try:
            if self.is_user_block(ret, uid) == True:
                return

            if appointment_type == BC.ONE_TIME_A_MONTH and b2b != 'b2b':
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(ret, '4주 1회 서비스는 신규 예약을 지원하지 않습니다.')
                mongo_logger.debug('not booking one time a month', extra = { 'user_id' : uid })
                ret['err_code'] = '4038' # 임시 처리
                return


            if total_taking_time_in_minutes >= 600:
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(ret, '클리닝 가능 시간을 초과하였습니다. (최대 10시간) 이전 화면으로 돌아가 추가사항을 2개이하로 줄여주세요.')
                ret['err_code'] = '4036' # 임시 처리
                return

            scheduler = HMScheduler()

            userdao = UserDAO()
            addrdao = AddressDAO()


            if user_address_idx == -1: # default_address
                address, geohash5, geohash6 = userdao.get_user_address(uid)
                _, size, kind = userdao.get_user_address_detail(uid)
            else: # address selection
                address, geohash5, geohash6 = userdao.get_user_address_by_index(uid, user_address_idx)
                _, size, kind = userdao.get_user_address_detail_by_index(uid, user_address_idx)

            gu_id = addrdao.get_gu_id(address)

            if gu_id == '':
                raise Exception('gu id is incorrect')

            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)


            now = dt.datetime.now()
            if now.hour >= 17: # 7시 이후 라면 -> 5시로 변경 2016.06.03
                if for_manager == '': # 사용자 앱에서는 내일 예약 불가능
                    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']
            # log to mixpanel
            mix.track(uid, 'request available schedule', {'time' : dt.datetime.now(), 'taking_time' : taking_time, 'additional_time' : additional_time, 'appointment_type' : appointment_type, 'have_pet' : have_pet, 'master_gender' : master_gender,'isdirty' : isdirty})

            # log to mongo
            mongo_logger.debug('request available schedule', extra = {'log_time' : dt.datetime.now(),  'user_id' : uid, 'taking_time' : taking_time, 'additional_time' : additional_time, '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'])

                mongo_logger.debug('no masters', extra = {'log_time' : dt.datetime.now(), 'user_id' : uid, 'taking_time' : total_taking_time_in_minutes, 'gu_id' : gu_id, 'address' : address})
                user_name = userdao.get_user_name(uid)
                user_phone = userdao.get_user_phone(uid)
                send_jandi('BOOKING_NOT_AVAILABE', '예약 불가능 알림', '고객 : {} 전번 : {}'.format(user_name, user_phone),
                            '주기 : {}, 주소 : {}'.format(appointment_type, address))

            self.set_status(Response.RESULT_OK)
        except Exception, e:
            add_err_message_to_response(ret, err_dict['err_mysql'])
            self.set_status(Response.RESULT_SERVERERROR)
            print_err_detail(e)
            mongo_logger.error('error request available schedules', extra = {'user_id' : uid, 'err' : str(e)})
Ejemplo n.º 8
0
    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'])
    def post(self):
        self.set_header("Content-Type", "application/json")

        ret = {}

        address                     = self.get_argument('address', '')
        house_type                  = self.get_argument('house_type', 0)
        house_size                  = self.get_argument('house_size', 10)

        appointment_type            = self.get_argument('appointment_type', BC.ONE_TIME)
        additional_task             = self.get_argument('additional_task', 0)
        have_pet                    = self.get_argument('have_pet', 0)
        master_gender               = self.get_argument('master_gender', 0)
        isdirty                     = self.get_argument('isdirty', 0)

        # convert parameters
        house_type                      = int(house_type)
        house_size                      = int(house_size)
        appointment_type                = int(appointment_type)
        additional_task                 = int(additional_task)
        have_pet                        = int(have_pet)
        master_gender                   = int(master_gender) # 0 dont care 1 women
        isdirty                         = int(isdirty)

        if house_type == 0 or house_type == 5:
            house_type = 0
            if house_size == 8:
                house_size = 12
            elif house_size == 9:
                house_size = 20
            elif house_size == 10:
                house_size = 30
            elif house_size == 11:
                house_size = 40
            elif house_size == 12:
                house_size = 54
        elif house_type == 1 or house_type == 6:
            house_type = 1
            if house_size == 13:
                house_size = 7
            elif house_size == 14:
                house_size = 13
            elif house_size == 15:
                house_size = 19
            elif house_size == 16:
                house_size = 29
            elif house_size == 18:
                house_size = 54
        elif house_type == 2 or house_type == 7:
            house_type = 1
            if house_size == 19:
                house_size = 24
            elif house_size == 20:
                house_size = 34
            elif house_size == 21:
                house_size = 44
            elif house_size == 22:
                house_size = 54

        # logging part
        mix = get_mixpanel()
        mongo_logger = get_mongo_logger()

        try:
            scheduler = HMScheduler()

            userdao = UserDAO()
            addrdao = AddressDAO()

            print 'request available_schedules 11'
            print address
            print house_size
            print house_type
            print appointment_type
            print additional_task
            print have_pet
            print master_gender
            print isdirty
            print '--------------------------------'

            if additional_task == 64:
                additional_task = 0

            basic_address   = address.rsplit(',', 1)[0]
            detail_address  = address.rsplit(',', 1)[1]

            print "basic_address : ", basic_address
            print "detail_address : ", detail_address

            # get gu_id & geohash
            full_address = '%s %s' % (basic_address, detail_address)
            print "full_address : ", full_address
            lat, lng    = get_latlng_from_address(full_address)
            geohash6   = get_geohash(lat, lng, 6)
            gu_id       = addrdao.get_gu_id(basic_address)

            if gu_id == '':
                raise Exception('gu id is incorrect')

            tp_key, time, price, first_time = get_time_price(appointment_type, house_type, house_size)
            cleaning_time = time + first_time

            task_time, task_price = get_additional_task_time_price(additional_task, house_type, house_size)

            comb_key = '%s_%d_%d_%d' % (tp_key, additional_task, have_pet, master_gender)

            # total time and price
            total_taking_time_in_minutes = cleaning_time + task_time

            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)


            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 '11 street log'
            # log to mixpanel
            #mix.track(uid, '11 request available schedule', {'time' : dt.datetime.now(), 'taking_time' : taking_time, 'additional_time' : additional_time, 'appointment_type' : appointment_type, 'have_pet' : have_pet, 'master_gender' : master_gender,'isdirty' : isdirty})

            # log to mongo
            mongo_logger.debug('11 request available schedule', extra = {'taking_time' : cleaning_time, 'additional_time' : task_time, 'appointment_type' : appointment_type, 'have_pet' : have_pet, 'master_gender' : master_gender,'isdirty' : isdirty})

            if len(available_schedules) > 0: # 가능한 날짜가 있다면
                ret['response'] = available_schedules
                ret['comb_key'] = comb_key
                print comb_key
            else:
                add_err_message_to_response(ret, err_dict['err_not_available'])

            self.set_status(Response.RESULT_OK)
        except Exception, e:
            add_err_message_to_response(ret, err_dict['err_mysql'])
            self.set_status(Response.RESULT_SERVERERROR)
            print_err_detail(e)
            mongo_logger.error('error 11 request available schedules', extra = {'err' : str(e)})