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', '') year = self.get_argument('yyyy', 2016) month = self.get_argument('mm', 9) ret = {} try: session = Session() masterdao = MasterDAO() userdao = UserDAO() bookingdao = BookingDAO() CANCELED_RATE = 0.5 year = int(year) month = int(month) first_day, last_day = get_month_day_range(dt.date(year, month, 7)) result = session.query(Booking, Master, User, UserAddress) \ .join(Master, Booking.master_id == Master.id) \ .join(User, Booking.user_id == User.id) \ .join(UserAddress, and_(Booking.user_id == UserAddress.user_id, Booking.addr_idx == UserAddress.user_addr_index)) \ .filter(and_(func.date(Booking.start_time) >= first_day, func.date(Booking.start_time) <= last_day)) \ .filter(Booking.master_id == master_id) \ .order_by(Booking.master_id, Booking.start_time) \ .all() monthly_salary = 0 monthly_salaries = [] for row in result: user_name = userdao.get_user_name(row.Booking.user_id) org_price = row.Booking.price_with_task status = row.Booking.cleaning_status appointment_index = row.Booking.appointment_index appointment_type = row.Booking.appointment_type additional_task = row.Booking.additional_task start_time = row.Booking.start_time end_time = row.Booking.estimated_end_time cleaning_duration = row.Booking.cleaning_duration / 6 charging_price = row.Booking.charging_price is_dirty = row.Booking.is_dirty is_b2b = row.User.is_b2b duration_in_minutes = ( end_time - start_time ).seconds / 360 # 계산을 단순하게 하기 위해 60 * 60이 아닌 60 * 6으로 나눔. 그뒤 10배 커지는 것을 방지하기 위해 시급에서 10 나눈 값만 곱함 minutes_for_salary = duration_in_minutes #if duration_in_minutes > cleaning_duration: # 30분의 시간이 더 더해지는 경우가 존재. 그 경우, 해당 시간은 임금에 반영 되지 않음 # if appointment_index == 1 and (appointment_type == BC.ONE_TIME_A_MONTH or appointment_type == BC.TWO_TIME_A_MONTH or appointment_type == BC.FOUR_TIME_A_MONTH): # minutes_for_salary = duration_in_minutes - 5 if is_dirty == 1: # 똥집인 경우 2시간 제외해야함 minutes_for_salary -= 20 house_type = row.UserAddress.kind house_size = row.UserAddress.size if row.Booking.cleaning_status == BC.BOOKING_COMPLETED or \ row.Booking.cleaning_status == BC.BOOKING_STARTED or \ row.Booking.cleaning_status == BC.BOOKING_UPCOMMING: if is_b2b: monthly_salary += int(minutes_for_salary * (row.Booking.wage_per_hour / 10)) else: # 오피스텔 13평 이하, 주택 7평 이하는 시급 14000 if appointment_type in BC.REGULAR_CLEANING_DICT: monthly_salary += minutes_for_salary * BC.SALARY_FOR_REGULAR_IN_HOUR else: monthly_salary += minutes_for_salary * BC.SALARY_FOR_ONETIME_IN_HOUR if start_time.weekday( ) in BC.WEEKEND and start_time >= dt.datetime( 2016, 12, 17): monthly_salary += BC.WEEKEND_ADDED_SALARY monthly_salary += bookingdao.get_extra_charge( row.Booking.id) elif row.Booking.payment_status == BC.BOOKING_CANCELED_CHARGE or \ row.Booking.payment_status == BC.BOOKING_CANCELED_REFUND: monthly_salary += int(charging_price * CANCELED_RATE) penalty_amount = masterdao.get_master_penalties( master_id, first_day, last_day) monthly_salary = int(monthly_salary * 0.967) # 3.3% 제외 actual_monthly_salary = monthly_salary - penalty_amount monthly_salary = '{:,}'.format(monthly_salary) actual_monthly_salary = '{:,}'.format(actual_monthly_salary) penalty_amount = '{:,}'.format(penalty_amount) from_date_str = dt.datetime.strftime(first_day, '%Y%m%d') to_date_str = dt.datetime.strftime(last_day, '%Y%m%d') monthly_salaries.append({ 'date_from': from_date_str, 'date_to': to_date_str, 'salary': monthly_salary, 'penalty_amount': penalty_amount, 'actual_monthly_salary': actual_monthly_salary }) master_row = session.query(Master).filter( Master.id == master_id).one() master_name = master_row.name master_phone = master_row.phone ret['response'] = { 'master_name': master_name, 'master_phone': master_phone, 'monthly_salary': monthly_salaries } self.set_status(Response.RESULT_OK) except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql'])
def post(self): self.set_header("Content-Type", "application/json") passcode = self.get_argument('passcode', 0) # n weeks before 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() week = 1 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(and_(func.date(Booking.start_time) >= last_saturday, func.date(Booking.start_time) <= now)) \ .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 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: # 오피스텔 13평 이하, 주택 7평 이하는 시급 14000 weekly_salary = 0 if is_b2b: weekly_salary = int(minutes_for_salary * (row.Booking.wage_per_hour / 10)) 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'] = masterdao.get_master_penalties( row.Booking.master_id, start_period, end_period) master_salaries.append(salary) else: salary['weekly_salary'] += weekly_salary prev_master_id = row.Master.id for ms in master_salaries: ms['weekly_salary'] = int(ms['weekly_salary'] * 0.967) ms['actual_weekly_salary'] = ms['weekly_salary'] - ms[ 'penalty_amount'] 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'])