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.

202 lines
9.7 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. # © 2019 Le Filament (<http://www.le-filament.com>)
  2. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  3. from odoo import models, fields, api
  4. # import dateutil.rrule as rrule
  5. # from datetime import date
  6. from dateutil.relativedelta import *
  7. from dateutil.easter import *
  8. from dateutil.rrule import rrule, DAILY, MINUTELY, rruleset
  9. from dateutil.parser import *
  10. # from datetime import *
  11. from datetime import datetime, timedelta
  12. class VracoopPointRetrait(models.Model):
  13. _name = "vracoop.point.retrait"
  14. _description = "Point de retrait"
  15. _inherit = ['website.published.multi.mixin']
  16. @api.model
  17. def default_get(self, fields):
  18. res = super(VracoopPointRetrait, self).default_get(fields)
  19. vracoop_time_ids = self.env['vracoop.time'].search([])
  20. vracoop_retrait_time_ids = []
  21. for vracoop_time_id in vracoop_time_ids:
  22. if vracoop_time_id.name == 6 or vracoop_time_id.name == 0:
  23. active_day = False
  24. else:
  25. active_day = True
  26. vals = {
  27. 'vracoop_time_id': vracoop_time_id.id,
  28. 'name': int(vracoop_time_id.name),
  29. 'first_morning_heure': vracoop_time_id.first_morning_heure,
  30. 'last_morning_heure': vracoop_time_id.last_morning_heure,
  31. 'first_noon_heure': vracoop_time_id.first_noon_heure,
  32. 'last_noon_heure': vracoop_time_id.last_noon_heure,
  33. 'preparation_time': vracoop_time_id.preparation_time,
  34. 'availability_time': vracoop_time_id.availability_time,
  35. 'active_day': active_day
  36. }
  37. vracoop_retrait_time_ids.append((0, 0, vals))
  38. res.update({'vracoop_retrait_time_ids': vracoop_retrait_time_ids})
  39. return res
  40. name = fields.Char("Nom du point relais")
  41. active = fields.Boolean(default=True)
  42. street = fields.Char()
  43. street2 = fields.Char()
  44. zip = fields.Char(change_default=True)
  45. city = fields.Char()
  46. state_id = fields.Many2one(
  47. "res.country.state",
  48. string='State',
  49. ondelete='restrict',
  50. domain="[('country_id', '=?', country_id)]")
  51. country_id = fields.Many2one(
  52. 'res.country', string='Country', ondelete='restrict')
  53. image = fields.Binary("Image", attachment=True,)
  54. image_medium = fields.Binary("Medium-sized image", attachment=True)
  55. image_small = fields.Binary("Small-sized image", attachment=True)
  56. vracoop_retrait_time_ids = fields.One2many(
  57. comodel_name='vracoop.retrait.time',
  58. inverse_name='vracoop_point_retrait_id',
  59. string="Configuration des horaires")
  60. nb_max_retrait = fields.Integer(
  61. "Nombre de retrait max par tranche horaire")
  62. nb_day_available = fields.Integer("Nombre de jours pour commande")
  63. @api.multi
  64. def slot_calculate(self):
  65. self.ensure_one()
  66. LIST_WEEK_DAY = [
  67. ('lundi', 0, 1, 'lun.'),
  68. ('mardi', 1, 2, 'mar.'),
  69. ('mercredi', 2, 3, 'mer.'),
  70. ('jeudi', 3, 4, 'jeu.'),
  71. ('vendredi', 4, 5, 'ven.'),
  72. ('samedi', 5, 6, 'sam.'),
  73. ('dimanche', 6, 0, 'dim.'),
  74. ]
  75. for rec in self:
  76. today_datetime = datetime.today()
  77. return_slot_list = []
  78. vals = []
  79. exclure_days_nb = rec.vracoop_retrait_time_ids.search_count([
  80. ('vracoop_point_retrait_id', '=', rec.id),
  81. ('active_day', '=', False)])
  82. count_day = rec.nb_day_available + exclure_days_nb
  83. list_week = list(rrule(
  84. DAILY,
  85. count=count_day,
  86. dtstart=datetime.today()))
  87. for week in list_week:
  88. exclure_the_day = rec.vracoop_retrait_time_ids.search([
  89. ('vracoop_point_retrait_id', '=', rec.id),
  90. ('active_day', '=', False),
  91. ('name', '=', week.strftime("%w"))])
  92. if exclure_the_day:
  93. pass
  94. else:
  95. corresponding_line = rec.vracoop_retrait_time_ids.search([
  96. ('vracoop_point_retrait_id', '=', rec.id),
  97. ('name', '=', week.strftime("%w"))])
  98. for week_day in LIST_WEEK_DAY:
  99. if week_day[2] == int(week.strftime("%w")):
  100. byweekday = week_day[1]
  101. day_short_name = week_day[3]
  102. time_available_week = datetime(
  103. week.year, week.month, week.day) + timedelta(
  104. hours=corresponding_line.availability_time)
  105. hour = time_available_week.strftime("%H")
  106. minute = time_available_week.strftime("%M")
  107. interval = int(hour)*60 + int(minute)
  108. first_morning_hour_week = datetime(
  109. week.year, week.month, week.day) + timedelta(
  110. hours=corresponding_line.first_morning_heure)
  111. last_morning_hour_week = datetime(
  112. week.year, week.month, week.day) + timedelta(
  113. hours=corresponding_line.last_morning_heure)
  114. first_noon_hour_week = datetime(
  115. week.year, week.month, week.day) + timedelta(
  116. hours=corresponding_line.first_noon_heure)
  117. last_noon_hour_week = datetime(
  118. week.year, week.month, week.day) + timedelta(
  119. hours=corresponding_line.last_noon_heure)
  120. list_slot_per_day_morning = list(
  121. rrule(
  122. MINUTELY,
  123. interval=interval,
  124. byweekday=byweekday,
  125. dtstart=first_morning_hour_week,
  126. until=last_morning_hour_week))
  127. list_slot_per_day_noon = list(
  128. rrule(
  129. MINUTELY, interval=interval,
  130. byweekday=byweekday,
  131. dtstart=first_noon_hour_week,
  132. until=last_noon_hour_week))
  133. slots = []
  134. nb_sale_slot = 0
  135. today_hour_available = today_datetime + timedelta(
  136. hours=corresponding_line.preparation_time)
  137. for slot_elem in list_slot_per_day_morning:
  138. first_slot = slot_elem.strftime("%H:%M")
  139. slot_elem_last = slot_elem + timedelta(
  140. hours=corresponding_line.availability_time)
  141. last_slot = slot_elem_last.strftime("%H:%M")
  142. if slot_elem.date() == today_datetime.date():
  143. if (today_hour_available > slot_elem_last):
  144. continue
  145. if slot_elem_last >= last_morning_hour_week:
  146. slot_elem_last = last_morning_hour_week
  147. last_slot = slot_elem_last.strftime("%H:%M")
  148. if slot_elem >= last_morning_hour_week:
  149. continue
  150. # Check number of maximum withdrawal not reached
  151. first_slot_hour = first_slot.split(":")
  152. first_slot_float = float(
  153. '%s.%s' % (first_slot_hour[0], first_slot_hour[1]))
  154. nb_sale_slot = self.env['sale.order'].search_count(
  155. [('vracoop_point_retrait_id', '=', rec.id),
  156. ('day_retrait', '=', week.date()),
  157. ('hour_retrait', '=', first_slot_float)])
  158. if nb_sale_slot < rec.nb_max_retrait:
  159. slots.append((first_slot, last_slot))
  160. for slot_elem in list_slot_per_day_noon:
  161. first_slot = slot_elem.strftime("%H:%M")
  162. slot_elem_last = slot_elem + timedelta(
  163. hours=corresponding_line.availability_time)
  164. last_slot = slot_elem_last.strftime("%H:%M")
  165. if week.date() == today_datetime.date():
  166. if (today_hour_available > slot_elem_last):
  167. continue
  168. if slot_elem_last >= last_noon_hour_week:
  169. slot_elem_last = last_noon_hour_week
  170. last_slot = slot_elem_last.strftime("%H:%M")
  171. if slot_elem >= last_noon_hour_week:
  172. continue
  173. # Check number of maximum withdrawal not reached
  174. first_slot_hour = first_slot.split(":")
  175. first_slot_float = float(
  176. '%s.%s' % (first_slot_hour[0], first_slot_hour[1]))
  177. nb_sale_slot = self.env['sale.order'].search_count(
  178. [('vracoop_point_retrait_id', '=', rec.id),
  179. ('day_retrait', '=', week.date()),
  180. ('hour_retrait', '=', first_slot_float)])
  181. if nb_sale_slot < rec.nb_max_retrait:
  182. slots.append((first_slot, last_slot))
  183. return_slot_list = slots
  184. if return_slot_list:
  185. vals.append(
  186. (day_short_name,
  187. week,
  188. week.strftime("%b"), return_slot_list))
  189. return vals