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

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

        ret = {}

        try:
            addresses = []

            session = Session()
            userdao = UserDAO()

            addresses = userdao.get_all_user_addresses(user_id)
            name = userdao.get_user_name(user_id)
            default_index = userdao.get_user_default_address_index(user_id)

            ret['response'] = {
                'name': name,
                'addresses': addresses,
                'user_id': user_id,
                'default_index': default_index
            }
            self.set_status(Response.RESULT_OK)

        except Exception, e:
            session.rollback()
            print_err_detail(e)
            self.set_status(Response.RESULT_SERVERERROR)
            add_err_message_to_response(ret, err_dict['err_mysql'])
    def post(self):
        self.set_header("Content-Type", "application/json")

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

        ret = {}

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

            addr_idx = userdao.get_user_default_address_index(user_id)

            booking = MovingCleaningBooking(user_id=user_id,
                                            addr_idx=addr_idx,
                                            datetime=dt.datetime.now())
            session.add(booking)
            session.commit()

            # send sms
            sms_sender = SMS_Sender()
            name = str(userdao.get_user_name(user_id))
            phone = str(userdao.get_user_phone(user_id))
            address, size, kind = userdao.get_user_address_detail(user_id)
            address = str(address)
            if kind == 0:
                kind = '오피스텔'
            elif kind == 1:
                kind = '주택'
            elif kind == 2:
                kind = '아파트'

            text = '입주청소 예약 문의\n이름: %s\n번호: %s\n주소: %s\n종류: %s\n평수:%d' % (
                name, phone, address, kind, size)
            #print sms_sender.send_for_manager(sender = MAIN_CALL, mtype = 'lms', to = JAMES_CALL, text = str(text))

            # jandi notification
            send_jandi('MOVING_IN_CLEANING', "이사청소 문의", name + ' 고객님 이사청소 문의',
                       text)

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

        except Exception, e:
            session.rollback()

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

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

        print 'phone', phone

        mongo_logger = get_mongo_logger()

        ret = {}

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

            try:
                result = session.query(User) \
                            .filter(func.aes_decrypt(func.from_base64(User.phone), \
                            func.substr(User.salt, 1, 16)) == phone,  \
                            User.active == 1) \
                            .all()

            except NoResultFound, e:
                session.close()
                self.set_status(Response.RESULT_OK)
                add_err_message_to_response(ret,
                                            err_dict['err_login_no_match'])
                mongo_logger.error('%s failed to get registerinfo' % phone,
                                   extra={'err': str(e)})
                return

            usersinfo = []

            for row in result:
                userinfo = {}
                userinfo['id'] = row.id
                userinfo['name'] = userdao.get_user_name(row.id)
                userinfo['phone'] = userdao.get_user_phone(row.id)
                userinfo['email'] = row.email
                usersinfo.append(userinfo)

            mongo_logger.debug('user registered info')

            ret['response'] = usersinfo
            self.set_status(Response.RESULT_OK)
    def get(self):
        self.set_header("Content-Type", "application/json")
        self.set_header('Access-Control-Allow-Origin', '*')

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

        ret = {}

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

            payment_histories = []

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

            for row in result:
                try:
                    auth_date = '20' + row.UserChargeRecord.auth_date
                    auth_date = dt.datetime.strptime(auth_date, '%Y%m%d%H%M%S')
                except Exception, e:
                    auth_date = None

                payment_info = {}
                payment_info['tid'] = row.UserChargeRecord.tid
                payment_info['amount'] = row.UserChargeRecord.amount
                payment_info['auth_date'] = convert_datetime_format2(
                    auth_date) if auth_date != None else ''

                payment_histories.append(payment_info)

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

            ret['response'] = {
                'user_id': user_id,
                'name': user_name,
                'phone': user_phone,
                'payment_histories': payment_histories
            }
            self.set_status(Response.RESULT_OK)
    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 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
    def post(self):
        self.set_header("Content-Type", "application/json")
        self.set_header('Access-Control-Allow-Origin', '*')

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

        ret = {}

        mongo_logger = get_mongo_logger()

        now = dt.datetime.now()

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

            row = session.query(Booking) \
                        .filter(Booking.id == booking_id) \
                        .filter(Booking.cleaning_status == BC.BOOKING_COMPLETED) \
                        .filter(Booking.payment_status != BC.BOOKING_PAID) \
                        .first()

            if row:
                user_id = row.user_id
                user_name = userdao.get_user_name(user_id)
                price = row.price_with_task
                appointment_type = row.appointment_type

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

                if ret_code:
                    row.payment_status = BC.BOOKING_PAID
                    session.commit()

                ret['response'] = {
                    'payment_status': str(ret_code),
                    'payment_result': value
                }
            else:
                ret['response'] = {
                    'payment_status': 'no unpaid booking',
                    'payment_result': ''
                }

            mongo_logger.debug('process unpaid booking',
                               extra={
                                   'booking_id': booking_id,
                                   'dt': now,
                                   'payment_status': ret_code,
                                   'payment_result': value
                               })

            self.set_status(Response.RESULT_OK)

        except Exception, e:
            session.rollback()

            print_err_detail(e)
            self.set_status(Response.RESULT_SERVERERROR)
            add_err_message_to_response(ret, err_dict['err_mysql'])
            mongo_logger.error('failed to process unpaid booking',
                               extra={'err': str(e)})
Exemplo n.º 8
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)

        wage_per_hour = self.get_argument('wage_per_hour', 0)
        address_index = self.get_argument('address_index', 0)

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

        coupon_id = self.get_argument('coupon_id', '')
        coupon_discount_price = self.get_argument('coupon_discount_price', 0)

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

        user_type = self.get_argument('user_type', 'unknown')

        # convert datetime

        # for ios fix
        if discounted_price != 0:
            discounted_price = discounted_price.replace('Optional(',
                                                        '').replace(')', '')

        price = int(price)
        price_with_task = int(price_with_task)
        discounted_price = int(discounted_price)
        coupon_discount_price = int(coupon_discount_price)
        laundry_apply_all = int(laundry_apply_all)
        wage_per_hour = int(wage_per_hour)

        print 'price_with_task', price_with_task
        print 'discounted_price', discounted_price

        search_keys = search_keys.split(',')

        mongo_logger = get_mongo_logger()
        mix = get_mixpanel()

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

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

            is_b2b = userdao.is_b2b(uid)

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

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

            card_idx = 0
            addr_idx = 0

            # get card and address idx
            if is_b2b:
                addr_idx = address_index
            else:
                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 - (
                        discounted_price + coupon_discount_price
                    )  # 할인은 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,
                    user_type=user_type,
                    wage_per_hour=wage_per_hour,
                    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 is_b2b:
                session.commit()

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

                send_jandi('NEW_BOOKING', '[b2b]새 예약 알림', 'b2b 고객님 예약완료',
                           user_name)

                # b2b용 알림톡 추가 필요

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

                mongo_logger.debug('b2b confirm booking',
                                   extra={
                                       'user_id': uid,
                                       'master_id': mid,
                                       'booking_id': booking_ids[0]
                                   })

                return

            charge_price = price_with_task - (discounted_price +
                                              coupon_discount_price)

            # 1주 1회면서, 이벤트 기간인 경우에는 결제 하지 않음
            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')

            print event_on
            if appointment_type == 4 and event_on:
                charge_price = price_with_task - price

                # 1회 이벤트 고객임을 명시해야함
                # table 필요
                free_event = UserFreeEvent(booking_request_id=request_id,
                                           user_id=uid,
                                           datetime=dt.datetime.now())
                session.add(free_event)

            if charge_price <= 0:
                ret_code = True
                msg = ''
            else:
                ret_code, msg = request_payment(uid, user_name, booking_ids[0],
                                                charge_price, appointment_type)

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

            if ret_code:
                session.commit()

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

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

                if coupon_id != '':
                    coupondao.set_coupon_status(coupon_id, 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
Exemplo n.º 9
0
    def get(self):
        self.set_header("Content-Type", "application/json")
        week = self.get_argument('week', 0)  # n weeks before
        week = int(week)

        ret = {}

        FRIDAY = 4
        SATURDAY = 5
        CANCELED_RATE = 0.5

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

            # get last saturday
            now = dt.datetime.now()
            if week != 0:
                offset = ((now.weekday() - FRIDAY) % 7) + (week - 1) * 7
                now -= dt.timedelta(days=offset)

            offset = (now.weekday() - SATURDAY) % 7
            last_saturday = (now - dt.timedelta(days=offset)).date()
            now = now.date()

            result = session.query(Booking, Master, User, UserAddress) \
                            .join(Master, Booking.master_id == Master.id) \
                            .join(User, Booking.user_id == User.id) \
                            .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \
                            .filter(Master.active != 0) \
                            .filter(and_(func.date(Booking.start_time) >= last_saturday, func.date(Booking.start_time) <= now)) \
                            .filter(or_(Booking.cleaning_status == BC.BOOKING_COMPLETED, \
                            and_(Booking.cleaning_status == BC.BOOKING_CANCELED, \
                            or_(Booking.payment_status == BC.BOOKING_CANCELED_REFUND, \
                            Booking.payment_status == BC.BOOKING_CANCELED_CHARGE)))) \
                            .order_by(Booking.master_id, Booking.start_time) \
                            .all()

            weekly_salary = 0

            master_salaries = []

            start_period = last_saturday
            end_period = now

            last_saturday = dt.datetime.strftime(last_saturday, '%Y%m%d')
            now = dt.datetime.strftime(now, '%Y%m%d')

            prev_master_id = None

            for row in result:
                if row.Booking.user_id == '81c2f5c1-7295-489d-8bb0-334121060ae3':
                    continue

                user_name = userdao.get_user_name(row.Booking.user_id)
                org_price = row.Booking.price_with_task
                status = row.Booking.cleaning_status
                appointment_index = row.Booking.appointment_index
                appointment_type = row.Booking.appointment_type
                start_time = row.Booking.start_time
                end_time = row.Booking.estimated_end_time
                cleaning_duration = row.Booking.cleaning_duration / 6
                charging_price = row.Booking.charging_price
                is_dirty = row.Booking.is_dirty
                is_b2b = row.User.is_b2b

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

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

                if is_dirty == 1:
                    minutes_for_salary -= 20

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

                extra_charge = 0
                if row.Booking.cleaning_status == BC.BOOKING_COMPLETED:
                    if is_b2b:
                        weekly_salary = int(minutes_for_salary *
                                            (row.Booking.wage_per_hour / 10))
                    else:
                        # 오피스텔 13평 이하, 주택 7평 이하는 시급 14000
                        weekly_salary = 0
                        if start_time >= dt.datetime(2017, 1, 1):
                            weekly_salary = minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR
                        else:
                            if appointment_type in BC.REGULAR_CLEANING_DICT:
                                weekly_salary = minutes_for_salary * BC.SALARY_FOR_REGULAR_IN_HOUR
                            else:
                                weekly_salary = minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR

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

                    extra_charge = bookingdao.get_extra_charge(row.Booking.id)
                    weekly_salary += extra_charge

                elif row.Booking.payment_status == BC.BOOKING_CANCELED_CHARGE or \
                    row.Booking.payment_status == BC.BOOKING_CANCELED_REFUND:
                    weekly_salary = int(charging_price * CANCELED_RATE)

                if prev_master_id == None or prev_master_id != row.Booking.master_id:  # 변함
                    salary = {}
                    salary_detail = []
                    bank_name, bank_code, account_no = masterdao.get_master_account(
                        row.Booking.master_id)

                    salary['weekly_salary'] = 0
                    salary['master_name'] = row.Master.name
                    salary['master_account'] = {
                        'bank_name': bank_name,
                        'bank_code': bank_code,
                        'account_no': account_no
                    }
                    salary['master_phone'] = row.Master.phone
                    salary['weekly_salary'] += weekly_salary
                    salary[
                        'penalty_amount'] = 0  #masterdao.get_master_penalties(row.Booking.master_id, start_period, end_period)

                    if weekly_salary > 0:
                        salary_detail.append({
                            'org_price':
                            org_price,
                            'charging_price':
                            charging_price,
                            'salary':
                            weekly_salary,
                            'extra_charge':
                            extra_charge,
                            'status':
                            status,
                            'start_time':
                            dt.datetime.strftime(start_time, '%Y-%m-%d %H:%M'),
                            'end_time':
                            dt.datetime.strftime(end_time, '%Y-%m-%d %H:%M'),
                            'cleaning_index':
                            appointment_index,
                            'user_name':
                            user_name
                        })

                    salary['salary_detail'] = salary_detail

                    master_salaries.append(salary)
                else:
                    salary['weekly_salary'] += weekly_salary
                    if weekly_salary > 0:
                        salary_detail.append({
                            'org_price':
                            org_price,
                            'charging_price':
                            charging_price,
                            'salary':
                            weekly_salary,
                            'extra_charge':
                            extra_charge,
                            'status':
                            status,
                            'start_time':
                            dt.datetime.strftime(start_time, '%Y-%m-%d %H:%M'),
                            'end_time':
                            dt.datetime.strftime(end_time, '%Y-%m-%d %H:%M'),
                            'cleaning_index':
                            appointment_index,
                            'user_name':
                            user_name
                        })

                prev_master_id = row.Master.id

            total_salaries = 0
            for ms in master_salaries:
                if start_time >= dt.datetime(2017, 1, 1):
                    ms['weekly_salary'] = int(ms['weekly_salary'])
                else:
                    ms['weekly_salary'] = int(ms['weekly_salary'] * 0.967)
                total_salaries += (ms['weekly_salary'] - ms['penalty_amount'])
                ms['actual_weekly_salary'] = '{:,}'.format(
                    ms['weekly_salary'] - ms['penalty_amount'])

            total_salaries = '{:,}'.format(total_salaries)

            master_salaries = sorted(master_salaries,
                                     key=lambda x: (x['master_name']))

            ret['response'] = {
                'date_from': last_saturday,
                'date_to': now,
                'master_salaries': master_salaries,
                'total_salaries': total_salaries
            }
            self.set_status(Response.RESULT_OK)

        except Exception, e:
            session.rollback()

            print_err_detail(e)
            self.set_status(Response.RESULT_SERVERERROR)
            add_err_message_to_response(ret, err_dict['err_mysql'])
    def get(self):
        self.set_header("Content-Type", "application/json")
        year = self.get_argument('yyyy', 2016)
        month = self.get_argument('mm', 9)

        ret = {}

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

            CANCELED_RATE = 0.5

            year = int(year)
            month = int(month)

            first_day, last_day = get_month_day_range(dt.date(year, month, 7))

            result = session.query(Booking, Master, User, UserAddress) \
                            .join(Master, Booking.master_id == Master.id) \
                            .join(User, Booking.user_id == User.id) \
                            .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \
                            .filter(and_(func.date(Booking.start_time) >= first_day, func.date(Booking.start_time) <= last_day)) \
                            .filter(Master.active == 1) \
                            .order_by(Booking.master_id, Booking.start_time) \
                            .all()

            monthly_salary_dict = {}
            prev_master_id = None

            for row in result:
                user_name = userdao.get_user_name(row.Booking.user_id)
                master_id = row.Booking.master_id
                master_name = row.Master.name
                master_phone = row.Master.phone
                org_price = row.Booking.price_with_task
                status = row.Booking.cleaning_status
                #appointment_index   = row.Booking.appointment_index
                appointment_type = row.Booking.appointment_type
                additional_task = row.Booking.additional_task
                start_time = row.Booking.start_time
                end_time = row.Booking.estimated_end_time
                #cleaning_duration   = row.Booking.cleaning_duration / 6
                charging_price = row.Booking.charging_price
                is_dirty = row.Booking.is_dirty
                is_b2b = row.User.is_b2b

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

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

                monthly_salary = 0

                if is_dirty == 1:  # 똥집인 경우 2시간 제외해야함
                    minutes_for_salary -= 20

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

                if row.Booking.cleaning_status == BC.BOOKING_COMPLETED or \
                    row.Booking.cleaning_status == BC.BOOKING_STARTED or \
                    row.Booking.cleaning_status == BC.BOOKING_UPCOMMING:

                    if is_b2b:
                        monthly_salary = int(minutes_for_salary *
                                             (row.Booking.wage_per_hour / 10))
                    else:
                        # 오피스텔 13평 이하, 주택 7평 이하는 시급 14000
                        if appointment_type in BC.REGULAR_CLEANING_DICT:
                            monthly_salary = minutes_for_salary * BC.SALARY_FOR_REGULAR_IN_HOUR
                        else:
                            monthly_salary = minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR

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

                    monthly_salary += bookingdao.get_extra_charge(
                        row.Booking.id)

                elif row.Booking.payment_status == BC.BOOKING_CANCELED_CHARGE or \
                    row.Booking.payment_status == BC.BOOKING_CANCELED_REFUND:
                    monthly_salary = int(charging_price * CANCELED_RATE)

                monthly_salary = monthly_salary * 0.967  # 3.3% 제외

                # 마스터가 신규
                if prev_master_id == None or master_id != prev_master_id:
                    penalty_amount = masterdao.get_master_penalties(
                        master_id, first_day, last_day)
                    monthly_salary_dict[master_id] = {
                        'name': master_name,
                        'phone': master_phone,
                        'monthly_salary': monthly_salary,
                        'penalty_amount': penalty_amount
                    }
                else:
                    monthly_salary_dict[master_id][
                        'monthly_salary'] += monthly_salary

                prev_master_id = master_id

            monthly_salary_dict = {value['name'] : {'master_id' : mid, \
                                                    'phone' : value['phone'], \
                                                    'monthly_salary' : int(value['monthly_salary']), \
                                                    'monthly_salary_str' : '{:,}'.format(int(value['monthly_salary'])), \
                                                    'penalty_amount' : value['penalty_amount']} \
                                    for mid, value in monthly_salary_dict.items()}

            monthly_salary_dict = OrderedDict(
                sorted(monthly_salary_dict.items(), key=lambda x: x[0]))

            ret['response'] = monthly_salary_dict

            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'])
Exemplo n.º 11
0
    def get(self):
        self.set_header("Content-Type", "application/json")
        master_id = self.get_argument('master_id', '')

        ret = {}

        # weekly
        SATURDAY = 5
        CANCELED_RATE = 0.5

        try:
            session = Session()
            # get last saturday
            userdao = UserDAO()
            masterdao = MasterDAO()
            bookingdao = BookingDAO()

            now = dt.datetime.now()
            offset = (now.weekday() - SATURDAY) % 7

            last_saturday = (now - dt.timedelta(days=offset)).date()
            now = now.date()

            date_range = []
            date_range.append((last_saturday, now))

            from_date = last_saturday - dt.timedelta(days=7)
            to_date = last_saturday - dt.timedelta(days=1)

            for i in range(11):
                date_range.append((from_date, to_date))

                from_date = from_date - dt.timedelta(days=7)
                to_date = to_date - dt.timedelta(days=7)

            weekly_salaries = []

            start_time = dt.datetime.now()

            for dr in date_range:
                from_date = dr[0]
                to_date = dr[1]

                result = session.query(Booking, Master, User, UserAddress) \
                                .join(Master, Booking.master_id == Master.id) \
                                .join(User, Booking.user_id == User.id) \
                                .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \
                                .filter(and_(func.date(Booking.start_time) >= from_date, func.date(Booking.start_time) <= to_date)) \
                                .filter(Booking.master_id == master_id) \
                                .filter(or_(Booking.cleaning_status == BC.BOOKING_COMPLETED, \
                                and_(Booking.cleaning_status == BC.BOOKING_CANCELED, \
                                or_(Booking.payment_status == BC.BOOKING_CANCELED_REFUND, \
                                Booking.payment_status == BC.BOOKING_CANCELED_CHARGE)))) \
                                .order_by(Booking.master_id, Booking.start_time) \
                                .all()

                weekly_salary = 0

                for row in result:
                    if row.Booking.user_id == '81c2f5c1-7295-489d-8bb0-334121060ae3':
                        continue

                    user_name = userdao.get_user_name(row.Booking.user_id)
                    org_price = row.Booking.price_with_task
                    status = row.Booking.cleaning_status
                    appointment_index = row.Booking.appointment_index
                    appointment_type = row.Booking.appointment_type
                    additional_task = row.Booking.additional_task
                    start_time = row.Booking.start_time
                    end_time = row.Booking.estimated_end_time
                    cleaning_duration = row.Booking.cleaning_duration / 6
                    charging_price = row.Booking.charging_price
                    is_dirty = row.Booking.is_dirty
                    is_b2b = row.User.is_b2b

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

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

                    if is_dirty == 1:
                        minutes_for_salary -= 20

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

                    if row.Booking.cleaning_status == BC.BOOKING_COMPLETED:
                        if is_b2b:
                            weekly_salary += int(
                                minutes_for_salary *
                                (row.Booking.wage_per_hour / 10))
                        else:
                            # 오피스텔 13평 이하, 주택 7평 이하는 시급 14000
                            if start_time >= dt.datetime(2017, 1, 1):
                                weekly_salary += minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR
                            else:
                                if appointment_type in BC.REGULAR_CLEANING_DICT:
                                    weekly_salary += minutes_for_salary * BC.SALARY_FOR_REGULAR_IN_HOUR
                                else:
                                    weekly_salary += minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR

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

                        weekly_salary += bookingdao.get_extra_charge(
                            row.Booking.id)

                    elif row.Booking.payment_status == BC.BOOKING_CANCELED_CHARGE or \
                        row.Booking.payment_status == BC.BOOKING_CANCELED_REFUND:
                        weekly_salary += int(charging_price * CANCELED_RATE)

                penalty_amount = 0  #masterdao.get_master_penalties(master_id, from_date, to_date)

                weekly_salary = int(weekly_salary)
                if start_time >= dt.datetime(2017, 1, 1):
                    weekly_salary = int(weekly_salary)
                else:
                    weekly_salary = int(weekly_salary * 0.967)

                actual_weekly_salary = weekly_salary - penalty_amount

                weekly_salary = '{:,}'.format(weekly_salary)
                actual_weekly_salary = '{:,}'.format(actual_weekly_salary)
                penalty_amount = '{:,}'.format(penalty_amount)

                from_date_str = dt.datetime.strftime(from_date, '%Y%m%d')
                to_date_str = dt.datetime.strftime(to_date, '%Y%m%d')

                weekly_salaries.append({
                    'date_from':
                    from_date_str,
                    'date_to':
                    to_date_str,
                    'salary':
                    weekly_salary,
                    'penalty_amount':
                    penalty_amount,
                    'actual_weekly_salary':
                    actual_weekly_salary
                })

            # montly
            '''monthly_salaries = []

            date_range = []

            from_date = dt.date(now.year, now.month, 1)
            to_date = now

            date_range.append((from_date, to_date))

            for i in range(11):
                to_date = from_date - dt.timedelta(days=1)
                from_date = dt.date(to_date.year, to_date.month, 1)

                date_range.append((from_date, to_date))

            for dr in date_range:
                from_date = dr[0]
                to_date = dr[1]

                result = session.query(Booking, Master, User, UserAddress) \
                                .join(Master, Booking.master_id == Master.id) \
                                .join(User, Booking.user_id == User.id) \
                                .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \
                                .filter(and_(func.date(Booking.start_time) >= from_date, func.date(Booking.start_time) <= to_date)) \
                                .filter(Booking.master_id == master_id) \
                                .order_by(Booking.master_id, Booking.start_time) \
                                .all()

                monthly_salary = 0

                for row in result:
                    user_name           = userdao.get_user_name(row.Booking.user_id)
                    org_price           = row.Booking.price_with_task
                    status              = row.Booking.cleaning_status
                    appointment_index   = row.Booking.appointment_index
                    appointment_type    = row.Booking.appointment_type
                    start_time          = row.Booking.start_time
                    end_time            = row.Booking.estimated_end_time
                    cleaning_duration   = row.Booking.cleaning_duration / 6
                    charging_price      = row.Booking.charging_price

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

                    if duration_in_minutes > cleaning_duration: # 30분의 시간이 더 더해지는 경우가 존재. 그 경우, 해당 시간은 임금에 반영 되지 않음
                        minutes_for_salary = duration_in_minutes - 5

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

                    if row.Booking.cleaning_status == BC.BOOKING_COMPLETED:
                        # 오피스텔 13평 이하, 주택 7평 이하는 시급 14000
                        if ((house_type == 0 and house_size <= 12) or (house_type == 1 and house_size <= 7)):
                            monthly_salary += minutes_for_salary * BC.SALARY_FOR_SMALL_IN_HOUR
                        else:
                            monthly_salary += minutes_for_salary * BC.SALARY_FOR_NORMAL_IN_HOUR

                        monthly_salary += bookingdao.get_extra_charge(row.Booking.id)

                    elif row.Booking.payment_status == BC.BOOKING_CANCELED_CHARGE or \
                        row.Booking.payment_status == BC.BOOKING_CANCELED_REFUND:
                        monthly_salary += int(charging_price * CANCELED_RATE)

                monthly_salary = int(monthly_salary)
                monthly_salary = '{:,}'.format(monthly_salary)

                from_date_str = dt.datetime.strftime(from_date, '%Y%m%d')
                to_date_str = dt.datetime.strftime(to_date, '%Y%m%d')

                monthly_salaries.append({'date_from' : from_date_str, 'date_to' : to_date_str, 'salary' : monthly_salary})

            # total
            total_salary = 0
            result = session.query(Booking, Master, User, UserAddress) \
                            .join(Master, Booking.master_id == Master.id) \
                            .join(User, Booking.user_id == User.id) \
                            .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \
                            .filter(Booking.master_id == master_id) \
                            .order_by(Booking.master_id, Booking.start_time) \
                            .all()

            for row in result:
                user_name           = userdao.get_user_name(row.Booking.user_id)
                org_price           = row.Booking.price_with_task
                status              = row.Booking.cleaning_status
                appointment_index   = row.Booking.appointment_index
                appointment_type    = row.Booking.appointment_type
                start_time          = row.Booking.start_time
                end_time            = row.Booking.estimated_end_time
                cleaning_duration   = row.Booking.cleaning_duration / 6
                charging_price      = row.Booking.charging_price

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

                if duration_in_minutes > cleaning_duration: # 30분의 시간이 더 더해지는 경우가 존재. 그 경우, 해당 시간은 임금에 반영 되지 않음
                    minutes_for_salary = duration_in_minutes - 5

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

                if row.Booking.cleaning_status == BC.BOOKING_COMPLETED:
                    # 오피스텔 13평 이하, 주택 7평 이하는 시급 14000
                    if ((house_type == 0 and house_size <= 12) or (house_type == 1 and house_size <= 7)):
                        total_salary += minutes_for_salary * BC.SALARY_FOR_SMALL_IN_HOUR
                    else:
                        total_salary += minutes_for_salary * BC.SALARY_FOR_NORMAL_IN_HOUR

                    total_salary += bookingdao.get_extra_charge(row.Booking.id)

                elif row.Booking.payment_status == BC.BOOKING_CANCELED_CHARGE or \
                    row.Booking.payment_status == BC.BOOKING_CANCELED_REFUND:
                    total_salary += int(charging_price * CANCELED_RATE)

            total_salary = int(total_salary)
            total_salary = '{:,}'.format(total_salary)'''

            # get master point
            #master_point = 0
            #point_row = session.query(func.sum(MasterPoint.point)).filter(MasterPoint.master_id == master_id).all()
            #master_point = int(point_row[0][0])

            master_row = session.query(Master).filter(
                Master.id == master_id).one()
            master_name = master_row.name
            master_phone = master_row.phone

            ret['response'] = {
                'master_name': master_name,
                'master_phone': master_phone,
                'weekly_salary': weekly_salaries,
                'total_salary': 0,
                'monthly_salary': []
            }
            self.set_status(Response.RESULT_OK)

        except Exception, e:
            session.rollback()

            print_err_detail(e)
            self.set_status(Response.RESULT_SERVERERROR)
            add_err_message_to_response(ret, err_dict['err_mysql'])
    def post(self):
            self.set_header("Content-Type", "application/json")

            ret = {}

            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

            # convert datetime
            price                   = int(price)
            price_with_task         = int(price_with_task)
            discounted_price        = int(discounted_price)
            laundry_apply_all       = int(laundry_apply_all)

            search_keys = search_keys.split(',')

            mongo_logger = get_mongo_logger()
            mix = get_mixpanel()

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

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

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

                # 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 - discounted_price # 할인은 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 - discounted_price <= 0:
                    ret_code = True
                    msg = ''
                else:
                    ret_code = True
                    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)
                    
                    session.commit()

                    mix.track(uid, 'confirm booking', {'time' : dt.datetime.now(), 'appointment_type' : appointment_type, 'additional_task' : additional_task})
                    mongo_logger.debug('confirm booking', extra = {'user_id' : uid, 'master_id' : mid, 'booking_id' : booking_ids[0], 'start_time' : start_time_list[0]})

                    #ret['response'] = {'booking_ids' : booking_ids} # victor 요청으로 첫번째 
                    ret['response'] = booking_ids[0]
                    self.set_status(Response.RESULT_OK)

                    # notification to managers
                    send_booking_iphone(booking_ids[0])

                    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회'

                    master_phone = masterdao.get_master_phone(mid)
                    send_alimtalk(master_phone, 'noti_manager_new', user_name, appointment_type_text)

                    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  
Exemplo n.º 13
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
    def post(self):
            self.set_header("Content-Type", "application/json")

            ret = {}

            store_key               = self.get_argument('store_key', '')
            uid                     = self.get_argument('uid', '')
            mid                     = self.get_argument('mid', '')
            appointment_type        = self.get_argument('appointment_type', BC.ONE_TIME)
            additional_task         = self.get_argument('additional_task', 0)
            discounted_price        = self.get_argument('discounted_price', 0)
            price                   = self.get_argument('price', 0)
            price_with_task         = self.get_argument('price_with_task', 0)
            promotion_code          = self.get_argument('promotion_code', '')
            have_pet                = self.get_argument('have_pet', 0)
            search_keys             = self.get_argument('search_keys', '')
            master_gender           = self.get_argument('master_gender', 0)
            isdirty                 = self.get_argument('isdirty', 0)
            first_added_time        = self.get_argument('first_added_time', 0)
            additional_time         = self.get_argument('additional_time', 10)
            laundry_apply_all       = self.get_argument('laundry_apply_all', 0) # -1 - 없앰, 0 - one time, 1 - all time

            # convert datetime
            appointment_type        = int(appointment_type)
            additional_task         = int(additional_task)
            price                   = int(price)
            price_with_task         = int(price_with_task)
            discounted_price        = int(discounted_price)
            have_pet                = int(have_pet)
            master_gender           = int(master_gender)
            isdirty                 = int(isdirty)
            laundry_apply_all       = int(laundry_apply_all)


            first_added_time        = int(first_added_time)
            additional_time         = int(additional_time)
            first_added_time_in_minutes   = first_added_time * 6
            additional_time_in_minutes    = additional_time * 6 

            print first_added_time, additional_time

            search_keys = search_keys.split(',')


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

            mongo_logger = get_mongo_logger()

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

            mix = get_mixpanel()

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

                holder = IntermediateValueHolder()

                card_idx = 0
                addr_idx = 0

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

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

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

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

                i = 1
                booking_ids = []
                start_time_list = []

                obj = sorted(obj, key = lambda x: x['date'])

                for item in obj:
                    print item['date']
                    booking_id = hashids.encode(int(item['date'] + time_to_str(item['start_time'])))
                    master_id = item['mid']

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

                    cleaning_duration = time_to_minutes(timedelta_to_time(estimated_end_time - dt.timedelta(minutes=additional_time_in_minutes + first_added_time_in_minutes) - start_time))

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

                    else: # 나머지
                        actual_price = price
                        if havetools == 1:
                            additional_task = 0
                        else: 
                            additional_task = 64
                            #actual_price += BC.VACCUM_CHARGE

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

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


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

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

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

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

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

                if ret_code:
                    session.commit()

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

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

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

                    except MultipleResultsFound, e:
                        session.close()
                        self.set_status(Response.RESULT_OK)
                        mongo_logger.debug('multiple first booking record', extra = {    'uid' : uid, 'mid' : mid, 'appointment_type' : appointment_type, 'have_pet' : have_pet, 'master_gender' : master_gender, 'isdirty' : isdirty})
                        add_err_message_to_response(ret, err_dict['err_multiple_record'])
                        return  
Exemplo n.º 15
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
Exemplo n.º 16
0
    def get(self):
        self.set_header("Content-Type", "application/json")

        ret = {}

        SATURDAY = 5
        CANCELED_RATE = 0.7

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

            # get last saturday
            now = dt.datetime.now()
            now -= dt.timedelta(days=3)
            offset = (now.weekday() - SATURDAY) % 7

            last_saturday = (now - dt.timedelta(days=offset)).date()
            now = now.date()

            result = session.query(Booking, UserPaymentRecord, UserPaymentRecordForIOS, EventPromotionBooking, Promotion, Master, User) \
                            .outerjoin(UserPaymentRecord, Booking.id == UserPaymentRecord.booking_id) \
                            .outerjoin(UserPaymentRecordForIOS, Booking.id == UserPaymentRecordForIOS.booking_id) \
                            .outerjoin(Promotion, Booking.id == Promotion.booking_id) \
                            .outerjoin(EventPromotionBooking, Booking.id == EventPromotionBooking.booking_id) \
                            .join(Master, Booking.master_id == Master.id) \
                            .join(User, Booking.user_id == User.id) \
                            .filter(and_(func.date(Booking.start_time) >= last_saturday, func.date(Booking.start_time) <= now)) \
                            .order_by(Booking.master_id, Booking.start_time) \
                            .all()

            weekly_salary = 0

            master_salaries = []

            last_saturday = dt.datetime.strftime(last_saturday, '%Y%m%d')
            now = dt.datetime.strftime(now, '%Y%m%d')

            prev_master_id = None

            for row in result:
                appointment_type = row.Booking.appointment_type
                fee_rate = master_fee_rate_dict[appointment_type]

                user_name = userdao.get_user_name(row.Booking.user_id)

                org_salary = 0
                charging_price = 0
                weekly_salary = 0
                status = 0

                canceled_amount = 0  # 관리자 재량으로 취소한 금액이 있다면
                discount_amount = 0  # 할일코드가 발급된 거라면, 그만큼 금액 추가

                if row.Booking.cleaning_status == BC.BOOKING_COMPLETED:
                    if row.UserPaymentRecord != None:
                        canceled_amount = row.UserPaymentRecord.canceled_amount

                    if row.Promotion != None:
                        discount_amount = row.Promotion.discount_price
                        if discount_amount <= 100:
                            discount_amount = row.Promotion.service_price

                    if row.EventPromotionBooking != None:
                        discount_amount = row.EventPromotionBooking.discount_price

                    if row.UserPaymentRecord == None:
                        org_salary = row.Booking.price_with_task
                    else:
                        org_salary = row.UserPaymentRecord.price
                        if row.UserPaymentRecord.status == 'CHARGED':
                            discount_amount = 0

                    charging_price = row.Booking.charging_price

                    manual_charging_price = 0
                    if row.UserPaymentRecordForIOS != None:
                        manual_charging_price += row.UserPaymentRecordForIOS.amount

                    # 2016. 03. 08 lily park 요청으로 canceled_amount 막음
                    weekly_salary = (org_salary + charging_price +
                                     manual_charging_price - canceled_amount +
                                     discount_amount) * fee_rate
                    #weekly_salary = (org_salary + charging_price + manual_charging_price + discount_amount) * fee_rate
                    status = BC.BOOKING_COMPLETED
                    start_time = row.Booking.start_time

                elif row.Booking.payment_status == BC.BOOKING_CANCELED_CHARGE:
                    if row.UserPaymentRecord != None:
                        canceled_amount = row.UserPaymentRecord.canceled_amount

                    org_salary = row.Booking.price_with_task
                    charging_price = row.Booking.charging_price

                    if row.User.devicetype == 'android':
                        weekly_salary = charging_price * fee_rate * CANCELED_RATE
                    status = BC.BOOKING_CANCELED_CHARGE
                    start_time = row.Booking.start_time

                elif row.Booking.payment_status == BC.BOOKING_CANCELED_REFUND:
                    if row.UserPaymentRecord != None:
                        canceled_amount = row.UserPaymentRecord.canceled_amount

                    org_salary = row.Booking.price_with_task
                    charging_price = row.Booking.charging_price
                    print row.Booking.id, row.Booking.master_id, charging_price
                    if row.User.devicetype == 'android':
                        weekly_salary = charging_price * fee_rate * CANCELED_RATE
                    status = BC.BOOKING_CANCELED_REFUND
                    start_time = row.Booking.start_time

                if prev_master_id == None or prev_master_id != row.Booking.master_id:  # 변함
                    salary = {}
                    salary_detail = []
                    salary['weekly_salary'] = 0
                    salary['master_name'] = row.Master.name
                    salary['master_phone'] = row.Master.phone
                    salary['weekly_salary'] += int(weekly_salary)

                    if int(weekly_salary) > 0:
                        salary_detail.append({
                            'org_price':
                            org_salary,
                            'charging_price':
                            charging_price,
                            'canceled_amount':
                            canceled_amount,
                            'discount_amount':
                            discount_amount,
                            'salary':
                            int(weekly_salary),
                            'status':
                            status,
                            'start_time':
                            dt.datetime.strftime(start_time, '%Y-%m-%d %H:%M'),
                            'user_name':
                            user_name,
                            'fee_rate':
                            fee_rate,
                            'cancel_fee_rate':
                            float(fee_rate * CANCELED_RATE)
                        })

                    salary['salary_detail'] = salary_detail

                    master_salaries.append(salary)
                else:
                    salary['weekly_salary'] += int(weekly_salary)
                    if int(weekly_salary) > 0:
                        salary['salary_detail'].append({
                            'org_price':
                            org_salary,
                            'charging_price':
                            charging_price,
                            'canceled_amount':
                            canceled_amount,
                            'discount_amount':
                            discount_amount,
                            'salary':
                            int(weekly_salary),
                            'status':
                            status,
                            'start_time':
                            dt.datetime.strftime(start_time, '%Y-%m-%d %H:%M'),
                            'user_name':
                            user_name,
                            'fee_rate':
                            fee_rate,
                            'cancel_fee_rate':
                            float(fee_rate * CANCELED_RATE)
                        })

                prev_master_id = row.Master.id

            salary_sum = 0
            for ms in master_salaries:
                salary_sum += ms['weekly_salary']
                ms['weekly_salary'] = '{:,}'.format(ms['weekly_salary'])

            print salary_sum

            ret['response'] = {
                'date_from': last_saturday,
                'date_to': now,
                'master_salaries': master_salaries
            }
            self.set_status(Response.RESULT_OK)

        except Exception, e:
            session.rollback()

            print_err_detail(e)
            self.set_status(Response.RESULT_SERVERERROR)
            add_err_message_to_response(ret, err_dict['err_mysql'])
    def get(self):
        self.set_header("Content-Type", "application/json")

        ret = {}
        SATURDAY = 5
        CANCELED_RATE = 0.5

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

            # get last saturday
            now = dt.datetime.now()
            offset = (now.weekday() - SATURDAY) % 7

            last_saturday = (now - dt.timedelta(days=offset)).date()
            now = now.date()

            result = session.query(Booking, Master, User, UserAddress) \
                            .join(Master, Booking.master_id == Master.id) \
                            .join(User, Booking.user_id == User.id) \
                            .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \
                            .filter(and_(func.date(Booking.start_time) >= last_saturday, func.date(Booking.start_time) <= now)) \
                            .filter(not_(User.email.like('*****@*****.**'))) \
                            .order_by(Booking.master_id, Booking.start_time) \
                            .all()

            weekly_salary = 0
            for row in result:
                user_name = userdao.get_user_name(row.Booking.user_id)
                org_price = row.Booking.price_with_task
                status = row.Booking.cleaning_status
                appointment_index = row.Booking.appointment_index
                appointment_type = row.Booking.appointment_type
                start_time = row.Booking.start_time
                end_time = row.Booking.estimated_end_time
                cleaning_duration = row.Booking.cleaning_duration / 6
                charging_price = row.Booking.charging_price
                is_b2b = row.User.is_b2b

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

                #if duration_in_minutes > cleaning_duration: # 30분의 시간이 더 더해지는 경우가 존재. 그 경우, 해당 시간은 임금에 반영 되지 않음
                #    minutes_for_salary = duration_in_minutes - 5

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

                extra_charge = 0
                if row.Booking.cleaning_status == BC.BOOKING_COMPLETED:
                    if is_b2b:
                        weekly_salary += int(minutes_for_salary *
                                             (row.Booking.wage_per_hour / 10))
                    else:
                        # 오피스텔 13평 이하, 주택 7평 이하는 시급 14000
                        if appointment_type in BC.REGULAR_CLEANING_DICT:
                            weekly_salary += minutes_for_salary * BC.SALARY_FOR_REGULAR_IN_HOUR
                        else:
                            weekly_salary += minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR

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

                    extra_charge = bookingdao.get_extra_charge(row.Booking.id)
                    weekly_salary += extra_charge

                elif row.Booking.payment_status == BC.BOOKING_CANCELED_CHARGE or \
                    row.Booking.payment_status == BC.BOOKING_CANCELED_REFUND:
                    weekly_salary += int(charging_price * CANCELED_RATE)

            ret['response'] = {'weekly_salary': weekly_salary, 'revenue': 100}
            self.set_status(Response.RESULT_OK)

        except Exception, e:
            session.rollback()

            print_err_detail(e)
            self.set_status(Response.RESULT_SERVERERROR)
            add_err_message_to_response(ret, err_dict['err_mysql'])
    def get(self):
        self.set_header("Content-Type", "application/json")
        master_id = self.get_argument('master_id', '')
        year = self.get_argument('yyyy', 2016)
        month = self.get_argument('mm', 9)

        ret = {}

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

            CANCELED_RATE = 0.5

            year = int(year)
            month = int(month)

            first_day, last_day = get_month_day_range(dt.date(year, month, 7))

            result = session.query(Booking, Master, User, UserAddress) \
                            .join(Master, Booking.master_id == Master.id) \
                            .join(User, Booking.user_id == User.id) \
                            .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \
                            .filter(and_(func.date(Booking.start_time) >= first_day, func.date(Booking.start_time) <= last_day)) \
                            .filter(Booking.master_id == master_id) \
                            .order_by(Booking.master_id, Booking.start_time) \
                            .all()

            monthly_salary = 0
            monthly_salaries = []

            for row in result:
                user_name = userdao.get_user_name(row.Booking.user_id)
                org_price = row.Booking.price_with_task
                status = row.Booking.cleaning_status
                appointment_index = row.Booking.appointment_index
                appointment_type = row.Booking.appointment_type
                additional_task = row.Booking.additional_task
                start_time = row.Booking.start_time
                end_time = row.Booking.estimated_end_time
                cleaning_duration = row.Booking.cleaning_duration / 6
                charging_price = row.Booking.charging_price
                is_dirty = row.Booking.is_dirty
                is_b2b = row.User.is_b2b

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

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

                if is_dirty == 1:  # 똥집인 경우 2시간 제외해야함
                    minutes_for_salary -= 20

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

                if row.Booking.cleaning_status == BC.BOOKING_COMPLETED or \
                    row.Booking.cleaning_status == BC.BOOKING_STARTED or \
                    row.Booking.cleaning_status == BC.BOOKING_UPCOMMING:

                    if is_b2b:
                        monthly_salary += int(minutes_for_salary *
                                              (row.Booking.wage_per_hour / 10))
                    else:
                        # 오피스텔 13평 이하, 주택 7평 이하는 시급 14000
                        if appointment_type in BC.REGULAR_CLEANING_DICT:
                            monthly_salary += minutes_for_salary * BC.SALARY_FOR_REGULAR_IN_HOUR
                        else:
                            monthly_salary += minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR

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

                    monthly_salary += bookingdao.get_extra_charge(
                        row.Booking.id)

                elif row.Booking.payment_status == BC.BOOKING_CANCELED_CHARGE or \
                    row.Booking.payment_status == BC.BOOKING_CANCELED_REFUND:
                    monthly_salary += int(charging_price * CANCELED_RATE)

            penalty_amount = masterdao.get_master_penalties(
                master_id, first_day, last_day)

            monthly_salary = int(monthly_salary * 0.967)  # 3.3% 제외
            actual_monthly_salary = monthly_salary - penalty_amount

            monthly_salary = '{:,}'.format(monthly_salary)
            actual_monthly_salary = '{:,}'.format(actual_monthly_salary)
            penalty_amount = '{:,}'.format(penalty_amount)

            from_date_str = dt.datetime.strftime(first_day, '%Y%m%d')
            to_date_str = dt.datetime.strftime(last_day, '%Y%m%d')

            monthly_salaries.append({
                'date_from':
                from_date_str,
                'date_to':
                to_date_str,
                'salary':
                monthly_salary,
                'penalty_amount':
                penalty_amount,
                'actual_monthly_salary':
                actual_monthly_salary
            })

            master_row = session.query(Master).filter(
                Master.id == master_id).one()
            master_name = master_row.name
            master_phone = master_row.phone

            ret['response'] = {
                'master_name': master_name,
                'master_phone': master_phone,
                'monthly_salary': monthly_salaries
            }

            self.set_status(Response.RESULT_OK)

        except Exception, e:
            session.rollback()

            print_err_detail(e)
            self.set_status(Response.RESULT_SERVERERROR)
            add_err_message_to_response(ret, err_dict['err_mysql'])
    def post(self):
        self.set_header("Content-Type", "application/json")
        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)})
    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 charge(self):
        try:
            print '-' * 40
            print 'charge started'
            current_time = dt.datetime.now()

            print current_time

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

            cron_time = current_time.replace(hour=hour,
                                             minute=minute,
                                             second=0,
                                             microsecond=0)
            print cron_time
            print '-' * 40

            userdao = UserDAO()

            session = Session()
            result = session.query(Booking) \
                                .filter(or_(Booking.cleaning_status == BC.BOOKING_UPCOMMING, Booking.cleaning_status == BC.BOOKING_STARTED)) \
                                .filter(Booking.payment_status == BC.BOOKING_UNPAID_YET) \
                                .filter(func.date(Booking.start_time) == cron_time.date()) \
                                .filter(func.HOUR(Booking.start_time) == cron_time.time().hour) \
                                .filter(func.MINUTE(Booking.start_time) == cron_time.time().minute) \
                                .all()

            for row in result:
                try:
                    # payment
                    booking_id = row.id
                    user_id = row.user_id
                    price = int(row.price_with_task)
                    user_name = userdao.get_user_name(user_id)

                    devicetype = userdao.get_user_device_type(user_id)
                    if devicetype == 'None':  # 안드로이드 사용자만 자동 과금한다
                        continue

                    print booking_id, user_id, price, user_name, 'tried to pay'

                    ret_code, msg = request_payment(
                        user_id, user_name, booking_id, price,
                        row.appointment_type)  # 자동 결제 성공
                    if ret_code:
                        # paid 로 상태 변경이 필요함
                        card_idx = userdao.get_user_default_card_index(user_id)

                        tid = msg
                        row.card_idx = card_idx
                        row.tid = tid
                        row.payment_status = BC.BOOKING_PAID
                        #row.cleaning_status = BC.BOOKING_UPCOMMING
                        row.status = BC.BOOKING_PAID
                        print tid, 'success'
                    else:  # 자동 결제 실패
                        row.payment_status = BC.BOOKING_PAYMENT_FAILED
                        #row.cleaning_status = BC.BOOKING_UPCOMMING
                        row.status == BC.BOOKING_PAYMENT_FAILED
                        print msg, 'failed'

                    session.commit()

                except Exception, e:
                    session.rollback()
                    print_err_detail(e)
                    continue

        except Exception, e:
            session.rollback()
            print_err_detail(e)
Exemplo n.º 22
0
    def get(self):
        self.set_header("Content-Type", "application/json")
        master_id = self.get_argument('master_id', '')
        date_from = self.get_argument('date_from')
        date_to = self.get_argument('date_to')

        ret = {}

        SATURDAY = 5
        CANCELED_RATE = 0.5

        print date_from, date_to

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

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

            result = session.query(Booking, Master, User, UserAddress) \
                            .join(Master, Booking.master_id == Master.id) \
                            .join(User, Booking.user_id == User.id) \
                            .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \
                            .filter(and_(func.date(Booking.start_time) >= date_from, func.date(Booking.start_time) <= date_to)) \
                            .filter(Booking.master_id == master_id) \
                            .filter(or_(Booking.cleaning_status == BC.BOOKING_COMPLETED, \
                            and_(Booking.cleaning_status == BC.BOOKING_CANCELED, \
                            or_(Booking.payment_status == BC.BOOKING_CANCELED_REFUND, \
                            Booking.payment_status == BC.BOOKING_CANCELED_CHARGE)))) \
                            .order_by(Booking.master_id, Booking.start_time) \
                            .all()

            weekly_salary = 0
            salary = {}
            salary_detail = []

            salary['weekly_salary'] = 0

            for row in result:
                if row.Booking.user_id == '81c2f5c1-7295-489d-8bb0-334121060ae3':
                    continue

                user_name = userdao.get_user_name(row.Booking.user_id)
                org_price = row.Booking.price_with_task
                status = row.Booking.cleaning_status
                appointment_index = row.Booking.appointment_index
                appointment_type = row.Booking.appointment_type
                start_time = row.Booking.start_time
                end_time = row.Booking.estimated_end_time
                cleaning_duration = row.Booking.cleaning_duration / 6
                charging_price = row.Booking.charging_price
                is_dirty = row.Booking.is_dirty
                is_b2b = row.User.is_b2b

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

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

                if is_dirty == 1:
                    minutes_for_salary -= 20

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

                extra_charge = 0
                if row.Booking.cleaning_status == BC.BOOKING_COMPLETED:
                    if is_b2b:
                        weekly_salary = int(minutes_for_salary *
                                            (row.Booking.wage_per_hour / 10))
                    else:
                        # 오피스텔 13평 이하, 주택 7평 이하는 시급 14000
                        weekly_salary = 0
                        if start_time >= dt.datetime(2017, 1, 1):
                            weekly_salary = minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR
                        else:
                            if appointment_type in BC.REGULAR_CLEANING_DICT:
                                weekly_salary = minutes_for_salary * BC.SALARY_FOR_REGULAR_IN_HOUR
                            else:
                                weekly_salary = minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR

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

                    extra_charge = bookingdao.get_extra_charge(row.Booking.id)
                    weekly_salary += extra_charge

                    salary['weekly_salary'] += weekly_salary

                elif row.Booking.payment_status == BC.BOOKING_CANCELED_CHARGE or \
                    row.Booking.payment_status == BC.BOOKING_CANCELED_REFUND:
                    weekly_salary = int(charging_price * CANCELED_RATE)

                    salary['weekly_salary'] += weekly_salary

                if weekly_salary > 0:
                    salary_detail.append({
                        'org_price':
                        org_price,
                        'charging_price':
                        charging_price,
                        'salary':
                        weekly_salary,
                        'extra_charge':
                        extra_charge,
                        'status':
                        status,
                        'start_time':
                        dt.datetime.strftime(start_time, '%Y-%m-%d %H:%M'),
                        'end_time':
                        dt.datetime.strftime(end_time, '%Y-%m-%d %H:%M'),
                        'cleaning_index':
                        appointment_index,
                        'user_name':
                        user_name
                    })

                salary['salary_detail'] = salary_detail

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

        except Exception, e:
            session.rollback()

            print_err_detail(e)
            self.set_status(Response.RESULT_SERVERERROR)
            add_err_message_to_response(ret, err_dict['err_mysql'])
    def post(self):
        self.set_header("Content-Type", "application/json")
        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)