def notify_10mins_ahead(self): try: userdao = UserDAO() current_time = dt.datetime.now() print '-' * 40 print 'push before 10 minutes' print 'current_time :', current_time hour = current_time.hour if current_time.minute >= 20 and current_time.minute <= 29: minute = 30 elif current_time.minute >= 50 and current_time.minute <= 59: hour += 1 minute = 0 else: minute = 0 cron_time = current_time.replace(hour=hour, minute=minute, second=0, microsecond=0) print 'cron_time :', cron_time print '-' * 40 session = Session() result = session.query(Booking, Master, User, UserPushKey) \ .join(Master, Booking.master_id == Master.id) \ .join(User, Booking.user_id == User.id) \ .outerjoin(UserPushKey, User.id == UserPushKey.user_id) \ .filter(or_(Booking.cleaning_status == BC.BOOKING_UPCOMMING, Booking.cleaning_status == BC.BOOKING_STARTED)) \ .filter(func.date(Booking.start_time) == cron_time.date()) \ .filter(func.HOUR(Booking.start_time) == cron_time.time().hour) \ .filter(func.MINUTE(Booking.start_time) == cron_time.time().minute) \ .all() for row in result: key = userdao.get_user_salt_by_id(row.User.id)[:16] crypto = aes.MyCrypto(key) booking_id = row.Booking.id pushkey = row.UserPushKey.pushkey if row.UserPushKey != None else '' user_name = crypto.decodeAES(row.User.name) phone = crypto.decodeAES(row.User.phone) master_name = row.Master.name devicetype = row.User.devicetype print 'push to', user_name, master_name, booking_id print pushkey if devicetype != 'android': pushkey = crypto.decodeAES(row.User.phone) send_10mins_ahead_notification(devicetype, [pushkey], booking_id) send_alimtalk(phone, 'noti_10', user_name, master_name) except Exception, e: print_err_detail(e)
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', '') new_pwd = self.get_argument('new_pwd', 'hm123') try: userdao = UserDAO() session = Session() user_row = session.query(User).filter(User.id == user_id).one() salt = userdao.get_user_salt_by_id(user_id) hash_obj = hashlib.sha256(salt + new_pwd) user_row.password = hash_obj.hexdigest() session.commit() ret['response'] = Response.SUCCESS 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'])
def notify(self): try: userdao = UserDAO() current_time = dt.datetime.now() print '-' * 40 print 'push before 2 hours' print 'current_time :', current_time hour = current_time.hour minute = 30 if current_time.minute >= 30 else 0 #current_time = current_time + dt.timedelta(hours=2) cron_time = current_time.replace(hour=hour+2, minute=minute, second = 0, microsecond=0) print 'cron_time :', cron_time print '-' * 40 session = Session() result = session.query(Booking, Master, MasterPushKey, User) \ .join(Master, Booking.master_id == Master.id) \ .join(MasterPushKey, Master.id == MasterPushKey.master_id) \ .join(User, Booking.user_id == User.id) \ .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \ .filter(func.date(Booking.start_time) == cron_time.date()) \ .filter(func.HOUR(Booking.start_time) == cron_time.time().hour) \ .filter(func.MINUTE(Booking.start_time) == cron_time.time().minute) \ .all() for row in result: key = userdao.get_user_salt_by_id(row.User.id)[:16] crypto = aes.MyCrypto(key) if row.Master.id == 'da2a1f50-fd36-40bf-8460-55b3e1b2c459': continue booking_id = row.Booking.id pushkey = row.MasterPushKey.pushkey if row.MasterPushKey != None else '' master_name = row.Master.name start_time = row.Booking.start_time time_str = convert_datetime_format4(start_time) print 'push to', master_name, booking_id print pushkey send_master_ahead_notification('android', [pushkey], booking_id, master_name, time_str) except Exception, e: print_err_detail(e)
def get(self): self.set_header("Content-Type", "application/json") ret = {} master_id = self.get_argument('master_id', '') try: session = Session() userdao = UserDAO() result = session.query(Master, Booking, User) \ .join(Booking, Master.id == Booking.master_id) \ .join(User, Booking.user_id == User.id) \ .filter(Booking.master_id == master_id) \ .filter(or_(Booking.cleaning_status == BC.BOOKING_UPCOMMING, Booking.cleaning_status == BC.BOOKING_STARTED, Booking.cleaning_status == BC.BOOKING_COMPLETED)) \ .order_by(desc(Booking.start_time)) \ .all() booking_list = [] for row in result: key = userdao.get_user_salt_by_id(row.Booking.user_id)[:16] crypto = aes.MyCrypto(key) booking = {} booking['booking_id'] = row.Booking.id booking['name'] = crypto.decodeAES(row.User.name) booking['start_time'] = convert_datetime_format2( row.Booking.start_time) booking['additional_task'] = row.Booking.additional_task booking['price'] = row.Booking.price_with_task booking['status'] = row.Booking.status booking['cleaning_status'] = row.Booking.cleaning_status booking['payment_status'] = row.Booking.payment_status booking_list.append(booking) ret['response'] = booking_list self.set_status(Response.RESULT_OK) except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
def get(self): self.set_header("Content-Type", "application/json") manager_id = self.get_argument('manager_id', '') ret = {} try: session = Session() userdao = UserDAO() payment_records = [] result = session.query(UserPaymentRecord, User) \ .join(User, UserPaymentRecord.user_id == User.id) \ .order_by(UserPaymentRecord.user_id, desc(UserPaymentRecord.auth_date)) \ .all() for row in result: payment = {} key = userdao.get_user_salt_by_id(row.User.id)[:16] crypto = aes.MyCrypto(key) payment['tid'] = row.UserPaymentRecord.tid payment['booking_id'] = row.UserPaymentRecord.booking_id payment['user_id'] = row.UserPaymentRecord.user_id payment['price'] = row.UserPaymentRecord.price payment['auth_date'] = row.UserPaymentRecord.auth_date payment[ 'canceled_amount'] = row.UserPaymentRecord.canceled_amount payment['canceled_date'] = row.UserPaymentRecord.canceled_date payment['status'] = row.UserPaymentRecord.status payment['user_name'] = crypto.decodeAES(row.User.name) payment['user_phone'] = crypto.decodeAES(row.User.phone) payment_records.append(payment) ret['response'] = payment_records self.set_status(Response.RESULT_OK) except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
def login(self, name, phone): session = Session() userdao = UserDAO() result = session.query(User) \ .filter(User.email == name + phone + '@11st.co.kr') \ .filter(User.authsource == '11st') \ .all() for row in result: key = userdao.get_user_salt_by_id(row.id)[:16] crypto = aes.MyCrypto(key) decrypted_name = crypto.decodeAES(row.name) decrypted_phone = crypto.decodeAES(row.phone) if name == decrypted_name and phone == decrypted_phone: # 동명이인 고려, 일치하게 된다면 id 반환 return row.id, True return '', False
def 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 get(self): self.set_header("Content-Type", "application/json") ret = {} try: session = Session() userdao = UserDAO() none_ios_users = [] for row in session.query(User, Booking) \ .join(Booking, User.id == Booking.user_id) \ .filter(Booking.cleaning_status == 0) \ .filter(User.devicetype == 'None') \ .group_by(User.id) \ .all(): user_dict = {} user_id = row.User.id key = userdao.get_user_salt_by_id(user_id)[:16] crypto = aes.MyCrypto(key) user_dict['name'] = crypto.decodeAES(row.User.name) user_dict['email'] = row.User.email user_dict['phone'] = crypto.decodeAES(row.User.phone) user_dict['gender'] = row.User.gender none_ios_users.append(user_dict) print len(none_ios_users) ret['response'] = none_ios_users self.set_status(Response.RESULT_OK) except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
def get(self): self.set_header("Content-Type", "application/json") ret = {} try: userdao = UserDAO() session = Session() result = session.query(MasterClaim, Master, User) \ .join(Master, MasterClaim.master_id == Master.id) \ .join(User, MasterClaim.user_id == User.id) \ .order_by(desc(MasterClaim.register_time)) \ .all() claims = [] for row in result: key = userdao.get_user_salt_by_id(row.User.id)[:16] crypto = aes.MyCrypto(key) claim = {} claim['user_name'] = crypto.decodeAES(row.User.name) claim['user_phone'] = crypto.decodeAES(row.User.phone) claim['master_name'] = row.Master.name claim['text'] = row.MasterClaim.claim_text claim['datetime'] = convert_datetime_format2( row.MasterClaim.register_time) claims.append(claim) ret['response'] = claims self.set_status(Response.RESULT_OK) except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
def notify(self): try: userdao = UserDAO() current_date = dt.datetime.now().date() print current_date session = Session() result = session.query(Booking, User, UserPushKey) \ .join(User, Booking.user_id == User.id) \ .join(UserPushKey, User.id == UserPushKey.user_id) \ .filter(func.date(Booking.start_time) == current_date) \ .filter(Booking.cleaning_status == BC.BOOKING_COMPLETED) \ .all() for row in result: key = userdao.get_user_salt_by_id(row.User.id)[:16] crypto = aes.MyCrypto(key) booking_id = row.Booking.id user_name = crypto.decodeAES(row.User.name) pushkey = row.UserPushKey.pushkey devicetype = row.User.devicetype if row.Booking.havereview == 0: # review 하지 않은 사용자에게만 보냄 print 'rating push to ', user_name, booking_id if devicetype != 'android': pushkey = crypto.decodeAES(row.User.phone) send_rating_notification(devicetype, [pushkey], booking_id, user_name) print 'notified to users for rating successfully...', dt.datetime.now() except Exception, e: print_err_detail(e)
def get(self): self.set_header("Content-Type", "application/json") ret = {} try: session = Session() userdao = UserDAO() users = [] for row in session.query(User, UserAddress, UserDefaultAddress, Booking) \ .outerjoin(UserAddress, User.id == UserAddress.user_id) \ .outerjoin(UserDefaultAddress, User.id == UserDefaultAddress.user_id) \ .outerjoin(Booking, and_(User.id == Booking.user_id)) \ .all(): if row.UserAddress != None and row.Booking == None: user_id = row.User.id key = userdao.get_user_salt_by_id(user_id)[:16] crypto = aes.MyCrypto(key) user_info = {} user_info['name'] = crypto.decodeAES(row.User.name) user_info['phone'] = crypto.decodeAES(row.User.phone) users.append(user_info) ret['response'] = users self.set_status(Response.RESULT_OK) except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
def get(self): self.set_header("Content-Type", "application/json") ret = {} try: session = Session() userdao = UserDAO() memos = [] result = session.query(UserMemo, User) \ .join(User, UserMemo.user_id == User.id) \ .order_by(desc(UserMemo.requested_datetime)) \ .all() for row in result: key = userdao.get_user_salt_by_id(row.User.id)[:16] crypto = aes.MyCrypto(key) memo = {} memo['time'] = dt.datetime.strftime( row.UserMemo.requested_datetime, '%Y-%m-%d %H:%M') memo['memo'] = row.UserMemo.memo memo['user_name'] = crypto.decodeAES(row.User.name) memos.append(memo) ret['response'] = memos self.set_status(Response.RESULT_OK) except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
def notify_try_charge_unpaid(self): try: mongo_logger = get_mongo_logger() userdao = UserDAO() bookingdao = BookingDAO() current_time = dt.datetime.now() two_weeks_before = current_time - dt.timedelta(days=28) two_weeks_before = two_weeks_before.date() print '-' * 40 print 'try charge unpaid notification via alimtalk' print 'cron_time :', current_time print '-' * 40 session = Session() result = session.query(Booking, User) \ .join(User, Booking.user_id == User.id) \ .filter(func.Date(Booking.start_time) >= two_weeks_before) \ .filter(Booking.cleaning_status == BC.BOOKING_COMPLETED) \ .filter(Booking.payment_status != BC.BOOKING_PAID) \ .filter(User.is_b2b == 0) \ .filter(Booking.source == 'hm') \ .order_by(Booking.start_time) \ .all() for row in result: if 'b2b.com' in row.User.email: # b2b 무시 continue if row.User.is_b2b == 1: # b2b 무시 continue if row.Booking.source != 'hm': # 11번가 무시 continue key = userdao.get_user_salt_by_id(row.User.id)[:16] crypto = aes.MyCrypto(key) user_id = row.Booking.user_id user_name = crypto.decodeAES(row.User.name) phone = crypto.decodeAES(row.User.phone) booking_id = row.Booking.id appointment_type = row.Booking.appointment_type cleaning_time = convert_datetime_format2( row.Booking.start_time) charge_price = row.Booking.price_with_task price = '{:,}원'.format(charge_price) print booking_id, user_id, user_name, cleaning_time, price status, try_charge, remain_days = bookingdao.is_next_booking_left_over_2days( booking_id) print status, try_charge, remain_days if status == 'FAILURE': # 다음 회차 예약 가져오기 실패. 건너 뜀 continue if try_charge: # 결제를 시도해야함 ret, value = request_payment(user_id, user_name, booking_id, charge_price, appointment_type) if ret: # 결제 성공 row.Booking.payment_status = BC.BOOKING_PAID session.commit() print '*** success ***' send_alimtalk(phone, 'notify_try_charge_unpaid_success', cleaning_time, price) mongo_logger.debug('user try charge success', extra={ 'dt': current_time, 'user_id': user_id, 'booking_id': booking_id, 'price': price, 'cleaning_time': cleaning_time }) else: # 결제 실패 print '*** failed ***' if remain_days == -1: mongo_logger.debug('no booking remains', extra={ 'dt': current_time, 'user_id': user_id, 'booking_id': booking_id, 'price': price, 'cleaning_time': cleaning_time }) elif remain_days > 3: # 3일 초과로 남았으면 실패 공지 send_alimtalk(phone, 'notify_charge_failure', cleaning_time, price) mongo_logger.debug('user try charge fail', extra={ 'dt': current_time, 'user_id': user_id, 'booking_id': booking_id, 'price': price, 'cleaning_time': cleaning_time }) elif remain_days >= 0: # 3일 이내면 전체 취소 print '*** cancel all ***' bookingdao.cancel_all_upcomings(booking_id) send_jandi( 'NEW_BOOKING', "미결제 전체 취소 알림", user_name + ' 고객님 전체 취소됨', '미결제 일시 : {}, 금액 : {}'.format( cleaning_time, price)) send_alimtalk( phone, 'notify_try_charge_unpaid_cancel_all', cleaning_time, price) mongo_logger.debug('user try charge cancel all', extra={ 'dt': current_time, 'user_id': user_id, 'booking_id': booking_id, 'price': price, 'cleaning_time': cleaning_time }) except Exception, e: print_err_detail(e) mongo_logger.error('failed to try charge failure', extra={'err': str(e)})
def get(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') date = self.get_argument('date', '') sigungu = self.get_argument('sigungu', '') customer_sigungu = self.get_argument('customer_sigungu', '') if date == None or date == '': date = dt.datetime.now() date = dt.datetime.strptime(date, '%Y%m%d') ret = {} try: session = Session() userdao = UserDAO() masterdao = MasterDAO() if sigungu == '': master_ids = masterdao.get_all_master_ids() else: master_ids = masterdao.get_master_ids_where_regions_available( sigungu) master_times = [] day_of_week = date.weekday() for mid in master_ids: master_schedules = [] '''start_times, end_times = masterdao.get_master_working_time(mid) start_times = start_times.split(',') end_times = end_times.split(',') st = start_times[day_of_week] if start_times[day_of_week] != '' else 8 et = end_times[day_of_week] if end_times[day_of_week] != '' else 8 st = int(st) et = int(et)''' st, et = masterdao.get_master_working_time_for_day( mid, date.date()) current_cleaning_counts = masterdao.get_master_completed_cleaning_count_at_date( mid, date) is_unassigned = masterdao.is_unassigned(mid) master_dict = {} master_dict['master_name'] = masterdao.get_master_name(mid) master_dict['master_id'] = mid master_dict['is_unassigned'] = is_unassigned master_dict[ 'is_beginner'] = True if current_cleaning_counts <= 10 else False master_dict[ 'current_cleaning_counts'] = current_cleaning_counts master_dict[ 'master_available_from'] = '0%s:00' % st if st < 10 else '%s:00' % st master_dict[ 'master_available_to'] = '0%s:00' % et if et < 10 else '%s:00' % et # for day off master_dict['is_day_off'] = masterdao.is_day_off( mid, date.date()) for row in session.query(Master, Booking, User, UserAddress, UserDefaultCard, Promotion, EventPromotionBooking) \ .outerjoin(Booking, Master.id == Booking.master_id) \ .join(User, User.id == Booking.user_id) \ .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \ .outerjoin(UserDefaultCard, User.id == UserDefaultCard.user_id) \ .outerjoin(Promotion, Booking.id == Promotion.booking_id) \ .outerjoin(EventPromotionBooking, Booking.id == EventPromotionBooking.booking_id) \ .filter(func.DATE(Booking.start_time) == date) \ .filter(Master.id == mid) \ .filter(or_(Booking.cleaning_status == BC.BOOKING_UPCOMMING, Booking.cleaning_status == BC.BOOKING_STARTED, Booking.cleaning_status == BC.BOOKING_COMPLETED)) \ .order_by(Master.name, Booking.start_time) \ .all(): key = userdao.get_user_salt_by_id(row.User.id)[:16] crypto = aes.MyCrypto(key) discount_price = 0 if row.Promotion != None: discount_price += row.Promotion.discount_price if row.EventPromotionBooking != None: discount_price += row.EventPromotionBooking.discount_price kind = row.UserAddress.kind if kind == 0: kind = '오피스텔' elif kind == 1: kind = '주택' else: kind = '아파트' address = crypto.decodeAES(row.UserAddress.address) if customer_sigungu in address: master_schedules.append( self.make_schedule_dict( row.Booking.id, row.User.devicetype, row.Booking.appointment_type, row.Booking.appointment_index, dt.datetime.strftime(row.Booking.start_time, '%H:%M'), dt.datetime.strftime( row.Booking.estimated_end_time, '%H:%M'), row.Booking.havereview, row.Booking.user_id, crypto.decodeAES(row.User.name), crypto.decodeAES(row.User.phone), crypto.decodeAES(row.UserAddress.address), row.UserAddress.size, kind, row.Booking.is_dirty, row.Booking.status, row.Booking.cleaning_status, row.Booking.payment_status, row.Booking.price_with_task, discount_price, row.Booking.routing_method, row.User.is_b2b, row.UserDefaultCard)) master_dict['time_list'] = master_schedules master_times.append(master_dict) ret['response'] = master_times self.set_status(Response.RESULT_OK) except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
def get(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') booking_id = self.get_argument('booking_id', '') ret = {} try: session = Session() row = session.query(Booking, Rating, OrderID11st, Master, User, UserAddress, MasterMemo) \ .outerjoin(Rating, Booking.id == Rating.booking_id) \ .outerjoin(OrderID11st, Booking.id == OrderID11st.booking_id) \ .join(Master, Booking.master_id == Master.id) \ .join(User, Booking.user_id == User.id) \ .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \ .outerjoin(MasterMemo, Booking.user_id == MasterMemo.user_id) \ .filter(Booking.id == booking_id) \ .order_by(desc(MasterMemo.datetime)) \ .first() if row == None: # no entry session.close() add_err_message_to_response(ret, err_dict['err_no_entry_to_cancel']) self.write(json.dumps(ret)) return userdao = UserDAO() key = userdao.get_user_salt_by_id(row.User.id)[:16] crypto = aes.MyCrypto(key) estimated_end_time = row.Booking.estimated_end_time if row.Booking.appointment_type == BC.ONE_TIME or row.Booking.appointment_type == BC.ONE_TIME_BUT_CONSIDERING: if row.Booking.is_dirty == 1: estimated_end_time -= dt.timedelta(hours=2) appointment_index = row.Booking.appointment_index appointment_type = row.Booking.appointment_type start_time = row.Booking.start_time end_time = row.Booking.estimated_end_time cleaning_duration = row.Booking.cleaning_duration / 6 is_dirty = row.Booking.is_dirty is_b2b = row.User.is_b2b duration_in_minutes = ( end_time - start_time ).seconds / 360 # 계산을 단순하게 하기 위해 60 * 60이 아닌 60 * 6으로 나눔. 그뒤 10배 커지는 것을 방지하기 위해 시급에서 10 나눈 값만 곱함 minutes_for_salary = duration_in_minutes #if duration_in_minutes > cleaning_duration: # 30분의 시간이 더 더해지는 경우가 존재. 그 경우, 해당 시간은 임금에 반영 되지 않음 # if appointment_index == 1 and (appointment_type == BC.ONE_TIME_A_MONTH or appointment_type == BC.TWO_TIME_A_MONTH or appointment_type == BC.FOUR_TIME_A_MONTH): # minutes_for_salary = duration_in_minutes - 5 if is_dirty == 1: minutes_for_salary -= 20 house_type = row.UserAddress.kind house_size = row.UserAddress.size expected_salary = 0 if is_b2b: expected_salary = int(minutes_for_salary * (row.Booking.wage_per_hour / 10)) else: if start_time >= dt.datetime(2017, 1, 1): expected_salary = minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR else: if appointment_type in BC.REGULAR_CLEANING_DICT: expected_salary = minutes_for_salary * BC.SALARY_FOR_REGULAR_IN_HOUR else: expected_salary = minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR if start_time.weekday( ) in BC.WEEKEND and start_time >= dt.datetime(2016, 12, 17): expected_salary += BC.WEEKEND_ADDED_SALARY booking_info = {} booking_info['booking_id'] = row.Booking.id booking_info['request_id'] = row.Booking.request_id booking_info['master_gender'] = row.Booking.master_gender booking_info['master_name'] = row.Master.name booking_info['master_pet_alergy'] = row.Master.pet_alergy booking_info[ 'user_memo'] = row.MasterMemo.memo if row.MasterMemo != None else '' booking_info['user_id'] = row.User.id booking_info['user_name'] = crypto.decodeAES(row.User.name) booking_info['user_email'] = row.User.email booking_info['user_gender'] = row.User.gender booking_info['user_phone'] = crypto.decodeAES(row.User.phone) booking_info['user_address'] = crypto.decodeAES( row.UserAddress.address) booking_info['jibun_address'] = convert_to_jibun_address( booking_info['user_address']) booking_info['user_home_size'] = row.UserAddress.size booking_info['user_home_kind'] = row.UserAddress.kind booking_info['devicetype'] = row.User.devicetype booking_info['appointment_type'] = row.Booking.appointment_type #booking_info['appointment_index'] = row.Booking.appointment_index booking_info['avg_rating'] = str( float((row.Rating.rate_clean + row.Rating.rate_master)) / 2.0) if row.Rating != None else 'None' booking_info[ 'clean_review'] = row.Rating.review_clean if row.Rating != None else '' booking_info[ 'master_review'] = row.Rating.review_master if row.Rating != None else '' booking_info['start_time'] = dt.datetime.strftime( row.Booking.start_time, '%Y-%m-%d %H:%M') booking_info['estimated_end_time'] = dt.datetime.strftime( estimated_end_time, '%Y-%m-%d %H:%M') booking_info['additional_task'] = row.Booking.additional_task booking_info['price'] = row.Booking.price_with_task booking_info['salary'] = expected_salary booking_info[ 'msg'] = row.Booking.message if row.Booking.message != None else '' booking_info[ 'trash_location'] = row.Booking.trash_location if row.Booking.trash_location != None else '' booking_info['enterhome'] = crypto.decodeAES( row.Booking.enterhome) if row.Booking.enterhome != None else '' booking_info['enterbuilding'] = crypto.decodeAES( row.Booking.enterbuilding ) if row.Booking.enterbuilding != None else '' #booking_info['havetools'] = row.Booking.havetools booking_info['havepet'] = row.Booking.havepet booking_info['status'] = row.Booking.status booking_info['payment_status'] = row.Booking.payment_status booking_info['cleaning_status'] = row.Booking.cleaning_status booking_info[ 'routing_method'] = row.Booking.routing_method if row.Booking.routing_method != None else '' booking_info['is_b2b'] = is_b2b booking_info[ '11st_id'] = row.OrderID11st.div_no if row.OrderID11st != None else '' ret['response'] = booking_info self.set_status(Response.RESULT_OK) #print booking_info['enterhome'] #print booking_info['enterbuilding'] except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
def get(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') year = self.get_argument('year', '') month = self.get_argument('month', '') if year == '' or month == '': now = dt.datetime.now() year = now.year month = now.month try: year = int(year) month = int(month) except: year = 2017 month = 2 ret = {} rb_users = [] userdao = UserDAO() try: session = Session() b1 = aliased(Booking) stmt = session.query(b1) \ .filter(b1.cleaning_status == 2) \ .filter(or_(b1.appointment_type == 1, b1.appointment_type == 2, b1.appointment_type == 4)) \ .subquery() rows = session.query(Booking, User, UserAddress, RegularBasisManagement) \ .join(User, Booking.user_id == User.id) \ .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \ .outerjoin(RegularBasisManagement, Booking.id == RegularBasisManagement.booking_id) \ .outerjoin(stmt, Booking.user_id == stmt.c.user_id) \ .filter(Booking.appointment_index == 1) \ .filter(Booking.cleaning_status == 2) \ .filter(or_(Booking.appointment_type == 1, Booking.appointment_type == 2, Booking.appointment_type == 4)) \ .filter(func.year(Booking.start_time) == year) \ .filter(func.month(Booking.start_time) == month) \ .filter(User.is_b2b == 0) \ .order_by(desc(Booking.start_time)) \ .all() for row in rows: key = userdao.get_user_salt_by_id(row.User.id)[:16] crypto = aes.MyCrypto(key) appointment_type = row.Booking.appointment_type if appointment_type == 1: appointment_type = '4주1회' elif appointment_type == 2: appointment_type = '2주1회' elif appointment_type == 4: appointment_type = '매주' user = {} user['booking_id'] = row.Booking.id user['name'] = crypto.decodeAES(row.User.name) user['phone'] = crypto.decodeAES(row.User.phone) user['address'] = crypto.decodeAES(row.UserAddress.address) user['reg_date'] = convert_datetime_format2(row.User.dateofreg) user['start_time'] = convert_datetime_format2( row.Booking.start_time) user['type'] = appointment_type user[ 'try_1st'] = row.RegularBasisManagement.try_1st if row.RegularBasisManagement != None else '진행안됨' user[ 'try_2nd'] = row.RegularBasisManagement.try_2nd if row.RegularBasisManagement != None else '진행안됨' user[ 'try_3rd'] = row.RegularBasisManagement.try_3rd if row.RegularBasisManagement != None else '진행안됨' user[ 'memo'] = row.RegularBasisManagement.memo if row.RegularBasisManagement != None else '' rb_users.append(user) ret['response'] = rb_users 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'])
def get(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') user_id = self.get_argument('user_id', '') ret = {} if user_id == '': self.set_status(Response.RESULT_BADREQUEST) add_err_message_to_response(ret, err_dict['invalid_param']) self.write(json.dumps(ret)) return mongo_logger = get_mongo_logger() mix = get_mixpanel() try: session = Session() userdao = UserDAO() key = userdao.get_user_salt_by_id(user_id)[:16] crypto = aes.MyCrypto(key) user_info = {} addresses = [] for row in session.query(User, UserAddress, UserDefaultAddress) \ .outerjoin(UserAddress, User.id == UserAddress.user_id) \ .outerjoin(UserDefaultAddress, User.id == UserDefaultAddress.user_id).filter(User.id == user_id) \ .order_by(UserAddress.user_addr_index) \ .all(): if row.UserAddress != None: kind = row.UserAddress.kind if kind == 3: kind = 0 addr = {'addr' : crypto.decodeAES(row.UserAddress.address), 'size' : row.UserAddress.size, 'kind' : kind, 'index' : row.UserAddress.user_addr_index} addresses.append(addr) default_idx = -1 if row.UserDefaultAddress != None: default_idx = row.UserDefaultAddress.address_idx user_info['name'] = crypto.decodeAES(row.User.name) user_info['email'] = row.User.email user_info['phone'] = crypto.decodeAES(row.User.phone) user_info['gender'] = row.User.gender user_info['auth_source'] = row.User.authsource user_info['devicetype'] = row.User.devicetype user_info['birthdate'] = crypto.decodeAES(row.User.dateofbirth) user_info['default_addr_idx'] = default_idx user_info['arr_address'] = addresses ret['response'] = user_info self.set_status(Response.RESULT_OK) mix.track(user_id, 'got userinfo', {'time' : dt.datetime.now()}) mongo_logger.debug('got userinfo', extra = {'user_id' : user_id}) print 'userinfo was successfully retrieved to', user_info['name'] except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql']) mix.track(user_id, 'failed to got userinfo', {'time' : dt.datetime.now()}) mongo_logger.debug('failed to got userinfo', extra = {'user_id' : user_id})
def notify_24hours_ahead(self): try: userdao = UserDAO() current_time = dt.datetime.now() print '-' * 40 print 'push before 24 hours' print 'current_time :', current_time hour = current_time.hour minute = 30 if current_time.minute >= 30 else 0 current_time = current_time + dt.timedelta(days=1) cron_time = current_time.replace(hour=hour, minute=minute, second=0, microsecond=0) print 'cron_time :', cron_time print '-' * 40 session = Session() result = session.query(Booking, Master, User, UserPushKey) \ .join(Master, Booking.master_id == Master.id) \ .join(User, Booking.user_id == User.id) \ .outerjoin(UserPushKey, User.id == UserPushKey.user_id) \ .filter(or_(Booking.cleaning_status == BC.BOOKING_UPCOMMING, Booking.cleaning_status == BC.BOOKING_STARTED)) \ .filter(func.date(Booking.start_time) == cron_time.date()) \ .filter(func.HOUR(Booking.start_time) == cron_time.time().hour) \ .filter(func.MINUTE(Booking.start_time) == cron_time.time().minute) \ .all() for row in result: key = userdao.get_user_salt_by_id(row.User.id)[:16] crypto = aes.MyCrypto(key) booking_id = row.Booking.id pushkey = row.UserPushKey.pushkey if row.UserPushKey != None else '' user_name = crypto.decodeAES(row.User.name) phone = crypto.decodeAES(row.User.phone) master_name = row.Master.name devicetype = row.User.devicetype price = row.Booking.price_with_task start_time = row.Booking.start_time print 'push to', user_name, master_name, booking_id print pushkey if devicetype != 'android': pushkey = crypto.decodeAES(row.User.phone) ampm = '오전' hour = start_time.hour if hour >= 12: if hour > 12: hour -= 12 ampm = '오후' minute = start_time.minute time_str = '%s %d시' % (ampm, hour) if minute == 30: time_str += ' 반' send_day_ahead_notification(devicetype, [pushkey], booking_id, user_name, time_str) send_alimtalk(phone, 'noti_24', user_name, master_name) except Exception, e: print_err_detail(e)
def notify_charge_failure(self): try: mongo_logger = get_mongo_logger() userdao = UserDAO() current_time = dt.datetime.now() print '-' * 40 print 'charge failure notification via alimtalk' print 'current_time :', current_time hour = current_time.hour minute = 30 if current_time.minute >= 30 else 0 cron_time = current_time.replace(hour=hour, minute=minute, second=0, microsecond=0) print 'cron_time :', cron_time print '-' * 40 session = Session() result = session.query(Booking, User) \ .join(User, Booking.user_id == User.id) \ .filter(Booking.cleaning_status == BC.BOOKING_COMPLETED) \ .filter(Booking.payment_status != BC.BOOKING_PAID) \ .filter(func.date(Booking.estimated_end_time) == cron_time.date()) \ .filter(func.HOUR(Booking.estimated_end_time) == cron_time.time().hour) \ .filter(func.MINUTE(Booking.estimated_end_time) == cron_time.time().minute) \ .filter(User.is_b2b == 0) \ .filter(Booking.source == 'hm') \ .all() for row in result: if 'b2b.com' in row.User.email: # b2b 무시 continue if row.User.is_b2b == 1: # b2b 무시 continue if row.Booking.source != 'hm': # 11번가 무시 continue key = userdao.get_user_salt_by_id(row.User.id)[:16] crypto = aes.MyCrypto(key) user_id = row.User.id phone = crypto.decodeAES(row.User.phone) cleaning_time = convert_datetime_format2( row.Booking.start_time) price = '{:,}원'.format(row.Booking.price_with_task) try: send_alimtalk(phone, 'notify_charge_failure', cleaning_time, price) mongo_logger.debug('user charge failure', extra={ 'dt': current_time, 'user_id': user_id, 'price': price, 'cleaning_time': cleaning_time }) except Exception, e: mongo_logger.error('err user charge failure', extra={ 'dt': current_time, 'user_id': user_id, 'price': price, 'cleaning_time': cleaning_time }) except Exception, e: print_err_detail(e) mongo_logger.error('failed to user charge failure', extra={'err': str(e)})
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 get(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') ret = {} try: session = Session() userdao = UserDAO() unassigned_bookings = [] # for modify request result = session.query(MasterBookingModifyRequest, Booking, Master, User) \ .join(Booking, Booking.id == MasterBookingModifyRequest.booking_id) \ .join(Master, MasterBookingModifyRequest.master_id == Master.id) \ .join(User, Booking.user_id == User.id) \ .filter(Booking.cleaning_status == 0) \ .order_by(Booking.start_time) \ .all() for row in result: key = userdao.get_user_salt_by_id(row.User.id)[:16] crypto = aes.MyCrypto(key) print 'request modification bookings list..' print row.MasterBookingModifyRequest.org_time print row.MasterBookingModifyRequest.master_id print row.Booking.master_id print row.Booking.start_time if row.MasterBookingModifyRequest.org_time != None and \ (row.MasterBookingModifyRequest.master_id != row.Booking.master_id or \ row.MasterBookingModifyRequest.org_time != row.Booking.start_time): continue booking = {} booking['id'] = row.MasterBookingModifyRequest.id booking['booking_id'] = row.Booking.id booking['user_name'] = crypto.decodeAES(row.User.name) booking['user_phone'] = crypto.decodeAES(row.User.phone) booking['master_name'] = row.Master.name booking['start_time'] = convert_datetime_format2( row.Booking.start_time) booking['reason'] = row.MasterBookingModifyRequest.reason booking['status'] = 'REQUESTED' unassigned_bookings.append(booking) # for unassigned result = session.query(Booking, Master, User) \ .join(Master, Booking.master_id == Master.id) \ .join(User, Booking.user_id == User.id) \ .filter(Master.active == 2) \ .filter(Booking.cleaning_status == 0) \ .order_by(Booking.start_time) \ .all() for row in result: key = userdao.get_user_salt_by_id(row.User.id)[:16] crypto = aes.MyCrypto(key) booking = {} booking['booking_id'] = row.Booking.id booking['user_name'] = crypto.decodeAES(row.User.name) booking['user_phone'] = crypto.decodeAES(row.User.phone) booking['master_name'] = row.Master.name booking['start_time'] = convert_datetime_format2( row.Booking.start_time) booking['reason'] = '업무 중단' booking['status'] = 'UNASSIGNED' unassigned_bookings.append(booking) ret['response'] = unassigned_bookings self.set_status(Response.RESULT_OK) except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
def post(self): self.set_header("Content-Type", "application/json") booking_id = self.get_argument('booking_id', '') reason_id = self.get_argument('reason_id', 0) etc_reason = self.get_argument('etc_reason', '') charge_amount = self.get_argument('charge_amount', 0) charge_amount = int(charge_amount) reason_id = int(reason_id) print 'cancel all charge amount : ', charge_amount 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)) \ .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 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 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: # 차액만큼 계속 더함 cancel_all_charge += charge_amount if current_payment_status == BC.BOOKING_PAID and current_cleaning_status == BC.BOOKING_UPCOMMING: new_status = BC.BOOKING_CANCELED_REFUND ''' partial = '1' if charge == 0: partial = '0' cancel_amount = int(price - charge) if cancel_amount > 0: ret_code, msg = cancel_payment(user_id, 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 ''' #row.Booking.modified_date = current_time 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: reason_row = reason.one() reason_row.kind = 1 '''if cancel_all_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 ''' 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) 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) master_pushkey = masterdao.get_master_pushkey(master_id) #send_all_bookings_canceled('android', [master_pushkey], booking_id, date) #send_alimtalk(master_phone, 'noti_manager_cancel_all', username, date, appointment_type_text) 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) except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
def post(self): self.set_header("Content-Type", "application/json") ret = {} date = self.get_argument('date') master_id = self.get_argument('master_id', '') # convert arguments date = dt.datetime.strptime(date, '%Y%m%d') try: session = Session() userdao = UserDAO() result = session.query(Booking, User, UserAddress) \ .join(User, Booking.user_id == User.id) \ .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \ .filter(Booking.master_id == master_id) \ .filter(func.date(Booking.start_time) == date) \ .filter(or_(Booking.cleaning_status == BC.BOOKING_UPCOMMING, Booking.cleaning_status == BC.BOOKING_STARTED, Booking.cleaning_status == BC.BOOKING_COMPLETED)) \ .order_by(Booking.start_time) \ .all() booking_list = [] for row in result: key = userdao.get_user_salt_by_id(row.Booking.user_id)[:16] crypto = aes.MyCrypto(key) booking = {} tooktime = time_to_minutes(timedelta_to_time(row.Booking.estimated_end_time - row.Booking.start_time)) if row.Booking.appointment_type == BC.ONE_TIME or row.Booking.appointment_type == BC.ONE_TIME_BUT_CONSIDERING: if row.Booking.is_dirty == 1: tooktime -= 120 start_time = row.Booking.start_time request_count = session.query(MasterBookingModifyRequest) \ .filter(MasterBookingModifyRequest.master_id == master_id) \ .filter(MasterBookingModifyRequest.booking_id == row.Booking.id) \ .filter(MasterBookingModifyRequest.org_time == start_time) \ .count() booking['booking_id'] = row.Booking.id booking['start_time'] = convert_time_format(row.Booking.start_time.time()) booking['name'] = crypto.decodeAES(row.User.name) booking['address'] = crypto.decodeAES(row.UserAddress.address) #booking['jibun_address'] = convert_to_jibun_address(booking['address']) booking['size'] = row.UserAddress.size booking['kind'] = row.UserAddress.kind booking['additional_task'] = row.Booking.additional_task booking['appointment_type'] = row.Booking.appointment_type booking['index'] = row.Booking.appointment_index booking['tooktime'] = int(tooktime / 6) booking['status'] = row.Booking.status booking['cleaning_status'] = row.Booking.cleaning_status booking['payment_status'] = row.Booking.payment_status booking['is_dirty'] = row.Booking.is_dirty booking['request_modify'] = request_count booking_list.append(booking) dayoff = False is_open_time = False free_from = None free_to = None row = session.query(MasterScheduleByDate) \ .filter(MasterScheduleByDate.master_id == master_id) \ .filter(MasterScheduleByDate.date == date) \ .first() if row != None: if row.active == 0: dayoff = True is_open_time = True free_from = row.free_from.strftime('%H:%M') free_to = row.free_to.strftime('%H:%M') ret['response'] = {'booking_list' : booking_list, 'free_from' : free_from, 'free_to' : free_to, 'is_open_time' : is_open_time, 'dayoff' : dayoff} self.set_status(Response.RESULT_OK) except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
def get(self): self.set_header("Content-Type", "application/json") ret = {} try: session = Session() bookings = [] now = dt.datetime.now() result = session.query(Booking, Promotion, EventPromotionBooking, Master, User, UserAddress) \ .outerjoin(Promotion, Booking.id == Promotion.booking_id) \ .outerjoin(EventPromotionBooking, Booking.id == EventPromotionBooking.booking_id) \ .join(Master, Master.id == Booking.master_id) \ .join(User, Booking.user_id == User.id) \ .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \ .filter(and_(Booking.appointment_index == 1, Booking.cleaning_status >= BC.BOOKING_UPCOMMING)) \ .order_by(desc(Booking.booking_time), desc(Booking.start_time)) \ .limit(40) for row in result: userdao = UserDAO() key = userdao.get_user_salt_by_id(row.User.id)[:16] crypto = aes.MyCrypto(key) booking_info = {} booking_info['booking_id'] = row.Booking.id booking_info['request_id'] = row.Booking.request_id booking_info['master_gender'] = row.Booking.master_gender booking_info['master_name'] = row.Master.name booking_info['user_id'] = row.User.id booking_info['user_name'] = crypto.decodeAES(row.User.name) booking_info['user_email'] = row.User.email booking_info['user_gender'] = row.User.gender booking_info['user_phone'] = crypto.decodeAES(row.User.phone) booking_info['user_address'] = crypto.decodeAES(row.UserAddress.address) booking_info['user_home_size'] = row.UserAddress.size booking_info['user_home_kind'] = row.UserAddress.kind booking_info['devicetype'] = row.User.devicetype booking_info['appointment_type'] = row.Booking.appointment_type booking_info['appointment_index'] = row.Booking.appointment_index booking_info['start_time'] = dt.datetime.strftime(row.Booking.start_time, '%Y-%m-%d %H:%M') booking_info['estimated_end_time'] = dt.datetime.strftime(row.Booking.estimated_end_time, '%Y-%m-%d %H:%M') booking_info['additional_task'] = row.Booking.additional_task booking_info['price'] = row.Booking.price_with_task booking_info['promotion_code'] = row.Promotion.promotion_code if row.Promotion != None else 'No code' booking_info['promotion_amount'] = row.Promotion.discount_price if row.Promotion != None else '0' booking_info['event_promotion_code'] = row.EventPromotionBooking.event_name if row.EventPromotionBooking != None else 'No event code' booking_info['event_promotion_amount'] = row.EventPromotionBooking.discount_price if row.EventPromotionBooking != None else '0' booking_info['msg'] = row.Booking.message if row.Booking.message != None else '' booking_info['trash_location'] = row.Booking.trash_location if row.Booking.trash_location != None else '' booking_info['enterhome'] = crypto.decodeAES(row.Booking.enterhome) if row.Booking.enterhome != None else '' booking_info['enterbuilding'] = crypto.decodeAES(row.Booking.enterbuilding) if row.Booking.enterbuilding != None else '' booking_info['havepet'] = row.Booking.havepet booking_info['status'] = row.Booking.status booking_info['cleaning_status'] = row.Booking.cleaning_status booking_info['payment_status'] = row.Booking.payment_status booking_info['devicetype'] = row.User.devicetype.lower() booking_info['booking_time'] = dt.datetime.strftime(row.Booking.booking_time, '%Y-%m-%d %H:%M') if row.Booking.booking_time != None else '' bookings.append(booking_info) print bookings ret['response'] = bookings self.set_status(Response.RESULT_OK) except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
def post(self): self.set_header("Content-Type", "application/json") booking_id = self.get_argument('booking_id', '') reason_id = self.get_argument('reason_id', 0) etc_reason = self.get_argument('etc_reason', '') reason_id = int(reason_id) ret = {} mongo_logger = get_mongo_logger() mix = get_mixpanel() try: session = Session() try: row = session.query(Booking, Master, User, UserAddress) \ .join(Master, Booking.master_id == Master.id) \ .join(User, Booking.user_id == User.id) \ .join(UserDefaultAddress, User.id == UserDefaultAddress.user_id) \ .join(UserAddress, and_(UserAddress.user_id == UserDefaultAddress.user_id, UserAddress.user_addr_index == UserDefaultAddress.address_idx)) \ .filter(Booking.id == booking_id) \ .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \ .one() except NoResultFound, e: session.close() self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_no_entry_to_cancel']) self.write(json.dumps(ret)) return charge = 0 new_status = BC.BOOKING_CANCELED_CHARGE request_id = row.Booking.request_id user_id = row.Booking.user_id appointment_index = row.Booking.appointment_index appointment_time = row.Booking.start_time appointment_type = row.Booking.appointment_type current_status = row.Booking.status current_cleaning_status = row.Booking.cleaning_status current_payment_status = row.Booking.payment_status price = row.Booking.price_with_task now = dt.datetime.now() diff_in_hours = (appointment_time - now).total_seconds() / 3600 if diff_in_hours >= 24: charge = price * BC.BOOKING_CHARGE_RATE_NO elif 4 <= diff_in_hours < 24: charge = price * BC.BOOKING_CHARGE_RATE_30 else: charge = price * BC.BOOKING_CHARGE_RATE_50 if current_payment_status == BC.BOOKING_PAID: new_status = BC.BOOKING_CANCELED_REFUND ''' partial = '1' if charge == 0: partial = '0' cancel_amount = int(price - charge) if cancel_amount > 0: ret_code, msg = cancel_payment(user_id, booking_id, cancel_amount, partial) if ret_code == False: session.close() self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, msg) self.write(json.dumps(ret)) return''' #row.Booking.modified_date = now row.Booking.charging_price = int(charge) row.Booking.status = new_status row.Booking.cleaning_status = BC.BOOKING_CANCELED row.Booking.payment_status = new_status masterdao = MasterDAO() userdao = UserDAO() key = userdao.get_user_salt_by_id(user_id)[:16] crypto = aes.MyCrypto(key) # push to homemaster via sms master_id = row.Master.id master_phone = str(row.Master.phone) master_name = str(row.Master.name) username = str(crypto.decodeAES(row.User.name)) userphone = str(crypto.decodeAES(row.User.phone)) date = str(convert_datetime_format(row.Booking.start_time)) addr = str(crypto.decodeAES(row.UserAddress.address)) appointment_type_text = '' if appointment_type == BC.ONE_TIME or appointment_type == BC.ONE_TIME_BUT_CONSIDERING: appointment_type_text = '1회' elif appointment_type == BC.FOUR_TIME_A_MONTH: appointment_type_text = '매주' elif appointment_type == BC.TWO_TIME_A_MONTH: appointment_type_text = '2주 1회' elif appointment_type == BC.ONE_TIME_A_MONTH: appointment_type_text = '4주 1회' #sms_sender = SMS_Sender() #text = BOOKING_CANCEL_TEXT % (username, userphone, master_name, date) #print sms_sender.send_for_manager(sender = MAIN_CALL, mtype = 'sms', to = MANAGERS_CALL, subject = BOOKING_TEXT_SUBJECT, text = text) for manager_phone in MANAGERS_CALL.split(','): send_alimtalk(manager_phone, 'noti_manager_cancel', username, date, appointment_type_text) master_pushkey = masterdao.get_master_pushkey(master_id) #send_booking_canceled('android', [master_pushkey], booking_id, date) print 'master_pushkey', master_pushkey print booking_id, date #send_alimtalk(master_phone, 'noti_manager_cancel', username, date, appointment_type_text) # adjust appointment index index_result = session.query(Booking).filter( Booking.request_id == request_id).filter( Booking.appointment_index > appointment_index).all() for index_row in index_result: index_row.appointment_index -= 1 CANCEL = 0 cancel_reason = CancelReason(booking_id=booking_id, user_id=user_id, reason_id=reason_id, etc_reason=etc_reason, kind=CANCEL, cancel_time=dt.datetime.now()) session.add(cancel_reason) session.commit() mix.track( user_id, 'cancel', { 'time': dt.datetime.now(), 'reason_id': reason_id, 'etc_reason': etc_reason }) mongo_logger.debug('%s was canceled' % booking_id, extra={ 'user_id': user_id, 'booking_id': booking_id }) ret['response'] = Response.SUCCESS self.set_status(Response.RESULT_OK)
def 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 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") master_id = self.get_argument('master_id', '') date = self.get_argument('date', '') ret = {} date = dt.datetime.strptime(date, '%Y%m%d') try: session = Session() userdao = UserDAO() masterdao = MasterDAO() content = '' result = session.query(Booking, Master, User, UserAddress) \ .join(Master, Booking.master_id == Master.id) \ .join(User, Booking.user_id == User.id) \ .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \ .filter(Booking.master_id == master_id) \ .filter(func.date(Booking.start_time) == date) \ .filter(or_(Booking.cleaning_status == BC.BOOKING_UPCOMMING, Booking.cleaning_status == BC.BOOKING_COMPLETED)) \ .order_by(Booking.start_time) \ .all() word_idx = 1 master_name = masterdao.get_master_name(master_id) master_phone = masterdao.get_master_phone(master_id) for row in result: key = userdao.get_user_salt_by_id(row.User.id)[:16] crypto = aes.MyCrypto(key) master_phone = str(row.Master.phone) master_name = str(row.Master.name) user_name = str(crypto.decodeAES(row.User.name)) appointment_index = str(row.Booking.appointment_index) enterbuilding = str( crypto.decodeAES(row.Booking.enterbuilding) ) if row.Booking.enterbuilding != None else str('') enterhome = str(crypto.decodeAES(row.Booking.enterhome) ) if row.Booking.enterhome != None else str('') date_str = str(convert_datetime_format2( row.Booking.start_time)) address = str(crypto.decodeAES(row.UserAddress.address)) appointment_type = str(4 / row.Booking.appointment_type) + '주' \ if row.Booking.appointment_type != BC.ONE_TIME \ and row.Booking.appointment_type != BC.ONE_TIME_BUT_CONSIDERING \ else '1회' additional_task = additional_task_string( row.Booking.additional_task) take_time = timedelta_to_time(row.Booking.estimated_end_time - row.Booking.start_time) take_time_str = '%d시간 %d분' % (take_time.hour, take_time.minute) message = str(row.Booking.message) trash_location = str(row.Booking.trash_location) text = CONFIRM_UPDATE_BODY % ( user_name, appointment_index, date_str, address, appointment_type, additional_task, take_time_str, enterbuilding, enterhome, message, trash_location) content += str(word_idx) + '. ' + str(text) + '\n\n' word_idx += 1 booking_date = dt.datetime.strftime(date, '%m월%d일') title = '%s 홈마스터님, %s 일정입니다.' % (master_name, booking_date) if word_idx == 1: content = '홈마스터님 내일 일정은 없습니다.' title = '홈마스터님 내일 일정은 없습니다.' ret['response'] = { 'content': content, 'phone': master_phone, 'subject': title } 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'])
row = session.query(Booking, User) \ .join(User, Booking.user_id == User.id) \ .filter(Booking.id == booking_id) \ .filter(Booking.cleaning_status == BC.BOOKING_UPCOMMING) \ .one() except NoResultFound, e: session.close() return False except MultipleResultsFound, e: session.close() return False userdao = UserDAO() key = userdao.get_user_salt_by_id(row.User.id)[:16] crypto = aes.MyCrypto(key) user_name = str(crypto.decodeAES(row.User.name)) user_phone = str(crypto.decodeAES(row.User.phone)) text = '%s 고객님 감사드립니다 :)\n홈마스터 서비스에 대한 안내는 첨부된 이미지를 참고 부탁드립니다~' % user_name sms_sender = SMS_Sender() sms_sender.send_for_manager(sender = MAIN_CALL, mtype = 'mms', to = user_phone, subject = NOTIFY_TEXT_SUBJECT, text = str(text), image='/home/dev/customer_mms.png') except Exception, e: print_err_detail(e) finally: session.close() return True
def get(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') datetime = self.get_argument('datetime', '') datetime = dt.datetime.strptime(datetime, '%Y%m%d') ret = {} try: session = Session() userdao = UserDAO() users_register = userdao.get_users_who_register_only(datetime) users_address = userdao.get_users_who_add_address_only(datetime) user_groups = [users_register, users_address] for user_group in user_groups: for user in user_group: if 'sigungu_id' in user: del user['sigungu_id'] try: user_id = user['id'] row = session.query(UserReason) \ .filter(UserReason.user_id == user_id) \ .one() user['contact1'] = row.contact1 user['contact2'] = row.contact2 user['contact3'] = row.contact3 user['contact1_time'] = convert_datetime_format2( row.contact1_time ) if row.contact1_time != None else '' user['contact2_time'] = convert_datetime_format2( row.contact2_time ) if row.contact2_time != None else '' user['contact3_time'] = convert_datetime_format2( row.contact3_time ) if row.contact3_time != None else '' user['reason'] = row.reason user['status'] = row.status user['possible'] = row.possible except Exception, e: #print_err_detail(e) user['contact1'] = '' user['contact2'] = '' user['contact3'] = '' user['contact1_time'] = '' user['contact2_time'] = '' user['contact3_time'] = '' user['reason'] = '' user['status'] = '' user['possible'] = '' result = session.query(UserReason, User, Booking) \ .join(User, UserReason.user_id == User.id) \ .join(Booking, User.id == Booking.user_id) \ .filter(UserReason.status == '성공') \ .group_by(User.id) \ .all() users_success = [] for row in result: key = userdao.get_user_salt_by_id(row.User.id)[:16] crypto = aes.MyCrypto(key) user_name = crypto.decodeAES(row.User.name) user_phone = crypto.decodeAES(row.User.phone) booking_id = row.Booking.id users_success.append({'name' : user_name, \ 'phone' : user_phone, \ 'booking_id' : booking_id }) user_in_funnel = {} user_in_funnel['register'] = users_register user_in_funnel['address'] = users_address user_in_funnel['success'] = users_success ret['response'] = user_in_funnel self.set_status(Response.RESULT_OK)