You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

361 lines
13 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. from odoo import api, fields, models
  2. from odoo.addons.beesdoo_shift.models.cooperative_status import add_days_delta
  3. class CooperativeStatus(models.Model):
  4. _inherit = "cooperative.status"
  5. _period = 28
  6. ######################################################
  7. # #
  8. # Override of method to define status behavior #
  9. # #
  10. ######################################################
  11. future_alert_date = fields.Date(compute="_compute_future_alert_date")
  12. next_countdown_date = fields.Date(compute="_compute_next_countdown_date")
  13. @api.depends(
  14. "today",
  15. "irregular_start_date",
  16. "sr",
  17. "holiday_start_time",
  18. "holiday_end_time",
  19. "temporary_exempt_start_date",
  20. "temporary_exempt_end_date",
  21. )
  22. def _compute_future_alert_date(self):
  23. """Compute date before which the worker is up to date"""
  24. for rec in self:
  25. # Only for irregular worker
  26. if (
  27. rec.working_mode != "irregular"
  28. and not rec.irregular_start_date
  29. ):
  30. rec.future_alert_date = False
  31. # Alert start time already set
  32. elif rec.alert_start_time:
  33. rec.future_alert_date = False
  34. # Holidays are not set properly
  35. elif bool(rec.holiday_start_time) != bool(rec.holiday_end_time):
  36. rec.future_alert_date = False
  37. # Exemption have not a start and end time
  38. elif bool(rec.temporary_exempt_start_date) != bool(
  39. rec.temporary_exempt_end_date
  40. ):
  41. rec.future_alert_date = False
  42. else:
  43. date = rec.today
  44. counter = rec.sr
  45. # Simulate the countdown
  46. while counter > 0:
  47. date = self._next_countdown_date(
  48. rec.irregular_start_date, date
  49. )
  50. # Check holidays
  51. if (
  52. rec.holiday_start_time
  53. and rec.holiday_end_time
  54. and date >= rec.holiday_start_time
  55. and date <= rec.holiday_end_time
  56. ):
  57. date = add_days_delta(date, 1)
  58. continue
  59. # Check temporary exemption
  60. if (
  61. rec.temporary_exempt_start_date
  62. and rec.temporary_exempt_end_date
  63. and date >= rec.temporary_exempt_start_date
  64. and date <= rec.temporary_exempt_end_date
  65. ):
  66. date = add_days_delta(date, 1)
  67. continue
  68. # Otherwise
  69. date = add_days_delta(date, 1)
  70. counter -= 1
  71. rec.future_alert_date = self._next_countdown_date(
  72. rec.irregular_start_date, date
  73. )
  74. @api.depends(
  75. "today",
  76. "irregular_start_date",
  77. "holiday_start_time",
  78. "holiday_end_time",
  79. "temporary_exempt_start_date",
  80. "temporary_exempt_end_date",
  81. )
  82. def _compute_next_countdown_date(self):
  83. """
  84. Compute the following countdown date. This date is the date when
  85. the worker will see his counter changed du to the cron. This
  86. date is like the birthday date of the worker that occurred each
  87. PERIOD.
  88. """
  89. for rec in self:
  90. # Only for irregular worker
  91. if (
  92. rec.working_mode != "irregular"
  93. and not rec.irregular_start_date
  94. ):
  95. rec.next_countdown_date = False
  96. # Holidays are not set properly
  97. elif bool(rec.holiday_start_time) != bool(rec.holiday_end_time):
  98. rec.next_countdown_date = False
  99. # Exemption have not a start and end time
  100. elif bool(rec.temporary_exempt_start_date) != bool(
  101. rec.temporary_exempt_end_date
  102. ):
  103. rec.next_countdown_date = False
  104. else:
  105. date = rec.today
  106. next_countdown_date = False
  107. while not next_countdown_date:
  108. date = self._next_countdown_date(
  109. rec.irregular_start_date, date
  110. )
  111. # Check holidays
  112. if (
  113. rec.holiday_start_time
  114. and rec.holiday_end_time
  115. and date >= rec.holiday_start_time
  116. and date <= rec.holiday_end_time
  117. ):
  118. date = add_days_delta(date, 1)
  119. continue
  120. # Check temporary exemption
  121. if (
  122. rec.temporary_exempt_start_date
  123. and rec.temporary_exempt_end_date
  124. and date >= rec.temporary_exempt_start_date
  125. and date <= rec.temporary_exempt_end_date
  126. ):
  127. date = add_days_delta(date, 1)
  128. continue
  129. # Otherwise
  130. next_countdown_date = date
  131. rec.next_countdown_date = next_countdown_date
  132. #####################################
  133. # Status Change implementation #
  134. #####################################
  135. def _get_regular_status(self):
  136. self.ensure_one()
  137. counter_unsubscribe = int(
  138. self.env["ir.config_parameter"]
  139. .sudo()
  140. .get_param("regular_counter_to_unsubscribe", -4)
  141. )
  142. alert_delay = int(
  143. self.env["ir.config_parameter"].sudo().get_param("alert_delay", 28)
  144. )
  145. grace_delay = int(
  146. self.env["ir.config_parameter"]
  147. .sudo()
  148. .get_param("default_grace_delay", 10)
  149. )
  150. ok = self.sr >= 0 and self.sc >= 0
  151. grace_delay = grace_delay + self.time_extension
  152. if (self.sr + self.sc) <= counter_unsubscribe or self.unsubscribed:
  153. return "unsubscribed"
  154. # Check if exempted. Exempt end date is not required.
  155. if (
  156. self.temporary_exempt_start_date
  157. and self.today >= self.temporary_exempt_start_date
  158. ):
  159. if (
  160. not self.temporary_exempt_end_date
  161. or self.today <= self.temporary_exempt_end_date
  162. ):
  163. return "exempted"
  164. # Transition to alert sr < 0 or stay in alert sr < 0 or sc < 0 and thus alert time is defined
  165. if (
  166. not ok
  167. and self.alert_start_time
  168. and self.extension_start_time
  169. and self.today
  170. <= add_days_delta(self.extension_start_time, grace_delay)
  171. ):
  172. return "extension"
  173. if (
  174. not ok
  175. and self.alert_start_time
  176. and self.extension_start_time
  177. and self.today
  178. > add_days_delta(self.extension_start_time, grace_delay)
  179. ):
  180. return "suspended"
  181. if (
  182. not ok
  183. and self.alert_start_time
  184. and self.today > add_days_delta(self.alert_start_time, alert_delay)
  185. ):
  186. return "suspended"
  187. if (self.sr < 0) or (not ok and self.alert_start_time):
  188. return "alert"
  189. if (
  190. self.holiday_start_time
  191. and self.holiday_end_time
  192. and self.today >= self.holiday_start_time
  193. and self.today <= self.holiday_end_time
  194. ):
  195. return "holiday"
  196. elif ok or (not self.alert_start_time and self.sr >= 0):
  197. return "ok"
  198. def _get_irregular_status(self):
  199. self.ensure_one()
  200. counter_unsubscribe = int(
  201. self.env["ir.config_parameter"]
  202. .sudo()
  203. .get_param("irregular_counter_to_unsubscribe", -3)
  204. )
  205. alert_delay = int(
  206. self.env["ir.config_parameter"].sudo().get_param("alert_delay", 28)
  207. )
  208. grace_delay = int(
  209. self.env["ir.config_parameter"]
  210. .sudo()
  211. .get_param("default_grace_delay", 10)
  212. )
  213. ok = self.sr >= 0
  214. grace_delay = grace_delay + self.time_extension
  215. if self.sr <= counter_unsubscribe or self.unsubscribed:
  216. return "unsubscribed"
  217. # Check if exempted. Exempt end date is not required.
  218. elif (
  219. self.temporary_exempt_start_date
  220. and self.today >= self.temporary_exempt_start_date
  221. ):
  222. if (
  223. not self.temporary_exempt_end_date
  224. or self.today <= self.temporary_exempt_end_date
  225. ):
  226. return "exempted"
  227. # Transition to alert sr < 0 or stay in alert sr < 0 or sc < 0 and thus alert time is defined
  228. elif (
  229. not ok
  230. and self.alert_start_time
  231. and self.extension_start_time
  232. and self.today
  233. <= add_days_delta(self.extension_start_time, grace_delay)
  234. ):
  235. return "extension"
  236. elif (
  237. not ok
  238. and self.alert_start_time
  239. and self.extension_start_time
  240. and self.today
  241. > add_days_delta(self.extension_start_time, grace_delay)
  242. ):
  243. return "suspended"
  244. elif (
  245. not ok
  246. and self.alert_start_time
  247. and self.today > add_days_delta(self.alert_start_time, alert_delay)
  248. ):
  249. return "suspended"
  250. elif (self.sr < 0) or (not ok and self.alert_start_time):
  251. return "alert"
  252. elif (
  253. self.holiday_start_time
  254. and self.holiday_end_time
  255. and self.today >= self.holiday_start_time
  256. and self.today <= self.holiday_end_time
  257. ):
  258. return "holiday"
  259. elif ok or (not self.alert_start_time and self.sr >= 0):
  260. return "ok"
  261. def _state_change(self, new_state):
  262. self.ensure_one()
  263. if new_state == "alert":
  264. self.write(
  265. {
  266. "alert_start_time": self.today,
  267. "extension_start_time": False,
  268. "time_extension": 0,
  269. }
  270. )
  271. if new_state == "ok":
  272. data = {"extension_start_time": False, "time_extension": 0}
  273. data["alert_start_time"] = False
  274. self.write(data)
  275. if new_state == "unsubscribed" or new_state == "resigning":
  276. # Remove worker from task_templates
  277. self.cooperator_id.sudo().write(
  278. {"subscribed_shift_ids": [(5, 0, 0)]}
  279. )
  280. # Remove worker from supercoop in task_templates
  281. task_tpls = self.env["beesdoo.shift.template"].search(
  282. [("super_coop_id", "in", self.cooperator_id.user_ids.ids)]
  283. )
  284. task_tpls.write({"super_coop_id": False})
  285. # Remove worker for future tasks (remove also supercoop)
  286. self.env["beesdoo.shift.shift"].sudo().unsubscribe_from_today(
  287. [self.cooperator_id.id], now=fields.Datetime.now()
  288. )
  289. def _change_counter(self, data):
  290. """
  291. Call when a shift state is changed
  292. use data generated by _get_counter_date_state_change
  293. """
  294. self.sc += data.get("sc", 0)
  295. self.sr += data.get("sr", 0)
  296. self.irregular_absence_counter += data.get(
  297. "irregular_absence_counter", 0
  298. )
  299. self.irregular_absence_date = data.get("irregular_absence_date", False)
  300. ###############################################
  301. ###### Irregular Cron implementation ##########
  302. ###############################################
  303. def _get_irregular_worker_domain(self, **kwargs):
  304. today = kwargs.get("today") or self.today
  305. return [
  306. "&",
  307. "&",
  308. "&",
  309. ("status", "not in", ["unsubscribed", "exempted"]),
  310. ("working_mode", "=", "irregular"),
  311. ("irregular_start_date", "!=", False),
  312. "|",
  313. "|",
  314. ("holiday_start_time", "=", False),
  315. ("holiday_end_time", "=", False),
  316. "|",
  317. ("holiday_start_time", ">", today),
  318. ("holiday_end_time", "<", today),
  319. ]
  320. def _change_irregular_counter(self):
  321. if self.sr > 0:
  322. self.sr -= 1
  323. elif self.alert_start_time:
  324. self.sr -= 1
  325. else:
  326. self.sr -= 2
  327. ##################################
  328. # Internal Implementation #
  329. ##################################
  330. def _next_countdown_date(self, irregular_start_date, today=False):
  331. """
  332. Return the next countdown date given irregular_start_date and
  333. today dates.
  334. This does not take holiday and other status into account.
  335. """
  336. today = today or fields.Date.today()
  337. delta = (today - irregular_start_date).days
  338. if not delta % self._period:
  339. return today
  340. return add_days_delta(today, self._period - (delta % self._period))