def calculate_casher_shift_report(self,cr,uid,start_datetime,end_datetime): ''' 计算会员卡业务发生情况 :param start_datetime datetime 业务起始时间 :param end_datetime datetime 业务结束时间 :return dict 'member_card_count' 新会员数量 'member_card_fee' 会员卡销售金额 'member_charge_fee' 会员充值金额 ''' pool = self.pool #计算新办会员卡数量 ids = self.search(cr,uid,[('begin_datetime','>=',ktv_helper.strftime(start_datetime)),('begin_datetime','<=',ktv_helper.strftime(end_datetime))]) member_card_count = len(ids) member_card_fee = 0.0 for r in self.browse(cr,uid,ids): member_card_fee += r.card_fee + r.up_card_fee #计算会员充值金额 charge_fee = 0.0 charge_ids = pool.get('ktv.member_charge').search(cr,uid,[('bill_datetime','>=',ktv_helper.strftime(start_datetime)), \ ('bill_datetime','<=',ktv_helper.strftime(end_datetime))]) for r in pool.get('ktv.member_charge').browse(cr,uid,charge_ids): charge_fee += r.charge_fee return { 'member_card_count' : member_card_count, 'new_member_card_fee' : member_card_fee, 'member_charge_fee' : charge_fee, }
def get_shift_report(self,cr,uid,context=None): ''' 计算收银员交接单 如果收银员未进行交班操作,则生成交班信息,如果收银员已进行交班操作,则查询交班信息 如果未到交班时刻,则只能查看信息,不能进行交班操作 #FIXME 当班结束30分钟内可交班 ''' pool = self.pool ret = {} #获取前一班次 pre_work_shift = pool.get('ktv.work_shifts_config').get_previous_work_shift(cr,uid,datetime.now()) if not pre_work_shift: raise osv.except_osv(_("错误"), _('找不到班次设置信息.')) #判断是否存在交接单 start_datetime = pre_work_shift['start_datetime'] end_datetime = pre_work_shift['end_datetime'] str_start_datetime = ktv_helper.strftime(start_datetime) str_end_datetime = ktv_helper.strftime(end_datetime) rpt_ids = self.search(cr,uid,[('start_datetime','=',str_start_datetime), \ ('end_datetime','=',str_end_datetime)]) if rpt_ids: ret = self.read(cr,uid,rpt_ids[0]) else: ret = pool.get('ktv.room_operate').calculate_casher_shift_report(cr,uid,start_datetime,end_datetime) ret_member = pool.get('ktv.member').calculate_casher_shift_report(cr,uid,start_datetime,end_datetime) ret.update(ret_member) ret['start_datetime'] = str_start_datetime ret['end_datetime'] = str_end_datetime ret['shift_name'] = pre_work_shift['name'] ret['print_datetime'] = ktv_helper.strftime(datetime.now()) return ret
def calculate_casher_shift_report(self, cr, uid, start_datetime, end_datetime): ''' 计算会员卡业务发生情况 :param start_datetime datetime 业务起始时间 :param end_datetime datetime 业务结束时间 :return dict 'member_card_count' 新会员数量 'member_card_fee' 会员卡销售金额 'member_charge_fee' 会员充值金额 ''' pool = self.pool #计算新办会员卡数量 ids = self.search( cr, uid, [('begin_datetime', '>=', ktv_helper.strftime(start_datetime)), ('begin_datetime', '<=', ktv_helper.strftime(end_datetime))]) member_card_count = len(ids) member_card_fee = 0.0 for r in self.browse(cr, uid, ids): member_card_fee += r.card_fee + r.up_card_fee #计算会员充值金额 charge_fee = 0.0 charge_ids = pool.get('ktv.member_charge').search(cr,uid,[('bill_datetime','>=',ktv_helper.strftime(start_datetime)), \ ('bill_datetime','<=',ktv_helper.strftime(end_datetime))]) for r in pool.get('ktv.member_charge').browse(cr, uid, charge_ids): charge_fee += r.charge_fee return { 'member_card_count': member_card_count, 'new_member_card_fee': member_card_fee, 'member_charge_fee': charge_fee, }
def calculate_sum_pay_info(self, cr, uid, ctx_args): """ 根据给定的数值,计算买钟费用 :params context 包含计算上下问信息,required :params context[room_id] integer 包厢id,required :params context[consume_minutes] integer 买钟时间 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,用于记录打折员工信息 """ #获取当前包厢费用信息 room_id = ctx_args.get('room_id') consume_minutes = ctx_args['consume_minutes'] sum_should_pay_info = self.get_default_checkout_dict(cr, uid) #获取包厢费用信息 r_id, room_fee, minimum_fee, minimum_fee_p, minimum_persons, is_member_hourly_fee, room_hourly_fee, hourly_discount, hourly_fee_p, hourly_p_discount = self.pool.get( 'ktv.room').get_current_fee_tuple(cr, uid, room_id, ctx_args) #买钟优惠 promotion_consume_minutes, promotion_present_minutes = (0, 0) #买钟优惠信息 hourly_fee_promotions = self.pool.get( 'ktv.hourly_fee_promotion').get_active_configs(cr, uid) if hourly_fee_promotions: promotion_consume_minutes, promotion_present_minutes = ( hourly_fee_promotions[0]['buy_minutes'], hourly_fee_promotions[0]['present_minutes']) #钟点费 hourly_fee = room_hourly_fee * consume_minutes / 60.0 #时长合计 = 买钟时间 + 赠送时间 present_minutes = ktv_helper.calculate_present_minutes( consume_minutes, promotion_consume_minutes, promotion_present_minutes) sum_minutes = consume_minutes + present_minutes #计算包厢关闭时间 open_time = datetime.now() close_time = open_time + timedelta(minutes=sum_minutes) #更新返回值 sum_should_pay_info.update({ 'open_time': ktv_helper.strftime(open_time), 'close_time': ktv_helper.strftime(close_time), 'consume_minutes': consume_minutes, 'present_minutes': present_minutes, #包厢钟点费 'room_hourly_fee': room_hourly_fee, 'hourly_fee': hourly_fee, 'total_fee': hourly_fee, }) sum_should_pay_info.update(ctx_args) return sum_should_pay_info
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
def calculate_sum_pay_info(self,cr,uid,ctx_args): """ 根据给定的数值,计算买钟费用 :params context 包含计算上下问信息,required :params context[room_id] integer 包厢id,required :params context[consume_minutes] integer 买钟时间 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,用于记录打折员工信息 """ #获取当前包厢费用信息 room_id = ctx_args.get('room_id') consume_minutes = ctx_args['consume_minutes'] sum_should_pay_info = self.get_default_checkout_dict(cr,uid) #获取包厢费用信息 r_id,room_fee,minimum_fee,minimum_fee_p,minimum_persons,is_member_hourly_fee,room_hourly_fee,hourly_discount,hourly_fee_p,hourly_p_discount = self.pool.get('ktv.room').get_current_fee_tuple(cr,uid,room_id,ctx_args) #买钟优惠 promotion_consume_minutes,promotion_present_minutes = (0,0) #买钟优惠信息 hourly_fee_promotions = self.pool.get('ktv.hourly_fee_promotion').get_active_configs(cr,uid) if hourly_fee_promotions: promotion_consume_minutes,promotion_present_minutes = (hourly_fee_promotions[0]['buy_minutes'],hourly_fee_promotions[0]['present_minutes']) #钟点费 hourly_fee = room_hourly_fee*consume_minutes/60.0 #时长合计 = 买钟时间 + 赠送时间 present_minutes = ktv_helper.calculate_present_minutes(consume_minutes,promotion_consume_minutes,promotion_present_minutes) sum_minutes = consume_minutes + present_minutes #计算包厢关闭时间 open_time = datetime.now() close_time = open_time + timedelta(minutes = sum_minutes) #更新返回值 sum_should_pay_info.update({ 'open_time' : ktv_helper.strftime(open_time), 'close_time' : ktv_helper.strftime(close_time), 'consume_minutes' : consume_minutes, 'present_minutes' : present_minutes, #包厢钟点费 'room_hourly_fee' : room_hourly_fee, 'hourly_fee' : hourly_fee, 'total_fee' : hourly_fee, }) sum_should_pay_info.update(ctx_args) return sum_should_pay_info
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 calculate_casher_shift_report(self, cr, uid, start_datetime, end_datetime): """ 计算会员卡业务发生情况 :param start_datetime datetime 业务起始时间 :param end_datetime datetime 业务结束时间 :return dict 'member_card_count' 新会员数量 'member_card_fee' 会员卡销售金额 'member_charge_fee' 会员充值金额 """ pool = self.pool # 计算新办会员卡数量 ids = self.search( cr, uid, [ ("begin_datetime", ">=", ktv_helper.strftime(start_datetime)), ("begin_datetime", "<=", ktv_helper.strftime(end_datetime)), ], ) member_card_count = len(ids) member_card_fee = 0.0 for r in self.browse(cr, uid, ids): member_card_fee += r.card_fee + r.up_card_fee # 计算会员充值金额 charge_fee = 0.0 charge_ids = pool.get("ktv.member_charge").search( cr, uid, [ ("bill_datetime", ">=", ktv_helper.strftime(start_datetime)), ("bill_datetime", "<=", ktv_helper.strftime(end_datetime)), ], ) for r in pool.get("ktv.member_charge").browse(cr, uid, charge_ids): charge_fee += r.charge_fee return { "member_card_count": member_card_count, "new_member_card_fee": member_card_fee, "member_charge_fee": charge_fee, }
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 _re_calculate_open_and_close_time(self,cr,uid,ctx_args): """ 重新计算续钟时,包厢开启和关闭时间 :params context[room_id] integer 包厢id,required :params context[consume_minutes] integer 续钟时间 required :params context[present_minutes] integer 赠送时间 required :rtype dict {'open_time' : '','close_time'} """ pool = self.pool room_id = ctx_args['room_id'] consume_minutes = ctx_args['consume_minutes'] present_minutes = ctx_args.get('present_minutes',0) room = pool.get('ktv.room').browse(cr,uid,room_id) r_op = room.current_room_operate_id last_close_time = r_op.close_time #重新计算open_time和close_time open_time = last_close_time close_time = ktv_helper.strftime(ktv_helper.strptime(open_time) + timedelta(minutes = consume_minutes + present_minutes)) return { 'open_time' : open_time, 'close_time' : close_time, }
def _re_calculate_open_and_close_time(self, cr, uid, ctx_args): """ 重新计算续钟时,包厢开启和关闭时间 :params context[room_id] integer 包厢id,required :params context[consume_minutes] integer 续钟时间 required :params context[present_minutes] integer 赠送时间 required :rtype dict {'open_time' : '','close_time'} """ pool = self.pool room_id = ctx_args['room_id'] consume_minutes = ctx_args['consume_minutes'] present_minutes = ctx_args.get('present_minutes', 0) room = pool.get('ktv.room').browse(cr, uid, room_id) r_op = room.current_room_operate_id last_close_time = r_op.close_time #重新计算open_time和close_time open_time = last_close_time close_time = ktv_helper.strftime( ktv_helper.strptime(open_time) + timedelta(minutes=consume_minutes + present_minutes)) return { 'open_time': open_time, 'close_time': close_time, }
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 calculate_casher_shift_report(self,cr,uid,start_datetime,end_datetime): ''' 计算给定时间段的包厢费用信息,在casher_shift_report中调用 :param pre_start_datetime datetime 前班起始时间 :param pre_end_datetime datetime 前班起始时间 :param start_datetime datetime 当班计算起始时间 :param end_datetime datetime 当班计算结束时间 :return dict 包厢费用信息 ''' pool = self.pool #关联的room_operate_ids room_operate_ids = [] #计算上个班次的起始时间 prev_shift = pool.get('ktv.work_shifts_config').get_previous_work_shift(cr,uid,start_datetime) str_pre_start_datetime = ktv_helper.strftime(prev_shift['start_datetime']) str_pre_end_datetime = ktv_helper.strftime(prev_shift['end_datetime']) str_start_datetime = ktv_helper.strftime(start_datetime) str_end_datetime = ktv_helper.strftime(end_datetime) #现金/支票/会员卡/信用卡/储值卡/免单/挂账/抵用券 cash_fee = check_fee = member_card_fee = credit_card_fee = store_card_fee = free_fee = on_credit_fee = sales_voucher_fee = 0.0 #前班开台未关(不包括预售) pre_not_close = [] #前班开台未关(预售) pre_presale_not_close = [] #前班开台本班关台(不包括预售) pre_close_on_current = [] #前班开本班关(预售) pre_presale_close_on_current = [] #前班开台本班未关(不包括预售) pre_not_close_on_current = [] #前班开台本班未关(预售) pre_presale_not_close_on_current = [] #前班开台信息 previous_open_ids = self.search(cr,uid,[('operate_date','>=',str_pre_start_datetime),('operate_date','<=',str_pre_end_datetime)]) #先计算前班开台信息 for op in self.browse(cr,uid,previous_open_ids): close_time = getattr(op,'close_time',None) is_presale = getattr(op,'is_presale',False) if not close_time or (close_time and close_time > str_pre_end_datetime): if is_presale: pre_presale_not_close.append(op) else: pre_not_close.append(op) if close_time and close_time > str_pre_end_datetime and close_time >= str_start_datetime and close_time <= str_end_datetime: room_operate_ids.append(op.id) if is_presale: pre_presale_close_on_current.append(op) else: pre_close_on_current.append(op) if not close_time or (close_time and close_time > str_end_datetime): if is_presale: pre_presale_not_close_on_current.append(op) else: pre_not_close_on_current.append(op) #当班开台(不包括预售) current_open = [] #当班开台(预售) current_presale_open = [] #当班关台(不包括预售) current_close = [] #当班关台(预售) current_presale_close = [] #当班未关(不包括预售) current_not_close = [] #当班未关(预售) current_presale_not_close = [] #当班的开台记录 current_open_ids = self.search(cr,uid,[('operate_date','>=',str_start_datetime),('operate_date','<=',str_end_datetime)]) #先计算当班开台信息 for op in self.browse(cr,uid,current_open_ids): close_time = getattr(op,'close_time',None) is_presale = getattr(op,'is_presale',False) if is_presale: current_presale_open.append(op) else: current_open.append(op) if close_time and close_time <= str_end_datetime: #room_operate只记录在当班结账信息 room_operate_ids.append(op.id) if is_presale: current_presale_close.append(op) else: current_close.append(op) if not close_time or (close_time and close_time > str_end_datetime): if is_presale: current_presale_not_close.append(op) else: current_not_close.append(op) #计算费用信息,应计算以下费用 前班开本班关(不含预售) + 本班开本班关(普通+预售) + 本班开且未关(预售) for op in (pre_close_on_current + current_close + current_presale_close + current_presale_not_close): cash_fee += op.total_after_discount_cash_fee member_card_fee += op.member_card_fee credit_card_fee += op.credit_card_fee free_fee += op.free_fee on_credit_fee += op.on_credit_fee sales_voucher_fee += sales_voucher_fee #计算台数信息 ''' #前班开台未关(不包括预售) pre_not_close = [] #前班开台未关(预售) pre_presale_not_close = [] #前班开台本班关台(不包括预售) pre_close_on_current = [] #前班开本班关(预售) pre_presale_close_on_current = [] #前班开台本班未关(不包括预售) pre_not_close_on_current = [] #前班开台本班未关(预售) pre_presale_not_close_on_current = [] #当班开台(不包括预售) current_open = [] #当班开台(预售) current_presale_open = [] #当班关台(不包括预售) current_close = [] #当班关台(预售) current_presale_close = [] #当班未关(不包括预售) current_not_close = [] #当班未关(预售) current_presale_not_close = [] ''' previous_open_count = previous_close_count = previous_not_close_count = previous_bills_count = \ current_open_count = current_close_count = current_not_close_count = current_bills_count = 0 previous_open_count = len(pre_not_close) + len(pre_presale_not_close) previous_close_count = len(pre_close_on_current) + len(pre_presale_close_on_current) previous_not_close_count = len(pre_not_close_on_current) + len(pre_presale_not_close_on_current) previous_bills_count = previous_open_count current_open_count = len(current_open) + len(current_presale_open) current_close_count = len(current_close) + len(current_presale_close) current_not_close_count = len(current_not_close) + len(current_presale_not_close) current_bills_count = current_open_count #cash_fee = check_fee = member_card_fee = credit_card_fee = store_card_fee = free_fee = on_credit_fee = sales_voucher_fee = 0.0 ret = { 'cash_fee' : cash_fee, 'check_fee' : check_fee, 'member_card_fee' : member_card_fee, 'credit_card_fee' : credit_card_fee, 'store_card_fee' : store_card_fee, 'free_fee' : free_fee, 'on_credit_fee' : on_credit_fee, 'sales_voucher_fee' : sales_voucher_fee, 'previous_open_count' : previous_open_count, 'previous_close_count' : previous_close_count, 'previous_not_close_count' : previous_not_close_count, 'previous_bills_count' : previous_bills_count, 'current_open_count' : current_open_count, 'current_close_count' : current_close_count, 'current_not_close_count' : current_not_close_count, 'current_bills_count' : current_bills_count, 'room_operate_ids' : room_operate_ids, 'sum_open_count' : previous_open_count + current_open_count, 'sum_close_count' : previous_close_count + current_close_count, 'sum_not_close_count' : previous_not_close_count + current_not_close_count, 'sum_bills_count' : previous_bills_count + current_bills_count, 'sum_fee' : cash_fee + check_fee + member_card_fee + credit_card_fee + sales_voucher_fee, } return ret
def calculate_casher_shift_report(self, cr, uid, start_datetime, end_datetime): ''' 计算给定时间段的包厢费用信息,在casher_shift_report中调用 :param pre_start_datetime datetime 前班起始时间 :param pre_end_datetime datetime 前班起始时间 :param start_datetime datetime 当班计算起始时间 :param end_datetime datetime 当班计算结束时间 :return dict 包厢费用信息 ''' pool = self.pool #关联的room_operate_ids room_operate_ids = [] #计算上个班次的起始时间 prev_shift = pool.get( 'ktv.work_shifts_config').get_previous_work_shift( cr, uid, start_datetime) str_pre_start_datetime = ktv_helper.strftime( prev_shift['start_datetime']) str_pre_end_datetime = ktv_helper.strftime(prev_shift['end_datetime']) str_start_datetime = ktv_helper.strftime(start_datetime) str_end_datetime = ktv_helper.strftime(end_datetime) #现金/支票/会员卡/信用卡/储值卡/免单/挂账/抵用券 cash_fee = check_fee = member_card_fee = credit_card_fee = store_card_fee = free_fee = on_credit_fee = sales_voucher_fee = 0.0 #前班开台未关(不包括预售) pre_not_close = [] #前班开台未关(预售) pre_presale_not_close = [] #前班开台本班关台(不包括预售) pre_close_on_current = [] #前班开本班关(预售) pre_presale_close_on_current = [] #前班开台本班未关(不包括预售) pre_not_close_on_current = [] #前班开台本班未关(预售) pre_presale_not_close_on_current = [] #前班开台信息 previous_open_ids = self.search( cr, uid, [('operate_date', '>=', str_pre_start_datetime), ('operate_date', '<=', str_pre_end_datetime)]) #先计算前班开台信息 for op in self.browse(cr, uid, previous_open_ids): close_time = getattr(op, 'close_time', None) is_presale = getattr(op, 'is_presale', False) if not close_time or (close_time and close_time > str_pre_end_datetime): if is_presale: pre_presale_not_close.append(op) else: pre_not_close.append(op) if close_time and close_time > str_pre_end_datetime and close_time >= str_start_datetime and close_time <= str_end_datetime: room_operate_ids.append(op.id) if is_presale: pre_presale_close_on_current.append(op) else: pre_close_on_current.append(op) if not close_time or (close_time and close_time > str_end_datetime): if is_presale: pre_presale_not_close_on_current.append(op) else: pre_not_close_on_current.append(op) #当班开台(不包括预售) current_open = [] #当班开台(预售) current_presale_open = [] #当班关台(不包括预售) current_close = [] #当班关台(预售) current_presale_close = [] #当班未关(不包括预售) current_not_close = [] #当班未关(预售) current_presale_not_close = [] #当班的开台记录 current_open_ids = self.search( cr, uid, [('operate_date', '>=', str_start_datetime), ('operate_date', '<=', str_end_datetime)]) #先计算当班开台信息 for op in self.browse(cr, uid, current_open_ids): close_time = getattr(op, 'close_time', None) is_presale = getattr(op, 'is_presale', False) if is_presale: current_presale_open.append(op) else: current_open.append(op) if close_time and close_time <= str_end_datetime: #room_operate只记录在当班结账信息 room_operate_ids.append(op.id) if is_presale: current_presale_close.append(op) else: current_close.append(op) if not close_time or (close_time and close_time > str_end_datetime): if is_presale: current_presale_not_close.append(op) else: current_not_close.append(op) #计算费用信息,应计算以下费用 前班开本班关(不含预售) + 本班开本班关(普通+预售) + 本班开且未关(预售) for op in (pre_close_on_current + current_close + current_presale_close + current_presale_not_close): cash_fee += op.total_after_discount_cash_fee member_card_fee += op.member_card_fee credit_card_fee += op.credit_card_fee free_fee += op.free_fee on_credit_fee += op.on_credit_fee sales_voucher_fee += sales_voucher_fee #计算台数信息 ''' #前班开台未关(不包括预售) pre_not_close = [] #前班开台未关(预售) pre_presale_not_close = [] #前班开台本班关台(不包括预售) pre_close_on_current = [] #前班开本班关(预售) pre_presale_close_on_current = [] #前班开台本班未关(不包括预售) pre_not_close_on_current = [] #前班开台本班未关(预售) pre_presale_not_close_on_current = [] #当班开台(不包括预售) current_open = [] #当班开台(预售) current_presale_open = [] #当班关台(不包括预售) current_close = [] #当班关台(预售) current_presale_close = [] #当班未关(不包括预售) current_not_close = [] #当班未关(预售) current_presale_not_close = [] ''' previous_open_count = previous_close_count = previous_not_close_count = previous_bills_count = \ current_open_count = current_close_count = current_not_close_count = current_bills_count = 0 previous_open_count = len(pre_not_close) + len(pre_presale_not_close) previous_close_count = len(pre_close_on_current) + len( pre_presale_close_on_current) previous_not_close_count = len(pre_not_close_on_current) + len( pre_presale_not_close_on_current) previous_bills_count = previous_open_count current_open_count = len(current_open) + len(current_presale_open) current_close_count = len(current_close) + len(current_presale_close) current_not_close_count = len(current_not_close) + len( current_presale_not_close) current_bills_count = current_open_count #cash_fee = check_fee = member_card_fee = credit_card_fee = store_card_fee = free_fee = on_credit_fee = sales_voucher_fee = 0.0 ret = { 'cash_fee': cash_fee, 'check_fee': check_fee, 'member_card_fee': member_card_fee, 'credit_card_fee': credit_card_fee, 'store_card_fee': store_card_fee, 'free_fee': free_fee, 'on_credit_fee': on_credit_fee, 'sales_voucher_fee': sales_voucher_fee, 'previous_open_count': previous_open_count, 'previous_close_count': previous_close_count, 'previous_not_close_count': previous_not_close_count, 'previous_bills_count': previous_bills_count, 'current_open_count': current_open_count, 'current_close_count': current_close_count, 'current_not_close_count': current_not_close_count, 'current_bills_count': current_bills_count, 'room_operate_ids': room_operate_ids, 'sum_open_count': previous_open_count + current_open_count, 'sum_close_count': previous_close_count + current_close_count, 'sum_not_close_count': previous_not_close_count + current_not_close_count, 'sum_bills_count': previous_bills_count + current_bills_count, 'sum_fee': cash_fee + check_fee + member_card_fee + credit_card_fee + sales_voucher_fee, } 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": 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
def re_calculate_fee(self,cr,uid,context): ''' 买钟换房重新计算费用 原系统中,对于买钟换房费用的计算,有两种方式: 1、按照新包厢全额补差价 2、按照在原包厢、新包厢中的不同消费时间计算后补差价 由于第2种方式计算比较复杂,本系统中暂不实现 :param context['room_id'] integer 原包厢id required :param context['changed_room_id'] integer 新包厢id required :param context['member_id'] integer 会员卡id :param context['discount_card_id'] integer 打折卡id :param context['discounter_id'] integer 员工id :return dict 重新计算后的买钟换房对象 ''' pool = self.pool room_id = context.get('room_id') changed_room_id = context.get('changed_room_id') room = pool.get('ktv.room').browse(cr,uid,room_id) r_op = room.current_room_operate_id changed_room = pool.get('ktv.room').browse(cr,uid,changed_room_id) #原买钟时长 ori_consume_minutes = r_op.ori_consume_minutes #当前实际消费时长 consume_minutes = r_op.consume_minutes - r_op.left_minutes #计算新包厢应付买钟费用 clone_dict = {k : v for k,v in context.items()} clone_dict['room_id'] = changed_room_id clone_dict['consume_minutes'] = ori_consume_minutes clone_dict.pop('changed_room_id') #计算应支付费用 sum_should_pay_info = self.calculate_sum_pay_info(cr,uid,clone_dict) _logger.debug('sum_should_pay_info = %s' % sum_should_pay_info) #计算已支付费用 sum_paid_info = pool.get('ktv.room_operate').calculate_sum_paid_info(cr,uid,r_op.id) #_logger.debug('sum_paid_info = %s' % sum_paid_info) #换房需要重新计算买钟时长和到钟时间 changed_room_minutes = ori_consume_minutes - consume_minutes present_minutes = sum_paid_info['present_minutes'] sum_should_pay_info['consume_minutes'] = 0 sum_should_pay_info['changed_room_minutes'] = changed_room_minutes sum_should_pay_info['close_time'] = ktv_helper.strftime(datetime.now() + timedelta(minutes = sum_paid_info['left_minutes'])) #计算应补差额 total_fee = sum_should_pay_info['hourly_fee'] - sum_paid_info['hourly_fee'] - sum_paid_info['changed_room_fee'] - sum_paid_info['prepay_fee'] sum_should_pay_info.update({ 'changed_room_hourly_fee': total_fee, 'hourly_fee' : 0.0, 'total_fee' : total_fee, }) #计算折扣信息 tmp_dict = {k : v for k,v in context.items() if k in ('member_id','discount_card_id','discounter_id')} discount_info = self.set_discount_info(cr,uid,sum_should_pay_info['total_fee'],**tmp_dict) sum_should_pay_info.update(discount_info) #重新计算相关字段 self.set_calculate_fields(cr,uid,sum_should_pay_info) sum_should_pay_info.update(context) return sum_should_pay_info
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(), }