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  
    def add_booking(self, order_dict, user_id):
        try:
            session = Session()
            holder = IntermediateValueHolder()

            if not 'lnkKey' in order_dict:
                print 'NO BOOKING ID - lnkKey'
                print '*' * 100
                return

            store_key = order_dict['lnkKey']

            obj = holder.retrieve(store_key)
            if obj == None:
                return [], False

            master_id = obj['master_id']
            dates = obj['dates']
            time = obj['time']
            cleaning_duration = obj['cleaning_duration']

            additional_time = 0
            if 'additional_time' in obj:
                additional_time = obj['additional_time']

            order_id = order_dict['ordNo']
            product_no = order_dict['sellerPrdNo']

            if '_' in product_no:
                product_no = product_no.split('_')
                appointment_type = int(product_no[2])
            else:
                appointment_type = 0

            # field
            request_id = str(uuid.uuid4())
            #appointment_type    = int(product_no[2])
            message = order_dict[
                'rsvEtcInfo5'] if 'rsvEtcInfo5' in order_dict else ''
            trash_location = '%s %s' % (order_dict['rsvEtcInfo1'],
                                        order_dict['rsvEtcInfo2'])
            havepet = 0 if order_dict['rsvEtcInfo3'] == '아니오' else 1
            card_idx = -1
            addr_idx = 0

            options = order_dict['RsvDtlsInfo']
            print options
            options_price = sum([int(opt['optAmt']) for opt in options[1:]])
            options_name = [opt['optNm'] for opt in options[1:]]

            additional_task = 0

            if options_name != [None]:
                for opt in options_name:
                    if '창문' in opt:
                        additional_task += 1
                    elif '베란다' in opt:
                        additional_task += 2
                    elif '빨래' in opt:
                        additional_task += 4
                    elif '옷장' in opt:
                        additional_task += 8
                    elif '단문형' in opt:
                        additional_task += 16
                    elif '양문형' in opt:
                        additional_task += 32

            actual_price = int(order_dict['rsvAmt'])
            price = actual_price - options_price

            now = dt.datetime.strftime(dt.datetime.now(), '%Y%m%d%H%M%S')
            hashids = Hashids(min_length=16, salt=now + user_id)

            booking_ids = []
            index = 1

            for date in dates:  #
                print date, time
                if index == 1:
                    booking_id = store_key
                else:
                    booking_id = hashids.encode(
                        int(date + time.replace(':', '')))

                print 'key', booking_id

                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=cleaning_duration + additional_time)

                if index != 1:
                    actual_price = price
                    additional_task = 0
                    estimated_end_time -= dt.timedelta(minutes=additional_time)

                booking = Booking(
                    id=booking_id,
                    request_id=request_id,
                    user_id=user_id,
                    master_id=master_id,
                    appointment_type=appointment_type,
                    appointment_index=index,
                    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,
                    message=message,
                    trash_location=trash_location,
                    havepet=havepet,
                    laundry_apply_all=0,
                    is_dirty=0,
                    master_gender=0,
                    source='11st',
                    status=BC.BOOKING_UPCOMMING,
                    cleaning_status=BC.BOOKING_UPCOMMING,
                    payment_status=BC.BOOKING_PAID)

                session.add(booking)
                index += 1

                booking_ids.append(booking_id)

            # remove store_key and related_keys
            store_key = obj['store_key']
            search_keys = obj['search_keys'].split(',')

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

            # order_11st에 order_id 추가 필요.
            print order_id
            order = Order11st(order_id=order_id)
            session.add(order)
            session.commit()
        except Exception, e:
            print_err_detail(e)
Пример #3
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
    def add_new_appointment(self, request_id, master_id, user_id,
                            appointment_type, appointment_index, booking_time,
                            start_time, estimated_end_time, cleaning_duration,
                            additional_task, price, price_with_task, card_idx,
                            addr_idx, message, trash_location, enterhome,
                            enterbuilding, routing_method, havetools, havepet,
                            laundry_apply_all, is_dirty, master_gender,
                            wage_per_hour, source, user_type):
        try:
            session = Session()
            now = dt.datetime.strftime(dt.datetime.now(), '%Y%m%d%H%M%S')
            hashids = Hashids(min_length=16, salt=user_id + now)
            booking_id = hashids.encode(
                int(dt.datetime.strftime(start_time, '%Y%m%d%H%M')))
            dow = start_time.date().weekday()

            booking = Booking(
                id=booking_id,
                request_id=request_id,
                user_id=user_id,
                master_id=master_id,
                appointment_type=appointment_type,
                appointment_index=appointment_index,
                dow=dow,
                booking_time=booking_time,
                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=price_with_task,
                charging_price=0,
                card_idx=card_idx,
                addr_idx=addr_idx,
                message=message,
                trash_location=trash_location,
                enterhome=enterhome,
                enterbuilding=enterbuilding,
                routing_method=routing_method,
                havetools=havetools,
                havepet=havepet,
                laundry_apply_all=laundry_apply_all,
                is_dirty=is_dirty,
                master_gender=master_gender,
                source=source,
                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)

            session.add(booking)
            session.commit()

            print booking_id, 'was successfully added for user :'******'by cron job at', dt.datetime.now(
            )
        except Exception, e:
            session.rollback()
            print_err_detail(e)
            raise Exception(e)
    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  
Пример #6
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