コード例 #1
0
    def notify_10mins_ahead(self):
        try:
            userdao = UserDAO()

            current_time = dt.datetime.now()
            print '-' * 40
            print 'push before 10 minutes'
            print 'current_time :', current_time

            hour = current_time.hour
            if current_time.minute >= 20 and current_time.minute <= 29:
                minute = 30
            elif current_time.minute >= 50 and current_time.minute <= 59:
                hour += 1
                minute = 0
            else:
                minute = 0

            cron_time = current_time.replace(hour=hour,
                                             minute=minute,
                                             second=0,
                                             microsecond=0)

            print 'cron_time :', cron_time
            print '-' * 40

            session = Session()
            result = session.query(Booking, Master, User, UserPushKey) \
                            .join(Master, Booking.master_id == Master.id) \
                            .join(User, Booking.user_id == User.id) \
                            .outerjoin(UserPushKey, User.id == UserPushKey.user_id) \
                            .filter(or_(Booking.cleaning_status == BC.BOOKING_UPCOMMING, Booking.cleaning_status == BC.BOOKING_STARTED)) \
                            .filter(func.date(Booking.start_time) == cron_time.date()) \
                            .filter(func.HOUR(Booking.start_time) == cron_time.time().hour) \
                            .filter(func.MINUTE(Booking.start_time) == cron_time.time().minute) \
                            .all()

            for row in result:
                key = userdao.get_user_salt_by_id(row.User.id)[:16]
                crypto = aes.MyCrypto(key)

                booking_id = row.Booking.id
                pushkey = row.UserPushKey.pushkey if row.UserPushKey != None else ''
                user_name = crypto.decodeAES(row.User.name)
                phone = crypto.decodeAES(row.User.phone)
                master_name = row.Master.name
                devicetype = row.User.devicetype

                print 'push to', user_name, master_name, booking_id
                print pushkey

                if devicetype != 'android':
                    pushkey = crypto.decodeAES(row.User.phone)

                send_10mins_ahead_notification(devicetype, [pushkey],
                                               booking_id)
                send_alimtalk(phone, 'noti_10', user_name, master_name)

        except Exception, e:
            print_err_detail(e)
コード例 #2
0
    def post(self):
        self.set_header("Content-Type", "application/json")
        self.set_header('Access-Control-Allow-Origin', '*')

        ret = {}

        user_id = self.get_argument('user_id', '')
        new_pwd = self.get_argument('new_pwd', 'hm123')

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

            user_row = session.query(User).filter(User.id == user_id).one()

            salt = userdao.get_user_salt_by_id(user_id)
            hash_obj = hashlib.sha256(salt + new_pwd)

            user_row.password = hash_obj.hexdigest()
            session.commit()

            ret['response'] = Response.SUCCESS
            self.set_status(Response.RESULT_OK)

        except Exception, e:
            print_err_detail(e)
            self.set_status(Response.RESULT_SERVERERROR)
            add_err_message_to_response(ret, err_dict['err_mysql'])
    def notify(self):
        try:
            userdao = UserDAO()

            current_time = dt.datetime.now()

            print '-' * 40
            print 'push before 2 hours'
            print 'current_time :', current_time

            hour = current_time.hour
            minute = 30 if current_time.minute >= 30 else 0

            #current_time = current_time + dt.timedelta(hours=2)
            cron_time = current_time.replace(hour=hour+2, minute=minute, second = 0, microsecond=0)

            print 'cron_time :', cron_time
            print '-' * 40

            session = Session()
            result = session.query(Booking, Master, MasterPushKey, User) \
                            .join(Master, Booking.master_id == Master.id) \
                            .join(MasterPushKey, Master.id == MasterPushKey.master_id) \
                            .join(User, Booking.user_id == User.id) \
                            .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \
                            .filter(func.date(Booking.start_time) == cron_time.date()) \
                            .filter(func.HOUR(Booking.start_time) == cron_time.time().hour) \
                            .filter(func.MINUTE(Booking.start_time) == cron_time.time().minute) \
                            .all()


            for row in result:

                key = userdao.get_user_salt_by_id(row.User.id)[:16]
                crypto = aes.MyCrypto(key)

                if row.Master.id == 'da2a1f50-fd36-40bf-8460-55b3e1b2c459':
                    continue

                booking_id = row.Booking.id
                pushkey = row.MasterPushKey.pushkey if row.MasterPushKey != None else ''
                master_name = row.Master.name

                start_time = row.Booking.start_time
                time_str = convert_datetime_format4(start_time)

                print 'push to', master_name, booking_id
                print pushkey

                send_master_ahead_notification('android', [pushkey], booking_id, master_name, time_str)

        except Exception, e:
            print_err_detail(e)
コード例 #4
0
    def get(self):
        self.set_header("Content-Type", "application/json")

        ret = {}

        master_id = self.get_argument('master_id', '')

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

            result = session.query(Master, Booking, User) \
                            .join(Booking, Master.id == Booking.master_id) \
                            .join(User, Booking.user_id == User.id) \
                            .filter(Booking.master_id == master_id) \
                            .filter(or_(Booking.cleaning_status == BC.BOOKING_UPCOMMING, Booking.cleaning_status == BC.BOOKING_STARTED, Booking.cleaning_status == BC.BOOKING_COMPLETED)) \
                            .order_by(desc(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 = {}

                booking['booking_id'] = row.Booking.id
                booking['name'] = crypto.decodeAES(row.User.name)
                booking['start_time'] = convert_datetime_format2(
                    row.Booking.start_time)
                booking['additional_task'] = row.Booking.additional_task
                booking['price'] = row.Booking.price_with_task
                booking['status'] = row.Booking.status
                booking['cleaning_status'] = row.Booking.cleaning_status
                booking['payment_status'] = row.Booking.payment_status

                booking_list.append(booking)

            ret['response'] = booking_list
            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'])
コード例 #5
0
    def get(self):
        self.set_header("Content-Type", "application/json")

        manager_id = self.get_argument('manager_id', '')

        ret = {}

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

            payment_records = []

            result = session.query(UserPaymentRecord, User) \
                            .join(User, UserPaymentRecord.user_id == User.id) \
                            .order_by(UserPaymentRecord.user_id, desc(UserPaymentRecord.auth_date)) \
                            .all()

            for row in result:
                payment = {}

                key = userdao.get_user_salt_by_id(row.User.id)[:16]
                crypto = aes.MyCrypto(key)

                payment['tid'] = row.UserPaymentRecord.tid
                payment['booking_id'] = row.UserPaymentRecord.booking_id
                payment['user_id'] = row.UserPaymentRecord.user_id
                payment['price'] = row.UserPaymentRecord.price
                payment['auth_date'] = row.UserPaymentRecord.auth_date
                payment[
                    'canceled_amount'] = row.UserPaymentRecord.canceled_amount
                payment['canceled_date'] = row.UserPaymentRecord.canceled_date
                payment['status'] = row.UserPaymentRecord.status
                payment['user_name'] = crypto.decodeAES(row.User.name)
                payment['user_phone'] = crypto.decodeAES(row.User.phone)

                payment_records.append(payment)

            ret['response'] = payment_records
            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'])
コード例 #6
0
    def login(self, name, phone):
        session = Session()
        userdao = UserDAO()
        result = session.query(User) \
                    .filter(User.email == name + phone + '@11st.co.kr') \
                    .filter(User.authsource == '11st') \
                    .all()

        for row in result:
            key = userdao.get_user_salt_by_id(row.id)[:16]
            crypto = aes.MyCrypto(key)

            decrypted_name = crypto.decodeAES(row.name)
            decrypted_phone = crypto.decodeAES(row.phone)

            if name == decrypted_name and phone == decrypted_phone:  # 동명이인 고려, 일치하게 된다면 id 반환
                return row.id, True

        return '', False
    def is_user_block(self, ret, uid):
        try:
            mongo_logger = get_mongo_logger()
            userdao = UserDAO()

            session = Session()
            result = session.query(User) \
                            .filter(User.id == uid) \
                            .one()

            key = userdao.get_user_salt_by_id(result.id)[:16]
            crypto = aes.MyCrypto(key)
            phone = crypto.decodeAES(result.phone)

            row = session.query(BlockUser, User) \
                         .join(User, User.id == BlockUser.user_id) \
                         .filter(func.aes_decrypt(func.from_base64(User.phone), func.substring(User.salt, 1, 16)) == phone) \
                         .all()

            print row

            session.close()
            if len(row) > 0:
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(
                    ret,
                    '현재 주문량이 많아 신규 예약이 불가능 합니다. 확실한 서비스 품질을 보증을 위해 바로 서비스를 제공해 드릴 수 없는 점 양해 부탁드립니다.'
                )
                mongo_logger.debug('block user', extra={'user_id': uid})
                ret['err_code'] = '4037'  # 임시 처리
                return True

            return False

        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'])
            return True
コード例 #8
0
    def get(self):
        self.set_header("Content-Type", "application/json")

        ret = {}

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

            none_ios_users = []

            for row in session.query(User, Booking) \
                            .join(Booking, User.id == Booking.user_id) \
                            .filter(Booking.cleaning_status == 0) \
                            .filter(User.devicetype == 'None') \
                            .group_by(User.id) \
                            .all():
                user_dict = {}

                user_id = row.User.id
                key = userdao.get_user_salt_by_id(user_id)[:16]
                crypto = aes.MyCrypto(key)

                user_dict['name'] = crypto.decodeAES(row.User.name)
                user_dict['email'] = row.User.email
                user_dict['phone'] = crypto.decodeAES(row.User.phone)
                user_dict['gender'] = row.User.gender

                none_ios_users.append(user_dict)

            print len(none_ios_users)
            ret['response'] = none_ios_users
            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'])
コード例 #9
0
    def get(self):
        self.set_header("Content-Type", "application/json")
        ret = {}

        try:
            userdao = UserDAO()

            session = Session()
            result = session.query(MasterClaim, Master, User) \
                            .join(Master, MasterClaim.master_id == Master.id) \
                            .join(User, MasterClaim.user_id == User.id) \
                            .order_by(desc(MasterClaim.register_time)) \
                            .all()

            claims = []
            for row in result:
                key = userdao.get_user_salt_by_id(row.User.id)[:16]
                crypto = aes.MyCrypto(key)

                claim = {}
                claim['user_name'] = crypto.decodeAES(row.User.name)
                claim['user_phone'] = crypto.decodeAES(row.User.phone)
                claim['master_name'] = row.Master.name
                claim['text'] = row.MasterClaim.claim_text
                claim['datetime'] = convert_datetime_format2(
                    row.MasterClaim.register_time)

                claims.append(claim)

            ret['response'] = claims
            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'])
コード例 #10
0
    def notify(self):
        try:
            userdao = UserDAO()

            current_date = dt.datetime.now().date()

            print current_date

            session = Session()
            result = session.query(Booking, User, UserPushKey) \
                        .join(User, Booking.user_id == User.id) \
                        .join(UserPushKey, User.id == UserPushKey.user_id) \
                        .filter(func.date(Booking.start_time) == current_date) \
                        .filter(Booking.cleaning_status == BC.BOOKING_COMPLETED) \
                        .all()

            for row in result:
                key = userdao.get_user_salt_by_id(row.User.id)[:16]
                crypto = aes.MyCrypto(key)

                booking_id = row.Booking.id
                user_name  = crypto.decodeAES(row.User.name)
                pushkey    = row.UserPushKey.pushkey
                devicetype = row.User.devicetype

                if row.Booking.havereview == 0: # review 하지 않은 사용자에게만 보냄
                    print 'rating push to ', user_name, booking_id

                    if devicetype != 'android':
                        pushkey = crypto.decodeAES(row.User.phone)

                    send_rating_notification(devicetype, [pushkey], booking_id, user_name)

            print 'notified to users for rating successfully...', dt.datetime.now()

        except Exception, e:
            print_err_detail(e)
    def get(self):
        self.set_header("Content-Type", "application/json")

        ret = {}

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

            users = []

            for row in session.query(User, UserAddress, UserDefaultAddress, Booking) \
                            .outerjoin(UserAddress, User.id == UserAddress.user_id) \
                            .outerjoin(UserDefaultAddress, User.id == UserDefaultAddress.user_id) \
                            .outerjoin(Booking, and_(User.id == Booking.user_id)) \
                            .all():

                if row.UserAddress != None and row.Booking == None:
                    user_id = row.User.id
                    key = userdao.get_user_salt_by_id(user_id)[:16]
                    crypto = aes.MyCrypto(key)

                    user_info = {}
                    user_info['name'] = crypto.decodeAES(row.User.name)
                    user_info['phone'] = crypto.decodeAES(row.User.phone)

                    users.append(user_info)

            ret['response'] = users
            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'])
コード例 #12
0
    def get(self):
        self.set_header("Content-Type", "application/json")

        ret = {}

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

            memos = []

            result = session.query(UserMemo, User) \
                            .join(User, UserMemo.user_id == User.id) \
                            .order_by(desc(UserMemo.requested_datetime)) \
                            .all()

            for row in result:
                key = userdao.get_user_salt_by_id(row.User.id)[:16]
                crypto = aes.MyCrypto(key)

                memo = {}
                memo['time'] = dt.datetime.strftime(
                    row.UserMemo.requested_datetime, '%Y-%m-%d %H:%M')
                memo['memo'] = row.UserMemo.memo
                memo['user_name'] = crypto.decodeAES(row.User.name)
                memos.append(memo)

            ret['response'] = memos
            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'])
コード例 #13
0
    def notify_try_charge_unpaid(self):
        try:
            mongo_logger = get_mongo_logger()

            userdao = UserDAO()
            bookingdao = BookingDAO()

            current_time = dt.datetime.now()
            two_weeks_before = current_time - dt.timedelta(days=28)
            two_weeks_before = two_weeks_before.date()

            print '-' * 40
            print 'try charge unpaid notification via alimtalk'
            print 'cron_time :', current_time
            print '-' * 40

            session = Session()
            result = session.query(Booking, User) \
                            .join(User, Booking.user_id == User.id) \
                            .filter(func.Date(Booking.start_time) >= two_weeks_before) \
                            .filter(Booking.cleaning_status == BC.BOOKING_COMPLETED) \
                            .filter(Booking.payment_status != BC.BOOKING_PAID) \
                            .filter(User.is_b2b == 0) \
                            .filter(Booking.source == 'hm') \
                            .order_by(Booking.start_time) \
                            .all()

            for row in result:
                if 'b2b.com' in row.User.email:  # b2b 무시
                    continue

                if row.User.is_b2b == 1:  # b2b 무시
                    continue

                if row.Booking.source != 'hm':  # 11번가 무시
                    continue

                key = userdao.get_user_salt_by_id(row.User.id)[:16]
                crypto = aes.MyCrypto(key)

                user_id = row.Booking.user_id
                user_name = crypto.decodeAES(row.User.name)
                phone = crypto.decodeAES(row.User.phone)

                booking_id = row.Booking.id
                appointment_type = row.Booking.appointment_type
                cleaning_time = convert_datetime_format2(
                    row.Booking.start_time)
                charge_price = row.Booking.price_with_task
                price = '{:,}원'.format(charge_price)

                print booking_id, user_id, user_name, cleaning_time, price

                status, try_charge, remain_days = bookingdao.is_next_booking_left_over_2days(
                    booking_id)
                print status, try_charge, remain_days

                if status == 'FAILURE':  # 다음 회차 예약 가져오기 실패. 건너 뜀
                    continue

                if try_charge:  # 결제를 시도해야함
                    ret, value = request_payment(user_id, user_name,
                                                 booking_id, charge_price,
                                                 appointment_type)

                    if ret:  # 결제 성공
                        row.Booking.payment_status = BC.BOOKING_PAID
                        session.commit()

                        print '*** success ***'

                        send_alimtalk(phone,
                                      'notify_try_charge_unpaid_success',
                                      cleaning_time, price)
                        mongo_logger.debug('user try charge success',
                                           extra={
                                               'dt': current_time,
                                               'user_id': user_id,
                                               'booking_id': booking_id,
                                               'price': price,
                                               'cleaning_time': cleaning_time
                                           })
                    else:  # 결제 실패
                        print '*** failed ***'
                        if remain_days == -1:
                            mongo_logger.debug('no booking remains',
                                               extra={
                                                   'dt': current_time,
                                                   'user_id': user_id,
                                                   'booking_id': booking_id,
                                                   'price': price,
                                                   'cleaning_time':
                                                   cleaning_time
                                               })

                        elif remain_days > 3:  # 3일 초과로 남았으면 실패 공지
                            send_alimtalk(phone, 'notify_charge_failure',
                                          cleaning_time, price)
                            mongo_logger.debug('user try charge fail',
                                               extra={
                                                   'dt': current_time,
                                                   'user_id': user_id,
                                                   'booking_id': booking_id,
                                                   'price': price,
                                                   'cleaning_time':
                                                   cleaning_time
                                               })

                        elif remain_days >= 0:  # 3일 이내면 전체 취소
                            print '*** cancel all ***'

                            bookingdao.cancel_all_upcomings(booking_id)

                            send_jandi(
                                'NEW_BOOKING', "미결제 전체 취소 알림",
                                user_name + ' 고객님 전체 취소됨',
                                '미결제 일시 : {}, 금액 : {}'.format(
                                    cleaning_time, price))

                            send_alimtalk(
                                phone, 'notify_try_charge_unpaid_cancel_all',
                                cleaning_time, price)
                            mongo_logger.debug('user try charge cancel all',
                                               extra={
                                                   'dt': current_time,
                                                   'user_id': user_id,
                                                   'booking_id': booking_id,
                                                   'price': price,
                                                   'cleaning_time':
                                                   cleaning_time
                                               })

        except Exception, e:
            print_err_detail(e)
            mongo_logger.error('failed to try charge failure',
                               extra={'err': str(e)})
コード例 #14
0
    def get(self):
        self.set_header("Content-Type", "application/json")
        self.set_header('Access-Control-Allow-Origin', '*')

        date = self.get_argument('date', '')
        sigungu = self.get_argument('sigungu', '')
        customer_sigungu = self.get_argument('customer_sigungu', '')

        if date == None or date == '':
            date = dt.datetime.now()

        date = dt.datetime.strptime(date, '%Y%m%d')

        ret = {}

        try:
            session = Session()
            userdao = UserDAO()
            masterdao = MasterDAO()

            if sigungu == '':
                master_ids = masterdao.get_all_master_ids()
            else:
                master_ids = masterdao.get_master_ids_where_regions_available(
                    sigungu)

            master_times = []

            day_of_week = date.weekday()

            for mid in master_ids:
                master_schedules = []
                '''start_times, end_times = masterdao.get_master_working_time(mid)

              start_times = start_times.split(',')
              end_times = end_times.split(',')

              st = start_times[day_of_week] if start_times[day_of_week] != '' else 8
              et = end_times[day_of_week] if end_times[day_of_week] != '' else 8

              st = int(st)
              et = int(et)'''

                st, et = masterdao.get_master_working_time_for_day(
                    mid, date.date())
                current_cleaning_counts = masterdao.get_master_completed_cleaning_count_at_date(
                    mid, date)
                is_unassigned = masterdao.is_unassigned(mid)

                master_dict = {}
                master_dict['master_name'] = masterdao.get_master_name(mid)
                master_dict['master_id'] = mid
                master_dict['is_unassigned'] = is_unassigned
                master_dict[
                    'is_beginner'] = True if current_cleaning_counts <= 10 else False
                master_dict[
                    'current_cleaning_counts'] = current_cleaning_counts
                master_dict[
                    'master_available_from'] = '0%s:00' % st if st < 10 else '%s:00' % st
                master_dict[
                    'master_available_to'] = '0%s:00' % et if et < 10 else '%s:00' % et

                # for day off
                master_dict['is_day_off'] = masterdao.is_day_off(
                    mid, date.date())

                for row in session.query(Master, Booking, User, UserAddress, UserDefaultCard, Promotion, EventPromotionBooking) \
                                  .outerjoin(Booking, Master.id == Booking.master_id) \
                                  .join(User, User.id == Booking.user_id) \
                                  .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \
                                  .outerjoin(UserDefaultCard, User.id == UserDefaultCard.user_id) \
                                  .outerjoin(Promotion, Booking.id == Promotion.booking_id) \
                                  .outerjoin(EventPromotionBooking, Booking.id == EventPromotionBooking.booking_id) \
                                  .filter(func.DATE(Booking.start_time) == date) \
                                  .filter(Master.id == mid) \
                                  .filter(or_(Booking.cleaning_status == BC.BOOKING_UPCOMMING, Booking.cleaning_status == BC.BOOKING_STARTED, Booking.cleaning_status == BC.BOOKING_COMPLETED)) \
                                  .order_by(Master.name, Booking.start_time) \
                                  .all():

                    key = userdao.get_user_salt_by_id(row.User.id)[:16]
                    crypto = aes.MyCrypto(key)

                    discount_price = 0
                    if row.Promotion != None:
                        discount_price += row.Promotion.discount_price
                    if row.EventPromotionBooking != None:
                        discount_price += row.EventPromotionBooking.discount_price

                    kind = row.UserAddress.kind
                    if kind == 0:
                        kind = '오피스텔'
                    elif kind == 1:
                        kind = '주택'
                    else:
                        kind = '아파트'

                    address = crypto.decodeAES(row.UserAddress.address)
                    if customer_sigungu in address:
                        master_schedules.append(
                            self.make_schedule_dict(
                                row.Booking.id, row.User.devicetype,
                                row.Booking.appointment_type,
                                row.Booking.appointment_index,
                                dt.datetime.strftime(row.Booking.start_time,
                                                     '%H:%M'),
                                dt.datetime.strftime(
                                    row.Booking.estimated_end_time, '%H:%M'),
                                row.Booking.havereview, row.Booking.user_id,
                                crypto.decodeAES(row.User.name),
                                crypto.decodeAES(row.User.phone),
                                crypto.decodeAES(row.UserAddress.address),
                                row.UserAddress.size, kind,
                                row.Booking.is_dirty, row.Booking.status,
                                row.Booking.cleaning_status,
                                row.Booking.payment_status,
                                row.Booking.price_with_task, discount_price,
                                row.Booking.routing_method, row.User.is_b2b,
                                row.UserDefaultCard))

                master_dict['time_list'] = master_schedules
                master_times.append(master_dict)

            ret['response'] = master_times
            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'])
コード例 #15
0
    def get(self):
        self.set_header("Content-Type", "application/json")
        self.set_header('Access-Control-Allow-Origin', '*')

        booking_id = self.get_argument('booking_id', '')

        ret = {}

        try:
            session = Session()

            row = session.query(Booking, Rating, OrderID11st, Master, User, UserAddress, MasterMemo) \
                        .outerjoin(Rating, Booking.id == Rating.booking_id) \
                        .outerjoin(OrderID11st, Booking.id == OrderID11st.booking_id) \
                        .join(Master, Booking.master_id == Master.id) \
                        .join(User, Booking.user_id == User.id) \
                        .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \
                        .outerjoin(MasterMemo, Booking.user_id == MasterMemo.user_id) \
                        .filter(Booking.id == booking_id) \
                        .order_by(desc(MasterMemo.datetime)) \
                        .first()

            if row == None:  # no entry
                session.close()
                add_err_message_to_response(ret,
                                            err_dict['err_no_entry_to_cancel'])
                self.write(json.dumps(ret))
                return

            userdao = UserDAO()
            key = userdao.get_user_salt_by_id(row.User.id)[:16]
            crypto = aes.MyCrypto(key)

            estimated_end_time = row.Booking.estimated_end_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:
                    estimated_end_time -= dt.timedelta(hours=2)

            appointment_index = row.Booking.appointment_index
            appointment_type = row.Booking.appointment_type
            start_time = row.Booking.start_time
            end_time = row.Booking.estimated_end_time
            cleaning_duration = row.Booking.cleaning_duration / 6
            is_dirty = row.Booking.is_dirty
            is_b2b = row.User.is_b2b

            duration_in_minutes = (
                end_time - start_time
            ).seconds / 360  # 계산을 단순하게 하기 위해 60 * 60이 아닌 60 * 6으로 나눔. 그뒤 10배 커지는 것을 방지하기 위해 시급에서 10 나눈 값만 곱함
            minutes_for_salary = duration_in_minutes

            #if duration_in_minutes > cleaning_duration: # 30분의 시간이 더 더해지는 경우가 존재. 그 경우, 해당 시간은 임금에 반영 되지 않음
            #    if appointment_index == 1 and (appointment_type == BC.ONE_TIME_A_MONTH or appointment_type == BC.TWO_TIME_A_MONTH or appointment_type == BC.FOUR_TIME_A_MONTH):
            #        minutes_for_salary = duration_in_minutes - 5

            if is_dirty == 1:
                minutes_for_salary -= 20

            house_type = row.UserAddress.kind
            house_size = row.UserAddress.size

            expected_salary = 0

            if is_b2b:
                expected_salary = int(minutes_for_salary *
                                      (row.Booking.wage_per_hour / 10))
            else:
                if start_time >= dt.datetime(2017, 1, 1):
                    expected_salary = minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR
                else:
                    if appointment_type in BC.REGULAR_CLEANING_DICT:
                        expected_salary = minutes_for_salary * BC.SALARY_FOR_REGULAR_IN_HOUR
                    else:
                        expected_salary = minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR

                if start_time.weekday(
                ) in BC.WEEKEND and start_time >= dt.datetime(2016, 12, 17):
                    expected_salary += BC.WEEKEND_ADDED_SALARY

            booking_info = {}
            booking_info['booking_id'] = row.Booking.id
            booking_info['request_id'] = row.Booking.request_id
            booking_info['master_gender'] = row.Booking.master_gender
            booking_info['master_name'] = row.Master.name
            booking_info['master_pet_alergy'] = row.Master.pet_alergy

            booking_info[
                'user_memo'] = row.MasterMemo.memo if row.MasterMemo != None else ''
            booking_info['user_id'] = row.User.id
            booking_info['user_name'] = crypto.decodeAES(row.User.name)
            booking_info['user_email'] = row.User.email
            booking_info['user_gender'] = row.User.gender
            booking_info['user_phone'] = crypto.decodeAES(row.User.phone)
            booking_info['user_address'] = crypto.decodeAES(
                row.UserAddress.address)
            booking_info['jibun_address'] = convert_to_jibun_address(
                booking_info['user_address'])
            booking_info['user_home_size'] = row.UserAddress.size
            booking_info['user_home_kind'] = row.UserAddress.kind
            booking_info['devicetype'] = row.User.devicetype
            booking_info['appointment_type'] = row.Booking.appointment_type
            #booking_info['appointment_index']   = row.Booking.appointment_index
            booking_info['avg_rating'] = str(
                float((row.Rating.rate_clean + row.Rating.rate_master)) /
                2.0) if row.Rating != None else 'None'
            booking_info[
                'clean_review'] = row.Rating.review_clean if row.Rating != None else ''
            booking_info[
                'master_review'] = row.Rating.review_master if row.Rating != None else ''
            booking_info['start_time'] = dt.datetime.strftime(
                row.Booking.start_time, '%Y-%m-%d %H:%M')
            booking_info['estimated_end_time'] = dt.datetime.strftime(
                estimated_end_time, '%Y-%m-%d %H:%M')
            booking_info['additional_task'] = row.Booking.additional_task
            booking_info['price'] = row.Booking.price_with_task
            booking_info['salary'] = expected_salary
            booking_info[
                'msg'] = row.Booking.message if row.Booking.message != None else ''
            booking_info[
                'trash_location'] = row.Booking.trash_location if row.Booking.trash_location != None else ''
            booking_info['enterhome'] = crypto.decodeAES(
                row.Booking.enterhome) if row.Booking.enterhome != None else ''
            booking_info['enterbuilding'] = crypto.decodeAES(
                row.Booking.enterbuilding
            ) if row.Booking.enterbuilding != None else ''
            #booking_info['havetools']           = row.Booking.havetools
            booking_info['havepet'] = row.Booking.havepet
            booking_info['status'] = row.Booking.status
            booking_info['payment_status'] = row.Booking.payment_status
            booking_info['cleaning_status'] = row.Booking.cleaning_status
            booking_info[
                'routing_method'] = row.Booking.routing_method if row.Booking.routing_method != None else ''

            booking_info['is_b2b'] = is_b2b
            booking_info[
                '11st_id'] = row.OrderID11st.div_no if row.OrderID11st != None else ''

            ret['response'] = booking_info
            self.set_status(Response.RESULT_OK)

            #print booking_info['enterhome']
            #print booking_info['enterbuilding']

        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 get(self):
        self.set_header("Content-Type", "application/json")
        self.set_header('Access-Control-Allow-Origin', '*')

        year = self.get_argument('year', '')
        month = self.get_argument('month', '')

        if year == '' or month == '':
            now = dt.datetime.now()
            year = now.year
            month = now.month

        try:
            year = int(year)
            month = int(month)
        except:
            year = 2017
            month = 2

        ret = {}
        rb_users = []

        userdao = UserDAO()

        try:
            session = Session()
            b1 = aliased(Booking)
            stmt = session.query(b1) \
                        .filter(b1.cleaning_status == 2) \
                        .filter(or_(b1.appointment_type == 1, b1.appointment_type == 2, b1.appointment_type == 4)) \
                        .subquery()

            rows = session.query(Booking, User, UserAddress, RegularBasisManagement) \
                        .join(User, Booking.user_id == User.id) \
                        .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \
                        .outerjoin(RegularBasisManagement, Booking.id == RegularBasisManagement.booking_id) \
                        .outerjoin(stmt, Booking.user_id == stmt.c.user_id) \
                        .filter(Booking.appointment_index == 1) \
                        .filter(Booking.cleaning_status == 2) \
                        .filter(or_(Booking.appointment_type == 1, Booking.appointment_type == 2, Booking.appointment_type == 4)) \
                        .filter(func.year(Booking.start_time) == year) \
                        .filter(func.month(Booking.start_time) == month) \
                        .filter(User.is_b2b == 0) \
                        .order_by(desc(Booking.start_time)) \
                        .all()

            for row in rows:
                key = userdao.get_user_salt_by_id(row.User.id)[:16]
                crypto = aes.MyCrypto(key)

                appointment_type = row.Booking.appointment_type

                if appointment_type == 1:
                    appointment_type = '4주1회'
                elif appointment_type == 2:
                    appointment_type = '2주1회'
                elif appointment_type == 4:
                    appointment_type = '매주'

                user = {}
                user['booking_id'] = row.Booking.id
                user['name'] = crypto.decodeAES(row.User.name)
                user['phone'] = crypto.decodeAES(row.User.phone)
                user['address'] = crypto.decodeAES(row.UserAddress.address)
                user['reg_date'] = convert_datetime_format2(row.User.dateofreg)
                user['start_time'] = convert_datetime_format2(
                    row.Booking.start_time)
                user['type'] = appointment_type

                user[
                    'try_1st'] = row.RegularBasisManagement.try_1st if row.RegularBasisManagement != None else '진행안됨'
                user[
                    'try_2nd'] = row.RegularBasisManagement.try_2nd if row.RegularBasisManagement != None else '진행안됨'
                user[
                    'try_3rd'] = row.RegularBasisManagement.try_3rd if row.RegularBasisManagement != None else '진행안됨'
                user[
                    'memo'] = row.RegularBasisManagement.memo if row.RegularBasisManagement != None else ''

                rb_users.append(user)

            ret['response'] = rb_users
            self.set_status(Response.RESULT_OK)

        except Exception, e:
            print_err_detail(e)
            self.set_status(Response.RESULT_SERVERERROR)
            add_err_message_to_response(ret, err_dict['err_mysql'])
コード例 #17
0
    def get(self):
        self.set_header("Content-Type", "application/json")
        self.set_header('Access-Control-Allow-Origin', '*')

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

        ret = {}

        if user_id == '':
            self.set_status(Response.RESULT_BADREQUEST)
            add_err_message_to_response(ret, err_dict['invalid_param'])
            self.write(json.dumps(ret))
            return

        mongo_logger = get_mongo_logger()
        mix = get_mixpanel()

        try:
            session = Session()

            userdao = UserDAO()

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

            user_info = {}
            addresses = []

            for row in session.query(User, UserAddress, UserDefaultAddress) \
                            .outerjoin(UserAddress, User.id == UserAddress.user_id) \
                            .outerjoin(UserDefaultAddress, User.id == UserDefaultAddress.user_id).filter(User.id == user_id) \
                            .order_by(UserAddress.user_addr_index) \
                            .all():
                if row.UserAddress != None:
                    kind = row.UserAddress.kind
                    if kind == 3:
                        kind = 0

                    addr = {'addr' : crypto.decodeAES(row.UserAddress.address), 'size' : row.UserAddress.size, 'kind' : kind, 'index' : row.UserAddress.user_addr_index}
                    addresses.append(addr)

                default_idx = -1
                if row.UserDefaultAddress != None:
                    default_idx = row.UserDefaultAddress.address_idx

                user_info['name']               = crypto.decodeAES(row.User.name)
                user_info['email']              = row.User.email
                user_info['phone']              = crypto.decodeAES(row.User.phone)
                user_info['gender']             = row.User.gender
                user_info['auth_source']        = row.User.authsource
                user_info['devicetype']         = row.User.devicetype
                user_info['birthdate']          = crypto.decodeAES(row.User.dateofbirth)
                user_info['default_addr_idx']   = default_idx

            user_info['arr_address'] = addresses

            ret['response'] = user_info
            self.set_status(Response.RESULT_OK)

            mix.track(user_id, 'got userinfo', {'time' : dt.datetime.now()})
            mongo_logger.debug('got userinfo', extra = {'user_id' : user_id})

            print 'userinfo was successfully retrieved to', user_info['name']

        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'])

            mix.track(user_id, 'failed to got userinfo', {'time' : dt.datetime.now()})
            mongo_logger.debug('failed to got userinfo', extra = {'user_id' : user_id})
    def notify_24hours_ahead(self):
        try:
            userdao = UserDAO()

            current_time = dt.datetime.now()

            print '-' * 40
            print 'push before 24 hours'
            print 'current_time :', current_time

            hour = current_time.hour
            minute = 30 if current_time.minute >= 30 else 0

            current_time = current_time + dt.timedelta(days=1)
            cron_time = current_time.replace(hour=hour,
                                             minute=minute,
                                             second=0,
                                             microsecond=0)

            print 'cron_time :', cron_time
            print '-' * 40

            session = Session()
            result = session.query(Booking, Master, User, UserPushKey) \
                            .join(Master, Booking.master_id == Master.id) \
                            .join(User, Booking.user_id == User.id) \
                            .outerjoin(UserPushKey, User.id == UserPushKey.user_id) \
                            .filter(or_(Booking.cleaning_status == BC.BOOKING_UPCOMMING, Booking.cleaning_status == BC.BOOKING_STARTED)) \
                            .filter(func.date(Booking.start_time) == cron_time.date()) \
                            .filter(func.HOUR(Booking.start_time) == cron_time.time().hour) \
                            .filter(func.MINUTE(Booking.start_time) == cron_time.time().minute) \
                            .all()

            for row in result:

                key = userdao.get_user_salt_by_id(row.User.id)[:16]
                crypto = aes.MyCrypto(key)

                booking_id = row.Booking.id
                pushkey = row.UserPushKey.pushkey if row.UserPushKey != None else ''
                user_name = crypto.decodeAES(row.User.name)
                phone = crypto.decodeAES(row.User.phone)
                master_name = row.Master.name
                devicetype = row.User.devicetype
                price = row.Booking.price_with_task

                start_time = row.Booking.start_time

                print 'push to', user_name, master_name, booking_id
                print pushkey

                if devicetype != 'android':
                    pushkey = crypto.decodeAES(row.User.phone)

                ampm = '오전'
                hour = start_time.hour
                if hour >= 12:
                    if hour > 12:
                        hour -= 12
                    ampm = '오후'

                minute = start_time.minute

                time_str = '%s %d시' % (ampm, hour)
                if minute == 30:
                    time_str += ' 반'

                send_day_ahead_notification(devicetype, [pushkey], booking_id,
                                            user_name, time_str)
                send_alimtalk(phone, 'noti_24', user_name, master_name)

        except Exception, e:
            print_err_detail(e)
コード例 #19
0
    def notify_charge_failure(self):
        try:
            mongo_logger = get_mongo_logger()

            userdao = UserDAO()

            current_time = dt.datetime.now()

            print '-' * 40
            print 'charge failure notification via alimtalk'
            print 'current_time :', current_time

            hour = current_time.hour
            minute = 30 if current_time.minute >= 30 else 0

            cron_time = current_time.replace(hour=hour,
                                             minute=minute,
                                             second=0,
                                             microsecond=0)

            print 'cron_time :', cron_time
            print '-' * 40

            session = Session()
            result = session.query(Booking, User) \
                            .join(User, Booking.user_id == User.id) \
                            .filter(Booking.cleaning_status == BC.BOOKING_COMPLETED) \
                            .filter(Booking.payment_status != BC.BOOKING_PAID) \
                            .filter(func.date(Booking.estimated_end_time) == cron_time.date()) \
                            .filter(func.HOUR(Booking.estimated_end_time) == cron_time.time().hour) \
                            .filter(func.MINUTE(Booking.estimated_end_time) == cron_time.time().minute) \
                            .filter(User.is_b2b == 0) \
                            .filter(Booking.source == 'hm') \
                            .all()

            for row in result:
                if 'b2b.com' in row.User.email:  # b2b 무시
                    continue

                if row.User.is_b2b == 1:  # b2b 무시
                    continue

                if row.Booking.source != 'hm':  # 11번가 무시
                    continue

                key = userdao.get_user_salt_by_id(row.User.id)[:16]
                crypto = aes.MyCrypto(key)

                user_id = row.User.id
                phone = crypto.decodeAES(row.User.phone)

                cleaning_time = convert_datetime_format2(
                    row.Booking.start_time)
                price = '{:,}원'.format(row.Booking.price_with_task)

                try:
                    send_alimtalk(phone, 'notify_charge_failure',
                                  cleaning_time, price)

                    mongo_logger.debug('user charge failure',
                                       extra={
                                           'dt': current_time,
                                           'user_id': user_id,
                                           'price': price,
                                           'cleaning_time': cleaning_time
                                       })
                except Exception, e:
                    mongo_logger.error('err user charge failure',
                                       extra={
                                           'dt': current_time,
                                           'user_id': user_id,
                                           'price': price,
                                           'cleaning_time': cleaning_time
                                       })

        except Exception, e:
            print_err_detail(e)
            mongo_logger.error('failed to user charge failure',
                               extra={'err': str(e)})
コード例 #20
0
    def post(self):
        self.set_header("Content-Type", "application/json")
        self.set_header('Access-Control-Allow-Origin', '*')

        booking_id = self.get_argument('booking_id', '')
        reason_id = self.get_argument('reason_id', CANCEL_ADMIN)
        etc_reason = self.get_argument('etc_reason', '')
        no_fee = self.get_argument('no_fee', 0)

        reason_id = int(reason_id)

        print "reason_id : ", reason_id

        no_fee = int(no_fee)

        ret = {}

        mongo_logger = get_mongo_logger()
        mix = get_mixpanel()

        try:
            session = Session()

            try:
                row = session.query(Booking, Master, User, UserAddress) \
                             .join(Master, Booking.master_id == Master.id) \
                             .join(User, Booking.user_id == User.id) \
                             .join(UserDefaultAddress, User.id == UserDefaultAddress.user_id) \
                             .join(UserAddress, and_(UserAddress.user_id == UserDefaultAddress.user_id, UserAddress.user_addr_index == UserDefaultAddress.address_idx)) \
                             .filter(Booking.id == booking_id) \
                             .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \
                             .one()

            except NoResultFound, e:
                session.close()
                self.set_status(Response.RESULT_OK)
                add_err_message_to_response(ret,
                                            err_dict['err_no_entry_to_cancel'])
                return

            user_id = row.Booking.user_id

            masterdao = MasterDAO()
            userdao = UserDAO()
            key = userdao.get_user_salt_by_id(user_id)[:16]
            crypto = aes.MyCrypto(key)

            # push to homemaster via sms
            master_id = row.Master.id

            master_phone = str(row.Master.phone)
            master_name = str(row.Master.name)
            username = str(crypto.decodeAES(row.User.name))
            userphone = str(crypto.decodeAES(row.User.phone))
            date = str(convert_datetime_format(row.Booking.start_time))
            addr = str(crypto.decodeAES(row.UserAddress.address))

            charge = 0
            new_status = BC.BOOKING_CANCELED_CHARGE

            request_id = row.Booking.request_id

            appointment_index = row.Booking.appointment_index
            appointment_time = row.Booking.start_time
            appointment_type = row.Booking.appointment_type
            current_status = row.Booking.status
            current_cleaning_status = row.Booking.cleaning_status
            current_payment_status = row.Booking.payment_status
            price = row.Booking.price_with_task
            source = row.Booking.source
            device_type = row.Booking.user_type
            now = dt.datetime.now()
            cancel_amount = 0

            diff_in_hours = (appointment_time - now).total_seconds() / 3600

            if diff_in_hours >= 24:
                charge = price * BC.BOOKING_CHARGE_RATE_NO
            elif 4 <= diff_in_hours < 24:
                charge = price * BC.BOOKING_CHARGE_RATE_30
            else:
                charge = price * BC.BOOKING_CHARGE_RATE_50

            if current_payment_status == BC.BOOKING_PAID:
                if no_fee == 1:  # 관리자가 선택하여 fee를 지불 할 수 있게 하기 위해서
                    charge = 0

                new_status = BC.BOOKING_CANCELED_REFUND

                partial = '1'
                if charge == 0:
                    partial = '0'

                is_event = session.query(UserFreeEvent) \
                                .filter(UserFreeEvent.booking_request_id == request_id) \
                                .first()

                is_event = True if is_event != None else False

                cancel_amount = int(price - charge)
                if cancel_amount > 0 and source == 'hm' and userdao.get_user_default_card_index(
                        user_id) != -1:
                    if not (is_event and appointment_index == 1):
                        ret_code, msg = cancel_payment(user_id, booking_id,
                                                       cancel_amount, partial)
                        if ret_code == False:
                            session.close()
                            self.set_status(Response.RESULT_OK)
                            add_err_ko_message_to_response(ret, msg)
                            #self.write(json.dumps(ret))
                            return
                    else:
                        # 결제 필요
                        # 취소에 대한 결제 필요
                        partial = '0'
                        cancel_amount = row.Booking.price_with_task - row.Booking.price
                        if cancel_amount > 0:
                            cancel_payment(user_id, booking_id, cancel_amount,
                                           partial)

                        complete_count = session.query(Booking) \
                                .filter(Booking.request_id == request_id) \
                                .filter(Booking.cleaning_status == 2) \
                                .count()

                        print complete_count, row.Booking.cleaning_status
                        if complete_count < 9 and row.Booking.cleaning_status == 2:
                            ret_code, msg = request_payment(
                                user_id, username, booking_id, price,
                                appointment_type)
                            if ret_code == False:
                                row.Booking.payment_status = BC.BOOKING_PAYMENT_FAILED

            else:  # cancel charge price
                print 'cancel charge'
                charging_price = int(charge)
                if charging_price > 0 and source == 'hm' and userdao.get_user_default_card_index(
                        user_id) != -1 and no_fee == 0:
                    print user_id, username, booking_id, charging_price, appointment_type

                    ret_code, msg = request_payment(user_id, username,
                                                    booking_id, charging_price,
                                                    appointment_type)
                    if ret_code == False:
                        new_status = BC.BOOKING_PAYMENT_FAILED

            #row.Booking.modified_date   = now
            row.Booking.charging_price = int(charge)
            row.Booking.status = new_status
            row.Booking.cleaning_status = BC.BOOKING_CANCELED
            row.Booking.payment_status = new_status

            appointment_type_text = ''
            if appointment_type == BC.ONE_TIME or appointment_type == BC.ONE_TIME_BUT_CONSIDERING:
                appointment_type_text = '1회'
            elif appointment_type == BC.FOUR_TIME_A_MONTH:
                appointment_type_text = '매주'
            elif appointment_type == BC.TWO_TIME_A_MONTH:
                appointment_type_text = '2주 1회'
            elif appointment_type == BC.ONE_TIME_A_MONTH:
                appointment_type_text = '4주 1회'

            #sms_sender = SMS_Sender()
            #text = BOOKING_CANCEL_TEXT % (username, userphone, master_name, date)
            #print sms_sender.send_for_manager(sender = MAIN_CALL, mtype = 'sms', to = MANAGERS_CALL, subject = BOOKING_TEXT_SUBJECT, text = text)
            #for manager_phone in MANAGERS_CALL.split(','):
            #    send_alimtalk(manager_phone, 'noti_manager_cancel', username, date, appointment_type_text)

            cancel_reasons = []
            cancel_reasons.append('지금은 서비스가 필요하지 않아요')
            cancel_reasons.append('집에 없어서 문을 열어드릴 수가 없어요')
            cancel_reasons.append('시간이 마음에 들지 않아요')
            cancel_reasons.append('클리닝을 잊고 있었네요')
            cancel_reasons.append('원하는 홈마스터가 아니에요')
            cancel_reasons.append('기타')
            cancel_reasons.append('이사가요')
            cancel_reasons.append('기타')
            cancel_reasons.append('관리자가 취소 했습니다')

            cancel_reason = cancel_reasons[reason_id]
            if cancel_reason == '기타':
                cancel_reason += ' ' + etc_reason
            elif reason_id == CANCEL_ADMIN:
                cancel_reason += ', 관리자 메모 : ' + etc_reason

            send_jandi(
                'NEW_BOOKING', "취소 알림", username + ' 고객님 취소함',
                '{}, {}, 사유 : {}'.format(date, appointment_type_text,
                                         cancel_reason))
            print 'jandi notification for cancel...'

            master_pushkey = masterdao.get_master_pushkey(master_id)
            #master_name = masterdao.get_master_name(master_id)
            #master_phone   = masterdao.get_master_phone(master_id)

            send_booking_canceled('android', [master_pushkey], booking_id,
                                  date, username)

            content = '''{} 홈마스터님
예약이 1회 취소 되었습니다.

고객 : {}
주기 : {}
날짜 : {}'''.format(master_name, username, appointment_type_text, date)

            message_sender = MessageSender()
            message_sender.send([master_phone], '예약 1회 취소 알림', content)

            print 'master_pushkey', master_pushkey
            print booking_id, date

            #send_alimtalk(master_phone, 'noti_manager_cancel', username, date, appointment_type_text)
            # adjust appointment index
            index_result = session.query(Booking).filter(
                Booking.request_id == request_id).filter(
                    Booking.appointment_index > appointment_index).all()
            for index_row in index_result:
                index_row.appointment_index -= 1

            coupondao = CouponDAO()
            coupondao.cancel_coupon_usage(booking_id)

            CANCEL = 0
            cancel_reason = CancelReason(booking_id=booking_id,
                                         user_id=user_id,
                                         reason_id=reason_id,
                                         etc_reason=etc_reason,
                                         kind=CANCEL,
                                         cancel_time=dt.datetime.now())
            session.add(cancel_reason)

            session.commit()

            mix.track(
                user_id, 'cancel', {
                    'time': dt.datetime.now(),
                    'reason_id': reason_id,
                    'etc_reason': etc_reason,
                    'cancel_amount': cancel_amount
                })
            mongo_logger.debug('%s was canceled' % booking_id,
                               extra={
                                   'user_id': user_id,
                                   'booking_id': booking_id,
                                   'cancel_amount': cancel_amount
                               })

            ret['response'] = Response.SUCCESS

            self.set_status(Response.RESULT_OK)
コード例 #21
0
    def get(self):
        self.set_header("Content-Type", "application/json")
        self.set_header('Access-Control-Allow-Origin', '*')

        ret = {}

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

            unassigned_bookings = []

            # for modify request
            result = session.query(MasterBookingModifyRequest, Booking, Master, User) \
                            .join(Booking, Booking.id == MasterBookingModifyRequest.booking_id) \
                            .join(Master, MasterBookingModifyRequest.master_id == Master.id) \
                            .join(User, Booking.user_id == User.id) \
                            .filter(Booking.cleaning_status == 0) \
                            .order_by(Booking.start_time) \
                            .all()

            for row in result:
                key = userdao.get_user_salt_by_id(row.User.id)[:16]
                crypto = aes.MyCrypto(key)

                print 'request modification bookings list..'
                print row.MasterBookingModifyRequest.org_time
                print row.MasterBookingModifyRequest.master_id
                print row.Booking.master_id
                print row.Booking.start_time

                if row.MasterBookingModifyRequest.org_time != None and \
                    (row.MasterBookingModifyRequest.master_id != row.Booking.master_id or \
                    row.MasterBookingModifyRequest.org_time != row.Booking.start_time):
                    continue

                booking = {}
                booking['id'] = row.MasterBookingModifyRequest.id
                booking['booking_id'] = row.Booking.id
                booking['user_name'] = crypto.decodeAES(row.User.name)
                booking['user_phone'] = crypto.decodeAES(row.User.phone)
                booking['master_name'] = row.Master.name
                booking['start_time'] = convert_datetime_format2(
                    row.Booking.start_time)
                booking['reason'] = row.MasterBookingModifyRequest.reason
                booking['status'] = 'REQUESTED'

                unassigned_bookings.append(booking)

            # for unassigned
            result = session.query(Booking, Master, User) \
                    .join(Master, Booking.master_id == Master.id) \
                    .join(User, Booking.user_id == User.id) \
                    .filter(Master.active == 2) \
                    .filter(Booking.cleaning_status == 0) \
                    .order_by(Booking.start_time) \
                    .all()

            for row in result:
                key = userdao.get_user_salt_by_id(row.User.id)[:16]
                crypto = aes.MyCrypto(key)

                booking = {}
                booking['booking_id'] = row.Booking.id
                booking['user_name'] = crypto.decodeAES(row.User.name)
                booking['user_phone'] = crypto.decodeAES(row.User.phone)
                booking['master_name'] = row.Master.name
                booking['start_time'] = convert_datetime_format2(
                    row.Booking.start_time)
                booking['reason'] = '업무 중단'
                booking['status'] = 'UNASSIGNED'

                unassigned_bookings.append(booking)

            ret['response'] = unassigned_bookings
            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'])
    def post(self):
        self.set_header("Content-Type", "application/json")
        booking_id = self.get_argument('booking_id', '')
        reason_id = self.get_argument('reason_id', 0)
        etc_reason = self.get_argument('etc_reason', '')
        charge_amount = self.get_argument('charge_amount', 0)

        charge_amount = int(charge_amount)
        reason_id = int(reason_id)

        print 'cancel all charge amount : ', charge_amount

        ret = {}

        mongo_logger = get_mongo_logger()
        mix = get_mixpanel()

        try:
            session = Session()
            userdao = UserDAO()
            masterdao = MasterDAO()

            stmt = session.query(Booking.request_id).filter(
                Booking.id == booking_id).subquery()
            first_startime = session.query(Booking.start_time).filter(
                Booking.request_id == stmt).order_by(
                    Booking.start_time).first()[0]

            result = session.query(Booking, Master, User, UserAddress) \
                         .join(Master, Booking.master_id == Master.id) \
                         .join(User, Booking.user_id == User.id) \
                         .join(UserDefaultAddress, User.id == UserDefaultAddress.user_id) \
                         .join(UserAddress, and_(UserAddress.user_id == UserDefaultAddress.user_id, UserAddress.user_addr_index == UserDefaultAddress.address_idx)) \
                         .filter(Booking.request_id == stmt) \
                         .filter(or_(Booking.cleaning_status == BC.BOOKING_UPCOMMING, Booking.cleaning_status == BC.BOOKING_STARTED)) \
                         .all()

            # 서비스를 처음 이용한지 2달이 넘었는지 아닌지 조사,
            # 넘지 않았다면 이미 부과된 금액에 대해서도 1회 서비스 금액 과의 차액만큼 부과됨
            current_time = dt.datetime.now()

            completed_charge = 1
            if current_time >= first_startime + dt.timedelta(days=57):
                completed_charge = 0

            cancel_all_charge = 0
            # 그동안의 모든 예약에 대해서 처리함
            for row in result:
                charge = 0

                new_status = BC.BOOKING_CANCELED_CHARGE

                bid = row.Booking.id
                user_id = row.Booking.user_id
                appointment_time = row.Booking.start_time
                current_status = row.Booking.status
                current_cleaning_status = row.Booking.cleaning_status
                current_payment_status = row.Booking.payment_status
                price = row.Booking.price_with_task

                diff_in_hours = (appointment_time -
                                 current_time).total_seconds() / 3600

                if diff_in_hours >= 24:
                    charge = price * BC.BOOKING_CHARGE_RATE_NO
                elif 4 <= diff_in_hours < 24:
                    charge = price * BC.BOOKING_CHARGE_RATE_30
                else:
                    charge = price * BC.BOOKING_CHARGE_RATE_50

                # 이미 지불한 금액에 대해 1회 비용의 차액만큼 계산
                if completed_charge == 1:
                    if current_cleaning_status == BC.BOOKING_COMPLETED:
                        # 차액만큼 계속 더함
                        cancel_all_charge += charge_amount

                if current_payment_status == BC.BOOKING_PAID and current_cleaning_status == BC.BOOKING_UPCOMMING:
                    new_status = BC.BOOKING_CANCELED_REFUND
                    '''
                    partial = '1'
                    if charge == 0:
                        partial = '0'

                    cancel_amount = int(price - charge)
                    if cancel_amount > 0:
                        ret_code, msg = cancel_payment(user_id, bid, cancel_amount, partial)
                        if ret_code == False:
                            session.close()
                            self.set_status(Response.RESULT_OK)
                            add_err_ko_message_to_response(ret, msg)
                            self.write(json.dumps(ret))
                            return   '''

                #row.Booking.modified_date   = current_time
                row.Booking.charging_price = int(charge)
                row.Booking.status = new_status
                row.Booking.cleaning_status = BC.BOOKING_CANCELED
                row.Booking.payment_status = new_status

                # add cancel reason
                CANCEL_ALL = 1
                reason = session.query(CancelReason).filter(
                    CancelReason.booking_id == bid)
                if reason.count() == 0:
                    cancel_reason = CancelReason(booking_id=bid,
                                                 user_id=user_id,
                                                 reason_id=reason_id,
                                                 etc_reason=etc_reason,
                                                 kind=CANCEL_ALL,
                                                 cancel_time=dt.datetime.now())
                    session.add(cancel_reason)
                else:
                    reason_row = reason.one()
                    reason_row.kind = 1
            '''if cancel_all_charge > 0:
                user_name = userdao.get_user_name(user_id)
                ret_code, msg = request_charge(user_id, user_name, cancel_all_charge)
                if ret_code == False:
                    session.close()
                    self.set_status(Response.RESULT_OK)
                    add_err_ko_message_to_response(ret, msg)
                    self.write(json.dumps(ret))
                    return  '''

            key = userdao.get_user_salt_by_id(row.User.id)[:16]
            crypto = aes.MyCrypto(key)

            # push to homemaster via sms
            master_id = row.Master.id
            master_phone = str(row.Master.phone)
            master_name = str(row.Master.name)
            username = str(crypto.decodeAES(row.User.name))
            userphone = str(crypto.decodeAES(row.User.phone))
            date = str(convert_datetime_format(row.Booking.start_time))
            addr = str(crypto.decodeAES(row.UserAddress.address))
            appointment_type = str(row.Booking.appointment_type)

            appointment_type_text = ''
            if appointment_type == BC.ONE_TIME or appointment_type == BC.ONE_TIME_BUT_CONSIDERING:
                appointment_type_text = '1회'
            elif appointment_type == BC.FOUR_TIME_A_MONTH:
                appointment_type_text = '매주'
            elif appointment_type == BC.TWO_TIME_A_MONTH:
                appointment_type_text = '2주 1회'
            elif appointment_type == BC.ONE_TIME_A_MONTH:
                appointment_type_text = '4주 1회'

            #sms_sender = SMS_Sender()
            #text = BOOKING_CANCEL_ALL_TEXT % (appointment_type, username, userphone, master_name, date)
            #send_result = sms_sender.send_for_manager(sender = MAIN_CALL, mtype = 'sms', to = MANAGERS_CALL, subject = BOOKING_TEXT_SUBJECT, text = text)

            for manager_phone in MANAGERS_CALL.split(','):
                send_alimtalk(manager_phone, 'noti_manager_cancel_all',
                              username, date, appointment_type_text)

            master_pushkey = masterdao.get_master_pushkey(master_id)
            #send_all_bookings_canceled('android', [master_pushkey], booking_id, date)

            #send_alimtalk(master_phone, 'noti_manager_cancel_all', username, date, appointment_type_text)

            session.commit()

            mix.track(
                user_id, 'cancel all', {
                    'time': dt.datetime.now(),
                    'reason_id': reason_id,
                    'etc_reason': etc_reason
                })
            mongo_logger.debug('%s was all canceled' % booking_id,
                               extra={
                                   'user_id': user_id,
                                   'booking_id': booking_id
                               })

            ret['response'] = Response.SUCCESS
            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'])
コード例 #23
0
    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'])
コード例 #24
0
    def get(self):
        self.set_header("Content-Type", "application/json")

        ret = {}

        try:
            session = Session()

            bookings = []

            now = dt.datetime.now()

            result = session.query(Booking, Promotion, EventPromotionBooking, Master, User, UserAddress) \
                            .outerjoin(Promotion, Booking.id == Promotion.booking_id) \
                            .outerjoin(EventPromotionBooking, Booking.id == EventPromotionBooking.booking_id) \
                            .join(Master, Master.id == Booking.master_id) \
                            .join(User, Booking.user_id == User.id) \
                            .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \
                            .filter(and_(Booking.appointment_index == 1, Booking.cleaning_status >= BC.BOOKING_UPCOMMING)) \
                            .order_by(desc(Booking.booking_time), desc(Booking.start_time)) \
                            .limit(40)
                            
            for row in result:

                userdao = UserDAO()
                key = userdao.get_user_salt_by_id(row.User.id)[:16]
                crypto = aes.MyCrypto(key)

                booking_info = {}
                booking_info['booking_id']          = row.Booking.id
                booking_info['request_id']          = row.Booking.request_id
                booking_info['master_gender']       = row.Booking.master_gender
                booking_info['master_name']         = row.Master.name
                booking_info['user_id']             = row.User.id
                booking_info['user_name']           = crypto.decodeAES(row.User.name)
                booking_info['user_email']          = row.User.email
                booking_info['user_gender']         = row.User.gender
                booking_info['user_phone']          = crypto.decodeAES(row.User.phone)
                booking_info['user_address']        = crypto.decodeAES(row.UserAddress.address)
                booking_info['user_home_size']      = row.UserAddress.size
                booking_info['user_home_kind']      = row.UserAddress.kind
                booking_info['devicetype']          = row.User.devicetype
                booking_info['appointment_type']    = row.Booking.appointment_type
                booking_info['appointment_index']   = row.Booking.appointment_index
                booking_info['start_time']          = dt.datetime.strftime(row.Booking.start_time, '%Y-%m-%d %H:%M')
                booking_info['estimated_end_time']  = dt.datetime.strftime(row.Booking.estimated_end_time, '%Y-%m-%d %H:%M')
                booking_info['additional_task']     = row.Booking.additional_task
                booking_info['price']               = row.Booking.price_with_task
                booking_info['promotion_code']      = row.Promotion.promotion_code if row.Promotion != None else 'No code'
                booking_info['promotion_amount']    = row.Promotion.discount_price if row.Promotion != None else '0'
                booking_info['event_promotion_code']      = row.EventPromotionBooking.event_name if row.EventPromotionBooking != None else 'No event code'
                booking_info['event_promotion_amount']    = row.EventPromotionBooking.discount_price if row.EventPromotionBooking != None else '0'
                booking_info['msg']                 = row.Booking.message if row.Booking.message != None else ''
                booking_info['trash_location']      = row.Booking.trash_location if row.Booking.trash_location != None else ''
                booking_info['enterhome']           = crypto.decodeAES(row.Booking.enterhome) if row.Booking.enterhome != None else ''
                booking_info['enterbuilding']       = crypto.decodeAES(row.Booking.enterbuilding) if row.Booking.enterbuilding != None else ''
                booking_info['havepet']             = row.Booking.havepet
                booking_info['status']              = row.Booking.status
                booking_info['cleaning_status']     = row.Booking.cleaning_status
                booking_info['payment_status']      = row.Booking.payment_status
                booking_info['devicetype']          = row.User.devicetype.lower()
                booking_info['booking_time']        = dt.datetime.strftime(row.Booking.booking_time, '%Y-%m-%d %H:%M') if row.Booking.booking_time != None else ''

                bookings.append(booking_info)

            print bookings
            ret['response'] = bookings
            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'])
    def post(self):
        self.set_header("Content-Type", "application/json")
        booking_id = self.get_argument('booking_id', '')
        reason_id = self.get_argument('reason_id', 0)
        etc_reason = self.get_argument('etc_reason', '')

        reason_id = int(reason_id)

        ret = {}

        mongo_logger = get_mongo_logger()
        mix = get_mixpanel()

        try:
            session = Session()

            try:
                row = session.query(Booking, Master, User, UserAddress) \
                             .join(Master, Booking.master_id == Master.id) \
                             .join(User, Booking.user_id == User.id) \
                             .join(UserDefaultAddress, User.id == UserDefaultAddress.user_id) \
                             .join(UserAddress, and_(UserAddress.user_id == UserDefaultAddress.user_id, UserAddress.user_addr_index == UserDefaultAddress.address_idx)) \
                             .filter(Booking.id == booking_id) \
                             .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \
                             .one()

            except NoResultFound, e:
                session.close()
                self.set_status(Response.RESULT_OK)
                add_err_message_to_response(ret,
                                            err_dict['err_no_entry_to_cancel'])
                self.write(json.dumps(ret))
                return

            charge = 0
            new_status = BC.BOOKING_CANCELED_CHARGE

            request_id = row.Booking.request_id
            user_id = row.Booking.user_id
            appointment_index = row.Booking.appointment_index
            appointment_time = row.Booking.start_time
            appointment_type = row.Booking.appointment_type
            current_status = row.Booking.status
            current_cleaning_status = row.Booking.cleaning_status
            current_payment_status = row.Booking.payment_status
            price = row.Booking.price_with_task
            now = dt.datetime.now()

            diff_in_hours = (appointment_time - now).total_seconds() / 3600

            if diff_in_hours >= 24:
                charge = price * BC.BOOKING_CHARGE_RATE_NO
            elif 4 <= diff_in_hours < 24:
                charge = price * BC.BOOKING_CHARGE_RATE_30
            else:
                charge = price * BC.BOOKING_CHARGE_RATE_50

            if current_payment_status == BC.BOOKING_PAID:
                new_status = BC.BOOKING_CANCELED_REFUND
                '''
                partial = '1'
                if charge == 0:
                    partial = '0'

                cancel_amount = int(price - charge)
                if cancel_amount > 0:
                    ret_code, msg = cancel_payment(user_id, booking_id, cancel_amount, partial)
                    if ret_code == False:
                        session.close()
                        self.set_status(Response.RESULT_OK)
                        add_err_ko_message_to_response(ret, msg)
                        self.write(json.dumps(ret))
                        return'''

            #row.Booking.modified_date   = now
            row.Booking.charging_price = int(charge)
            row.Booking.status = new_status
            row.Booking.cleaning_status = BC.BOOKING_CANCELED
            row.Booking.payment_status = new_status

            masterdao = MasterDAO()
            userdao = UserDAO()
            key = userdao.get_user_salt_by_id(user_id)[:16]
            crypto = aes.MyCrypto(key)

            # push to homemaster via sms
            master_id = row.Master.id
            master_phone = str(row.Master.phone)
            master_name = str(row.Master.name)
            username = str(crypto.decodeAES(row.User.name))
            userphone = str(crypto.decodeAES(row.User.phone))
            date = str(convert_datetime_format(row.Booking.start_time))
            addr = str(crypto.decodeAES(row.UserAddress.address))

            appointment_type_text = ''
            if appointment_type == BC.ONE_TIME or appointment_type == BC.ONE_TIME_BUT_CONSIDERING:
                appointment_type_text = '1회'
            elif appointment_type == BC.FOUR_TIME_A_MONTH:
                appointment_type_text = '매주'
            elif appointment_type == BC.TWO_TIME_A_MONTH:
                appointment_type_text = '2주 1회'
            elif appointment_type == BC.ONE_TIME_A_MONTH:
                appointment_type_text = '4주 1회'

            #sms_sender = SMS_Sender()
            #text = BOOKING_CANCEL_TEXT % (username, userphone, master_name, date)
            #print sms_sender.send_for_manager(sender = MAIN_CALL, mtype = 'sms', to = MANAGERS_CALL, subject = BOOKING_TEXT_SUBJECT, text = text)
            for manager_phone in MANAGERS_CALL.split(','):
                send_alimtalk(manager_phone, 'noti_manager_cancel', username,
                              date, appointment_type_text)

            master_pushkey = masterdao.get_master_pushkey(master_id)
            #send_booking_canceled('android', [master_pushkey], booking_id, date)

            print 'master_pushkey', master_pushkey
            print booking_id, date

            #send_alimtalk(master_phone, 'noti_manager_cancel', username, date, appointment_type_text)

            # adjust appointment index
            index_result = session.query(Booking).filter(
                Booking.request_id == request_id).filter(
                    Booking.appointment_index > appointment_index).all()
            for index_row in index_result:
                index_row.appointment_index -= 1

            CANCEL = 0
            cancel_reason = CancelReason(booking_id=booking_id,
                                         user_id=user_id,
                                         reason_id=reason_id,
                                         etc_reason=etc_reason,
                                         kind=CANCEL,
                                         cancel_time=dt.datetime.now())
            session.add(cancel_reason)

            session.commit()

            mix.track(
                user_id, 'cancel', {
                    'time': dt.datetime.now(),
                    'reason_id': reason_id,
                    'etc_reason': etc_reason
                })
            mongo_logger.debug('%s was canceled' % booking_id,
                               extra={
                                   'user_id': user_id,
                                   'booking_id': booking_id
                               })

            ret['response'] = Response.SUCCESS
            self.set_status(Response.RESULT_OK)
コード例 #26
0
    def post(self):
        self.set_header("Content-Type", "application/json")
        self.set_header('Access-Control-Allow-Origin', '*')

        booking_id = self.get_argument('booking_id', '')
        reason_id = self.get_argument('reason_id', CANCEL_ADMIN)
        etc_reason = self.get_argument('etc_reason', '')
        charge_amount = self.get_argument('charge_amount', 0)
        no_fee = self.get_argument('no_fee', 0)

        regular_cancel_charge = self.get_argument('regular_cancel_charge', 0)

        charge_amount = int(charge_amount)
        reason_id = int(reason_id)
        no_fee = int(no_fee)

        regular_cancel_charge = int(regular_cancel_charge)

        print 'cancel all charge amount : ', charge_amount
        print 'reason_id : ', reason_id
        print 'etc_reason : ', etc_reason

        ret = {}

        mongo_logger = get_mongo_logger()
        mix = get_mixpanel()

        try:
            session = Session()
            userdao = UserDAO()
            masterdao = MasterDAO()

            stmt = session.query(Booking.request_id).filter(
                Booking.id == booking_id).subquery()
            first_startime = session.query(Booking.start_time).filter(
                Booking.request_id == stmt).order_by(
                    Booking.start_time).first()[0]

            result = session.query(Booking, Master, User, UserAddress) \
                         .join(Master, Booking.master_id == Master.id) \
                         .join(User, Booking.user_id == User.id) \
                         .join(UserDefaultAddress, User.id == UserDefaultAddress.user_id) \
                         .join(UserAddress, and_(UserAddress.user_id == UserDefaultAddress.user_id, UserAddress.user_addr_index == UserDefaultAddress.address_idx)) \
                         .filter(Booking.request_id == stmt) \
                         .filter(or_(Booking.cleaning_status == BC.BOOKING_UPCOMMING, Booking.cleaning_status == BC.BOOKING_STARTED, Booking.cleaning_status == BC.BOOKING_COMPLETED)) \
                         .all()

            # 서비스를 처음 이용한지 2달이 넘었는지 아닌지 조사,
            # 넘지 않았다면 이미 부과된 금액에 대해서도 1회 서비스 금액 과의 차액만큼 부과됨
            current_time = dt.datetime.now()

            completed_charge = 1
            if current_time >= first_startime + dt.timedelta(days=57):
                completed_charge = 0

            cancel_all_charge = 0
            # 그동안의 모든 예약에 대해서 처리함
            for row in result:
                charge = 0

                new_status = BC.BOOKING_CANCELED_CHARGE

                key = userdao.get_user_salt_by_id(row.User.id)[:16]
                crypto = aes.MyCrypto(key)

                username = str(crypto.decodeAES(row.User.name))

                request_id = row.Booking.request_id
                appointment_index = row.Booking.appointment_index

                bid = row.Booking.id
                user_id = row.Booking.user_id
                appointment_time = row.Booking.start_time
                current_status = row.Booking.status
                current_cleaning_status = row.Booking.cleaning_status
                current_payment_status = row.Booking.payment_status
                price = row.Booking.price_with_task
                source = row.Booking.source
                appointment_type = row.Booking.appointment_type

                diff_in_hours = (appointment_time -
                                 current_time).total_seconds() / 3600

                if diff_in_hours >= 24:
                    charge = price * BC.BOOKING_CHARGE_RATE_NO
                elif 4 <= diff_in_hours < 24:
                    charge = price * BC.BOOKING_CHARGE_RATE_30
                else:
                    charge = price * BC.BOOKING_CHARGE_RATE_50

                # 이미 지불한 금액에 대해 1회 비용의 차액만큼 계산
                if completed_charge == 1:
                    if current_cleaning_status == BC.BOOKING_COMPLETED:
                        # 차액만큼 계속 더함
                        _, house_size, house_type = userdao.get_user_address_detail_by_index(
                            user_id, row.Booking.addr_idx)
                        time_prices = get_basic_time_price(
                            house_type, house_size)
                        try:
                            print time_prices[0]['price']
                            print time_prices[appointment_type]['price']
                            charge_amount = int(
                                time_prices[0]['price'] -
                                time_prices[appointment_type]['price'])
                        except Exception:
                            charge_amount = 3000
                        cancel_all_charge += charge_amount

                # event
                is_event = session.query(UserFreeEvent) \
                                .filter(UserFreeEvent.booking_request_id == request_id) \
                                .first()

                is_event = True if is_event != None else False

                if is_event == True and appointment_index == 1:
                    partial = '0'
                    cancel_amount = row.Booking.price_with_task - row.Booking.price
                    cancel_payment(user_id, bid, cancel_amount, partial)

                    # 취소에 대한 결제 필요
                    # 8회 이상 썼다면(완료카운트 9회 미만일 경우 결제)
                    complete_count = session.query(Booking) \
                            .filter(Booking.request_id == request_id) \
                            .filter(Booking.cleaning_status == 2) \
                            .count()

                    if complete_count < 9 and row.Booking.cleaning_status == 2:
                        ret_code, msg = request_payment(
                            user_id, username, booking_id, price,
                            appointment_type)
                        if ret_code == False:
                            row.Booking.payment_status = BC.BOOKING_PAYMENT_FAILED

                if current_payment_status == BC.BOOKING_PAID and current_cleaning_status == BC.BOOKING_UPCOMMING:
                    if no_fee == 1:
                        charge = 0

                    new_status = BC.BOOKING_CANCELED_REFUND

                    partial = '1'
                    if charge == 0:
                        partial = '0'

                    cancel_amount = int(price - charge)
                    if cancel_amount > 0 and source == 'hm' and userdao.get_user_default_card_index(
                            user_id) != -1:
                        if not (is_event and appointment_index == 1):
                            ret_code, msg = cancel_payment(
                                user_id, bid, cancel_amount, partial)
                            if ret_code == False:
                                session.close()
                                self.set_status(Response.RESULT_OK)
                                add_err_ko_message_to_response(ret, msg)
                                #self.write(json.dumps(ret))
                                return

                elif current_payment_status == BC.BOOKING_UNPAID_YET and current_cleaning_status == BC.BOOKING_UPCOMMING:
                    print 'cancel charge'
                    charging_price = int(charge)
                    if charging_price > 0 and source == 'hm' and userdao.get_user_default_card_index(
                            user_id) != -1 and no_fee == 0:
                        print user_id, username, booking_id, charging_price, appointment_type
                        ret_code, msg = request_payment(
                            user_id, username, bid, charging_price,
                            appointment_type)
                        if ret_code == False:
                            new_status = BC.BOOKING_PAYMENT_FAILED

                #row.Booking.modified_date   = current_time
                if current_cleaning_status == BC.BOOKING_UPCOMMING:
                    row.Booking.charging_price = int(charge)
                    row.Booking.status = new_status
                    row.Booking.cleaning_status = BC.BOOKING_CANCELED
                    row.Booking.payment_status = new_status

                # add cancel reason
                CANCEL_ALL = 1
                reason = session.query(CancelReason).filter(
                    CancelReason.booking_id == bid)
                if reason.count() == 0:
                    cancel_reason = CancelReason(booking_id=bid,
                                                 user_id=user_id,
                                                 reason_id=reason_id,
                                                 etc_reason=etc_reason,
                                                 kind=CANCEL_ALL,
                                                 cancel_time=dt.datetime.now())
                    session.add(cancel_reason)
                else:
                    try:
                        reason_row = reason.one()
                        reason_row.kind = 1
                    except Exception, e:
                        print e

            # 수수료 임시 처리 막기
            #cancel_all_charge = 0
            if cancel_all_charge > 0 and source == 'hm' and regular_cancel_charge == 0:
                user_name = userdao.get_user_name(user_id)
                ret_code, msg = request_charge(user_id, user_name,
                                               cancel_all_charge)
                if ret_code == False:
                    session.close()
                    self.set_status(Response.RESULT_OK)
                    add_err_ko_message_to_response(ret, msg)
                    self.write(json.dumps(ret))
                    return

            if row != None:
                key = userdao.get_user_salt_by_id(row.User.id)[:16]
                crypto = aes.MyCrypto(key)

                # push to homemaster via sms
                master_id = row.Master.id
                master_phone = str(row.Master.phone)
                master_name = str(row.Master.name)
                username = str(crypto.decodeAES(row.User.name))
                userphone = str(crypto.decodeAES(row.User.phone))
                date = str(convert_datetime_format(row.Booking.start_time))
                addr = str(crypto.decodeAES(row.UserAddress.address))
                appointment_type = str(row.Booking.appointment_type)

                print 'app _type'
                print appointment_type

                appointment_type_text = ''
                if appointment_type == BC.ONE_TIME or appointment_type == BC.ONE_TIME_BUT_CONSIDERING:
                    appointment_type_text = '1회'
                elif appointment_type == BC.FOUR_TIME_A_MONTH:
                    appointment_type_text = '매주'
                elif appointment_type == BC.TWO_TIME_A_MONTH:
                    appointment_type_text = '2주 1회'
                elif appointment_type == BC.ONE_TIME_A_MONTH:
                    appointment_type_text = '4주 1회'

                #sms_sender = SMS_Sender()
                #text = BOOKING_CANCEL_ALL_TEXT % (appointment_type, username, userphone, master_name, date)
                #send_result = sms_sender.send_for_manager(sender = MAIN_CALL, mtype = 'sms', to = MANAGERS_CALL, subject = BOOKING_TEXT_SUBJECT, text = text)

                #for manager_phone in MANAGERS_CALL.split(','):
                #    send_alimtalk(manager_phone, 'noti_manager_cancel_all', username, date, appointment_type_text)

                cancel_all_reasons = []
                cancel_all_reasons.append('너무 비싸요')
                cancel_all_reasons.append('제가 여행을 가요')
                cancel_all_reasons.append('청소품질이 마음에 들지 않아요')
                cancel_all_reasons.append('필요할 때에만 서비스를 이용하고 싶어요')
                cancel_all_reasons.append('다른 업체로 바꿀래요')
                cancel_all_reasons.append('원하던 홈마스터가 오질 않아요')
                cancel_all_reasons.append('저 이사가요')
                cancel_all_reasons.append('기타')
                cancel_all_reasons.append('관리자가 취소 했습니다')

                cancel_reason = cancel_all_reasons[reason_id]
                if cancel_reason == '기타':
                    cancel_reason += ' ' + etc_reason
                elif reason_id == CANCEL_ADMIN:
                    cancel_reason += ', 관리자 메모 : ' + etc_reason

                send_jandi(
                    'NEW_BOOKING', "전체 취소 알림", username + ' 고객님 전체 취소함',
                    '{}, {} 사유 : {}'.format(date, appointment_type_text,
                                            cancel_reason))

                print 'jandi notification for cancel all...'

                master_pushkey = masterdao.get_master_pushkey(master_id)
                send_all_bookings_canceled('android', [master_pushkey],
                                           booking_id, date, username)

                master_phone = masterdao.get_master_phone(master_id)
                master_name = masterdao.get_master_name(master_id)

                user_name = userdao.get_user_name(user_id)

                content = '''{} 홈마스터님
정기 고객의 예약이 전체 취소 되었습니다.

고객 : {}
주기 : {}'''.format(master_name, user_name, appointment_type_text)

                print 'text'
                print appointment_type_text
                message_sender = MessageSender()
                message_sender.send([master_phone], '예약 전체 취소 알림', content)

                #send_alimtalk(master_phone, 'noti_manager_cancel_all', username, date, appointment_type_text)

            coupondao = CouponDAO()
            coupondao.cancelall_coupon_usage(booking_id)

            session.commit()

            mix.track(
                user_id, 'cancel all', {
                    'time': dt.datetime.now(),
                    'reason_id': reason_id,
                    'etc_reason': etc_reason
                })
            mongo_logger.debug('%s was all canceled' % booking_id,
                               extra={
                                   'user_id': user_id,
                                   'booking_id': booking_id
                               })

            ret['response'] = Response.SUCCESS
            self.set_status(Response.RESULT_OK)
    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)})
    def post(self):
        self.set_header("Content-Type", "application/json")

        master_id = self.get_argument('master_id', '')
        date = self.get_argument('date', '')

        ret = {}

        date = dt.datetime.strptime(date, '%Y%m%d')

        try:
            session = Session()
            userdao = UserDAO()
            masterdao = MasterDAO()

            content = ''
            result = session.query(Booking, Master, User, UserAddress) \
                            .join(Master, Booking.master_id == Master.id) \
                            .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_COMPLETED)) \
                            .order_by(Booking.start_time) \
                            .all()

            word_idx = 1

            master_name = masterdao.get_master_name(master_id)
            master_phone = masterdao.get_master_phone(master_id)

            for row in result:
                key = userdao.get_user_salt_by_id(row.User.id)[:16]
                crypto = aes.MyCrypto(key)
                master_phone = str(row.Master.phone)
                master_name = str(row.Master.name)
                user_name = str(crypto.decodeAES(row.User.name))
                appointment_index = str(row.Booking.appointment_index)
                enterbuilding = str(
                    crypto.decodeAES(row.Booking.enterbuilding)
                ) if row.Booking.enterbuilding != None else str('')
                enterhome = str(crypto.decodeAES(row.Booking.enterhome)
                                ) if row.Booking.enterhome != None else str('')
                date_str = str(convert_datetime_format2(
                    row.Booking.start_time))
                address = str(crypto.decodeAES(row.UserAddress.address))
                appointment_type    = str(4 / row.Booking.appointment_type) + '주' \
                                      if row.Booking.appointment_type != BC.ONE_TIME \
                                      and row.Booking.appointment_type != BC.ONE_TIME_BUT_CONSIDERING \
                                      else '1회'
                additional_task = additional_task_string(
                    row.Booking.additional_task)
                take_time = timedelta_to_time(row.Booking.estimated_end_time -
                                              row.Booking.start_time)
                take_time_str = '%d시간 %d분' % (take_time.hour, take_time.minute)
                message = str(row.Booking.message)
                trash_location = str(row.Booking.trash_location)

                text = CONFIRM_UPDATE_BODY % (
                    user_name, appointment_index, date_str, address,
                    appointment_type, additional_task, take_time_str,
                    enterbuilding, enterhome, message, trash_location)

                content += str(word_idx) + '. ' + str(text) + '\n\n'
                word_idx += 1

            booking_date = dt.datetime.strftime(date, '%m월%d일')
            title = '%s 홈마스터님, %s 일정입니다.' % (master_name, booking_date)

            if word_idx == 1:
                content = '홈마스터님 내일 일정은 없습니다.'
                title = '홈마스터님 내일 일정은 없습니다.'

            ret['response'] = {
                'content': content,
                'phone': master_phone,
                'subject': title
            }
            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'])
コード例 #29
0
            row = session.query(Booking, User) \
                         .join(User, Booking.user_id == User.id) \
                         .filter(Booking.id == booking_id) \
                         .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \
                         .one()

        except NoResultFound, e:
                session.close()
                return False               

        except MultipleResultsFound, e:
            session.close()
            return False

        userdao = UserDAO()
        key = userdao.get_user_salt_by_id(row.User.id)[:16]
        crypto = aes.MyCrypto(key)

        user_name = str(crypto.decodeAES(row.User.name))
        user_phone = str(crypto.decodeAES(row.User.phone))

        text = '%s 고객님 감사드립니다 :)\n홈마스터 서비스에 대한 안내는 첨부된 이미지를 참고 부탁드립니다~' % user_name

        sms_sender = SMS_Sender()
        sms_sender.send_for_manager(sender = MAIN_CALL, mtype = 'mms', to = user_phone, subject = NOTIFY_TEXT_SUBJECT, text = str(text), image='/home/dev/customer_mms.png')

    except Exception, e:
        print_err_detail(e)
    finally:
        session.close()
        return True
コード例 #30
0
    def get(self):
        self.set_header("Content-Type", "application/json")
        self.set_header('Access-Control-Allow-Origin', '*')

        datetime = self.get_argument('datetime', '')
        datetime = dt.datetime.strptime(datetime, '%Y%m%d')

        ret = {}

        try:
            session = Session()

            userdao = UserDAO()
            users_register = userdao.get_users_who_register_only(datetime)
            users_address = userdao.get_users_who_add_address_only(datetime)

            user_groups = [users_register, users_address]
            for user_group in user_groups:
                for user in user_group:
                    if 'sigungu_id' in user:
                        del user['sigungu_id']
                    try:
                        user_id = user['id']
                        row = session.query(UserReason) \
                                    .filter(UserReason.user_id == user_id) \
                                    .one()

                        user['contact1'] = row.contact1
                        user['contact2'] = row.contact2
                        user['contact3'] = row.contact3
                        user['contact1_time'] = convert_datetime_format2(
                            row.contact1_time
                        ) if row.contact1_time != None else ''
                        user['contact2_time'] = convert_datetime_format2(
                            row.contact2_time
                        ) if row.contact2_time != None else ''
                        user['contact3_time'] = convert_datetime_format2(
                            row.contact3_time
                        ) if row.contact3_time != None else ''
                        user['reason'] = row.reason
                        user['status'] = row.status
                        user['possible'] = row.possible

                    except Exception, e:
                        #print_err_detail(e)
                        user['contact1'] = ''
                        user['contact2'] = ''
                        user['contact3'] = ''
                        user['contact1_time'] = ''
                        user['contact2_time'] = ''
                        user['contact3_time'] = ''
                        user['reason'] = ''
                        user['status'] = ''
                        user['possible'] = ''


            result = session.query(UserReason, User, Booking) \
                            .join(User, UserReason.user_id == User.id) \
                            .join(Booking, User.id == Booking.user_id) \
                            .filter(UserReason.status == '성공') \
                            .group_by(User.id) \
                            .all()

            users_success = []
            for row in result:
                key = userdao.get_user_salt_by_id(row.User.id)[:16]
                crypto = aes.MyCrypto(key)

                user_name = crypto.decodeAES(row.User.name)
                user_phone = crypto.decodeAES(row.User.phone)

                booking_id = row.Booking.id

                users_success.append({'name' : user_name, \
                                    'phone' : user_phone, \
                                    'booking_id' : booking_id
                                    })

            user_in_funnel = {}
            user_in_funnel['register'] = users_register
            user_in_funnel['address'] = users_address
            user_in_funnel['success'] = users_success

            ret['response'] = user_in_funnel

            self.set_status(Response.RESULT_OK)