123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- # -*- coding: utf-8 -*-
- import datetime
- import copy
- from odoo.exceptions import ValidationError
- # 计算累计数据。
- # 例如:
- # 2019.2.2之前的累计数据:(场、舍、批次)
- # (1, 1, 1), [11.1, 12.1]
- # (1, 1, 2), [21.2, 22.2]
- # (1, 2, 1), [31.3, 32.3]
- # 每日数据:
- # (1, 1, 1), 2019.2.2, [100, 100])
- # (1, 1, 1), 2019.2.3, [1000, 1000])
- # (1, 2, 1), 2019.2.2, [100, 100])
- # (1, 2, 1), 2019.2.3, [1000, 1000])
- # (1, 3, 3), 2019.2.2, [100, 100])
- # (1, 3, 3), 2019.2.3, [1000, 1000])
- # (1, 1, 2), 2019.2.3, [1000, 1000])
- # (1, 4, 4), 2019.2.3, [1000, 1000])
- # 则:累计数据:
- # [(1, 4, 4), '2019-02-02', [0, 0]]
- # [(1, 4, 4), '2019-02-03', [1000, 1000]]
- # [(1, 2, 1), '2019-02-02', [131.3, 132.3]]
- # [(1, 2, 1), '2019-02-03', [1131.3, 1132.3]]
- # [(1, 1, 1), '2019-02-02', [111.1, 112.1]]
- # [(1, 1, 1), '2019-02-03', [1111.1, 1112.1]]
- # [(1, 3, 3), '2019-02-02', [100, 100]]
- # [(1, 3, 3), '2019-02-03', [1100, 1100]]
- # [(1, 1, 2), '2019-02-02', [21.2, 22.2]]
- # [(1, 1, 2), '2019-02-03', [1021.2, 1022.2]]
- # =====用法:=====
- # date = datetime.date(2019, 2, 2)
- # helper = CumulativeHelper(date, 2)
- # helper.add_sumup_data((1, 1, 1), [11.1, 12.1])
- # helper.add_sumup_data((1, 1, 2), [21.2, 22.2])
- # helper.add_sumup_data((1, 2, 1), [31.3, 32.3])
- # day1 = date + datetime.timedelta(days=1)
- # helper.add_data_after_sumup((1, 1, 1), date, [100, 100])
- # helper.add_data_after_sumup((1, 1, 1), day1, [1000, 1000])
- # helper.add_data_after_sumup((1, 2, 1), date, [100, 100])
- # helper.add_data_after_sumup((1, 2, 1), day1, [1000, 1000])
- # helper.add_data_after_sumup((1, 3, 3), date, [100, 100])
- # helper.add_data_after_sumup((1, 3, 3), day1, [1000, 1000])
- # helper.add_data_after_sumup((1, 1, 2), day1, [1000, 1000])
- # helper.add_data_after_sumup((1, 4, 4), day1, [1000, 1000])
- # result = helper.get()
- class CumulativeHelper:
- def __init__(self, date, sumup_data_count):
- self.date = date
- self.sumup_data_count = sumup_data_count
- self.yesterday = date + datetime.timedelta(days=-1)
- self.last_data = {}
- self.data = {} # 从date的前一天开始的累计数据
- self.current_date = None
- self.current_sumup = None
- self.current_key = None
- return
- def add_sumup_data(self, key, sumup_data_list): # 添加指定日期之前的累计数据。 key:tuple,例如:(养殖场ID, 栋舍ID)
- if not sumup_data_list or len(sumup_data_list) != self.sumup_data_count:
- raise ValidationError(u'开发错误:累计数据项数不对:key:{}'.format(key))
- if key not in self.data:
- self.last_data[key] = DateData()
- self.last_data[key].add(self.yesterday, sumup_data_list)
- return
- def _init_current(self, key):
- sumup_data = self._get_yesterday_data(key, self.date)
- self.current_key = key
- self.current_sumup = sumup_data
- self.current_date = self.yesterday
- return
- def add_data_after_sumup(self, key, date, data_list_today): # 添加指定日期开始的当天数据。 key:tuple,例如:(养殖场ID, 栋舍ID)
- if not data_list_today or len(data_list_today) != self.sumup_data_count:
- raise ValidationError(u'开发错误:当前日期数据项数不对:date:{0},key:{1}'.format(date, key))
- if key != self.current_key:
- self._init_current(key)
- if key not in self.data:
- self.data[key] = DateData()
- self.current_date += datetime.timedelta(days=1)
- if date != self.current_date: # 说明当前时间不是最近的累计数据的时间下一天。即:时间不连续
- diff_days = (date - self.current_date).days
- if diff_days < 0:
- raise ValidationError(u'开发错误:添加的数据的日期错误。请确认是否按日期排序了')
- sumup = [i for i in self.current_sumup] if self.current_sumup else [0 for i in data_list_today]
- for i in range(diff_days):
- self.data[key].add(self.current_date, sumup)
- self.current_date += datetime.timedelta(days=1)
- if not self.current_sumup:
- self.current_sumup = data_list_today
- else:
- for i in range(len(data_list_today)):
- self.current_sumup[i] += data_list_today[i]
- self.data[key].add(date, copy.deepcopy(self.current_sumup))
- return
- def get(self):
- result = []
- for key, value in self.data.items():
- all_day_data = value.getAll()
- for item in all_day_data:
- date, sumup_data = item
- result.append([key, date, sumup_data])
- return result
- def _get_yesterday_data(self, key, date):
- if not self.last_data:
- return None
- yesterday = date + datetime.timedelta(days=-1)
- if yesterday == self.yesterday:
- if key in self.last_data:
- return self.last_data[key].get(yesterday)
- return None
- if key in self.data:
- return self.data[key].get(yesterday)
- return None
- class DateData:
- def __init__(self):
- self.data = []
- return
- def add(self, date, data): # 同一个日期只有一个数据。如果重复,则替换
- for _list in self.data:
- if _list[0] == date:
- _list[1] = data
- return
- self.data.append([date, data])
- return
- def get(self, date):
- for _list in self.data:
- if _list[0] == date:
- return _list[1]
- return []
- def getAll(self):
- return self.data
|