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.
203 lines
9.7 KiB
203 lines
9.7 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
|
|
# import dateutil.rrule as rrule
|
|
# from datetime import date
|
|
from dateutil.relativedelta import *
|
|
from dateutil.easter import *
|
|
from dateutil.rrule import rrule, DAILY, MINUTELY, rruleset
|
|
from dateutil.parser import *
|
|
# from datetime import *
|
|
from datetime import datetime, timedelta
|
|
|
|
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")
|
|
|
|
@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 = datetime.today()
|
|
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
|
|
|
|
list_week = list(rrule(
|
|
DAILY,
|
|
count=count_day,
|
|
dtstart=datetime.today()))
|
|
|
|
for week in list_week:
|
|
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:
|
|
corresponding_line = rec.vracoop_retrait_time_ids.search([
|
|
('vracoop_point_retrait_id', '=', rec.id),
|
|
('name', '=', week.strftime("%w"))])
|
|
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]
|
|
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)
|
|
|
|
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
|
|
|
|
today_hour_available = today_datetime + timedelta(
|
|
hours=corresponding_line.preparation_time)
|
|
|
|
for slot_elem in list_slot_per_day_morning:
|
|
first_slot = slot_elem.strftime("%H:%M")
|
|
slot_elem_last = slot_elem + timedelta(
|
|
hours=corresponding_line.availability_time)
|
|
last_slot = slot_elem_last.strftime("%H:%M")
|
|
if slot_elem.date() == today_datetime.date():
|
|
if (today_hour_available > slot_elem_last):
|
|
continue
|
|
if slot_elem_last >= last_morning_hour_week:
|
|
slot_elem_last = last_morning_hour_week
|
|
last_slot = slot_elem_last.strftime("%H:%M")
|
|
if slot_elem >= last_morning_hour_week:
|
|
continue
|
|
# Check number of maximum withdrawal not reached
|
|
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))
|
|
|
|
for slot_elem in list_slot_per_day_noon:
|
|
first_slot = slot_elem.strftime("%H:%M")
|
|
slot_elem_last = slot_elem + timedelta(
|
|
hours=corresponding_line.availability_time)
|
|
last_slot = slot_elem_last.strftime("%H:%M")
|
|
if week.date() == today_datetime.date():
|
|
if (today_hour_available > slot_elem_last):
|
|
continue
|
|
if slot_elem_last >= last_noon_hour_week:
|
|
slot_elem_last = last_noon_hour_week
|
|
last_slot = slot_elem_last.strftime("%H:%M")
|
|
if slot_elem >= last_noon_hour_week:
|
|
continue
|
|
# Check number of maximum withdrawal not reached
|
|
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))
|
|
|
|
return_slot_list = slots
|
|
if return_slot_list:
|
|
vals.append(
|
|
(day_short_name,
|
|
week,
|
|
week.strftime("%b"), return_slot_list))
|
|
|
|
return vals
|