def get_presale_last_checkout_dict(self,cr,uid,id,context = None): """ 获取包厢最后一次结账信息,并返回给客户端 """ last_checkout = self.get_presale_last_checkout(cr,uid,id,context) if not last_checkout: return None pool = self.pool.get(last_checkout._table_name) fields_list = pool.fields_get(cr,uid).keys() ret = pool.read(cr,uid,last_checkout.id,fields_list) #关闭时间是当前时间 ret.update({ "close_time" : datetime.now().strftime("%Y-%m-%d %H:%M:%S"), #重新计算消费时长 "consume_minutes" : ktv_helper.timedelta_minutes(ktv_helper.strptime(last_checkout.open_time),datetime.now()), }) #当前买断 buyout_config_id = getattr(last_checkout,'buyout_config_id',None) if buyout_config_id: buyout_config_fields_list = self.pool.get('ktv.buyout_config').fields_get(cr,uid).keys() buyout_config_dict = self.pool.get('ktv.buyout_config').read(cr,uid,buyout_config_id.id,buyout_config_fields_list) ret['buyout_config_id'] = buyout_config_dict return ret
def get_active_configs(self,cr,uid,room_type_id): ''' 获取当前有效的买断设置信息 :params integer room_type_id 包厢类型id :params integer buyout_config_id 买断设置id :return array 符合条件的买断信息数组 ''' ret = [] #1 获取所有买断信息,并逐个进行判断 ids = self.search(cr,uid,[("room_type_id",'=',room_type_id)]) configs = self.browse(cr,uid,ids) #2 判断当日买断是否启用 context_now = ktv_helper.user_context_now(self,cr,uid) #判断是周几 weekday_str = ktv_helper.weekday_str(context_now.weekday()) #判断特殊日设置 s_day_ids = self.pool.get('ktv.buyout_config_special_day').search(cr,uid,[("room_type_id",'=',room_type_id)]) s_days = self.pool.get('ktv.buyout_config_special_day').read(cr,uid,s_day_ids,['room_type_id','special_day']) s_days_list = [s_day['special_day'] for s_day in s_days] #买断起止时间 #time_from 当前时间 #time_to 买断结束时间 #如果当日是特殊日,则直接返回所有买断设置 in_sp_day = datetime.today() in s_days_list #根据设置的星期是否有效来得到返回的设置 for c in configs: buyout_enable = getattr(c,weekday_str + '_buyout_enable',False) in_time_range = ktv_helper.utc_time_between(c.time_from,c.time_to,datetime.now()) time_from = datetime.now() time_to = ktv_helper.float_time_to_datetime(c.time_to) #判断时间设置是否跨天 if time_to < time_from: time_to = time_to + timedelta(days = 1) if (in_sp_day and in_time_range) or (buyout_enable and in_time_range): buyout_fee = getattr(c,weekday_str + "_buyout_fee",0.0) if in_sp_day: buyout_fee = getattr(c,"special_day_buyout_fee") ret.append({ "id" : c.id, "room_type_id" : c.room_type_id.id, "name" : getattr(c,"name"), #起始时间是当前时间 "time_from" : time_from.strftime('%Y-%m-%d %H:%M:%S'), "time_to" : time_to.strftime('%Y-%m-%d %H:%M:%S'), "is_member" : getattr(c,'is_member'), "buyout_fee" : buyout_fee, #计算实际买断分钟数量 "buyout_time" : ktv_helper.timedelta_minutes(time_from,time_to), }) return ret
def re_calculate_fee(self,cr,uid,context): """ 重新计算买断换房信息 :params context dict required context['room_id'] integer 原包厢id required context['changed_room_id'] integer 新包厢id required context['changed_buyout_config_id'] integer 新买断id required context['member_id'] 会员id,可能为空 context['discount_card_id'] 打折卡id,可能为空 context['discounter_id'] 员工id,可能为空 计算方法: 1 获取原包厢最后结算信息 2 计算新包厢应收费用信息 3 计算各项费用应补差额 4 计算折扣信息 :return dict 计算后的买断换房结算信息 """ #原包厢 origin_room = self.pool.get('ktv.room').browse(cr,uid,context["origin_room_id"]) changed_room = self.pool.get('ktv.room').browse(cr,uid,context['changed_room_id']) #当前买断信息 active_buyout_config = self.pool.get('ktv.buyout_config').get_active_buyout_fee(cr,uid,context['changed_buyout_config_id']) #最后结账信息 last_checkout = self.pool.get('ktv.room').get_presale_last_checkout(cr,uid,context["origin_room_id"]) if not last_checkout: raise osv.except_osv(_("错误"), _('找不到包厢:%s的最后结账信息.' % origin_room.name)) #原包厢结账信息 last_checkout_info = { #原包厢 "room_id" : last_checkout.room_operate_id.room_id.id, #原买断信息 "buyout_config_id" : last_checkout.buyout_config_id and [last_checkout.buyout_config_id.id,last_checkout.buyout_config_id.name] or None, "open_time" : last_checkout.open_time, #关闭时间是当前时间 "close_time" : datetime.now().strftime("%Y-%m-%d %H:%M:%S"), #重新计算消费时长 "consume_minutes" : ktv_helper.timedelta_minutes(ktv_helper.strptime(last_checkout.open_time),datetime.now()), #现金 "cash_fee" : last_checkout.cash_fee, #信用卡 "credit_card_no" : last_checkout.credit_card_no or None, "credit_card_fee" : last_checkout.credit_card_fee, #会员卡 "member_card_id" : last_checkout.member_card_id and last_checkout.member_card_id.id or None, "member_card_fee" : last_checkout.member_card_fee, #抵扣券 "sales_voucher_fee" : last_checkout.sales_voucher_fee, #挂账 "on_crediter_id" : last_checkout.on_crediter_id and last_checkout.on_crediter_id.id or None, "on_credit_fee" : last_checkout.on_credit_fee, #免单 "freer_id" : last_checkout.freer_id and last_checkout.freer_id.id or None, "free_fee" : last_checkout.free_fee, #合计付款 "sum_should_fee" : last_checkout.sum_should_fee, } #应补钟点费 = 新包厢买断费 - 原支付费用 changed_room_sum_hourly_fee = active_buyout_config['buyout_fee'] - last_checkout_info['sum_should_fee'] #计算打折信息 ret = { #原费用信息 "last_checkout_info" : last_checkout_info, "origin_room_id" : context["origin_room_id"], "changed_room_id" : context['changed_room_id'], #原room_operate "ref_room_operate_id" : last_checkout.room_operate_id.id, "buyout_config_id" : context['changed_buyout_config_id'], "open_time" : active_buyout_config['time_from'], "close_time" : active_buyout_config['time_to'], "consume_minutes" : active_buyout_config['buyout_time'], "present_minutes" : 0, "room_fee" : 0, "service_fee_rate" : 0, "service_fee" : 0, "sum_hourly_fee" : 0, "sum_hourly_fee_p" : 0, "sum_buffet_fee" : 0, "changed_room_fee" : 0, "changed_room_sum_hourly_fee" : changed_room_sum_hourly_fee, "changed_room_sum_hourly_fee" : 0, "changed_room_sum_hourly_fee_p" : 0, "changed_room_sum_buffet_fee" : 0, "changed_room_service_fee" : 0, "changed_room_minutes" : 0, "merged_room_hourly_fee" : 0, "minimum_fee" : 0, "minimum_fee_diff" : 0, "prepay_fee" : 0, "drinks_fee" : 0, "uncheckout_drinks_fee" : 0, "minimum_drinks_fee" : 0, "guest_damage_fee" : 0, "member_room_fee_discount_rate" : 0, "member_room_fee_discount_fee" : 0, "discount_card_room_fee_discount_rate" : 0, "discount_card_room_fee_discount_fee" : 0, "discounter_room_fee_discount_rate" : 0, "discounter_room_fee_discount_fee" : 0, "discount_fee" : 0, "discount_rate" : 0, "cash_fee" : 0, "member_card_fee" : 0, "sales_voucher_fee" : 0, "credit_card_fee" : 0, "on_credit_fee" : 0, "free_fee" : 0, } #同时只能有一种打折方式可用 #会员打折费用 #打折卡打折 if 'discount_card_id' in context and context['discount_card_id']: discount_card = self.pool.get('ktv.discount_card').browse(cr,uid,context['discount_card_id']) ret['discount_card_id'] = context['discount_card_id'] ret['discount_card_room_fee_discount_rate'] = discount_card_room_fee_discount_rate = discount_card.discount_card_type_id.room_fee_discount ret['discount_card_room_fee_discount_fee'] = discount_card_room_fee_discount_fee = active_buyout_config['buyout_fee']*(100 - discount_card_room_fee_discount_rate)/100 ret['discount_rate'] = discount_card_room_fee_discount_rate ret['discount_fee'] = discount_card_room_fee_discount_fee if 'member_id' in context and context['member_id']: the_member = self.pool.get('ktv.member').browse(cr,uid,context['member_id']) ret['member_id'] = context['member_id'] ret['member_room_fee_discount_rate'] = member_room_fee_discount_rate = the_member.member_class_id.room_fee_discount ret['member_room_fee_discount_fee'] = member_room_fee_discount_fee = active_buyout_config['buyout_fee']*(100 - member_room_fee_discount_rate)/100 ret['discount_rate'] = member_room_fee_discount_rate ret['discount_fee'] = member_room_fee_discount_fee #员工打折 #TODO #if 'discounter_id' in context and context['discounter_id']: #默认情况下,重新计算后,费用做如下处理: ret['sum_should_fee'] = changed_room_sum_hourly_fee - ret['discount_fee'] ret['cash_fee'] = ret['sum_should_fee'] ret['act_pay_fee'] = ret['cash_fee'] ret['change_fee'] = 0.0 ret.update({ 'member_card_fee' : 0.0, 'credit_card_fee' : 0.0, 'sales_voucher_fee' : 0.0, }) return ret
def get_hourly_fee_array(self,cr,uid,room_id,context): """ 计算当前包厢钟点费用信息,按照时段钟点费的设置,消费可能分为几段时间进行计算, 因各个时间段的钟点费用不同 打印时还可使用 :param room_id integer 当前要计算的包厢id required :param context[datetime_open] string 包厢消费起始时间 required :param context[datetime_close] string 包厢消费结束时间 required :param context[price_class_id] integer 价格类型id required :param context[member_id] integer 会员卡id :rtype list 分段费用数组 """ pool = self.pool datetime_open = ktv_helper.strptime(context['datetime_open']) datetime_close = ktv_helper.strptime(context['datetime_close']) room = pool.get('ktv.room').browse(cr,uid,room_id) room_type_id = room.room_type_id.id price_class_id = context.get('price_class_id') member_id = context.get('member_id',None) member_class_id = None if member_id: member = pool.get('ktv.member').browse(cr,uid,member_id) member_class_id = member.member_class_id.id #hourly_fee_configs 包厢时段设置 hourly_fee_discount_configs = [] domain = {'price_class_id' : price_class_id,'ignore_time_range' : True} if member_class_id: domain['member_class_id'] = member_class_id domain['which_fee']="member_hourly_fee_discount" hourly_discount_configs = self.pool.get('ktv.member_hourly_fee_discount')\ .get_active_conifg(cr,uid,room_type_id,domain) hourly_discount_configs = self.pool.get("ktv.hourly_fee_discount").get_active_configs(cr,uid,room_type_id,domain) #形成config_array数组 def construct_config_array(c): config_datetime_from = ktv_helper.float_time_to_datetime(c['time_from']) config_datetime_to = ktv_helper.float_time_to_datetime(c['time_to']) #如果config_datetime_to < config_datetime_from,则config_datetime_to + 1 day if config_datetime_to < config_datetime_from: config_datetime_to = config_datetime_to + timedelta(days = 1) #先形成时间顺序的数组 #FIXME 此处要求在设置时间时,必须是连续的 return { 'datetime_from' : config_datetime_from, 'datetime_to' : config_datetime_to, 'hourly_fee' : c['hourly_fee'], 'hourly_discount' : c['hourly_discount'], } config_array = [construct_config_array(c) for c in hourly_discount_configs] #根据获取到的设置进行分段费用计算 for c in config_array: #判断时间情况如下所列,共有6种情况 # |--1--|-2--|--3--|--4-| # |----| # |----| # |---------------| # |----------------------------| # |----------| # |---------| #设置的最早时段 config_datetime_min = config_array[0]['datetime_from'] config_datetime_max = config_array[-1]['datetime_to'] _logger.debug('config_datetime_min = %s' % config_datetime_min) _logger.debug('config_datetime_max = %s' % config_datetime_max) _logger.debug('datetime_open = %s' % datetime_open) _logger.debug('datetime_close = %s' % datetime_close) #情况1:消费时间不在设置时间区间内,按照正常费用设置 if datetime_close <= config_datetime_min or datetime_open >= config_datetime_max: config_array = [] #情况2: 消费时段包含在设置时段内 #更新第一个的datetime_from 更新最后一个的datetime_to if datetime_open >= config_datetime_min and datetime_close <= config_datetime_max: #删除不在消费时段内的元素 [config_array.remove(c_fee) for c_fee in config_array if c_fee['datetime_to'] <= datetime_open] [config_array.remove(c_fee) for c_fee in config_array if c_fee['datetime_from'] >= datetime_close] config_array[0]['datetime_from'] = datetime_open config_array[-1]['datetime_to'] = datetime_close #3:消费时段包含设置时段 #在首尾分别添加费用设置 if datetime_open < config_datetime_min and datetime_close > config_datetime_max: config_array.insert(0,{ "datetime_from" : datetime_open, "datetime_to" : config_datetime_min, "hourly_fee" : room.hourly_fee, "hourly_discount" : 100, }) config_array.append({ "datetime_from" : config_datetime_max, "datetime_to" : datetime_close, "hourly_fee" : room.hourly_fee, "hourly_discount" : 100, }) #4:消费起始时间早于设置开始时间,消费结束时间早于设置结束时间 #在数组头部添加费用设置,删除后部的元素 if datetime_open < config_datetime_min and datetime_close < config_datetime_max: #删除不在消费时段内的元素 [config_array.remove(c_fee) for c_fee in config_array if c_fee['datetime_from'] >= datetime_close] config_array.insert(0,{ "datetime_from" : datetime_open, "datetime_to" : config_datetime_min, "hourly_fee" : room.hourly_fee, "hourly_discount" : 100, }) config_array[-1]['datetime_to'] = datetime_close #5:消费起始时间晚于设置开始时间,消费结束时间晚于设置结束时间 #删除数组头部不符合要求的数据,在数组尾部添加费用设置 if datetime_open >= config_datetime_min and datetime_close >= config_datetime_max: #删除不在消费时段内的元素 [config_array.remove(c_fee) for c_fee in config_array if c_fee['datetime_to'] <= datetime_open] config_array.append({ "datetime_from" : config_datetime_max, "datetime_to" : datetime_close, "hourly_fee" : room.hourly_fee, "hourly_discount" : 100, }) config_array[0]['datetime_from'] = datetime_open #逐个计算费用信息 for c in config_array: consume_minutes= ktv_helper.timedelta_minutes(c["datetime_from"],c["datetime_to"]) c['sum_hourly_fee']= ktv_helper.float_round(cr,c['hourly_fee']*consume_minutes/60) c['consume_minutes']= consume_minutes c['time_from'] = c['datetime_from'].strftime('%H:%M') c['time_to'] = c['datetime_to'].strftime('%H:%M') #如果没有钟点费用信息,则设置默认钟点费信息 if not config_array: tmp_dict = dict() consume_minutes= ktv_helper.timedelta_minutes(datetime_open,datetime_close) tmp_dict['sum_hourly_fee']= ktv_helper.float_round(cr,room.hourly_fee*consume_minutes/60) tmp_dict['hourly_fee']= room.hourly_fee tmp_dict['hourly_discount']= 100 #不打折 tmp_dict['consume_minutes']= consume_minutes tmp_dict['datetime_from'] = datetime_open tmp_dict['datetime_to'] = datetime_close tmp_dict['time_from'] = datetime_open.strftime('%H:%M') tmp_dict['time_to'] = datetime_close.strftime('%H:%M') config_array.append(tmp_dict) _logger.debug("config array = %s",repr(config_array)) return config_array
def get_active_configs(self, cr, uid, room_type_id): ''' 获取当前有效的买断设置信息 :params integer room_type_id 包厢类型id :params integer buyout_config_id 买断设置id :return array 符合条件的买断信息数组 ''' ret = [] #1 获取所有买断信息,并逐个进行判断 ids = self.search(cr, uid, [("room_type_id", '=', room_type_id)]) configs = self.browse(cr, uid, ids) #2 判断当日买断是否启用 context_now = ktv_helper.user_context_now(self, cr, uid) #判断是周几 weekday_str = ktv_helper.weekday_str(context_now.weekday()) #判断特殊日设置 s_day_ids = self.pool.get('ktv.buyout_config_special_day').search( cr, uid, [("room_type_id", '=', room_type_id)]) s_days = self.pool.get('ktv.buyout_config_special_day').read( cr, uid, s_day_ids, ['room_type_id', 'special_day']) s_days_list = [s_day['special_day'] for s_day in s_days] #买断起止时间 #time_from 当前时间 #time_to 买断结束时间 #如果当日是特殊日,则直接返回所有买断设置 in_sp_day = datetime.today() in s_days_list #根据设置的星期是否有效来得到返回的设置 for c in configs: buyout_enable = getattr(c, weekday_str + '_buyout_enable', False) in_time_range = ktv_helper.utc_time_between( c.time_from, c.time_to, datetime.now()) time_from = datetime.now() time_to = ktv_helper.float_time_to_datetime(c.time_to) #判断时间设置是否跨天 if time_to < time_from: time_to = time_to + timedelta(days=1) if (in_sp_day and in_time_range) or (buyout_enable and in_time_range): buyout_fee = getattr(c, weekday_str + "_buyout_fee", 0.0) if in_sp_day: buyout_fee = getattr(c, "special_day_buyout_fee") ret.append({ "id": c.id, "room_type_id": c.room_type_id.id, "name": getattr(c, "name"), #起始时间是当前时间 "time_from": ktv_helper.strftime(time_from), "time_to": ktv_helper.strftime(time_to), "is_member": getattr(c, 'is_member'), "buyout_fee": buyout_fee, #计算实际买断分钟数量 "buyout_time": ktv_helper.timedelta_minutes(time_from, time_to), }) return ret