zhangdongming пре 1 година
родитељ
комит
3b1e464ccc
1 измењених фајлова са 176 додато и 1 уклоњено
  1. 176 1
      Controller/UnicomCombo/UnicomComboTaskController.py

+ 176 - 1
Controller/UnicomCombo/UnicomComboTaskController.py

@@ -19,7 +19,7 @@ from django.db.models import Q
 from django.views import View
 
 from Model.models import UnicomComboOrderInfo, UnicomCombo, Order_Model, UnicomDeviceInfo, UnicomFlowPush, \
-    IotCardUsageHistory, AccessNumberTaskQueue, IotCardOrderUsageHistory
+    IotCardUsageHistory, AccessNumberTaskQueue, IotCardOrderUsageHistory, OperatingCosts
 from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.TelecomObject import TelecomObject
@@ -72,6 +72,8 @@ class UnicomComboTaskView(View):
             return self.get_access_number_change_task(response)
         elif operation == 'queryTotalTrafficToday':
             return self.query_total_traffic_today(response)
+        elif operation == 'createMonthlyCost':
+            return self.query_4G_order_info(response)
         else:
             return response.json(414)
 
@@ -678,3 +680,176 @@ class UnicomComboTaskView(View):
                 IotCardOrderUsageHistory.objects.bulk_create(iccid_list)
         except Exception as e:
             logger.error('统计4G卡日用量异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @classmethod
+    def query_4G_order_info(cls, response):
+        # 获取当前月的开始时间戳
+        first_timestamp, last_timestamp = cls.get_current_month_range()
+        # 统计条件失效时间大于当月开始时间(6月成本账单)统计范围订单创建时间大于5月1号的套餐
+        # 查询APP上显示的套餐
+        u_order_qs = UnicomComboOrderInfo.objects.filter(expire_time__gte=first_timestamp, combo__is_show=True
+                                                         , created_time__gte=1714492800) \
+            .exclude(combo_id__in=[24, 26, 34]).values('status', 'combo__expiration_days', 'flow_total_usage',
+                                                       'combo__flow_total', 'order_id',
+                                                       'activation_time', 'expire_time', 'created_time', 'iccid'
+                                                       ).order_by('created_time')
+        asy = threading.Thread(target=UnicomComboTaskView.created_flow_monthly_cost,
+                               args=(u_order_qs, first_timestamp, last_timestamp))
+        asy.start()
+        print(datetime.datetime.today())
+        print(u_order_qs.count())
+        # 查询APP不显示购买的套餐 执行异步
+        u_order_qs = UnicomComboOrderInfo.objects.filter(expire_time__gte=first_timestamp, combo__is_show=False
+                                                         , created_time__gte=1714492800) \
+            .exclude(combo_id__in=[24, 26, 34]).values('status', 'combo__expiration_days', 'flow_total_usage',
+                                                       'combo__flow_total', 'order_id',
+                                                       'activation_time', 'expire_time', 'created_time', 'iccid'
+                                                       ).order_by('created_time')
+        asy = threading.Thread(target=UnicomComboTaskView.created_flow_monthly_cost,
+                               args=(u_order_qs, first_timestamp, last_timestamp))
+        asy.start()
+        print(u_order_qs.count())
+        return response.json(0)
+
+    @classmethod
+    def created_flow_monthly_cost(cls, u_order_qs, first_timestamp, last_timestamp):
+        print(f'开始了{datetime.datetime.now()}')
+        first_date = int(datetime.datetime.fromtimestamp(first_timestamp).strftime('%Y%m%d'))
+        costs_list = []
+        for item in u_order_qs:
+            try:
+                # 查询订单是否存在
+                order_qs = Order_Model.objects.filter(orderID=item['order_id'], status=1).values('orderID', 'UID',
+                                                                                                 'payTime', 'price',
+                                                                                                 'store_meal_name')
+
+                if not order_qs.exists():
+                    continue
+
+                u_order = item
+
+                price = float(order_qs[0]['price'])
+
+                day_average_price = 0  # 收入分摊/天  订单金额/套餐总天数
+
+                if price > day_average_price:
+                    expiration_days = int(u_order['combo__expiration_days'])
+                    day_average_price = price / expiration_days
+
+                # 套餐到期时间与当月结算时间相差天数=剩余使用天数
+                expire_time = datetime.datetime.fromtimestamp(u_order['expire_time'])
+                month_time = datetime.datetime.fromtimestamp(last_timestamp)
+                # 剩余使用天数
+                days_diff = (expire_time - month_time).days
+
+                # 当月结算时间与套餐创建时间相差天数=当月结算天数
+                if u_order['created_time'] >= first_timestamp:
+                    c_time = datetime.datetime.fromtimestamp(u_order['created_time'])
+                else:
+                    c_time = datetime.datetime.fromtimestamp(first_timestamp)
+                settlement_days = (month_time - c_time).days + 1
+                settlement_days = 0 if settlement_days < 0 else settlement_days
+
+                # 组装当月成本账单结构
+                costs_vo = {
+                    'settlement_days': settlement_days,  # 当月结算天数
+                    'order_id': order_qs[0]['orderID'],
+                    'uid': order_qs[0]['UID'],
+                    'day_average_price': Decimal(day_average_price).quantize(Decimal('0.0000')),  # 收入分摊/天
+                    'purchase_quantity': u_order['combo__flow_total'],
+                    'start_time': u_order['created_time'],
+                    'end_time': u_order['expire_time'],
+                    'created_time': last_timestamp,
+                    'remaining_usage_time': days_diff,  # 剩余使用时间
+                    'time': first_timestamp,
+                    'country_name': '中国',
+                    'order_type': '4G',
+                    'region': '国内',
+                    'price': order_qs[0]['price']
+                }
+                days = int(u_order['combo__expiration_days'])
+                if settlement_days > 0 and price > 0:
+                    # 实际收入/套餐总天数*结算天数
+                    costs_vo['monthly_income'] = Decimal((price - price * 0.0054) / days * settlement_days).quantize(
+                        Decimal('0.0000'))
+                month_average_price = day_average_price * settlement_days if day_average_price > 0 else 0
+                # 收入分摊/天*当月使用天数
+                costs_vo['month_average_price'] = Decimal(month_average_price).quantize(Decimal('0.00'))
+
+                # 使用filter()方法进行查询
+                uos_qs = UnicomComboOrderInfo.objects.filter(
+                    iccid=u_order['iccid'], expire_time__gte=first_timestamp
+                ).exclude(combo_id__in=[24, 26, 34])
+                con = uos_qs.count()
+                profit_margin = 0
+                cost = 2
+                profit = 0  # 当月利润
+
+                # 查询IOT卡订单用量历史
+                n_flow = IotCardOrderUsageHistory.objects.filter(
+                    order_id=u_order['order_id'],
+                    cycle__gte=first_date
+                ).order_by('-cycle_date')
+
+                cost = cost if not uos_qs.exists() else cost / con  # 联通4G单卡月租2元/对应套餐数量   当月成本分摊
+                if n_flow.exists():
+                    # 查询IOT卡订单用量历史
+                    old_flow = IotCardOrderUsageHistory.objects.filter(
+                        order_id=u_order['order_id'],
+                        cycle__lt=first_date
+                    ).order_by('-cycle_date')
+                    old_use_flow = float(old_flow.first().total_traffic if old_flow.exists() else 0)
+                    n_user_flow = float(n_flow.first().total_traffic)
+                    actual_flow = n_user_flow - old_use_flow if n_user_flow > 0 else 0
+                    costs_vo['actual_flow'] = actual_flow
+                    # 基础分摊成本
+
+                    flow_cost = 0
+                    # 流量使用成本
+                    if actual_flow > 0:
+                        flow_cost = (actual_flow / 1024 * 0.4)
+                    cost = cost + flow_cost
+                    if 'monthly_income' in costs_vo:
+                        profit = float(costs_vo['monthly_income']) - cost
+                        profit_margin = profit / cost * (1 * 100)
+                    costs_vo['actual_flow'] = Decimal(actual_flow).quantize(Decimal('0.00'))
+                elif price > 0:
+                    if 'monthly_income' in costs_vo:
+                        profit = float(costs_vo['monthly_income']) - cost
+                        profit_margin = profit / cost * (1 * 100)
+                costs_vo['flow_cost'] = Decimal(cost).quantize(Decimal('0.00'))
+                costs_vo['profit'] = Decimal(profit).quantize(Decimal('0.00'))
+                costs_vo['profit_margin'] = Decimal(profit_margin).quantize(Decimal('0.00'))
+                fee = price * 0.0054 if price > 0 else 0
+                costs_vo['fee'] = Decimal(fee).quantize(Decimal('0.00'))
+                costs_vo['real_income'] = Decimal(price - fee).quantize(Decimal('0.00'))
+                costs_vo['expire'] = order_qs[0]['store_meal_name']
+                costs_list.append(OperatingCosts(**costs_vo))
+                # # 批量插入操作,每300条记录插入一次
+                if len(costs_list) >= 300:
+                    OperatingCosts.objects.bulk_create(costs_list)
+                    costs_list = []
+
+            except Exception as e:
+                logger.error('统计4G卡日用量异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+                continue
+        # 插入剩余的记录
+        if costs_list:
+            OperatingCosts.objects.bulk_create(costs_list)
+        return True
+
+    @staticmethod
+    def get_current_month_range():
+        # 获取当前日期
+        today = datetime.datetime.today()
+        # 获取当前月份第一天
+        first_day = today.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
+        # 获取下个月第一天
+        next_month = today.replace(day=28) + datetime.timedelta(days=4)  # 跳过了2月份的28号日期
+        last_day = next_month - datetime.timedelta(days=next_month.day)
+
+        # 转换为时间戳
+        first_timestamp = int(first_day.timestamp())
+        last_timestamp = int(last_day.timestamp())
+
+        return first_timestamp, last_timestamp