def get(self): self.set_header("Content-Type", "application/json") ret = {} try: session = Session() userdao = UserDAO() bookingdao = BookingDAO() # get last saturday now = dt.datetime.now() if week != 0: offset = ((now.weekday() - FRIDAY) % 7) + (week - 1) * 7 now -= dt.timedelta(days=offset) offset = (now.weekday() - SATURDAY) % 7 last_saturday = (now - dt.timedelta(days=offset)).date() now = now.date() # rating # 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 get(self): self.set_header("Content-Type", "application/json") master_id = self.get_argument('master_id', '') year = self.get_argument('yyyy', 2016) month = self.get_argument('mm', 9) ret = {} try: session = Session() masterdao = MasterDAO() userdao = UserDAO() bookingdao = BookingDAO() CANCELED_RATE = 0.5 year = int(year) month = int(month) first_day, last_day = get_month_day_range(dt.date(year, month, 7)) result = session.query(Booking, Master, User, UserAddress) \ .join(Master, Booking.master_id == Master.id) \ .join(User, Booking.user_id == User.id) \ .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \ .filter(and_(func.date(Booking.start_time) >= first_day, func.date(Booking.start_time) <= last_day)) \ .filter(Booking.master_id == master_id) \ .order_by(Booking.master_id, Booking.start_time) \ .all() monthly_salary = 0 monthly_salaries = [] for row in result: user_name = userdao.get_user_name(row.Booking.user_id) org_price = row.Booking.price_with_task status = row.Booking.cleaning_status appointment_index = row.Booking.appointment_index appointment_type = row.Booking.appointment_type additional_task = row.Booking.additional_task start_time = row.Booking.start_time end_time = row.Booking.estimated_end_time cleaning_duration = row.Booking.cleaning_duration / 6 charging_price = row.Booking.charging_price is_dirty = row.Booking.is_dirty is_b2b = row.User.is_b2b duration_in_minutes = ( end_time - start_time ).seconds / 360 # 계산을 단순하게 하기 위해 60 * 60이 아닌 60 * 6으로 나눔. 그뒤 10배 커지는 것을 방지하기 위해 시급에서 10 나눈 값만 곱함 minutes_for_salary = duration_in_minutes #if duration_in_minutes > cleaning_duration: # 30분의 시간이 더 더해지는 경우가 존재. 그 경우, 해당 시간은 임금에 반영 되지 않음 # if appointment_index == 1 and (appointment_type == BC.ONE_TIME_A_MONTH or appointment_type == BC.TWO_TIME_A_MONTH or appointment_type == BC.FOUR_TIME_A_MONTH): # minutes_for_salary = duration_in_minutes - 5 if is_dirty == 1: # 똥집인 경우 2시간 제외해야함 minutes_for_salary -= 20 house_type = row.UserAddress.kind house_size = row.UserAddress.size if row.Booking.cleaning_status == BC.BOOKING_COMPLETED or \ row.Booking.cleaning_status == BC.BOOKING_STARTED or \ row.Booking.cleaning_status == BC.BOOKING_UPCOMMING: if is_b2b: monthly_salary += int(minutes_for_salary * (row.Booking.wage_per_hour / 10)) else: # 오피스텔 13평 이하, 주택 7평 이하는 시급 14000 if appointment_type in BC.REGULAR_CLEANING_DICT: monthly_salary += minutes_for_salary * BC.SALARY_FOR_REGULAR_IN_HOUR else: monthly_salary += minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR if start_time.weekday( ) in BC.WEEKEND and start_time >= dt.datetime( 2016, 12, 17): monthly_salary += BC.WEEKEND_ADDED_SALARY monthly_salary += bookingdao.get_extra_charge( row.Booking.id) elif row.Booking.payment_status == BC.BOOKING_CANCELED_CHARGE or \ row.Booking.payment_status == BC.BOOKING_CANCELED_REFUND: monthly_salary += int(charging_price * CANCELED_RATE) penalty_amount = masterdao.get_master_penalties( master_id, first_day, last_day) monthly_salary = int(monthly_salary * 0.967) # 3.3% 제외 actual_monthly_salary = monthly_salary - penalty_amount monthly_salary = '{:,}'.format(monthly_salary) actual_monthly_salary = '{:,}'.format(actual_monthly_salary) penalty_amount = '{:,}'.format(penalty_amount) from_date_str = dt.datetime.strftime(first_day, '%Y%m%d') to_date_str = dt.datetime.strftime(last_day, '%Y%m%d') monthly_salaries.append({ 'date_from': from_date_str, 'date_to': to_date_str, 'salary': monthly_salary, 'penalty_amount': penalty_amount, 'actual_monthly_salary': actual_monthly_salary }) master_row = session.query(Master).filter( Master.id == master_id).one() master_name = master_row.name master_phone = master_row.phone ret['response'] = { 'master_name': master_name, 'master_phone': master_phone, 'monthly_salary': monthly_salaries } self.set_status(Response.RESULT_OK) except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
def 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_mybookings(self, session, user_id, mode): bookings = [] now = dt.datetime.now() bookingdao = BookingDAO() try: if mode == 'upcoming': results = session.query(Booking) \ .group_by(Booking.request_id) \ .having(Booking.user_id == user_id) \ .order_by(func.min(Booking.start_time)) \ .all() for booking_row in results: booking_result = session.query(Booking, Master, User) \ .join(Master, Booking.master_id == Master.id) \ .join(User, Booking.user_id == User.id) \ .filter(Booking.request_id == booking_row.request_id) \ .filter(or_(Booking.cleaning_status == BC.BOOKING_UPCOMMING, Booking.cleaning_status == BC.BOOKING_STARTED, Booking.cleaning_status == BC.BOOKING_CANCELED)) \ .filter(func.date(Booking.start_time) >= now.date()) \ .order_by(Booking.start_time) \ .all() for row in booking_result: 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 booking = {} booking['id'] = row.Booking.id booking['request_id'] = row.Booking.request_id booking['index'] = row.Booking.appointment_index booking['devicetype'] = row.User.devicetype booking['datetime'] = convert_datetime_format( row.Booking.start_time) booking['tooktime'] = int(tooktime / 6) # to make 2.5 to 25 booking[ 'additional_task'] = row.Booking.additional_task booking[ 'master_name'] = row.Master.name if row.Master != None else '' booking[ 'master_img_url'] = row.Master.img_url if row.Master != None else '' booking['status'] = row.Booking.cleaning_status booking['payment_status'] = row.Booking.payment_status booking[ 'appointment_type'] = row.Booking.appointment_type booking['cancel_reason'] = bookingdao.get_cancel_reason( row.Booking.id ) if row.Booking.cleaning_status == BC.BOOKING_CANCELED else '' bookings.append(booking) elif mode == 'past': results = session.query(Booking) \ .group_by(Booking.request_id) \ .having(Booking.user_id == user_id) \ .order_by(func.min(Booking.start_time)) \ .all() print now.date() for booking_row in results: booking_result = session.query(Booking, Master) \ .join(Master, Booking.master_id == Master.id) \ .filter(Booking.request_id == booking_row.request_id) \ .filter(or_(Booking.cleaning_status == BC.BOOKING_COMPLETED, Booking.cleaning_status == BC.BOOKING_STARTED, Booking.cleaning_status == BC.BOOKING_CANCELED)) \ .filter(func.date(Booking.start_time) <= now.date()) \ .order_by(Booking.start_time) \ .all() for row in booking_result: if row.Booking.cleaning_status == BC.BOOKING_COMPLETED: end_time = row.Booking.end_time else: end_time = row.Booking.estimated_end_time if row.Booking.working_start_time != None: tooktime = time_to_minutes( timedelta_to_time( end_time - row.Booking.working_start_time)) else: tooktime = time_to_minutes( timedelta_to_time(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 booking = {} booking['id'] = row.Booking.id booking['request_id'] = row.Booking.request_id booking['index'] = row.Booking.appointment_index booking['datetime'] = convert_datetime_format( row.Booking.start_time) booking['tooktime'] = int(tooktime / 6) # to make 2.5 to 25 booking['havereview'] = row.Booking.havereview booking[ 'additional_task'] = row.Booking.additional_task booking[ 'master_name'] = row.Master.name if row.Master != None else '' booking[ 'master_img_url'] = row.Master.img_url if row.Master != None else '' booking['status'] = row.Booking.cleaning_status booking['payment_status'] = row.Booking.payment_status booking[ 'appointment_type'] = row.Booking.appointment_type booking['cancel_reason'] = bookingdao.get_cancel_reason( row.Booking.id ) if row.Booking.cleaning_status == BC.BOOKING_CANCELED else '' bookings.append(booking) except Exception, e: print_err_detail(e) raise Exception(e)
def get(self): self.set_header("Content-Type", "application/json") week = self.get_argument('week', 0) # n weeks before week = int(week) ret = {} FRIDAY = 4 SATURDAY = 5 CANCELED_RATE = 0.5 try: session = Session() userdao = UserDAO() masterdao = MasterDAO() bookingdao = BookingDAO() # get last saturday now = dt.datetime.now() if week != 0: offset = ((now.weekday() - FRIDAY) % 7) + (week - 1) * 7 now -= dt.timedelta(days=offset) offset = (now.weekday() - SATURDAY) % 7 last_saturday = (now - dt.timedelta(days=offset)).date() now = now.date() result = session.query(Booking, Master, User, UserAddress) \ .join(Master, Booking.master_id == Master.id) \ .join(User, Booking.user_id == User.id) \ .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \ .filter(Master.active != 0) \ .filter(and_(func.date(Booking.start_time) >= last_saturday, func.date(Booking.start_time) <= now)) \ .filter(or_(Booking.cleaning_status == BC.BOOKING_COMPLETED, \ and_(Booking.cleaning_status == BC.BOOKING_CANCELED, \ or_(Booking.payment_status == BC.BOOKING_CANCELED_REFUND, \ Booking.payment_status == BC.BOOKING_CANCELED_CHARGE)))) \ .order_by(Booking.master_id, Booking.start_time) \ .all() weekly_salary = 0 master_salaries = [] start_period = last_saturday end_period = now last_saturday = dt.datetime.strftime(last_saturday, '%Y%m%d') now = dt.datetime.strftime(now, '%Y%m%d') prev_master_id = None for row in result: if row.Booking.user_id == '81c2f5c1-7295-489d-8bb0-334121060ae3': continue user_name = userdao.get_user_name(row.Booking.user_id) org_price = row.Booking.price_with_task status = row.Booking.cleaning_status appointment_index = row.Booking.appointment_index appointment_type = row.Booking.appointment_type start_time = row.Booking.start_time end_time = row.Booking.estimated_end_time cleaning_duration = row.Booking.cleaning_duration / 6 charging_price = row.Booking.charging_price is_dirty = row.Booking.is_dirty is_b2b = row.User.is_b2b duration_in_minutes = ( end_time - start_time ).seconds / 360 # 계산을 단순하게 하기 위해 60 * 60이 아닌 60 * 6으로 나눔. 그뒤 10배 커지는 것을 방지하기 위해 시급에서 10 나눈 값만 곱함 minutes_for_salary = duration_in_minutes #if duration_in_minutes > cleaning_duration: # 30분의 시간이 더 더해지는 경우가 존재. 그 경우, 해당 시간은 임금에 반영 되지 않음 # if appointment_index == 1 and (appointment_type == BC.ONE_TIME_A_MONTH or appointment_type == BC.TWO_TIME_A_MONTH or appointment_type == BC.FOUR_TIME_A_MONTH): # minutes_for_salary = duration_in_minutes - 5 if is_dirty == 1: minutes_for_salary -= 20 house_type = row.UserAddress.kind house_size = row.UserAddress.size extra_charge = 0 if row.Booking.cleaning_status == BC.BOOKING_COMPLETED: if is_b2b: weekly_salary = int(minutes_for_salary * (row.Booking.wage_per_hour / 10)) else: # 오피스텔 13평 이하, 주택 7평 이하는 시급 14000 weekly_salary = 0 if start_time >= dt.datetime(2017, 1, 1): weekly_salary = minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR else: if appointment_type in BC.REGULAR_CLEANING_DICT: weekly_salary = minutes_for_salary * BC.SALARY_FOR_REGULAR_IN_HOUR else: weekly_salary = minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR if start_time.weekday( ) in BC.WEEKEND and start_time >= dt.datetime( 2016, 12, 17): weekly_salary += BC.WEEKEND_ADDED_SALARY extra_charge = bookingdao.get_extra_charge(row.Booking.id) weekly_salary += extra_charge elif row.Booking.payment_status == BC.BOOKING_CANCELED_CHARGE or \ row.Booking.payment_status == BC.BOOKING_CANCELED_REFUND: weekly_salary = int(charging_price * CANCELED_RATE) if prev_master_id == None or prev_master_id != row.Booking.master_id: # 변함 salary = {} salary_detail = [] bank_name, bank_code, account_no = masterdao.get_master_account( row.Booking.master_id) salary['weekly_salary'] = 0 salary['master_name'] = row.Master.name salary['master_account'] = { 'bank_name': bank_name, 'bank_code': bank_code, 'account_no': account_no } salary['master_phone'] = row.Master.phone salary['weekly_salary'] += weekly_salary salary[ 'penalty_amount'] = 0 #masterdao.get_master_penalties(row.Booking.master_id, start_period, end_period) if weekly_salary > 0: salary_detail.append({ 'org_price': org_price, 'charging_price': charging_price, 'salary': weekly_salary, 'extra_charge': extra_charge, 'status': status, 'start_time': dt.datetime.strftime(start_time, '%Y-%m-%d %H:%M'), 'end_time': dt.datetime.strftime(end_time, '%Y-%m-%d %H:%M'), 'cleaning_index': appointment_index, 'user_name': user_name }) salary['salary_detail'] = salary_detail master_salaries.append(salary) else: salary['weekly_salary'] += weekly_salary if weekly_salary > 0: salary_detail.append({ 'org_price': org_price, 'charging_price': charging_price, 'salary': weekly_salary, 'extra_charge': extra_charge, 'status': status, 'start_time': dt.datetime.strftime(start_time, '%Y-%m-%d %H:%M'), 'end_time': dt.datetime.strftime(end_time, '%Y-%m-%d %H:%M'), 'cleaning_index': appointment_index, 'user_name': user_name }) prev_master_id = row.Master.id total_salaries = 0 for ms in master_salaries: if start_time >= dt.datetime(2017, 1, 1): ms['weekly_salary'] = int(ms['weekly_salary']) else: ms['weekly_salary'] = int(ms['weekly_salary'] * 0.967) total_salaries += (ms['weekly_salary'] - ms['penalty_amount']) ms['actual_weekly_salary'] = '{:,}'.format( ms['weekly_salary'] - ms['penalty_amount']) total_salaries = '{:,}'.format(total_salaries) master_salaries = sorted(master_salaries, key=lambda x: (x['master_name'])) ret['response'] = { 'date_from': last_saturday, 'date_to': now, 'master_salaries': master_salaries, 'total_salaries': total_salaries } self.set_status(Response.RESULT_OK) except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
def get(self): self.set_header("Content-Type", "application/json") year = self.get_argument('yyyy', 2016) month = self.get_argument('mm', 9) ret = {} try: session = Session() masterdao = MasterDAO() userdao = UserDAO() bookingdao = BookingDAO() CANCELED_RATE = 0.5 year = int(year) month = int(month) first_day, last_day = get_month_day_range(dt.date(year, month, 7)) result = session.query(Booking, Master, User, UserAddress) \ .join(Master, Booking.master_id == Master.id) \ .join(User, Booking.user_id == User.id) \ .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \ .filter(and_(func.date(Booking.start_time) >= first_day, func.date(Booking.start_time) <= last_day)) \ .filter(Master.active == 1) \ .order_by(Booking.master_id, Booking.start_time) \ .all() monthly_salary_dict = {} prev_master_id = None for row in result: user_name = userdao.get_user_name(row.Booking.user_id) master_id = row.Booking.master_id master_name = row.Master.name master_phone = row.Master.phone org_price = row.Booking.price_with_task status = row.Booking.cleaning_status #appointment_index = row.Booking.appointment_index appointment_type = row.Booking.appointment_type additional_task = row.Booking.additional_task start_time = row.Booking.start_time end_time = row.Booking.estimated_end_time #cleaning_duration = row.Booking.cleaning_duration / 6 charging_price = row.Booking.charging_price is_dirty = row.Booking.is_dirty is_b2b = row.User.is_b2b duration_in_minutes = ( end_time - start_time ).seconds / 360 # 계산을 단순하게 하기 위해 60 * 60이 아닌 60 * 6으로 나눔. 그뒤 10배 커지는 것을 방지하기 위해 시급에서 10 나눈 값만 곱함 minutes_for_salary = duration_in_minutes #if duration_in_minutes > cleaning_duration: # 30분의 시간이 더 더해지는 경우가 존재. 그 경우, 해당 시간은 임금에 반영 되지 않음 # if appointment_index == 1 and (appointment_type == BC.ONE_TIME_A_MONTH or appointment_type == BC.TWO_TIME_A_MONTH or appointment_type == BC.FOUR_TIME_A_MONTH): # minutes_for_salary = duration_in_minutes - 5 monthly_salary = 0 if is_dirty == 1: # 똥집인 경우 2시간 제외해야함 minutes_for_salary -= 20 house_type = row.UserAddress.kind house_size = row.UserAddress.size if row.Booking.cleaning_status == BC.BOOKING_COMPLETED or \ row.Booking.cleaning_status == BC.BOOKING_STARTED or \ row.Booking.cleaning_status == BC.BOOKING_UPCOMMING: if is_b2b: monthly_salary = int(minutes_for_salary * (row.Booking.wage_per_hour / 10)) else: # 오피스텔 13평 이하, 주택 7평 이하는 시급 14000 if appointment_type in BC.REGULAR_CLEANING_DICT: monthly_salary = minutes_for_salary * BC.SALARY_FOR_REGULAR_IN_HOUR else: monthly_salary = minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR if start_time.weekday( ) in BC.WEEKEND and start_time >= dt.datetime( 2016, 12, 17): monthly_salary += BC.WEEKEND_ADDED_SALARY monthly_salary += bookingdao.get_extra_charge( row.Booking.id) elif row.Booking.payment_status == BC.BOOKING_CANCELED_CHARGE or \ row.Booking.payment_status == BC.BOOKING_CANCELED_REFUND: monthly_salary = int(charging_price * CANCELED_RATE) monthly_salary = monthly_salary * 0.967 # 3.3% 제외 # 마스터가 신규 if prev_master_id == None or master_id != prev_master_id: penalty_amount = masterdao.get_master_penalties( master_id, first_day, last_day) monthly_salary_dict[master_id] = { 'name': master_name, 'phone': master_phone, 'monthly_salary': monthly_salary, 'penalty_amount': penalty_amount } else: monthly_salary_dict[master_id][ 'monthly_salary'] += monthly_salary prev_master_id = master_id monthly_salary_dict = {value['name'] : {'master_id' : mid, \ 'phone' : value['phone'], \ 'monthly_salary' : int(value['monthly_salary']), \ 'monthly_salary_str' : '{:,}'.format(int(value['monthly_salary'])), \ 'penalty_amount' : value['penalty_amount']} \ for mid, value in monthly_salary_dict.items()} monthly_salary_dict = OrderedDict( sorted(monthly_salary_dict.items(), key=lambda x: x[0])) ret['response'] = monthly_salary_dict self.set_status(Response.RESULT_OK) except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
def get(self): self.set_header("Content-Type", "application/json") master_id = self.get_argument('master_id', '') date_from = self.get_argument('date_from') date_to = self.get_argument('date_to') ret = {} SATURDAY = 5 CANCELED_RATE = 0.5 print date_from, date_to date_from = dt.datetime.strptime(date_from, '%Y%m%d').date() date_to = dt.datetime.strptime(date_to, '%Y%m%d').date() try: session = Session() userdao = UserDAO() bookingdao = BookingDAO() result = session.query(Booking, Master, User, UserAddress) \ .join(Master, Booking.master_id == Master.id) \ .join(User, Booking.user_id == User.id) \ .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \ .filter(and_(func.date(Booking.start_time) >= date_from, func.date(Booking.start_time) <= date_to)) \ .filter(Booking.master_id == master_id) \ .filter(or_(Booking.cleaning_status == BC.BOOKING_COMPLETED, \ and_(Booking.cleaning_status == BC.BOOKING_CANCELED, \ or_(Booking.payment_status == BC.BOOKING_CANCELED_REFUND, \ Booking.payment_status == BC.BOOKING_CANCELED_CHARGE)))) \ .order_by(Booking.master_id, Booking.start_time) \ .all() weekly_salary = 0 salary = {} salary_detail = [] salary['weekly_salary'] = 0 for row in result: if row.Booking.user_id == '81c2f5c1-7295-489d-8bb0-334121060ae3': continue user_name = userdao.get_user_name(row.Booking.user_id) org_price = row.Booking.price_with_task status = row.Booking.cleaning_status appointment_index = row.Booking.appointment_index appointment_type = row.Booking.appointment_type start_time = row.Booking.start_time end_time = row.Booking.estimated_end_time cleaning_duration = row.Booking.cleaning_duration / 6 charging_price = row.Booking.charging_price is_dirty = row.Booking.is_dirty is_b2b = row.User.is_b2b duration_in_minutes = ( end_time - start_time ).seconds / 360 # 계산을 단순하게 하기 위해 60 * 60이 아닌 60 * 6으로 나눔. 그뒤 10배 커지는 것을 방지하기 위해 시급에서 10 나눈 값만 곱함 minutes_for_salary = duration_in_minutes #if duration_in_minutes > cleaning_duration: # 30분의 시간이 더 더해지는 경우가 존재. 그 경우, 해당 시간은 임금에 반영 되지 않음 # if appointment_index == 1 and (appointment_type == BC.ONE_TIME_A_MONTH or appointment_type == BC.TWO_TIME_A_MONTH or appointment_type == BC.FOUR_TIME_A_MONTH): # minutes_for_salary = duration_in_minutes - 5 if is_dirty == 1: minutes_for_salary -= 20 house_type = row.UserAddress.kind house_size = row.UserAddress.size extra_charge = 0 if row.Booking.cleaning_status == BC.BOOKING_COMPLETED: if is_b2b: weekly_salary = int(minutes_for_salary * (row.Booking.wage_per_hour / 10)) else: # 오피스텔 13평 이하, 주택 7평 이하는 시급 14000 weekly_salary = 0 if start_time >= dt.datetime(2017, 1, 1): weekly_salary = minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR else: if appointment_type in BC.REGULAR_CLEANING_DICT: weekly_salary = minutes_for_salary * BC.SALARY_FOR_REGULAR_IN_HOUR else: weekly_salary = minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR if start_time.weekday( ) in BC.WEEKEND and start_time >= dt.datetime( 2016, 12, 17): weekly_salary += BC.WEEKEND_ADDED_SALARY extra_charge = bookingdao.get_extra_charge(row.Booking.id) weekly_salary += extra_charge salary['weekly_salary'] += weekly_salary elif row.Booking.payment_status == BC.BOOKING_CANCELED_CHARGE or \ row.Booking.payment_status == BC.BOOKING_CANCELED_REFUND: weekly_salary = int(charging_price * CANCELED_RATE) salary['weekly_salary'] += weekly_salary if weekly_salary > 0: salary_detail.append({ 'org_price': org_price, 'charging_price': charging_price, 'salary': weekly_salary, 'extra_charge': extra_charge, 'status': status, 'start_time': dt.datetime.strftime(start_time, '%Y-%m-%d %H:%M'), 'end_time': dt.datetime.strftime(end_time, '%Y-%m-%d %H:%M'), 'cleaning_index': appointment_index, 'user_name': user_name }) salary['salary_detail'] = salary_detail ret['response'] = salary self.set_status(Response.RESULT_OK) except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
def get(self): self.set_header("Content-Type", "application/json") ret = {} SATURDAY = 5 CANCELED_RATE = 0.5 try: session = Session() userdao = UserDAO() bookingdao = BookingDAO() # get last saturday now = dt.datetime.now() offset = (now.weekday() - SATURDAY) % 7 last_saturday = (now - dt.timedelta(days=offset)).date() now = now.date() result = session.query(Booking, Master, User, UserAddress) \ .join(Master, Booking.master_id == Master.id) \ .join(User, Booking.user_id == User.id) \ .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \ .filter(and_(func.date(Booking.start_time) >= last_saturday, func.date(Booking.start_time) <= now)) \ .filter(not_(User.email.like('*****@*****.**'))) \ .order_by(Booking.master_id, Booking.start_time) \ .all() weekly_salary = 0 for row in result: user_name = userdao.get_user_name(row.Booking.user_id) org_price = row.Booking.price_with_task status = row.Booking.cleaning_status appointment_index = row.Booking.appointment_index appointment_type = row.Booking.appointment_type start_time = row.Booking.start_time end_time = row.Booking.estimated_end_time cleaning_duration = row.Booking.cleaning_duration / 6 charging_price = row.Booking.charging_price is_b2b = row.User.is_b2b duration_in_minutes = ( end_time - start_time ).seconds / 360 # 계산을 단순하게 하기 위해 60 * 60이 아닌 60 * 6으로 나눔. 그뒤 10배 커지는 것을 방지하기 위해 시급에서 10 나눈 값만 곱함 minutes_for_salary = duration_in_minutes #if duration_in_minutes > cleaning_duration: # 30분의 시간이 더 더해지는 경우가 존재. 그 경우, 해당 시간은 임금에 반영 되지 않음 # minutes_for_salary = duration_in_minutes - 5 house_type = row.UserAddress.kind house_size = row.UserAddress.size extra_charge = 0 if row.Booking.cleaning_status == BC.BOOKING_COMPLETED: if is_b2b: weekly_salary += int(minutes_for_salary * (row.Booking.wage_per_hour / 10)) else: # 오피스텔 13평 이하, 주택 7평 이하는 시급 14000 if appointment_type in BC.REGULAR_CLEANING_DICT: weekly_salary += minutes_for_salary * BC.SALARY_FOR_REGULAR_IN_HOUR else: weekly_salary += minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR if start_time.weekday( ) in BC.WEEKEND and start_time >= dt.datetime( 2016, 12, 17): weekly_salary += BC.WEEKEND_ADDED_SALARY extra_charge = bookingdao.get_extra_charge(row.Booking.id) weekly_salary += extra_charge elif row.Booking.payment_status == BC.BOOKING_CANCELED_CHARGE or \ row.Booking.payment_status == BC.BOOKING_CANCELED_REFUND: weekly_salary += int(charging_price * CANCELED_RATE) ret['response'] = {'weekly_salary': weekly_salary, 'revenue': 100} self.set_status(Response.RESULT_OK) except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
def get_total_salaries(self, start_date, end_date): FRIDAY = 4 SATURDAY = 5 CANCELED_RATE = 0.5 bookingdao = BookingDAO() session = Session() result = session.query(Booking, Master, User, UserAddress) \ .join(Master, Booking.master_id == Master.id) \ .join(User, Booking.user_id == User.id) \ .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \ .filter(and_(func.date(Booking.start_time) >= start_date, func.date(Booking.start_time) <= end_date)) \ .filter(or_(Booking.cleaning_status == BC.BOOKING_COMPLETED, Booking.cleaning_status == BC.BOOKING_CANCELED)) \ .order_by(Booking.master_id, Booking.start_time) \ .all() weekly_salary = 0 prev_master_id = None for row in result: status = row.Booking.cleaning_status appointment_index = row.Booking.appointment_index appointment_type = row.Booking.appointment_type start_time = row.Booking.start_time end_time = row.Booking.estimated_end_time cleaning_duration = row.Booking.cleaning_duration / 6 charging_price = row.Booking.charging_price is_dirty = row.Booking.is_dirty is_b2b = row.User.is_b2b duration_in_minutes = ( end_time - start_time ).seconds / 360 # 계산을 단순하게 하기 위해 60 * 60이 아닌 60 * 6으로 나눔. 그뒤 10배 커지는 것을 방지하기 위해 시급에서 10 나눈 값만 곱함 minutes_for_salary = duration_in_minutes #if duration_in_minutes > cleaning_duration: # 30분의 시간이 더 더해지는 경우가 존재. 그 경우, 해당 시간은 임금에 반영 되지 않음 # if appointment_index == 1 and (appointment_type == BC.ONE_TIME_A_MONTH or appointment_type == BC.TWO_TIME_A_MONTH or appointment_type == BC.FOUR_TIME_A_MONTH): # minutes_for_salary = duration_in_minutes - 5 if is_dirty == 1: minutes_for_salary -= 20 house_type = row.UserAddress.kind house_size = row.UserAddress.size extra_charge = 0 if row.Booking.cleaning_status == BC.BOOKING_COMPLETED: if is_b2b: weekly_salary += int(minutes_for_salary * (row.Booking.wage_per_hour / 10)) else: # 오피스텔 13평 이하, 주택 7평 이하는 시급 14000 if appointment_type in BC.REGULAR_CLEANING_DICT: weekly_salary += minutes_for_salary * BC.SALARY_FOR_REGULAR_IN_HOUR else: weekly_salary += minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR if start_time.weekday( ) in BC.WEEKEND and start_time >= dt.datetime( 2016, 12, 17): weekly_salary += BC.WEEKEND_ADDED_SALARY extra_charge = bookingdao.get_extra_charge(row.Booking.id) weekly_salary += extra_charge elif row.Booking.payment_status == BC.BOOKING_CANCELED_CHARGE or \ row.Booking.payment_status == BC.BOOKING_CANCELED_REFUND: weekly_salary += int(charging_price * CANCELED_RATE) session.close() return weekly_salary
def get(self): self.set_header("Content-Type", "application/json") master_id = self.get_argument('master_id', '') ret = {} # weekly SATURDAY = 5 CANCELED_RATE = 0.5 try: session = Session() # get last saturday userdao = UserDAO() masterdao = MasterDAO() bookingdao = BookingDAO() now = dt.datetime.now() offset = (now.weekday() - SATURDAY) % 7 last_saturday = (now - dt.timedelta(days=offset)).date() now = now.date() date_range = [] date_range.append((last_saturday, now)) from_date = last_saturday - dt.timedelta(days=7) to_date = last_saturday - dt.timedelta(days=1) for i in range(11): date_range.append((from_date, to_date)) from_date = from_date - dt.timedelta(days=7) to_date = to_date - dt.timedelta(days=7) weekly_salaries = [] start_time = dt.datetime.now() for dr in date_range: from_date = dr[0] to_date = dr[1] result = session.query(Booking, Master, User, UserAddress) \ .join(Master, Booking.master_id == Master.id) \ .join(User, Booking.user_id == User.id) \ .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \ .filter(and_(func.date(Booking.start_time) >= from_date, func.date(Booking.start_time) <= to_date)) \ .filter(Booking.master_id == master_id) \ .filter(or_(Booking.cleaning_status == BC.BOOKING_COMPLETED, \ and_(Booking.cleaning_status == BC.BOOKING_CANCELED, \ or_(Booking.payment_status == BC.BOOKING_CANCELED_REFUND, \ Booking.payment_status == BC.BOOKING_CANCELED_CHARGE)))) \ .order_by(Booking.master_id, Booking.start_time) \ .all() weekly_salary = 0 for row in result: if row.Booking.user_id == '81c2f5c1-7295-489d-8bb0-334121060ae3': continue user_name = userdao.get_user_name(row.Booking.user_id) org_price = row.Booking.price_with_task status = row.Booking.cleaning_status appointment_index = row.Booking.appointment_index appointment_type = row.Booking.appointment_type additional_task = row.Booking.additional_task start_time = row.Booking.start_time end_time = row.Booking.estimated_end_time cleaning_duration = row.Booking.cleaning_duration / 6 charging_price = row.Booking.charging_price is_dirty = row.Booking.is_dirty is_b2b = row.User.is_b2b duration_in_minutes = ( end_time - start_time ).seconds / 360 # 계산을 단순하게 하기 위해 60 * 60이 아닌 60 * 6으로 나눔. 그뒤 10배 커지는 것을 방지하기 위해 시급에서 10 나눈 값만 곱함 minutes_for_salary = duration_in_minutes #if duration_in_minutes > cleaning_duration: # 30분의 시간이 더 더해지는 경우가 존재. 그 경우, 해당 시간은 임금에 반영 되지 않음 # if appointment_index == 1 and (appointment_type == BC.ONE_TIME_A_MONTH or appointment_type == BC.TWO_TIME_A_MONTH or appointment_type == BC.FOUR_TIME_A_MONTH): # minutes_for_salary = duration_in_minutes - 5 if is_dirty == 1: minutes_for_salary -= 20 house_type = row.UserAddress.kind house_size = row.UserAddress.size if row.Booking.cleaning_status == BC.BOOKING_COMPLETED: if is_b2b: weekly_salary += int( minutes_for_salary * (row.Booking.wage_per_hour / 10)) else: # 오피스텔 13평 이하, 주택 7평 이하는 시급 14000 if start_time >= dt.datetime(2017, 1, 1): weekly_salary += minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR else: if appointment_type in BC.REGULAR_CLEANING_DICT: weekly_salary += minutes_for_salary * BC.SALARY_FOR_REGULAR_IN_HOUR else: weekly_salary += minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR if start_time.weekday( ) in BC.WEEKEND and start_time >= dt.datetime( 2016, 12, 17): weekly_salary += BC.WEEKEND_ADDED_SALARY weekly_salary += bookingdao.get_extra_charge( row.Booking.id) elif row.Booking.payment_status == BC.BOOKING_CANCELED_CHARGE or \ row.Booking.payment_status == BC.BOOKING_CANCELED_REFUND: weekly_salary += int(charging_price * CANCELED_RATE) penalty_amount = 0 #masterdao.get_master_penalties(master_id, from_date, to_date) weekly_salary = int(weekly_salary) if start_time >= dt.datetime(2017, 1, 1): weekly_salary = int(weekly_salary) else: weekly_salary = int(weekly_salary * 0.967) actual_weekly_salary = weekly_salary - penalty_amount weekly_salary = '{:,}'.format(weekly_salary) actual_weekly_salary = '{:,}'.format(actual_weekly_salary) penalty_amount = '{:,}'.format(penalty_amount) from_date_str = dt.datetime.strftime(from_date, '%Y%m%d') to_date_str = dt.datetime.strftime(to_date, '%Y%m%d') weekly_salaries.append({ 'date_from': from_date_str, 'date_to': to_date_str, 'salary': weekly_salary, 'penalty_amount': penalty_amount, 'actual_weekly_salary': actual_weekly_salary }) # montly '''monthly_salaries = [] date_range = [] from_date = dt.date(now.year, now.month, 1) to_date = now date_range.append((from_date, to_date)) for i in range(11): to_date = from_date - dt.timedelta(days=1) from_date = dt.date(to_date.year, to_date.month, 1) date_range.append((from_date, to_date)) for dr in date_range: from_date = dr[0] to_date = dr[1] result = session.query(Booking, Master, User, UserAddress) \ .join(Master, Booking.master_id == Master.id) \ .join(User, Booking.user_id == User.id) \ .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \ .filter(and_(func.date(Booking.start_time) >= from_date, func.date(Booking.start_time) <= to_date)) \ .filter(Booking.master_id == master_id) \ .order_by(Booking.master_id, Booking.start_time) \ .all() monthly_salary = 0 for row in result: user_name = userdao.get_user_name(row.Booking.user_id) org_price = row.Booking.price_with_task status = row.Booking.cleaning_status appointment_index = row.Booking.appointment_index appointment_type = row.Booking.appointment_type start_time = row.Booking.start_time end_time = row.Booking.estimated_end_time cleaning_duration = row.Booking.cleaning_duration / 6 charging_price = row.Booking.charging_price duration_in_minutes = (end_time - start_time).seconds / 360 # 계산을 단순하게 하기 위해 60 * 60이 아닌 60 * 6으로 나눔. 그뒤 10배 커지는 것을 방지하기 위해 시급에서 10 나눈 값만 곱함 minutes_for_salary = duration_in_minutes if duration_in_minutes > cleaning_duration: # 30분의 시간이 더 더해지는 경우가 존재. 그 경우, 해당 시간은 임금에 반영 되지 않음 minutes_for_salary = duration_in_minutes - 5 house_type = row.UserAddress.kind house_size = row.UserAddress.size if row.Booking.cleaning_status == BC.BOOKING_COMPLETED: # 오피스텔 13평 이하, 주택 7평 이하는 시급 14000 if ((house_type == 0 and house_size <= 12) or (house_type == 1 and house_size <= 7)): monthly_salary += minutes_for_salary * BC.SALARY_FOR_SMALL_IN_HOUR else: monthly_salary += minutes_for_salary * BC.SALARY_FOR_NORMAL_IN_HOUR monthly_salary += bookingdao.get_extra_charge(row.Booking.id) elif row.Booking.payment_status == BC.BOOKING_CANCELED_CHARGE or \ row.Booking.payment_status == BC.BOOKING_CANCELED_REFUND: monthly_salary += int(charging_price * CANCELED_RATE) monthly_salary = int(monthly_salary) monthly_salary = '{:,}'.format(monthly_salary) from_date_str = dt.datetime.strftime(from_date, '%Y%m%d') to_date_str = dt.datetime.strftime(to_date, '%Y%m%d') monthly_salaries.append({'date_from' : from_date_str, 'date_to' : to_date_str, 'salary' : monthly_salary}) # total total_salary = 0 result = session.query(Booking, Master, User, UserAddress) \ .join(Master, Booking.master_id == Master.id) \ .join(User, Booking.user_id == User.id) \ .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \ .filter(Booking.master_id == master_id) \ .order_by(Booking.master_id, Booking.start_time) \ .all() for row in result: user_name = userdao.get_user_name(row.Booking.user_id) org_price = row.Booking.price_with_task status = row.Booking.cleaning_status appointment_index = row.Booking.appointment_index appointment_type = row.Booking.appointment_type start_time = row.Booking.start_time end_time = row.Booking.estimated_end_time cleaning_duration = row.Booking.cleaning_duration / 6 charging_price = row.Booking.charging_price duration_in_minutes = (end_time - start_time).seconds / 360 # 계산을 단순하게 하기 위해 60 * 60이 아닌 60 * 6으로 나눔. 그뒤 10배 커지는 것을 방지하기 위해 시급에서 10 나눈 값만 곱함 minutes_for_salary = duration_in_minutes if duration_in_minutes > cleaning_duration: # 30분의 시간이 더 더해지는 경우가 존재. 그 경우, 해당 시간은 임금에 반영 되지 않음 minutes_for_salary = duration_in_minutes - 5 house_type = row.UserAddress.kind house_size = row.UserAddress.size if row.Booking.cleaning_status == BC.BOOKING_COMPLETED: # 오피스텔 13평 이하, 주택 7평 이하는 시급 14000 if ((house_type == 0 and house_size <= 12) or (house_type == 1 and house_size <= 7)): total_salary += minutes_for_salary * BC.SALARY_FOR_SMALL_IN_HOUR else: total_salary += minutes_for_salary * BC.SALARY_FOR_NORMAL_IN_HOUR total_salary += bookingdao.get_extra_charge(row.Booking.id) elif row.Booking.payment_status == BC.BOOKING_CANCELED_CHARGE or \ row.Booking.payment_status == BC.BOOKING_CANCELED_REFUND: total_salary += int(charging_price * CANCELED_RATE) total_salary = int(total_salary) total_salary = '{:,}'.format(total_salary)''' # get master point #master_point = 0 #point_row = session.query(func.sum(MasterPoint.point)).filter(MasterPoint.master_id == master_id).all() #master_point = int(point_row[0][0]) master_row = session.query(Master).filter( Master.id == master_id).one() master_name = master_row.name master_phone = master_row.phone ret['response'] = { 'master_name': master_name, 'master_phone': master_phone, 'weekly_salary': weekly_salaries, 'total_salary': 0, 'monthly_salary': [] } self.set_status(Response.RESULT_OK) except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])