def re_calculate_fee(self,cr,uid,context): """ 重新计算应退费用 :params context 包含计算上下问信息,required :params context[room_id] integer 包厢id,required """ #计算以往客户付费合计 pool = self.pool room_id = context.get('room_id') room = pool.get('ktv.room').browse(cr,uid,room_id) r_op = room.current_room_operate_id sum_refund_info = self.get_default_checkout_dict(cr,uid) #在实际消费时长 < 买钟时长(不包括赠送时长)时,可以退钟 #计算退钟时间,退钟时长 = refund_minutes = ktv_helper.str_timedelta_minutes(ktv_helper.utc_now_str(),r_op.close_time) - r_op.present_minutes _logger.debug("refund_minutes = % s" % refund_minutes) if refund_minutes <= 0: return None #计算room_operate.close_time ~ datetime.now()时间内应收费用(折前) tmp_dict = {k:v for k,v in context.items() if k not in ('member_id','discount_card_id','discounter_id')} tmp_dict['price_class_id'] = getattr(r_op.price_class_id,'id') tmp_dict['consume_minutes'] = refund_minutes sum_refund_info = self.calculate_sum_pay_info(cr,uid,tmp_dict) #退钟时,open_time = now close_time = close_time - refund_minutes sum_refund_info['open_time'] = ktv_helper.utc_now_str() sum_refund_info['close_time'] = ktv_helper.strftime(datetime.now() + timedelta(minutes = refund_minutes)) self.set_calculate_fields(cr,uid,sum_refund_info) return sum_refund_info
def get_all_hourly_fee_array(self,cr,uid,context): """ 获取所有时段钟点费用信息,其中包括换房 :param context 包含计算上下文信息,required :param context['room_id'] integer required 结账包厢id :param context[fee_type_id] integer 计费方式id required :param context[price_class_id] integer 价格类型 required :param context[member_id] integer 会员卡id :return 分时段的费用信息 tuple """ pool = self.pool room_id = context['room_id'] room = pool.get('ktv.room').browse(cr,uid,room_id) r_op = room.current_room_operate_id fee_type_id = context.get('fee_type_id') price_class_id = context.get('price_class_id') #如果member_id为空,则默认使用上次包厢操作的member_id member_id = context.get('member_id',None) member = pool.get('ktv.member').browse(cr,uid,member_id) if member_id else r_op.last_member_id room_opens = r_op.room_opens_ids and r_op.room_opens_ids[0] room_changes = r_op.room_change_ids #计算room_opens的room_fee和hourly_fee origin_room = room_opens.room_id room_fee = origin_room.room_fee #关闭时间,如果room_opens未关闭,则为当前时间,否则为room_opens关闭时间 close_time = room_opens.close_time if room_opens.close_time else ktv_helper.utc_now_str() #计算钟点费环境变量 cal_ctx = { 'datetime_open' : room_opens.open_time, 'datetime_close' : close_time, 'price_class_id' : price_class_id } if member: cal_ctx['member_class_id'] = member.member_class_id.id room_opens_hourly_fee_array = self.get_hourly_fee_array(cr,uid,origin_room.id,cal_ctx) #计算room_change的时段费用数组 room_changed_hourly_fee_array =[] for room_change in r_op.room_change_ids: close_time = room_change.close_time if room_change.close_time else ktv_helper.utc_now_str() changed_room = room_change.changed_room_id cal_ctx.update({ 'datetime_open' : room_change.open_time, 'datetime_close' : room_change.close_time if room_change.close_time else ktv_helper.utc_now_str(), }) #钟点费合计 tmp_array = self.get_hourly_fee_array(cr,uid,changed_room.id,cal_ctx) room_changed_hourly_fee_array += tmp_array return (room_opens_hourly_fee_array,room_changed_hourly_fee_array)
def process_operate(self,cr,uid,room_change_vals): """ 处理正常开房-换房信息 :param room_change_vals dict 换房对象数据 :return (room_change,包厢状态,cron定时任务对象) """ room_id = room_change_vals.get("room_id") changed_room_id = room_change_vals['changed_room_id'] cur_rp_id = self.pool.get('ktv.room').find_or_create_room_operate(cr,uid,room_id) #获取最近一次的换房(room_change)或开房(room_opens)信息 room_opens,room_change = self.pool.get('ktv.room_operate').last_room_opens_and_change(cr,uid,cur_rp_id) #修改room_opens或上次room_change的close_time close_time = ktv_helper.utc_now_str() if room_change: self.pool.get('ktv.room_change').write(cr,uid,room_change.id,{"close_time" : close_time}) elif room_opens: self.pool.get('ktv.room_opens').write(cr,uid,room_opens.id,{"close_time" : close_time}) #修改原包厢状态 self.pool.get('ktv.room').write(cr,uid,room_id,{'state' : room.STATE_FREE,'current_room_operate_id' : None,}) #修改新包厢状态 self.pool.get('ktv.room').write(cr,uid,changed_room_id,{'state' : room.STATE_IN_USE,'current_room_operate_id' : cur_rp_id}) room_change_vals["room_operate_id"] = cur_rp_id room_change_id = self.create(cr,uid,room_change_vals) fields = self.fields_get(cr,uid).keys() room_change = self.read(cr,uid,room_change_id,fields) return (room_change,None,None)
def re_calculate_fee(self, cr, uid, context): """ 重新计算应退费用 :params context 包含计算上下问信息,required :params context[room_id] integer 包厢id,required """ #计算以往客户付费合计 pool = self.pool room_id = context.get('room_id') room = pool.get('ktv.room').browse(cr, uid, room_id) r_op = room.current_room_operate_id sum_refund_info = self.get_default_checkout_dict(cr, uid) #在实际消费时长 < 买钟时长(不包括赠送时长)时,可以退钟 #计算退钟时间,退钟时长 = refund_minutes = ktv_helper.str_timedelta_minutes( ktv_helper.utc_now_str(), r_op.close_time) - r_op.present_minutes _logger.debug("refund_minutes = % s" % refund_minutes) if refund_minutes <= 0: return None #计算room_operate.close_time ~ datetime.now()时间内应收费用(折前) tmp_dict = { k: v for k, v in context.items() if k not in ('member_id', 'discount_card_id', 'discounter_id') } tmp_dict['price_class_id'] = getattr(r_op.price_class_id, 'id') tmp_dict['consume_minutes'] = refund_minutes sum_refund_info = self.calculate_sum_pay_info(cr, uid, tmp_dict) #退钟时,open_time = now close_time = close_time - refund_minutes sum_refund_info['open_time'] = ktv_helper.utc_now_str() sum_refund_info['close_time'] = ktv_helper.strftime( datetime.now() + timedelta(minutes=refund_minutes)) self.set_calculate_fields(cr, uid, sum_refund_info) return sum_refund_info
def process_operate(self, cr, uid, room_change_vals): """ 处理正常开房-换房信息 :param room_change_vals dict 换房对象数据 :return (room_change,包厢状态,cron定时任务对象) """ room_id = room_change_vals.get("room_id") changed_room_id = room_change_vals['changed_room_id'] cur_rp_id = self.pool.get('ktv.room').find_or_create_room_operate( cr, uid, room_id) #获取最近一次的换房(room_change)或开房(room_opens)信息 room_opens, room_change = self.pool.get( 'ktv.room_operate').last_room_opens_and_change(cr, uid, cur_rp_id) #修改room_opens或上次room_change的close_time close_time = ktv_helper.utc_now_str() if room_change: self.pool.get('ktv.room_change').write(cr, uid, room_change.id, {"close_time": close_time}) elif room_opens: self.pool.get('ktv.room_opens').write(cr, uid, room_opens.id, {"close_time": close_time}) #修改原包厢状态 self.pool.get('ktv.room').write(cr, uid, room_id, { 'state': room.STATE_FREE, 'current_room_operate_id': None, }) #修改新包厢状态 self.pool.get('ktv.room').write(cr, uid, changed_room_id, { 'state': room.STATE_IN_USE, 'current_room_operate_id': cur_rp_id }) room_change_vals["room_operate_id"] = cur_rp_id room_change_id = self.create(cr, uid, room_change_vals) fields = self.fields_get(cr, uid).keys() room_change = self.read(cr, uid, room_change_id, fields) return (room_change, None, None)
def update_previous_checkout_for_presale_room_change(self,cr,uid,op_id): """ 修改上次结账信息的关房时间和消费时间,在预售换房时使用 :param op_id integer :rtype dict 更新的checkout """ #修改关联的最后一次结账信息中的关闭时间和消费时长 pool = self.pool p_checkout,l_checkout = self.last_two_presale_checkout(cr,uid,op_id) close_time = ktv_helper.utc_now_str() consume_minutes = ktv_helper.str_timedelta_minutes(p_checkout['open_time'],close_time) osv_name = p_checkout['osv_name'] update_attrs = {"close_time" : close_time} if 'room_change' in osv_name: update_attrs['changed_room_minutes'] = consume_minutes else: update_attrs['consume_minutes'] = consume_minutes if p_checkout: pool.get(osv_name).write(cr,uid,p_checkout['id'],update_attrs) return p_checkout and pool.get(osv_name).read(cr,uid,p_checkout['id'])
def update_previous_checkout_for_presale_room_change(self, cr, uid, op_id): """ 修改上次结账信息的关房时间和消费时间,在预售换房时使用 :param op_id integer :rtype dict 更新的checkout """ #修改关联的最后一次结账信息中的关闭时间和消费时长 pool = self.pool p_checkout, l_checkout = self.last_two_presale_checkout(cr, uid, op_id) close_time = ktv_helper.utc_now_str() consume_minutes = ktv_helper.str_timedelta_minutes( p_checkout['open_time'], close_time) osv_name = p_checkout['osv_name'] update_attrs = {"close_time": close_time} if 'room_change' in osv_name: update_attrs['changed_room_minutes'] = consume_minutes else: update_attrs['consume_minutes'] = consume_minutes if p_checkout: pool.get(osv_name).write(cr, uid, p_checkout['id'], update_attrs) return p_checkout and pool.get(osv_name).read(cr, uid, p_checkout['id'])
def daily_report(self,cr,uid,start_datetime = None,end_datetime = None): ''' 日营业额统计报表,统计给定时间段的包厢费用信息 默认情况下统计当日营业额 NOTE 注意,此处传入的是日期类型是字符串 :param start_datetime string default = None 形式如yyyy-mm-dd HH:MM:SS 统计起始时间,一般是根据营业时间计算的起始时间 :param end_datetime string default = None 形式如yyyy-mm-dd HH:MM:SS 统计结束时间,一般是根据营业时间计算的结束时间 :return dict 营业额统计数据 ''' today_start_datetime,today_end_datetime = self.pool.get('ktv.opening_time_config').get_time_range(cr,uid) if not start_datetime or not end_datetime: start_datetime = ktv_helper.strftime(today_start_datetime) end_datetime = ktv_helper.strftime(today_end_datetime) #首先计算不同支付方式的费用 #应计算以下业务: #A 在时间区间内关房的正常开房业务(开房时间不一定在区间内),也包括换房 #B 在时间区间内发生的预售业务,(包括已关房的和未关房的) group_member_class_fee = {} #按照会员卡类别分组的费用 group_room_type_fee = {} #按照包厢类别分组的实收金额费用 cash_fee = member_card_fee = sales_voucher_fee = prepay_fee = free_fee = credit_card_fee \ = on_credit_fee = check_fee = store_card_fee = total_after_discount_fee = 0.0 room_fee = hourly_fee = changed_room_fee = changed_room_hourly_fee = total_fee = total_discount_fee = 0.0 song_ticket_minutes = 0 #在本区间内的关房业务 close_ids = self.search(cr,uid,[('close_time','>=',start_datetime),('close_time','<=',end_datetime)]) close_ops = [op for op in self.browse(cr,uid,close_ids) if not op.is_presale] #在本区间内发生的预售业务 presale_ids = self.search(cr,uid,[('operate_date','>=',start_datetime),('operate_date','<=',end_datetime)]) presale_ops = [op for op in self.browse(cr,uid,presale_ids) if op.is_presale] for op in presale_ops + close_ops: cash_fee += op.total_after_discount_cash_fee member_card_fee += op.member_card_fee sales_voucher_fee += op.sales_voucher_fee prepay_fee += op.prepay_fee free_fee += op.free_fee credit_card_fee += op.credit_card_fee on_credit_fee += op.on_credit_fee total_after_discount_fee += op.total_after_discount_fee #-------------------- room_fee += op.room_fee hourly_fee += op.hourly_fee changed_room_fee += op.changed_room_fee changed_room_hourly_fee += op.changed_room_hourly_fee total_fee += op.total_fee total_discount_fee += op.total_discount_fee song_ticket_minutes += song_ticket_minutes #以下计算按照会员级别分组的member_card_fee if op.last_member_id: member_class_id = op.last_member_id.member_class_id.id member_class_name = op.last_member_id.member_class_id.name member_class_fee = group_member_class_fee.get(member_class_id,[member_class_name,0.0]) group_member_class_fee[member_class_id] = [member_class_name,member_class_fee[1] + op.member_card_fee] #以下按照不同的包厢类别计算实收金额 room_type_id = op.last_room_id.room_type_id.id room_type_name = op.last_room_id.room_type_id.name room_type_fee = group_room_type_fee.get(room_type_id,[room_type_name,0.0]) group_room_type_fee[room_type_id] = [room_type_name,room_type_fee[1] + op.total_after_discount_fee] return { 'start_datetime' : start_datetime, 'end_datetime' : end_datetime, 'print_datetime' : ktv_helper.utc_now_str(), 'cash_fee' : cash_fee, 'member_card_fee' : member_card_fee, 'credit_card_fee' : credit_card_fee, 'sales_voucher_fee' : sales_voucher_fee, 'free_fee' : free_fee, 'on_credit_fee' : on_credit_fee, 'check_fee' : check_fee, 'prepay_fee' : prepay_fee, 'store_card_fee' : store_card_fee, 'total_after_discount_fee' : total_after_discount_fee, 'room_fee' : room_fee, 'hourly_fee' : hourly_fee, 'changed_room_fee' : changed_room_fee, 'changed_room_hourly_fee' : changed_room_hourly_fee, 'total_fee' : total_fee, 'total_discount_fee' : total_discount_fee, 'song_ticket_minutes' : song_ticket_minutes, 'group_member_class_fee' : group_member_class_fee.values(), 'group_room_type_fee' : group_room_type_fee.values(), }
def _compute_fields(self,cr,uid,ids,name,args,context = None): """ 计算以下字段的值: open_time 以room_opens或room_checkout_buytime或room_checkout_buytime中的open_time为准 close_time 以最后一次结算时间为准 consume_minutes changed_room_minutes """ ret = {} for record in self.browse(cr,uid,ids): #依次判断所有开房相关操作:room_opens > room_checkout_buyout > room_checkout_buytime which_room_open_ops = record.room_opens_ids or record.room_checkout_buyout_ids or record.room_checkout_buytime_ids last_room = which_room_open_ops[0].room_id if which_room_open_ops else None fee_type_id = which_room_open_ops[0].fee_type_id.id if which_room_open_ops else None price_class_id = which_room_open_ops[0].price_class_id.id if which_room_open_ops else None open_time = which_room_open_ops[0].open_time if which_room_open_ops else None guest_name = which_room_open_ops[0].guest_name if which_room_open_ops else None persons_count = which_room_open_ops[0].persons_count if which_room_open_ops else None prepay_fee = which_room_open_ops[0].prepay_fee if which_room_open_ops else None #判断是否预售操作presale is_presale = True if record.room_checkout_buyout_ids or record.room_checkout_buytime_ids else False #是否已结账 is_shift_reported = True if record.casher_shift_report_id else False #依次判断关房操作,也有可能当前包厢尚未关闭,close_time可能为空 #room_change > room_checkout > room_change_checkout_buytime > room_change_checkout_buyout > room_checkout_buytime which_room_close_ops = record.room_checkout_ids or record.room_change_ids or \ record.room_change_checkout_buyout_ids or record.room_checkout_buyout_ids or \ record.room_checkout_buytime_refund_ids or record.room_checkout_buytime_continue_ids or \ record.room_change_checkout_buytime_ids or record.room_checkout_buytime_ids close_time = None last_member = None last_buyout_config = None last_cron = None if which_room_close_ops: close_time = which_room_close_ops[0].close_time #获取最后一次操作的member_id last_member =getattr(which_room_close_ops[-1],'member_id',None) last_buyout_config = getattr(which_room_close_ops[-1],'buyout_config_id',None) #最后一次cron任务 last_cron = getattr(which_room_close_ops[-1],'cron_id',None) #获取last_room_id last_room = getattr(which_room_close_ops[-1],'room_id',None) if not last_buyout_config: #最后买断id last_buyout_config = getattr(which_room_open_ops[0],'buyout_config_id',None) if which_room_open_ops else None last_buyout_config_id = getattr(last_buyout_config,'id',None) last_cron_id = getattr(last_cron,'id',None) last_room_id = getattr(last_room,'id',None) if not last_member: last_member = which_room_open_ops[0].member_id if which_room_open_ops else None last_member_id = getattr(last_member,'id',None) consume_minutes = 0 if open_time: consume_minutes = ktv_helper.str_timedelta_minutes(open_time,close_time if close_time else ktv_helper.utc_now_str()) #到钟报警 alert = False #计算已消费时长和剩余消费时长 left_minutes = 0 #如果当前时间>close_time 则该包厢已关闭 #如果当前时间<=close_time 则该包厢尚未关闭 if close_time: if ktv_helper.utc_now_str() > close_time: left_minutes = 0 else: left_minutes = ktv_helper.str_timedelta_minutes(ktv_helper.utc_now_str(),close_time) if left_minutes <= 5: alert = True #计算consume_minutes ori_consume_minutes = changed_room_minutes = total_minutes = present_minutes = song_ticket_minutes = 0 total_fee = room_fee = hourly_fee = changed_room_fee = changed_room_hourly_fee = guest_damage_fee = total_discount_fee = total_after_discount_fee = total_after_discount_cash_fee = 0.0 on_credit_fee = member_card_fee = credit_card_fee = sales_voucher_fee = free_fee = 0.0 for r_ops in (record.room_checkout_ids,record.room_checkout_buyout_ids,record.room_checkout_buytime_ids,record.room_change_checkout_buyout_ids,record.room_change_checkout_buytime_ids,record.room_checkout_buytime_continue_ids): for r_op in r_ops: present_minutes += r_op.present_minutes changed_room_minutes += r_op.changed_room_minutes ori_consume_minutes += r_op.consume_minutes song_ticket_minutes += r_op.song_ticket_minutes room_fee += r_op.room_fee hourly_fee += r_op.hourly_fee changed_room_fee += r_op.changed_room_fee changed_room_hourly_fee += r_op.changed_room_hourly_fee guest_damage_fee += r_op.guest_damage_fee member_card_fee += r_op.member_card_fee credit_card_fee += r_op.credit_card_fee on_credit_fee += r_op.on_credit_fee sales_voucher_fee += r_op.sales_voucher_fee free_fee += r_op.free_fee total_fee += r_op.total_fee total_discount_fee += r_op.total_discount_fee total_after_discount_fee += r_op.total_after_discount_fee total_after_discount_cash_fee += r_op.total_after_discount_cash_fee total_minutes += r_op.consume_minutes + r_op.changed_room_minutes ret[record.id] = { 'guest_name' : guest_name, 'persons_count' : persons_count or 1, 'fee_type_id' : fee_type_id, 'price_class_id' : price_class_id, 'last_cron_id' : last_cron_id, 'last_room_id' : last_room_id, 'last_member_id' : last_member_id, 'last_buyout_config_id' : last_buyout_config_id, 'open_time' : open_time, 'close_time' : close_time, 'prepay_fee' : prepay_fee or 0.0, 'ori_consume_minutes' : ori_consume_minutes or 0, 'consume_minutes' : consume_minutes or 0, 'left_minutes' : left_minutes or 0, 'alert' : alert, 'present_minutes' : present_minutes or 0, 'total_minutes' : total_minutes or 0, 'room_fee' : room_fee or 0.0, 'hourly_fee' : hourly_fee or 0.0, 'changed_room_fee' : changed_room_fee or 0.0, 'changed_room_hourly_fee' : changed_room_hourly_fee or 0.0, 'changed_room_minutes' : changed_room_minutes or 0, 'guest_damage_fee' : guest_damage_fee or 0.0, 'member_card_fee' : member_card_fee or 0.0, 'credit_card_fee' : credit_card_fee or 0.0, 'sales_voucher_fee' : sales_voucher_fee or 0.0, 'on_credit_fee' : on_credit_fee or 0.0, 'free_fee' : free_fee or 0.0, 'song_ticket_minutes' : song_ticket_minutes or 0, 'total_fee' : total_fee or 0.0, 'total_discount_fee' : total_discount_fee or 0.0, 'total_after_discount_fee' : total_after_discount_fee or 0.0, 'total_after_discount_cash_fee' : total_after_discount_cash_fee or 0.0, 'is_shift_reported' : is_shift_reported, 'is_presale' : is_presale, } _logger.debug("ret = %s" % ret) return ret
def _calculate_sum_should_pay_info(self,cr,uid,context): """ 计算正常开房-结账费用信息 :params context 包含计算上下文信息,required :param context['room_id'] integer required 结账包厢id :params context[fee_type_id] integer 计费方式id required :params context[price_class_id] integer 价格类型 required :params context[member_id] integer 会员卡id :params context[discount_card_id] integer 打折卡id :params context[discounter_id] integer 员工id,用于记录打折员工信息 :return 计算费用后的结账对象 dict """ pool = self.pool room_id = context['room_id'] room = pool.get('ktv.room').browse(cr,uid,room_id) r_op = room.current_room_operate_id discount_card_id = context.get('discount_card_id',None) discounter_id = context.get('discounter_id',None) sum_should_pay_info = self.get_default_checkout_dict(cr,uid) room_opens_lines,room_change_lines = self.get_all_hourly_fee_array(cr,uid,context) room_opens = r_op.room_opens_ids and r_op.room_opens_ids[0] room_changes = r_op.room_change_ids #如果没有开房信息,或包厢已结账room_checkout,则返回None if r_op.room_checkout_ids or not room_opens: _logger.debug("Not Found room_opens or room_checkout") raise osv.except_osv(_("错误"), _('包厢操作数据错误,该包厢已结账或找不到开房信息.')) #计算room_opens的room_fee和hourly_fee origin_room = room_opens.room_id room_fee = origin_room.room_fee #关闭时间,如果room_opens未关闭,则为当前时间,否则为room_opens关闭时间 close_time = room_opens.close_time if room_opens.close_time else ktv_helper.utc_now_str() sum_should_pay_info['open_time'] = room_opens.open_time sum_should_pay_info['room_fee'] = origin_room.room_fee sum_should_pay_info['service_fee_rate'] = origin_room.service_fee_rate consume_minutes,hourly_fee = (0,0.0) for c in room_opens_lines: consume_minutes += c['consume_minutes'] hourly_fee += c['sum_hourly_fee'] #计算room_change的room_fee和hourly_fee changed_room_hourly_fee,changed_room_minutes = (0.0,0) for c in room_change_lines: changed_room_hourly_fee += c['sum_hourly_fee'] changed_room_minutes += c['consume_minutes'] #计算changed_room_fee,默认按照room_fee高的补差价 changed_room_fee = 0.0 for room_change in room_changes: close_time = room_change.close_time if room_change.close_time else ktv_helper.utc_now_str() changed_room = room_change.changed_room_id if changed_room.room_fee > origin_room.room_fee: changed_room_fee = changed_room.room_fee - origin_room.room_fee #合并两项费用 sum_should_pay_info.update({ 'room_operate_id' : r_op.id, 'room_id' : context['room_id'], 'price_class_id' : context['price_class_id'], 'fee_type_id' : context['fee_type_id'], 'guest_name' : getattr(r_op,'guest_name',None), 'persons_count' : r_op.persons_count, 'open_time' : room_opens.open_time, 'close_time' : close_time, 'prepay_fee' : r_op.prepay_fee, 'room_fee' : origin_room.room_fee, 'hourly_fee' : hourly_fee, 'consume_minutes' : consume_minutes, 'changed_room_fee' : changed_room_fee, 'changed_room_hourly_fee' : changed_room_hourly_fee, 'changed_room_minutes' : changed_room_minutes, 'guest_damage_fee' : r_op.guest_damage_fee, }) #根据fee_type_id计算费用 self.calculate_with_fee_type_id(cr,uid,context['fee_type_id'],sum_should_pay_info) #计算折扣 discount_info = self.set_discount_info(cr,uid,sum_should_pay_info['total_fee'],context.get('member_id',None),discount_card_id,discounter_id) sum_should_pay_info.update(discount_info) self.set_calculate_fields(cr,uid,sum_should_pay_info) _logger.debug("sum_pay_info = %s " % sum_should_pay_info) return sum_should_pay_info
def _compute_fields(self, cr, uid, ids, name, args, context=None): """ 计算以下字段的值: open_time 以room_opens或room_checkout_buytime或room_checkout_buytime中的open_time为准 close_time 以最后一次结算时间为准 consume_minutes changed_room_minutes """ ret = {} for record in self.browse(cr, uid, ids): #依次判断所有开房相关操作:room_opens > room_checkout_buyout > room_checkout_buytime which_room_open_ops = record.room_opens_ids or record.room_checkout_buyout_ids or record.room_checkout_buytime_ids last_room = which_room_open_ops[ 0].room_id if which_room_open_ops else None fee_type_id = which_room_open_ops[ 0].fee_type_id.id if which_room_open_ops else None price_class_id = which_room_open_ops[ 0].price_class_id.id if which_room_open_ops else None open_time = which_room_open_ops[ 0].open_time if which_room_open_ops else None guest_name = which_room_open_ops[ 0].guest_name if which_room_open_ops else None persons_count = which_room_open_ops[ 0].persons_count if which_room_open_ops else None prepay_fee = which_room_open_ops[ 0].prepay_fee if which_room_open_ops else None #判断是否预售操作presale is_presale = True if record.room_checkout_buyout_ids or record.room_checkout_buytime_ids else False #是否已结账 is_shift_reported = True if record.casher_shift_report_id else False #依次判断关房操作,也有可能当前包厢尚未关闭,close_time可能为空 #room_change > room_checkout > room_change_checkout_buytime > room_change_checkout_buyout > room_checkout_buytime which_room_close_ops = record.room_checkout_ids or record.room_change_ids or \ record.room_change_checkout_buyout_ids or record.room_checkout_buyout_ids or \ record.room_checkout_buytime_refund_ids or record.room_checkout_buytime_continue_ids or \ record.room_change_checkout_buytime_ids or record.room_checkout_buytime_ids close_time = None last_member = None last_buyout_config = None last_cron = None if which_room_close_ops: close_time = which_room_close_ops[0].close_time #获取最后一次操作的member_id last_member = getattr(which_room_close_ops[-1], 'member_id', None) last_buyout_config = getattr(which_room_close_ops[-1], 'buyout_config_id', None) #最后一次cron任务 last_cron = getattr(which_room_close_ops[-1], 'cron_id', None) #获取last_room_id last_room = getattr(which_room_close_ops[-1], 'room_id', None) if not last_buyout_config: #最后买断id last_buyout_config = getattr( which_room_open_ops[0], 'buyout_config_id', None) if which_room_open_ops else None last_buyout_config_id = getattr(last_buyout_config, 'id', None) last_cron_id = getattr(last_cron, 'id', None) last_room_id = getattr(last_room, 'id', None) if not last_member: last_member = which_room_open_ops[ 0].member_id if which_room_open_ops else None last_member_id = getattr(last_member, 'id', None) consume_minutes = 0 if open_time: consume_minutes = ktv_helper.str_timedelta_minutes( open_time, close_time if close_time else ktv_helper.utc_now_str()) #到钟报警 alert = False #计算已消费时长和剩余消费时长 left_minutes = 0 #如果当前时间>close_time 则该包厢已关闭 #如果当前时间<=close_time 则该包厢尚未关闭 if close_time: if ktv_helper.utc_now_str() > close_time: left_minutes = 0 else: left_minutes = ktv_helper.str_timedelta_minutes( ktv_helper.utc_now_str(), close_time) if left_minutes <= 5: alert = True #计算consume_minutes ori_consume_minutes = changed_room_minutes = total_minutes = present_minutes = song_ticket_minutes = 0 total_fee = room_fee = hourly_fee = changed_room_fee = changed_room_hourly_fee = guest_damage_fee = total_discount_fee = total_after_discount_fee = total_after_discount_cash_fee = 0.0 on_credit_fee = member_card_fee = credit_card_fee = sales_voucher_fee = free_fee = 0.0 for r_ops in (record.room_checkout_ids, record.room_checkout_buyout_ids, record.room_checkout_buytime_ids, record.room_change_checkout_buyout_ids, record.room_change_checkout_buytime_ids, record.room_checkout_buytime_continue_ids): for r_op in r_ops: present_minutes += r_op.present_minutes changed_room_minutes += r_op.changed_room_minutes ori_consume_minutes += r_op.consume_minutes song_ticket_minutes += r_op.song_ticket_minutes room_fee += r_op.room_fee hourly_fee += r_op.hourly_fee changed_room_fee += r_op.changed_room_fee changed_room_hourly_fee += r_op.changed_room_hourly_fee guest_damage_fee += r_op.guest_damage_fee member_card_fee += r_op.member_card_fee credit_card_fee += r_op.credit_card_fee on_credit_fee += r_op.on_credit_fee sales_voucher_fee += r_op.sales_voucher_fee free_fee += r_op.free_fee total_fee += r_op.total_fee total_discount_fee += r_op.total_discount_fee total_after_discount_fee += r_op.total_after_discount_fee total_after_discount_cash_fee += r_op.total_after_discount_cash_fee total_minutes += r_op.consume_minutes + r_op.changed_room_minutes ret[record.id] = { 'guest_name': guest_name, 'persons_count': persons_count or 1, 'fee_type_id': fee_type_id, 'price_class_id': price_class_id, 'last_cron_id': last_cron_id, 'last_room_id': last_room_id, 'last_member_id': last_member_id, 'last_buyout_config_id': last_buyout_config_id, 'open_time': open_time, 'close_time': close_time, 'prepay_fee': prepay_fee or 0.0, 'ori_consume_minutes': ori_consume_minutes or 0, 'consume_minutes': consume_minutes or 0, 'left_minutes': left_minutes or 0, 'alert': alert, 'present_minutes': present_minutes or 0, 'total_minutes': total_minutes or 0, 'room_fee': room_fee or 0.0, 'hourly_fee': hourly_fee or 0.0, 'changed_room_fee': changed_room_fee or 0.0, 'changed_room_hourly_fee': changed_room_hourly_fee or 0.0, 'changed_room_minutes': changed_room_minutes or 0, 'guest_damage_fee': guest_damage_fee or 0.0, 'member_card_fee': member_card_fee or 0.0, 'credit_card_fee': credit_card_fee or 0.0, 'sales_voucher_fee': sales_voucher_fee or 0.0, 'on_credit_fee': on_credit_fee or 0.0, 'free_fee': free_fee or 0.0, 'song_ticket_minutes': song_ticket_minutes or 0, 'total_fee': total_fee or 0.0, 'total_discount_fee': total_discount_fee or 0.0, 'total_after_discount_fee': total_after_discount_fee or 0.0, 'total_after_discount_cash_fee': total_after_discount_cash_fee or 0.0, 'is_shift_reported': is_shift_reported, 'is_presale': is_presale, } _logger.debug("ret = %s" % ret) return ret
def daily_report(self, cr, uid, start_datetime=None, end_datetime=None): ''' 日营业额统计报表,统计给定时间段的包厢费用信息 默认情况下统计当日营业额 NOTE 注意,此处传入的是日期类型是字符串 :param start_datetime string default = None 形式如yyyy-mm-dd HH:MM:SS 统计起始时间,一般是根据营业时间计算的起始时间 :param end_datetime string default = None 形式如yyyy-mm-dd HH:MM:SS 统计结束时间,一般是根据营业时间计算的结束时间 :return dict 营业额统计数据 ''' today_start_datetime, today_end_datetime = self.pool.get( 'ktv.opening_time_config').get_time_range(cr, uid) if not start_datetime or not end_datetime: start_datetime = ktv_helper.strftime(today_start_datetime) end_datetime = ktv_helper.strftime(today_end_datetime) #首先计算不同支付方式的费用 #应计算以下业务: #A 在时间区间内关房的正常开房业务(开房时间不一定在区间内),也包括换房 #B 在时间区间内发生的预售业务,(包括已关房的和未关房的) group_member_class_fee = {} #按照会员卡类别分组的费用 group_room_type_fee = {} #按照包厢类别分组的实收金额费用 cash_fee = member_card_fee = sales_voucher_fee = prepay_fee = free_fee = credit_card_fee \ = on_credit_fee = check_fee = store_card_fee = total_after_discount_fee = 0.0 room_fee = hourly_fee = changed_room_fee = changed_room_hourly_fee = total_fee = total_discount_fee = 0.0 song_ticket_minutes = 0 #在本区间内的关房业务 close_ids = self.search(cr, uid, [('close_time', '>=', start_datetime), ('close_time', '<=', end_datetime)]) close_ops = [ op for op in self.browse(cr, uid, close_ids) if not op.is_presale ] #在本区间内发生的预售业务 presale_ids = self.search(cr, uid, [('operate_date', '>=', start_datetime), ('operate_date', '<=', end_datetime)]) presale_ops = [ op for op in self.browse(cr, uid, presale_ids) if op.is_presale ] for op in presale_ops + close_ops: cash_fee += op.total_after_discount_cash_fee member_card_fee += op.member_card_fee sales_voucher_fee += op.sales_voucher_fee prepay_fee += op.prepay_fee free_fee += op.free_fee credit_card_fee += op.credit_card_fee on_credit_fee += op.on_credit_fee total_after_discount_fee += op.total_after_discount_fee #-------------------- room_fee += op.room_fee hourly_fee += op.hourly_fee changed_room_fee += op.changed_room_fee changed_room_hourly_fee += op.changed_room_hourly_fee total_fee += op.total_fee total_discount_fee += op.total_discount_fee song_ticket_minutes += song_ticket_minutes #以下计算按照会员级别分组的member_card_fee if op.last_member_id: member_class_id = op.last_member_id.member_class_id.id member_class_name = op.last_member_id.member_class_id.name member_class_fee = group_member_class_fee.get( member_class_id, [member_class_name, 0.0]) group_member_class_fee[member_class_id] = [ member_class_name, member_class_fee[1] + op.member_card_fee ] #以下按照不同的包厢类别计算实收金额 room_type_id = op.last_room_id.room_type_id.id room_type_name = op.last_room_id.room_type_id.name room_type_fee = group_room_type_fee.get(room_type_id, [room_type_name, 0.0]) group_room_type_fee[room_type_id] = [ room_type_name, room_type_fee[1] + op.total_after_discount_fee ] return { 'start_datetime': start_datetime, 'end_datetime': end_datetime, 'print_datetime': ktv_helper.utc_now_str(), 'cash_fee': cash_fee, 'member_card_fee': member_card_fee, 'credit_card_fee': credit_card_fee, 'sales_voucher_fee': sales_voucher_fee, 'free_fee': free_fee, 'on_credit_fee': on_credit_fee, 'check_fee': check_fee, 'prepay_fee': prepay_fee, 'store_card_fee': store_card_fee, 'total_after_discount_fee': total_after_discount_fee, 'room_fee': room_fee, 'hourly_fee': hourly_fee, 'changed_room_fee': changed_room_fee, 'changed_room_hourly_fee': changed_room_hourly_fee, 'total_fee': total_fee, 'total_discount_fee': total_discount_fee, 'song_ticket_minutes': song_ticket_minutes, 'group_member_class_fee': group_member_class_fee.values(), 'group_room_type_fee': group_room_type_fee.values(), }