Пример #1
0
    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,
            }
Пример #2
0
  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
Пример #3
0
    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,
        }
Пример #4
0
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
Пример #5
0
    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
Пример #6
0
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
Пример #8
0
    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,
        }
Пример #9
0
    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,
     }
Пример #12
0
    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(),
                }
Пример #13
0
    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
Пример #14
0
    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
Пример #15
0
    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
Пример #16
0
    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
Пример #17
0
    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(),
        }