Exemple #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)
Exemple #2
0
def send_survey_link():
    update_time = dt.datetime(2016, 9, 27)

    session = Session()
    result  = session.query(User) \
                     .filter(func.length(func.aes_decrypt(func.from_base64(User.phone), func.substring(User.salt, 1, 16))) < 12) \
                     .filter(User.phone != 'out') \
                     .filter(User.active == 1) \
                     .filter(not_(User.email.op('regexp')(r'._$'))) \
                     .all()

    sms_sender = Message_Sender()

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

        name = crypto.decodeAES(row.name)
        phone = crypto.decodeAES(row.phone)
        print name, phone

        text = '''(광고) 홈마스터 설문조사참여하고 신세계 상품권 받으세요^^
https://goo.gl/kYNti3
~12.31'''
        print sms_sender.send(sender=MAIN_CALL,
                              mtype='lms',
                              to=str(phone),
                              text=str(text))
Exemple #3
0
class ManualChargeHandler(tornado.web.RequestHandler):
    def post(self):
        self.set_header("Content-Type", "application/json")
        self.set_header('Access-Control-Allow-Origin', '*')

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

        price = int(price)

        ret = {}

        try:
            session = Session()

            try:
                row = session.query(Booking, User) \
                        .join(User, Booking.user_id == User.id) \
                        .filter(Booking.id == booking_id) \
                        .one()

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

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

            userdao = UserDAO()

            user_id = row.User.id

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

            user_name = crypto.decodeAES(row.User.name)
            appointment_type = row.Booking.appointment_type

            if row.User.devicetype == 'None':
                try:
                    record = UserPaymentRecordForIOS(booking_id, user_id,
                                                     price, dt.datetime.now())
                    session.add(record)
                    session.commit()
                    ret_code = True
                except Exception, e:
                    ret_code = False
                    value = str(e)
    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)
    def get_user_phone(self, uid):
        phone = ''
        try:
            session = Session()

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

            row = session.query(User).filter(User.id == uid).one()
            phone = crypto.decodeAES(row.phone)
        except NoResultFound, e:
            print_err_detail(e)
Exemple #6
0
    def get(self):
        self.set_header("Content-Type", "application/json")

        ret = {}

        try:
            session = Session()

            ratings = []

            userdao = UserDAO()

            result = session.query(Rating, Booking, User, Master) \
                            .join(Booking, Rating.booking_id == Booking.id) \
                            .join(Master, Rating.master_id == Master.id) \
                            .join(User, Booking.user_id == User.id) \
                            .order_by(desc(Rating.review_time)) \
                            .all()

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

                rating = {}

                rating['user_name'] = crypto.decodeAES(row.User.name)
                rating['master_name'] = row.Master.name
                rating['appointment_type'] = row.Booking.appointment_type
                rating['start_time'] = dt.datetime.strftime(
                    row.Booking.start_time, '%Y-%m-%d %H:%M')
                rating['estimated_end_time'] = dt.datetime.strftime(
                    row.Booking.estimated_end_time, '%Y-%m-%d %H:%M')
                rating['end_time'] = dt.datetime.strftime(
                    row.Booking.end_time, '%Y-%m-%d %H:%M')
                rating['clean_rating'] = float(row.Rating.rate_clean)
                rating['clean_review'] = row.Rating.review_clean
                rating['master_rating'] = float(row.Rating.rate_master)
                rating['master_review'] = row.Rating.review_master
                rating['review_time'] = dt.datetime.strftime(
                    row.Rating.review_time, '%Y-%m-%d %H:%M')

                ratings.append(rating)

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

        except Exception, e:
            session.rollback()

            print_err_detail(e)
            self.set_status(Response.RESULT_SERVERERROR)
            add_err_message_to_response(ret, err_dict['err_mysql'])
class ModifyEntranceMethodHandler(tornado.web.RequestHandler):
    def post(self):
        self.set_header("Content-Type", "application/json")
        self.set_header('Access-Control-Allow-Origin', '*')

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

        ret = {}

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

            try:
                row = session.query(Booking).filter(
                    Booking.id == booking_id).one()
            except NoResultFound, e:
                session.close()
                self.set_status(Response.RESULT_OK)
                add_err_message_to_response(ret, err_dict['err_no_record'])
                return

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

            request_id = row.request_id
            user_id = row.user_id

            key = userdao.get_user_salt_by_id(user_id)[:16]
            crypto = aes.MyCrypto(key)
            encrypted_enterhome = crypto.encodeAES(str(enterhome))
            encrypted_enterbuilding = crypto.encodeAES(str(enterbuilding))

            result = session.query(Booking).filter(
                Booking.request_id == request_id).all()
            for booking_row in result:
                booking_row.enterhome = encrypted_enterhome
                booking_row.enterbuilding = encrypted_enterbuilding

            session.commit()

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

            print booking_id, 'was updated entherhome, enterbuilding', dt.datetime.now(
            )
Exemple #8
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'])
class ManualUnpaidChargeHandler(tornado.web.RequestHandler):
    def post(self):
        self.set_header("Content-Type", "application/json")

        user_id      = self.get_argument('user_id', '')
        amount       = self.get_argument('amount', '')
        interest     = self.get_argument('interest', '0')
        quota        = self.get_argument('quota', '00')

        amount = int(amount)

        ret = {}

        try:
            session = Session()

            try:
                row = session.query(User) \
                        .filter(User.id == user_id) \
                        .one()

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

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

            userdao = UserDAO()
            user_id = row.id

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

            user_name = crypto.decodeAES(row.name)

            ret_code, value = request_unpaid_charge(user_id, user_name, amount, interest, quota)
            if ret_code == True:
                ret['response'] = Response.SUCCESS
            else:
                add_err_ko_message_to_response(ret, value)

            self.set_status(Response.RESULT_OK)
Exemple #10
0
    def get(self):
        self.set_header("Content-Type", "application/json")
        self.set_header('Access-Control-Allow-Origin', '*')

        ret = {}

        print "test-intro"

        try:
            session = Session()

            result = session.query(UserClaim, Booking, User, Master) \
                            .join(Booking, UserClaim.booking_id == Booking.id) \
                            .join(Master, Master.id == Booking.master_id) \
                            .join(User, User.id == Booking.user_id) \
                            .all()
            claims = []
            Userdao = UserDAO()

            print result

            for record in result:
                key = Userdao.get_user_salt(record.User.email)[:16]
                if key == None or key == '':
                    continue

                crypto = aes.MyCrypto(key)

                claim_info = {}
                claim_info['cleanning_date'] = dt.datetime.strftime(
                    record.Booking.start_time, '%Y-%m-%d %H:%M')
                claim_info['user_name'] = crypto.decodeAES(record.User.name)
                claim_info['user_phone'] = crypto.decodeAES(record.User.phone)
                claim_info['master_name'] = record.Master.name
                claim_info['claim_comment'] = record.UserClaim.comment
                claim_info['claim_reg_time'] = dt.datetime.strftime(
                    record.UserClaim.register_time, '%Y-%m-%d %H:%M')
                claims.append(claim_info)

            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'])
Exemple #11
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'])
    def get(self):
        self.set_header("Content-Type", "application/json")

        ret = {}

        try:
            session = Session()

            users = []

            userdao = UserDAO()

            for row in session.query(User, UserAddress) \
                            .outerjoin(UserDefaultAddress, UserDefaultAddress.user_id == User.id) \
                            .outerjoin(UserAddress, and_(UserDefaultAddress.user_id == UserAddress.user_id, UserDefaultAddress.address_idx == UserAddress.user_addr_index)) \
                            .order_by(desc(User.dateofreg)) \
                            .all():

                key = userdao.get_user_salt(row.User.email)[:16]
                crypto = aes.MyCrypto(key)

                user_info = {}
                user_info['user_id']    = row.User.id
                user_info['dateofreg']  = dt.datetime.strftime(row.User.dateofreg, '%Y-%m-%d %H:%M')
                user_info['devicetype'] = row.User.devicetype
                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['birthdate']  = crypto.decodeAES(row.User.dateofbirth)
                user_info['default_address'] = crypto.decodeAES(row.UserAddress.address) if row.UserAddress != None else ''
                user_info['default_address_size'] = row.UserAddress.size if row.UserAddress != None else ''
                user_info['default_address_kind'] = row.UserAddress.kind if row.UserAddress != None else ''

                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'])
    def get_user_address_by_index(self, uid, addr_idx):
        try:
            session = Session()

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

            row = session.query(User, UserAddress) \
                .join(UserAddress, and_(User.id == UserAddress.user_id, UserAddress.user_addr_index == addr_idx)) \
                .filter(User.id == uid) \
                .one()

            address = crypto.decodeAES(row.UserAddress.address)
            geohash5 = row.UserAddress.geohash5
            geohash6 = row.UserAddress.geohash6

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

        ret = {}

        try:
            session = Session()

            result = session.query(Booking, User) \
                            .join(User, and_(Booking.user_id == User.id, and_(or_(Booking.cleaning_status == 1, Booking.cleaning_status == 2), or_(Booking.payment_status == 0, Booking.payment_status == -3)))) \
                            .filter(not_(User.email.like('*****@*****.**'))) \
                            .all()
            unpaid_datas = []
            Userdao = UserDAO()

            for record in result:
                key = Userdao.get_user_salt(record.User.email)[:16]
                if key == None or key == '':
                    continue

                crypto = aes.MyCrypto(key)

                unpaid_info = {}
                unpaid_info['booking_id'] = record.Booking.id
                unpaid_info[
                    'appointment_type'] = record.Booking.appointment_type
                unpaid_info['cleanning_date'] = dt.datetime.strftime(
                    record.Booking.start_time, '%Y-%m-%d %H:%M')
                unpaid_info['user_name'] = crypto.decodeAES(record.User.name)
                unpaid_info['user_phone'] = crypto.decodeAES(record.User.phone)
                unpaid_info['price_with_task'] = record.Booking.price_with_task
                unpaid_datas.append(unpaid_info)

            ret['response'] = unpaid_datas
            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 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 get_user_address_full_detail_by_index(self, uid, addr_idx):
        try:
            session = Session()

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

            row = session.query(User, UserAddress) \
                .join(UserAddress, and_(User.id == UserAddress.user_id, UserAddress.user_addr_index == addr_idx)) \
                .filter(User.id == uid) \
                .one()

            address = crypto.decodeAES(row.UserAddress.address)
            size = row.UserAddress.size
            kind = row.UserAddress.kind
            rooms = row.UserAddress.rooms
            baths = row.UserAddress.baths

        except NoResultFound, e:
            print_err_detail(e)
    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
Exemple #18
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'])
Exemple #19
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'])
    def get_all_user_addresses(self, uid):
        addresses = []
        try:
            session = Session()

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

            result = session.query(User, UserAddress) \
                .join(UserAddress, User.id == UserAddress.user_id) \
                .filter(User.id == uid) \
                .order_by(UserAddress.user_addr_index) \
                .all()

            for row in result:
                address = crypto.decodeAES(row.UserAddress.address)
                kind = row.UserAddress.kind
                size = row.UserAddress.size

                addresses.append((address, kind, size))

        except NoResultFound, 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'])
Exemple #22
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)
Exemple #23
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'])
Exemple #24
0
                         .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
    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")

        ret = {}

        name         = self.get_argument('name', '')
        gender       = self.get_argument('gender', 1)
        authsource   = self.get_argument('authsource', 'None')
        devicetype   = self.get_argument('devicetype', 'None')
        email        = self.get_argument('email', '')
        password     = self.get_argument('password', '')
        salt         = self.get_argument('salt', '')
        phone        = self.get_argument('phone', '')
        birthdate    = self.get_argument('birthdate', '')
        registerdate = self.get_argument('regdate', '')

        if gender == '':
            gender = 1

        gender = int(gender)

        err_msg = ''

        if name == '':
            err_msg = 'name is invalid'
        elif email == '':
            err_msg = 'email is invalid'
        elif password == '':
            err_msg = 'password is invalid'

        if err_msg != '': # invalid argument situation
            ret['response'] = err_msg
            self.set_status(Response.RESULT_BADREQUEST)
            add_err_message_to_response(ret, err_dict['invalid_param'])
            return

        mongo_logger = get_mongo_logger()
        mix = get_mixpanel()

        try:
            session = Session()

            guid = str(uuid.uuid4())
            registerdate_str = registerdate
            #registerdate = dt.datetime.strptime(registerdate, '%Y-%m-%d').date()
            registerdate = dt.datetime.now()

            count = session.query(User).filter(User.email == email, User.active == 1).count()
            if count > 0:
                session.close()

                self.set_status(Response.RESULT_OK)
                add_err_message_to_response(ret, err_dict['err_dup_email'])
                mongo_logger.debug('%s is already existed' % email, extra = {'err' : 'duplicate email'})
                return

            # phone duplicacy check
            count = session.query(User) \
                            .filter(func.aes_decrypt(func.from_base64(User.phone), \
                            func.substr(User.salt, 1, 16)) == phone,  \
                            User.active == 1) \
                            .count()
            if count > 0:
                session.close()

                self.set_status(Response.RESULT_OK)
                add_err_message_to_response(ret, err_dict['err_dup_phone'])
                mongo_logger.debug('phone already existed', extra = {'err' : 'duplicate phone'})
                return

            key = salt[:16]

            print key

            crypto = aes.MyCrypto(key)

            encrypted_name = crypto.encodeAES(str(name))
            encrypted_phone = crypto.encodeAES(str(phone))
            encrypted_birthdate = crypto.encodeAES(str(birthdate))

            print encrypted_name, name
            print encrypted_phone, phone
            print encrypted_birthdate, birthdate


            new_user = User(id = guid, name = encrypted_name, gender = gender, authsource = authsource,
                    devicetype = devicetype, email = email, password = password, salt = salt,
                    phone = encrypted_phone, dateofbirth = encrypted_birthdate,
                    dateofreg = registerdate, dateoflastlogin= registerdate)
            session.add(new_user)
            session.commit()

            now = dt.datetime.now()
            expire_date = dt.datetime(2016, 12, 31, 23, 59)

            if now <= expire_date:
                user_id = guid
                discount_price = 10000
                title           = '크리스마스는 깨끗한 집에서!'
                description     = '1만원 할인쿠폰'

                hashids = Hashids(min_length = 8, salt = user_id)
                coupon_id = hashids.encode(int(dt.datetime.strftime(now, '%Y%m%d%H%M%S')))

                user_coupon = UserCoupon(id = coupon_id, user_id = user_id, discount_price = discount_price,
                                     expire_date = expire_date, title = title, description = description,
                                     issue_date = now)

                session.add(user_coupon)
                session.commit()

                sender = SMS_Sender()

                if devicetype == 'ios':
                    # send lms
                    row = session.query(Promotion) \
                                .filter(Promotion.discount_price == 10000) \
                                .filter(Promotion.used == 0) \
                                .first()
                    code = row.promotion_code
                    row.used = 2
                    session.commit()

                    sender.send2(mtype = 'lms', to = phone, subject = '홈마스터 12월 회원가입 이벤트!',
                                text = '홈마스터 앱에서 클리닝 예약 시, 아래 코드를 입력 해주세요 (10,000원 할인코드): \n' + code)
                elif devicetype == 'android':
                    sender.send2(mtype = 'lms', to = phone, subject = '홈마스터 12월 회원가입 이벤트!',
                                text = '홈마스터 10,000 할인 쿠폰이 도착했습니다. 앱의 쿠폰함에서 확인해주세요~')

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

            print email, 'has successfully registered..!!'

            print dt.datetime.now()
            mix.track(guid, 'register', {'time' : dt.datetime.now()})
            mix.people_set(guid, {'$name' : name, '$email' : email, '$gender' : gender,
                                  '$authsource' : authsource, '$phone' : phone, '$devicetype' : devicetype,
                                  '$brithdate' : birthdate, '$registerdate' : registerdate_str,
                                  '$time' : dt.datetime.now()},
                                  {'$ip' : '121.134.224.40'})
            mongo_logger.debug('register', extra = {'log_time' : dt.datetime.now(), 'user_id': guid, 'user_name' : name, 'gender' : gender, 'authsource' : authsource, 'devicetype' : devicetype, 'email' : email, 'phone' : phone})


        except Exception, e:
            session.rollback()
            add_err_message_to_response(ret, err_dict['err_mysql'])
            self.set_status(Response.RESULT_SERVERERROR)
            print_err_detail(e)
            mongo_logger.error('failed to register', extra = {'log_time' : dt.datetime.now(), 'user_name' : name, 'gender' : gender, 'authsource' : authsource, 'devicetype' : devicetype, 'email' : email, 'phone' : phone, 'err' : str(e)})
    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)})
class ModifyAddressBookingHandler(tornado.web.RequestHandler):
    def post(self):
        ret = {}

        user_id = self.get_argument('user_id', '')
        index   = self.get_argument('index', '')
        address = self.get_argument('address', '')
        size    = self.get_argument('size', 0)
        kind    = self.get_argument('kind', 1)

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

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

        mongo_logger = get_mongo_logger()
        mix = get_mixpanel()

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

            try:
                row = session.query(UserAddress) \
                            .filter(and_(UserAddress.user_id == user_id, UserAddress.user_addr_index == index)) \
                            .one()
            except NoResultFound, e:
                session.close()
                self.set_status(Response.RESULT_OK)
                add_err_message_to_response(ret, err_dict['err_no_record'])
                mongo_logger.error('failed to find address, no record', extra = {'err' : str(e)})
                return

            except MultipleResultsFound, e:
                session.close()
                self.set_status(Response.RESULT_OK)
                add_err_message_to_response(ret, err_dict['err_multiple_record'])
                mongo_logger.error('failed to find address, multiple record', extra = {'err' : str(e)})
                return

            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(user_id)[:16]
            crypto = aes.MyCrypto(key)

            encrypted_address = crypto.encodeAES(str(address))

            row.address = encrypted_address
            row.size = size
            row.kind = kind
            row.latitude = latitude
            row.longitude = longitude
            row.geohash5 = geohash5
            row.geohash6 = geohash6

            # modify booking info time and price
            now = dt.datetime.now().date()

            result = session.query(Booking) \
                            .filter(Booking.user_id == user_id) \
                            .filter(Booking.addr_idx == index) \
                            .filter(Booking.start_time >= now) \
                            .all()

            i = 0
            for row in result:
                if i == 0:
                    appointment_type = row.appointment_type
                    _, time, price, first_time = get_time_price(appointment_type, kind, size)

                new_duration = time
                org_duration = row.cleaning_duration

                new_price = price
                org_price = row.price

                # fix time
                row.estimated_end_time += dt.timedelta(minutes = (new_duration - org_duration))
                row.end_time = row.estimated_end_time

                # fix price
                row.price_with_task += (new_price - org_price)
                row.price = new_price

                row.cleaning_duration = new_duration

                i += 1

            session.commit()

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

            print user_id, 'modify address successfully!'
            mix.track(user_id, 'modify address', {'time' : dt.datetime.now()})
            mongo_logger.debug('%s modify address' % user_id, extra = {'user_id' : user_id, 'address' : address, 'size' : size, 'kind' : kind})
    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)
    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})