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
Esempio n. 2
0
    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)
Esempio n. 3
0
    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)
Esempio n. 4
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
Esempio n. 5
0
    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)
Esempio n. 6
0
    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'])
Esempio n. 7
0
    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'])
Esempio n. 8
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(),
                }
Esempio n. 9
0
    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
Esempio n. 10
0
    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
Esempio n. 11
0
    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
Esempio n. 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(),
        }