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.

220 lines
11 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
  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 == 'samedi' or vracoop_time_id.name == 'dimanche':
  23. active_day = False
  24. else:
  25. active_day = True
  26. vals = {
  27. 'vracoop_time_id': vracoop_time_id.id,
  28. 'name': 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),
  68. ('mardi', 1),
  69. ('mercredi', 2),
  70. ('jeudi', 3),
  71. ('vendredi', 4),
  72. ('samedi', 5),
  73. ('dimanche', 6),
  74. ]
  75. for rec in self:
  76. my_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("%A"))])
  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("%A"))])
  98. for week_day in LIST_WEEK_DAY:
  99. if week_day[0] == week.strftime("%A"):
  100. byweekday = week_day[1]
  101. time_available_week = datetime(
  102. week.year, week.month, week.day) + timedelta(
  103. hours=corresponding_line.availability_time)
  104. hour = time_available_week.strftime("%H")
  105. minute = time_available_week.strftime("%M")
  106. interval = int(hour)*60 + int(minute)
  107. if week.day == my_datetime.day:
  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. today_hour_available = my_datetime + timedelta(
  121. hours=corresponding_line.preparation_time)
  122. if (today_hour_available > first_morning_hour_week) and (today_hour_available < last_morning_hour_week):
  123. dtstart_morning = today_hour_available
  124. dtstart_noon = first_noon_hour_week
  125. elif (today_hour_available > first_noon_hour_week) and (today_hour_available < last_noon_hour_week):
  126. dtstart_morning = today_hour_available
  127. dtstart_noon = today_hour_available
  128. elif (today_hour_available > last_morning_hour_week) and (today_hour_available < first_noon_hour_week):
  129. dtstart_morning = today_hour_available
  130. dtstart_noon = first_noon_hour_week
  131. else:
  132. dtstart_morning = today_hour_available
  133. dtstart_noon = today_hour_available
  134. list_slot_per_day_morning = list(
  135. rrule(
  136. MINUTELY,
  137. interval=interval,
  138. byweekday=byweekday,
  139. dtstart=dtstart_morning,
  140. until=last_morning_hour_week))
  141. list_slot_per_day_noon = list(
  142. rrule(
  143. MINUTELY,
  144. interval=interval,
  145. byweekday=byweekday,
  146. dtstart=dtstart_noon,
  147. until=last_noon_hour_week))
  148. else:
  149. first_morning_hour_week = datetime(
  150. week.year, week.month, week.day) + timedelta(
  151. hours=corresponding_line.first_morning_heure)
  152. last_morning_hour_week = datetime(
  153. week.year, week.month, week.day) + timedelta(
  154. hours=corresponding_line.last_morning_heure)
  155. first_noon_hour_week = datetime(
  156. week.year, week.month, week.day) + timedelta(
  157. hours=corresponding_line.first_noon_heure)
  158. last_noon_hour_week = datetime(
  159. week.year, week.month, week.day) + timedelta(
  160. hours=corresponding_line.last_noon_heure)
  161. list_slot_per_day_morning = list(
  162. rrule(
  163. MINUTELY,
  164. interval=interval,
  165. byweekday=byweekday,
  166. dtstart=first_morning_hour_week,
  167. until=last_morning_hour_week))
  168. list_slot_per_day_noon = list(
  169. rrule(
  170. MINUTELY, interval=interval,
  171. byweekday=byweekday,
  172. dtstart=first_noon_hour_week,
  173. until=last_noon_hour_week))
  174. slots = []
  175. nb_sale_slot = 0
  176. for slot_per_day_morning in list_slot_per_day_morning:
  177. first_slot = slot_per_day_morning.strftime("%H:%M")
  178. slot_per_day_morning = slot_per_day_morning + timedelta(
  179. hours=corresponding_line.availability_time)
  180. last_slot = slot_per_day_morning.strftime("%H:%M")
  181. first_slot_hour = first_slot.split(":")
  182. first_slot_float = float(
  183. '%s.%s' % (first_slot_hour[0], first_slot_hour[1]))
  184. nb_sale_slot = self.env['sale.order'].search_count(
  185. [('vracoop_point_retrait_id', '=', rec.id),
  186. ('day_retrait', '=', week.date()),
  187. ('hour_retrait', '=', first_slot_float)])
  188. if nb_sale_slot < rec.nb_max_retrait:
  189. slots.append((first_slot, last_slot))
  190. nb_sale_slot = 0
  191. for slot_per_day_noon in list_slot_per_day_noon:
  192. first_slot = slot_per_day_noon.strftime("%H:%M")
  193. slot_per_day_noon = slot_per_day_noon + timedelta(
  194. hours=corresponding_line.availability_time)
  195. last_slot = slot_per_day_noon.strftime("%H:%M")
  196. nb_sale_slot = self.env['sale.order'].search_count(
  197. [('vracoop_point_retrait_id', '=', rec.id),
  198. ('day_retrait', '=', week.date()),
  199. ('hour_retrait', '=', first_slot_float)])
  200. if nb_sale_slot < rec.nb_max_retrait:
  201. slots.append((first_slot, last_slot))
  202. return_slot_list = slots
  203. if return_slot_list:
  204. vals.append(
  205. (week.strftime("%a"),
  206. week,
  207. week.strftime("%b"), return_slot_list))
  208. return vals