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

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

        print 'master_id : ' + master_id

        ret = {}

        try:
            session = Session()
            master_notices = []

            try:
                result = session.query(Master) \
                                .filter(Master.id == master_id) \
                                .filter(Master.active == 1) \
                                .one()

            except NoResultFound, e:
                session.close()
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(ret, '등록되지 않은 마스터 입니다.')
                return

            except MultipleResultsFound, e:
                session.close()
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(ret, '마스터가 중복 되어 있습니다.')
                return
コード例 #2
0
    def post(self):
        self.set_header("Content-Type", "application/json")
        self.set_header('Access-Control-Allow-Origin', '*')

        user_id = self.get_argument('id', '')
        tid = self.get_argument('tid', '')
        amount = self.get_argument('amount', 0)
        partial = self.get_argument('partial', 1)
        cancel_msg = self.get_argument('cancel_msg', '')

        amount = int(amount)

        if cancel_msg == '':
            cancel_msg = '취소'

        ret = {}

        try:
            mongo_logger = get_mongo_logger()
            mix = get_mixpanel()

            userdao = UserDAO()

            request_url = '%s:%d/homemaster_payment/cancel_payment' % (
                PAYMENT_HOST, PAYMENT_PORT)
            params = {}
            params['id'] = user_id
            params['tid'] = tid
            params['amount'] = amount
            params['partial'] = partial
            params['cancel_msg'] = cancel_msg

            response = requests.post(request_url, data=params)
            result = json.loads(response.text)

            if response.status_code == 200 and result['response'] != "":
                mix.track(user_id, 'cancel payment',
                          {'time': dt.datetime.now()})
                mongo_logger.debug('cancel payment',
                                   extra={'user_id': user_id})

                ret['response'] = result['response']
                self.set_status(Response.RESULT_OK)
            else:
                print 'An error occurred while register card'
                print result['err_msg']
                add_err_ko_message_to_response(ret, result['err_msg'])
                mix.track(user_id, 'cannot cancel payment',
                          {'time': dt.datetime.now()})
                mongo_logger.error('failed to cancel payment',
                                   extra={'user_id': user_id})
        except Exception, e:
            print_err_detail(e)
            self.set_status(Response.RESULT_SERVERERROR)
            add_err_message_to_response(ret, err_dict['err_mysql'])
コード例 #3
0
    def post(self):
            self.set_header("Content-Type", "application/json")
            self.set_header('Access-Control-Allow-Origin', '*')

            ret = {}

            UNUSED      = 0
            USED        = 1
            OCCUPIED    = 2

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

            try:
                session = Session()

                if promotion_code in PROMOTION_CODES: # 특별 할인 코드
                    discount_price = 0
                    now = dt.datetime.now()

                    print promotion_code, now

                    event_row = session.query(EventPromotion).filter(EventPromotion.code == promotion_code).one()

                    if event_row.count <= 0:
                        self.set_status(Response.RESULT_OK)
                        add_err_ko_message_to_response(ret, '이벤트 할인코드가 전부 사용되었습니다.')
                        return
                    if now >= event_row.expires:
                        self.set_status(Response.RESULT_OK)
                        add_err_ko_message_to_response(ret, '이벤트 할인코드 사용기간이 만료되었습니다.')
                        return
                    else:
                        discount_price = event_row.amount
                        event_row.count -= 1

                    session.commit()
                    ret['response'] = {'discount_price' : discount_price}
                    return

                try:
                    row = session.query(Promotion).filter(Promotion.promotion_code == promotion_code).one()
                except NoResultFound, e:
                    session.close()
                    self.set_status(Response.RESULT_OK)
                    add_err_message_to_response(ret, err_dict['err_no_used_promotion'])
                    return

                except MultipleResultsFound, e:
                    session.close()
                    self.set_status(Response.RESULT_OK)
                    add_err_message_to_response(ret, err_dict['err_multiple_record'])
                    return
    def post(self):
        self.set_header("Content-Type", "application/json")
        self.set_header('Access-Control-Allow-Origin', '*')

        master_id = self.get_argument('master_id', '')
        off_date = self.get_argument('off_date', '')  # 20160603

        master_date_key = '{0}_{1}'.format(master_id, off_date)

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

        ret = {}

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

            # add request logs
            # type : 1 - request, 0 - cancel
            day_off_request = MasterDayoffRequest(
                master_id=master_id,
                date=off_date,
                type=0,
                request_time=dt.datetime.now())
            session.add(day_off_request)

            # master schedules by date active -> 0
            row = session.query(MasterScheduleByDate) \
                    .filter(MasterScheduleByDate.master_id == master_id) \
                    .filter(MasterScheduleByDate.date == off_date) \
                    .one()

            row.active = 1

            # commit
            session.commit()

            master_name = masterdao.get_master_name(master_id)
            send_jandi('HOMEMASTER_REST', "휴무 신청 취소",
                       master_name + ' 홈마스터님 휴무 신청 취소',
                       '휴무 취소 날짜 : {}'.format(off_date))

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

            print 'master_id', master_id, 'cancel dayoff request', off_date

        except NoResultFound, e:
            self.set_status(Response.RESULT_OK)
            add_err_ko_message_to_response(ret, '휴무 신청 취소 가능 날짜가 아닙니다.')
            return
コード例 #5
0
    def post(self):
        ret = {}

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

        index = int(index)

        print user_id, index

        self.set_header("Content-Type", "application/json")

        mongo_logger = get_mongo_logger()
        mix = get_mixpanel()

        try:
            session = Session()

            try:
                default_index = session.query(UserDefaultAddress) \
                    .filter(UserDefaultAddress.user_id == user_id) \
                    .one()

                # 기본 주소이면 삭제 안되도록 함
                if default_index.address_idx == index:
                    print 'default index'
                    session.close()
                    self.set_status(Response.RESULT_OK)
                    add_err_ko_message_to_response(ret, '기본 주소는 삭제 하실 수 없습니다.')
                    return

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

            except MultipleResultsFound, e:
                session.close()
                self.set_status(Response.RESULT_OK)
                add_err_message_to_response(ret,
                                            err_dict['err_multiple_record'])
                print_err_detail(e)
                return
コード例 #6
0
    def post(self):
        self.set_header("Content-Type", "application/json")

        uid     = self.get_argument('uid', '')
        price   = self.get_argument('price', '')

        ret = {}

        try:
            mongo_logger = get_mongo_logger()
            mix = get_mixpanel()

            userdao = UserDAO()

            request_url = '%s:%d/homemaster_payment/request_payment' % (PAYMENT_HOST, PAYMENT_PORT)

            params = {}
            params['id']            = uid
            params['name']          = userdao.get_user_name(uid)
            params['price']         = price
            params['product_name']  = 'moving'
            

            response = requests.post(request_url, data = params)
            result = json.loads(response.text)

            if response.status_code == 200 and result['response'] == "SUCCESS":
                mix.track(uid, 'request mc payment', {'time' : dt.datetime.now(), 'tid' : result['tid'], 'authdate' : result['authdate']})
                mongo_logger.debug('%s request mc payment' % uid, extra = {'user_id' : uid, 'tid' : result['tid'], 'authdate' : result['authdate']})
                
                ret['response'] = result['response']
                self.set_status(Response.RESULT_OK)
            else:
                print 'An error occurred when paying moving clean'
                print result['err_code'], result['err_msg']
                add_err_ko_message_to_response(ret, result['err_msg'])

                mix.track(uid, 'cannot request mc payment', {'time' : dt.datetime.now(), 'code' : result['err_code']})
                mongo_logger.error('%s failed to request mc payment' % uid, extra = {'err' : result['err_msg']})
        except Exception, e:
            print_err_detail(e)
            self.set_status(Response.RESULT_SERVERERROR)
            add_err_message_to_response(ret, err_dict['err_mysql'])
    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 post(self):
        self.set_header("Content-Type", "application/json")

        ret = {}

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

        try:
            session = Session()

            if not bank_name in bank_dict.keys():
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(
                    ret, bank_name + '은(는) 지원하지 않는 은행입니다.')
                return

            bank_dict = BC.bank_dict

            account_no = account_no.replace('-', '')

            account = MasterAccount(master_id=master_id,
                                    account_no=account_no,
                                    bank_code=bank_dict[bank_name],
                                    bank_name=bank_name,
                                    datetime=dt.datetime.now())

            session.add(account)
            session.commit()

            print master_id, ' has successfully add account!'

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

        except NoResultFound, e:
            session.close()
            self.set_status(Response.RESULT_OK)
            add_err_message_to_response(ret, err_dict['err_no_record'])
            return
コード例 #9
0
    def get(self):
        self.set_header("Content-Type", "application/json")
        self.set_header('Access-Control-Allow-Origin', '*')

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

        ret = {}

        print uid
        print PAYMENT_HOST, PAYMENT_PORT

        try:
            mongo_logger = get_mongo_logger()
            mix = get_mixpanel()

            userdao = UserDAO()

            request_url = '%s:%d/homemaster_payment/get_cards' % (PAYMENT_HOST,
                                                                  PAYMENT_PORT)
            params = {}
            params['id'] = uid

            response = requests.get(request_url, params=params)
            print response
            result = json.loads(response.text)

            print result

            if response.status_code == 200 and result['response'] != "":
                ret['response'] = result['response']
                self.set_status(Response.RESULT_OK)
            else:
                print 'An error occurred while get card info'
                add_err_ko_message_to_response(ret, '카드정보 읽기 실패')
        except Exception, e:
            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)
コード例 #11
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', '')
        booking_id           = self.get_argument('booking_id', '')
        coupon_id            = self.get_argument('coupon_id', '')

        mongo_logger = get_mongo_logger()
        now = dt.datetime.now()

        try:
            session = Session()

            count = session.query(UserCoupon) \
                           .filter(UserCoupon.booking_id == booking_id) \
                           .count()

            if count > 0:
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(ret, '이미 쿠폰이 적용된 예약 입니다.')
                return


            row = session.query(UserCoupon) \
                         .filter(UserCoupon.user_id == user_id) \
                         .filter(UserCoupon.id == coupon_id) \
                         .one()

            if row.expire_date <= now:
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(ret, '사용 기한이 만료된 쿠폰 입니다.')
                return

            if row.used != 0:
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(ret, '이미 사용한 쿠폰 입니다.')
                return

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

            mongo_logger.debug('apply user coupon', extra = {'user_id' : user_id, 'booking_id' : booking_id })

        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 apply user coupon', extra = {'user_id' : user_id, 'booking_id' : booking_id, 'err' : str(e)})
コード例 #12
0
class ChargeHandler(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':
                ret_code = False
                add_err_ko_message_to_response(ret, '카드 등록 고객 아님')
                return

            else:
                ret_code, value = request_payment(user_id, user_name,
                                                  booking_id, price,
                                                  appointment_type)

            if ret_code == True:
                row.Booking.tid = value
                row.Booking.status = BC.BOOKING_PAID
                row.Booking.payment_status = BC.BOOKING_PAID
                session.commit()

                ret['response'] = Response.SUCCESS
            else:
                add_err_ko_message_to_response(ret, value)

            self.set_status(Response.RESULT_OK)
    def post(self):
        self.set_header("Content-Type", "application/json")

        ret = {}

        booking_id = self.get_argument('booking_id', '')
        additional_task = self.get_argument('additional_task', '')
        new_price = self.get_argument('new_price', 0)
        total_taking_time = self.get_argument('total_taking_time', '')
        laundry_apply_all = self.get_argument(
            'laundry_apply_all',
            0)  # -2 - 전체없앰 -1 - 하나 없앰, 0 - one time, 1 - all time

        # convert parameter
        new_price = int(new_price)
        additional_task = int(additional_task)
        total_taking_time = int(total_taking_time)
        total_taking_time_in_minutes = total_taking_time * 6
        laundry_apply_all = int(laundry_apply_all)

        print 'update additional task params'
        print booking_id
        print additional_task
        print new_price
        print total_taking_time
        print laundry_apply_all

        mix = get_mixpanel()
        mongo_logger = get_mongo_logger()

        try:
            print 'total_minutes :', total_taking_time_in_minutes
            if total_taking_time_in_minutes >= 720:
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(
                    ret,
                    '클리닝 가능 시간을 초과하였습니다. (최대 12시간) 이전 화면으로 돌아가 추가사항을 2개이하로 줄여주세요.'
                )
                return

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

            holder = IntermediateValueHolder()

            row = session.query(Booking).filter(Booking.id == booking_id).one()

            uid = row.user_id
            start_time = row.start_time
            end_time = row.estimated_end_time
            request_id = row.request_id
            appointment_index = row.appointment_index
            appointment_type = row.appointment_type
            payment_status = row.payment_status
            price_with_task = row.price_with_task

            isdirty = row.is_dirty
            if isdirty == 1:
                total_taking_time_in_minutes += 120

            org_taking_time_in_minutes = time_to_minutes(
                timedelta_to_time(end_time - start_time))

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

            is_event = True if is_event != None else False

            user_name = userdao.get_user_name(uid)

            # 추가 업무로 인해 소요된 시간이 더 크다면 앞 뒤 일정을 고려.
            # 고려해서 이동이 가능하다면 추가 업무 할당함.
            if total_taking_time_in_minutes > org_taking_time_in_minutes:
                print '2'
                master_id, time = masterdao.get_masterid_and_starttime_from_booking(
                    booking_id)
                search_key = '%s_%d' % (master_id, time)
                new_estimated_end_time = masterdao.is_schedule_extend_available(
                    booking_id, total_taking_time_in_minutes)

                if new_estimated_end_time != None and holder.store(
                        search_key, 1):  # 변경이 가능함.
                    if payment_status == BC.BOOKING_PAID:  # 미리 지불한 경우는 취소 하고 다시 결제함
                        # 전거래 취소 및 재결제
                        if not (is_event and appointment_index == 1):
                            print 'in this case'
                            cancel_ret_code, msg = cancel_payment(
                                uid, booking_id, price_with_task, partial='0')
                            if cancel_ret_code:

                                pay_ret_code, pay_msg = request_payment(
                                    uid,
                                    user_name,
                                    booking_id,
                                    new_price,
                                    appointment_type,
                                    status='UPDATED')
                                if pay_ret_code:
                                    row.tid = pay_msg
                                    row.payment_status = BC.BOOKING_PAID
                                else:
                                    row.payment_status = BC.BOOKING_PAYMENT_FAILED
                                    session.commit()
                                    session.close()
                                    self.set_status(Response.RESULT_OK)
                                    add_err_ko_message_to_response(
                                        ret, pay_msg)
                                    return
                        else:  # 정기 1회 이벤트 일 때
                            print 'hahaha'
                            charge_amount = new_price - row.price
                            print charge_amount

                            if row.price_with_task != row.price:  # 다르면
                                charge_amount = new_price - row.price_with_task

                            pay_ret_code, pay_msg = request_payment(
                                uid,
                                user_name,
                                booking_id,
                                charge_amount,
                                appointment_type,
                                status='UPDATED')
                            if pay_ret_code:
                                row.tid = pay_msg
                                row.payment_status = BC.BOOKING_PAID
                            else:
                                row.payment_status = BC.BOOKING_PAYMENT_FAILED
                                session.commit()
                                session.close()
                                self.set_status(Response.RESULT_OK)
                                add_err_ko_message_to_response(ret, pay_msg)
                                return

                    row.estimated_end_time = new_estimated_end_time
                    row.additional_task = additional_task
                    row.price_with_task = new_price
                    row.laundry_apply_all = laundry_apply_all

                    session.commit()
                    holder.remove(search_key)

                else:
                    print '3'
                    session.close()
                    self.set_status(Response.RESULT_OK)
                    add_err_message_to_response(
                        ret, err_dict['err_hm_have_next_schedule'])

                    # 메모리에서 삭제
                    holder.remove(search_key)
                    return

            else:  # 같거나 작은 경우는 바로 변경
                print '4'
                if payment_status == BC.BOOKING_PAID:  # 미리 지불한 경우는 취소 하고 다시 결제함
                    # 전거래 취소 및 재결제
                    if not (is_event and appointment_index == 1):
                        cancel_ret_code, msg = cancel_payment(uid,
                                                              booking_id,
                                                              price_with_task,
                                                              partial='0')
                        if cancel_ret_code:
                            user_name = userdao.get_user_name(uid)
                            pay_ret_code, pay_msg = request_payment(
                                uid,
                                user_name,
                                booking_id,
                                new_price,
                                appointment_type,
                                status='UPDATED')
                            if pay_ret_code:
                                row.tid = pay_msg
                                row.payment_status = BC.BOOKING_PAID
                            else:
                                row.payment_status = BC.BOOKING_PAYMENT_FAILED
                                session.commit()
                                session.close()
                                self.set_status(Response.RESULT_OK)
                                add_err_ko_message_to_response(ret, pay_msg)
                                return
                    else:
                        if row.price_with_task != row.price:  # 다르면
                            charge_amount = row.price_with_task - new_price
                            cancel_payment(uid,
                                           booking_id,
                                           charge_amount,
                                           partial='0')

                row.additional_task = additional_task
                row.estimated_end_time = end_time + dt.timedelta(
                    minutes=total_taking_time_in_minutes -
                    org_taking_time_in_minutes)
                row.price_with_task = new_price
                row.laundry_apply_all = laundry_apply_all

            # 빨래의 경우는 시간 변경이 없으므로 마지막에 바로 적용
            # about laundry

            print '5'
            all_upcoming_bookings = session.query(Booking) \
                    .filter(Booking.request_id == request_id) \
                    .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \
                    .filter(Booking.appointment_index >= appointment_index) \
                    .all()

            if laundry_apply_all == 1:  # 전체 선택
                for booking in all_upcoming_bookings:
                    bits = "{0:07b}".format(booking.additional_task)
                    if bits[4] == '0':  # 빨래가 세팅되어 있다면
                        booking.additional_task += 4  # 빨래
                    booking.laundry_apply_all = laundry_apply_all

            elif laundry_apply_all == -2:  # 선택 해제
                for booking in all_upcoming_bookings:
                    bits = "{0:07b}".format(booking.additional_task)
                    if bits[4] == '1':  # 빨래가 세팅되어 있다면
                        booking.additional_task -= 4  # 빨래 제거
                    booking.laundry_apply_all = laundry_apply_all

            print '6'

            session.commit()

            # alim talk
            user_name = userdao.get_user_name(uid)
            additional_task_str = additional_task_string(additional_task)

            #for manager_phone in MANAGERS_CALL.split(','):
            #    send_alimtalk(manager_phone, 'noti_manager_modify_task', user_name, additional_task_str)

            # log to mixpanel
            mix.track(
                uid, 'update additional task', {
                    'time': dt.datetime.now(),
                    'booking_id': booking_id,
                    'additional_task': additional_task,
                    'new_price': new_price,
                    'total_taking_time': total_taking_time,
                    'laundry_apply_all': laundry_apply_all
                })

            # log to mongo
            mongo_logger.debug('update additional task',
                               extra={
                                   'user_id': uid,
                                   'booking_id': booking_id,
                                   'additional_task': additional_task,
                                   'new_price': new_price,
                                   'total_taking_time': total_taking_time,
                                   'laundry_apply_all': laundry_apply_all
                               })

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

        except NoResultFound, e:
            print_err_detail(e)
            session.close()
            self.set_status(Response.RESULT_OK)
            add_err_message_to_response(ret, err_dict['err_no_record'])
            return
コード例 #14
0
            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)
            else:
                ret_code, value = request_payment(user_id, user_name,
                                                  booking_id, price,
                                                  appointment_type, 'CHARGED')

            if ret_code == True:
                ret['response'] = Response.SUCCESS
            else:
                add_err_ko_message_to_response(ret, value)

            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'])
        finally:
            session.close()
            self.write(json.dumps(ret))
コード例 #15
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)
コード例 #16
0
    def get(self):

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

        ret = {}

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

        mongo_logger = get_mongo_logger()
        now = dt.datetime.now()

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

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

            except NoResultFound, e:
                session.close()
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(ret, '등록되지 않은 고객 입니다.')
                return

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

            name = crypto.decodeAES(result.name)

            user_coupons = {}
            user_coupons['user_name'] = name

            results = session.query(UserCoupon) \
                             .filter(UserCoupon.user_id == user_id) \
                             .order_by(UserCoupon.expire_date) \
                             .all()

            print "request user coupon sql query for adminweb"

            coupons = []
            for result in results:
                user_coupon = {}
                user_coupon['issue_date'] = dt.datetime.strftime(
                    result.issue_date, '%Y.%m.%d')
                user_coupon['expire_date'] = dt.datetime.strftime(
                    result.expire_date, '%Y.%m.%d')
                user_coupon['discount_price'] = result.discount_price
                user_coupon['used'] = 1 if result.used == 1 else 0
                user_coupon['is_expired'] = 1 if result.expire_date.date(
                ) <= now.date() else 0
                user_coupon['title'] = result.title
                user_coupon[
                    'booking_id'] = '' if result.booking_id == None else result.booking_id

                coupons.append(user_coupon)

            user_coupons['coupons'] = coupons

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

            mongo_logger.debug('request user coupon for adminweb',
                               extra={'user_id': user_id})
コード例 #17
0
    def post(self):
        self.set_header("Content-Type", "application/json")
        self.set_header('Access-Control-Allow-Origin', '*')

        ret = {}

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

        amount = int(amount)

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

            count = session.query(Promotion) \
                        .filter(Promotion.booking_id == booking_id) \
                        .count()

            if count > 0:
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(ret, '이미 할인이 적용된 예약입니다.')
                return

            row = session.query(Promotion) \
                        .filter(Promotion.used == 0) \
                        .filter(Promotion.discount_price == amount) \
                        .filter(Promotion.source == 'hm') \
                        .first()

            booking_row = session.query(Booking) \
                                .filter(Booking.id == booking_id) \
                                .one()

            if row == None:
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(ret, '해당 쿠폰이 존재하지 않습니다.')
                return

            if booking_row.payment_status != 0:
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(
                    ret, '결제되지 않은 예약에 대해서만 할인 적용이 가능합니다.')
                return

            if booking_row.cleaning_status != 0:
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(ret, '다가오는 클리닝만 할일 적용이 가능합니다.')
                return

            row.booking_id = booking_id
            row.used = 1
            row.service_price = booking_row.price_with_task
            row.used_datetime = dt.datetime.now()

            if amount <= 100:
                discount_price = int(booking_row.price_with_task *
                                     float(amount) / 100)
                booking_row.price_with_task -= discount_price

            else:
                booking_row.price_with_task -= amount

            session.commit()

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

        except Exception, e:
            session.rollback()
            add_err_message_to_response(ret, err_dict['err_mysql'])
            self.set_status(Response.RESULT_SERVERERROR)
            print_err_detail(e)
コード例 #18
0
class EditBookingHandler(tornado.web.RequestHandler):
    def post(self):
        self.set_header("Content-Type", "application/json")

        booking_id = self.get_argument('booking_id', '')
        changed = self.get_argument('ischange', '')
        date = self.get_argument('date', dt.datetime.now())
        start_time_range_begin = self.get_argument('range_begin',
                                                   BC.START_TIME_RANGE_BEGIN)
        start_time_range_begin_min = self.get_argument('range_begin_min', 0)
        start_time_range_end = self.get_argument('range_end',
                                                 BC.START_TIME_RANGE_END)
        start_time_range_end_min = self.get_argument('range_end_min', 0)
        price = self.get_argument('price', 0)
        taking_time = self.get_argument('taking_time', 25)
        additional_task = self.get_argument('additional_task', 0)
        message = self.get_argument('msg', '')
        laundry_apply_all = self.get_argument(
            'laundry_apply_all', 0)  # -1 - 없앰, 0 - one time, 1 - all time

        print 'edit booking params....'
        print booking_id, changed, date, additional_task, taking_time, price
        # convert datetime

        price = int(price)
        taking_time = int(taking_time)
        additional_task = int(additional_task)
        taking_time_in_minutes = taking_time * 6
        laundry_apply_all = int(laundry_apply_all)

        changed = "{0:03b}".format(int(changed))

        mongo_logger = get_mongo_logger()

        mongo_logger.debug('%s was called to updated' % booking_id,
                           extra={
                               'changed': changed,
                               'date': date,
                               'start_time_range_begin':
                               start_time_range_begin,
                               'start_time_range_end': start_time_range_end,
                               'price': price,
                               'taking_time': taking_time,
                               'additional_task': additional_task,
                               'user_message': message
                           })

        ret = {}

        mix = get_mixpanel()

        try:
            session = Session()

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

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

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

            uid = row.user_id
            price_with_task = row.price_with_task
            appointment_type = row.appointment_type
            org_master_id = row.master_id

            holder = IntermediateValueHolder()

            org_date = dt.datetime.strftime(row.start_time, '%m월%d일')

            time_changed = changed[2]
            task_changed = changed[1]
            msg_changed = changed[0]

            # booking can not be updated within 24 hours ahead
            appointment_time = row.start_time
            current_time = dt.datetime.now()
            diff_in_hours = (appointment_time -
                             current_time).total_seconds() / 3600

            if diff_in_hours < 24:  # 못바꾸도록 함
                time_changed = 0
                task_changed = 0

            havetools = 1
            if additional_task >= 64:
                havetools = 0

            # time이 변경되었다면 무조건 scheduling
            if time_changed == '1':
                date = dt.datetime.strptime(date, '%Y%m%d')
                start_time_range_begin = int(start_time_range_begin)
                start_time_range_begin_min = int(start_time_range_begin_min)
                start_time_range_end = int(start_time_range_end)
                start_time_range_end_min = int(start_time_range_end_min)

                appointment_type = 0  # 여기서는 1회 청소로 한다. 편집이기 때문에
                start_time = row.start_time
                end_time = row.estimated_end_time
                have_pet = row.havepet
                master_gender = row.master_gender
                price_with_task = row.price_with_task
                addr_idx = row.addr_idx

                org_taking_time_in_minutes = time_to_minutes(
                    timedelta_to_time(end_time - start_time))
                new_taking_time_in_minutes = org_taking_time_in_minutes + taking_time_in_minutes

                address, geohash5, geohash6 = userdao.get_user_address_by_index(
                    uid, addr_idx)
                gu_id = addrdao.get_gu_id(address)
                dates = [int(dt.datetime.strftime(date, '%Y%m%d'))]

                schedule_by_date_list = masterdao.get_master_schedule_by_dates(
                    gu_id, have_pet, master_gender, dates)
                success, msg, store_key, search_keys, result = masterdao.find_master_by_score(schedule_by_date_list, \
                                                    gu_id, \
                                                    uid, \
                                                    appointment_type, \
                                                    dates, \
                                                    start_time_range_begin, \
                                                    start_time_range_begin_min, \
                                                    start_time_range_end, \
                                                    start_time_range_end_min, \
                                                    new_taking_time_in_minutes, \
                                                    geohash6)

                # if not successful
                if success != 'SUCCESS':
                    session.close()
                    self.set_status(Response.RESULT_OK)
                    add_err_message_to_response(
                        ret, err_dict['err_no_hm_at_that_time'])
                    self.write(json.dumps(ret))
                    return

                else:  # find matching homemaster
                    item = result[0]

                    master_id = item['mid']
                    dow = dt.datetime.strptime(item['date'],
                                               '%Y%m%d').date().weekday()
                    start_time = dt.datetime.combine(
                        dt.datetime.strptime(item['date'], '%Y%m%d'),
                        item['start_time'])
                    estimated_end_time = dt.datetime.combine(
                        dt.datetime.strptime(item['date'], '%Y%m%d'),
                        item['end_time'])

                    status = row.payment_status
                    if status == BC.BOOKING_PAID:  # 미리 지불한 경우는 취소 하고 다시 결제함
                        # 전거래 취소 및 재결제
                        cancel_ret_code, msg = cancel_payment(uid,
                                                              booking_id,
                                                              price_with_task,
                                                              partial='0')
                        if cancel_ret_code:
                            user_name = userdao.get_user_name(uid)
                            pay_ret_code, pay_msg = request_payment(
                                uid,
                                user_name,
                                booking_id,
                                price,
                                appointment_type,
                                status='UPDATED')
                            if pay_ret_code:
                                row.tid = pay_msg
                                row.payment_status = BC.BOOKING_PAID
                            else:
                                row.payment_status = BC.BOOKING_PAYMENT_FAILED
                                session.commit()
                                session.close()
                                self.set_status(Response.RESULT_OK)
                                add_err_ko_message_to_response(ret, pay_msg)
                                self.write(json.dumps(ret))
                                return

                    row.master_id = master_id
                    row.dow = dow
                    row.price_with_task = price
                    row.start_time = start_time
                    row.message = message
                    row.additional_task = additional_task
                    row.havetools = havetools
                    row.estimated_end_time = estimated_end_time
                    row.laundry_apply_all = laundry_apply_all

                    if org_master_id != master_id:
                        row.is_master_changed = 1

                    # about laundry
                    request_id = row.request_id
                    appointment_index = row.appointment_index

                    all_bookings = session.query(Booking) \
                            .filter(Booking.request_id == request_id) \
                            .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \
                            .filter(Booking.appointment_index > appointment_index) \
                            .all()

                    if laundry_apply_all == 1:
                        for booking in all_bookings:
                            booking.additional_task += 4  # 빨래
                            booking.laundry_apply_all = laundry_apply_all
                    else:
                        for booking in all_bookings:
                            bits = "{0:07b}".format(booking.additional_task)
                            if bits[4] == '1':
                                booking.additional_task -= 4  # 빨래 제거
                            booking.laundry_apply_all = laundry_apply_all

                    session.commit()

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

            else:
                if task_changed == '1':
                    if taking_time_in_minutes > 0:  # 실제 시간이 늘어났을 경우에만 뒷 스케쥴 확인

                        master_id, start_date_int = masterdao.get_masterid_and_starttime_from_booking(
                            booking_id)
                        search_key = '%s_%d' % (master_id, start_date_int)

                        new_estimated_end_time = masterdao.is_master_available_next_schedule(
                            booking_id, taking_time_in_minutes)
                        print new_estimated_end_time, '&&&&'

                        if new_estimated_end_time != None and holder.store(
                                search_key, 1):  # 실제로 시간이 가능하면
                            status = row.payment_status
                            if status == BC.BOOKING_PAID:  # 미리 지불한 경우는 취소 하고 다시 결제함
                                # 전거래 취소 및 재결제
                                cancel_ret_code, msg = cancel_payment(
                                    uid,
                                    booking_id,
                                    price_with_task,
                                    partial='0')
                                if cancel_ret_code:
                                    user_name = userdao.get_user_name(uid)
                                    pay_ret_code, pay_msg = request_payment(
                                        uid,
                                        user_name,
                                        booking_id,
                                        price,
                                        appointment_type,
                                        status='UPDATED')
                                    if pay_ret_code:
                                        row.tid = pay_msg
                                        row.payment_status = BC.BOOKING_PAID
                                    else:
                                        row.payment_status = BC.BOOKING_PAYMENT_FAILED
                                        session.commit()
                                        session.close()
                                        self.set_status(Response.RESULT_OK)
                                        add_err_ko_message_to_response(
                                            ret, pay_msg)
                                        self.write(json.dumps(ret))
                                        return

                            row.estimated_end_time = new_estimated_end_time
                            row.additional_task = additional_task
                            row.message = message
                            row.price_with_task = price
                            row.havetools = havetools
                            row.laundry_apply_all = laundry_apply_all

                            # about laundry
                            request_id = row.request_id
                            appointment_index = row.appointment_index

                            all_bookings = session.query(Booking) \
                                    .filter(Booking.request_id == request_id) \
                                    .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \
                                    .filter(Booking.appointment_index > appointment_index) \
                                    .all()

                            if laundry_apply_all == 1:
                                for booking in all_bookings:
                                    booking.additional_task += 4  # 빨래
                                    booking.laundry_apply_all = laundry_apply_all
                            else:
                                for booking in all_bookings:
                                    bits = "{0:07b}".format(
                                        booking.additional_task)
                                    if bits[4] == '1':
                                        booking.additional_task -= 4  # 빨래 제거
                                    booking.laundry_apply_all = laundry_apply_all

                            session.commit()

                            # 메모리에서 삭제
                            holder.remove(search_key)

                        else:  # 스케쥴이 있어서 불가능 함
                            session.close()
                            self.set_status(Response.RESULT_OK)
                            add_err_message_to_response(
                                ret, err_dict['err_hm_have_next_schedule'])
                            self.write(json.dumps(ret))
                            return
                    else:  # 시간이 줄어들었거나, 그대로인경우에는 additional task 값만 바꾸면 됨
                        status = row.payment_status
                        if status == BC.BOOKING_PAID:  # 미리 지불한 경우는 취소 하고 다시 결제함
                            # 전거래 취소 및 재결제
                            cancel_ret_code, msg = cancel_payment(
                                uid, booking_id, price_with_task, partial='0')
                            if cancel_ret_code:
                                user_name = userdao.get_user_name(uid)
                                pay_ret_code, pay_msg = request_payment(
                                    uid,
                                    user_name,
                                    booking_id,
                                    price,
                                    appointment_type,
                                    status='UPDATED')
                                if pay_ret_code:
                                    row.tid = pay_msg
                                    row.payment_status = BC.BOOKING_PAID
                                else:
                                    row.payment_status = BC.BOOKING_PAYMENT_FAILED
                                    session.commit()
                                    session.close()
                                    self.set_status(Response.RESULT_OK)
                                    add_err_ko_message_to_response(
                                        ret, pay_msg)
                                    self.write(json.dumps(ret))
                                    return

                        print row.estimated_end_time, taking_time_in_minutes
                        row.estimated_end_time = row.estimated_end_time + dt.timedelta(
                            minutes=taking_time_in_minutes)
                        row.additional_task = additional_task
                        row.message = message
                        row.price_with_task = price
                        row.havetools = havetools
                        row.laundry_apply_all = laundry_apply_all

                        # about laundry
                        request_id = row.request_id
                        appointment_index = row.appointment_index

                        all_bookings = session.query(Booking) \
                                .filter(Booking.request_id == request_id) \
                                .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \
                                .filter(Booking.appointment_index > appointment_index) \
                                .all()

                        if laundry_apply_all == 1:
                            for booking in all_bookings:
                                booking.additional_task += 4  # 빨래
                                booking.laundry_apply_all = laundry_apply_all
                        else:
                            for booking in all_bookings:
                                bits = "{0:07b}".format(
                                    booking.additional_task)
                                if bits[4] == '1':
                                    booking.additional_task -= 4  # 빨래 제거
                                booking.laundry_apply_all = laundry_apply_all

                        session.commit()
                else:
                    row.message = message
                    session.commit()

            # 문자 전송
            #send_updated_text(booking_id, org_date)

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

            mix.track(
                uid, 'update', {
                    'time': dt.datetime.now(),
                    'booking_id': booking_id,
                    'additional_task': additional_task
                })
            mongo_logger.debug('%s was updated' % booking_id,
                               extra={
                                   'user_id': uid,
                                   'booking_id': booking_id
                               })
            print booking_id, 'successfully updated...'
コード例 #19
0
    def post(self):
        self.set_header("Content-Type", "application/json")
        self.set_header('Access-Control-Allow-Origin', '*')

        uid = self.get_argument('id', '')
        cno = self.get_argument('cno', '')
        expy = self.get_argument('expy', '')
        expm = self.get_argument('expm', '')
        ssnf = self.get_argument('ssnf', '')
        cpftd = self.get_argument('cpftd', '')
        calias = self.get_argument('calias', '')

        ret = {}

        print uid

        try:
            mongo_logger = get_mongo_logger()
            mix = get_mixpanel()

            userdao = UserDAO()

            request_url = '%s:%d/homemaster_payment/register_card' % (
                PAYMENT_HOST, PAYMENT_PORT)
            params = {}
            params['id'] = uid
            params['cno'] = cno
            params['expy'] = expy
            params['expm'] = expm
            params['ssnf'] = ssnf
            params['cpftd'] = cpftd
            params['calias'] = calias

            response = requests.post(request_url, data=params)
            result = json.loads(response.text)

            if response.status_code == 200 and result['response'] != "":
                mix.track(uid, 'register card', {
                    'time': dt.datetime.now(),
                    'calias': calias
                })
                mongo_logger.debug('register card',
                                   extra={
                                       'log_time': dt.datetime.now(),
                                       'user_id': uid
                                   })

                ret['response'] = result['response']
                self.set_status(Response.RESULT_OK)
            else:
                print 'An error occurred while register card'
                print result['err_code'], result['err_msg']
                add_err_ko_message_to_response(ret, result['err_msg'])

                mix.track(uid, 'cannot register card',
                          {'time': dt.datetime.now()})
                mongo_logger.error('failed to register card',
                                   extra={
                                       'log_time': dt.datetime.now(),
                                       'err': result['err_msg']
                                   })
        except Exception, e:
            print_err_detail(e)
            self.set_status(Response.RESULT_SERVERERROR)
            add_err_message_to_response(ret, err_dict['err_mysql'])
                        self.set_status(Response.RESULT_OK)
                        mongo_logger.debug('multiple first booking record', extra = {    'uid' : uid, 'mid' : mid, 'appointment_type' : appointment_type, 'have_pet' : have_pet, 'master_gender' : master_gender, 'isdirty' : isdirty})
                        add_err_message_to_response(ret, err_dict['err_multiple_record'])
                        return  

                    # notification to homemaster
                    booking_id = first_booking.Booking.id
                    master_pushkey  = first_booking.MasterPushKey.pushkey if first_booking.MasterPushKey != None else ''
                    cleaning_time   = convert_datetime_format2(first_booking.Booking.start_time)

                    send_new_booking_notification('android', [master_pushkey], booking_ids[0], cleaning_time)

                else: # 결제 에러인 경우
                    session.close()
                    self.set_status(Response.RESULT_OK)
                    add_err_ko_message_to_response(ret, msg)
                    mongo_logger.debug('request booking failed to charge', extra = {'user_id' : uid, 'master_id' : mid,
                                                                        'appointment_type' : appointment_type, 
                                                                        'have_pet' : have_pet, 'master_gender' : master_gender,
                                                                        'isdirty' : isdirty})
                    self.write(json.dumps(ret)) 
                    return 
                
            except Exception, e:
                session.rollback()
                add_err_message_to_response(ret, err_dict['err_mysql'])
                mongo_logger.debug('request booking failed', extra = {'user_id' : uid, 'master_id' : mid,
                                                                        'appointment_type' : appointment_type, 
                                                                        'have_pet' : have_pet, 'master_gender' : master_gender,
                                                                        'isdirty' : isdirty})
                self.set_status(Response.RESULT_SERVERERROR)
コード例 #21
0
class RemoveAddressHandler(tornado.web.RequestHandler):
    def post(self):
        ret = {}

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

        index = int(index)

        print user_id, index

        self.set_header("Content-Type", "application/json")

        mongo_logger = get_mongo_logger()
        mix = get_mixpanel()

        try:
            session = Session()

            try:
                default_index = session.query(UserDefaultAddress) \
                    .filter(UserDefaultAddress.user_id == user_id) \
                    .one()

                # 기본 주소이면 삭제 안되도록 함
                if default_index.address_idx == index:
                    print 'default index'
                    session.close()
                    self.set_status(Response.RESULT_OK)
                    add_err_ko_message_to_response(ret, '기본 주소는 삭제 하실 수 없습니다.')
                    return

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

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

            # 지난 예약 혹은 다가오는 예약에 해당 주소가 연결되어 있다면 삭제가 안되도록 함
            booking_index_count = session.query(Booking) \
                                        .filter(Booking.cleaning_status > BC.BOOKING_CANCELED) \
                                        .filter(Booking.user_id == user_id) \
                                        .filter(Booking.addr_idx == index) \
                                        .count()

            print booking_index_count

            if booking_index_count > 0:
                session.close()
                self.set_status(Response.RESULT_OK)
                print 'booking'
                add_err_ko_message_to_response(
                    ret, '완료된 예약과, 다가오는 예약의 주소는 삭제 하실 수 없습니다.')
                return

            session.query(UserAddress) \
                    .filter(UserAddress.user_id == user_id) \
                    .filter(UserAddress.user_addr_index == index) \
                    .delete()

            session.commit()

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

            print user_id, 'remove address', index, 'successfully!'

            mix.track(user_id, 'remove address', {
                'time': dt.datetime.now(),
                'index': index
            })
            mongo_logger.debug('remove address',
                               extra={
                                   'user_id': user_id,
                                   'index': index
                               })
コード例 #22
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 = self.get_argument('reason', '')
        print booking_id, reason

        ret = {}

        try:
            session = Session()

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

            now = dt.datetime.now().date() + dt.timedelta(days=2)

            row = session.query(Booking) \
                        .filter(Booking.id == booking_id) \
                        .filter(Booking.cleaning_status == 0) \
                        .filter(func.date(Booking.start_time) >= now) \
                        .one()

            master_id = row.master_id
            start_time = row.start_time

            request = MasterBookingModifyRequest(
                master_id=master_id,
                booking_id=booking_id,
                reason=reason,
                org_time=start_time,
                request_time=dt.datetime.now())
            session.add(request)
            session.commit()

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

            master_name = masterdao.get_master_name(row.Booking.master_id)
            user_name = userdao.get_user_name(row.Booking.user_id)
            district = addressdao.get_gu_name(
                userdao.get_user_address(row.Booking.user_id)[0])
            appointment_time = convert_datetime_format2(row.Booking.start_time)

            for manager_phone in MANAGERS_CALL.split(','):
                send_alimtalk(manager_phone, 'noti_manager_modify_schedule',
                              master_name, user_name, district,
                              appointment_time)

            send_jandi(
                'HOMEMASTER_REST', "휴무 신청", master_name + ' 홈마스터님 일정변경 신청',
                '고객 : {}\n지역 : {}\n일정 : {}'.format(user_name, district,
                                                   appointment_time))

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

            print 'booking_id', booking_id, 'was requested to modify'

        except NoResultFound, e:
            session.close()
            self.set_status(Response.RESULT_OK)
            add_err_ko_message_to_response(
                ret, '해당일은 일정 변경이 불가능 합니다. 일정 변경은 최소 이틀전에 가능합니다.')
            return
コード例 #23
0
    def post(self):
        self.set_header("Content-Type", "application/json")
        self.set_header('Access-Control-Allow-Origin', '*')

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

        ret = {}

        try:
            session = Session()

            users = []
            userdao = UserDAO()

            if search_term == None or search_term == '' or len(
                    search_term) == 1 or search_term == '010':
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(ret, '잘못된 파라미터 입니다.')
                return

            total_cnt = session.query(User).count()
            now = dt.datetime.now()

            query = session.query(User, UserAddress, UserMemo) \
                            .outerjoin(UserDefaultAddress, UserDefaultAddress.user_id == User.id) \
                            .outerjoin(UserAddress, and_(UserDefaultAddress.user_id == UserAddress.user_id, UserDefaultAddress.address_idx == UserAddress.user_addr_index)) \
                            .outerjoin(UserMemo, User.id == UserMemo.user_id)

            if search_term != '':
                print 'searching term : ' + search_term
                #search_term = search_term.lower()

                query = query.filter(
                    or_(
                        func.aes_decrypt(
                            func.from_base64(User.name),
                            func.substring(User.salt, 1,
                                           16)).like('%' + search_term + '%'),
                        func.aes_decrypt(func.from_base64(User.phone),
                                         func.substring(User.salt, 1,
                                                        16)).like(search_term +
                                                                  '%'),
                        User.email.like(search_term + '%'),
                        User.id == search_term))

            result = query.order_by(desc(User.dateofreg)).all()

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

                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['authsource'] = row.User.authsource
                user_info['phone'] = crypto.decodeAES(row.User.phone)
                user_info['gender'] = row.User.gender
                user_info['active'] = row.User.active
                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 ''
                user_info[
                    'memo'] = row.UserMemo.memo if row.UserMemo != None else ''
                user_info['is_b2b'] = row.User.is_b2b
                #user_info['all_addresses'] = userdao.get_all_user_addresses(row.User.id)

                users.append(user_info)

            ret['response'] = {'count': total_cnt, 'users': 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'])
コード例 #24
0
class RegisterCardAndChargeHandler(tornado.web.RequestHandler):
    def initialize(self, mongo):

        self.mongo = mongo
        booking = mongo.booking
        booking.authenticate(MONGO_USER, MONGO_PWD, source='booking')

        self.db = booking.customer

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

        cleaning_id = self.get_argument('cleaning_id', '')
        cno = self.get_argument('cno', '')
        expy = self.get_argument('expy', '')
        expm = self.get_argument('expm', '')
        ssnf = self.get_argument('ssnf', '')
        cpftd = self.get_argument('cpftd', '')
        calias = self.get_argument('calias', '')

        ret = {}

        try:
            mongo_logger = get_mongo_logger()
            mix = get_mixpanel()

            userdao = UserDAO()

            doc = self.db.find_one_and_update(
                {'cleaning_id': cleaning_id}, {'$set': {
                    'payment': '선결제'
                }},
                return_document=ReturnDocument.AFTER)
            if doc == None:
                self.set_status(Response.RESULT_OK)
                add_err_message_to_response(ret,
                                            err_dict['err_no_cleaning_id'])
                return

            print cno

            try:
                uid = doc['user_id']
            except Exception, e:
                self.set_status(Response.RESULT_OK)
                add_err_message_to_response(ret, err_dict['err_no_user_id'])
                return

            try:
                amount = int(doc['total_price'])
            except Exception, e:
                self.set_status(Response.RESULT_OK)
                add_err_message_to_response(ret,
                                            err_dict['err_invalid_amount'])
                return

            address = doc['address']
            period = doc['period']
            dates = ','.join(doc['dates'])
            start_date = doc['start_date']

            request_url = '%s:%d/homemaster_payment/register_card' % (
                PAYMENT_HOST, PAYMENT_PORT)
            params = {}
            params['id'] = uid
            params['cno'] = cno
            params['expy'] = expy
            params['expm'] = expm
            params['ssnf'] = ssnf
            params['cpftd'] = cpftd
            params['calias'] = calias

            response = requests.post(request_url, data=params)
            result = json.loads(response.text)

            if response.status_code == 200 and result['response'] != "":
                mix.track(uid, 'register card', {
                    'time': dt.datetime.now(),
                    'calias': calias
                })
                mongo_logger.debug('%s registered card' % uid,
                                   extra={'user_id': uid})

                user_name = userdao.get_user_name(uid)
                user_phone = userdao.get_user_phone(uid)

                import redis
                try:
                    from utils.secrets import REDIS_HOST, REDIS_PORT, REDIS_PWD
                except ImportError:
                    REDIS_HOST = 'localhost'
                    REDIS_PORT = 6379
                    REDIS_PWD = ''

                r = redis.Redis(host=REDIS_HOST,
                                port=REDIS_PORT,
                                password=REDIS_PWD)
                event_on = r.get('free_event')

                if period in ['매주여러번', '매주한번'] and event_on:
                    result = True
                    msg = ''
                else:
                    result, msg = request_payment_web(uid, user_name, amount)

                if result:
                    ret['response'] = Response.SUCCESS

                    # jandi notification
                    description = '{}({}) 고객님, 예약됨 {} {} - {}, {}'.format(
                        user_name, user_phone, period, address, start_date,
                        dates)

                    send_jandi('NEW_WEB', '[웹]신규예약', '선결제', description)
                else:
                    ret['response'] = ''
                    ret['err_msg'] = msg

                self.set_status(Response.RESULT_OK)

                mongo_logger.debug('request payment web',
                                   extra={
                                       'user_id': uid,
                                       'amount': amount
                                   })
            else:
                print 'An error occurred while register card'
                print result['err_code'], result['err_msg']
                add_err_ko_message_to_response(ret, result['err_msg'])

                mix.track(uid, 'cannot register card',
                          {'time': dt.datetime.now()})
                mongo_logger.error('%s failed to register card' % uid,
                                   extra={'err': result['err_msg']})
コード例 #25
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', '')
        direction = self.get_argument('direction', '')  # forward, #backward

        if direction == '':
            direction = 'forward'

        if not direction in ['forward', 'backward']:
            self.set_status(Response.RESULT_OK)
            add_err_message_to_response(ret, err_dict['invalid_param'])

            return

        ret = {}

        try:
            session = Session()
            row = session.query(Booking).filter(Booking.id == booking_id).one()

            if row.cleaning_status != BC.BOOKING_UPCOMMING:
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(ret, '다가오는 예약이 아니면 미룰 수 없습니다.')
                return

            master_id = row.master_id
            work_date = row.start_time.date()

            day_of_week = work_date.weekday()

            start_time = row.start_time
            end_time = row.estimated_end_time

            start_hour = start_time.time().hour
            start_minute = start_time.time().minute

            end_hour = end_time.time().hour
            end_minute = end_time.time().minute

            master_time = session.query(MasterTimeSlot) \
                    .filter(MasterTimeSlot.master_id == master_id) \
                    .filter(MasterTimeSlot.day_of_week == day_of_week) \
                    .one()

            master_start_time = master_time.start_time
            master_end_time = master_time.end_time

            if start_hour <= master_start_time.hour and start_minute == 0 and direction == 'backward':
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(
                    ret, '홈마스터님 근무 시작 시각은 ' + str(master_start_time.hour) +
                    ' 시 입니다.')
                return

            if end_hour >= master_end_time.hour and direction == 'forward':
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(
                    ret,
                    '홈마스터님 근무 종료 시각은 ' + str(master_end_time.hour) + ' 시 입니다.')
                return

            #겹치는 다른 일정이 없으면 미룬다.
            if direction == 'backward':
                minutes = -30
                count = session.query(Booking) \
                    .filter(Booking.master_id == master_id) \
                    .filter(func.date(Booking.start_time) == work_date) \
                    .filter(Booking.estimated_end_time < end_time) \
                    .filter(Booking.estimated_end_time >= start_time - dt.timedelta(minutes = 30)) \
                    .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \
                    .count()

            elif direction == 'forward':
                minutes = 30
                count = session.query(Booking) \
                    .filter(Booking.master_id == master_id) \
                    .filter(func.date(Booking.start_time) == work_date) \
                    .filter(Booking.start_time > start_time) \
                    .filter(Booking.start_time <= end_time + dt.timedelta(minutes = 30)) \
                    .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \
                    .count()

            print booking_id, master_id, work_date
            print direction, minutes, count

            if count != 0:
                self.set_status(Response.RESULT_OK)
                add_err_ko_message_to_response(
                    ret, '다른 예약과 겹쳐, 시간을 당기거나 미룰 수 없습니다.')
                return

            row.start_time += dt.timedelta(minutes=minutes)
            row.estimated_end_time += dt.timedelta(minutes=minutes)
            row.end_time = row.estimated_end_time

            session.commit()

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

        except NoResultFound, e:
            self.set_status(Response.RESULT_OK)
            add_err_message_to_response(ret, err_dict['err_no_record'])
            return
コード例 #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', '')
        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)
    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")
        self.set_header('Access-Control-Allow-Origin', '*')

        ret = {}

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

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

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

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

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


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

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

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


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

            scheduler = HMScheduler()

            userdao = UserDAO()
            addrdao = AddressDAO()


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

            gu_id = addrdao.get_gu_id(address)

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

            available_schedules = scheduler.get_available_slots(gu_id = gu_id, geohash = geohash6, appointment_type = appointment_type, taking_time = total_taking_time_in_minutes,
                                                                prefer_women = True if master_gender == 1 else False,
                                                                have_pet = True if have_pet == 1 else False,
                                                                isdirty = True if isdirty == 1 else False,
                                                                user_id = uid)


            now = dt.datetime.now()
            if now.hour >= 17: # 7시 이후 라면 -> 5시로 변경 2016.06.03
                if for_manager == '': # 사용자 앱에서는 내일 예약 불가능
                    tomorrow = now + dt.timedelta(days=1)
                    tomorrow = dt.datetime.strftime(tomorrow, '%Y%m%d')
                    if tomorrow in available_schedules:
                        del available_schedules[tomorrow]

            for day in available_schedules:
                print '[', day, ']'
                print available_schedules[day]['by_time']
            # log to mixpanel
            mix.track(uid, 'request available schedule', {'time' : dt.datetime.now(), 'taking_time' : taking_time, 'additional_time' : additional_time, 'appointment_type' : appointment_type, 'have_pet' : have_pet, 'master_gender' : master_gender,'isdirty' : isdirty})

            # log to mongo
            mongo_logger.debug('request available schedule', extra = {'log_time' : dt.datetime.now(),  'user_id' : uid, 'taking_time' : taking_time, 'additional_time' : additional_time, 'appointment_type' : appointment_type, 'have_pet' : have_pet, 'master_gender' : master_gender,'isdirty' : isdirty})

            if len(available_schedules) > 0: # 가능한 날짜가 있다면
                ret['response'] = {'schedule' : available_schedules, 'first_date' : available_schedules.keys()[0] }
            else:
                add_err_message_to_response(ret, err_dict['err_not_available'])

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

            self.set_status(Response.RESULT_OK)
        except Exception, e:
            add_err_message_to_response(ret, err_dict['err_mysql'])
            self.set_status(Response.RESULT_SERVERERROR)
            print_err_detail(e)
            mongo_logger.error('error request available schedules', extra = {'user_id' : uid, 'err' : str(e)})
コード例 #29
0
    def post(self):
        self.set_header("Content-Type", "application/json")

        ret = {}

        uid = self.get_argument('uid', '')
        date = self.get_argument('date', dt.datetime.now())
        start_time_range_begin = self.get_argument('range_begin',
                                                   BC.START_TIME_RANGE_BEGIN)
        start_time_range_begin_min = self.get_argument('range_begin_min', 0)
        start_time_range_end = self.get_argument('range_end',
                                                 BC.START_TIME_RANGE_END)
        start_time_range_end_min = self.get_argument('range_end_min', 0)
        appointment_type = self.get_argument('appointment_type', BC.ONE_TIME)
        taking_time = self.get_argument('taking_time', 25)
        first_added_time = self.get_argument('first_added_time', 0)
        additional_time = self.get_argument('additional_time', 10)
        have_pet = self.get_argument('have_pet', 0)
        master_gender = self.get_argument('master_gender', 0)
        isdirty = self.get_argument('isdirty', 0)

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

        start_time_range_begin = int(start_time_range_begin)
        start_time_range_begin_min = int(start_time_range_begin_min)

        start_time_range_end = int(start_time_range_end)
        start_time_range_end_min = int(start_time_range_end_min)

        appointment_type = int(appointment_type)
        taking_time = int(taking_time)
        first_added_time = int(first_added_time)
        additional_time = int(additional_time)

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

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

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

        mongo_logger = get_mongo_logger()

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

        mix = get_mixpanel()

        try:
            session = Session()

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

            holder = IntermediateValueHolder()

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

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

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

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

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

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

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

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

            #get available homemaster's time table day by day
            schedule_by_date_list = masterdao.get_master_schedule_by_dates(
                gu_id, have_pet, master_gender, dates)
            success, msg, store_key, search_keys, result = masterdao.find_master_by_score(schedule_by_date_list, \
                                                gu_id, \
                                                uid, \
                                                appointment_type, \
                                                dates, \
                                                start_time_range_begin, \
                                                start_time_range_begin_min, \
                                                start_time_range_end, \
                                                start_time_range_end_min, \
                                                total_taking_time_in_minutes, \
                                                geohash6)

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

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

                    schedules.append(s)

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

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

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

            self.set_status(Response.RESULT_OK)

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

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

        ret = {}

        uid = self.get_argument('uid', '')
        search_keys = self.get_argument('search_keys', '')
        store_key = self.get_argument('store_key', '')

        #price                   = self.get_argument('price', 0)
        #price_with_task         = self.get_argument('price_with_task', 0)
        #discounted_price        = self.get_argument('discounted_price', 0)
        promotion_code = self.get_argument('promotion_code', '')

        laundry_apply_all = self.get_argument(
            'laundry_apply_all', 0)  # -1 - 없앰, 0 - one time, 1 - all time

        has_card = self.get_argument('has_card', 0)
        # ---------- card paremeters ------------
        cno = self.get_argument('cno', '')
        expy = self.get_argument('expy', '')
        expm = self.get_argument('expm', '')
        ssnf = self.get_argument('ssnf', '')
        cpftd = self.get_argument('cpftd', '')
        calias = self.get_argument('calias', '')

        # register card
        request_url = '%s:%d/homemaster_payment/register_card' % (PAYMENT_HOST,
                                                                  PAYMENT_PORT)
        params = {}
        params['id'] = uid
        params['cno'] = cno
        params['expy'] = expy
        params['expm'] = expm
        params['ssnf'] = ssnf
        params['cpftd'] = cpftd
        params['calias'] = calias

        has_card = int(has_card)

        mongo_logger = get_mongo_logger()
        mix = get_mixpanel()

        # 카드가 없는 경우에만 카드 등록하고 진행, 있다면 바로 진행
        if has_card == 0:
            response = requests.post(request_url, data=params)
            result = json.loads(response.text)

            if response.status_code != 200 or result['response'] == "":
                print 'An error occurred while register card'
                print result['err_code'], result['err_msg']
                add_err_ko_message_to_response(ret, result['err_msg'])
                mongo_logger.error('register card failed', extra={'uid': uid})
                return

        laundry_apply_all = int(laundry_apply_all)

        search_keys = search_keys.split(',')

        try:
            session = Session()
            userdao = UserDAO()
            masterdao = MasterDAO()
            promotiondao = PromotionDAO()
            addressdao = AddressDAO()

            holder = IntermediateValueHolder()

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

            obj = holder.retrieve(store_key)
            print obj
            if obj == None:
                self.set_status(Response.RESULT_OK)
                add_err_message_to_response(ret,
                                            err_dict['err_booking_timeout'])
                mix.track(uid, 'request timeout', {'time': dt.datetime.now()})
                mongo_logger.error('%s got timed out' % uid)
                return

            # retrieve all stored values
            uid = obj['user_id']
            mid = obj['master_id']
            dates = obj['dates']
            time = obj['time']
            appointment_type = obj['appointment_type']
            additional_task = obj['additional_task']
            org_additional_task = additional_task

            taking_time = obj['taking_time']
            first_added_time = obj['first_added_time']
            additional_time = obj['additional_time']
            total_time = obj['total_time']
            master_gender = obj['master_gender']
            have_pet = obj['have_pet']
            isdirty = obj['isdirty']

            # price
            # price_with_task
            # discounted_price
            address, house_size, house_type = userdao.get_user_address_detail(
                uid)
            _, _, price, _ = get_time_price(appointment_type, house_type,
                                            house_size)
            _, additional_price = get_additional_task_time_price(
                additional_task, house_type, house_size)

            discounted_price = 0
            if promotion_code != '':
                discounted_price = promotiondao.get_discount_price(
                    promotion_code)

            price_with_task = price + additional_price
            if 0 < discounted_price <= 100:
                price_with_task *= (float(100 - discounted_price) / 100)
            else:
                price_with_task -= discounted_price

            price_with_task = int(price_with_task)

            print '-' * 30
            print price, additional_price
            print promotion_code, price_with_task
            print '##' * 20

            # hasids to generate unique booking id
            now = dt.datetime.strftime(dt.datetime.now(), '%Y%m%d%H%M%S')
            hashids = Hashids(min_length=16, salt=now + uid)

            # set tool info
            havetools = 1
            if additional_task >= 64:
                havetools = 0

            card_idx = 0
            addr_idx = 0

            # get card and address idx
            addr_idx = userdao.get_user_default_address_index(uid)
            card_idx = userdao.get_user_default_card_index(uid)

            i = 1
            booking_ids = []
            start_time_list = []

            for date in dates:  #
                print date, time
                booking_id = hashids.encode(int(date + time.replace(':', '')))
                print 'key', booking_id
                master_id = mid

                date = dt.datetime.strptime(date, '%Y%m%d')
                dow = date.date().weekday()
                booking_time = dt.time(hour=int(time.split(':')[0]),
                                       minute=int(time.split(':')[1]))

                start_time = dt.datetime.combine(date, booking_time)
                estimated_end_time = start_time + dt.timedelta(
                    minutes=total_time)
                cleaning_duration = taking_time

                actual_price = 0
                if i == 1:  # 1 번째 클리닝
                    actual_price = price_with_task  # 할인은 1회만 적용됨

                else:  # 나머지
                    actual_price = price
                    if havetools == 1:
                        additional_task = 0
                    else:
                        additional_task = 64

                    if laundry_apply_all == 1:
                        additional_task += 4  # 빨래

                    isdirty = 0  # 첫째 이후에는 is dirty는 0
                    estimated_end_time = estimated_end_time - dt.timedelta(
                        minutes=additional_time + first_added_time)

                booking = Booking(
                    id=booking_id,
                    request_id=request_id,
                    user_id=uid,
                    master_id=mid,
                    appointment_type=appointment_type,
                    appointment_index=i,
                    dow=dow,
                    booking_time=dt.datetime.now(),
                    org_start_time=start_time,
                    start_time=start_time,
                    estimated_end_time=estimated_end_time,
                    end_time=
                    estimated_end_time,  # update after homemaster finish their job
                    cleaning_duration=cleaning_duration,
                    additional_task=additional_task,
                    price=price,
                    price_with_task=actual_price,
                    charging_price=0,
                    card_idx=card_idx,
                    addr_idx=addr_idx,
                    havetools=havetools,
                    havepet=have_pet,
                    laundry_apply_all=laundry_apply_all,
                    is_dirty=isdirty,
                    master_gender=master_gender,
                    status=BC.BOOKING_UPCOMMING,
                    cleaning_status=BC.BOOKING_UPCOMMING,
                    payment_status=BC.BOOKING_UNPAID_YET)
                i += 1

                session.add(booking)
                booking_ids.append(booking_id)
                start_time_list.append(start_time)

                #print 'booking_id', booking_id, 'was added..'

            # charge for first appointment date
            user_name = userdao.get_user_name(uid)
            if price_with_task <= 0:
                ret_code = True
                msg = ''
            else:
                ret_code, msg = request_payment(uid, user_name, booking_ids[0],
                                                price_with_task,
                                                appointment_type)

            # 결제 정보 출력
            print user_name, ret_code, msg

            if ret_code:
                session.commit()

                # remove store_key and related_keys
                holder.remove(store_key)
                for sk in search_keys:
                    holder.remove(sk)

                # promotion code 와 연결
                if promotion_code != '':
                    promotiondao.set_promotion_code_status(
                        promotion_code, 1, booking_ids[0], price_with_task)

                # change status to paid
                try:
                    first_booking = session.query(Booking, User, MasterPushKey) \
                                            .join(User, Booking.user_id == User.id) \
                                            .outerjoin(MasterPushKey, Booking.master_id == MasterPushKey.master_id) \
                                            .filter(Booking.id == booking_ids[0]) \
                                            .one()
                except NoResultFound, e:
                    session.close()
                    self.set_status(Response.RESULT_OK)
                    mongo_logger.debug('no first booking record',
                                       extra={
                                           'uid': uid,
                                           'mid': mid,
                                           'appointment_type':
                                           appointment_type,
                                           'have_pet': have_pet,
                                           'master_gender': master_gender,
                                           'isdirty': isdirty
                                       })
                    add_err_message_to_response(ret, err_dict['err_no_record'])
                    return

                except MultipleResultsFound, e:
                    session.close()
                    self.set_status(Response.RESULT_OK)
                    mongo_logger.debug('multiple first booking record',
                                       extra={
                                           'uid': uid,
                                           'mid': mid,
                                           'appointment_type':
                                           appointment_type,
                                           'have_pet': have_pet,
                                           'master_gender': master_gender,
                                           'isdirty': isdirty
                                       })
                    add_err_message_to_response(
                        ret, err_dict['err_multiple_record'])
                    return