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.
 
 
 

283 lines
14 KiB

# © 2019 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields, api
from dateutil.rrule import rrule, DAILY, MINUTELY
from dateutil.relativedelta import relativedelta
from datetime import datetime, timedelta
from pytz import timezone
class VracoopPointRetrait(models.Model):
_name = "vracoop.point.retrait"
_description = "Point de retrait"
_inherit = ['website.published.multi.mixin']
@api.model
def default_get(self, fields):
res = super(VracoopPointRetrait, self).default_get(fields)
vracoop_time_ids = self.env['vracoop.time'].search([])
vracoop_retrait_time_ids = []
for vracoop_time_id in vracoop_time_ids:
if vracoop_time_id.name == 6 or vracoop_time_id.name == 0:
active_day = False
else:
active_day = True
vals = {
'vracoop_time_id': vracoop_time_id.id,
'name': int(vracoop_time_id.name),
'first_morning_heure': vracoop_time_id.first_morning_heure,
'last_morning_heure': vracoop_time_id.last_morning_heure,
'first_noon_heure': vracoop_time_id.first_noon_heure,
'last_noon_heure': vracoop_time_id.last_noon_heure,
'preparation_time': vracoop_time_id.preparation_time,
'availability_time': vracoop_time_id.availability_time,
'active_day': active_day
}
vracoop_retrait_time_ids.append((0, 0, vals))
res.update({'vracoop_retrait_time_ids': vracoop_retrait_time_ids})
return res
name = fields.Char("Nom du point relais")
active = fields.Boolean(default=True)
street = fields.Char()
street2 = fields.Char()
zip = fields.Char(change_default=True)
city = fields.Char()
state_id = fields.Many2one(
"res.country.state",
string='State',
ondelete='restrict',
domain="[('country_id', '=?', country_id)]")
country_id = fields.Many2one(
'res.country', string='Country', ondelete='restrict')
image = fields.Binary("Image", attachment=True,)
image_medium = fields.Binary("Medium-sized image", attachment=True)
image_small = fields.Binary("Small-sized image", attachment=True)
vracoop_retrait_time_ids = fields.One2many(
comodel_name='vracoop.retrait.time',
inverse_name='vracoop_point_retrait_id',
string="Configuration des horaires")
nb_max_retrait = fields.Integer(
"Nombre de retrait max par tranche horaire")
nb_day_available = fields.Integer(
"Nombre de jours pour commande", default=7)
nb_hours_preparation = fields.Float(
"Nombre d'heures de préparation", default=0.0)
@api.multi
def slot_calculate(self):
self.ensure_one()
LIST_WEEK_DAY = [
('lundi', 0, 1, 'lun.'),
('mardi', 1, 2, 'mar.'),
('mercredi', 2, 3, 'mer.'),
('jeudi', 3, 4, 'jeu.'),
('vendredi', 4, 5, 'ven.'),
('samedi', 5, 6, 'sam.'),
('dimanche', 6, 0, 'dim.'),
]
for rec in self:
today_datetime_utc = datetime.now(timezone('UTC'))
today_datetime2 = today_datetime_utc.astimezone(timezone('Europe/Berlin'))
today_datetime = datetime(
today_datetime2.year,
today_datetime2.month,
today_datetime2.day,
today_datetime2.hour,
today_datetime2.minute,
today_datetime2.second)
# today_datetime = datetime.strptime(today_datetime2, "%Y-%m-%d %H:%M:%S")
return_slot_list = []
vals = []
exclure_days_nb = rec.vracoop_retrait_time_ids.search_count([
('vracoop_point_retrait_id', '=', rec.id),
('active_day', '=', False)])
count_day = rec.nb_day_available + exclure_days_nb
# Ajout pour BUG
corresponding_line = rec.vracoop_retrait_time_ids.search([
('vracoop_point_retrait_id', '=', rec.id),
('name', '=', today_datetime.strftime("%w"))])
today_hour_available = today_datetime + timedelta(
hours=(corresponding_line.preparation_time + rec.nb_hours_preparation))
# Liste des jours où je peux récupérer la commande
# en fonction nombre de jour dispo sur la fiche du point retrait
first_day = datetime.today() + relativedelta(hours=corresponding_line.preparation_time + rec.nb_hours_preparation)
list_week = list(rrule(
DAILY,
count=count_day,
dtstart=first_day))
for week in list_week:
# On exclut les jours où la journée
# du point de retrait n'est pas actif
exclure_the_day = rec.vracoop_retrait_time_ids.search([
('vracoop_point_retrait_id', '=', rec.id),
('active_day', '=', False),
('name', '=', week.strftime("%w"))])
if exclure_the_day:
pass
else:
# Récupération de la ligne du jour correpsondant
corresponding_line = rec.vracoop_retrait_time_ids.search([
('vracoop_point_retrait_id', '=', rec.id),
('name', '=', week.strftime("%w"))])
# Récupération du nom du jour et du Short name du jour
for week_day in LIST_WEEK_DAY:
if week_day[2] == int(week.strftime("%w")):
byweekday = week_day[1]
day_short_name = week_day[3]
# Calcul de l'heure à laquelle la commande est disponible
time_available_week = datetime(
week.year, week.month, week.day) + timedelta(
hours=corresponding_line.availability_time)
hour = time_available_week.strftime("%H")
minute = time_available_week.strftime("%M")
interval = int(hour)*60 + int(minute)
first_morning_hour_week = datetime(
week.year, week.month, week.day) + timedelta(
hours=corresponding_line.first_morning_heure)
last_morning_hour_week = datetime(
week.year, week.month, week.day) + timedelta(
hours=corresponding_line.last_morning_heure)
first_noon_hour_week = datetime(
week.year, week.month, week.day) + timedelta(
hours=corresponding_line.first_noon_heure)
last_noon_hour_week = datetime(
week.year, week.month, week.day) + timedelta(
hours=corresponding_line.last_noon_heure)
# Calcul des Slots (matin et après-midi) par jour en
# fonction de l'intervalle (correspondant au temps de mis
# à disposition) et des dates de début et de fin de retrait
list_slot_per_day_morning = list(
rrule(
MINUTELY,
interval=interval,
byweekday=byweekday,
dtstart=first_morning_hour_week,
until=last_morning_hour_week))
list_slot_per_day_noon = list(
rrule(
MINUTELY, interval=interval,
byweekday=byweekday,
dtstart=first_noon_hour_week,
until=last_noon_hour_week))
slots = []
nb_sale_slot = 0
# Heure disponible pour un retrait
# en fonction du temps de préparation
# today_hour_available = today_datetime + timedelta(
# hours=(corresponding_line.preparation_time + rec.nb_hours_preparation))
# Boucle pour les créneaux du matin
for slot_elem in list_slot_per_day_morning:
# Conversion du 1er Slot en HH:MM
first_slot = slot_elem.strftime("%H:%M")
# Calcul du dernier slot
# en fonction du temps de mis à dsiposition
slot_elem_last = slot_elem + timedelta(
hours=corresponding_line.availability_time)
# Conversion du Dernier Slot en HH:MM
last_slot = slot_elem_last.strftime("%H:%M")
if slot_elem >= last_morning_hour_week:
continue
if slot_elem_last >= last_morning_hour_week:
slot_elem_last = last_morning_hour_week
last_slot = slot_elem_last.strftime("%H:%M")
# Si le jour est égal à la date du jour
if (slot_elem_last > last_morning_hour_week):
if (today_hour_available > last_morning_hour_week):
continue
if (today_hour_available > slot_elem_last):
continue
if (today_hour_available > slot_elem):
slot_elem_first = today_hour_available + timedelta(
hours=1.0)
first_slot = slot_elem_first.strftime("%H:00")
if first_slot == last_slot:
continue
# Vérification si
# Nombre max de retrait défini a été atteint
# Pas de controle si La valeur définie est 0
if rec.nb_max_retrait > 0:
first_slot_hour = first_slot.split(":")
first_slot_float = float(
'%s.%s' % (first_slot_hour[0], first_slot_hour[1]))
nb_sale_slot = self.env['sale.order'].search_count(
[('vracoop_point_retrait_id', '=', rec.id),
('day_retrait', '=', week.date()),
('hour_retrait', '=', first_slot_float)])
if nb_sale_slot < rec.nb_max_retrait:
slots.append((first_slot, last_slot))
else:
slots.append((first_slot, last_slot))
# Boucle pour les créneaux de l'après-midi
for slot_elem in list_slot_per_day_noon:
# Conversion du 1er Slot en HH:MM
first_slot = slot_elem.strftime("%H:%M")
# Calcul du dernier slot
# en fonction du temps de mis à dsiposition
slot_elem_last = slot_elem + timedelta(
hours=corresponding_line.availability_time)
# Conversion du Dernier Slot en HH:MM
last_slot = slot_elem_last.strftime("%H:%M")
if slot_elem >= last_noon_hour_week:
continue
if slot_elem_last >= last_noon_hour_week:
slot_elem_last = last_noon_hour_week
last_slot = slot_elem_last.strftime("%H:%M")
# Si le jour est égal à la date du jour
if (slot_elem_last > last_noon_hour_week):
if (today_hour_available > last_noon_hour_week):
continue
if (today_hour_available > slot_elem_last):
continue
if (today_hour_available > slot_elem):
slot_elem_first = today_hour_available + timedelta(
hours=1.0)
first_slot = slot_elem_first.strftime("%H:00")
if first_slot == last_slot:
continue
# Vérification si
# Nombre max de retrait défini a été atteint
# Pas de controle si La valeur définie est 0
if rec.nb_max_retrait > 0:
first_slot_hour = first_slot.split(":")
first_slot_float = float(
'%s.%s' % (first_slot_hour[0], first_slot_hour[1]))
nb_sale_slot = self.env['sale.order'].search_count(
[('vracoop_point_retrait_id', '=', rec.id),
('day_retrait', '=', week.date()),
('hour_retrait', '=', first_slot_float)])
if nb_sale_slot < rec.nb_max_retrait:
slots.append((first_slot, last_slot))
else:
slots.append((first_slot, last_slot))
return_slot_list = slots
if return_slot_list:
vals.append(
(day_short_name,
week,
week.strftime("%b"), return_slot_list))
return vals