def get(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') master_id = self.get_argument('master_id', '') print 'master_id : ' + master_id ret = {} try: session = Session() master_notices = [] try: result = session.query(Master) \ .filter(Master.id == master_id) \ .filter(Master.active == 1) \ .one() except NoResultFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, '등록되지 않은 마스터 입니다.') return except MultipleResultsFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, '마스터가 중복 되어 있습니다.') return
def post(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') user_id = self.get_argument('id', '') tid = self.get_argument('tid', '') amount = self.get_argument('amount', 0) partial = self.get_argument('partial', 1) cancel_msg = self.get_argument('cancel_msg', '') amount = int(amount) if cancel_msg == '': cancel_msg = '취소' ret = {} try: mongo_logger = get_mongo_logger() mix = get_mixpanel() userdao = UserDAO() request_url = '%s:%d/homemaster_payment/cancel_payment' % ( PAYMENT_HOST, PAYMENT_PORT) params = {} params['id'] = user_id params['tid'] = tid params['amount'] = amount params['partial'] = partial params['cancel_msg'] = cancel_msg response = requests.post(request_url, data=params) result = json.loads(response.text) if response.status_code == 200 and result['response'] != "": mix.track(user_id, 'cancel payment', {'time': dt.datetime.now()}) mongo_logger.debug('cancel payment', extra={'user_id': user_id}) ret['response'] = result['response'] self.set_status(Response.RESULT_OK) else: print 'An error occurred while register card' print result['err_msg'] add_err_ko_message_to_response(ret, result['err_msg']) mix.track(user_id, 'cannot cancel payment', {'time': dt.datetime.now()}) mongo_logger.error('failed to cancel payment', extra={'user_id': user_id}) except Exception, e: print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
def post(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') ret = {} UNUSED = 0 USED = 1 OCCUPIED = 2 promotion_code = self.get_argument('promotion_code', '') try: session = Session() if promotion_code in PROMOTION_CODES: # 특별 할인 코드 discount_price = 0 now = dt.datetime.now() print promotion_code, now event_row = session.query(EventPromotion).filter(EventPromotion.code == promotion_code).one() if event_row.count <= 0: self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, '이벤트 할인코드가 전부 사용되었습니다.') return if now >= event_row.expires: self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, '이벤트 할인코드 사용기간이 만료되었습니다.') return else: discount_price = event_row.amount event_row.count -= 1 session.commit() ret['response'] = {'discount_price' : discount_price} return try: row = session.query(Promotion).filter(Promotion.promotion_code == promotion_code).one() except NoResultFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_no_used_promotion']) return except MultipleResultsFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_multiple_record']) return
def post(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') master_id = self.get_argument('master_id', '') off_date = self.get_argument('off_date', '') # 20160603 master_date_key = '{0}_{1}'.format(master_id, off_date) off_date = dt.datetime.strptime(off_date, '%Y%m%d') ret = {} try: session = Session() masterdao = MasterDAO() # add request logs # type : 1 - request, 0 - cancel day_off_request = MasterDayoffRequest( master_id=master_id, date=off_date, type=0, request_time=dt.datetime.now()) session.add(day_off_request) # master schedules by date active -> 0 row = session.query(MasterScheduleByDate) \ .filter(MasterScheduleByDate.master_id == master_id) \ .filter(MasterScheduleByDate.date == off_date) \ .one() row.active = 1 # commit session.commit() master_name = masterdao.get_master_name(master_id) send_jandi('HOMEMASTER_REST', "휴무 신청 취소", master_name + ' 홈마스터님 휴무 신청 취소', '휴무 취소 날짜 : {}'.format(off_date)) ret['response'] = Response.SUCCESS self.set_status(Response.RESULT_OK) print 'master_id', master_id, 'cancel dayoff request', off_date except NoResultFound, e: self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, '휴무 신청 취소 가능 날짜가 아닙니다.') return
def post(self): ret = {} user_id = self.get_argument('user_id', '') index = self.get_argument('index', 0) index = int(index) print user_id, index self.set_header("Content-Type", "application/json") mongo_logger = get_mongo_logger() mix = get_mixpanel() try: session = Session() try: default_index = session.query(UserDefaultAddress) \ .filter(UserDefaultAddress.user_id == user_id) \ .one() # 기본 주소이면 삭제 안되도록 함 if default_index.address_idx == index: print 'default index' session.close() self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, '기본 주소는 삭제 하실 수 없습니다.') return except NoResultFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_no_record']) print_err_detail(e) return except MultipleResultsFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_multiple_record']) print_err_detail(e) return
def post(self): self.set_header("Content-Type", "application/json") uid = self.get_argument('uid', '') price = self.get_argument('price', '') ret = {} try: mongo_logger = get_mongo_logger() mix = get_mixpanel() userdao = UserDAO() request_url = '%s:%d/homemaster_payment/request_payment' % (PAYMENT_HOST, PAYMENT_PORT) params = {} params['id'] = uid params['name'] = userdao.get_user_name(uid) params['price'] = price params['product_name'] = 'moving' response = requests.post(request_url, data = params) result = json.loads(response.text) if response.status_code == 200 and result['response'] == "SUCCESS": mix.track(uid, 'request mc payment', {'time' : dt.datetime.now(), 'tid' : result['tid'], 'authdate' : result['authdate']}) mongo_logger.debug('%s request mc payment' % uid, extra = {'user_id' : uid, 'tid' : result['tid'], 'authdate' : result['authdate']}) ret['response'] = result['response'] self.set_status(Response.RESULT_OK) else: print 'An error occurred when paying moving clean' print result['err_code'], result['err_msg'] add_err_ko_message_to_response(ret, result['err_msg']) mix.track(uid, 'cannot request mc payment', {'time' : dt.datetime.now(), 'code' : result['err_code']}) mongo_logger.error('%s failed to request mc payment' % uid, extra = {'err' : result['err_msg']}) except Exception, e: print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
def is_user_block(self, ret, uid): try: mongo_logger = get_mongo_logger() userdao = UserDAO() session = Session() result = session.query(User) \ .filter(User.id == uid) \ .one() key = userdao.get_user_salt_by_id(result.id)[:16] crypto = aes.MyCrypto(key) phone = crypto.decodeAES(result.phone) row = session.query(BlockUser, User) \ .join(User, User.id == BlockUser.user_id) \ .filter(func.aes_decrypt(func.from_base64(User.phone), func.substring(User.salt, 1, 16)) == phone) \ .all() print row session.close() if len(row) > 0: self.set_status(Response.RESULT_OK) add_err_ko_message_to_response( ret, '현재 주문량이 많아 신규 예약이 불가능 합니다. 확실한 서비스 품질을 보증을 위해 바로 서비스를 제공해 드릴 수 없는 점 양해 부탁드립니다.' ) mongo_logger.debug('block user', extra={'user_id': uid}) ret['err_code'] = '4037' # 임시 처리 return True return False except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql']) return True
def post(self): self.set_header("Content-Type", "application/json") ret = {} master_id = self.get_argument('master_id', '') account_no = self.get_argument('account_no', '') bank_name = self.get_argument('bank_name', '') try: session = Session() if not bank_name in bank_dict.keys(): self.set_status(Response.RESULT_OK) add_err_ko_message_to_response( ret, bank_name + '은(는) 지원하지 않는 은행입니다.') return bank_dict = BC.bank_dict account_no = account_no.replace('-', '') account = MasterAccount(master_id=master_id, account_no=account_no, bank_code=bank_dict[bank_name], bank_name=bank_name, datetime=dt.datetime.now()) session.add(account) session.commit() print master_id, ' has successfully add account!' ret['response'] = Response.SUCCESS self.set_status(Response.RESULT_OK) except NoResultFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_no_record']) return
def get(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') uid = self.get_argument('user_id', '') ret = {} print uid print PAYMENT_HOST, PAYMENT_PORT try: mongo_logger = get_mongo_logger() mix = get_mixpanel() userdao = UserDAO() request_url = '%s:%d/homemaster_payment/get_cards' % (PAYMENT_HOST, PAYMENT_PORT) params = {} params['id'] = uid response = requests.get(request_url, params=params) print response result = json.loads(response.text) print result if response.status_code == 200 and result['response'] != "": ret['response'] = result['response'] self.set_status(Response.RESULT_OK) else: print 'An error occurred while get card info' add_err_ko_message_to_response(ret, '카드정보 읽기 실패') except Exception, e: print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
class ManualUnpaidChargeHandler(tornado.web.RequestHandler): def post(self): self.set_header("Content-Type", "application/json") user_id = self.get_argument('user_id', '') amount = self.get_argument('amount', '') interest = self.get_argument('interest', '0') quota = self.get_argument('quota', '00') amount = int(amount) ret = {} try: session = Session() try: row = session.query(User) \ .filter(User.id == user_id) \ .one() except NoResultFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_login_no_record']) return except MultipleResultsFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_multiple_record']) return userdao = UserDAO() user_id = row.id key = userdao.get_user_salt_by_id(user_id)[:16] crypto = aes.MyCrypto(key) user_name = crypto.decodeAES(row.name) ret_code, value = request_unpaid_charge(user_id, user_name, amount, interest, quota) if ret_code == True: ret['response'] = Response.SUCCESS else: add_err_ko_message_to_response(ret, value) self.set_status(Response.RESULT_OK)
def post(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') ret = {} user_id = self.get_argument('user_id', '') booking_id = self.get_argument('booking_id', '') coupon_id = self.get_argument('coupon_id', '') mongo_logger = get_mongo_logger() now = dt.datetime.now() try: session = Session() count = session.query(UserCoupon) \ .filter(UserCoupon.booking_id == booking_id) \ .count() if count > 0: self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, '이미 쿠폰이 적용된 예약 입니다.') return row = session.query(UserCoupon) \ .filter(UserCoupon.user_id == user_id) \ .filter(UserCoupon.id == coupon_id) \ .one() if row.expire_date <= now: self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, '사용 기한이 만료된 쿠폰 입니다.') return if row.used != 0: self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, '이미 사용한 쿠폰 입니다.') return ret['response'] = row.discount_price self.set_status(Response.RESULT_OK) mongo_logger.debug('apply user coupon', extra = {'user_id' : user_id, 'booking_id' : booking_id }) except Exception, e: session.rollback() add_err_message_to_response(ret, err_dict['err_mysql']) self.set_status(Response.RESULT_SERVERERROR) print_err_detail(e) mongo_logger.error('failed to apply user coupon', extra = {'user_id' : user_id, 'booking_id' : booking_id, 'err' : str(e)})
class ChargeHandler(tornado.web.RequestHandler): def post(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') booking_id = self.get_argument('booking_id', '') price = self.get_argument('price', '') product_name = self.get_argument('product_name', '') price = int(price) ret = {} try: session = Session() try: row = session.query(Booking, User) \ .join(User, Booking.user_id == User.id) \ .filter(Booking.id == booking_id) \ .one() except NoResultFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_login_no_record']) return except MultipleResultsFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_multiple_record']) return userdao = UserDAO() user_id = row.User.id key = userdao.get_user_salt_by_id(user_id)[:16] crypto = aes.MyCrypto(key) user_name = crypto.decodeAES(row.User.name) appointment_type = row.Booking.appointment_type if row.User.devicetype == 'None': ret_code = False add_err_ko_message_to_response(ret, '카드 등록 고객 아님') return else: ret_code, value = request_payment(user_id, user_name, booking_id, price, appointment_type) if ret_code == True: row.Booking.tid = value row.Booking.status = BC.BOOKING_PAID row.Booking.payment_status = BC.BOOKING_PAID session.commit() ret['response'] = Response.SUCCESS else: add_err_ko_message_to_response(ret, value) self.set_status(Response.RESULT_OK)
def post(self): self.set_header("Content-Type", "application/json") ret = {} booking_id = self.get_argument('booking_id', '') additional_task = self.get_argument('additional_task', '') new_price = self.get_argument('new_price', 0) total_taking_time = self.get_argument('total_taking_time', '') laundry_apply_all = self.get_argument( 'laundry_apply_all', 0) # -2 - 전체없앰 -1 - 하나 없앰, 0 - one time, 1 - all time # convert parameter new_price = int(new_price) additional_task = int(additional_task) total_taking_time = int(total_taking_time) total_taking_time_in_minutes = total_taking_time * 6 laundry_apply_all = int(laundry_apply_all) print 'update additional task params' print booking_id print additional_task print new_price print total_taking_time print laundry_apply_all mix = get_mixpanel() mongo_logger = get_mongo_logger() try: print 'total_minutes :', total_taking_time_in_minutes if total_taking_time_in_minutes >= 720: self.set_status(Response.RESULT_OK) add_err_ko_message_to_response( ret, '클리닝 가능 시간을 초과하였습니다. (최대 12시간) 이전 화면으로 돌아가 추가사항을 2개이하로 줄여주세요.' ) return session = Session() masterdao = MasterDAO() userdao = UserDAO() holder = IntermediateValueHolder() row = session.query(Booking).filter(Booking.id == booking_id).one() uid = row.user_id start_time = row.start_time end_time = row.estimated_end_time request_id = row.request_id appointment_index = row.appointment_index appointment_type = row.appointment_type payment_status = row.payment_status price_with_task = row.price_with_task isdirty = row.is_dirty if isdirty == 1: total_taking_time_in_minutes += 120 org_taking_time_in_minutes = time_to_minutes( timedelta_to_time(end_time - start_time)) is_event = session.query(UserFreeEvent) \ .filter(UserFreeEvent.booking_request_id == request_id) \ .first() is_event = True if is_event != None else False user_name = userdao.get_user_name(uid) # 추가 업무로 인해 소요된 시간이 더 크다면 앞 뒤 일정을 고려. # 고려해서 이동이 가능하다면 추가 업무 할당함. if total_taking_time_in_minutes > org_taking_time_in_minutes: print '2' master_id, time = masterdao.get_masterid_and_starttime_from_booking( booking_id) search_key = '%s_%d' % (master_id, time) new_estimated_end_time = masterdao.is_schedule_extend_available( booking_id, total_taking_time_in_minutes) if new_estimated_end_time != None and holder.store( search_key, 1): # 변경이 가능함. if payment_status == BC.BOOKING_PAID: # 미리 지불한 경우는 취소 하고 다시 결제함 # 전거래 취소 및 재결제 if not (is_event and appointment_index == 1): print 'in this case' cancel_ret_code, msg = cancel_payment( uid, booking_id, price_with_task, partial='0') if cancel_ret_code: pay_ret_code, pay_msg = request_payment( uid, user_name, booking_id, new_price, appointment_type, status='UPDATED') if pay_ret_code: row.tid = pay_msg row.payment_status = BC.BOOKING_PAID else: row.payment_status = BC.BOOKING_PAYMENT_FAILED session.commit() session.close() self.set_status(Response.RESULT_OK) add_err_ko_message_to_response( ret, pay_msg) return else: # 정기 1회 이벤트 일 때 print 'hahaha' charge_amount = new_price - row.price print charge_amount if row.price_with_task != row.price: # 다르면 charge_amount = new_price - row.price_with_task pay_ret_code, pay_msg = request_payment( uid, user_name, booking_id, charge_amount, appointment_type, status='UPDATED') if pay_ret_code: row.tid = pay_msg row.payment_status = BC.BOOKING_PAID else: row.payment_status = BC.BOOKING_PAYMENT_FAILED session.commit() session.close() self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, pay_msg) return row.estimated_end_time = new_estimated_end_time row.additional_task = additional_task row.price_with_task = new_price row.laundry_apply_all = laundry_apply_all session.commit() holder.remove(search_key) else: print '3' session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response( ret, err_dict['err_hm_have_next_schedule']) # 메모리에서 삭제 holder.remove(search_key) return else: # 같거나 작은 경우는 바로 변경 print '4' if payment_status == BC.BOOKING_PAID: # 미리 지불한 경우는 취소 하고 다시 결제함 # 전거래 취소 및 재결제 if not (is_event and appointment_index == 1): cancel_ret_code, msg = cancel_payment(uid, booking_id, price_with_task, partial='0') if cancel_ret_code: user_name = userdao.get_user_name(uid) pay_ret_code, pay_msg = request_payment( uid, user_name, booking_id, new_price, appointment_type, status='UPDATED') if pay_ret_code: row.tid = pay_msg row.payment_status = BC.BOOKING_PAID else: row.payment_status = BC.BOOKING_PAYMENT_FAILED session.commit() session.close() self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, pay_msg) return else: if row.price_with_task != row.price: # 다르면 charge_amount = row.price_with_task - new_price cancel_payment(uid, booking_id, charge_amount, partial='0') row.additional_task = additional_task row.estimated_end_time = end_time + dt.timedelta( minutes=total_taking_time_in_minutes - org_taking_time_in_minutes) row.price_with_task = new_price row.laundry_apply_all = laundry_apply_all # 빨래의 경우는 시간 변경이 없으므로 마지막에 바로 적용 # about laundry print '5' all_upcoming_bookings = session.query(Booking) \ .filter(Booking.request_id == request_id) \ .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \ .filter(Booking.appointment_index >= appointment_index) \ .all() if laundry_apply_all == 1: # 전체 선택 for booking in all_upcoming_bookings: bits = "{0:07b}".format(booking.additional_task) if bits[4] == '0': # 빨래가 세팅되어 있다면 booking.additional_task += 4 # 빨래 booking.laundry_apply_all = laundry_apply_all elif laundry_apply_all == -2: # 선택 해제 for booking in all_upcoming_bookings: bits = "{0:07b}".format(booking.additional_task) if bits[4] == '1': # 빨래가 세팅되어 있다면 booking.additional_task -= 4 # 빨래 제거 booking.laundry_apply_all = laundry_apply_all print '6' session.commit() # alim talk user_name = userdao.get_user_name(uid) additional_task_str = additional_task_string(additional_task) #for manager_phone in MANAGERS_CALL.split(','): # send_alimtalk(manager_phone, 'noti_manager_modify_task', user_name, additional_task_str) # log to mixpanel mix.track( uid, 'update additional task', { 'time': dt.datetime.now(), 'booking_id': booking_id, 'additional_task': additional_task, 'new_price': new_price, 'total_taking_time': total_taking_time, 'laundry_apply_all': laundry_apply_all }) # log to mongo mongo_logger.debug('update additional task', extra={ 'user_id': uid, 'booking_id': booking_id, 'additional_task': additional_task, 'new_price': new_price, 'total_taking_time': total_taking_time, 'laundry_apply_all': laundry_apply_all }) ret['response'] = Response.SUCCESS self.set_status(Response.RESULT_OK) except NoResultFound, e: print_err_detail(e) session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_no_record']) return
if row.User.devicetype == 'None': try: record = UserPaymentRecordForIOS(booking_id, user_id, price, dt.datetime.now()) session.add(record) session.commit() ret_code = True except Exception, e: ret_code = False value = str(e) else: ret_code, value = request_payment(user_id, user_name, booking_id, price, appointment_type, 'CHARGED') if ret_code == True: ret['response'] = Response.SUCCESS else: add_err_ko_message_to_response(ret, value) self.set_status(Response.RESULT_OK) except Exception, e: print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql']) finally: session.close() self.write(json.dumps(ret))
def post(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') booking_id = self.get_argument('booking_id', '') reason_id = self.get_argument('reason_id', CANCEL_ADMIN) etc_reason = self.get_argument('etc_reason', '') charge_amount = self.get_argument('charge_amount', 0) no_fee = self.get_argument('no_fee', 0) regular_cancel_charge = self.get_argument('regular_cancel_charge', 0) charge_amount = int(charge_amount) reason_id = int(reason_id) no_fee = int(no_fee) regular_cancel_charge = int(regular_cancel_charge) print 'cancel all charge amount : ', charge_amount print 'reason_id : ', reason_id print 'etc_reason : ', etc_reason ret = {} mongo_logger = get_mongo_logger() mix = get_mixpanel() try: session = Session() userdao = UserDAO() masterdao = MasterDAO() stmt = session.query(Booking.request_id).filter( Booking.id == booking_id).subquery() first_startime = session.query(Booking.start_time).filter( Booking.request_id == stmt).order_by( Booking.start_time).first()[0] result = session.query(Booking, Master, User, UserAddress) \ .join(Master, Booking.master_id == Master.id) \ .join(User, Booking.user_id == User.id) \ .join(UserDefaultAddress, User.id == UserDefaultAddress.user_id) \ .join(UserAddress, and_(UserAddress.user_id == UserDefaultAddress.user_id, UserAddress.user_addr_index == UserDefaultAddress.address_idx)) \ .filter(Booking.request_id == stmt) \ .filter(or_(Booking.cleaning_status == BC.BOOKING_UPCOMMING, Booking.cleaning_status == BC.BOOKING_STARTED, Booking.cleaning_status == BC.BOOKING_COMPLETED)) \ .all() # 서비스를 처음 이용한지 2달이 넘었는지 아닌지 조사, # 넘지 않았다면 이미 부과된 금액에 대해서도 1회 서비스 금액 과의 차액만큼 부과됨 current_time = dt.datetime.now() completed_charge = 1 if current_time >= first_startime + dt.timedelta(days=57): completed_charge = 0 cancel_all_charge = 0 # 그동안의 모든 예약에 대해서 처리함 for row in result: charge = 0 new_status = BC.BOOKING_CANCELED_CHARGE key = userdao.get_user_salt_by_id(row.User.id)[:16] crypto = aes.MyCrypto(key) username = str(crypto.decodeAES(row.User.name)) request_id = row.Booking.request_id appointment_index = row.Booking.appointment_index bid = row.Booking.id user_id = row.Booking.user_id appointment_time = row.Booking.start_time current_status = row.Booking.status current_cleaning_status = row.Booking.cleaning_status current_payment_status = row.Booking.payment_status price = row.Booking.price_with_task source = row.Booking.source appointment_type = row.Booking.appointment_type diff_in_hours = (appointment_time - current_time).total_seconds() / 3600 if diff_in_hours >= 24: charge = price * BC.BOOKING_CHARGE_RATE_NO elif 4 <= diff_in_hours < 24: charge = price * BC.BOOKING_CHARGE_RATE_30 else: charge = price * BC.BOOKING_CHARGE_RATE_50 # 이미 지불한 금액에 대해 1회 비용의 차액만큼 계산 if completed_charge == 1: if current_cleaning_status == BC.BOOKING_COMPLETED: # 차액만큼 계속 더함 _, house_size, house_type = userdao.get_user_address_detail_by_index( user_id, row.Booking.addr_idx) time_prices = get_basic_time_price( house_type, house_size) try: print time_prices[0]['price'] print time_prices[appointment_type]['price'] charge_amount = int( time_prices[0]['price'] - time_prices[appointment_type]['price']) except Exception: charge_amount = 3000 cancel_all_charge += charge_amount # event is_event = session.query(UserFreeEvent) \ .filter(UserFreeEvent.booking_request_id == request_id) \ .first() is_event = True if is_event != None else False if is_event == True and appointment_index == 1: partial = '0' cancel_amount = row.Booking.price_with_task - row.Booking.price cancel_payment(user_id, bid, cancel_amount, partial) # 취소에 대한 결제 필요 # 8회 이상 썼다면(완료카운트 9회 미만일 경우 결제) complete_count = session.query(Booking) \ .filter(Booking.request_id == request_id) \ .filter(Booking.cleaning_status == 2) \ .count() if complete_count < 9 and row.Booking.cleaning_status == 2: ret_code, msg = request_payment( user_id, username, booking_id, price, appointment_type) if ret_code == False: row.Booking.payment_status = BC.BOOKING_PAYMENT_FAILED if current_payment_status == BC.BOOKING_PAID and current_cleaning_status == BC.BOOKING_UPCOMMING: if no_fee == 1: charge = 0 new_status = BC.BOOKING_CANCELED_REFUND partial = '1' if charge == 0: partial = '0' cancel_amount = int(price - charge) if cancel_amount > 0 and source == 'hm' and userdao.get_user_default_card_index( user_id) != -1: if not (is_event and appointment_index == 1): ret_code, msg = cancel_payment( user_id, bid, cancel_amount, partial) if ret_code == False: session.close() self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, msg) #self.write(json.dumps(ret)) return elif current_payment_status == BC.BOOKING_UNPAID_YET and current_cleaning_status == BC.BOOKING_UPCOMMING: print 'cancel charge' charging_price = int(charge) if charging_price > 0 and source == 'hm' and userdao.get_user_default_card_index( user_id) != -1 and no_fee == 0: print user_id, username, booking_id, charging_price, appointment_type ret_code, msg = request_payment( user_id, username, bid, charging_price, appointment_type) if ret_code == False: new_status = BC.BOOKING_PAYMENT_FAILED #row.Booking.modified_date = current_time if current_cleaning_status == BC.BOOKING_UPCOMMING: row.Booking.charging_price = int(charge) row.Booking.status = new_status row.Booking.cleaning_status = BC.BOOKING_CANCELED row.Booking.payment_status = new_status # add cancel reason CANCEL_ALL = 1 reason = session.query(CancelReason).filter( CancelReason.booking_id == bid) if reason.count() == 0: cancel_reason = CancelReason(booking_id=bid, user_id=user_id, reason_id=reason_id, etc_reason=etc_reason, kind=CANCEL_ALL, cancel_time=dt.datetime.now()) session.add(cancel_reason) else: try: reason_row = reason.one() reason_row.kind = 1 except Exception, e: print e # 수수료 임시 처리 막기 #cancel_all_charge = 0 if cancel_all_charge > 0 and source == 'hm' and regular_cancel_charge == 0: user_name = userdao.get_user_name(user_id) ret_code, msg = request_charge(user_id, user_name, cancel_all_charge) if ret_code == False: session.close() self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, msg) self.write(json.dumps(ret)) return if row != None: key = userdao.get_user_salt_by_id(row.User.id)[:16] crypto = aes.MyCrypto(key) # push to homemaster via sms master_id = row.Master.id master_phone = str(row.Master.phone) master_name = str(row.Master.name) username = str(crypto.decodeAES(row.User.name)) userphone = str(crypto.decodeAES(row.User.phone)) date = str(convert_datetime_format(row.Booking.start_time)) addr = str(crypto.decodeAES(row.UserAddress.address)) appointment_type = str(row.Booking.appointment_type) print 'app _type' print appointment_type appointment_type_text = '' if appointment_type == BC.ONE_TIME or appointment_type == BC.ONE_TIME_BUT_CONSIDERING: appointment_type_text = '1회' elif appointment_type == BC.FOUR_TIME_A_MONTH: appointment_type_text = '매주' elif appointment_type == BC.TWO_TIME_A_MONTH: appointment_type_text = '2주 1회' elif appointment_type == BC.ONE_TIME_A_MONTH: appointment_type_text = '4주 1회' #sms_sender = SMS_Sender() #text = BOOKING_CANCEL_ALL_TEXT % (appointment_type, username, userphone, master_name, date) #send_result = sms_sender.send_for_manager(sender = MAIN_CALL, mtype = 'sms', to = MANAGERS_CALL, subject = BOOKING_TEXT_SUBJECT, text = text) #for manager_phone in MANAGERS_CALL.split(','): # send_alimtalk(manager_phone, 'noti_manager_cancel_all', username, date, appointment_type_text) cancel_all_reasons = [] cancel_all_reasons.append('너무 비싸요') cancel_all_reasons.append('제가 여행을 가요') cancel_all_reasons.append('청소품질이 마음에 들지 않아요') cancel_all_reasons.append('필요할 때에만 서비스를 이용하고 싶어요') cancel_all_reasons.append('다른 업체로 바꿀래요') cancel_all_reasons.append('원하던 홈마스터가 오질 않아요') cancel_all_reasons.append('저 이사가요') cancel_all_reasons.append('기타') cancel_all_reasons.append('관리자가 취소 했습니다') cancel_reason = cancel_all_reasons[reason_id] if cancel_reason == '기타': cancel_reason += ' ' + etc_reason elif reason_id == CANCEL_ADMIN: cancel_reason += ', 관리자 메모 : ' + etc_reason send_jandi( 'NEW_BOOKING', "전체 취소 알림", username + ' 고객님 전체 취소함', '{}, {} 사유 : {}'.format(date, appointment_type_text, cancel_reason)) print 'jandi notification for cancel all...' master_pushkey = masterdao.get_master_pushkey(master_id) send_all_bookings_canceled('android', [master_pushkey], booking_id, date, username) master_phone = masterdao.get_master_phone(master_id) master_name = masterdao.get_master_name(master_id) user_name = userdao.get_user_name(user_id) content = '''{} 홈마스터님 정기 고객의 예약이 전체 취소 되었습니다. 고객 : {} 주기 : {}'''.format(master_name, user_name, appointment_type_text) print 'text' print appointment_type_text message_sender = MessageSender() message_sender.send([master_phone], '예약 전체 취소 알림', content) #send_alimtalk(master_phone, 'noti_manager_cancel_all', username, date, appointment_type_text) coupondao = CouponDAO() coupondao.cancelall_coupon_usage(booking_id) session.commit() mix.track( user_id, 'cancel all', { 'time': dt.datetime.now(), 'reason_id': reason_id, 'etc_reason': etc_reason }) mongo_logger.debug('%s was all canceled' % booking_id, extra={ 'user_id': user_id, 'booking_id': booking_id }) ret['response'] = Response.SUCCESS self.set_status(Response.RESULT_OK)
def get(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') ret = {} user_id = self.get_argument('user_id', '') mongo_logger = get_mongo_logger() now = dt.datetime.now() try: session = Session() userdao = UserDAO() try: result = session.query(User) \ .filter(User.id == user_id) \ .one() except NoResultFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, '등록되지 않은 고객 입니다.') return key = userdao.get_user_salt(result.email)[:16] crypto = aes.MyCrypto(key) name = crypto.decodeAES(result.name) user_coupons = {} user_coupons['user_name'] = name results = session.query(UserCoupon) \ .filter(UserCoupon.user_id == user_id) \ .order_by(UserCoupon.expire_date) \ .all() print "request user coupon sql query for adminweb" coupons = [] for result in results: user_coupon = {} user_coupon['issue_date'] = dt.datetime.strftime( result.issue_date, '%Y.%m.%d') user_coupon['expire_date'] = dt.datetime.strftime( result.expire_date, '%Y.%m.%d') user_coupon['discount_price'] = result.discount_price user_coupon['used'] = 1 if result.used == 1 else 0 user_coupon['is_expired'] = 1 if result.expire_date.date( ) <= now.date() else 0 user_coupon['title'] = result.title user_coupon[ 'booking_id'] = '' if result.booking_id == None else result.booking_id coupons.append(user_coupon) user_coupons['coupons'] = coupons ret['response'] = user_coupons self.set_status(Response.RESULT_OK) mongo_logger.debug('request user coupon for adminweb', extra={'user_id': user_id})
def post(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') ret = {} booking_id = self.get_argument('booking_id', '') amount = self.get_argument('amount', '') amount = int(amount) try: session = Session() userdao = UserDAO() count = session.query(Promotion) \ .filter(Promotion.booking_id == booking_id) \ .count() if count > 0: self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, '이미 할인이 적용된 예약입니다.') return row = session.query(Promotion) \ .filter(Promotion.used == 0) \ .filter(Promotion.discount_price == amount) \ .filter(Promotion.source == 'hm') \ .first() booking_row = session.query(Booking) \ .filter(Booking.id == booking_id) \ .one() if row == None: self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, '해당 쿠폰이 존재하지 않습니다.') return if booking_row.payment_status != 0: self.set_status(Response.RESULT_OK) add_err_ko_message_to_response( ret, '결제되지 않은 예약에 대해서만 할인 적용이 가능합니다.') return if booking_row.cleaning_status != 0: self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, '다가오는 클리닝만 할일 적용이 가능합니다.') return row.booking_id = booking_id row.used = 1 row.service_price = booking_row.price_with_task row.used_datetime = dt.datetime.now() if amount <= 100: discount_price = int(booking_row.price_with_task * float(amount) / 100) booking_row.price_with_task -= discount_price else: booking_row.price_with_task -= amount session.commit() ret['response'] = Response.SUCCESS self.set_status(Response.RESULT_OK) except Exception, e: session.rollback() add_err_message_to_response(ret, err_dict['err_mysql']) self.set_status(Response.RESULT_SERVERERROR) print_err_detail(e)
class EditBookingHandler(tornado.web.RequestHandler): def post(self): self.set_header("Content-Type", "application/json") booking_id = self.get_argument('booking_id', '') changed = self.get_argument('ischange', '') date = self.get_argument('date', dt.datetime.now()) start_time_range_begin = self.get_argument('range_begin', BC.START_TIME_RANGE_BEGIN) start_time_range_begin_min = self.get_argument('range_begin_min', 0) start_time_range_end = self.get_argument('range_end', BC.START_TIME_RANGE_END) start_time_range_end_min = self.get_argument('range_end_min', 0) price = self.get_argument('price', 0) taking_time = self.get_argument('taking_time', 25) additional_task = self.get_argument('additional_task', 0) message = self.get_argument('msg', '') laundry_apply_all = self.get_argument( 'laundry_apply_all', 0) # -1 - 없앰, 0 - one time, 1 - all time print 'edit booking params....' print booking_id, changed, date, additional_task, taking_time, price # convert datetime price = int(price) taking_time = int(taking_time) additional_task = int(additional_task) taking_time_in_minutes = taking_time * 6 laundry_apply_all = int(laundry_apply_all) changed = "{0:03b}".format(int(changed)) mongo_logger = get_mongo_logger() mongo_logger.debug('%s was called to updated' % booking_id, extra={ 'changed': changed, 'date': date, 'start_time_range_begin': start_time_range_begin, 'start_time_range_end': start_time_range_end, 'price': price, 'taking_time': taking_time, 'additional_task': additional_task, 'user_message': message }) ret = {} mix = get_mixpanel() try: session = Session() userdao = UserDAO() addrdao = AddressDAO() masterdao = MasterDAO() try: row = session.query(Booking).filter( Booking.id == booking_id).one() except NoResultFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_no_record']) return except MultipleResultsFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_multiple_record']) return uid = row.user_id price_with_task = row.price_with_task appointment_type = row.appointment_type org_master_id = row.master_id holder = IntermediateValueHolder() org_date = dt.datetime.strftime(row.start_time, '%m월%d일') time_changed = changed[2] task_changed = changed[1] msg_changed = changed[0] # booking can not be updated within 24 hours ahead appointment_time = row.start_time current_time = dt.datetime.now() diff_in_hours = (appointment_time - current_time).total_seconds() / 3600 if diff_in_hours < 24: # 못바꾸도록 함 time_changed = 0 task_changed = 0 havetools = 1 if additional_task >= 64: havetools = 0 # time이 변경되었다면 무조건 scheduling if time_changed == '1': date = dt.datetime.strptime(date, '%Y%m%d') start_time_range_begin = int(start_time_range_begin) start_time_range_begin_min = int(start_time_range_begin_min) start_time_range_end = int(start_time_range_end) start_time_range_end_min = int(start_time_range_end_min) appointment_type = 0 # 여기서는 1회 청소로 한다. 편집이기 때문에 start_time = row.start_time end_time = row.estimated_end_time have_pet = row.havepet master_gender = row.master_gender price_with_task = row.price_with_task addr_idx = row.addr_idx org_taking_time_in_minutes = time_to_minutes( timedelta_to_time(end_time - start_time)) new_taking_time_in_minutes = org_taking_time_in_minutes + taking_time_in_minutes address, geohash5, geohash6 = userdao.get_user_address_by_index( uid, addr_idx) gu_id = addrdao.get_gu_id(address) dates = [int(dt.datetime.strftime(date, '%Y%m%d'))] schedule_by_date_list = masterdao.get_master_schedule_by_dates( gu_id, have_pet, master_gender, dates) success, msg, store_key, search_keys, result = masterdao.find_master_by_score(schedule_by_date_list, \ gu_id, \ uid, \ appointment_type, \ dates, \ start_time_range_begin, \ start_time_range_begin_min, \ start_time_range_end, \ start_time_range_end_min, \ new_taking_time_in_minutes, \ geohash6) # if not successful if success != 'SUCCESS': session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response( ret, err_dict['err_no_hm_at_that_time']) self.write(json.dumps(ret)) return else: # find matching homemaster item = result[0] master_id = item['mid'] dow = dt.datetime.strptime(item['date'], '%Y%m%d').date().weekday() start_time = dt.datetime.combine( dt.datetime.strptime(item['date'], '%Y%m%d'), item['start_time']) estimated_end_time = dt.datetime.combine( dt.datetime.strptime(item['date'], '%Y%m%d'), item['end_time']) status = row.payment_status if status == BC.BOOKING_PAID: # 미리 지불한 경우는 취소 하고 다시 결제함 # 전거래 취소 및 재결제 cancel_ret_code, msg = cancel_payment(uid, booking_id, price_with_task, partial='0') if cancel_ret_code: user_name = userdao.get_user_name(uid) pay_ret_code, pay_msg = request_payment( uid, user_name, booking_id, price, appointment_type, status='UPDATED') if pay_ret_code: row.tid = pay_msg row.payment_status = BC.BOOKING_PAID else: row.payment_status = BC.BOOKING_PAYMENT_FAILED session.commit() session.close() self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, pay_msg) self.write(json.dumps(ret)) return row.master_id = master_id row.dow = dow row.price_with_task = price row.start_time = start_time row.message = message row.additional_task = additional_task row.havetools = havetools row.estimated_end_time = estimated_end_time row.laundry_apply_all = laundry_apply_all if org_master_id != master_id: row.is_master_changed = 1 # about laundry request_id = row.request_id appointment_index = row.appointment_index all_bookings = session.query(Booking) \ .filter(Booking.request_id == request_id) \ .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \ .filter(Booking.appointment_index > appointment_index) \ .all() if laundry_apply_all == 1: for booking in all_bookings: booking.additional_task += 4 # 빨래 booking.laundry_apply_all = laundry_apply_all else: for booking in all_bookings: bits = "{0:07b}".format(booking.additional_task) if bits[4] == '1': booking.additional_task -= 4 # 빨래 제거 booking.laundry_apply_all = laundry_apply_all session.commit() holder.remove(store_key) for sk in search_keys: holder.remove(sk) else: if task_changed == '1': if taking_time_in_minutes > 0: # 실제 시간이 늘어났을 경우에만 뒷 스케쥴 확인 master_id, start_date_int = masterdao.get_masterid_and_starttime_from_booking( booking_id) search_key = '%s_%d' % (master_id, start_date_int) new_estimated_end_time = masterdao.is_master_available_next_schedule( booking_id, taking_time_in_minutes) print new_estimated_end_time, '&&&&' if new_estimated_end_time != None and holder.store( search_key, 1): # 실제로 시간이 가능하면 status = row.payment_status if status == BC.BOOKING_PAID: # 미리 지불한 경우는 취소 하고 다시 결제함 # 전거래 취소 및 재결제 cancel_ret_code, msg = cancel_payment( uid, booking_id, price_with_task, partial='0') if cancel_ret_code: user_name = userdao.get_user_name(uid) pay_ret_code, pay_msg = request_payment( uid, user_name, booking_id, price, appointment_type, status='UPDATED') if pay_ret_code: row.tid = pay_msg row.payment_status = BC.BOOKING_PAID else: row.payment_status = BC.BOOKING_PAYMENT_FAILED session.commit() session.close() self.set_status(Response.RESULT_OK) add_err_ko_message_to_response( ret, pay_msg) self.write(json.dumps(ret)) return row.estimated_end_time = new_estimated_end_time row.additional_task = additional_task row.message = message row.price_with_task = price row.havetools = havetools row.laundry_apply_all = laundry_apply_all # about laundry request_id = row.request_id appointment_index = row.appointment_index all_bookings = session.query(Booking) \ .filter(Booking.request_id == request_id) \ .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \ .filter(Booking.appointment_index > appointment_index) \ .all() if laundry_apply_all == 1: for booking in all_bookings: booking.additional_task += 4 # 빨래 booking.laundry_apply_all = laundry_apply_all else: for booking in all_bookings: bits = "{0:07b}".format( booking.additional_task) if bits[4] == '1': booking.additional_task -= 4 # 빨래 제거 booking.laundry_apply_all = laundry_apply_all session.commit() # 메모리에서 삭제 holder.remove(search_key) else: # 스케쥴이 있어서 불가능 함 session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response( ret, err_dict['err_hm_have_next_schedule']) self.write(json.dumps(ret)) return else: # 시간이 줄어들었거나, 그대로인경우에는 additional task 값만 바꾸면 됨 status = row.payment_status if status == BC.BOOKING_PAID: # 미리 지불한 경우는 취소 하고 다시 결제함 # 전거래 취소 및 재결제 cancel_ret_code, msg = cancel_payment( uid, booking_id, price_with_task, partial='0') if cancel_ret_code: user_name = userdao.get_user_name(uid) pay_ret_code, pay_msg = request_payment( uid, user_name, booking_id, price, appointment_type, status='UPDATED') if pay_ret_code: row.tid = pay_msg row.payment_status = BC.BOOKING_PAID else: row.payment_status = BC.BOOKING_PAYMENT_FAILED session.commit() session.close() self.set_status(Response.RESULT_OK) add_err_ko_message_to_response( ret, pay_msg) self.write(json.dumps(ret)) return print row.estimated_end_time, taking_time_in_minutes row.estimated_end_time = row.estimated_end_time + dt.timedelta( minutes=taking_time_in_minutes) row.additional_task = additional_task row.message = message row.price_with_task = price row.havetools = havetools row.laundry_apply_all = laundry_apply_all # about laundry request_id = row.request_id appointment_index = row.appointment_index all_bookings = session.query(Booking) \ .filter(Booking.request_id == request_id) \ .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \ .filter(Booking.appointment_index > appointment_index) \ .all() if laundry_apply_all == 1: for booking in all_bookings: booking.additional_task += 4 # 빨래 booking.laundry_apply_all = laundry_apply_all else: for booking in all_bookings: bits = "{0:07b}".format( booking.additional_task) if bits[4] == '1': booking.additional_task -= 4 # 빨래 제거 booking.laundry_apply_all = laundry_apply_all session.commit() else: row.message = message session.commit() # 문자 전송 #send_updated_text(booking_id, org_date) ret['response'] = Response.SUCCESS self.set_status(Response.RESULT_OK) mix.track( uid, 'update', { 'time': dt.datetime.now(), 'booking_id': booking_id, 'additional_task': additional_task }) mongo_logger.debug('%s was updated' % booking_id, extra={ 'user_id': uid, 'booking_id': booking_id }) print booking_id, 'successfully updated...'
def post(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') uid = self.get_argument('id', '') cno = self.get_argument('cno', '') expy = self.get_argument('expy', '') expm = self.get_argument('expm', '') ssnf = self.get_argument('ssnf', '') cpftd = self.get_argument('cpftd', '') calias = self.get_argument('calias', '') ret = {} print uid try: mongo_logger = get_mongo_logger() mix = get_mixpanel() userdao = UserDAO() request_url = '%s:%d/homemaster_payment/register_card' % ( PAYMENT_HOST, PAYMENT_PORT) params = {} params['id'] = uid params['cno'] = cno params['expy'] = expy params['expm'] = expm params['ssnf'] = ssnf params['cpftd'] = cpftd params['calias'] = calias response = requests.post(request_url, data=params) result = json.loads(response.text) if response.status_code == 200 and result['response'] != "": mix.track(uid, 'register card', { 'time': dt.datetime.now(), 'calias': calias }) mongo_logger.debug('register card', extra={ 'log_time': dt.datetime.now(), 'user_id': uid }) ret['response'] = result['response'] self.set_status(Response.RESULT_OK) else: print 'An error occurred while register card' print result['err_code'], result['err_msg'] add_err_ko_message_to_response(ret, result['err_msg']) mix.track(uid, 'cannot register card', {'time': dt.datetime.now()}) mongo_logger.error('failed to register card', extra={ 'log_time': dt.datetime.now(), 'err': result['err_msg'] }) except Exception, e: print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
self.set_status(Response.RESULT_OK) mongo_logger.debug('multiple first booking record', extra = { 'uid' : uid, 'mid' : mid, 'appointment_type' : appointment_type, 'have_pet' : have_pet, 'master_gender' : master_gender, 'isdirty' : isdirty}) add_err_message_to_response(ret, err_dict['err_multiple_record']) return # notification to homemaster booking_id = first_booking.Booking.id master_pushkey = first_booking.MasterPushKey.pushkey if first_booking.MasterPushKey != None else '' cleaning_time = convert_datetime_format2(first_booking.Booking.start_time) send_new_booking_notification('android', [master_pushkey], booking_ids[0], cleaning_time) else: # 결제 에러인 경우 session.close() self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, msg) mongo_logger.debug('request booking failed to charge', extra = {'user_id' : uid, 'master_id' : mid, 'appointment_type' : appointment_type, 'have_pet' : have_pet, 'master_gender' : master_gender, 'isdirty' : isdirty}) self.write(json.dumps(ret)) return except Exception, e: session.rollback() add_err_message_to_response(ret, err_dict['err_mysql']) mongo_logger.debug('request booking failed', extra = {'user_id' : uid, 'master_id' : mid, 'appointment_type' : appointment_type, 'have_pet' : have_pet, 'master_gender' : master_gender, 'isdirty' : isdirty}) self.set_status(Response.RESULT_SERVERERROR)
class RemoveAddressHandler(tornado.web.RequestHandler): def post(self): ret = {} user_id = self.get_argument('user_id', '') index = self.get_argument('index', 0) index = int(index) print user_id, index self.set_header("Content-Type", "application/json") mongo_logger = get_mongo_logger() mix = get_mixpanel() try: session = Session() try: default_index = session.query(UserDefaultAddress) \ .filter(UserDefaultAddress.user_id == user_id) \ .one() # 기본 주소이면 삭제 안되도록 함 if default_index.address_idx == index: print 'default index' session.close() self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, '기본 주소는 삭제 하실 수 없습니다.') return except NoResultFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_no_record']) print_err_detail(e) return except MultipleResultsFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_multiple_record']) print_err_detail(e) return # 지난 예약 혹은 다가오는 예약에 해당 주소가 연결되어 있다면 삭제가 안되도록 함 booking_index_count = session.query(Booking) \ .filter(Booking.cleaning_status > BC.BOOKING_CANCELED) \ .filter(Booking.user_id == user_id) \ .filter(Booking.addr_idx == index) \ .count() print booking_index_count if booking_index_count > 0: session.close() self.set_status(Response.RESULT_OK) print 'booking' add_err_ko_message_to_response( ret, '완료된 예약과, 다가오는 예약의 주소는 삭제 하실 수 없습니다.') return session.query(UserAddress) \ .filter(UserAddress.user_id == user_id) \ .filter(UserAddress.user_addr_index == index) \ .delete() session.commit() ret['response'] = Response.SUCCESS self.set_status(Response.RESULT_OK) print user_id, 'remove address', index, 'successfully!' mix.track(user_id, 'remove address', { 'time': dt.datetime.now(), 'index': index }) mongo_logger.debug('remove address', extra={ 'user_id': user_id, 'index': index })
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") self.set_header('Access-Control-Allow-Origin', '*') search_term = self.get_argument('search_term', '') ret = {} try: session = Session() users = [] userdao = UserDAO() if search_term == None or search_term == '' or len( search_term) == 1 or search_term == '010': self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, '잘못된 파라미터 입니다.') return total_cnt = session.query(User).count() now = dt.datetime.now() query = session.query(User, UserAddress, UserMemo) \ .outerjoin(UserDefaultAddress, UserDefaultAddress.user_id == User.id) \ .outerjoin(UserAddress, and_(UserDefaultAddress.user_id == UserAddress.user_id, UserDefaultAddress.address_idx == UserAddress.user_addr_index)) \ .outerjoin(UserMemo, User.id == UserMemo.user_id) if search_term != '': print 'searching term : ' + search_term #search_term = search_term.lower() query = query.filter( or_( func.aes_decrypt( func.from_base64(User.name), func.substring(User.salt, 1, 16)).like('%' + search_term + '%'), func.aes_decrypt(func.from_base64(User.phone), func.substring(User.salt, 1, 16)).like(search_term + '%'), User.email.like(search_term + '%'), User.id == search_term)) result = query.order_by(desc(User.dateofreg)).all() for row in result: key = userdao.get_user_salt(row.User.email)[:16] if key == None or key == '': continue crypto = aes.MyCrypto(key) user_info = {} user_info['user_id'] = row.User.id user_info['dateofreg'] = dt.datetime.strftime( row.User.dateofreg, '%Y-%m-%d %H:%M') user_info['devicetype'] = row.User.devicetype user_info['name'] = crypto.decodeAES(row.User.name) user_info['email'] = row.User.email user_info['authsource'] = row.User.authsource user_info['phone'] = crypto.decodeAES(row.User.phone) user_info['gender'] = row.User.gender user_info['active'] = row.User.active user_info['birthdate'] = crypto.decodeAES(row.User.dateofbirth) user_info['default_address'] = crypto.decodeAES( row.UserAddress.address) if row.UserAddress != None else '' user_info[ 'default_address_size'] = row.UserAddress.size if row.UserAddress != None else '' user_info[ 'default_address_kind'] = row.UserAddress.kind if row.UserAddress != None else '' user_info[ 'memo'] = row.UserMemo.memo if row.UserMemo != None else '' user_info['is_b2b'] = row.User.is_b2b #user_info['all_addresses'] = userdao.get_all_user_addresses(row.User.id) users.append(user_info) ret['response'] = {'count': total_cnt, 'users': users} self.set_status(Response.RESULT_OK) except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
class RegisterCardAndChargeHandler(tornado.web.RequestHandler): def initialize(self, mongo): self.mongo = mongo booking = mongo.booking booking.authenticate(MONGO_USER, MONGO_PWD, source='booking') self.db = booking.customer def post(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') cleaning_id = self.get_argument('cleaning_id', '') cno = self.get_argument('cno', '') expy = self.get_argument('expy', '') expm = self.get_argument('expm', '') ssnf = self.get_argument('ssnf', '') cpftd = self.get_argument('cpftd', '') calias = self.get_argument('calias', '') ret = {} try: mongo_logger = get_mongo_logger() mix = get_mixpanel() userdao = UserDAO() doc = self.db.find_one_and_update( {'cleaning_id': cleaning_id}, {'$set': { 'payment': '선결제' }}, return_document=ReturnDocument.AFTER) if doc == None: self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_no_cleaning_id']) return print cno try: uid = doc['user_id'] except Exception, e: self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_no_user_id']) return try: amount = int(doc['total_price']) except Exception, e: self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_invalid_amount']) return address = doc['address'] period = doc['period'] dates = ','.join(doc['dates']) start_date = doc['start_date'] request_url = '%s:%d/homemaster_payment/register_card' % ( PAYMENT_HOST, PAYMENT_PORT) params = {} params['id'] = uid params['cno'] = cno params['expy'] = expy params['expm'] = expm params['ssnf'] = ssnf params['cpftd'] = cpftd params['calias'] = calias response = requests.post(request_url, data=params) result = json.loads(response.text) if response.status_code == 200 and result['response'] != "": mix.track(uid, 'register card', { 'time': dt.datetime.now(), 'calias': calias }) mongo_logger.debug('%s registered card' % uid, extra={'user_id': uid}) user_name = userdao.get_user_name(uid) user_phone = userdao.get_user_phone(uid) import redis try: from utils.secrets import REDIS_HOST, REDIS_PORT, REDIS_PWD except ImportError: REDIS_HOST = 'localhost' REDIS_PORT = 6379 REDIS_PWD = '' r = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, password=REDIS_PWD) event_on = r.get('free_event') if period in ['매주여러번', '매주한번'] and event_on: result = True msg = '' else: result, msg = request_payment_web(uid, user_name, amount) if result: ret['response'] = Response.SUCCESS # jandi notification description = '{}({}) 고객님, 예약됨 {} {} - {}, {}'.format( user_name, user_phone, period, address, start_date, dates) send_jandi('NEW_WEB', '[웹]신규예약', '선결제', description) else: ret['response'] = '' ret['err_msg'] = msg self.set_status(Response.RESULT_OK) mongo_logger.debug('request payment web', extra={ 'user_id': uid, 'amount': amount }) else: print 'An error occurred while register card' print result['err_code'], result['err_msg'] add_err_ko_message_to_response(ret, result['err_msg']) mix.track(uid, 'cannot register card', {'time': dt.datetime.now()}) mongo_logger.error('%s failed to register card' % uid, extra={'err': result['err_msg']})
def post(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') booking_id = self.get_argument('booking_id', '') direction = self.get_argument('direction', '') # forward, #backward if direction == '': direction = 'forward' if not direction in ['forward', 'backward']: self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['invalid_param']) return ret = {} try: session = Session() row = session.query(Booking).filter(Booking.id == booking_id).one() if row.cleaning_status != BC.BOOKING_UPCOMMING: self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, '다가오는 예약이 아니면 미룰 수 없습니다.') return master_id = row.master_id work_date = row.start_time.date() day_of_week = work_date.weekday() start_time = row.start_time end_time = row.estimated_end_time start_hour = start_time.time().hour start_minute = start_time.time().minute end_hour = end_time.time().hour end_minute = end_time.time().minute master_time = session.query(MasterTimeSlot) \ .filter(MasterTimeSlot.master_id == master_id) \ .filter(MasterTimeSlot.day_of_week == day_of_week) \ .one() master_start_time = master_time.start_time master_end_time = master_time.end_time if start_hour <= master_start_time.hour and start_minute == 0 and direction == 'backward': self.set_status(Response.RESULT_OK) add_err_ko_message_to_response( ret, '홈마스터님 근무 시작 시각은 ' + str(master_start_time.hour) + ' 시 입니다.') return if end_hour >= master_end_time.hour and direction == 'forward': self.set_status(Response.RESULT_OK) add_err_ko_message_to_response( ret, '홈마스터님 근무 종료 시각은 ' + str(master_end_time.hour) + ' 시 입니다.') return #겹치는 다른 일정이 없으면 미룬다. if direction == 'backward': minutes = -30 count = session.query(Booking) \ .filter(Booking.master_id == master_id) \ .filter(func.date(Booking.start_time) == work_date) \ .filter(Booking.estimated_end_time < end_time) \ .filter(Booking.estimated_end_time >= start_time - dt.timedelta(minutes = 30)) \ .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \ .count() elif direction == 'forward': minutes = 30 count = session.query(Booking) \ .filter(Booking.master_id == master_id) \ .filter(func.date(Booking.start_time) == work_date) \ .filter(Booking.start_time > start_time) \ .filter(Booking.start_time <= end_time + dt.timedelta(minutes = 30)) \ .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \ .count() print booking_id, master_id, work_date print direction, minutes, count if count != 0: self.set_status(Response.RESULT_OK) add_err_ko_message_to_response( ret, '다른 예약과 겹쳐, 시간을 당기거나 미룰 수 없습니다.') return row.start_time += dt.timedelta(minutes=minutes) row.estimated_end_time += dt.timedelta(minutes=minutes) row.end_time = row.estimated_end_time session.commit() ret['response'] = Response.SUCCESS self.set_status(Response.RESULT_OK) except NoResultFound, e: self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_no_record']) return
def post(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') booking_id = self.get_argument('booking_id', '') reason_id = self.get_argument('reason_id', CANCEL_ADMIN) etc_reason = self.get_argument('etc_reason', '') no_fee = self.get_argument('no_fee', 0) reason_id = int(reason_id) print "reason_id : ", reason_id no_fee = int(no_fee) ret = {} mongo_logger = get_mongo_logger() mix = get_mixpanel() try: session = Session() try: row = session.query(Booking, Master, User, UserAddress) \ .join(Master, Booking.master_id == Master.id) \ .join(User, Booking.user_id == User.id) \ .join(UserDefaultAddress, User.id == UserDefaultAddress.user_id) \ .join(UserAddress, and_(UserAddress.user_id == UserDefaultAddress.user_id, UserAddress.user_addr_index == UserDefaultAddress.address_idx)) \ .filter(Booking.id == booking_id) \ .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \ .one() except NoResultFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_no_entry_to_cancel']) return user_id = row.Booking.user_id masterdao = MasterDAO() userdao = UserDAO() key = userdao.get_user_salt_by_id(user_id)[:16] crypto = aes.MyCrypto(key) # push to homemaster via sms master_id = row.Master.id master_phone = str(row.Master.phone) master_name = str(row.Master.name) username = str(crypto.decodeAES(row.User.name)) userphone = str(crypto.decodeAES(row.User.phone)) date = str(convert_datetime_format(row.Booking.start_time)) addr = str(crypto.decodeAES(row.UserAddress.address)) charge = 0 new_status = BC.BOOKING_CANCELED_CHARGE request_id = row.Booking.request_id appointment_index = row.Booking.appointment_index appointment_time = row.Booking.start_time appointment_type = row.Booking.appointment_type current_status = row.Booking.status current_cleaning_status = row.Booking.cleaning_status current_payment_status = row.Booking.payment_status price = row.Booking.price_with_task source = row.Booking.source device_type = row.Booking.user_type now = dt.datetime.now() cancel_amount = 0 diff_in_hours = (appointment_time - now).total_seconds() / 3600 if diff_in_hours >= 24: charge = price * BC.BOOKING_CHARGE_RATE_NO elif 4 <= diff_in_hours < 24: charge = price * BC.BOOKING_CHARGE_RATE_30 else: charge = price * BC.BOOKING_CHARGE_RATE_50 if current_payment_status == BC.BOOKING_PAID: if no_fee == 1: # 관리자가 선택하여 fee를 지불 할 수 있게 하기 위해서 charge = 0 new_status = BC.BOOKING_CANCELED_REFUND partial = '1' if charge == 0: partial = '0' is_event = session.query(UserFreeEvent) \ .filter(UserFreeEvent.booking_request_id == request_id) \ .first() is_event = True if is_event != None else False cancel_amount = int(price - charge) if cancel_amount > 0 and source == 'hm' and userdao.get_user_default_card_index( user_id) != -1: if not (is_event and appointment_index == 1): ret_code, msg = cancel_payment(user_id, booking_id, cancel_amount, partial) if ret_code == False: session.close() self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, msg) #self.write(json.dumps(ret)) return else: # 결제 필요 # 취소에 대한 결제 필요 partial = '0' cancel_amount = row.Booking.price_with_task - row.Booking.price if cancel_amount > 0: cancel_payment(user_id, booking_id, cancel_amount, partial) complete_count = session.query(Booking) \ .filter(Booking.request_id == request_id) \ .filter(Booking.cleaning_status == 2) \ .count() print complete_count, row.Booking.cleaning_status if complete_count < 9 and row.Booking.cleaning_status == 2: ret_code, msg = request_payment( user_id, username, booking_id, price, appointment_type) if ret_code == False: row.Booking.payment_status = BC.BOOKING_PAYMENT_FAILED else: # cancel charge price print 'cancel charge' charging_price = int(charge) if charging_price > 0 and source == 'hm' and userdao.get_user_default_card_index( user_id) != -1 and no_fee == 0: print user_id, username, booking_id, charging_price, appointment_type ret_code, msg = request_payment(user_id, username, booking_id, charging_price, appointment_type) if ret_code == False: new_status = BC.BOOKING_PAYMENT_FAILED #row.Booking.modified_date = now row.Booking.charging_price = int(charge) row.Booking.status = new_status row.Booking.cleaning_status = BC.BOOKING_CANCELED row.Booking.payment_status = new_status appointment_type_text = '' if appointment_type == BC.ONE_TIME or appointment_type == BC.ONE_TIME_BUT_CONSIDERING: appointment_type_text = '1회' elif appointment_type == BC.FOUR_TIME_A_MONTH: appointment_type_text = '매주' elif appointment_type == BC.TWO_TIME_A_MONTH: appointment_type_text = '2주 1회' elif appointment_type == BC.ONE_TIME_A_MONTH: appointment_type_text = '4주 1회' #sms_sender = SMS_Sender() #text = BOOKING_CANCEL_TEXT % (username, userphone, master_name, date) #print sms_sender.send_for_manager(sender = MAIN_CALL, mtype = 'sms', to = MANAGERS_CALL, subject = BOOKING_TEXT_SUBJECT, text = text) #for manager_phone in MANAGERS_CALL.split(','): # send_alimtalk(manager_phone, 'noti_manager_cancel', username, date, appointment_type_text) cancel_reasons = [] cancel_reasons.append('지금은 서비스가 필요하지 않아요') cancel_reasons.append('집에 없어서 문을 열어드릴 수가 없어요') cancel_reasons.append('시간이 마음에 들지 않아요') cancel_reasons.append('클리닝을 잊고 있었네요') cancel_reasons.append('원하는 홈마스터가 아니에요') cancel_reasons.append('기타') cancel_reasons.append('이사가요') cancel_reasons.append('기타') cancel_reasons.append('관리자가 취소 했습니다') cancel_reason = cancel_reasons[reason_id] if cancel_reason == '기타': cancel_reason += ' ' + etc_reason elif reason_id == CANCEL_ADMIN: cancel_reason += ', 관리자 메모 : ' + etc_reason send_jandi( 'NEW_BOOKING', "취소 알림", username + ' 고객님 취소함', '{}, {}, 사유 : {}'.format(date, appointment_type_text, cancel_reason)) print 'jandi notification for cancel...' master_pushkey = masterdao.get_master_pushkey(master_id) #master_name = masterdao.get_master_name(master_id) #master_phone = masterdao.get_master_phone(master_id) send_booking_canceled('android', [master_pushkey], booking_id, date, username) content = '''{} 홈마스터님 예약이 1회 취소 되었습니다. 고객 : {} 주기 : {} 날짜 : {}'''.format(master_name, username, appointment_type_text, date) message_sender = MessageSender() message_sender.send([master_phone], '예약 1회 취소 알림', content) print 'master_pushkey', master_pushkey print booking_id, date #send_alimtalk(master_phone, 'noti_manager_cancel', username, date, appointment_type_text) # adjust appointment index index_result = session.query(Booking).filter( Booking.request_id == request_id).filter( Booking.appointment_index > appointment_index).all() for index_row in index_result: index_row.appointment_index -= 1 coupondao = CouponDAO() coupondao.cancel_coupon_usage(booking_id) CANCEL = 0 cancel_reason = CancelReason(booking_id=booking_id, user_id=user_id, reason_id=reason_id, etc_reason=etc_reason, kind=CANCEL, cancel_time=dt.datetime.now()) session.add(cancel_reason) session.commit() mix.track( user_id, 'cancel', { 'time': dt.datetime.now(), 'reason_id': reason_id, 'etc_reason': etc_reason, 'cancel_amount': cancel_amount }) mongo_logger.debug('%s was canceled' % booking_id, extra={ 'user_id': user_id, 'booking_id': booking_id, 'cancel_amount': cancel_amount }) ret['response'] = Response.SUCCESS self.set_status(Response.RESULT_OK)
def post(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') ret = {} uid = self.get_argument('uid', '') appointment_type = self.get_argument('appointment_type', BC.ONE_TIME) taking_time = self.get_argument('taking_time', 25) first_added_time = self.get_argument('first_added_time', 0) additional_time = self.get_argument('additional_time', 10) have_pet = self.get_argument('have_pet', 0) master_gender = self.get_argument('master_gender', 0) isdirty = self.get_argument('isdirty', 0) for_manager = self.get_argument('for_manager', '') # for address parameter address = self.get_argument('address', '') size = self.get_argument('size', 25) kind = self.get_argument('kind', 0) size = int(size) kind = int(kind) # convert parameters appointment_type = int(appointment_type) taking_time = int(taking_time) first_added_time = int(first_added_time) additional_time = int(additional_time) taking_time_in_minutes = taking_time * 6 first_added_time_in_minutes = first_added_time * 6 additional_time_in_minutes = additional_time * 6 total_taking_time_in_minutes = taking_time_in_minutes + first_added_time_in_minutes + additional_time_in_minutes have_pet = int(have_pet) master_gender = int(master_gender) # 0 dont care 1 women isdirty = int(isdirty) # logging part mix = get_mixpanel() mongo_logger = get_mongo_logger() try: print uid if self.is_user_block(ret, uid) == True: return if appointment_type == BC.ONE_TIME_A_MONTH: self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, '4주 1회 서비스는 신규 예약을 지원하지 않습니다.') mongo_logger.debug('not booking one time a month', extra = { 'user_id' : uid }) ret['err_code'] = '4038' # 임시 처리 return if total_taking_time_in_minutes <= 0 or taking_time_in_minutes <= 0: self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, '클리닝 시간이 잘못 설정되었습니다.') ret['err_code'] = '9999' # 임시 처리 return if total_taking_time_in_minutes >= 600: self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, '클리닝 가능 시간을 초과하였습니다. (최대 10시간) 이전 화면으로 돌아가 추가사항을 2개이하로 줄여주세요.') ret['err_code'] = '4036' # 임시 처리 return scheduler = HMScheduler() session = Session() userdao = UserDAO() addrdao = AddressDAO() # add user address latlng = get_latlng_from_address(address) if len(latlng) > 1: latitude = latlng[0] longitude = latlng[1] geohash5 = get_geohash(latitude, longitude, 5) geohash6 = get_geohash(latitude, longitude, 6) else: latitude = 0.0 longitude = 0.0 geohash5 = '' geohash6 = '' key = userdao.get_user_salt_by_id(uid)[:16] crypto = aes.MyCrypto(key) encrypted_address = crypto.encodeAES(str(address)) count = session.query(UserAddress).filter(UserAddress.user_id == uid).count() last_index = session.query(UserAddress).filter(UserAddress.user_id == uid).order_by(desc(UserAddress.user_addr_index)).first() index = 0 if last_index != None: index = last_index.user_addr_index + 1 new_address = UserAddress(user_id = uid, address = encrypted_address, size = size, kind = kind, user_addr_index = index, latitude = latitude, longitude = longitude, geohash5 = geohash5, geohash6 = geohash6) session.add(new_address) session.commit() # set default address index if count == 0: new_default_address = UserDefaultAddress(user_id=uid, address_idx=index) session.add(new_default_address) else: record = session.query(UserDefaultAddress).filter(UserDefaultAddress.user_id == uid).one() record.address_idx = index session.commit() address, geohash5, geohash6 = userdao.get_user_address(uid) _, size, kind = userdao.get_user_address_detail(uid) gu_id = addrdao.get_gu_id(address) if gu_id == '': raise Exception('gu id is incorrect') return available_schedules = scheduler.get_available_slots(gu_id = gu_id, geohash = geohash6, appointment_type = appointment_type, taking_time = total_taking_time_in_minutes, prefer_women = True if master_gender == 1 else False, have_pet = True if have_pet == 1 else False, isdirty = True if isdirty == 1 else False, user_id = uid) now = dt.datetime.now() if now.hour >= 17: # 7시 이후 라면 -> 5시로 변경 2016.06.03 if for_manager == '': # 사용자 앱에서는 내일 예약 불가능 tomorrow = now + dt.timedelta(days=1) tomorrow = dt.datetime.strftime(tomorrow, '%Y%m%d') if tomorrow in available_schedules: del available_schedules[tomorrow] for day in available_schedules: print '[', day, ']' print available_schedules[day]['by_time'] # log to mixpanel mix.track(uid, 'request available schedule', {'time' : dt.datetime.now(), 'taking_time' : taking_time, 'additional_time' : additional_time, 'appointment_type' : appointment_type, 'have_pet' : have_pet, 'master_gender' : master_gender,'isdirty' : isdirty}) # log to mongo mongo_logger.debug('request available schedule', extra = {'log_time' : dt.datetime.now(), 'user_id' : uid, 'taking_time' : taking_time, 'additional_time' : additional_time, 'appointment_type' : appointment_type, 'have_pet' : have_pet, 'master_gender' : master_gender,'isdirty' : isdirty}) if len(available_schedules) > 0: # 가능한 날짜가 있다면 ret['response'] = {'schedule' : available_schedules, 'first_date' : available_schedules.keys()[0] } else: add_err_message_to_response(ret, err_dict['err_not_available']) mongo_logger.debug('no masters', extra = {'log_time' : dt.datetime.now(), 'user_id' : uid, 'taking_time' : total_taking_time_in_minutes, 'gu_id' : gu_id, 'address' : address}) user_name = userdao.get_user_name(uid) user_phone = userdao.get_user_phone(uid) send_jandi('BOOKING_NOT_AVAILABE', '예약 불가능 알림', '고객 : {} 전번 : {}'.format(user_name, user_phone), '주기 : {}, 주소 : {}'.format(appointment_type, address)) self.set_status(Response.RESULT_OK) except Exception, e: add_err_message_to_response(ret, err_dict['err_mysql']) self.set_status(Response.RESULT_SERVERERROR) print_err_detail(e) mongo_logger.error('error request available schedules', extra = {'user_id' : uid, 'err' : str(e)})
def post(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') ret = {} uid = self.get_argument('uid', '') appointment_type = self.get_argument('appointment_type', BC.ONE_TIME) taking_time = self.get_argument('taking_time', 25) first_added_time = self.get_argument('first_added_time', 0) additional_time = self.get_argument('additional_time', 0) have_pet = self.get_argument('have_pet', 0) master_gender = self.get_argument('master_gender', 0) isdirty = self.get_argument('isdirty', 0) for_manager = self.get_argument('for_manager', '') # for b2b appointment user_address_idx = self.get_argument('user_address_idx', -1) b2b = self.get_argument('b2b', '') # convert parameters appointment_type = int(appointment_type) taking_time = int(taking_time) first_added_time = int(first_added_time) additional_time = int(additional_time) taking_time_in_minutes = taking_time * 6 first_added_time_in_minutes = first_added_time * 6 additional_time_in_minutes = additional_time * 6 total_taking_time_in_minutes = taking_time_in_minutes + first_added_time_in_minutes + additional_time_in_minutes have_pet = int(have_pet) master_gender = int(master_gender) # 0 dont care 1 women isdirty = int(isdirty) # logging part mix = get_mixpanel() mongo_logger = get_mongo_logger() try: if self.is_user_block(ret, uid) == True: return if appointment_type == BC.ONE_TIME_A_MONTH and b2b != 'b2b': self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, '4주 1회 서비스는 신규 예약을 지원하지 않습니다.') mongo_logger.debug('not booking one time a month', extra = { 'user_id' : uid }) ret['err_code'] = '4038' # 임시 처리 return if total_taking_time_in_minutes >= 600: self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, '클리닝 가능 시간을 초과하였습니다. (최대 10시간) 이전 화면으로 돌아가 추가사항을 2개이하로 줄여주세요.') ret['err_code'] = '4036' # 임시 처리 return scheduler = HMScheduler() userdao = UserDAO() addrdao = AddressDAO() if user_address_idx == -1: # default_address address, geohash5, geohash6 = userdao.get_user_address(uid) _, size, kind = userdao.get_user_address_detail(uid) else: # address selection address, geohash5, geohash6 = userdao.get_user_address_by_index(uid, user_address_idx) _, size, kind = userdao.get_user_address_detail_by_index(uid, user_address_idx) gu_id = addrdao.get_gu_id(address) if gu_id == '': raise Exception('gu id is incorrect') available_schedules = scheduler.get_available_slots(gu_id = gu_id, geohash = geohash6, appointment_type = appointment_type, taking_time = total_taking_time_in_minutes, prefer_women = True if master_gender == 1 else False, have_pet = True if have_pet == 1 else False, isdirty = True if isdirty == 1 else False, user_id = uid) now = dt.datetime.now() if now.hour >= 17: # 7시 이후 라면 -> 5시로 변경 2016.06.03 if for_manager == '': # 사용자 앱에서는 내일 예약 불가능 tomorrow = now + dt.timedelta(days=1) tomorrow = dt.datetime.strftime(tomorrow, '%Y%m%d') if tomorrow in available_schedules: del available_schedules[tomorrow] for day in available_schedules: print '[', day, ']' print available_schedules[day]['by_time'] # log to mixpanel mix.track(uid, 'request available schedule', {'time' : dt.datetime.now(), 'taking_time' : taking_time, 'additional_time' : additional_time, 'appointment_type' : appointment_type, 'have_pet' : have_pet, 'master_gender' : master_gender,'isdirty' : isdirty}) # log to mongo mongo_logger.debug('request available schedule', extra = {'log_time' : dt.datetime.now(), 'user_id' : uid, 'taking_time' : taking_time, 'additional_time' : additional_time, 'appointment_type' : appointment_type, 'have_pet' : have_pet, 'master_gender' : master_gender,'isdirty' : isdirty}) if len(available_schedules) > 0: # 가능한 날짜가 있다면 ret['response'] = {'schedule' : available_schedules, 'first_date' : available_schedules.keys()[0] } else: add_err_message_to_response(ret, err_dict['err_not_available']) mongo_logger.debug('no masters', extra = {'log_time' : dt.datetime.now(), 'user_id' : uid, 'taking_time' : total_taking_time_in_minutes, 'gu_id' : gu_id, 'address' : address}) user_name = userdao.get_user_name(uid) user_phone = userdao.get_user_phone(uid) send_jandi('BOOKING_NOT_AVAILABE', '예약 불가능 알림', '고객 : {} 전번 : {}'.format(user_name, user_phone), '주기 : {}, 주소 : {}'.format(appointment_type, address)) self.set_status(Response.RESULT_OK) except Exception, e: add_err_message_to_response(ret, err_dict['err_mysql']) self.set_status(Response.RESULT_SERVERERROR) print_err_detail(e) mongo_logger.error('error request available schedules', extra = {'user_id' : uid, 'err' : str(e)})
def post(self): self.set_header("Content-Type", "application/json") ret = {} uid = self.get_argument('uid', '') date = self.get_argument('date', dt.datetime.now()) start_time_range_begin = self.get_argument('range_begin', BC.START_TIME_RANGE_BEGIN) start_time_range_begin_min = self.get_argument('range_begin_min', 0) start_time_range_end = self.get_argument('range_end', BC.START_TIME_RANGE_END) start_time_range_end_min = self.get_argument('range_end_min', 0) appointment_type = self.get_argument('appointment_type', BC.ONE_TIME) taking_time = self.get_argument('taking_time', 25) first_added_time = self.get_argument('first_added_time', 0) additional_time = self.get_argument('additional_time', 10) have_pet = self.get_argument('have_pet', 0) master_gender = self.get_argument('master_gender', 0) isdirty = self.get_argument('isdirty', 0) # convert datetime date = dt.datetime.strptime(date, '%Y%m%d') start_time_range_begin = int(start_time_range_begin) start_time_range_begin_min = int(start_time_range_begin_min) start_time_range_end = int(start_time_range_end) start_time_range_end_min = int(start_time_range_end_min) appointment_type = int(appointment_type) taking_time = int(taking_time) first_added_time = int(first_added_time) additional_time = int(additional_time) taking_time_in_minutes = taking_time * 6 first_added_time_in_minutes = first_added_time * 6 additional_time_in_minutes = additional_time * 6 total_taking_time_in_minutes = taking_time_in_minutes + first_added_time_in_minutes + additional_time_in_minutes have_pet = int(have_pet) master_gender = int(master_gender) # 0 dont care 1 women 2 men isdirty = int(isdirty) print 'request schedule' print 'taking time :', taking_time_in_minutes mongo_logger = get_mongo_logger() mongo_logger.debug('%s request schedule' % uid, extra={ 'date': dt.datetime.strftime(date, '%Y%m%d'), 'start_time_range_begin': start_time_range_begin, 'start_time_range_end': start_time_range_end, 'taking_time': taking_time, 'additional_time': additional_time, 'appointment_type': appointment_type, 'have_pet': have_pet, 'master_gender': master_gender, 'isdirty': isdirty }) mix = get_mixpanel() try: session = Session() userdao = UserDAO() addrdao = AddressDAO() masterdao = MasterDAO() holder = IntermediateValueHolder() # request id to group each individual bookings request_id = str(uuid.uuid4()) # get user's address and cover address to gu code address, geohash5, geohash6 = userdao.get_user_address(uid) gu_id = addrdao.get_gu_id(address) # four consecutive appointment days to make booking if regular , otherwise just one day dates = [int(dt.datetime.strftime(date, '%Y%m%d'))] if appointment_type == BC.ONE_TIME_A_MONTH or appointment_type == BC.TWO_TIME_A_MONTH or appointment_type == BC.FOUR_TIME_A_MONTH: dates = [ int( dt.datetime.strftime( date + dt.timedelta(days=i * BC.DAYS_IN_A_WEEK * (4 / appointment_type)), '%Y%m%d')) for i in xrange(4) ] # 크리스마스 및 새해 임시로 막음. if date.date() == dt.date(2016, 2, 7) or date.date() == dt.date( 2016, 2, 8) or date.date() == dt.date( 2016, 2, 9) or date.date() == dt.date(2016, 2, 10): self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, '설날 연휴동안은, 예약이 불가능합니다.') self.write(json.dumps(ret)) return # 스케쥴이 이미 해당 날짜에 있다면, 있다고 표시하고 리턴함 num_schedules_on_dates = userdao.get_user_schedule_on_dates( uid, [dt.datetime.strptime(str(d), '%Y%m%d').date() for d in dates]) if num_schedules_on_dates > 0: self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_schedules_on_dates']) self.write(json.dumps(ret)) return # 똥집인 경우 3시간 추가됨. if isdirty == 1: if appointment_type == BC.ONE_TIME or appointment_type == BC.ONE_TIME_BUT_CONSIDERING: total_taking_time_in_minutes += 120 print 'gu_id', gu_id, have_pet, master_gender, dates #get available homemaster's time table day by day schedule_by_date_list = masterdao.get_master_schedule_by_dates( gu_id, have_pet, master_gender, dates) success, msg, store_key, search_keys, result = masterdao.find_master_by_score(schedule_by_date_list, \ gu_id, \ uid, \ appointment_type, \ dates, \ start_time_range_begin, \ start_time_range_begin_min, \ start_time_range_end, \ start_time_range_end_min, \ total_taking_time_in_minutes, \ geohash6) # if not successful if success != 'SUCCESS': self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_no_hm_at_that_time']) mix.track( uid, 'request schedule', { 'time': dt.datetime.now(), 'date': dt.datetime.strftime(date, '%Y%m%d'), 'start_time_range_begin': start_time_range_begin, 'start_time_range_begin_min': start_time_range_begin_min, 'start_time_range_end': start_time_range_end, 'start_time_range_end_min': start_time_range_end_min, 'taking_time': taking_time, 'additional_time': additional_time, 'appointment_type': appointment_type, 'have_pet': have_pet, 'master_gender': master_gender, 'isdirty': isdirty, 'status': 'no homemaster' }) print uid, 'was not able to find any homemasters....' else: schedules = [] for row in result: s = {} s['date'] = row['date'] s['start_time'] = time_to_str(row['start_time']) s['end_time'] = time_to_str(row['end_time']) schedules.append(s) mid = row['mid'] name, img_url, avg_rating = masterdao.get_master_name_img_and_average_rating( mid) search_keys_str = ','.join(search_keys) ret['response'] = { 'store_key': store_key, 'search_keys': search_keys_str, 'schedules': schedules, 'uid': uid, 'mid': row['mid'], 'name': name, 'img_url': img_url, 'avg_rating': str(float(avg_rating)) } print uid, 'successfully made booking requests...' mix.track( uid, 'request schedule', { 'time': dt.datetime.now(), 'date': dt.datetime.strftime(date, '%Y%m%d'), 'start_time_range_begin': start_time_range_begin, 'start_time_range_begin_min': start_time_range_begin_min, 'start_time_range_end': start_time_range_end, 'start_time_range_end_min': start_time_range_end_min, 'taking_time': taking_time, 'additional_time': additional_time, 'appointment_type': appointment_type, 'have_pet': have_pet, 'master_gender': master_gender, 'isdirty': isdirty, 'status': 'find homemaster' }) mongo_logger.debug('%s made booking requests' % uid, extra={'user_id': uid}) self.set_status(Response.RESULT_OK) except Exception, e: session.rollback() add_err_message_to_response(ret, err_dict['err_mysql']) self.set_status(Response.RESULT_SERVERERROR) print_err_detail(e) mongo_logger.error('error occurred when request schedule', extra={'err': str(e)}) # if error occur, then remove all keys holder.remove(store_key) for sk in search_keys: holder.remove(sk)
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