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.

225 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
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. 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("%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. if week.day == my_datetime.day:
  109. first_morning_hour_week = datetime(
  110. week.year, week.month, week.day) + timedelta(
  111. hours=corresponding_line.first_morning_heure)
  112. last_morning_hour_week = datetime(
  113. week.year, week.month, week.day) + timedelta(
  114. hours=corresponding_line.last_morning_heure)
  115. first_noon_hour_week = datetime(
  116. week.year, week.month, week.day) + timedelta(
  117. hours=corresponding_line.first_noon_heure)
  118. last_noon_hour_week = datetime(
  119. week.year, week.month, week.day) + timedelta(
  120. hours=corresponding_line.last_noon_heure)
  121. today_hour_available = my_datetime + timedelta(
  122. hours=corresponding_line.preparation_time)
  123. if (today_hour_available > first_morning_hour_week) and (today_hour_available < last_morning_hour_week):
  124. dtstart_morning = today_hour_available
  125. dtstart_noon = first_noon_hour_week
  126. elif (today_hour_available > first_noon_hour_week) and (today_hour_available < last_noon_hour_week):
  127. dtstart_morning = today_hour_available
  128. dtstart_noon = today_hour_available
  129. elif (today_hour_available > last_morning_hour_week) and (today_hour_available < first_noon_hour_week):
  130. dtstart_morning = today_hour_available
  131. dtstart_noon = first_noon_hour_week
  132. else:
  133. dtstart_morning = today_hour_available
  134. dtstart_noon = today_hour_available
  135. list_slot_per_day_morning = list(
  136. rrule(
  137. MINUTELY,
  138. interval=interval,
  139. byweekday=byweekday,
  140. dtstart=dtstart_morning,
  141. until=last_morning_hour_week))
  142. list_slot_per_day_noon = list(
  143. rrule(
  144. MINUTELY,
  145. interval=interval,
  146. byweekday=byweekday,
  147. dtstart=dtstart_noon,
  148. until=last_noon_hour_week))
  149. else:
  150. first_morning_hour_week = datetime(
  151. week.year, week.month, week.day) + timedelta(
  152. hours=corresponding_line.first_morning_heure)
  153. last_morning_hour_week = datetime(
  154. week.year, week.month, week.day) + timedelta(
  155. hours=corresponding_line.last_morning_heure)
  156. first_noon_hour_week = datetime(
  157. week.year, week.month, week.day) + timedelta(
  158. hours=corresponding_line.first_noon_heure)
  159. last_noon_hour_week = datetime(
  160. week.year, week.month, week.day) + timedelta(
  161. hours=corresponding_line.last_noon_heure)
  162. list_slot_per_day_morning = list(
  163. rrule(
  164. MINUTELY,
  165. interval=interval,
  166. byweekday=byweekday,
  167. dtstart=first_morning_hour_week,
  168. until=last_morning_hour_week))
  169. list_slot_per_day_noon = list(
  170. rrule(
  171. MINUTELY, interval=interval,
  172. byweekday=byweekday,
  173. dtstart=first_noon_hour_week,
  174. until=last_noon_hour_week))
  175. slots = []
  176. nb_sale_slot = 0
  177. for slot_per_day_morning in list_slot_per_day_morning:
  178. first_slot = slot_per_day_morning.strftime("%H:%M")
  179. slot_per_day_morning = slot_per_day_morning + timedelta(
  180. hours=corresponding_line.availability_time)
  181. last_slot = slot_per_day_morning.strftime("%H:%M")
  182. first_slot_hour = first_slot.split(":")
  183. first_slot_float = float(
  184. '%s.%s' % (first_slot_hour[0], first_slot_hour[1]))
  185. nb_sale_slot = self.env['sale.order'].search_count(
  186. [('vracoop_point_retrait_id', '=', rec.id),
  187. ('day_retrait', '=', week.date()),
  188. ('hour_retrait', '=', first_slot_float)])
  189. if nb_sale_slot < rec.nb_max_retrait:
  190. slots.append((first_slot, last_slot))
  191. nb_sale_slot = 0
  192. for slot_per_day_noon in list_slot_per_day_noon:
  193. first_slot = slot_per_day_noon.strftime("%H:%M")
  194. slot_per_day_noon = slot_per_day_noon + timedelta(
  195. hours=corresponding_line.availability_time)
  196. last_slot = slot_per_day_noon.strftime("%H:%M")
  197. first_slot_hour = first_slot.split(":")
  198. first_slot_float = float(
  199. '%s.%s' % (first_slot_hour[0], first_slot_hour[1]))
  200. nb_sale_slot = self.env['sale.order'].search_count(
  201. [('vracoop_point_retrait_id', '=', rec.id),
  202. ('day_retrait', '=', week.date()),
  203. ('hour_retrait', '=', first_slot_float)])
  204. if nb_sale_slot < rec.nb_max_retrait:
  205. slots.append((first_slot, last_slot))
  206. return_slot_list = slots
  207. if return_slot_list:
  208. vals.append(
  209. (day_short_name,
  210. week,
  211. week.strftime("%b"), return_slot_list))
  212. return vals