123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- # -*- encoding: utf-8 -*-
- """
- @File : AgentDeviceController.py
- @Time : 2024/3/8 13:55
- @Author : stephen
- @Email : zhangdongming@asj6.wecom.work
- @Software: PyCharm
- """
- from datetime import datetime
- from dateutil.relativedelta import relativedelta
- from collections import defaultdict
- from decimal import Decimal
- import traceback
- from django.http import QueryDict
- from django.views import View
- from AgentModel.models import AgentCustomerInfo, AgentDeviceOrder, AgentDevice, AgentCloudServicePackage
- from Model.models import DeviceTypeModel
- from Object.ResponseObject import ResponseObject
- from Object.TokenObject import TokenObject
- class AgentDeviceView(View):
- def get(self, request, *args, **kwargs):
- request.encoding = 'utf-8'
- operation = kwargs.get('operation')
- return self.validation(request.GET, request, operation)
- def post(self, request, *args, **kwargs):
- request.encoding = 'utf-8'
- operation = kwargs.get('operation')
- return self.validation(request.POST, request, operation)
- def delete(self, request, *args, **kwargs):
- request.encoding = 'utf-8'
- operation = kwargs.get('operation')
- delete = QueryDict(request.body)
- if not delete:
- delete = request.GET
- return self.validation(delete, request, operation)
- def put(self, request, *args, **kwargs):
- request.encoding = 'utf-8'
- operation = kwargs.get('operation')
- put = QueryDict(request.body)
- return self.validation(put, request, operation)
- def validation(self, request_dict, request, operation):
- language = request_dict.get('language', 'en')
- response = ResponseObject(language, 'pc')
- # 订单结算界面
- if operation == 'XXXXX':
- pass
- else:
- tko = TokenObject(
- request.META.get('HTTP_AUTHORIZATION'),
- returntpye='pc')
- if tko.code != 0:
- return response.json(tko.code)
- response.lang = tko.lang
- userID = tko.userID
- if operation == 'getAgentDevice':
- return self.get_agent_device(userID, request_dict, response)
- elif operation == 'getAgentDeviceOrder':
- return self.get_agent_device_order(userID, request_dict, response)
- else:
- return response.json(444, 'operation')
- def get_agent_device(self, userID, request_dict, response):
- """
- 查询设备明细
- @param userID: userID
- @param request_dict: 请求参数
- @param request_dict ac_id: 代理商id
- @param request_dict device_name: 设备名字
- @param request_dict status: 设备类型
- @param request_dict serial_number: 设备9位序列号
- @param response: 响应对象
- @return:
- """
- device_name = request_dict.get('device_name', None)
- status = request_dict.get('status', None)
- serial_number = request_dict.get('serial_number', None)
- agent_customer_info = AgentCustomerInfo.objects.filter(user_id=userID).first()
- if agent_customer_info is None:
- return response.json(104, 'Agent customer not found')
- ac_id = agent_customer_info.id
- try:
- agent_device_qs = AgentDevice.objects.filter(ac_id=ac_id)
- if device_name:
- # 根据device_name查询对应的type值
- device_types = list(DeviceTypeModel.objects.filter(name=device_name).values_list('type', flat=True))
- agent_device_qs = agent_device_qs.filter(type__in=device_types)
- if status:
- agent_device_qs = agent_device_qs.filter(status=status)
- if serial_number:
- agent_device_qs = agent_device_qs.filter(serial_number=serial_number)
- # 构造返回列表
- device_list = []
- for device in agent_device_qs:
- device_type = DeviceTypeModel.objects.filter(type=device.type).first()
- device_name = device_type.name if device_type else device.type
- device_list.append({
- 'id': device.id,
- 'ac_id': device.ac_id,
- 'status': device.status,
- 'serial_number': device.serial_number,
- 'device_name': device_name,
- 'at_time': device.at_time,
- })
- return response.json(0, {'list': device_list})
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- def calculate_profit_or_revenue(self, agent_device_orders, package_details, time_unit, metric_type, start_time, end_time):
- """
- 计算利润或者营业额
- @param agent_device_orders: 代理设备订单
- @param package_details: 代理套餐详情
- @param time_unit: 时间单位
- @param metric_type: 利润或者营业额
- @param start_time: 开始时间
- @param end_time: 结束时间
- @return:
- """
- summary = defaultdict(lambda: {"云存": Decimal('0.00'), "4G": Decimal('0.00'), "all": Decimal('0.00')})
- time_format = {
- "month": "%Y-%m",
- "year": "%Y",
- "quarter": lambda x: f"{x.year}年{(x.month - 1) // 3 + 1}季度"
- }
- for order in agent_device_orders:
- package = package_details.get(order.csp_id)
- if not package:
- continue
- # 根据利润类型计算利润或者直接使用营业额
- if metric_type == 1: # 利润
- profit = package.profit if package.profit_type == 1 else order.profit_amount * package.profit / Decimal(
- '100.00')
- else: # 营业额
- profit = order.profit_amount
- # 区分云服务 + 4G套餐并加入 summary
- service_type = "icloud" if package.type == 1 else "unicom"
- time_key = datetime.fromtimestamp(order.created_time).strftime(
- time_format[time_unit]) if time_unit != "quarter" else time_format[time_unit](
- datetime.fromtimestamp(order.created_time))
- summary[time_key][service_type] += profit
- summary[time_key]["all"] += profit
- # 补全时间段内所有可能的时间单位
- current_time = start_time
- end_time += relativedelta(days=1) # 包括结束日期
- while current_time < end_time:
- time_key = current_time.strftime(time_format[time_unit]) if time_unit != "quarter" else time_format[
- time_unit](current_time)
- if time_key not in summary:
- summary[time_key] = {"云存": Decimal('0.00'), "4G": Decimal('0.00'), "all": Decimal('0.00')}
- current_time += relativedelta(months=1) if time_unit == "month" else relativedelta(
- years=1) if time_unit == "year" else relativedelta(months=3)
- return [{"time": time, **data} for time, data in sorted(summary.items())]
- def get_agent_device_order(self, userID, request_dict, response):
- """
- 查询设备订单明细
- @param userID: userID
- @param request_dict: 请求参数
- @param request_dict startTime: 开始时间
- @param request_dict endTime: 结束时间
- @param request_dict timeUnit: 时间单位
- @param request_dict metric_type: 利润或者营业额
- @param response: 响应对象
- @return:
- """
- try:
- startTime = int(request_dict.get('startTime', 1704038400))
- endTime = int(request_dict.get('endTime', 1732982400))
- timeUnit = request_dict.get('timeUnit', 'month')
- metric_type = int(request_dict.get('metric_type', 0))
- agent_customer_info = AgentCustomerInfo.objects.filter(user_id=userID).first()
- if not agent_customer_info:
- return response.json(104, 'Agent customer not found')
- agent_device_orders = AgentDeviceOrder.objects.filter(
- ac_id=agent_customer_info.id, created_time__gte=startTime, created_time__lte=endTime, status__in=[1, 2]
- )
-
- # 获取代理套餐包id
- package_ids = agent_device_orders.values_list('csp_id', flat=True).distinct()
- package_details = {pkg.id: pkg for pkg in AgentCloudServicePackage.objects.filter(id__in=package_ids)}
- start_time = datetime.fromtimestamp(startTime)
- end_time = datetime.fromtimestamp(endTime)
- result = self.calculate_profit_or_revenue(agent_device_orders, package_details, timeUnit, metric_type,
- start_time, end_time)
- return response.json(0, {'list': result})
- except Exception as e:
- error_msg = f"error_line:{traceback.format_exc()}, error_msg:{str(e)}"
- return response.json(500, error_msg)
|