cumulative_helper.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. # -*- coding: utf-8 -*-
  2. import datetime
  3. import copy
  4. from odoo.exceptions import ValidationError
  5. # 计算累计数据。
  6. # 例如:
  7. # 2019.2.2之前的累计数据:(场、舍、批次)
  8. # (1, 1, 1), [11.1, 12.1]
  9. # (1, 1, 2), [21.2, 22.2]
  10. # (1, 2, 1), [31.3, 32.3]
  11. # 每日数据:
  12. # (1, 1, 1), 2019.2.2, [100, 100])
  13. # (1, 1, 1), 2019.2.3, [1000, 1000])
  14. # (1, 2, 1), 2019.2.2, [100, 100])
  15. # (1, 2, 1), 2019.2.3, [1000, 1000])
  16. # (1, 3, 3), 2019.2.2, [100, 100])
  17. # (1, 3, 3), 2019.2.3, [1000, 1000])
  18. # (1, 1, 2), 2019.2.3, [1000, 1000])
  19. # (1, 4, 4), 2019.2.3, [1000, 1000])
  20. # 则:累计数据:
  21. # [(1, 4, 4), '2019-02-02', [0, 0]]
  22. # [(1, 4, 4), '2019-02-03', [1000, 1000]]
  23. # [(1, 2, 1), '2019-02-02', [131.3, 132.3]]
  24. # [(1, 2, 1), '2019-02-03', [1131.3, 1132.3]]
  25. # [(1, 1, 1), '2019-02-02', [111.1, 112.1]]
  26. # [(1, 1, 1), '2019-02-03', [1111.1, 1112.1]]
  27. # [(1, 3, 3), '2019-02-02', [100, 100]]
  28. # [(1, 3, 3), '2019-02-03', [1100, 1100]]
  29. # [(1, 1, 2), '2019-02-02', [21.2, 22.2]]
  30. # [(1, 1, 2), '2019-02-03', [1021.2, 1022.2]]
  31. # =====用法:=====
  32. # date = datetime.date(2019, 2, 2)
  33. # helper = CumulativeHelper(date, 2)
  34. # helper.add_sumup_data((1, 1, 1), [11.1, 12.1])
  35. # helper.add_sumup_data((1, 1, 2), [21.2, 22.2])
  36. # helper.add_sumup_data((1, 2, 1), [31.3, 32.3])
  37. # day1 = date + datetime.timedelta(days=1)
  38. # helper.add_data_after_sumup((1, 1, 1), date, [100, 100])
  39. # helper.add_data_after_sumup((1, 1, 1), day1, [1000, 1000])
  40. # helper.add_data_after_sumup((1, 2, 1), date, [100, 100])
  41. # helper.add_data_after_sumup((1, 2, 1), day1, [1000, 1000])
  42. # helper.add_data_after_sumup((1, 3, 3), date, [100, 100])
  43. # helper.add_data_after_sumup((1, 3, 3), day1, [1000, 1000])
  44. # helper.add_data_after_sumup((1, 1, 2), day1, [1000, 1000])
  45. # helper.add_data_after_sumup((1, 4, 4), day1, [1000, 1000])
  46. # result = helper.get()
  47. class CumulativeHelper:
  48. def __init__(self, date, sumup_data_count):
  49. self.date = date
  50. self.sumup_data_count = sumup_data_count
  51. self.yesterday = date + datetime.timedelta(days=-1)
  52. self.last_data = {}
  53. self.data = {} # 从date的前一天开始的累计数据
  54. self.current_date = None
  55. self.current_sumup = None
  56. self.current_key = None
  57. return
  58. def add_sumup_data(self, key, sumup_data_list): # 添加指定日期之前的累计数据。 key:tuple,例如:(养殖场ID, 栋舍ID)
  59. if not sumup_data_list or len(sumup_data_list) != self.sumup_data_count:
  60. raise ValidationError(u'开发错误:累计数据项数不对:key:{}'.format(key))
  61. if key not in self.data:
  62. self.last_data[key] = DateData()
  63. self.last_data[key].add(self.yesterday, sumup_data_list)
  64. return
  65. def _init_current(self, key):
  66. sumup_data = self._get_yesterday_data(key, self.date)
  67. self.current_key = key
  68. self.current_sumup = sumup_data
  69. self.current_date = self.yesterday
  70. return
  71. def add_data_after_sumup(self, key, date, data_list_today): # 添加指定日期开始的当天数据。 key:tuple,例如:(养殖场ID, 栋舍ID)
  72. if not data_list_today or len(data_list_today) != self.sumup_data_count:
  73. raise ValidationError(u'开发错误:当前日期数据项数不对:date:{0},key:{1}'.format(date, key))
  74. if key != self.current_key:
  75. self._init_current(key)
  76. if key not in self.data:
  77. self.data[key] = DateData()
  78. self.current_date += datetime.timedelta(days=1)
  79. if date != self.current_date: # 说明当前时间不是最近的累计数据的时间下一天。即:时间不连续
  80. diff_days = (date - self.current_date).days
  81. if diff_days < 0:
  82. raise ValidationError(u'开发错误:添加的数据的日期错误。请确认是否按日期排序了')
  83. sumup = [i for i in self.current_sumup] if self.current_sumup else [0 for i in data_list_today]
  84. for i in range(diff_days):
  85. self.data[key].add(self.current_date, sumup)
  86. self.current_date += datetime.timedelta(days=1)
  87. if not self.current_sumup:
  88. self.current_sumup = data_list_today
  89. else:
  90. for i in range(len(data_list_today)):
  91. self.current_sumup[i] += data_list_today[i]
  92. self.data[key].add(date, copy.deepcopy(self.current_sumup))
  93. return
  94. def get(self):
  95. result = []
  96. for key, value in self.data.items():
  97. all_day_data = value.getAll()
  98. for item in all_day_data:
  99. date, sumup_data = item
  100. result.append([key, date, sumup_data])
  101. return result
  102. def _get_yesterday_data(self, key, date):
  103. if not self.last_data:
  104. return None
  105. yesterday = date + datetime.timedelta(days=-1)
  106. if yesterday == self.yesterday:
  107. if key in self.last_data:
  108. return self.last_data[key].get(yesterday)
  109. return None
  110. if key in self.data:
  111. return self.data[key].get(yesterday)
  112. return None
  113. class DateData:
  114. def __init__(self):
  115. self.data = []
  116. return
  117. def add(self, date, data): # 同一个日期只有一个数据。如果重复,则替换
  118. for _list in self.data:
  119. if _list[0] == date:
  120. _list[1] = data
  121. return
  122. self.data.append([date, data])
  123. return
  124. def get(self, date):
  125. for _list in self.data:
  126. if _list[0] == date:
  127. return _list[1]
  128. return []
  129. def getAll(self):
  130. return self.data