Browse Source

财务月结算

peng 1 year ago
parent
commit
98f0a7e921
2 changed files with 102 additions and 5 deletions
  1. 78 5
      Controller/Cron/CronTaskController.py
  2. 24 0
      Model/models.py

+ 78 - 5
Controller/Cron/CronTaskController.py

@@ -13,7 +13,7 @@ import json
 import threading
 import time
 import zipfile
-
+import calendar
 import paypalrestsdk
 import requests
 import csv
@@ -22,17 +22,18 @@ from django.db.models import Q, Sum, Count
 from django.views import View
 
 from Ansjer.config import USED_SERIAL_REDIS_LIST, UNUSED_SERIAL_REDIS_LIST, CONFIG_INFO, CONFIG_US, \
-    RESET_REGION_ID_SERIAL_REDIS_LIST, LOGGER, PAYPAL_CRD, CONFIG_EUR, DETECT_PUSH_DOMAINS
+    RESET_REGION_ID_SERIAL_REDIS_LIST, LOGGER, PAYPAL_CRD, CONFIG_EUR, DETECT_PUSH_DOMAINS, ACCESS_KEY_ID, \
+    SECRET_ACCESS_KEY, REGION_NAME
 from Model.models import Device_User, Device_Info, UidSetModel, UID_Bucket, Unused_Uid_Meal, Order_Model, StsCrdModel, \
     VodHlsModel, ExperienceContextModel, AiService, VodHlsSummary, VideoPlaybackTimeModel, DeviceUserSummary, \
     CountryModel, DeviceTypeModel, OrdersSummary, DeviceInfoSummary, CompanySerialModel, \
     CloudLogModel, UidCloudStorageCount, UserExModel, DeviceDomainRegionModel, VodHlsTag, VodHlsTagType, IcloudService, \
     Store_Meal, Lang, VodBucketModel, UnicomComboOrderInfo, UnicomDeviceInfo, AbnormalOrder, DailyReconciliation, \
-    CustomizedPush, UIDCompanySerialModel, UIDModel, LogModel
+    CustomizedPush, UIDCompanySerialModel, UIDModel, LogModel, OperatingCosts
+from Object.AWS.AmazonS3Util import AmazonS3Util
 from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.utils import LocalDateTimeUtil
-from Object.utils.PayPalUtil import PayPalService
 from Service.CommonService import CommonService
 from Service.EquipmentInfoService import EQUIPMENT_INFO_MODEL_LIST
 from Service.VodHlsService import SplitVodHlsObject
@@ -301,7 +302,7 @@ class CronDelDataView(View):
         # 每次删除条数
         size = 5000
 
-        for i in range(1, len(EQUIPMENT_INFO_MODEL_LIST)+1):
+        for i in range(1, len(EQUIPMENT_INFO_MODEL_LIST) + 1):
             sql = "DELETE FROM equipment_info_{} WHERE add_time< %s LIMIT %s ".format(i)
             cursor.execute(sql, [expiration_time, size])
 
@@ -797,6 +798,8 @@ class CronCollectDataView(View):
             return self.collect_device_info(response)
         elif operation == 'collectFlowInfo':  # 定时保存设备数据
             return self.collect_flow_info(response)
+        elif operation == 'collectOperatingCosts':  # 定时运营成本
+            return self.collect_operating_costs(response)
         else:
             return response.json(404)
 
@@ -1123,6 +1126,73 @@ class CronCollectDataView(View):
         except Exception as e:
             return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
+    @staticmethod
+    def collect_operating_costs(response):
+        try:
+            created_time = int(time.time())
+            today = datetime.datetime.today()
+            end_time = datetime.datetime(today.year, today.month, 1)
+            start_time = end_time - relativedelta(months=1)
+            start_time_stamp = CommonService.str_to_timestamp(start_time.strftime('%Y-%m-%d %H:%M:%S'))
+            end_time_stamp = CommonService.str_to_timestamp(end_time.strftime('%Y-%m-%d %H:%M:%S'))
+            order_list = UID_Bucket.objects.filter(endTime__gte=start_time_stamp).values_list('orderId', flat=True)
+            order_qs = Order_Model.objects.filter(orderID__in=order_list).values('trade_no', 'price', 'UID', 'payTime',
+                                                                                 'order_type', 'rank__expire',
+                                                                                 'payType', 'uid_bucket_id', 'channel',
+                                                                                 'rank__bucket__bucket',
+                                                                                 'orderID')
+            s3_obj = AmazonS3Util(ACCESS_KEY_ID, SECRET_ACCESS_KEY, REGION_NAME)
+            paypal_api = paypalrestsdk.Api(PAYPAL_CRD)
+            for order in order_qs:
+                price = float(order['price'])
+                if order['payType'] == 1:  # paypal支付查询手续费
+                    paypal_url = 'v1/reporting/transactions?start_date={}-{}-{}T00:00:00-0000&end_date={}-{}-{}T00:00:00-0000&transaction_id={}&fields=all&page_size=100&page=1'.format(
+                        start_time.year, start_time.month, start_time.day, end_time.year, end_time.month, end_time.day,
+                        order['trade_no'])
+                    paypal_order_list = paypal_api.get(paypal_url)
+                    fee = paypal_order_list
+                else:
+                    fee = 0
+                bucket_qs = UID_Bucket.objects.filter(id=order['uid_bucket_id']).values('endTime')
+                if bucket_qs[0]['endTime'] > end_time_stamp:  # 当月结算天数
+                    settlement_days = (end_time - start_time).days
+                else:
+                    settlement_days = (bucket_qs[0]['endTime'] - start_time_stamp) / 86400
+                day_average_price = price / ((bucket_qs[0]['endTime'] - order['payTime']) / 86400)  # 收入分摊/天
+                month_average_price = day_average_price * settlement_days  # 收入分摊/月
+                monthly_income = (price - fee) / settlement_days  # 当月结算收入
+                remaining_usage_time = (bucket_qs[0]['endTime'] - end_time_stamp) / 86400  # 剩余使用时间
+                # path = '{uid}/vod{channel}'.format(uid=order['uid'], channel=order['channel'])
+                # s3_result = s3_obj.get_object_list(order['rank__bucket__bucket'], path,
+                #                                    path + '/{}'.format(start_time_stamp))
+                # actual_storage = 0
+                # actual_api = 0
+                # for item in s3_result:
+                #     temp_time = int(item['Key'].split('/')['2'])
+                #     if temp_time < end_time_stamp:
+                #         actual_storage += item['Size']
+                #         actual_api += 1
+                with transaction.atomic():
+                    operating_costs_qs = OperatingCosts.objects.filter(order_id=order['orderID'], time=start_time)
+                    if operating_costs_qs.exists():
+                        operating_costs_qs.update(fee=fee, day_average_price=day_average_price,
+                                                  month_average_price=month_average_price,
+                                                  monthly_income=monthly_income,
+                                                  settlement_days=settlement_days,
+                                                  remaining_usage_time=remaining_usage_time)
+                    else:
+                        OperatingCosts.objects.create(order_id=order['orderID'], fee=fee,
+                                                      day_average_price=day_average_price,
+                                                      month_average_price=month_average_price,
+                                                      monthly_income=monthly_income,
+                                                      settlement_days=settlement_days,
+                                                      remaining_usage_time=remaining_usage_time,
+                                                      created_time=created_time,
+                                                      time=start_time)
+            return response.json(0)
+        except Exception as e:
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
     @staticmethod
     def collect_icloud_order(response):
         try:
@@ -1695,6 +1765,7 @@ class CronComparedDataView(View):
     @staticmethod
     def compared_ansjer_order(request_dict, response):
         start_date_stamp = request_dict.get('time', None)
+        end_time = request_dict.get('end_time', None)
         if start_date_stamp:
             start_date = datetime.datetime.fromtimestamp(int(start_date_stamp))
             end_date = start_date + datetime.timedelta(days=1)
@@ -1707,6 +1778,8 @@ class CronComparedDataView(View):
             start_date_stamp = int(start_date.timestamp())
             end_date_stamp = int(end_date.timestamp())
         try:
+            if end_time:
+                end_date_stamp = end_time
             order_qs = Order_Model.objects.filter(status__in=[1, 5, 6], payType=1, payTime__gte=start_date_stamp,
                                                   payTime__lt=end_date_stamp).values('orderID', 'trade_no', 'price')
             if CONFIG_INFO == CONFIG_EUR:

+ 24 - 0
Model/models.py

@@ -4210,6 +4210,30 @@ class DeviceInfoSummary(models.Model):
         verbose_name_plural = verbose_name
 
 
+class OperatingCosts(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='设备汇总列表主键')
+    order_id = models.CharField(verbose_name='订单号', default='', max_length=24, db_index=True)
+    fee = models.CharField(verbose_name='手续费', default='', max_length=8)
+    day_average_price = models.CharField(verbose_name='收入分摊/天', default='', max_length=16)  # 订单金额/订单天数
+    month_average_price = models.CharField(verbose_name='收入分摊/月', default='', max_length=16)  # 收入分摊/天*当月使用天数
+    purchase_quantity = models.CharField(verbose_name='购买量/月', default='', max_length=8, blank=True)
+    actual_storage = models.CharField(default='', verbose_name='实际存储量', max_length=16)
+    actual_api = models.IntegerField(default=0, verbose_name='实际调用api次数')
+    monthly_income = models.CharField(verbose_name='当月结算收入', default='', max_length=16)  # 实际收入/套餐总天数*结算天数
+    settlement_days = models.SmallIntegerField(verbose_name='当月结算天数', default=0)
+    remaining_usage_time = models.IntegerField(default=0, verbose_name='剩余使用时间')
+    created_time = models.IntegerField(default=0, verbose_name='当月结算时间')
+    time = models.IntegerField(verbose_name='时间戳', default=0)
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'operating_costs'
+        verbose_name = '运营成本'
+        verbose_name_plural = verbose_name
+
+
 class KVS(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='主键')
     stream_name = models.CharField(default='', max_length=128, verbose_name='视频流名称')  # 视频流名称,为序列号